Implements the transport for communicating with other routers via TCP/IP.
Connection protocol
The protocol used to establish the connection between the peers is implemented in the {@link net.i2p.router.transport.tcp.ConnectionBuilder} for "Alice", the initiator, and in {@link net.i2p.router.transport.tcp.ConnectionHandler} for "Bob", the receiving peer. (+ implies concatenation)
Common case:
1) Alice to Bob:
#bytesFollowing + #versions + v1 [+ v2 [etc]] + tag? + tagData + properties
2) Bob to Alice:
#bytesFollowing + versionOk + #bytesIP + IP + tagOk? + nonce + properties
#bytesFollowingis a 2 byte unsigned integer specifying how many bytes there are (after the current pair) in the line sent. 0xFFFF is reserved#versionsis a 1 byte unsigned integer specifying how many acceptable 1 byte version numbers follow (preferred value first).v1(etc) is a 1 byte unsigned integer specifying a protocol version. The value 0x0 is not allowed.tag?is a 1 byte value specifying whether a tag follows - 0x0 means no tag follows, 0x1 means a 32 byte tag follows.tagDatais a 32 byte tag, if necessarypropertiesis a name=value mapping, formatted as the other I2P mappings (via {@link net.i2p.data.DataHelper#readProperties})versionOkis a 1 byte value specifying the protocol version that is agreed upon, or 0x0 if no compatible protocol versions are available.#bytesIPis a 2 byte unsigned integer specifying how many bytes following make up the IP addressIPis made up of#bytesIPbytes formatting the peer who established the connection's IP address as a string (e.g. "192.168.1.1")tagOk?is a 1 byte value specifying whether the tag provided is available for use - 0x0 means no, 0x1 means yes.nonceis a 4 byte random value
Whether or not the tagData is specified by Alice and is accepted
by Bob determines which of the scenarios below are used. In addition, the IP
address provided by Bob gives Alice the opportunity to fire up a socket listener
on that interface and include it in her list of reachable addresses. The
properties mappings are left for future expansion.
Connection establishment with a valid tag:
With a valid tag and nonce received, both Alice and
Bob load up the previously negotiated sessionKey and set the
iv to the first 16 bytes of H(tag + nonce). The
remainder of the communication is AES256 encrypted per
{@link net.i2p.crypto.AESInputStream} and {@link net.i2p.crypto.AESOutputStream}
3) Alice to Bob:
H(nonce)
4) Bob to Alice:
H(tag)
5) If the hashes are not correct, disconnect immediately and do not consume the tag
6) Alice to Bob:
routerInfo + currentTime + H(routerInfo + currentTime + nonce + tag)
7) Bob should now verify that he can establish a connection to her through one of the routerAddresses specified in her RouterInfo. The testing process is described below.
8) Bob to Alice:
routerInfo + status + properties + H(routerInfo + status + properties + nonce + tag)
9) If the status is okay, both Alice and Bob consume the
tagData, updating the next tag to be H(E(nonce + tag, sessionKey))
(with nonce+tag padded with 12 bytes of 0x0 at the end).
Otherwise, both sides disconnect and do not consume the tag. In addition, on error the
properties mapping has a more detailed reason under the key "MESSAGE".
H(x)is the SHA256 hash of x, formatted per {@link net.i2p.data.Hash#writeBytes}.routerInfois the serialization of the local router's info per {@link net.i2p.data.RouterInfo#writeBytes}.currentTimeis what the local router thinks the current network time is, formatted per {@link net.i2p.data.DataHelper#writeDate}.statusis a 1 byte value:- 0x0 means OK
- 0x1 means Alice was not reachable
- 0x2 means the clock was skewed (Bob's current time may be available in the properties mapping under "SKEW", formatted as "yyyyMMddhhmmssSSS", per {@link java.text.SimpleDateFormat}).
- 0x3 means the signature is invalid (only used by steps 9 and 11 below)
- Other values are currently undefined (yet fatal) errors
Connection establishment without a valid tag:
3) Alice to Bob
X
4) Bob to Alice
Y
5) Both sides complete the Diffie-Hellman exchange, setting the
sessionKey to the first 32 bytes of the result (e.g. (X^y mod p)),
iv to the next 16 bytes, and the nextTag to the 32
bytes after that. The rest of the data is AES256 encrypted with those settings per
{@link net.i2p.crypto.AESInputStream} and {@link net.i2p.crypto.AESOutputStream}
6) Alice to Bob
H(nonce)
7) Bob to Alice
H(nextTag)
8) If they disagree, disconnect immediately and do not persist the tags or keys
9) Alice to Bob
routerInfo + currentTime
+ S(routerInfo + currentTime + nonce + nextTag, routerIdent.signingKey)
10) Bob should now verify that he can establish a connection to her through one of the routerAddresses specified in her RouterInfo. The testing process is described below.
11) Bob to Alice
routerInfo + status + properties
+ S(routerInfo + status + properties + nonce + nextTag, routerIdent.signingKey)
12) If the signature matches on both sides and status is okay, both sides
save the sessionKey negotiated as well as the nextTag.
Otherwise, the keys and tags are discarded and both sides drop the connection.
Xis a 256 byte unsigned integer in 2s complement, representing g^x mod p (wheregandpare defined in {@link net.i2p.crypto.CryptoConstants} and x is a randomly chosen valueYis a 256 byte unsigned integer in 2s complement, representing g^y mod p (wheregandpare defined in {@link net.i2p.crypto.CryptoConstants} and y is a randomly chosen valueS(val, key)is the DSA signature of thevalusing the given signingkey(in this case, the router's signing keys to provide authentication that they are who they say they are). The signature is formatted per {@link net.i2p.data.Signature}.
Peer testing
As mentioned in steps 7 and 10 above, Bob should verify that Alice is reachable to prevent a restricted route from being formed (he may decide not to do this once I2P supports restricted routes)
1) Bob to Alice
0xFFFF + #versions + v1 [+ v2 [etc]] + properties
2) Alice to Bob
0xFFFF + versionOk + #bytesIP + IP + currentTime + properties
3) Both sides close the socket









