|
||||||||||
PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES |
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. |
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 ConnectionBuilder
for "Alice", the initiator, and in
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 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 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
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:SimpleDateFormat
).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 valueY
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 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 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
|
||||||||||
PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES |