Package net.i2p.router.transport.tcp

Implements the transport for communicating with other routers via TCP/IP.

See:
          Description

Class Summary
ConnectionBuilder Class responsible for all of the handshaking necessary to establish a connection with a peer.
ConnectionHandler Class responsible for all of the handshaking necessary to turn a socket into a TCPConnection.
ConnectionRunner Push out I2NPMessages across the wire
ConnectionTagManager Organize the tags used to connect with peers.
MessageHandler Receive messages from a message reader and bounce them off to the transport for further enqueueing.
PersistentConnectionTagManager Simple persistent impl writing the connection tags to connectionTag.keys (or another file specified via "i2np.tcp.tagFile")
TCPAddress Wrap up an address
TCPConnection Central choke point for a single TCP connection to a single peer.
TCPConnectionEstablisher Build new outbound connections, one at a time.
TCPListener Listen for TCP connections with a listener thread
TCPTransport TCP Transport implementation, coordinating the connections between peers and the transmission of messages across those connections.
 

Package net.i2p.router.transport.tcp Description

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 ConnectionBuilder for "Alice", the initiator, and in 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

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 AESInputStream and 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 ok, 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".

Connection establishment without a vald 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 AESInputStream and 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 ok, both sides save the sessionKey negotiated as well as the nextTag. Otherwise, the keys and tags are discarded and both sides drop the connection.

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