Portability | portable |
---|---|
Stability | experimental |
Maintainer | pxqr.sta@gmail.com |
Safe Haskell | None |
PeerID
represent self assigned peer identificator. Ideally each
host in the network should have unique peer id to avoid
collisions, therefore for peer ID generation we use good entropy
source. (FIX not really) Peer ID is sent in tracker request,
sent and received in peer handshakes and used in /distributed
hash table/ queries.
- data PeerId
- genPeerId :: IO PeerId
- timestamp :: IO BS.ByteString
- entropy :: IO BS.ByteString
- azureusStyle :: BS.ByteString -> BS.ByteString -> BS.ByteString -> PeerId
- shadowStyle :: Char -> BS.ByteString -> BS.ByteString -> PeerId
- clientInfo :: PeerId -> ClientInfo
- byteStringPadded :: BS.ByteString -> Int -> Char -> BS.Builder
- defaultClientId :: BS.ByteString
- defaultVersionNumber :: BS.ByteString
PeerId
Peer identifier is exactly 20 bytes long bytestring.
Generation
Here we use Azureus-style encoding with the following args:
-
HS
for the client id. - Version of the package for the version number
- UTC time day ++ day time for the random number.
timestamp :: IO BS.ByteStringSource
Gives 15 characters long decimal timestamp such that:
- 6 bytes : first 6 characters from picoseconds obtained with %q.
- 1 bytes : character
.
for readability. - 9..* bytes: number of whole seconds since the Unix epoch (!)REVERSED.
Can be used both with shadow and azureus style encoding. This format is used to make the ID's readable(for debugging) and more or less random.
entropy :: IO BS.ByteStringSource
Gives 15 character long random bytestring. This is more robust method for generation of random part of peer ID than timestamp.
Encoding
:: BS.ByteString | 2 character client ID, padded with |
-> BS.ByteString | Version number, padded with |
-> BS.ByteString | Random number, padded with '0'. |
-> PeerId | Azureus-style encoded peer ID. |
:: Char | Client ID. |
-> BS.ByteString | Version number. |
-> BS.ByteString | Random number. |
-> PeerId | Shadow style encoded peer ID. |
Shadow-style encoding have the following layout:
- 1 byte : client id.
- 0-4 bytes: version number. If less than 4 then padded with
-
char. - 15 bytes : random number. If length is less than 15 then padded with '0' char.
Decoding
clientInfo :: PeerId -> ClientInfoSource
Tries to extract meaningful information from peer ID bytes. If
peer id uses unknown coding style then client info returned is
def
.
Extra
:: BS.ByteString | bytestring to be padded. |
-> Int | size of result builder. |
-> Char | character used for padding. |
-> BS.Builder |
Pad bytestring so it's becomes exactly request length. Conversion is done like so:
- length < size: Complete bytestring by given charaters.
- length = size: Output bytestring as is.
- length > size: Drop last (length - size) charaters from a given bytestring.
defaultClientId :: BS.ByteStringSource
HS - 2 bytes long client identifier.
defaultVersionNumber :: BS.ByteStringSource
Gives exactly 4 bytes long version number for any version of the package. Version is taken from .cabal.