2008-02-01 19:13:27 +00:00
|
|
|
{% extends "_layout.html" %}
|
2010-07-28 01:13:15 +00:00
|
|
|
{% block title %}SSU Transport{% endblock %}
|
2008-02-01 19:13:27 +00:00
|
|
|
{% block content %}
|
|
|
|
|
2010-07-28 01:13:15 +00:00
|
|
|
Updated July 2010 for release 0.8
|
|
|
|
|
2008-02-01 19:13:27 +00:00
|
|
|
<h1>Secure Semireliable UDP (SSU)</h1>
|
2008-02-04 16:51:34 +00:00
|
|
|
<p>
|
2009-05-12 19:20:08 +00:00
|
|
|
SSU (also called "UDP" in much of the I2P documentation and user interfaces)
|
2010-07-28 01:13:15 +00:00
|
|
|
is one of two <a href="transport.html">transports</a> currently implemented in I2P.
|
2009-05-12 19:20:08 +00:00
|
|
|
The other is <a href="ntcp.html">NTCP</a>.
|
|
|
|
</p><p>
|
2010-07-28 01:13:15 +00:00
|
|
|
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.
|
2008-02-01 19:13:27 +00:00
|
|
|
|
|
|
|
|
2010-07-28 01:13:15 +00:00
|
|
|
<h2>SSU Services</h2>
|
2008-02-01 19:13:27 +00:00
|
|
|
|
2010-07-28 01:13:15 +00:00
|
|
|
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:
|
2008-02-01 19:13:27 +00:00
|
|
|
|
2010-07-28 01:13:15 +00:00
|
|
|
<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>
|
2008-02-01 19:13:27 +00:00
|
|
|
|
|
|
|
|
2010-07-28 01:13:15 +00:00
|
|
|
<h1>Protocol Details</h1>
|
2008-02-01 19:13:27 +00:00
|
|
|
|
|
|
|
<h2><a name="congestioncontrol">Congestion control</a></h2>
|
|
|
|
|
|
|
|
<p>SSU's need for only semireliable delivery, TCP-friendly operation,
|
|
|
|
and the capacity for high throughput allows a great deal of latitude in
|
|
|
|
congestion control. The congestion control algorithm outlined below is
|
|
|
|
meant to be both efficient in bandwidth as well as simple to implement.</p>
|
|
|
|
|
|
|
|
<p>Packets are scheduled according to the the router's policy, taking care
|
|
|
|
not to exceed the router's outbound capacity or to exceed the measured
|
|
|
|
capacity of the remote peer. The measured capacity should operate along the
|
|
|
|
lines of TCP's slow start and congestion avoidance, with additive increases
|
|
|
|
to the sending capacity and multiplicative decreases in face of congestion.
|
|
|
|
Veering away from TCP, however, routers may give up on some messages after
|
|
|
|
a given period or number of retransmissions while continuing to transmit
|
|
|
|
other messages.</p>
|
|
|
|
|
|
|
|
<p>The congestion detection techniques vary from TCP as well, since each
|
|
|
|
message has its own unique and nonsequential identifier, and each message
|
|
|
|
has a limited size - at most, 32KB. To efficiently transmit this feedback
|
|
|
|
to the sender, the receiver periodically includes a list of fully ACKed
|
|
|
|
message identifiers and may also include bitfields for partially received
|
|
|
|
messages, where each bit represents the reception of a fragment. If
|
|
|
|
duplicate fragments arrive, the message should be ACKed again, or if the
|
|
|
|
message has still not been fully received, the bitfield should be
|
|
|
|
retransmitted with any new updates.</p>
|
|
|
|
|
|
|
|
<p>The simplest possible implementation does not need to pad the packets to
|
|
|
|
any particular size, but instead just places a single message fragment into
|
|
|
|
a packet and sends it off (careful not to exceed the MTU). A more efficient
|
|
|
|
strategy would be to bundle multiple message fragments into the same packet,
|
|
|
|
so long as it doesn't exceed the MTU, but this is not necessary. Eventually,
|
|
|
|
a set of fixed packet sizes may be appropriate to further hide the data
|
|
|
|
fragmentation to external adversaries, but the tunnel, garlic, and end to
|
|
|
|
end padding should be sufficient for most needs until then.</p>
|
|
|
|
|
2009-05-12 19:20:08 +00:00
|
|
|
<h3><a name="mtu">MTU</a></h3>
|
|
|
|
<p>
|
|
|
|
The current implementation uses two MTU values: 608 and 1350.
|
|
|
|
</p><p>
|
|
|
|
596 gives us 588 IP byes, 568 UDP bytes, and with an SSU data message,
|
|
|
|
522 fragment bytes, which is enough to send a tunnel data message in 2
|
|
|
|
packets. A tunnel data message sent over the wire is 1044 bytes, meaning
|
|
|
|
we need 522 fragment bytes to fit it in 2 packets - add 46 for SSU, 20
|
|
|
|
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
|
2010-07-28 01:13:15 +00:00
|
|
|
(larger I2NP messages may be up to 1900 to 4500 bytes, which isn't going to fit
|
2009-05-12 19:20:08 +00:00
|
|
|
into a live network MTU anyway).
|
|
|
|
</p>
|
|
|
|
|
|
|
|
<h3><ajname="max">Message Size Limits</a></h3>
|
|
|
|
<p>
|
|
|
|
While a statement above claims that the maximum message size is 32KB, the practical
|
|
|
|
limit differs. The protocol limits the number of fragments to 7 bits, or 128.
|
|
|
|
The current implementation, however, limits each message to a maximum of 64 fragments,
|
|
|
|
which is sufficient for 64 * 534 = 33.3 KB.
|
|
|
|
Due to overhead for bundled leasesets and session keys, the practical limit
|
|
|
|
at the application level is about 6KB lower, or about 26KB.
|
|
|
|
Further work is necessary to raise the UDP transport limit above 32KB.
|
|
|
|
|
2008-02-01 19:13:27 +00:00
|
|
|
<h2><a name="keys">Keys</a></h2>
|
|
|
|
|
|
|
|
<p>All encryption used is AES256/CBC with 32 byte keys and 16 byte IVs.
|
|
|
|
The MAC and session keys are negotiated as part of the DH exchange, used
|
|
|
|
for the HMAC and encryption, respectively. Prior to the DH exchange,
|
|
|
|
the publicly knowable introKey is used for the MAC and encryption.</p>
|
|
|
|
|
|
|
|
<p>When using the introKey, both the initial message and any subsequent
|
|
|
|
reply use the introKey of the responder (Bob) - the responder does
|
|
|
|
not need to know the introKey of the requestor (Alice). The DSA
|
|
|
|
signing key used by Bob should already be known to Alice when she
|
|
|
|
contacts him, though Alice's DSA key may not already be known by
|
|
|
|
Bob.</p>
|
|
|
|
|
2009-05-24 22:58:30 +00:00
|
|
|
<p>Upon receiving a message, the receiver checks the "from" IP address and port
|
2010-01-02 02:47:28 +00:00
|
|
|
with all established sessions - if there are matches,
|
2009-05-24 22:58:30 +00:00
|
|
|
that session's MAC keys are tested in the HMAC. If none
|
2008-02-01 19:13:27 +00:00
|
|
|
of those verify or if there are no matching IP addresses, the
|
|
|
|
receiver tries their introKey in the MAC. If that does not verify,
|
|
|
|
the packet is dropped. If it does verify, it is interpreted
|
|
|
|
according to the message type, though if the receiver is overloaded,
|
|
|
|
it may be dropped anyway.</p>
|
|
|
|
|
|
|
|
<p>If Alice and Bob have an established session, but Alice loses the
|
|
|
|
keys for some reason and she wants to contact Bob, she may at any
|
|
|
|
time simply establish a new session through the SessionRequest and
|
|
|
|
related messages. If Bob has lost the key but Alice does not know
|
|
|
|
that, she will first attempt to prod him to reply, by sending a
|
|
|
|
DataMessage with the wantReply flag set, and if Bob continually
|
|
|
|
fails to reply, she will assume the key is lost and reestablish a
|
|
|
|
new one.</p>
|
|
|
|
|
|
|
|
<p>For the DH key agreement,
|
|
|
|
<a href="http://www.faqs.org/rfcs/rfc3526.html">RFC3526</a> 2048bit
|
|
|
|
MODP group (#14) is used:</p>
|
|
|
|
<pre>
|
|
|
|
p = 2^2048 - 2^1984 - 1 + 2^64 * { [2^1918 pi] + 124476 }
|
|
|
|
g = 2
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
<p>The DSA p, q, and g are shared according to the scope of the
|
|
|
|
identity which created them.</p>
|
|
|
|
|
|
|
|
<h2><a name="replay">Replay prevention</a></h2>
|
|
|
|
|
|
|
|
<p>Replay prevention at the SSU layer occurs by rejecting packets
|
|
|
|
with exceedingly old timestamps or those which reuse an IV. To
|
|
|
|
detect duplicate IVs, a sequence of Bloom filters are employed to
|
|
|
|
"decay" periodically so that only recently added IVs are detected.</p>
|
|
|
|
|
|
|
|
<p>The messageIds used in DataMessages are defined at layers above
|
|
|
|
the SSU transport and are passed through transparently. These IDs
|
|
|
|
are not in any particular order - in fact, they are likely to be
|
|
|
|
entirely random. The SSU layer makes no attempt at messageId
|
|
|
|
replay prevention - higher layers should take that into account.</p>
|
|
|
|
|
|
|
|
<h2><a name="introduction">Introduction</a></h2>
|
|
|
|
|
|
|
|
<p>Indirect session establishment by means of a third party introduction
|
|
|
|
is necessary for efficient NAT traversal. Charlie, a router behind a
|
|
|
|
NAT or firewall which does not allow unsolicited inbound UDP packets,
|
|
|
|
first contacts a few peers, choosing some to serve as introducers. Each
|
|
|
|
of these peers (Bob, Bill, Betty, etc) provide Charlie with an introduction
|
|
|
|
tag - a 4 byte random number - which he then makes available to the public
|
|
|
|
as methods of contacting him. Alice, a router who has Charlie's published
|
|
|
|
contact methods, first sends a RelayRequest packet to one or more of the
|
|
|
|
introducers, asking each to introduce her to Charlie (offering the
|
|
|
|
introduction tag to identify Charlie). Bob then forwards a RelayIntro
|
|
|
|
packet to Charlie including Alice's public IP and port number, then sends
|
|
|
|
Alice back a RelayResponse packet containing Charlie's public IP and port
|
|
|
|
number. When Charlie receives the RelayIntro packet, he sends off a small
|
|
|
|
random packet to Alice's IP and port (poking a hole in his NAT/firewall),
|
|
|
|
and when Alice receive's Bob's RelayResponse packet, she begins a new
|
|
|
|
full direction session establishment with the specified IP and port.</p>
|
|
|
|
|
|
|
|
<!--
|
|
|
|
should Bob wait for Charlie to ack the RelayIntro packet to avoid
|
|
|
|
situations where that packet is lost yet Alice gets Charlie's IP with
|
|
|
|
Charlie not yet punching a hole in his NAT for her to get through?
|
|
|
|
Perhaps Alice should send to multiple Bobs at once, hoping that at
|
|
|
|
least one of them gets through
|
|
|
|
-->
|
|
|
|
|
|
|
|
<h2><a name="peerTesting">Peer testing</a></h2>
|
|
|
|
|
|
|
|
<p>The automation of collaborative reachability testing for peers is
|
|
|
|
enabled by a sequence of PeerTest messages. With its proper
|
|
|
|
execution, a peer will be able to determine their own reachability
|
|
|
|
and may update its behavior accordingly. The testing process is
|
|
|
|
quite simple:</p>
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
Alice Bob Charlie
|
|
|
|
PeerTest ------------------->
|
|
|
|
PeerTest-------------------->
|
|
|
|
<-------------------PeerTest
|
|
|
|
<-------------------PeerTest
|
|
|
|
<------------------------------------------PeerTest
|
|
|
|
PeerTest------------------------------------------>
|
|
|
|
<------------------------------------------PeerTest
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
<p>Each of the PeerTest messages carry a nonce identifying the
|
|
|
|
test series itself, as initialized by Alice. If Alice doesn't
|
|
|
|
get a particular message that she expects, she will retransmit
|
|
|
|
accordingly, and based upon the data received or the messages
|
|
|
|
missing, she will know her reachability. The various end states
|
|
|
|
that may be reached are as follows:</p>
|
|
|
|
|
|
|
|
<ul>
|
|
|
|
<li>If she doesn't receive a response from Bob, she will retransmit
|
|
|
|
up to a certain number of times, but if no response ever arrives,
|
|
|
|
she will know that her firewall or NAT is somehow misconfigured,
|
|
|
|
rejecting all inbound UDP packets even in direct response to an
|
|
|
|
outbound packet. Alternately, Bob may be down or unable to get
|
|
|
|
Charlie to reply.</li>
|
|
|
|
|
|
|
|
<li>If Alice doesn't receive a PeerTest message with the
|
|
|
|
expected nonce from a third party (Charlie), she will retransmit
|
|
|
|
her initial request to Bob up to a certain number of times, even
|
|
|
|
if she has received Bob's reply already. If Charlie's first message
|
|
|
|
still doesn't get through but Bob's does, she knows that she is
|
|
|
|
behind a NAT or firewall that is rejecting unsolicited connection
|
|
|
|
attempts and that port forwarding is not operating properly (the
|
|
|
|
IP and port that Bob offered up should be forwarded).</li>
|
|
|
|
|
|
|
|
<li>If Alice receives Bob's PeerTest message and both of Charlie's
|
|
|
|
PeerTest messages but the enclosed IP and port numbers in Bob's
|
|
|
|
and Charlie's second messages don't match, she knows that she is
|
|
|
|
behind a symmetric NAT, rewriting all of her outbound packets with
|
|
|
|
different 'from' ports for each peer contacted. She will need to
|
|
|
|
explicitly forward a port and always have that port exposed for
|
|
|
|
remote connectivity, ignoring further port discovery.</li>
|
|
|
|
|
|
|
|
<li>If Alice receives Charlie's first message but not his second,
|
|
|
|
she will retransmit her PeerTest message to Charlie up to a
|
|
|
|
certain number of times, but if no response is received she knows
|
|
|
|
that Charlie is either confused or no longer online.</li>
|
|
|
|
</ul>
|
|
|
|
|
|
|
|
<p>Alice should choose Bob arbitrarily from known peers who seem
|
|
|
|
to be capable of participating in peer tests. Bob in turn should
|
|
|
|
choose Charlie arbitrarily from peers that he knows who seem to be
|
|
|
|
capable of participating in peer tests and who are on a different
|
|
|
|
IP from both Bob and Alice. If the first error condition occurs
|
|
|
|
(Alice doesn't get PeerTest messages from Bob), Alice may decide
|
|
|
|
to designate a new peer as Bob and try again with a different nonce.</p>
|
|
|
|
|
|
|
|
<p>Alice's introduction key is included in all of the PeerTest
|
|
|
|
messages so that she doesn't need to already have an established
|
|
|
|
session with Bob and so that Charlie can contact her without knowing
|
|
|
|
any additional information. Alice may go on to establish a session
|
|
|
|
with either Bob or Charlie, but it is not required.</p>
|
|
|
|
|
|
|
|
<h2><a name="messageSequences">Message sequences</a></h2>
|
|
|
|
|
|
|
|
<h3><a name="establishDirect">Connection establishment (direct)</a></h3>
|
|
|
|
|
2010-07-28 01:13:15 +00:00
|
|
|
Alice connects directly to Bob.
|
|
|
|
|
2008-02-01 19:13:27 +00:00
|
|
|
<pre>
|
|
|
|
Alice Bob
|
|
|
|
SessionRequest--------------------->
|
|
|
|
<---------------------SessionCreated
|
|
|
|
SessionConfirmed------------------->
|
|
|
|
SessionConfirmed------------------->
|
|
|
|
SessionConfirmed------------------->
|
|
|
|
SessionConfirmed------------------->
|
|
|
|
<--------------------------Data
|
|
|
|
</pre>
|
|
|
|
|
2010-07-28 01:13:15 +00:00
|
|
|
<h3><a name="establishIndirect">Connection establishment (indirect using an introducer)</a></h3>
|
|
|
|
|
|
|
|
Alice first connects to introducer Bob, who relays the request to Charlie.
|
2008-02-01 19:13:27 +00:00
|
|
|
|
|
|
|
<pre>
|
|
|
|
Alice Bob Charlie
|
|
|
|
RelayRequest ---------------------->
|
|
|
|
<--------------RelayResponse RelayIntro----------->
|
|
|
|
<--------------------------------------------Data (ignored)
|
|
|
|
SessionRequest-------------------------------------------->
|
|
|
|
<--------------------------------------------SessionCreated
|
|
|
|
SessionConfirmed------------------------------------------>
|
|
|
|
SessionConfirmed------------------------------------------>
|
|
|
|
SessionConfirmed------------------------------------------>
|
|
|
|
SessionConfirmed------------------------------------------>
|
|
|
|
<---------------------------------------------------Data
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
<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>
|
|
|
|
|
|
|
|
<h2><a name="capabilities">Peer capabilities</a></h2>
|
|
|
|
|
|
|
|
<dl>
|
|
|
|
<dt>B</dt>
|
|
|
|
<dd>If the peer address contains the 'B' capability, that means
|
|
|
|
they are willing and able to participate in peer tests as
|
|
|
|
a 'Bob' or 'Charlie'.</dd>
|
|
|
|
<dt>C</dt>
|
|
|
|
<dd>If the peer address contains the 'C' capability, that means
|
|
|
|
they are willing and able to serve as an introducer - serving
|
|
|
|
as a Bob for an otherwise unreachable Alice.</dd>
|
|
|
|
</dl>
|
|
|
|
|
2010-07-28 01:13:15 +00:00
|
|
|
<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>.
|
|
|
|
|
|
|
|
|
2008-02-01 19:13:27 +00:00
|
|
|
{% endblock %}
|