Files
i2p.www/www.i2p2/pages/udp_spec.html

789 lines
27 KiB
HTML
Raw Normal View History

2010-07-28 01:13:15 +00:00
{% extends "_layout.html" %}
2010-08-11 21:55:21 +00:00
{% block title %}SSU Protocol Specification{% endblock %}
2010-07-28 01:13:15 +00:00
{% block content %}
2011-09-14 15:14:11 +00:00
Updated August 2011 for release 0.8.9
2011-07-27 18:44:50 +00:00
2010-07-28 01:13:15 +00:00
<p>
<a href="udp.html">See the SSU page for an overview of the SSU transport</a>.
<h1>Specification</h1>
2010-08-11 21:55:21 +00:00
<h2 id="DH">DH Key Exchange</h2>
<p>
The initial 2048-bit DH key exchange is described on the
<a href="udp.html#keys">SSU page</a>.
This exchange uses the same shared prime as that used for I2P's
<a href="how_cryptography.html#elgamal">ElGamal encryption</a>.
</p>
2010-08-11 21:55:21 +00:00
<h2 id="header">Message Header</h2>
2010-07-28 01:13:15 +00:00
<p>
All UDP datagrams begin with a 16 byte MAC (Message Authentication Code)
2011-09-14 15:14:11 +00:00
and a 16 byte IV (Initialization Vector)
2010-08-11 21:55:21 +00:00
followed by a variable-size
payload encrypted with the appropriate key. The MAC used is
2010-07-28 01:13:15 +00:00
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>
2011-10-11 18:16:36 +00:00
where '||' means append.
The payload is the message starting with the flag byte.
The macKey is either the introduction key or the
2011-09-14 15:14:11 +00:00
session key, as specified for each message below.
2010-07-28 01:13:15 +00:00
2011-10-11 18:16:36 +00:00
<p>The payload itself (that is, the message starting with the flag byte)
is AES256/CBC encrypted with the IV and the
2010-07-28 01:13:15 +00:00
sessionKey, with replay prevention addressed within its body,
explained below. The payloadLength in the MAC is a 2 byte unsigned
2010-08-11 21:55:21 +00:00
integer.</p>
2010-07-28 01:13:15 +00:00
2010-08-11 21:55:21 +00:00
<p>The protocolVersion is a 2 byte unsigned integer
and is currently set to 0. Peers using a different protocol version will
2010-07-28 01:13:15 +00:00
not be able to communicate with this peer, though earlier versions not
using this flag are.</p>
<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
2010-08-11 21:55:21 +00:00
timestamp (seconds since the unix epoch). The flag byte contains
2010-07-28 01:13:15 +00:00
the following bitfields:</p>
<pre>
Bit order: 76543210 (bit 7 is MSB)
bits 7-4: payload type
bit 3: rekey?
bit 2: extended options included
bits 1-0: reserved
2010-07-28 01:13:15 +00:00
</pre>
<pre>
Header: 37+ bytes
2011-10-11 18:16:36 +00:00
Encryption starts with the flag byte.
2010-07-28 01:13:15 +00:00
+----+----+----+----+----+----+----+----+
| MAC |
2010-08-11 21:55:21 +00:00
+ +
2010-07-28 01:13:15 +00:00
| |
+----+----+----+----+----+----+----+----+
| IV |
2010-08-11 21:55:21 +00:00
+ +
2010-07-28 01:13:15 +00:00
| |
+----+----+----+----+----+----+----+----+
|flag| time | (optionally |
+----+----+----+----+----+ |
| this may have 64 byte keying material |
| and/or a one+N byte extended options) |
+---------------------------------------|
</pre>
2010-08-11 21:55:21 +00:00
<h3 id="rekey">Rekeying</h3>
<p>If the rekey flag is set, 64 bytes of keying material follow the
timestamp.
<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>
<h3 id="extend">Extended Options</h3>
<p>
If the extended options flag is set, a one byte option
size value is appended, followed by that many extended option
bytes.</p>
<p>NOTE: Extended options is currently unimplemented.</p>
<h2 id="padding">Padding</h2>
<p>
All messages contain 0 or more bytes of padding.
2010-08-16 01:55:25 +00:00
Each message must be padded to a 16 byte boundary, as required by the <a href="how_cryptography.html#AES">AES256 encryption layer</a>.
2010-08-11 21:55:21 +00:00
Currently, messages are not padded beyond the next 16 byte boundary.
The fixed-size tunnel messages of 1024 bytes (at a higher layer)
provide a significant amount of protection.
In the future, additional padding in the transport layer up to
a set of fixed packet sizes may be appropriate to further hide the data
fragmentation to external adversaries.
</p>
<h2 id="keys">Keys</h2>
<p>
Both introduction keys and session keys are 32 bytes,
and are defined by the
<a href="common_structures_spec.html#type_SessionKey">Common structures specification</a>.
The key used for the MAC and encryption is specified for each message below.
</p>
2011-09-14 15:14:11 +00:00
<p>Introduction keys are delivered through an external channel
(the network database, where they are identical to the router Hash for now).
</p>
2010-08-11 21:55:21 +00:00
<h2 id="notes">Notes</h2>
<h3 id="ipv6">IPv6 Notes</h3>
While the protocol specification supports 16-byte IPv6 addresses,
IPv6 addressing is not currently supported within I2P.
All IP addresses are currently 4 bytes.
<h3 id="time">Timestamps</h3>
While most of I2P uses 8-byte <a href="common_structures_spec.html#type_Date">Date</a> timestamps with
millisecond resolution, SSU uses a 4-byte timestamp with one-second resolution.
2010-07-28 06:10:34 +00:00
<h2 id="messages">Messages</h2>
2010-07-28 01:13:15 +00:00
<p>
2010-08-16 01:55:25 +00:00
There are 10 messages (payload types) defined:
2010-07-28 01:13:15 +00:00
</p><p>
<table border="1">
<tr><th>Type<th>Message<th>Notes
2011-09-14 15:14:11 +00:00
<tr><td align="center">0<td>SessionRequest<td>
<tr><td align="center">1<td>SessionCreated<td>
<tr><td align="center">2<td>SessionConfirmed<td>
<tr><td align="center">3<td>RelayRequest<td>
<tr><td align="center">4<td>RelayResponse<td>
<tr><td align="center">5<td>RelayIntro<td>
<tr><td align="center">6<td>Data<td>
<tr><td align="center">7<td>PeerTest<td>
<tr><td align="center">8<td>SessionDestroyed<td>Implemented as of 0.8.9
2010-08-11 21:55:21 +00:00
<tr><td align="center">n/a<td>HolePunch<td>
2010-07-28 01:13:15 +00:00
</table>
</p>
2010-07-28 06:10:34 +00:00
<h3 id="sessionRequest">SessionRequest (type 0)</h3>
2010-08-11 21:55:21 +00:00
<p>
This is the first message sent to establish a session.
</p>
2010-07-28 01:13:15 +00:00
<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>
2010-08-11 21:55:21 +00:00
<li>N bytes, currently uninterpreted</li>
2010-07-28 01:13:15 +00:00
</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>
2010-08-11 21:55:21 +00:00
<p>
Typical size including header, in current implementation: 304 bytes
</p>
<h4>Notes</h4>
<ul><li>
IP address is always 4 bytes in the current implementation.
</li><li>
The uninterpreted data could possibly be used in the future for challenges.
</li></ul>
IP address is always 4 bytes in the current implementation.
2010-07-28 06:10:34 +00:00
<h3 id="sessionCreated">SessionCreated (type 1)</h3>
2010-08-11 21:55:21 +00:00
<p>
This is the response to a Session Request.
</p>
2010-07-28 01:13:15 +00:00
<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>
2010-08-11 21:55:21 +00:00
<li>2 byte Alice's port number</li>
<li>4 byte relay (introduction) tag which Alice can publish (else 0x00000000)</li>
2010-07-28 01:13:15 +00:00
<li>4 byte timestamp (seconds from the epoch) for use in the DSA
signature</li>
2010-08-11 21:55:21 +00:00
<li>40 byte <a href="common_structures_spec.html#type_Signature">DSA signature</a> of the critical exchanged data
2010-07-28 01:13:15 +00:00
(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>
2010-08-11 21:55:21 +00:00
<li>N bytes, currently uninterpreted</li>
2010-07-28 01:13:15 +00:00
</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 |
2010-08-11 21:55:21 +00:00
+ +
2010-07-28 01:13:15 +00:00
| |
2010-08-11 21:55:21 +00:00
+ +
2010-07-28 01:13:15 +00:00
| |
2010-08-11 21:55:21 +00:00
+ +
2010-07-28 01:13:15 +00:00
| |
2010-08-11 21:55:21 +00:00
+ +----+----+----+----+----+----+
2010-07-28 01:13:15 +00:00
| | (8 bytes of padding)
+----+----+----+----+----+----+----+----+
| |
+----+----+ |
| arbitrary amount |
| of uninterpreted data |
. . .
| |
+----+----+----+----+----+----+----+----+
</pre>
2010-08-11 21:55:21 +00:00
<p>
Typical size including header, in current implementation: 368 bytes
</p>
<h4>Notes</h4>
<ul><li>
IP address is always 4 bytes in the current implementation.
</li><li>
If the relay tag is nonzero, Bob is offering to act as an introducer for Alice.
Alice may subsequently publish Bob's address and the relay tag in the network database.
</li><li>
Signed-on time appears to be unused or unverified in the current implementation.
</li><li>
The uninterpreted data could possibly be used in the future for challenges.
</li></ul>
2010-07-28 06:10:34 +00:00
<h3 id="sessionConfirmed">SessionConfirmed (type 2)</h3>
2010-08-11 21:55:21 +00:00
<p>
This is the response to a Session Created message and the last step in establishing a session.
There may be multiple Session Confirmed messages required if the Router Identity must be fragmented.
</p>
2010-07-28 01:13:15 +00:00
<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>
2010-08-11 21:55:21 +00:00
Bit order: 76543210 (bit 7 is MSB)
2010-08-16 01:55:25 +00:00
bits 7-4: current identity fragment # 0-14
bits 3-0: total identity fragments (F) 1-15</pre></li>
2010-07-28 01:13:15 +00:00
<li>2 byte size of the current identity fragment</li>
2010-08-11 21:55:21 +00:00
<li>that many byte fragment of Alice's
<a href="common_structures_spec#struct_RouterIdentity">Router Identity</a>
</li>
<li>After the last identity fragment only:
<ul><li>4 byte signed-on time
2010-08-16 01:55:25 +00:00
</li></ul>
<li>N bytes padding, currently uninterpreted
<li>After the last identity fragment only:
<ul><li>The last 40
2010-08-11 21:55:21 +00:00
bytes contain the <a href="common_structures_spec.html#type_Signature">DSA signature</a> of the critical exchanged
2010-07-28 01:13:15 +00:00
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>
2010-08-16 01:55:25 +00:00
</li></ul>
2010-07-28 01:13:15 +00:00
</ul></td></tr>
<tr><td align="right" valign="top"><b>Key used:</b></td>
<td>sessionKey</td></tr>
</table>
<pre>
2010-08-11 21:55:21 +00:00
<b>Fragment 0 through F-2</b>
2010-07-28 01:13:15 +00:00
+----+----+----+----+----+----+----+----+
|info| cursize | |
+----+----+----+ |
| fragment of Alice's full |
2010-08-11 21:55:21 +00:00
| Router Identity |
2010-07-28 01:13:15 +00:00
. . .
| |
+----+----+----+----+----+----+----+----+
2010-08-16 01:55:25 +00:00
| arbitrary amount of uninterpreted |
| data |
+----+----+----+----+----+----+----+----+
2010-07-28 01:13:15 +00:00
2010-08-11 21:55:21 +00:00
<b>Fragment F-1:</b>
2010-07-28 01:13:15 +00:00
+----+----+----+----+----+----+----+----+
|info| cursize | |
+----+----+----+ |
2010-08-11 21:55:21 +00:00
| last fragment of Alice's full |
| Router Identity |
2010-07-28 01:13:15 +00:00
. . .
| |
+----+----+----+----+----+----+----+----+
| signed on time | |
+----+----+----+----+ |
| arbitrary amount of uninterpreted |
2010-08-16 01:55:25 +00:00
| data, to 40 bytes prior to |
2010-07-28 01:13:15 +00:00
| end of the current packet |
+----+----+----+----+----+----+----+----+
| DSA signature |
2010-08-11 21:55:21 +00:00
+ +
2010-07-28 01:13:15 +00:00
| |
2010-08-11 21:55:21 +00:00
+ +
2010-07-28 01:13:15 +00:00
| |
2010-08-11 21:55:21 +00:00
+ +
2010-07-28 01:13:15 +00:00
| |
2010-08-11 21:55:21 +00:00
+ +
2010-07-28 01:13:15 +00:00
| |
+----+----+----+----+----+----+----+----+
</pre>
2010-08-11 21:55:21 +00:00
<p>
Typical size including header, in current implementation: 480 bytes
</p>
<h4>Notes</h4>
<ul><li>
In the current implementation, the maximum fragment size is 512 bytes.
</li><li>
The typical <a href="common_structures_spec.html#struct_RouterIdentity">Router Identity</a>
is 387 bytes, so no fragmentation is usually necessary.
</li><li>
There is no mechanism for requesting or redelivering missing fragments.
</li><li>
2010-08-16 01:55:25 +00:00
The total fragments field F must be set identically in all fragments.
</li><li>
2010-08-11 21:55:21 +00:00
Signed-on time appears to be unused or unverified in the current implementation.
</li></ul>
2010-07-28 06:10:34 +00:00
<h3 id="sessionDestroyed">SessionDestroyed (type 8)</h3>
2010-08-11 21:55:21 +00:00
<p>
2011-07-27 18:44:50 +00:00
The Session Destroyed message was implemented (reception only) in release 0.8.1,
2011-09-14 15:14:11 +00:00
and is never sent. Transmission implemented as of release 0.8.9.
2010-08-11 21:55:21 +00:00
</p>
2010-07-28 01:13:15 +00:00
<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>
2011-09-14 15:14:11 +00:00
<p>
Typical size including header, in current implementation: 48 bytes
</p>
2010-07-28 06:10:34 +00:00
<h3 id="relayRequest">RelayRequest (type 3)</h3>
2010-08-11 21:55:21 +00:00
<p>
This is the first message sent from Alice to Bob to request an introduction to Charlie.
</p>
2010-07-28 01:13:15 +00:00
<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>
2011-09-14 15:14:11 +00:00
<li>4 byte relay (introduction) tag, nonzero</li>
2010-07-28 01:13:15 +00:00
<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>
2010-08-11 21:55:21 +00:00
<li>Alice's 32-byte introduction key (so Bob can reply with Charlie's info)</li>
2010-07-30 21:01:19 +00:00
<li>4 byte nonce of Alice's relay request</li>
2010-07-28 01:13:15 +00:00
<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>
+----+----+----+----+----+----+----+----+
2010-08-11 21:55:21 +00:00
| relay tag |size| Alice IP addr
+----+----+----+----+----+--- +----+----|
| Port (A)|size| challenge bytes |
+----+----+----+----+ +
| to be delivered to Charlie |
2010-07-28 01:13:15 +00:00
+----+----+----+----+----+----+----+----+
| Alice's intro key |
2010-08-11 21:55:21 +00:00
+ +
2010-07-28 01:13:15 +00:00
| |
2010-08-11 21:55:21 +00:00
+ +
2010-07-28 01:13:15 +00:00
| |
2010-08-11 21:55:21 +00:00
+ +
2010-07-28 01:13:15 +00:00
| |
+----+----+----+----+----+----+----+----+
| nonce | |
+----+----+----+----+ |
| arbitrary amount of uninterpreted data|
+----+----+----+----+----+----+----+----+
</pre>
2010-08-11 21:55:21 +00:00
<p>
Typical size including header, in current implementation: 96 bytes
</p>
<h4>Notes</h4>
<ul><li>
IP address is always 4 bytes in the current implementation.
</li><li>
Challenge is unimplemented, challenge size is always zero
2010-08-11 21:55:21 +00:00
</li></ul>
2010-07-28 06:10:34 +00:00
<h3 id="relayResponse">RelayResponse (type 4)</h3>
2010-08-11 21:55:21 +00:00
<p>
This is the response to a Relay Request and is sent from Bob to Alice.
</p>
2010-07-28 01:13:15 +00:00
<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>
2010-08-11 21:55:21 +00:00
<li>2 byte Charlie's port number</li>
2010-07-28 01:13:15 +00:00
<li>1 byte IP address size</li>
<li>that many byte representation of Alice's IP address</li>
2010-08-11 21:55:21 +00:00
<li>2 byte Alice's port number</li>
2010-07-28 01:13:15 +00:00
<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>
+----+----+----+----+----+----+----+----+
2010-08-11 21:55:21 +00:00
|size| Charlie IP | Port (C)|size|
2010-07-28 01:13:15 +00:00
+----+----+----+----+----+----+----+----+
2010-08-11 21:55:21 +00:00
| Alice IP | Port (A)| nonce
2010-07-28 01:13:15 +00:00
+----+----+----+----+----+----+----+----+
2010-08-11 21:55:21 +00:00
| arbitrary amount of |
+----+----+ |
| uninterpreted data |
2010-07-28 01:13:15 +00:00
+----+----+----+----+----+----+----+----+
</pre>
2010-08-11 21:55:21 +00:00
<p>
Typical size including header, in current implementation: 64 bytes
</p>
<h4>Notes</h4>
IP address is always 4 bytes in the current implementation.
2010-07-28 06:10:34 +00:00
<h3 id="relayIntro">RelayIntro (type 5)</h3>
2010-08-11 21:55:21 +00:00
<p>
This is the introduction for Alice, which is sent from Bob to Charlie.
</p>
2010-07-28 01:13:15 +00:00
<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>
+----+----+----+----+----+----+----+----+
2010-08-11 21:55:21 +00:00
|size| Alice IP | Port (A)|size|
2010-07-28 01:13:15 +00:00
+----+----+----+----+----+----+----+----+
2010-08-11 21:55:21 +00:00
| that many bytes of challenge |
+ |
| data relayed from Alice |
2010-07-28 01:13:15 +00:00
+----+----+----+----+----+----+----+----+
| arbitrary amount of uninterpreted data|
+----+----+----+----+----+----+----+----+
</pre>
2010-08-11 21:55:21 +00:00
<p>
Typical size including header, in current implementation: 48 bytes
</p>
<h4>Notes</h4>
<ul><li>
IP address is always 4 bytes in the current implementation.
</li><li>
Challenge is unimplemented, challenge size is always zero
2010-08-11 21:55:21 +00:00
</li></ul>
2010-07-28 06:10:34 +00:00
<h3 id="data">Data (type 6)</h3>
2010-08-11 21:55:21 +00:00
<p>
This message is used for data transport and acknowledgment.
2010-08-11 21:55:21 +00:00
</p>
2010-07-28 01:13:15 +00:00
<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>
2010-08-11 21:55:21 +00:00
Bit order: 76543210 (bit 7 is MSB)
bit 7: explicit ACKs included
bit 6: ACK bitfields included
bit 5: reserved
bit 4: explicit congestion notification (ECN)
bit 3: request previous ACKs
bit 2: want reply
bit 1: extended data included (unused, never set)
bit 0: reserved</pre></li>
2010-07-28 01:13:15 +00:00
<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
2010-08-11 21:55:21 +00:00
Bit order: 76543210 (bit 7 is MSB)
bit 7: 1 (further bitfield bytes follow)
bit 6: 1 (fragment 0 received)
bit 5: 0 (fragment 1 not received)
bit 4: 1 (fragment 2 received)
bit 3: 0 (fragment 3 not received)
bit 2: 0 (fragment 4 not received)
bit 1: 1 (fragment 5 received)
bit 0: 0 (fragment 6 not received)
2010-07-28 01:13:15 +00:00
byte 1
2010-08-11 21:55:21 +00:00
Bit order: 76543210 (bit 7 is MSB)
bit 7: 0 (no further bitfield bytes)
bit 6: 0 (fragment 7 not received)
bit 5: 0 (fragment 8 not received)
bit 4: 1 (fragment 9 received)
bit 3: 0 (fragment 10 not received)
bit 2: 0 (fragment 11 not received)
2010-07-28 01:13:15 +00:00
bit 1: 0 (fragment 12 not received)
2010-08-11 21:55:21 +00:00
bit 0: 0 (fragment 13 not received)</pre></li>
2010-07-28 01:13:15 +00:00
</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>
2010-08-11 21:55:21 +00:00
<li>If nonzero, that many message fragments. Each fragment contains:<ul>
2010-07-28 01:13:15 +00:00
<li>4 byte messageId</li>
<li>3 byte fragment info:<pre>
2010-08-11 21:55:21 +00:00
Bit order: 76543210 (bit 7 is MSB)
bits 23-17: fragment # 0 - 127
bit 16: isLast (1 = true)
bits 15-14: unused
bits 13-0: fragment size 0 - 16383</pre></li>
2010-07-28 01:13:15 +00:00
<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>
2010-08-11 21:55:21 +00:00
<h4>Notes</h4>
<ul><li>
IP address is always 4 bytes in the current implementation.
</li><li>
If the number of fragments is zero, this is an ack-only or keepalive message.
</li><li>
The ECN feature is unimplemented, and the bit is never set.
</li><li>
The want reply bit is always set in the current implementation.
</li><li>
Extended data is unimplemented and never present.
</li><li>
The current implementation does not pack multiple fragments into a single packet;
the number of fragments is always 0 or 1.
</li></ul>
2010-07-28 06:10:34 +00:00
<h3 id="peerTest">PeerTest (type 7)</h3>
2010-08-11 21:55:21 +00:00
<p>
See <a href="udp.html#peerTesting">the UDP overview page</a> for details.
</p>
2010-07-28 01:13:15 +00:00
<table border="1">
<tr><td align="right" valign="top"><b>Peer:</b></td>
2010-08-11 21:55:21 +00:00
<td>Any</td></tr>
2010-07-28 01:13:15 +00:00
<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>
2010-08-11 21:55:21 +00:00
<li>2 byte Alice's port number</li>
<li>Alice's 32-byte introduction key</li>
2010-07-28 01:13:15 +00:00
<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>
+----+----+----+----+----+----+----+----+
2010-08-11 21:55:21 +00:00
| test nonce |size| Alice IP addr
+----+----+----+----+----+----+----+----+
| 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 |
|----+----+----+ |
2010-07-28 01:13:15 +00:00
| uninterpreted data |
+----+----+----+----+----+----+----+----+
</pre>
2010-08-11 21:55:21 +00:00
<p>
Typical size including header, in current implementation: 80 bytes
</p>
<h4>Notes</h4>
IP address is always 4 bytes in the current implementation.
<h3 id="holePunch">HolePunch</h3>
<p>
A HolePunch is simply a UDP packet with no data.
It is unauthenticated and unencrypted.
It does not contain a SSU header, so it does not have a message type number.
It is sent from Charlie to Alice as a part of the Introduction sequence.
</p>
<h2><a name="sampleDatagrams">Sample datagrams</a></h2>
<b>Minimal data message (no fragments, no ACKs, no NACKs, etc)</b><br />
<i>(Size: 39 bytes)</i>
<pre>
+----+----+----+----+----+----+----+----+
| MAC |
+ +
| |
+----+----+----+----+----+----+----+----+
| IV |
+ +
| |
+----+----+----+----+----+----+----+----+
|flag| time |flag|#frg| |
+----+----+----+----+----+----+----+ |
| padding to fit a full AES256 block |
+----+----+----+----+----+----+----+----+
</pre>
<b>Minimal data message with payload</b><br />
<i>(Size: 46+fragmentSize bytes)</i>
<pre>
+----+----+----+----+----+----+----+----+
| MAC |
+ +
| |
+----+----+----+----+----+----+----+----+
| IV |
+ +
| |
+----+----+----+----+----+----+----+----+
|flag| time |flag|#frg|
+----+----+----+----+----+----+----+----+
messageId | frag info | |
+----+----+----+----+----+----+ |
| that many bytes of fragment data |
. . .
| |
+----+----+----+----+----+----+----+----+
</pre>
2010-07-28 01:13:15 +00:00
{% endblock %}