- Big rewrite of how_peerselection

- Split up tunnel-alt to new discussion and spec pages
- Major enhancement to tunnel message spec
- Some additions and update to tunnel discussion
- Some tunnel-alt work, needs lots more
- how_netdb LS store fixup
This commit is contained in:
zzz
2010-07-30 19:30:31 +00:00
parent 76a9052cff
commit 12d23e36f1
5 changed files with 862 additions and 382 deletions

View File

@ -331,14 +331,15 @@
</p>
<p>
A router publishes its own RouterInfo by directly connecting to a floodfill router
and sending it a <a href="i2np.html">I2NP</a> DatabaseStoreMessage
with a nonzero Reply Token. The message is not end-to-end garlic encrypted,
as this is a direct connection, so there are no intervening routers
(and no need to hide this data anyway).
A router publishes a local LeaseSet by
sending a <a href="i2np.html">I2NP</a> DatabaseStoreMessage
with a nonzero Reply Token over an outbound client tunnel for that Destination.
The message is end-to-end garlic encrypted using the Destination's Session Key Manager,
to hide the message from the tunnel's outbound endpoint.
The floodfill router replies with a
<a href="i2np.html">I2NP</a> DeliveryStatusMessage,
with the Message ID set to the value of the Reply Token.
This message is sent back to one of the client's inbound tunnels.
</p>

View File

@ -1,28 +1,61 @@
{% extends "_layout.html" %}
{% block title %}How Peer Selection and Profiling Work{% endblock %}
{% block content %}<p>Peer selection within I2P is simply the process of choosing which routers
on the network we want our messages to go through (which peers will we
{% block title %}Peer Profiling and Selection{% endblock %}
{% block content %}
Updated July 2010 for release 0.8
<h2>Overview</h2>
<h3>Peer Profiling</h3>
<p><b>Peer profiling</b> is the process of collecting data based on the <b>observed</b> performance
of other routers or peers, and classifying those peers into groups.
Profling does <b>not</b> use any claimed performance data published by the peer itself
in the <a href="how_networkdatabase.html">network database</a>.
<p>
Profiles are used for two purposes:
<ol>
<li>Selecting peers to relay our traffic through, which is discussed below
<li>Choosing peers from the set of floodfill routers to use for network database storage and queries,
which is discussed on the <a href="how_networkdatabase.html">network database</a> page
</ol>
<h3>Peer Selection</h3>
<p><b>Peer selection</b> is the process of choosing which routers
on the network we want to relay our messages to go through (which peers will we
ask to join our tunnels). To accomplish this, we keep track of how each
peer performs (the peer's "profile") and use that data to estimate how
fast they are, how often they will be able to accept our requests, and
whether they seem to be overloaded or otherwise unable to perform what
they agree to reliably.</p>
<p>
Claimed bandwidth is untrusted and is <b>only</b> used to avoid those peers
Unlike some other anonymous networks, in I2P,
claimed bandwidth is untrusted and is <b>only</b> used to avoid those peers
advertising very low bandwidth insufficient for routing tunnels.
All peer selection is done through profiling.
This makes
This prevents simple attacks based on peers claiming high bandwidth
in order to capture large numbers of tunnels.
It also makes
<a href="how_threatmodel.html#timing">timing attacks</a>
more difficult.
</p>
<p>
Peer selection is done quite frequently, as a router may maintain a large number
of client and exploratory tunnels, and a tunnel lifetime is only 10 minutes.
<h3>Further Information</h3>
<p>
For more information see the paper
<a href="/_static/pdf/I2P-PET-CON-2009.1.pdf">Peer Profiling and Selection in the I2P Anonymous Network</a>
presented at
<a href="http://www.pet-con.org/index.php/PET_Convention_2009.1">PET-CON 2009.1</a>.
See <a href="#notes">below</a> for notes on minor changes since the paper was published.
</p>
<h2>Peer profiles</h2>
<h2>Profiles</h2>
<p>Each peer has a set of data points collected about them, including statistics
about how long it takes for them to reply to a network database query, how
@ -32,25 +65,17 @@ when the last communication error occurred. The specific data points gathered
can be found in the <a href="http://docs.i2p2.de/router/net/i2p/router/peermanager/PeerProfile.html">code</a>
</p>
<p>Currently, there is no 'ejection' strategy to get rid of the profiles for
peers that are no longer active (or when the network consists of thousands
of peers, to get rid of peers that are performing poorly). However, the size
of each profile is fairly small, and is unrelated to how much data is
collected about the peer, so that a router can keep a few thousand active
peer profiles before the overhead becomes a serious concern. Once it becomes necessary,
we can simply compact the poorly performing profiles (keeping only the most
basic data) and maintain hundreds of thousands of profiles in memory. Beyond
that size, we can simply eject the peers (e.g. keeping the best 100,000).</p>
<p>
The actual in-memory size of a peer profile should be analyzed,
and unused portions should be removed.
This is a good topic for further research and optimization.
Profiles are fairly small, a few KB. To control memory usage, the profile expiration time
lessens as the number of profiles grows.
Profiles are kept in memory until router shutdown, when they are written to disk.
At startup, the profiles are read so the router need not reinitialize all profiles,
thus allowing a router to quickly re-integrate into the network after startup.
</p>
<h2>Peer summaries</h2>
<h2>Peer Summaries</h2>
<p>While the profiles themselves can be considered a summary of a peer's
performance, to allow for effective peer selection we break each summary down
@ -59,113 +84,176 @@ integrated into the network it is, and whether it is failing.</p>
<h3>Speed</h3>
<p>The speed calculation (as implemented
<a href="http://docs.i2p2.de/router/net/i2p/router/peermanager/SpeedCalculator.html">here</a>)
<p>The speed calculation
simply goes through the profile and estimates how much data we can
send or receive on a single tunnel through the peer in a minute. For this estimate it just looks at past
performance.
</p><p>
Previous algorithms used a longer time,
weighing more recent data more heavily, and extrapolating it for the future.
Another previous calculation used total (rather than per-tunnel) bandwidth,
but it was decided that this method overrated slow, high-capacity peers
(that is, slow in bandwidth but high-capacity in number of tunnels).
Even earlier methods were much more complex.
</p><p>
The current speed calculation has remained unchanged since early 2006,
and it is a topic for further study to verify its effectiveness
on today's network.
send or receive on a single tunnel through the peer in a minute. For this estimate it just looks at
performance in the previous minute.
</p>
<h3>Capacity</h3>
<p>The capacity calculation (as implemented
<a href="http://docs.i2p2.de/router/net/i2p/router/peermanager/CapacityCalculator.html">here</a>)
simply goes through the profile and estimates how many tunnels we think the peer
would agree to participate in over the next hour. For this estimate it looks at
how many the peer has agreed to lately, how many the peer rejected, and how many
of the agreed to tunnels failed, and extrapolates the data. In addition, it
includes a 'growth factor' (when the peer isn't failing or rejecting requests) so
that we will keep trying to push their limits.
<p>The capacity calculation
simply goes through the profile and estimates how many tunnels the peer
would agree to participate in over a given time period. For this estimate it looks at
how many tunnel build requests
the peer has accepted, rejected, and dropped, and how many
of the agreed-to tunnels later failed.
While the calculation is time-weighted so that recent activity counts more than later activity,
statistics up to 48 hours old may be included.
</p><p>
The tunnel-failure part of the calculation was disabled for
a long period, but it was reinstated for release 0.6.2,
as it became apparent that recognizing and avoiding unreliable and unreachable
Recognizing and avoiding unreliable and unreachable
peers is critically important.
Unfortunately, as the tunnel tests require the participation of several peers,
it is difficult to positively identify the cause of a failure.
The recent changes assign a probability of failure to each of the
Unfortunately, as the tunnel building and testing require the participation of several peers,
it is difficult to positively identify the cause of a dropped build request or test failure.
The router assigns a probability of failure to each of the
peers, and uses that probability in the capacity calculation.
These recent changes may require additional adjustment,
and are a topic for further study to verify their effectiveness
on today's network.
Drops and test failures are weighted much higher than rejections.
</p>
<h3>Integration</h3>
<p>The integration calculation (as implemented
<a href="http://docs.i2p2.de/router/net/i2p/router/peermanager/IntegrationCalculator.html">here</a>)
is important only for the network database (and in turn, only when trying to focus
the 'exploration' of the network to detect and heal splits). At the moment it is
not used for anything though, as the detection code is not necessary for generally
well connected networks. In any case, the calculation itself simply tracks how many
times the peer is able to tell us about a peer we didn't know (or updated data for
a peer we did know).</p>
<p>
In upcoming releases, the integration calculation will be used, combined with
other measurements of a peer's connectivity and reliability, to determine
suitability for use as a floodfill router in the <a href="how_networkdatabase.html">network database</a>.
By determining whether a peer is actually a useful floodfill router
(rather than just claiming to be), intelligent decisions can be made about
whether to send database queries and stores to that peer.
Also, high-capacity non-floodfill routers can analyze the number of
floodfill peers in the network and join the floodfill router pool if
insufficient floodfill peers are present,
thus eliminating a major weakness in today's floodfill scheme.
</p>
<h3>Failing</h3>
<p>The failing calculation (as implemented
<a href="http://docs.i2p2.de/router/net/i2p/router/peermanager/IsFailingCalculator.html">here</a>)
keeps track of a few data points and determines whether the peer is overloaded
or is unable to honor its agreements. When a peer is marked as failing, it will
be avoided whenever possible.</p>
<h2>Peer organization</h2>
<p>As mentioned above, we drill through each peer's profile to come up with a
few key calculations, and based upon those, we organize each peer into five
groups - fast, capable, well integrated, not failing, and failing. When the
router wants to build a tunnel, it looks for fast peers, while when it wants
to test peers it simply chooses capable ones. Within each of these groups
however, the peer selected is random so that we balance the load (and risk)
across peers as well as to prevent some simple attacks.</p>
few key calculations, and based upon those, we organize each peer into three
groups - fast, high capacity, and standard.
<p>The groupings are not mutually exclusive, nor are they unrelated: <ul>
<li>A peer is active if we have sent or received a message from the peer in the
last few minutes</li>
<li>A peer is considered "high capacity" if its capacity calculation meets or
exceeds the median of all active peers. </li>
exceeds the median of all peers. </li>
<li>A peer is considered "fast" if they are already "high capacity" and their
speed calculation meets or exceeds the median of all "high capacity" peers.</li>
<li>A peer is considered "well integrated" if its integration calculation meets
or exceeds the mean value of active peers.</li>
<li>A peer is considered "failing" if the failing calculation returns true.</li>
<li>A peer is considered "not failing" if it is not "high capacity" or "failing"</li>
speed calculation meets or exceeds the median of all peers.</li>
<li>A peer is considered "standard" if it is not "high capacity"</li>
</ul>
These groupings are implemented in the <a
href="http://docs.i2p2.de/router/net/i2p/router/peermanager/ProfileOrganizer.html">ProfileOrganizer</a>'s
reorganize() method (using the calculateThresholds() and locked_placeProfile() methods in turn).</p>
These groupings are implemented in the router's <a
href="http://docs.i2p2.de/router/net/i2p/router/peermanager/ProfileOrganizer.html">ProfileOrganizer</a>.
<h2>To Do</h2>
<h3>Group size limits</h3>
The size of the groups may be limited.
<ul>
<li>The fast group is limited to 30 peers.
If there would be more, only the ones with the highest speed rating are placed in the group.
<li>The high capacity group is limited to 75 peers (including the fast group)
If there would be more, only the ones with the highest capactiy rating are placed in the group.
<li>The standard group has no fixed limit, but is somewhat smaller than the number of RouterInfos
stored in the local network database.
On an active router in today's network, there may be about 1000 RouterInfos and 500 peer profiles
(including those in the fast and high capacity groups)
</ul>
<h2>Recalculation and Stability</h2>
Summaries are recalculated, and peers are resorted into groups, every 45 seconds.
<p>
As described above, each of the calculations is critical to peer selection and
requires review to determine the effectiveness in today's network.
Also, the size of in-memory profiles must be studied,
unused portions removed, and an ejection strategy implemented.
The groups tend to be fairly stable, that is, there is not much "churn" in the rankings
at each recalculation.
Peers in the fast and high capacity groups get more tunnels build through them, which increases their speed and capacity ratings,
which reinforces their presence in the group.
<h2>Peer Selection</h2>
The router selects peers from the above groups to build tunnels through.
<h3>Peer Selection for Client Tunnels</h3>
Client tunnels are used for application traffic, such as for HTTP proxies and web servers.
<p>
To reduce the susceptibililty to <a href="http://blog.torproject.org/blog/one-cell-enough">some attacks</a>,
and increase performance,
peers for building client tunnels are chosen randomly from the smallest group, which is the "fast" group.
There is no bias toward selecting peers that were previously participants in a tunnel for the same client.
<h3>Peer Selection for Exploratory Tunnels</h3>
Exploratory tunnels are used for router administrative purposes, such as network database traffic
and testing client tunnels.
Exploratory tunnels are also used to contact previously unconnected routers, which is why
they are called "exploratory".
These tunnels are usually low-bandwidth.
<p>
Peers for building exploratory tunnels are generally chosen randomly from the standard group.
If the success rate of these build attempts is low compared to the client tunnel build success rate,
the router will select a weighted average of peers randomly from the high capacity group instead.
This helps maintain a satisfactory build success rate even when network performace is poor.
There is no bias toward selecting peers that were previously participants in an exploratory tunnel.
<p>
As the standard group includes a very large subset of all peers the router knows about,
exploratory tunnels are essentially built through a random selection of all peers,
until the build success rate becomes too low.
<h3>Restrictions</h3>
To prevent some simple attacks, and for performance, there are the following restrictions:
<ul>
<li>
Two peers from the same /16 IP space may not be in the same tunnel.
<li>
A peer may participate in a maximum of 33% of all tunnels created by the router.
<li>
Peers with extremely low bandwidth are not used.
<li>
Peers for which a recent connection attempt failed are not used.
</ul>
<h3>Peer Ordering in Tunnels</h3>
Peers are ordered within tunnels to
to deal with the <a href="http://prisms.cs.umass.edu/brian/pubs/wright-tissec.pdf">predecessor
attack</a> <a href="http://prisms.cs.umass.edu/brian/pubs/wright.tissec.2008.pdf">(2008
update)</a>.
More information is on the <a href="tunnel-alt.html#ordering">tunnel page</a>.
<h2>Future Work</h2>
<ul>
<li>
Continue to analyze an tune speed and capacity calculations as necessary
<li>
Implement a more aggressive ejection strategy if necessary to control memory usage as the network grows
<li>
Evaluate group size limits
<li>
Use GeoIP data to include or exclude certain peers, if configured
</ul>
<h2 id="notes">Notes</h2>
For those reading the paper
<a href="/_static/pdf/I2P-PET-CON-2009.1.pdf">Peer Profiling and Selection in the I2P Anonymous Network</a>,
please keep in mind the following minor changes in I2P since the paper's publication:
<ul>
<li>The Integration calculation is still not used
<li>In the paper, "groups" are called "tiers"
<li>The "Failing" tier is no longer used
<li>The "Not Failing" tier is now named "Standard"
</ul>
<h2>References</h2>
<ul>
<li>
<a href="/_static/pdf/I2P-PET-CON-2009.1.pdf">Peer Profiling and Selection in the I2P Anonymous Network</a>
<li>
<a href="http://blog.torproject.org/blog/one-cell-enough">One Cell Enough</a>
<li>
<a href="https://wiki.torproject.org/noreply/TheOnionRouter/TorFAQ#EntryGuards">Tor Entry Guards</a>
<li>
<a href="http://freehaven.net/anonbib/#murdoch-pet2007">Murdoch 2007 Paper</a>
<li>
<a href="http://www.crhc.uiuc.edu/~nikita/papers/tuneup-cr.pdf">Tune-up for Tor</a>
<li>
<a href="http://systems.cs.colorado.edu/~bauerk/papers/wpes25-bauer.pdf">Low-resource Routing Attacks Against Tor</a>
</ul>
{% endblock %}

View File

@ -2,35 +2,9 @@
{% block title %}Tunnel Implementation{% endblock %}
{% block content %}
<b>Note: This documents the current tunnel build implementation as of release 0.6.1.10.</b>
<br>
<pre>
1) <a href="#tunnel.overview">Tunnel overview</a>
2) <a href="#tunnel.operation">Tunnel operation</a>
2.1) <a href="#tunnel.preprocessing">Message preprocessing</a>
2.2) <a href="#tunnel.gateway">Gateway processing</a>
2.3) <a href="#tunnel.participant">Participant processing</a>
2.4) <a href="#tunnel.endpoint">Endpoint processing</a>
2.5) <a href="#tunnel.padding">Padding</a>
2.6) <a href="#tunnel.fragmentation">Tunnel fragmentation</a>
2.7) <a href="#tunnel.alternatives">Alternatives</a>
2.7.1) <a href="#tunnel.reroute">Adjust tunnel processing midstream</a>
2.7.2) <a href="#tunnel.bidirectional">Use bidirectional tunnels</a>
2.7.3) <a href="#tunnel.backchannel">Backchannel communication</a>
2.7.4) <a href="#tunnel.variablesize">Variable size tunnel messages</a>
3) <a href="#tunnel.building">Tunnel building</a>
3.1) <a href="#tunnel.peerselection">Peer selection</a>
3.1.1) <a href="#tunnel.selection.exploratory">Exploratory tunnel peer selection</a>
3.1.2) <a href="#tunnel.selection.client">Client tunnel peer selection</a>
3.2) <a href="#tunnel.request">Request delivery</a>
3.3) <a href="#tunnel.pooling">Pooling</a>
3.4) <a href="#tunnel.building.alternatives">Alternatives</a>
3.4.1) <a href="#tunnel.building.telescoping">Telescopic building</a>
3.4.2) <a href="#tunnel.building.nonexploratory">Non-exploratory tunnels for management</a>
4) <a href="#tunnel.throttling">Tunnel throttling</a>
5) <a href="#tunnel.mixing">Mixing/batching</a>
See <a href="tunnel-alt-creation.html">tunnel creation</a> for additional details.
</pre>
This page documents the current tunnel implementation.
Updated July 2010 for release 0.8
<h2>1) <a name="tunnel.overview">Tunnel overview</a></h2>
@ -60,12 +34,6 @@ a tunnel, or even for colluding participants to determine whether they are a
part of the same tunnel at all (barring the situation where colluding peers are
next to each other in the tunnel).</p>
<p>Beyond their length, there are additional configurable parameters
for each tunnel that can be used, such as a throttle on the frequency of
messages delivered, how padding should be used, how long a tunnel should be
in operation, whether to inject chaff messages, and what, if any, batching
strategies should be employed.</p>
<p>In practice, a series of tunnel pools are used for different
purposes - each local client destination has its own set of inbound
tunnels and outbound tunnels, configured to meet its anonymity and
@ -96,84 +64,34 @@ requested.</p>
<p>Tunnel IDs are 4 byte numbers used at each hop - participants know what
tunnel ID to listen for messages with and what tunnel ID they should be forwarded
on as to the next hop, and each hop chooses the tunnel ID which they receive messages
on. Tunnels themselves are short lived (10 minutes at the
moment), and even if subsequent tunnels are built using the same sequence of
on. Tunnels themselves are short-lived (10 minutes).
Even if subsequent tunnels are built using the same sequence of
peers, each hop's tunnel ID will change.</p>
<h3>2.1) <a name="tunnel.preprocessing">Message preprocessing</a></h3>
<p>When the gateway wants to deliver data through the tunnel, it first
gathers zero or more <a href="i2np.html">I2NP</a> messages, selects how much padding will be used,
fragments it across the necessary number of 1KB tunnel messages, and decides how
each I2NP message should be handled by the tunnel endpoint, encoding that
data into the raw tunnel payload:</p>
<p>A tunnel gateway's function is to fragment and pack
<a href="i2np.html">I2NP messages</a> into fixed-size
<a href="tunnel_message_specification.html">tunnel messages</a>
and encrypt the tunnel messages.
Tunnel messages contain the following:
<ul>
<li>The 4 byte Tunnel ID</li>
<li>The 16 byte IV</li>
<li>the first 4 bytes of the SHA256 of (the remaining preprocessed data concatenated
with the IV), using the IV as will be seen on the tunnel endpoint (for
outbound tunnels), or the IV as was seen on the tunnel gateway (for inbound
tunnels) (see below for IV processing).</li>
<li>0 or more bytes containing random nonzero integers</li>
<li>1 byte containing 0x00</li>
<li>a series of zero or more { instructions, message } pairs</li>
<li>A 4 byte Tunnel ID</li>
<li>A 16 byte IV (initialization vector)</li>
<li>A checksum
<li>Padding, if necessary</li>
<li>One or more { delivery instruction, I2NP message fragment} pairs</li>
</ul>
<p>Note that the padding, if any, must be before the instruction/message pairs.
there is no provision for padding at the end.</p>
<p>The instructions are encoded with a single control byte, followed by any
necessary additional information. The first bit in that control byte determines
how the remainder of the header is interpreted - if it is not set, the message
is either not fragmented or this is the first fragment in the message. If it is
set, this is a follow on fragment.</p>
<p>With the first (leftmost or MSB) bit being 0, this is the first or only fragment, and the instructions are:</p>
<ul>
<li>1 byte control byte:<pre>
bit 0: is follow on fragment? (1 = true, 0 = false, must be 0)
bits 1-2: delivery type
(0x0 = LOCAL, 0x01 = TUNNEL, 0x02 = ROUTER)
bit 3: delay included? (1 = true, 0 = false) (unimplemented)
bit 4: fragmented? (1 = true, 0 = false)
bit 5: extended options? (1 = true, 0 = false) (unimplemented)
bits 6-7: reserved</pre></li>
<li>if the delivery type was TUNNEL, a 4 byte tunnel ID</li>
<li>if the delivery type was TUNNEL or ROUTER, a 32 byte router hash</li>
<li>if the delay included flag is true, a 1 byte value (unimplemented):<pre>
bit 0: type (0 = strict, 1 = randomized)
bits 1-7: delay exponent (2^value minutes)</pre></li>
<li>if the fragmented flag is true, a 4 byte message ID</li>
<li>if the extended options flag is true (unimplemented):<pre>
= a 1 byte option size (in bytes)
= that many bytes</pre></li>
<li>2 byte size of the I2NP message or this fragment</li>
</ul>
<p>If the first bit being 1, this is a follow-on fragment, and the instructions are:</p>
<ul>
<li>1 byte control byte:<pre>
bit 0: is follow on fragment? (1 = true, 0 = false, must be 1)
bits 1-6: fragment number
bit 7: is last? (1 = true, 0 = false)</pre></li>
<li>4 byte message ID (same one defined in the first fragment)</li>
<li>2 byte size of this fragment</li>
</ul>
<p>The I2NP message is encoded in its standard form, and the
preprocessed payload must be padded to a multiple of 16 bytes.
The total size, including the tunnel ID and IV, is 1028 bytes.
</p>
<p>
While the maximum payload size is nominally 64KB, the size is further constrained by the
method of fragmenting I2NP messages into multiple 1KB tunnel messages.
The maximum number of fragments is 64, and the message may not be perfectly aligned,
so the message must nominally fit in 63 fragments, and be padded to a 16 byte boundary.
Therefore the maximum size is 960 + (62 * 986) - 12 = 62080 bytes, or approximately 60.6KB.
</p>
<h3>2.2) <a name="tunnel.gateway">Gateway processing</a></h3>
Details are in the
<a href="tunnel_message_specification.html">tunnel message specification</a>.
<h3>2.2) <a name="tunnel.gateway">Gateway Processing</a></h3>
<p>After the preprocessing of messages into a padded payload, the gateway builds
a random 16 byte IV value, iteratively encrypting it and the tunnel message as
@ -188,7 +106,7 @@ data with the IV and layer keys for all hops in the tunnel. The result of the o
tunnel encryption is that when each peer encrypts it, the endpoint will recover
the initial preprocessed data.</p>
<h3>2.3) <a name="tunnel.participant">Participant processing</a></h3>
<h3>2.3) <a name="tunnel.participant">Participant Processing</a></h3>
<p>When a peer receives a tunnel message, it checks that the message came from
the same previous hop as before (initialized when the first message comes through
@ -211,7 +129,7 @@ false positive. The unique value fed into the Bloom filter is the XOR of the IV
and the first block so as to prevent nonsequential colluding peers in the tunnel
from tagging a message by resending it with the IV and first block switched.</p>
<h3>2.4) <a name="tunnel.endpoint">Endpoint processing</a></h3>
<h3>2.4) <a name="tunnel.endpoint">Endpoint Processing</a></h3>
<p>After receiving and validating a tunnel message at the last hop in the tunnel,
how the endpoint recovers the data encoded by the gateway depends upon whether
@ -225,18 +143,6 @@ layer and IV keys of each step in reverse order.</p>
which it may then parse out into the included I2NP messages and forwards them as
requested in their delivery instructions.</p>
<h3>2.5) <a name="tunnel.padding">Padding</a></h3>
<p>Several tunnel padding strategies are possible, each with their own merits:</p>
<ul>
<li>No padding</li>
<li>Padding to a random size</li>
<li>Padding to a fixed size</li>
<li>Padding to the closest KB</li>
<li>Padding to the closest exponential size (2^n bytes)</li>
</ul>
<p>These padding strategies can be used on a variety of levels, addressing the
exposure of message size information to different adversaries. After gathering
and reviewing some <a href="http://dev.i2p.net/~jrandom/messageSizes/">statistics</a>
@ -245,7 +151,7 @@ with a fixed tunnel message size of 1024 bytes. Within this however, the fragme
messages themselves are not padded by the tunnel at all (though for end to end
messages, they may be padded as part of the garlic wrapping).</p>
<h3>2.6) <a name="tunnel.fragmentation">Tunnel fragmentation</a></h3>
<h3>2.6) <a name="tunnel.fragmentation">Tunnel Fragmentation</a></h3>
<p>To prevent adversaries from tagging the messages along the path by adjusting
the message size, all tunnel messages are a fixed 1024 bytes in size. To accommodate
@ -254,100 +160,8 @@ gateway splits up the larger I2NP messages into fragments contained within each
tunnel message. The endpoint will attempt to rebuild the I2NP message from the
fragments for a short period of time, but will discard them as necessary.</p>
<p>Routers have a lot of leeway as to how the fragments are arranged, whether
they are stuffed inefficiently as discrete units, batched for a brief period to
fit more payload into the 1024 byte tunnel messages, or opportunistically padded
with other messages that the gateway wanted to send out.</p>
<h3>2.7) <a name="tunnel.alternatives">Alternatives</a></h3>
<h4>2.7.1) <a name="tunnel.reroute">Adjust tunnel processing midstream</a></h4>
<p>While the simple tunnel routing algorithm should be sufficient for most cases,
there are three alternatives that can be explored:</p>
<ul>
<li>Have a peer other than the endpoint temporarily act as the termination
point for a tunnel by adjusting the encryption used at the gateway to give them
the plaintext of the preprocessed I2NP messages. Each peer could check to see
whether they had the plaintext, processing the message when received as if they
did.</li>
<li>Allow routers participating in a tunnel to remix the message before
forwarding it on - bouncing it through one of that peer's own outbound tunnels,
bearing instructions for delivery to the next hop.</li>
<li>Implement code for the tunnel creator to redefine a peer's "next hop" in
the tunnel, allowing further dynamic redirection.</li>
</ul>
<h4>2.7.2) <a name="tunnel.bidirectional">Use bidirectional tunnels</a></h4>
<p>The current strategy of using two separate tunnels for inbound and outbound
communication is not the only technique available, and it does have anonymity
implications. On the positive side, by using separate tunnels it lessens the
traffic data exposed for analysis to participants in a tunnel - for instance,
peers in an outbound tunnel from a web browser would only see the traffic of
an HTTP GET, while the peers in an inbound tunnel would see the payload
delivered along the tunnel. With bidirectional tunnels, all participants would
have access to the fact that e.g. 1KB was sent in one direction, then 100KB
in the other. On the negative side, using unidirectional tunnels means that
there are two sets of peers which need to be profiled and accounted for, and
additional care must be taken to address the increased speed of predecessor
attacks. The tunnel pooling and building process outlined below should
minimize the worries of the predecessor attack, though if it were desired,
it wouldn't be much trouble to build both the inbound and outbound tunnels
along the same peers.</p>
<h4>2.7.3) <a name="tunnel.backchannel">Backchannel communication</a></h4>
<p>At the moment, the IV values used are random values. However, it is
possible for that 16 byte value to be used to send control messages from the
gateway to the endpoint, or on outbound tunnels, from the gateway to any of the
peers. The inbound gateway could encode certain values in the IV once, which
the endpoint would be able to recover (since it knows the endpoint is also the
creator). For outbound tunnels, the creator could deliver certain values to the
participants during the tunnel creation (e.g. "if you see 0x0 as the IV, that
means X", "0x1 means Y", etc). Since the gateway on the outbound tunnel is also
the creator, they can build a IV so that any of the peers will receive the
correct value. The tunnel creator could even give the inbound tunnel gateway
a series of IV values which that gateway could use to communicate with
individual participants exactly one time (though this would have issues regarding
collusion detection)</p>
<p>This technique could later be used deliver message mid stream, or to allow the
inbound gateway to tell the endpoint that it is being DoS'ed or otherwise soon
to fail. At the moment, there are no plans to exploit this backchannel.</p>
<h4>2.7.4) <a name="tunnel.variablesize">Variable size tunnel messages</a></h4>
<p>While the transport layer may have its own fixed or variable message size,
using its own fragmentation, the tunnel layer may instead use variable size
tunnel messages. The difference is an issue of threat models - a fixed size
at the transport layer helps reduce the information exposed to external
adversaries (though overall flow analysis still works), but for internal
adversaries (aka tunnel participants) the message size is exposed. Fixed size
tunnel messages help reduce the information exposed to tunnel participants, but
does not hide the information exposed to tunnel endpoints and gateways. Fixed
size end to end messages hide the information exposed to all peers in the
network.</p>
<p>As always, its a question of who I2P is trying to protect against. Variable
sized tunnel messages are dangerous, as they allow participants to use the
message size itself as a backchannel to other participants - e.g. if you see a
1337 byte message, you're on the same tunnel as another colluding peer. Even
with a fixed set of allowable sizes (1024, 2048, 4096, etc), that backchannel
still exists as peers could use the frequency of each size as the carrier (e.g.
two 1024 byte messages followed by an 8192). Smaller messages do incur the
overhead of the headers (IV, tunnel ID, hash portion, etc), but larger fixed size
messages either increase latency (due to batching) or dramatically increase
overhead (due to padding). Fragmentation helps amortize the overhead, at the
cost of potential message loss due to lost fragments.</p>
<p>Timing attacks are also relevant when reviewing the effectiveness of fixed
size messages, though they require a substantial view of network activity
patterns to be effective. Excessive artificial delays in the tunnel will be
detected by the tunnel's creator, due to periodic testing, causing that entire
tunnel to be scrapped and the profiles for peers within it to be adjusted.</p>
<h2>3) <a name="tunnel.building">Tunnel building</a></h2>
<h2><a name="tunnel.building">Tunnel Building</a></h2>
<p>When building a tunnel, the creator must send a request with the necessary
configuration data to each of the hops and wait for all of them to agree before
@ -358,14 +172,14 @@ reply. There are three important dimensions to keep in mind when producing
the tunnels: what peers are used (and where), how the requests are sent (and
replies received), and how they are maintained.</p>
<h3>3.1) <a name="tunnel.peerselection">Peer selection</a></h3>
<h3>3.1) <a name="tunnel.peerselection">Peer Selection</a></h3>
<p>Beyond the two types of tunnels - inbound and outbound - there are two styles
of peer selection used for different tunnels - exploratory and client.
Exploratory tunnels are used for both network database maintenance and tunnel
maintenance, while client tunnels are used for end to end client messages. </p>
<h4>3.1.1) <a name="tunnel.selection.exploratory">Exploratory tunnel peer selection</a></h4>
<h4><a name="tunnel.selection.exploratory">Exploratory tunnel peer selection</a></h4>
<p>Exploratory tunnels are built out of a random selection of peers from a subset
of the network. The particular subset varies on the local router and on what their
@ -375,7 +189,12 @@ category. The secondary purpose of the tunnels, beyond merely tunnel routing,
is to find underutilized high capacity peers so that they can be promoted for
use in client tunnels.</p>
<h4>3.1.2) <a name="tunnel.selection.client">Client tunnel peer selection</a></h4>
<p>
Exporatory peer selection is disucssed further on the
<a href="how_peerselection.html">Peer Profiling and Selection page</a>.
<h4><a name="tunnel.selection.client">Client tunnel peer selection</a></h4>
<p>Client tunnels are built with a more stringent set of requirements - the local
router will select peers out of its "fast and high capacity" profile category so
@ -383,86 +202,101 @@ that performance and reliability will meet the needs of the client application.
However, there are several important details beyond that basic selection that
should be adhered to, depending upon the client's anonymity needs.</p>
<p>For some clients who are worried about adversaries mounting a predecessor
attack, the tunnel selection can keep the peers selected in a strict order -
if A, B, and C are in a tunnel, the hop after A is always B, and the hop after
B is always C. A less strict ordering is also possible, assuring that while
the hop after A may be B, B may never be before A. Other configuration options
include the ability for just the inbound tunnel gateways and outbound tunnel
endpoints to be fixed, or rotated on an MTBF rate.</p>
<p>
Client peer selection is disucssed further on the
<a href="how_peerselection.html">Peer Profiling and Selection page</a>.
<h4><a name="ordering">Peer Ordering within Tunnels</a></h4>
Peers are ordered within tunnels to
to deal with the <a href="http://prisms.cs.umass.edu/brian/pubs/wright-tissec.pdf">predecessor
attack</a> <a href="http://prisms.cs.umass.edu/brian/pubs/wright.tissec.2008.pdf">(2008
update)</a>.
<p>To frustrate the predecgessor
attack, the tunnel selection keeps the peers selected in a strict order -
if A, B, and C are in a tunnel for a particular tunnel pool, the hop after A is always B, and the hop after
B is always C.
<p>Ordering is implemented by generating a random 32-byte key for each
tunnel pool at startup.
Peers should not be able to guess the ordering, or an attacker could
craft two router hashes far apart to maximize the chance of being at both
ends of a tunnel.
Peers are sorted by XOR distance of the
SHA256 Hash of (the peer's hash concatenated with the random key) from the random key
<pre>
p = peer hash
k = random key
d = XOR(H(p+k), k)
</pre>
<p>Because each tunnel pool uses a different random key, ordering is consistent
within a single pool but not between different pools.
New keys are generated at each router restart.
<p>In the initial implementation, only random ordering was implemented,
though strict ordering will be implemented in 0.6.1.33. Later, we may implement
controls for the user to select which strategy to use for individual clients.</p>
<h3>3.2) <a name="tunnel.request">Request delivery</a></h3>
<p>A new tunnel request preparation, delivery, and response method has been
<a href="tunnel-alt-creation.html">devised</a>, which reduces the number of
<p>
A multi-hop tunnel is built using a single build message which is repeatedly
decrypted and forwarded.
In the terminology of
<a href="http://www-users.cs.umn.edu/~hopper/hashing_it_out.pdf">Hashing it out in Public</a>,
this is "non-interactive" telescopic tunnel building.
<p>This tunnel request preparation, delivery, and response method is
<a href="tunnel-alt-creation.html">designed</a> to reduce the number of
predecessors exposed, cuts the number of messages transmitted, verifies proper
connectivity, and avoids the message counting attack of traditional telescopic
tunnel creation. The old technique is listed below as an <a
href="#tunnel.building.exploratory">alternative</a>.</p>
tunnel creation.
(This method, which sends messages to extend a tunnel through the already-established
part of the tunnel, is termed "interactive" telescopic tunnel building in
the "Hashing it out" paper.)
<p>The details of tunnel request and response messages, and their encryption,
<a href="tunnel-alt-creation.html">are specified here</a>.
<p>Peers may reject tunnel creation requests for a variety of reasons, though
a series of four increasingly severe rejections are known: probabilistic rejection
(due to approaching the router's capacity, or in response to a flood of requests),
transient overload, bandwidth overload, and critical failure. When received,
those four are interpreted by the tunnel creator to help adjust their profile of
the router in question.</p>
the router in question.
<p>
For more information on peer profiling, see the
<a href="how_peerselection.html">Peer Profiling and Selection page</a>.
<h3>3.3) <a name="tunnel.pooling">Pooling</a></h3>
<h3>3.3) <a name="tunnel.pooling">Tunnel Pools</a></h3>
<p>To allow efficient operation, the router maintains a series of tunnel pools,
each managing a group of tunnels used for a specific purpose with their own
configuration. When a tunnel is needed for that purpose, the router selects one
out of the appropriate pool at random. Overall, there are two exploratory tunnel
pools - one inbound and one outbound - each using the router's exploration
defaults. In addition, there is a pair of pools for each local destination -
one inbound and one outbound tunnel. Those pools use the configuration specified
when the local destination connected to the router, or the router's defaults if
pools - one inbound and one outbound - each using the router's default configuration.
In addition, there is a pair of pools for each local destination -
one inbound and one outbound tunnel pool. Those pools use the configuration specified
when the local destination connects to the router via <a href="i2cp.html">I2CP</a>, or the router's defaults if
not specified.</p>
<p>Each pool has within its configuration a few key settings, defining how many
tunnels to keep active, how many backup tunnels to maintain in case of failure,
<strike>how frequently to test the tunnels</strike>, how long the tunnels should be, whether those
lengths should be randomized, <strike>how often replacement tunnels should be built</strike>, as
well as any of the other settings allowed when configuring individual tunnels.</p>
how long the tunnels should be, whether those
lengths should be randomized, as
well as any of the other settings allowed when configuring individual tunnels.
Configuration options are specified on the <a href="i2cp.html">I2CP page</a>.
<h3>3.4) <a name="tunnel.building.alternatives">Alternatives</a></h3>
<h3 id="length">Default Tunnel Lengths</h3>
<h4>3.4.1) <a name="tunnel.building.telescoping">Telescopic building</a></h4>
TODO
<p>One question that may arise regarding the use of the exploratory tunnels for
sending and receiving tunnel creation messages is how that impacts the tunnel's
vulnerability to predecessor attacks. While the endpoints and gateways of
those tunnels will be randomly distributed across the network (perhaps even
including the tunnel creator in that set), another alternative is to use the
tunnel pathways themselves to pass along the request and response, as is done
in <a href="http://www.torproject.org/">TOR</a>. This, however, may lead to leaks
during tunnel creation, allowing peers to discover how many hops there are later
on in the tunnel by monitoring the timing or <a
href="http://dev.i2p.net/pipermail/2005-October/001057.html">packet count</a> as
the tunnel is built.</p>
<h3 id="strategy">Anticipatory Build Strategy and Priority</h3>
<h4>3.4.2) <a name="tunnel.building.nonexploratory">Non-exploratory tunnels for management</a></h4>
TODO - Parallelism, priority, success time tracking, pool differences
<p>A second alternative to the tunnel building process is to give the router
an additional set of non-exploratory inbound and outbound pools, using those for
the tunnel request and response. Assuming the router has a well integrated view
of the network, this should not be necessary, but if the router was partitioned
in some way, using non-exploratory pools for tunnel management would reduce the
leakage of information about what peers are in the router's partition.</p>
<h2><a name="tunnel.throttling">Tunnel Message Throttling</a></h2>
<h4>3.4.3) <a name="tunnel.building.exploratory">Exploratory request delivery</a></h4>
<p>A third alternative, used until I2P 0.6.1.10, garlic encrypts individual tunnel
request messages and delivers them to the hops individually, transmitting them
through exploratory tunnels with their reply coming back in a separate
exploratory tunnel. This strategy has been dropped in favor of the one outlined
above.</p>
<h2>4) <a name="tunnel.throttling">Tunnel throttling</a></h2>
TODO: Document current strategies, priority, and WRED
<p>Even though the tunnels within I2P bear a resemblance to a circuit switched
network, everything within I2P is strictly message based - tunnels are merely
@ -478,13 +312,14 @@ capacity and utilization. On the other hand, each router can simply drop
messages that are beyond its capacity, exploiting the research used on the
normal Internet.</p>
<h2>5) <a name="tunnel.mixing">Mixing/batching</a></h2>
<p>What strategies should be used at the gateway and at each hop for delaying,
<h2><a name="future">Future Work</a></h3>
<h3><a name="tunnel.mixing">Mixing/batching</a></h3>
<p>What strategies could be used at the gateway and at each hop for delaying,
reordering, rerouting, or padding messages? To what extent should this be done
automatically, how much should be configured as a per tunnel or per hop setting,
and how should the tunnel's creator (and in turn, user) control this operation?
All of this is left as unknown, to be worked out for
<a href="http://www.i2p.net/roadmap#3.0">I2P 3.0</a></p>
All of this is left as unknown, to be worked out for a distant future release.
{% endblock %}

View File

@ -0,0 +1,245 @@
{% extends "_layout.html" %}
{% block title %}Tunnel Discussion{% endblock %}
{% block content %}
Note: This document contains older information about alternatives to the
current tunnel implementation in I2P,
and speculation on future possibilities. For current information see
<a href="tunnel-alt.html">the tunnel page</a>.
<p>
That page documents the current tunnel build implementation as of release 0.6.1.10.
The older tunnel build method, used prior to release 0.6.1.10, is documented on
<a href="tunnel.html">the old tunnel page</a>.
<h3 id="config">Configuration Alternatives</h3>
<p>Beyond their length, there may be additional configurable parameters
for each tunnel that can be used, such as a throttle on the frequency of
messages delivered, how padding should be used, how long a tunnel should be
in operation, whether to inject chaff messages, and what, if any, batching
strategies should be employed.
None of these are currently implemented.
</p>
<h3><a name="tunnel.padding">Padding Alternatives</a></h3>
<p>Several tunnel padding strategies are possible, each with their own merits:</p>
<ul>
<li>No padding</li>
<li>Padding to a random size</li>
<li>Padding to a fixed size</li>
<li>Padding to the closest KB</li>
<li>Padding to the closest exponential size (2^n bytes)</li>
</ul>
<p>These padding strategies can be used on a variety of levels, addressing the
exposure of message size information to different adversaries. After gathering
and reviewing some <a href="http://dev.i2p.net/~jrandom/messageSizes/">statistics</a>
from the 0.4 network, as well as exploring the anonymity tradeoffs, we're starting
with a fixed tunnel message size of 1024 bytes. Within this however, the fragmented
messages themselves are not padded by the tunnel at all (though for end to end
messages, they may be padded as part of the garlic wrapping).</p>
<h3><a name="tunnel.fragmentation">Fragmentation Alternatives</a></h3>
<p>To prevent adversaries from tagging the messages along the path by adjusting
the message size, all tunnel messages are a fixed 1024 bytes in size. To accommodate
larger I2NP messages as well as to support smaller ones more efficiently, the
gateway splits up the larger I2NP messages into fragments contained within each
tunnel message. The endpoint will attempt to rebuild the I2NP message from the
fragments for a short period of time, but will discard them as necessary.</p>
<p>Routers have a lot of leeway as to how the fragments are arranged, whether
they are stuffed inefficiently as discrete units, batched for a brief period to
fit more payload into the 1024 byte tunnel messages, or opportunistically padded
with other messages that the gateway wanted to send out.</p>
<h3><a name="tunnel.alternatives">More Alternatives</a></h3>
<h4><a name="tunnel.reroute">Adjust tunnel processing midstream</a></h4>
<p>While the simple tunnel routing algorithm should be sufficient for most cases,
there are three alternatives that can be explored:</p>
<ul>
<li>Have a peer other than the endpoint temporarily act as the termination
point for a tunnel by adjusting the encryption used at the gateway to give them
the plaintext of the preprocessed I2NP messages. Each peer could check to see
whether they had the plaintext, processing the message when received as if they
did.</li>
<li>Allow routers participating in a tunnel to remix the message before
forwarding it on - bouncing it through one of that peer's own outbound tunnels,
bearing instructions for delivery to the next hop.</li>
<li>Implement code for the tunnel creator to redefine a peer's "next hop" in
the tunnel, allowing further dynamic redirection.</li>
</ul>
<h4><a name="tunnel.bidirectional">Use bidirectional tunnels</a></h4>
<p>The current strategy of using two separate tunnels for inbound and outbound
communication is not the only technique available, and it does have anonymity
implications. On the positive side, by using separate tunnels it lessens the
traffic data exposed for analysis to participants in a tunnel - for instance,
peers in an outbound tunnel from a web browser would only see the traffic of
an HTTP GET, while the peers in an inbound tunnel would see the payload
delivered along the tunnel. With bidirectional tunnels, all participants would
have access to the fact that e.g. 1KB was sent in one direction, then 100KB
in the other. On the negative side, using unidirectional tunnels means that
there are two sets of peers which need to be profiled and accounted for, and
additional care must be taken to address the increased speed of predecessor
attacks. The tunnel pooling and building process outlined below should
minimize the worries of the predecessor attack, though if it were desired,
it wouldn't be much trouble to build both the inbound and outbound tunnels
along the same peers.</p>
<h4><a name="tunnel.backchannel">Backchannel communication</a></h4>
<p>At the moment, the IV values used are random values. However, it is
possible for that 16 byte value to be used to send control messages from the
gateway to the endpoint, or on outbound tunnels, from the gateway to any of the
peers. The inbound gateway could encode certain values in the IV once, which
the endpoint would be able to recover (since it knows the endpoint is also the
creator). For outbound tunnels, the creator could deliver certain values to the
participants during the tunnel creation (e.g. "if you see 0x0 as the IV, that
means X", "0x1 means Y", etc). Since the gateway on the outbound tunnel is also
the creator, they can build a IV so that any of the peers will receive the
correct value. The tunnel creator could even give the inbound tunnel gateway
a series of IV values which that gateway could use to communicate with
individual participants exactly one time (though this would have issues regarding
collusion detection)</p>
<p>This technique could later be used deliver message mid stream, or to allow the
inbound gateway to tell the endpoint that it is being DoS'ed or otherwise soon
to fail. At the moment, there are no plans to exploit this backchannel.</p>
<h4><a name="tunnel.variablesize">Variable size tunnel messages</a></h4>
<p>While the transport layer may have its own fixed or variable message size,
using its own fragmentation, the tunnel layer may instead use variable size
tunnel messages. The difference is an issue of threat models - a fixed size
at the transport layer helps reduce the information exposed to external
adversaries (though overall flow analysis still works), but for internal
adversaries (aka tunnel participants) the message size is exposed. Fixed size
tunnel messages help reduce the information exposed to tunnel participants, but
does not hide the information exposed to tunnel endpoints and gateways. Fixed
size end to end messages hide the information exposed to all peers in the
network.</p>
<p>As always, its a question of who I2P is trying to protect against. Variable
sized tunnel messages are dangerous, as they allow participants to use the
message size itself as a backchannel to other participants - e.g. if you see a
1337 byte message, you're on the same tunnel as another colluding peer. Even
with a fixed set of allowable sizes (1024, 2048, 4096, etc), that backchannel
still exists as peers could use the frequency of each size as the carrier (e.g.
two 1024 byte messages followed by an 8192). Smaller messages do incur the
overhead of the headers (IV, tunnel ID, hash portion, etc), but larger fixed size
messages either increase latency (due to batching) or dramatically increase
overhead (due to padding). Fragmentation helps amortize the overhead, at the
cost of potential message loss due to lost fragments.</p>
<p>Timing attacks are also relevant when reviewing the effectiveness of fixed
size messages, though they require a substantial view of network activity
patterns to be effective. Excessive artificial delays in the tunnel will be
detected by the tunnel's creator, due to periodic testing, causing that entire
tunnel to be scrapped and the profiles for peers within it to be adjusted.</p>
<h3><a name="tunnel.building.alternatives">Alternatives</a></h3>
Reference:
<a href="http://www-users.cs.umn.edu/~hopper/hashing_it_out.pdf">Hashing it out in Public</a>
<h4 id="tunnel.building.old">Old tunnel build method</h4>
The old tunnel build method, used prior to release 0.6.1.10, is documented on
<a href="tunnel.html">the old tunnel page</a>.
This was an "all at once" or "parallel" method,
where messages were sent in parallel to each of the participants.
<h4><a name="tunnel.building.telescoping">One-Shot Telescopic building</a></h4>
NOTE: This is the current method.
<p>One question that arose regarding the use of the exploratory tunnels for
sending and receiving tunnel creation messages is how that impacts the tunnel's
vulnerability to predecessor attacks. While the endpoints and gateways of
those tunnels will be randomly distributed across the network (perhaps even
including the tunnel creator in that set), another alternative is to use the
tunnel pathways themselves to pass along the request and response, as is done
in <a href="http://www.torproject.org/">Tor</a>. This, however, may lead to leaks
during tunnel creation, allowing peers to discover how many hops there are later
on in the tunnel by monitoring the timing or <a
href="http://dev.i2p.net/pipermail/2005-October/001057.html">packet count</a> as
the tunnel is built.</p>
<h4><a name="tunnel.building.telescoping">"Interactive" Telescopic building</a></h4>
Build the hops one at a time with a message through the existing part of the tunnel for each.
Has major issues as the peers can count the messages to determine their location in the tunnel.
<h4><a name="tunnel.building.nonexploratory">Non-exploratory tunnels for management</a></h4>
<p>A second alternative to the tunnel building process is to give the router
an additional set of non-exploratory inbound and outbound pools, using those for
the tunnel request and response. Assuming the router has a well integrated view
of the network, this should not be necessary, but if the router was partitioned
in some way, using non-exploratory pools for tunnel management would reduce the
leakage of information about what peers are in the router's partition.</p>
<h4><a name="tunnel.building.exploratory">Exploratory request delivery</a></h4>
<p>A third alternative, used until I2P 0.6.1.10, garlic encrypts individual tunnel
request messages and delivers them to the hops individually, transmitting them
through exploratory tunnels with their reply coming back in a separate
exploratory tunnel. This strategy has been dropped in favor of the one outlined
above.</p>
<h4 id="history">More History and Discussion</a></h4>
Before the introduction of the Variable Tunnel Build Message,
there were at least two problems:
<ol>
<li>
The size of the messages (caused by an 8-hop maximum, when the typical tunnel length is 2 or 3 hops...
and current research indicates that more than 3 hops does not enhance anonymity);
<li>
The high build failure rate, especially for long (and exploratory) tunnels, since all hops must agree or the tunnel is discarded.
</ol>
The VTBM has fixed #1 and improved #2.
<p>
Welterde has proposed modifications to the parallel method to allow for reconfiguration.
Sponge has proposed using 'tokens' of some sort.
<p>
Any students of tunnel building must study the historical record leading up to the current method,
especially the various anonymity vulnerabilities that may exist in various methods.
The mail archives from October 2005 at <a href="http://zzz.i2p/archives/2005-10/">zzz.i2p</a> or
<a href="http://osdir.com/ml/network.i2p/2005-10/">osdir.com</a> are particularly helpful.
As stated on <a href="tunnel-alt-creation.html">the tunnel creation specification</a>,
the current strategy came about during a discussion on the I2P mailing list between
Michael Rogers, Matthew Toseland (toad), and jrandom regarding the predecessor attack.
See:<a href="http://osdir.com/ml/network.i2p/2005-10/msg00138.html">Summary</a> and
<a href="http://osdir.com/ml/network.i2p/2005-10/msg00129.html">Reasoning</a>.
<p>
The build changes in 0.6.1.10, released February 2006, were the last incompatible change in i2p;
i.e., all releases since 0.6.1.10 are backward compatible. Any tunnel build change would cause a similar 'flag day',
unless we implemented code so that the build originator would only use the new method if all participants
(and build/reply endpoints/gateways) supported it.
<h4><a name="ordering">Peer ordering alternatives</a></h4>
A less strict ordering is also possible, assuring that while
the hop after A may be B, B may never be before A. Other configuration options
include the ability for just the inbound tunnel gateways and outbound tunnel
endpoints to be fixed, or rotated on an MTBF rate.</p>
<h2><a name="tunnel.mixing">Mixing/batching</a></h2>
<p>What strategies should be used at the gateway and at each hop for delaying,
reordering, rerouting, or padding messages? To what extent should this be done
automatically, how much should be configured as a per tunnel or per hop setting,
and how should the tunnel's creator (and in turn, user) control this operation?
All of this is left as unknown, to be worked out for
<a href="http://www.i2p.net/roadmap#3.0">I2P 3.0</a></p>
{% endblock %}

View File

@ -0,0 +1,311 @@
{% extends "_layout.html" %}
{% block title %}Tunnel Message Specification{% endblock %}
{% block content %}
Updated July 2010 for release 0.8
<h1>Tunnel Message Specification</h1>
This document specifies the format of tunnel messages.
For general information about tunnels see
<a href="tunnel-alt.html">the tunnel documentation</a>.
<h2>Message preprocessing</h3>
A <i>tunnel gateway</i> is the entrance, or first hop, of a tunnel.
For an outbound tunnel, the gateway is the creator of the tunnel.
For an inbound tunnel, the gateway is at the opposite end from the creator of the tunnel.
<p>
A gateway <i>preprocesses</i> <a href="i2np.html">I2NP messages</a>
by fragmenting and combining them into tunnel messages.
<p>
While I2NP messages are variable size from 0 to almost 64 KB,
tunnel messages are fixed-size, approximately 1 KB.
Fixed message size
restricts several types of attacks that are possible from
observing message size.
<p>
After the tunnel messages are created, they are encrypted as described in
<a href="tunnel-alt.html">the tunnel documentation</a>.
<h2 id="msg_Data">Tunnel Message (Encrypted)</h2>
These are the contents of a tunnel data message after encryption.
<pre>
{% filter escape %}
+----+----+----+----+----+----+----+----+
| Tunnel ID | IV |
+----+----+----+----+ +
| |
+ +----+----+----+----+
| | |
+----+----+----+----+ +
| |
+ Encrypted Data +
~ ~
| |
+ +-------------------+
| |
+----+----+----+----+
{% endfilter %}
</pre>
<h4>Definition</h4>
<pre>
{% filter escape %}
Tunnel ID:
4 bytes
The ID of the next hop
IV:
16 bytes
The initialization vector
Encrypted Data
1008 bytes
The encrypted tunnel message
Total Size: 1028 Bytes
{% endfilter %}
</pre>
<h2 id="msg_Data">Tunnel Message (Decrypted)</h2>
These are the contents of a tunnel data message when decrypted.
<pre>
{% filter escape %}
+----+----+----+----+----+----+----+----+
| Tunnel ID | IV |
+----+----+----+----+ +
| |
+ +----+----+----+----+
| | Checksum |
+----+----+----+----+----+----+----+----+
| nonzero padding.. |
~ ~
| |
+ +----+
| |zero|
+----+----+----+----+----+----+----+----+
| |
| Delivery Instructions 1 |
~ ~
| |
+----+----+----+----+----+----+----+----+
| |
+ I2NP Message Fragment 1 +
| |
~ ~
| |
+----+----+----+----+----+----+----+----+
| |
| Delivery Instructions 2... |
~ ~
| |
+----+----+----+----+----+----+----+----+
| |
+ I2NP Message Fragment 2... +
| |
~ ~
| |
+ +-------------------+
| |
+----+----+----+----+
{% endfilter %}
</pre>
<h4>Definition</h4>
<pre>
{% filter escape %}
Tunnel ID:
4 bytes
The ID of the next hop
IV:
16 bytes
The initialization vector
Checksum:
4 bytes
The first 4 bytes of the SHA256 hash of the remaining contents of the message concatenated with the IV
Nonzero padding:
0 or more bytes
Random nonzero data for padding
Zero:
1 byte
The value 0x00
Delivery Instructions:
Length varies but is typically 7, 39, 43, or 47 bytes
Indicates the fragment and the routing for the fragment
See <a href="#delivery">below</a> for specification
Message Fragment:
1 to 996 bytes, actual maximum depends on delivery instruction size
A partial or full I2NP Message
Total Size: 1028 Bytes
{% endfilter %}
</pre>
<p>Note that the padding, if any, must be before the instruction/message pairs.
there is no provision for padding at the end.</p>
<h2 id="delivery">Delivery Instructions</h2>
<p>The instructions are encoded with a single control byte, followed by any
necessary additional information. The first bit (MSB) in that control byte determines
how the remainder of the header is interpreted - if it is not set, the message
is either not fragmented or this is the first fragment in the message. If it is
set, this is a follow on fragment.</p>
<h3>First Fragment Delivery Instructions</h3>
<p>If the MSB of the first byte is 0, this is an initial I2NP message fragment,
or a complete I2NP message, and the instructions are:</p>
<pre>
{% filter escape %}
+----+----+----+----+----+----+----+----+
|flag| Tunnel ID (opt) | |
+----+----+----+----+----+ +
| |
+ +
| To Hash (optional) |
+ +
| |
+ +--------------+
| |dly | Msg... |
+----+----+----+----+----+----+----+----+
|..ID(opt)| ext opts... (opt) | size |
+----+----+----+----+----+----+----+----+
{% endfilter %}
</pre>
<h4>Definition</h4>
<pre>
{% filter escape %}
flag:
1 byte
Bit order: 76543210
bit 7: 0 to specify an initial fragment
bits 6-5: delivery type
0x0 = LOCAL, 0x01 = DESTINATION, 0x02 = ROUTER, 0x03 = TUNNEL
bit 4: delay included? Unimplemented, always 0
If 1, a delay byte is included
bit 3: fragmented? If 0, the message is not fragmented, what follows is the entire message
If 1, the message is fragmented, and the instructions contain a Message ID
bit 2: extended options? Unimplemented, always 0
If 1, extended options are included
bits 1-0: reserved
Tunnel ID:
4 bytes
Optional, present if delivery type is TUNNEL
The destination tunnel ID
To Hash:
32 bytes
Optional, present if delivery type is DESTINATION, ROUTER, or TUNNEL
If DESTINATION, the SHA256 Hash of the destination
If ROUTER, the SHA256 Hash of the router
If TUNNEL, the SHA256 Hash of the gatweay router
Delay:
1 bytes
Optional, present if delay included flag is set
Unimplemented, never present; original specification:
bit 7: type (0 = strict, 1 = randomized)
bits 6-0: delay exponent (2^value minutes)
Message ID:
4 bytes
Optional, present if this message is the first of 2 or more fragments
An ID that uniquely identifies all fragments as belonging to a single message
(the current implementation uses the <a href="i2np_spec.html#struct_header">I2NP Message ID</a>)
Extended Options:
2 or more bytes
Optional, present if extend options flag is set
Unimplemented, never present; original specification:
One byte length and then that many bytes
size:
2 bytes
The length of the fragment that follows
Valid values: 1 to approx. 960
Total length: Typical length is 39 bytes for ROUTER / DESTINATION delivery or 43 bytes for TUNNEL delivery (unfragmented);
43 bytes for ROUTER / DESTINATION delivery or 47 bytes for TUNNEL delivery (first fragment)
{% endfilter %}
</pre>
<h3>Follow-on Fragment Delivery Instructions</h3>
<p>If the MSB of the first byte is 1, this is a follow-on fragment, and the instructions are:</p>
<pre>
{% filter escape %}
+----+----+----+----+----+----+----+
|frag| Message ID | size |
+----+----+----+----+----+----+----+
{% endfilter %}
</pre>
<h4>Definition</h4>
<pre>
{% filter escape %}
frag:
1 byte
Binary 1nnnnnnd
The first bit is 1 to indicate this is a follow-on fragment
nnnnnn is the 6 bit fragment number from 1 to 63
d is 1 to indicate the last fragment, 0 otherwise
Message ID:
4 bytes
The same ID specified in the first fragment
size:
2 bytes
The length of the fragment that follows
Valid values: 1 to 996
Total length: 7 bytes
{% endfilter %}
</pre>
<h3><a href="http://docs.i2p2.de/router/net/i2p/data/i2np/DeliveryInstructions.html">Delivery Instructions Javadoc</a></h3>
<h2>Notes</h2>
<h3>I2NP Message Maximum Size</h3>
<p>
While the maximum I2NP message size is nominally 64 KB, the size is further constrained by the
method of fragmenting I2NP messages into multiple 1 KB tunnel messages.
The maximum number of fragments is 64, and the initial fragment may not
be perfectly aligned at the start of a tunnel message.
So the message must nominally fit in 63 fragments.
<p>
The maximum size of an initial fragment is 956 bytes (assuming TUNNEL delivery mode);
the maximum size of a follow-on fragment is 996 bytes.
Therefore the maximum size is approximately 956 + (62 * 996) = 62708 bytes, or 61.2 KB.
</p>
<h3>Ordering, Batching, Packing</h3>
Tunnel messages may be dropped or reordered.
The tunnel gateway, who creates tunnel messages, is free to implement any
batching, mixing, or reordering strategy to fragment I2NP messages and
efficiently pack fragments into tunnel messages.
In general, an optimal packing is not possible (the "packing problem").
The gateways may implement various delay and reordering strategies.
<h3>Cover Traffic</h3>
Tunnel messages may contain only padding (i.e. no delivery instructions or message fragments at all)
for cover traffic. This is unimplemented.
{% endblock %}