forked from I2P_Developers/i2p.www
ssu update; move spec to new page
This commit is contained in:
@ -112,5 +112,11 @@ I2P is designed as a "mesh network", where it is assumed that any router can con
|
||||
This assumption may be broken by routers that have exceeded their connection limits, and by
|
||||
routers that are behind restrictive state firewalls (restricted routes).
|
||||
|
||||
<p>
|
||||
The current connection limits are higher for SSU than for NTCP, based on the assumption that
|
||||
the memory requirements for an NTCP connection are higher than that for SSU.
|
||||
However, as NTCP buffers are partially in the kernel and SSU buffers are on the Java heap,
|
||||
that assumption is difficult to verify.
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
@ -1,545 +1,36 @@
|
||||
{% extends "_layout.html" %}
|
||||
{% block title %}SSU{% endblock %}
|
||||
{% block title %}SSU Transport{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
Updated July 2010 for release 0.8
|
||||
|
||||
<h1>Secure Semireliable UDP (SSU)</h1>
|
||||
<p>
|
||||
SSU (also called "UDP" in much of the I2P documentation and user interfaces)
|
||||
is one of two transports currently implemented in I2P.
|
||||
is one of two <a href="transport.html">transports</a> currently implemented in I2P.
|
||||
The other is <a href="ntcp.html">NTCP</a>.
|
||||
</p><p>
|
||||
SSU was enabled in I2P release 0.6 as the top-priority transport.
|
||||
NTCP was enabled in I2P release 0.6.1.22 as the top-priority transport,
|
||||
while leaving SSU in place as a secondary transport.
|
||||
The reader should not rely solely on the picture or document below, but should
|
||||
verify the details in the implementation.
|
||||
</p><p>
|
||||
While NTCP is now the primary transport, SSU is still relied upon for
|
||||
firewall detection and traversal. In I2P releases through 0.7.3, inbound
|
||||
TCP was not enabled by default, leaving SSU as the only transport available
|
||||
for outbound connections to a majority of routers.
|
||||
Beginning with release 0.7.4, I2P will enable inbound NTCP if it detects
|
||||
that the router is not firewalled, or the port is forwarded.
|
||||
This should lessen the usage of SSU further.
|
||||
</p><p>
|
||||
Analysis of current SSU performance, including assessment of window size adjustment
|
||||
and other parameters, and adjustment of the protocol implementation to improve
|
||||
performance, is a topic for future work.
|
||||
</p>
|
||||
|
||||
<h1>Implementation Diagram</h1>
|
||||
This is a diagram developed by jrandom.
|
||||
It appears to accurately reflect the current implementation, however there may be small differences.
|
||||
<p>
|
||||
<img src="/_static/images/udp.png">
|
||||
SSU is the newer of the two transports,
|
||||
introduced in I2P release 0.6.
|
||||
In a standard I2P installation, the router uses both NTCP and SSU for outbound connections.
|
||||
A router
|
||||
The selection of a transport for a connection.
|
||||
|
||||
|
||||
<h1>Specification</h1>
|
||||
<h2>SSU Services</h2>
|
||||
|
||||
<p>
|
||||
The goal of this protocol is to provide secure, authenticated,
|
||||
semireliable, and unordered message delivery, exposing only a minimal
|
||||
amount of data easily discernible to third parties. It should
|
||||
support high degree communication as well as TCP-friendly congestion
|
||||
control, and may include PMTU detection. It should be capable of
|
||||
efficiently moving bulk data at rates sufficient for home users.
|
||||
In addition, it should support techniques for addressing network
|
||||
obstacles, like most NATs or firewalls.</p>
|
||||
Like the NTCP transport, SSU provides reliable, encrypted, connection-oriented, point-to-point data transport.
|
||||
Unique to SSU, it also provides IP detection and NAT traversal services, including:
|
||||
|
||||
<h2><a name="addressing">Addressing and introduction</a></h2>
|
||||
<ul>
|
||||
<li>Cooperative NAT/Firewall traversal using <a href="#introduction">introducers</a>
|
||||
<li>Local IP detection by inspection of incoming packets and <a href="#peerTesting">peer testing</a>
|
||||
<li>Communication of firewall status and local IP, and changes to either to NTCP
|
||||
<li>Communication of firewall status and local IP, and changes to either, to the router and the user interface
|
||||
</ul>
|
||||
|
||||
<p>To contact an SSU peer, one of two sets of information is necessary:
|
||||
a direct address, for when the peer is publicly reachable, or an
|
||||
indirect address, for using a third party to introduce the peer.
|
||||
There is no restriction on the number of addresses a peer may have.</p>
|
||||
|
||||
<pre>
|
||||
Direct: ssu://host:port/introKey[?opts=[A-Z]*]
|
||||
Indirect: ssu://tag@relayhost:port/relayIntroKey/targetIntroKey[?opts=[A-Z]*]
|
||||
</pre>
|
||||
|
||||
<p>These introduction keys are delivered through an external channel
|
||||
(the network database, where they are identical to the router Hash for now)
|
||||
and must be used when establishing a session key. For the indirect
|
||||
address, the peer must first contact the relayhost and ask them for
|
||||
an introduction to the peer known at that relayhost under the given
|
||||
tag. If possible, the relayhost sends a message to the addressed
|
||||
peer telling them to contact the requesting peer, and also gives
|
||||
the requesting peer the IP and port on which the addressed peer is
|
||||
located. In addition, the peer establishing the connection must
|
||||
already know the public keys of the peer they are connecting to (but
|
||||
not necessary to any intermediary relay peer).</p>
|
||||
|
||||
<p>Each of the addresses may also expose a series of options - special
|
||||
capabilities of that particular peer. For a list of available
|
||||
capabilities, see <a href="#capabilities">below</a>.</p>
|
||||
|
||||
<h2><a name="header">Header</a></h2>
|
||||
|
||||
<p>
|
||||
All UDP datagrams begin with a 16 byte MAC (Message Authentication Code)
|
||||
and a 16 byte IV (Initialization Vector
|
||||
followed by a variable
|
||||
size payload encrypted with the appropriate key. The MAC used is
|
||||
HMAC-MD5, truncated to 16 bytes, while the key is a full 32 byte AES256
|
||||
key. The specific construct of the MAC is the first 16 bytes from:</p>
|
||||
<pre>
|
||||
HMAC-MD5(payload || IV || (payloadLength ^ protocolVersion), macKey)
|
||||
</pre>
|
||||
|
||||
<p>The protocol version is currently 0.</p>
|
||||
|
||||
<p>The payload itself is AES256/CBC encrypted with the IV and the
|
||||
sessionKey, with replay prevention addressed within its body,
|
||||
explained below. The payloadLength in the MAC is a 2 byte unsigned
|
||||
integer in 2s complement.</p>
|
||||
|
||||
<p>The protocolVersion is a 2 byte unsigned integer in 2s complement,
|
||||
and currently set to 0. Peers using a different protocol version will
|
||||
not be able to communicate with this peer, though earlier versions not
|
||||
using this flag are.</p>
|
||||
|
||||
<h2><a name="payload">Payload</a></h2>
|
||||
|
||||
<p>Within the AES encrypted payload, there is a minimal common structure
|
||||
to the various messages - a one byte flag and a four byte sending
|
||||
timestamp (*seconds* since the unix epoch). The flag byte contains
|
||||
the following bitfields:</p>
|
||||
<pre>
|
||||
bits 0-3: payload type
|
||||
bit 4: rekey?
|
||||
bit 5: extended options included
|
||||
bits 6-7: reserved
|
||||
</pre>
|
||||
|
||||
<p>If the rekey flag is set, 64 bytes of keying material follow the
|
||||
timestamp. If the extended options flag is set, a one byte option
|
||||
size value is appended to, followed by that many extended option
|
||||
bytes, which are currently uninterpreted.</p>
|
||||
|
||||
<p>When rekeying, the first 32 bytes of the keying material is fed
|
||||
into a SHA256 to produce the new MAC key, and the next 32 bytes are
|
||||
fed into a SHA256 to produce the new session key, though the keys are
|
||||
not immediately used. The other side should also reply with the
|
||||
rekey flag set and that same keying material. Once both sides have
|
||||
sent and received those values, the new keys should be used and the
|
||||
previous keys discarded. It may be useful to keep the old keys
|
||||
around briefly, to address packet loss and reordering.</p>
|
||||
|
||||
<p>NOTE: Rekeying is currently unimplemented.</p>
|
||||
|
||||
<pre>
|
||||
Header: 37+ bytes
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| MAC |
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| IV |
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|flag| time | (optionally |
|
||||
+----+----+----+----+----+ |
|
||||
| this may have 64 byte keying material |
|
||||
| and/or a one+N byte extended options) |
|
||||
+---------------------------------------|
|
||||
</pre>
|
||||
|
||||
<h2><a name="messages">Messages</a></h2>
|
||||
<p>
|
||||
There are 8 messages defined:
|
||||
</p><p>
|
||||
<table border="1">
|
||||
<tr><th>Type<th>Message
|
||||
<tr><td align="center">0<td>SessionRequest
|
||||
<tr><td align="center">1<td>SessionCreated
|
||||
<tr><td align="center">2<td>SessionConfirmed
|
||||
<tr><td align="center">3<td>RelayRequest
|
||||
<tr><td align="center">4<td>RelayResponse
|
||||
<tr><td align="center">5<td>RelayIntro
|
||||
<tr><td align="center">6<td>Data
|
||||
<tr><td align="center">7<td>PeerTest
|
||||
</table>
|
||||
</p>
|
||||
|
||||
<h3><a name="sessionRequest">SessionRequest (type 0)</a></h3>
|
||||
<table border="1">
|
||||
<tr><td align="right" valign="top"><b>Peer:</b></td>
|
||||
<td>Alice to Bob</td></tr>
|
||||
<tr><td align="right" valign="top"><b>Data:</b></td>
|
||||
<td><ul>
|
||||
<li>256 byte X, to begin the DH agreement</li>
|
||||
<li>1 byte IP address size</li>
|
||||
<li>that many byte representation of Bob's IP address</li>
|
||||
<li>N bytes, currently uninterpreted (later, for challenges)</li>
|
||||
</ul></td></tr>
|
||||
<tr><td align="right" valign="top"><b>Key used:</b></td>
|
||||
<td>introKey</td></tr>
|
||||
</table>
|
||||
|
||||
<pre>
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| X, as calculated from DH |
|
||||
| |
|
||||
. . .
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|size| that many byte IP address (4-16) |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| arbitrary amount |
|
||||
| of uninterpreted data |
|
||||
. . .
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
</pre>
|
||||
|
||||
<h3><a name="sessionCreated">SessionCreated (type 1)</a></h3>
|
||||
<table border="1">
|
||||
<tr><td align="right" valign="top"><b>Peer:</b></td>
|
||||
<td>Bob to Alice</td></tr>
|
||||
<tr><td align="right" valign="top"><b>Data:</b></td>
|
||||
<td><ul>
|
||||
<li>256 byte Y, to complete the DH agreement</li>
|
||||
<li>1 byte IP address size</li>
|
||||
<li>that many byte representation of Alice's IP address</li>
|
||||
<li>2 byte port number (unsigned, big endian 2s complement)</li>
|
||||
<li>4 byte relay tag which Alice can publish (else 0x0)</li>
|
||||
<li>4 byte timestamp (seconds from the epoch) for use in the DSA
|
||||
signature</li>
|
||||
<li>40 byte DSA signature of the critical exchanged data
|
||||
(X + Y + Alice's IP + Alice's port + Bob's IP + Bob's port + Alice's
|
||||
new relay tag + Bob's signed on time), encrypted with another
|
||||
layer of encryption using the negotiated sessionKey. The IV
|
||||
is reused here.</li>
|
||||
<li>8 bytes padding, encrypted with an additional layer of encryption
|
||||
using the negotiated session key as part of the DSA block</li>
|
||||
<li>N bytes, currently uninterpreted (later, for challenges)</li>
|
||||
</ul></td></tr>
|
||||
<tr><td align="right" valign="top"><b>Key used:</b></td>
|
||||
<td>introKey, with an additional layer of encryption over the 40 byte
|
||||
signature and the following 8 bytes padding.</td></tr>
|
||||
</table>
|
||||
|
||||
<pre>
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| Y, as calculated from DH |
|
||||
| |
|
||||
. . .
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|size| that many byte IP address (4-16) |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| Port (A)| public relay tag | signed
|
||||
+----+----+----+----+----+----+----+----+
|
||||
on time | |
|
||||
+----+----+ |
|
||||
| DSA signature |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| +----+----+----+----+----+----+
|
||||
| | (8 bytes of padding)
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
+----+----+ |
|
||||
| arbitrary amount |
|
||||
| of uninterpreted data |
|
||||
. . .
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
</pre>
|
||||
|
||||
<h3><a name="sessionConfirmed">SessionConfirmed (type 2)</a></h3>
|
||||
<table border="1">
|
||||
<tr><td align="right" valign="top"><b>Peer:</b></td>
|
||||
<td>Alice to Bob</td></tr>
|
||||
<tr><td align="right" valign="top"><b>Data:</b></td>
|
||||
<td><ul>
|
||||
<li>1 byte identity fragment info:<pre>
|
||||
bits 0-3: current identity fragment #
|
||||
bits 4-7: total identity fragments</pre></li>
|
||||
<li>2 byte size of the current identity fragment</li>
|
||||
<li>that many byte fragment of Alice's identity.</li>
|
||||
<li>on the last identity fragment, the signed on time is
|
||||
included after the identity fragment, and the last 40
|
||||
bytes contain the DSA signature of the critical exchanged
|
||||
data (X + Y + Alice's IP + Alice's port + Bob's IP + Bob's port
|
||||
+ Alice's new relay key + Alice's signed on time)</li>
|
||||
</ul></td></tr>
|
||||
<tr><td align="right" valign="top"><b>Key used:</b></td>
|
||||
<td>sessionKey</td></tr>
|
||||
</table>
|
||||
|
||||
<pre>
|
||||
<b>Fragment 1 through N-1</b>
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|info| cursize | |
|
||||
+----+----+----+ |
|
||||
| fragment of Alice's full |
|
||||
| identity keys |
|
||||
. . .
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|
||||
<b>Fragment N:</b>
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|info| cursize | |
|
||||
+----+----+----+ |
|
||||
| fragment of Alice's full |
|
||||
| identity keys |
|
||||
. . .
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| signed on time | |
|
||||
+----+----+----+----+ |
|
||||
| arbitrary amount of uninterpreted |
|
||||
| data, up from the end of the |
|
||||
| identity key to 40 bytes prior to |
|
||||
| end of the current packet |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| DSA signature |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
</pre>
|
||||
|
||||
<h3><a name="relayRequest">RelayRequest (type 3)</a></h3>
|
||||
<table border="1">
|
||||
<tr><td align="right" valign="top"><b>Peer:</b></td>
|
||||
<td>Alice to Bob</td></tr>
|
||||
<tr><td align="right" valign="top"><b>Data:</b></td>
|
||||
<td><ul>
|
||||
<li>4 byte relay tag</li>
|
||||
<li>1 byte IP address size</li>
|
||||
<li>that many byte representation of Alice's IP address</li>
|
||||
<li>2 byte port number (of Alice)</li>
|
||||
<li>1 byte challenge size</li>
|
||||
<li>that many bytes to be relayed to Charlie in the intro</li>
|
||||
<li>Alice's intro key (so Bob can reply with Charlie's info)</li>
|
||||
<li>4 byte nonce of alice's relay request</li>
|
||||
<li>N bytes, currently uninterpreted</li>
|
||||
</ul></td></tr>
|
||||
<tr><td align="right" valign="top"><b>Key used:</b></td>
|
||||
<td>introKey (or sessionKey, if Alice/Bob is established)</td></tr>
|
||||
</table>
|
||||
|
||||
<pre>
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| relay tag |size| that many |
|
||||
+----+----+----+----+----+ +----|
|
||||
| bytes for Alice's IP address |port
|
||||
+----+----+----+----+----+----+----+----+
|
||||
(A) |size| that many challenge bytes |
|
||||
+----+----+ |
|
||||
| to be delivered to Charlie |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| Alice's intro key |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| nonce | |
|
||||
+----+----+----+----+ |
|
||||
| arbitrary amount of uninterpreted data|
|
||||
+----+----+----+----+----+----+----+----+
|
||||
</pre>
|
||||
|
||||
<h3><a name="relayResponse">RelayResponse (type 4)</a></h3>
|
||||
<table border="1">
|
||||
<tr><td align="right" valign="top"><b>Peer:</b></td>
|
||||
<td>Bob to Alice</td></tr>
|
||||
<tr><td align="right" valign="top"><b>Data:</b></td>
|
||||
<td><ul>
|
||||
<li>1 byte IP address size</li>
|
||||
<li>that many byte representation of Charlie's IP address</li>
|
||||
<li>2 byte port number</li>
|
||||
<li>1 byte IP address size</li>
|
||||
<li>that many byte representation of Alice's IP address</li>
|
||||
<li>2 byte port number</li>
|
||||
<li>4 byte nonce sent by Alice</li>
|
||||
<li>N bytes, currently uninterpreted</li>
|
||||
</ul></td></tr>
|
||||
<tr><td align="right" valign="top"><b>Key used:</b></td>
|
||||
<td>introKey (or sessionKey, if Alice/Bob is established)</td></tr>
|
||||
</table>
|
||||
|
||||
<pre>
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|size| that many bytes making up |
|
||||
+----+ +----+----+
|
||||
| Charlie's IP address | Port (C)|
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|size| that many bytes making up |
|
||||
+----+ +----+----+
|
||||
| Alice's IP address | Port (A)|
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| nonce | |
|
||||
+----+----+----+----+ |
|
||||
| arbitrary amount of uninterpreted data|
|
||||
+----+----+----+----+----+----+----+----+
|
||||
</pre>
|
||||
|
||||
<h3><a name="relayIntro">RelayIntro (type 5)</a></h3>
|
||||
<table border="1">
|
||||
<tr><td align="right" valign="top"><b>Peer:</b></td>
|
||||
<td>Bob to Charlie</td></tr>
|
||||
<tr><td align="right" valign="top"><b>Data:</b></td>
|
||||
<td><ul>
|
||||
<li>1 byte IP address size</li>
|
||||
<li>that many byte representation of Alice's IP address</li>
|
||||
<li>2 byte port number (of Alice)</li>
|
||||
<li>1 byte challenge size</li>
|
||||
<li>that many bytes relayed from Alice</li>
|
||||
<li>N bytes, currently uninterpreted</li>
|
||||
</ul></td></tr>
|
||||
<tr><td align="right" valign="top"><b>Key used:</b></td>
|
||||
<td>sessionKey</td></tr>
|
||||
</table>
|
||||
|
||||
<pre>
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|size| that many bytes making up |
|
||||
+----+ +----+----+
|
||||
| Alice's IP address | Port (A)|
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|size| that many bytes of challenge |
|
||||
+----+ |
|
||||
| data relayed from Alice |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| arbitrary amount of uninterpreted data|
|
||||
+----+----+----+----+----+----+----+----+
|
||||
</pre>
|
||||
|
||||
<h3><a name="data">Data (type 6)</a></h3>
|
||||
<table border="1">
|
||||
<tr><td align="right" valign="top"><b>Peer:</b></td>
|
||||
<td>Any</td></tr>
|
||||
<tr><td align="right" valign="top"><b>Data:</b></td>
|
||||
<td><ul>
|
||||
<li>1 byte flags:<pre>
|
||||
bit 0: explicit ACKs included
|
||||
bit 1: ACK bitfields included
|
||||
bit 2: reserved
|
||||
bit 3: explicit congestion notification
|
||||
bit 4: request previous ACKs
|
||||
bit 5: want reply
|
||||
bit 6: extended data included
|
||||
bit 7: reserved</pre></li>
|
||||
<li>if explicit ACKs are included:<ul>
|
||||
<li>a 1 byte number of ACKs</li>
|
||||
<li>that many 4 byte MessageIds being fully ACKed</li>
|
||||
</ul></li>
|
||||
<li>if ACK bitfields are included:<ul>
|
||||
<li>a 1 byte number of ACK bitfields</li>
|
||||
<li>that many 4 byte MessageIds + a 1 or more byte ACK bitfield.
|
||||
The bitfield uses the 7 low bits of each byte, with the high
|
||||
bit specifying whether an additional bitfield byte follows it
|
||||
(1 = true, 0 = the current bitfield byte is the last). These
|
||||
sequence of 7 bit arrays represent whether a fragment has been
|
||||
received - if a bit is 1, the fragment has been received. To
|
||||
clarify, assuming fragments 0, 2, 5, and 9 have been received,
|
||||
the bitfield bytes would be as follows:<pre>
|
||||
byte 0
|
||||
bit 0: 1 (further bitfield bytes follow)
|
||||
bit 1: 1 (fragment 0 received)
|
||||
bit 2: 0 (fragment 1 not received)
|
||||
bit 3: 1 (fragment 2 received)
|
||||
bit 4: 0 (fragment 3 not received)
|
||||
bit 5: 0 (fragment 4 not received)
|
||||
bit 6: 1 (fragment 5 received)
|
||||
bit 7: 0 (fragment 6 not received)
|
||||
byte 1
|
||||
bit 0: 0 (no further bitfield bytes)
|
||||
bit 1: 0 (fragment 7 not received)
|
||||
bit 1: 0 (fragment 8 not received)
|
||||
bit 1: 1 (fragment 9 received)
|
||||
bit 1: 0 (fragment 10 not received)
|
||||
bit 1: 0 (fragment 11 not received)
|
||||
bit 1: 0 (fragment 12 not received)
|
||||
bit 1: 0 (fragment 13 not received)</pre></li>
|
||||
</ul></li>
|
||||
<li>If extended data included:<ul>
|
||||
<li>1 byte data size</li>
|
||||
<li>that many bytes of extended data (currently uninterpreted)</li></ul></li>
|
||||
<li>1 byte number of fragments (can be zero)</li>
|
||||
<li>If nonzero, that many message fragments:<ul>
|
||||
<li>4 byte messageId</li>
|
||||
<li>3 byte fragment info:<pre>
|
||||
bits 0-6: fragment #
|
||||
bit 7: isLast (1 = true)
|
||||
bits 8-9: unused
|
||||
bits 10-23: fragment size</pre></li>
|
||||
<li>that many bytes</li></ul>
|
||||
<li>N bytes padding, uninterpreted</li>
|
||||
</ul></td></tr>
|
||||
<tr><td align="right" valign="top"><b>Key used:</b></td>
|
||||
<td>sessionKey</td></tr>
|
||||
</table>
|
||||
|
||||
<pre>
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|flag| (additional headers, determined |
|
||||
+----+ |
|
||||
| by the flags, such as ACKs or |
|
||||
| bitfields |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|#frg| messageId | frag info |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| that many bytes of fragment data |
|
||||
. . .
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| messageId | frag info | |
|
||||
+----+----+----+----+----+----+----+ |
|
||||
| that many bytes of fragment data |
|
||||
. . .
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| messageId | frag info | |
|
||||
+----+----+----+----+----+----+----+ |
|
||||
| that many bytes of fragment data |
|
||||
. . .
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| arbitrary amount of uninterpreted data|
|
||||
+----+----+----+----+----+----+----+----+
|
||||
</pre>
|
||||
|
||||
<h3><a name="peerTest">PeerTest (type 7)</a></h3>
|
||||
<table border="1">
|
||||
<tr><td align="right" valign="top"><b>Peer:</b></td>
|
||||
<td><a href="#peerTesting">Any</a></td></tr>
|
||||
<tr><td align="right" valign="top"><b>Data:</b></td>
|
||||
<td><ul>
|
||||
<li>4 byte nonce</li>
|
||||
<li>1 byte IP address size</li>
|
||||
<li>that many byte representation of Alice's IP address</li>
|
||||
<li>2 byte port number</li>
|
||||
<li>Alice's introduction key</li>
|
||||
<li>N bytes, currently uninterpreted</li>
|
||||
</ul></td></tr>
|
||||
<tr><td align="right" valign="top"><b>Key used:</b></td>
|
||||
<td>introKey (or sessionKey if the connection has already been established)</td></tr>
|
||||
</table>
|
||||
|
||||
<pre>
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| test nonce |size| that many |
|
||||
+----+----+----+----+----+ |
|
||||
|bytes making up Alice's IP address |
|
||||
|----+----+----+----+----+----+----+----+
|
||||
| Port (A)| Alice or Charlie's |
|
||||
+----+----+ |
|
||||
| introduction key (Alice's is sent to |
|
||||
| Bob and Charlie, while Charlie's is | |
|
||||
| sent to Alice) |
|
||||
| +----+----+----+----+----+----+
|
||||
| | arbitrary amount of |
|
||||
|----+----+ |
|
||||
| uninterpreted data |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
</pre>
|
||||
<h1>Protocol Details</h1>
|
||||
|
||||
<h2><a name="congestioncontrol">Congestion control</a></h2>
|
||||
|
||||
@ -588,7 +79,7 @@ for UDP, and 8 for IP, giving us 596. Round up to mod 16, giving a total
|
||||
of 608.
|
||||
</p><p>
|
||||
Based on measurements, 1350 fits nearly all reasonably small I2NP messages
|
||||
(larger I2NP messages may be up to 1900B-4500B, which isn't going to fit
|
||||
(larger I2NP messages may be up to 1900 to 4500 bytes, which isn't going to fit
|
||||
into a live network MTU anyway).
|
||||
</p>
|
||||
|
||||
@ -760,6 +251,8 @@ with either Bob or Charlie, but it is not required.</p>
|
||||
|
||||
<h3><a name="establishDirect">Connection establishment (direct)</a></h3>
|
||||
|
||||
Alice connects directly to Bob.
|
||||
|
||||
<pre>
|
||||
Alice Bob
|
||||
SessionRequest--------------------->
|
||||
@ -771,7 +264,9 @@ with either Bob or Charlie, but it is not required.</p>
|
||||
<--------------------------Data
|
||||
</pre>
|
||||
|
||||
<h3><a name="establishIndirect">Connection establishment (indirect)</a></h3>
|
||||
<h3><a name="establishIndirect">Connection establishment (indirect using an introducer)</a></h3>
|
||||
|
||||
Alice first connects to introducer Bob, who relays the request to Charlie.
|
||||
|
||||
<pre>
|
||||
Alice Bob Charlie
|
||||
@ -840,4 +335,28 @@ with either Bob or Charlie, but it is not required.</p>
|
||||
as a Bob for an otherwise unreachable Alice.</dd>
|
||||
</dl>
|
||||
|
||||
<h1><a name="future">Future Work</a></h1>
|
||||
<p>
|
||||
Analysis of current SSU performance, including assessment of window size adjustment
|
||||
and other parameters, and adjustment of the protocol implementation to improve
|
||||
performance, is a topic for future work.
|
||||
<p>
|
||||
The current implementation repeatedly sends acknowledgements for the same packets,
|
||||
which unnecessarily increases overhead.
|
||||
<p>
|
||||
The Session Destroyed message is not currently implemented and is scheduled for release 0.8.1.
|
||||
<p>
|
||||
Rekeying is currently unimplemented and may never be.
|
||||
|
||||
|
||||
<h1>Implementation Diagram</h1>
|
||||
This diagram
|
||||
should accurately reflect the current implementation, however there may be small differences.
|
||||
<p>
|
||||
<img src="/_static/images/udp.png">
|
||||
|
||||
<h1><a name="spec">Specification</a></h1>
|
||||
<a href="udp_spec.html">Now on the SSU specification page</a>.
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
537
www.i2p2/pages/udp_spec.html
Normal file
537
www.i2p2/pages/udp_spec.html
Normal file
@ -0,0 +1,537 @@
|
||||
{% extends "_layout.html" %}
|
||||
{% block title %}SSU Specification{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
Updated July 2010 for release 0.8
|
||||
<p>
|
||||
<a href="udp.html">See the SSU page for an overview of the SSU transport</a>.
|
||||
|
||||
<h1>Specification</h1>
|
||||
|
||||
<p>
|
||||
The goal of this protocol is to provide secure, authenticated,
|
||||
semireliable, and unordered message delivery, exposing only a minimal
|
||||
amount of data easily discernible to third parties. It should
|
||||
support high degree communication as well as TCP-friendly congestion
|
||||
control, and may include PMTU detection. It should be capable of
|
||||
efficiently moving bulk data at rates sufficient for home users.
|
||||
In addition, it should support techniques for addressing network
|
||||
obstacles, like most NATs or firewalls.</p>
|
||||
|
||||
<h2><a name="addressing">Addressing and introduction</a></h2>
|
||||
|
||||
<p>To contact an SSU peer, one of two sets of information is necessary:
|
||||
a direct address, for when the peer is publicly reachable, or an
|
||||
indirect address, for using a third party to introduce the peer.
|
||||
There is no restriction on the number of addresses a peer may have.</p>
|
||||
|
||||
<pre>
|
||||
Direct: ssu://host:port/introKey[?opts=[A-Z]*]
|
||||
Indirect: ssu://tag@relayhost:port/relayIntroKey/targetIntroKey[?opts=[A-Z]*]
|
||||
</pre>
|
||||
|
||||
<p>These introduction keys are delivered through an external channel
|
||||
(the network database, where they are identical to the router Hash for now)
|
||||
and must be used when establishing a session key. For the indirect
|
||||
address, the peer must first contact the relayhost and ask them for
|
||||
an introduction to the peer known at that relayhost under the given
|
||||
tag. If possible, the relayhost sends a message to the addressed
|
||||
peer telling them to contact the requesting peer, and also gives
|
||||
the requesting peer the IP and port on which the addressed peer is
|
||||
located. In addition, the peer establishing the connection must
|
||||
already know the public keys of the peer they are connecting to (but
|
||||
not necessary to any intermediary relay peer).</p>
|
||||
|
||||
<p>Each of the addresses may also expose a series of options - special
|
||||
capabilities of that particular peer. For a list of available
|
||||
capabilities, see <a href="#capabilities">below</a>.</p>
|
||||
|
||||
<h2><a name="header">Header</a></h2>
|
||||
|
||||
<p>
|
||||
All UDP datagrams begin with a 16 byte MAC (Message Authentication Code)
|
||||
and a 16 byte IV (Initialization Vector
|
||||
followed by a variable
|
||||
size payload encrypted with the appropriate key. The MAC used is
|
||||
HMAC-MD5, truncated to 16 bytes, while the key is a full 32 byte AES256
|
||||
key. The specific construct of the MAC is the first 16 bytes from:</p>
|
||||
<pre>
|
||||
HMAC-MD5(payload || IV || (payloadLength ^ protocolVersion), macKey)
|
||||
</pre>
|
||||
|
||||
<p>The protocol version is currently 0.</p>
|
||||
|
||||
<p>The payload itself is AES256/CBC encrypted with the IV and the
|
||||
sessionKey, with replay prevention addressed within its body,
|
||||
explained below. The payloadLength in the MAC is a 2 byte unsigned
|
||||
integer in 2s complement.</p>
|
||||
|
||||
<p>The protocolVersion is a 2 byte unsigned integer in 2s complement,
|
||||
and currently set to 0. Peers using a different protocol version will
|
||||
not be able to communicate with this peer, though earlier versions not
|
||||
using this flag are.</p>
|
||||
|
||||
<h2><a name="payload">Payload</a></h2>
|
||||
|
||||
<p>Within the AES encrypted payload, there is a minimal common structure
|
||||
to the various messages - a one byte flag and a four byte sending
|
||||
timestamp (*seconds* since the unix epoch). The flag byte contains
|
||||
the following bitfields:</p>
|
||||
<pre>
|
||||
bits 0-3: payload type
|
||||
bit 4: rekey?
|
||||
bit 5: extended options included
|
||||
bits 6-7: reserved
|
||||
</pre>
|
||||
|
||||
<p>If the rekey flag is set, 64 bytes of keying material follow the
|
||||
timestamp. If the extended options flag is set, a one byte option
|
||||
size value is appended to, followed by that many extended option
|
||||
bytes, which are currently uninterpreted.</p>
|
||||
|
||||
<p>When rekeying, the first 32 bytes of the keying material is fed
|
||||
into a SHA256 to produce the new MAC key, and the next 32 bytes are
|
||||
fed into a SHA256 to produce the new session key, though the keys are
|
||||
not immediately used. The other side should also reply with the
|
||||
rekey flag set and that same keying material. Once both sides have
|
||||
sent and received those values, the new keys should be used and the
|
||||
previous keys discarded. It may be useful to keep the old keys
|
||||
around briefly, to address packet loss and reordering.</p>
|
||||
|
||||
<p>NOTE: Rekeying is currently unimplemented.</p>
|
||||
|
||||
<pre>
|
||||
Header: 37+ bytes
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| MAC |
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| IV |
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|flag| time | (optionally |
|
||||
+----+----+----+----+----+ |
|
||||
| this may have 64 byte keying material |
|
||||
| and/or a one+N byte extended options) |
|
||||
+---------------------------------------|
|
||||
</pre>
|
||||
|
||||
<h2><a name="messages">Messages</a></h2>
|
||||
<p>
|
||||
There are 8 messages defined:
|
||||
</p><p>
|
||||
<table border="1">
|
||||
<tr><th>Type<th>Message<th>Notes
|
||||
<tr><td align="center">0<td>SessionRequest
|
||||
<tr><td align="center">1<td>SessionCreated
|
||||
<tr><td align="center">2<td>SessionConfirmed
|
||||
<tr><td align="center">8<td>SessionDestroyed<td>Unimplemented
|
||||
<tr><td align="center">3<td>RelayRequest
|
||||
<tr><td align="center">4<td>RelayResponse
|
||||
<tr><td align="center">5<td>RelayIntro
|
||||
<tr><td align="center">6<td>Data
|
||||
<tr><td align="center">7<td>PeerTest
|
||||
</table>
|
||||
</p>
|
||||
|
||||
<h3><a name="sessionRequest">SessionRequest (type 0)</a></h3>
|
||||
<table border="1">
|
||||
<tr><td align="right" valign="top"><b>Peer:</b></td>
|
||||
<td>Alice to Bob</td></tr>
|
||||
<tr><td align="right" valign="top"><b>Data:</b></td>
|
||||
<td><ul>
|
||||
<li>256 byte X, to begin the DH agreement</li>
|
||||
<li>1 byte IP address size</li>
|
||||
<li>that many byte representation of Bob's IP address</li>
|
||||
<li>N bytes, currently uninterpreted (later, for challenges)</li>
|
||||
</ul></td></tr>
|
||||
<tr><td align="right" valign="top"><b>Key used:</b></td>
|
||||
<td>introKey</td></tr>
|
||||
</table>
|
||||
|
||||
<pre>
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| X, as calculated from DH |
|
||||
| |
|
||||
. . .
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|size| that many byte IP address (4-16) |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| arbitrary amount |
|
||||
| of uninterpreted data |
|
||||
. . .
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
</pre>
|
||||
|
||||
<h3><a name="sessionCreated">SessionCreated (type 1)</a></h3>
|
||||
<table border="1">
|
||||
<tr><td align="right" valign="top"><b>Peer:</b></td>
|
||||
<td>Bob to Alice</td></tr>
|
||||
<tr><td align="right" valign="top"><b>Data:</b></td>
|
||||
<td><ul>
|
||||
<li>256 byte Y, to complete the DH agreement</li>
|
||||
<li>1 byte IP address size</li>
|
||||
<li>that many byte representation of Alice's IP address</li>
|
||||
<li>2 byte port number (unsigned, big endian 2s complement)</li>
|
||||
<li>4 byte relay tag which Alice can publish (else 0x0)</li>
|
||||
<li>4 byte timestamp (seconds from the epoch) for use in the DSA
|
||||
signature</li>
|
||||
<li>40 byte DSA signature of the critical exchanged data
|
||||
(X + Y + Alice's IP + Alice's port + Bob's IP + Bob's port + Alice's
|
||||
new relay tag + Bob's signed on time), encrypted with another
|
||||
layer of encryption using the negotiated sessionKey. The IV
|
||||
is reused here.</li>
|
||||
<li>8 bytes padding, encrypted with an additional layer of encryption
|
||||
using the negotiated session key as part of the DSA block</li>
|
||||
<li>N bytes, currently uninterpreted (later, for challenges)</li>
|
||||
</ul></td></tr>
|
||||
<tr><td align="right" valign="top"><b>Key used:</b></td>
|
||||
<td>introKey, with an additional layer of encryption over the 40 byte
|
||||
signature and the following 8 bytes padding.</td></tr>
|
||||
</table>
|
||||
|
||||
<pre>
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| Y, as calculated from DH |
|
||||
| |
|
||||
. . .
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|size| that many byte IP address (4-16) |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| Port (A)| public relay tag | signed
|
||||
+----+----+----+----+----+----+----+----+
|
||||
on time | |
|
||||
+----+----+ |
|
||||
| DSA signature |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| +----+----+----+----+----+----+
|
||||
| | (8 bytes of padding)
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
+----+----+ |
|
||||
| arbitrary amount |
|
||||
| of uninterpreted data |
|
||||
. . .
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
</pre>
|
||||
|
||||
<h3><a name="sessionConfirmed">SessionConfirmed (type 2)</a></h3>
|
||||
<table border="1">
|
||||
<tr><td align="right" valign="top"><b>Peer:</b></td>
|
||||
<td>Alice to Bob</td></tr>
|
||||
<tr><td align="right" valign="top"><b>Data:</b></td>
|
||||
<td><ul>
|
||||
<li>1 byte identity fragment info:<pre>
|
||||
bits 0-3: current identity fragment #
|
||||
bits 4-7: total identity fragments</pre></li>
|
||||
<li>2 byte size of the current identity fragment</li>
|
||||
<li>that many byte fragment of Alice's identity.</li>
|
||||
<li>on the last identity fragment, the signed on time is
|
||||
included after the identity fragment, and the last 40
|
||||
bytes contain the DSA signature of the critical exchanged
|
||||
data (X + Y + Alice's IP + Alice's port + Bob's IP + Bob's port
|
||||
+ Alice's new relay key + Alice's signed on time)</li>
|
||||
</ul></td></tr>
|
||||
<tr><td align="right" valign="top"><b>Key used:</b></td>
|
||||
<td>sessionKey</td></tr>
|
||||
</table>
|
||||
|
||||
<pre>
|
||||
<b>Fragment 1 through N-1</b>
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|info| cursize | |
|
||||
+----+----+----+ |
|
||||
| fragment of Alice's full |
|
||||
| identity keys |
|
||||
. . .
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|
||||
<b>Fragment N:</b>
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|info| cursize | |
|
||||
+----+----+----+ |
|
||||
| fragment of Alice's full |
|
||||
| identity keys |
|
||||
. . .
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| signed on time | |
|
||||
+----+----+----+----+ |
|
||||
| arbitrary amount of uninterpreted |
|
||||
| data, up from the end of the |
|
||||
| identity key to 40 bytes prior to |
|
||||
| end of the current packet |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| DSA signature |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
</pre>
|
||||
|
||||
<h3><a name="sessionDestroyed">SessionDestroyed (type 8)</a></h3>
|
||||
Currently unimplemented, scheduled for implementation in version 0.8.1.
|
||||
<table border="1">
|
||||
<tr><td align="right" valign="top"><b>Peer:</b></td>
|
||||
<td>Alice to Bob or Bob to Alice</td></tr>
|
||||
<tr><td align="right" valign="top"><b>Data:</b></td>
|
||||
<td>none
|
||||
</td></tr>
|
||||
<tr><td align="right" valign="top"><b>Key used:</b></td>
|
||||
<td>sessionKey or introKey</td></tr>
|
||||
</table>
|
||||
|
||||
<pre>
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| no data |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
</pre>
|
||||
|
||||
<h3><a name="relayRequest">RelayRequest (type 3)</a></h3>
|
||||
<table border="1">
|
||||
<tr><td align="right" valign="top"><b>Peer:</b></td>
|
||||
<td>Alice to Bob</td></tr>
|
||||
<tr><td align="right" valign="top"><b>Data:</b></td>
|
||||
<td><ul>
|
||||
<li>4 byte relay tag</li>
|
||||
<li>1 byte IP address size</li>
|
||||
<li>that many byte representation of Alice's IP address</li>
|
||||
<li>2 byte port number (of Alice)</li>
|
||||
<li>1 byte challenge size</li>
|
||||
<li>that many bytes to be relayed to Charlie in the intro</li>
|
||||
<li>Alice's intro key (so Bob can reply with Charlie's info)</li>
|
||||
<li>4 byte nonce of alice's relay request</li>
|
||||
<li>N bytes, currently uninterpreted</li>
|
||||
</ul></td></tr>
|
||||
<tr><td align="right" valign="top"><b>Key used:</b></td>
|
||||
<td>introKey (or sessionKey, if Alice/Bob is established)</td></tr>
|
||||
</table>
|
||||
|
||||
<pre>
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| relay tag |size| that many |
|
||||
+----+----+----+----+----+ +----|
|
||||
| bytes for Alice's IP address |port
|
||||
+----+----+----+----+----+----+----+----+
|
||||
(A) |size| that many challenge bytes |
|
||||
+----+----+ |
|
||||
| to be delivered to Charlie |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| Alice's intro key |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| nonce | |
|
||||
+----+----+----+----+ |
|
||||
| arbitrary amount of uninterpreted data|
|
||||
+----+----+----+----+----+----+----+----+
|
||||
</pre>
|
||||
|
||||
<h3><a name="relayResponse">RelayResponse (type 4)</a></h3>
|
||||
<table border="1">
|
||||
<tr><td align="right" valign="top"><b>Peer:</b></td>
|
||||
<td>Bob to Alice</td></tr>
|
||||
<tr><td align="right" valign="top"><b>Data:</b></td>
|
||||
<td><ul>
|
||||
<li>1 byte IP address size</li>
|
||||
<li>that many byte representation of Charlie's IP address</li>
|
||||
<li>2 byte port number</li>
|
||||
<li>1 byte IP address size</li>
|
||||
<li>that many byte representation of Alice's IP address</li>
|
||||
<li>2 byte port number</li>
|
||||
<li>4 byte nonce sent by Alice</li>
|
||||
<li>N bytes, currently uninterpreted</li>
|
||||
</ul></td></tr>
|
||||
<tr><td align="right" valign="top"><b>Key used:</b></td>
|
||||
<td>introKey (or sessionKey, if Alice/Bob is established)</td></tr>
|
||||
</table>
|
||||
|
||||
<pre>
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|size| that many bytes making up |
|
||||
+----+ +----+----+
|
||||
| Charlie's IP address | Port (C)|
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|size| that many bytes making up |
|
||||
+----+ +----+----+
|
||||
| Alice's IP address | Port (A)|
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| nonce | |
|
||||
+----+----+----+----+ |
|
||||
| arbitrary amount of uninterpreted data|
|
||||
+----+----+----+----+----+----+----+----+
|
||||
</pre>
|
||||
|
||||
<h3><a name="relayIntro">RelayIntro (type 5)</a></h3>
|
||||
<table border="1">
|
||||
<tr><td align="right" valign="top"><b>Peer:</b></td>
|
||||
<td>Bob to Charlie</td></tr>
|
||||
<tr><td align="right" valign="top"><b>Data:</b></td>
|
||||
<td><ul>
|
||||
<li>1 byte IP address size</li>
|
||||
<li>that many byte representation of Alice's IP address</li>
|
||||
<li>2 byte port number (of Alice)</li>
|
||||
<li>1 byte challenge size</li>
|
||||
<li>that many bytes relayed from Alice</li>
|
||||
<li>N bytes, currently uninterpreted</li>
|
||||
</ul></td></tr>
|
||||
<tr><td align="right" valign="top"><b>Key used:</b></td>
|
||||
<td>sessionKey</td></tr>
|
||||
</table>
|
||||
|
||||
<pre>
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|size| that many bytes making up |
|
||||
+----+ +----+----+
|
||||
| Alice's IP address | Port (A)|
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|size| that many bytes of challenge |
|
||||
+----+ |
|
||||
| data relayed from Alice |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| arbitrary amount of uninterpreted data|
|
||||
+----+----+----+----+----+----+----+----+
|
||||
</pre>
|
||||
|
||||
<h3><a name="data">Data (type 6)</a></h3>
|
||||
<table border="1">
|
||||
<tr><td align="right" valign="top"><b>Peer:</b></td>
|
||||
<td>Any</td></tr>
|
||||
<tr><td align="right" valign="top"><b>Data:</b></td>
|
||||
<td><ul>
|
||||
<li>1 byte flags:<pre>
|
||||
bit 0: explicit ACKs included
|
||||
bit 1: ACK bitfields included
|
||||
bit 2: reserved
|
||||
bit 3: explicit congestion notification
|
||||
bit 4: request previous ACKs
|
||||
bit 5: want reply
|
||||
bit 6: extended data included
|
||||
bit 7: reserved</pre></li>
|
||||
<li>if explicit ACKs are included:<ul>
|
||||
<li>a 1 byte number of ACKs</li>
|
||||
<li>that many 4 byte MessageIds being fully ACKed</li>
|
||||
</ul></li>
|
||||
<li>if ACK bitfields are included:<ul>
|
||||
<li>a 1 byte number of ACK bitfields</li>
|
||||
<li>that many 4 byte MessageIds + a 1 or more byte ACK bitfield.
|
||||
The bitfield uses the 7 low bits of each byte, with the high
|
||||
bit specifying whether an additional bitfield byte follows it
|
||||
(1 = true, 0 = the current bitfield byte is the last). These
|
||||
sequence of 7 bit arrays represent whether a fragment has been
|
||||
received - if a bit is 1, the fragment has been received. To
|
||||
clarify, assuming fragments 0, 2, 5, and 9 have been received,
|
||||
the bitfield bytes would be as follows:<pre>
|
||||
byte 0
|
||||
bit 0: 1 (further bitfield bytes follow)
|
||||
bit 1: 1 (fragment 0 received)
|
||||
bit 2: 0 (fragment 1 not received)
|
||||
bit 3: 1 (fragment 2 received)
|
||||
bit 4: 0 (fragment 3 not received)
|
||||
bit 5: 0 (fragment 4 not received)
|
||||
bit 6: 1 (fragment 5 received)
|
||||
bit 7: 0 (fragment 6 not received)
|
||||
byte 1
|
||||
bit 0: 0 (no further bitfield bytes)
|
||||
bit 1: 0 (fragment 7 not received)
|
||||
bit 1: 0 (fragment 8 not received)
|
||||
bit 1: 1 (fragment 9 received)
|
||||
bit 1: 0 (fragment 10 not received)
|
||||
bit 1: 0 (fragment 11 not received)
|
||||
bit 1: 0 (fragment 12 not received)
|
||||
bit 1: 0 (fragment 13 not received)</pre></li>
|
||||
</ul></li>
|
||||
<li>If extended data included:<ul>
|
||||
<li>1 byte data size</li>
|
||||
<li>that many bytes of extended data (currently uninterpreted)</li></ul></li>
|
||||
<li>1 byte number of fragments (can be zero)</li>
|
||||
<li>If nonzero, that many message fragments:<ul>
|
||||
<li>4 byte messageId</li>
|
||||
<li>3 byte fragment info:<pre>
|
||||
bits 0-6: fragment #
|
||||
bit 7: isLast (1 = true)
|
||||
bits 8-9: unused
|
||||
bits 10-23: fragment size</pre></li>
|
||||
<li>that many bytes</li></ul>
|
||||
<li>N bytes padding, uninterpreted</li>
|
||||
</ul></td></tr>
|
||||
<tr><td align="right" valign="top"><b>Key used:</b></td>
|
||||
<td>sessionKey</td></tr>
|
||||
</table>
|
||||
|
||||
<pre>
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|flag| (additional headers, determined |
|
||||
+----+ |
|
||||
| by the flags, such as ACKs or |
|
||||
| bitfields |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|#frg| messageId | frag info |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| that many bytes of fragment data |
|
||||
. . .
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| messageId | frag info | |
|
||||
+----+----+----+----+----+----+----+ |
|
||||
| that many bytes of fragment data |
|
||||
. . .
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| messageId | frag info | |
|
||||
+----+----+----+----+----+----+----+ |
|
||||
| that many bytes of fragment data |
|
||||
. . .
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| arbitrary amount of uninterpreted data|
|
||||
+----+----+----+----+----+----+----+----+
|
||||
</pre>
|
||||
|
||||
<h3><a name="peerTest">PeerTest (type 7)</a></h3>
|
||||
<table border="1">
|
||||
<tr><td align="right" valign="top"><b>Peer:</b></td>
|
||||
<td><a href="#peerTesting">Any</a></td></tr>
|
||||
<tr><td align="right" valign="top"><b>Data:</b></td>
|
||||
<td><ul>
|
||||
<li>4 byte nonce</li>
|
||||
<li>1 byte IP address size</li>
|
||||
<li>that many byte representation of Alice's IP address</li>
|
||||
<li>2 byte port number</li>
|
||||
<li>Alice's introduction key</li>
|
||||
<li>N bytes, currently uninterpreted</li>
|
||||
</ul></td></tr>
|
||||
<tr><td align="right" valign="top"><b>Key used:</b></td>
|
||||
<td>introKey (or sessionKey if the connection has already been established)</td></tr>
|
||||
</table>
|
||||
|
||||
<pre>
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| test nonce |size| that many |
|
||||
+----+----+----+----+----+ |
|
||||
|bytes making up Alice's IP address |
|
||||
|----+----+----+----+----+----+----+----+
|
||||
| Port (A)| Alice or Charlie's |
|
||||
+----+----+ |
|
||||
| introduction key (Alice's is sent to |
|
||||
| Bob and Charlie, while Charlie's is | |
|
||||
| sent to Alice) |
|
||||
| +----+----+----+----+----+----+
|
||||
| | arbitrary amount of |
|
||||
|----+----+ |
|
||||
| uninterpreted data |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
</pre>
|
||||
|
||||
|
||||
|
||||
{% endblock %}
|
Reference in New Issue
Block a user