## 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`

- `#bytesFollowing` is a 2 byte unsigned integer specifying how many bytes there are (after the current pair) in the line sent. 0xFFFF is reserved
- `#versions` is 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.
- `tagData` is a 32 byte tag, if necessary
- `properties` is a name=value mapping, formatted as the other I2P mappings (via `DataHelper.readProperties(java.io.InputStream)`)
- `versionOk` is a 1 byte value specifying the protocol version that is agreed upon, or 0x0 if no compatible protocol versions are available.
- `#bytesIP` is a 2 byte unsigned integer specifying how many bytes following make up the IP address
- `IP` is made up of `#bytesIP` bytes 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.
- `nonce` is 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 `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".

- `H(x)` is the SHA256 hash of x, formatted per `Hash.writeBytes(java.io.OutputStream)`.
- `routerInfo` is the serialization of the local router's info per `RouterInfo.writeBytes(java.io.OutputStream)`.
- `currentTime` is what the local router thinks the current network time is, formatted per `DataHelper.writeDate(java.io.OutputStream, java.util.Date)`.
- `status` is 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 `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 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.

- `X` is a 256 byte unsigned integer in 2s complement, representing g^x mod p (where `g` and `p` are defined in `CryptoConstants` and x is a randomly chosen value
- `Y` is a 256 byte unsigned integer in 2s complement, representing g^y mod p (where `g` and `p` are defined in `CryptoConstants` and y is a randomly chosen value
- `S(val, key)` is the DSA signature of the `val` using the given signing `key` (in this case, the router's signing keys to provide authentication that they are who they say they are). The signature is formatted per `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