{% extends "_layout.html" %} {% block title %}Old TCP Package{% endblock %} {% block content %}
Implements the transport for communicating with other routers via TCP/IP.
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)
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 necessaryproperties
is a name=value mapping, formatted as the other I2P
mappings (via {@link net.i2p.data.DataHelper#readProperties})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 addressIP
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 valueWhether 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.
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 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 {@link net.i2p.data.Hash#writeBytes}.routerInfo
is the serialization of the local router's info
per {@link net.i2p.data.RouterInfo#writeBytes}.currentTime
is what the local router thinks the current network time
is, formatted per {@link net.i2p.data.DataHelper#writeDate}.status
is a 1 byte value: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 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 {@link net.i2p.crypto.CryptoConstants} and x is a randomly chosen valueY
is a 256 byte unsigned integer in 2s complement, representing
g^y mod p (where g
and p
are defined
in {@link net.i2p.crypto.CryptoConstants} and y is a randomly chosen valueS(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 {@link net.i2p.data.Signature}.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
{% endblock %}