forked from I2P_Developers/i2p.www
Drop todo sections that have been completed
This commit is contained in:
@@ -14,27 +14,12 @@ will come up, especially as I2P gets more peer review, but these are the main
|
|||||||
|
|
||||||
<h2>{{ _('Core functionality') }} <span class="permalink"><a href="#core">[{{ _('link') }}]</a></span></h2>
|
<h2>{{ _('Core functionality') }} <span class="permalink"><a href="#core">[{{ _('link') }}]</a></span></h2>
|
||||||
<ul class="targetlist">
|
<ul class="targetlist">
|
||||||
<li><a href="#nat">{% trans -%}
|
|
||||||
NAT/Firewall bridging via 1-hop restricted routes
|
|
||||||
{%- endtrans %}</a></li>
|
|
||||||
<li><a href="#transport">{% trans -%}
|
|
||||||
High degree transport layer with UDP, NBIO, or NIO
|
|
||||||
{%- endtrans %}</a></li>
|
|
||||||
<li><a href="#netdb">{% trans -%}
|
<li><a href="#netdb">{% trans -%}
|
||||||
NetworkDB and profile tuning and ejection policy for large nets
|
NetworkDB and profile tuning and ejection policy for large nets
|
||||||
{%- endtrans %}</a></li>
|
{%- endtrans %}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<h2>{{ _('Security / anonymity') }} <span class="permalink"><a href="#security">[{{ _('link') }}]</a></span></h2>
|
<h2>{{ _('Security / anonymity') }} <span class="permalink"><a href="#security">[{{ _('link') }}]</a></span></h2>
|
||||||
<ul class="targetlist">
|
<ul class="targetlist">
|
||||||
<li><a href="#tunnelId">{% trans -%}
|
|
||||||
Per-hop tunnel id & new permuted TunnelVerificationStructure encryption
|
|
||||||
{%- endtrans %}</a></li>
|
|
||||||
<li><a href="#ordering">{% trans -%}
|
|
||||||
Strict ordering of participants within tunnels
|
|
||||||
{%- endtrans %}</a></li>
|
|
||||||
<li><a href="#tunnelLength">{% trans -%}
|
|
||||||
Randomly permuted tunnel lengths
|
|
||||||
{%- endtrans %}</a></li>
|
|
||||||
<li><a href="#fullRestrictedRoutes">{% trans -%}
|
<li><a href="#fullRestrictedRoutes">{% trans -%}
|
||||||
Full blown n-hop restricted routes with optional trusted links
|
Full blown n-hop restricted routes with optional trusted links
|
||||||
{%- endtrans %}</a></li>
|
{%- endtrans %}</a></li>
|
||||||
@@ -51,167 +36,6 @@ Stop & go mix w/ garlics & tunnels
|
|||||||
<h2>{{ _('Performance') }} <span class="permalink"><a href="{{ site_url('about/performance/future') }}">[{{ _('link') }}]</a></span></h2>
|
<h2>{{ _('Performance') }} <span class="permalink"><a href="{{ site_url('about/performance/future') }}">[{{ _('link') }}]</a></span></h2>
|
||||||
|
|
||||||
<h2 id="core">{{ _('Core functionality') }}</h2>
|
<h2 id="core">{{ _('Core functionality') }}</h2>
|
||||||
<ul class="targetlist">
|
|
||||||
<li>
|
|
||||||
<h3 id="nat">{% trans -%}
|
|
||||||
NAT/Firewall bridging via 1-hop restricted routes
|
|
||||||
{%- endtrans %}</h3>
|
|
||||||
</li>
|
|
||||||
<!-- <li style="list-style: none; display: inline"> -->
|
|
||||||
<b><i>{{ _('Implemented in I2P 0.6.0.6') }}</i></b>
|
|
||||||
<p>{% trans -%}
|
|
||||||
The functionality of allowing routers to fully participate within the network
|
|
||||||
while behind firewalls and NATs that they do not control requires some basic
|
|
||||||
restricted route operation (since those peers will not be able to receive
|
|
||||||
inbound connections). To do this successfully, you consider peers one of
|
|
||||||
two ways:
|
|
||||||
{%- endtrans %}</p>
|
|
||||||
<!-- </li> -->
|
|
||||||
</ul>
|
|
||||||
<ul>
|
|
||||||
<li>{% trans -%}
|
|
||||||
<b>Peers who have reachable interfaces</b> - these peers do not need to
|
|
||||||
do anything special
|
|
||||||
{%- endtrans %}</li>
|
|
||||||
<li>{% trans -%}
|
|
||||||
<b>Peers who do not have reachable interfaces</b> - these peers must build
|
|
||||||
a tunnel pointing at them where the gateway is one of the peers they have
|
|
||||||
established a connection with who has both a publicly reachable interface
|
|
||||||
and who has agreed to serve as their 'introducer'.
|
|
||||||
{%- endtrans %}</li>
|
|
||||||
</ul>
|
|
||||||
<div style="margin-left:25px;">
|
|
||||||
<p>{% trans -%}
|
|
||||||
To do this, peers who have no IP address simply connect to a few peers,
|
|
||||||
build a tunnel through them, and publish a reference to those tunnels within
|
|
||||||
their RouterInfo structure in the network database.
|
|
||||||
{%- endtrans %}</p>
|
|
||||||
<p>{% trans -%}
|
|
||||||
When someone wants to contact any particular router, they first must get
|
|
||||||
its RouterInfo from the network database, which will tell them whether they
|
|
||||||
can connect directly (e.g. the peer has a publicly reachable interface)
|
|
||||||
or whether they need to contact them indirectly. Direct connections occur
|
|
||||||
as normal, while indirect connections are done through one of the published
|
|
||||||
tunnels.
|
|
||||||
{%- endtrans %}</p>
|
|
||||||
<p>{% trans -%}
|
|
||||||
When a router just wants to get a message or two to a specific hidden peer,
|
|
||||||
they can just use the indirect tunnel for sending the payload. However,
|
|
||||||
if the router wants to talk to the hidden peer often (for instance, as part
|
|
||||||
of a tunnel), they will send a garlic routed message through the indirect
|
|
||||||
tunnel to that hidden peer which unwraps to contain a message which should
|
|
||||||
be sent to the originating router. That hidden peer then establishes an
|
|
||||||
outbound connection to the originating router and from then on, those two
|
|
||||||
routers can talk to each other directly over that newly established direct
|
|
||||||
connection.
|
|
||||||
{%- endtrans %}</p>
|
|
||||||
<p>{% trans -%}
|
|
||||||
Of course, that only works if the originating peer can receive connections
|
|
||||||
(they aren't also hidden). However, if the originating peer is hidden, they
|
|
||||||
can simply direct the garlic routed message to come back to the originating
|
|
||||||
peer's inbound tunnel.
|
|
||||||
{%- endtrans %}</p>
|
|
||||||
<p>{% trans -%}
|
|
||||||
This is not meant to provide a way for a peer's IP address to be concealed,
|
|
||||||
merely as a way to let people behind firewalls and NATs fully operate within
|
|
||||||
the network. Concealing the peer's IP address adds a little more work, as
|
|
||||||
described <a href="#fullRestrictedRoutes">below.</a>
|
|
||||||
{%- endtrans %}</p>
|
|
||||||
<p>{% trans -%}
|
|
||||||
With this technique, any router can participate as any part of a tunnel.
|
|
||||||
For efficiency purposes, a hidden peer would be a bad choice for an inbound
|
|
||||||
gateway, and within any given tunnel, two neighboring peers wouldn't want
|
|
||||||
to be hidden. But that is not technically necessary.
|
|
||||||
{%- endtrans %}</p>
|
|
||||||
</div>
|
|
||||||
<ul class="targetlist">
|
|
||||||
<li>
|
|
||||||
<h3 id="transport">{% trans -%}
|
|
||||||
High degree transport layer with UDP, NBIO, or NIO
|
|
||||||
{%- endtrans %}</h3>
|
|
||||||
<b><i>{{ _('Both UDP and NIO have been Implemented in I2P') }}</i></b>
|
|
||||||
<p>{% trans -%}
|
|
||||||
Standard TCP communication in Java generally requires blocking socket
|
|
||||||
calls, and to keep a blocked socket from hanging the entire system, those
|
|
||||||
blocking calls are done on their own threads. Our current TCP transport
|
|
||||||
is implemented in a naive fashion - for each peer we are talking to, we
|
|
||||||
have one thread reading and one thread writing. The reader thread simply
|
|
||||||
loops a bunch of read() calls, building I2NP messages and adding them
|
|
||||||
to our internal inbound message queue, and the writer thread pulls messages
|
|
||||||
off a per-connection outbound message queue and shoves the data through
|
|
||||||
write() calls.
|
|
||||||
{%- endtrans %}</p>
|
|
||||||
<p>{% trans -%}
|
|
||||||
We do this fairly efficiently, from a CPU perspective - at any time,
|
|
||||||
almost all of these threads are sitting idle, blocked waiting for something
|
|
||||||
to do. However, each thread consumes real resources (on older Linux kernels,
|
|
||||||
for instance, each thread would often be implemented as a fork()'ed process).
|
|
||||||
As the network grows, the number of peers each router will want to talk
|
|
||||||
with will increase (remember, I2P is fully connected, meaning that any
|
|
||||||
given peer should know how to get a message to any other peer, and restricted
|
|
||||||
route support will probably not significantly reduce the number of connections
|
|
||||||
necessary). This means that with a 100,000 router network, each router
|
|
||||||
will have up to 199,998 threads just to deal with the TCP connections!
|
|
||||||
{%- endtrans %}</p>
|
|
||||||
<p>{% trans -%}
|
|
||||||
Obviously, that just won't work. We need to use a transport layer that
|
|
||||||
can scale. In Java, we have two main camps:
|
|
||||||
{%- endtrans %}</p>
|
|
||||||
<h4>UDP</h4>
|
|
||||||
<b><i>{% trans ssu=site_url('docs/transport/ssu') -%}
|
|
||||||
Implemented in I2P 0.6 ("SSU") as documented <a href="{{ ssu }}">elsewhere</a>
|
|
||||||
{%- endtrans %}</i></b>
|
|
||||||
<p>{% trans -%}
|
|
||||||
Sending and receiving UDP datagrams is a connectionless operation - if
|
|
||||||
we are communicating with 100,000 peers, we simply stick the UDP packets
|
|
||||||
in a queue and have a single thread pulling them off the queue and shoving
|
|
||||||
them out the pipe (and to receive, have a single thread pulling in any
|
|
||||||
UDP packets received and adding them to an inbound queue).
|
|
||||||
{%- endtrans %}</p>
|
|
||||||
<p>{% trans -%}
|
|
||||||
However, moving to UDP means losing the benefits of TCP's ordering, congestion
|
|
||||||
control, MTU discovery, etc. Implementing that code will take significant
|
|
||||||
work, however I2P doesn't need it to be as strong as TCP. Specifically,
|
|
||||||
a while ago I was taking some measurements in the simulator and on the
|
|
||||||
live net, and the vast majority of messages transferred would fit easily
|
|
||||||
within a single unfragmented UDP packet, and the largest of the messages
|
|
||||||
would fit within 20-30 packets. As mule pointed out, TCP adds a significant
|
|
||||||
overhead when dealing with so many small packets, as the ACKs are within
|
|
||||||
an order of magnitude in size. With UDP, we can optimize the transport
|
|
||||||
for both efficiency and resilience by taking into account I2P's particular
|
|
||||||
needs.
|
|
||||||
{%- endtrans %}</p>
|
|
||||||
<p>{% trans -%}
|
|
||||||
It will be a lot of work though.
|
|
||||||
{%- endtrans %}</p>
|
|
||||||
<h4>{{ _('NIO or NBIO') }}</h4>
|
|
||||||
<b><i>{% trans -%}
|
|
||||||
NIO Implemented in I2P 0.6.1.22 ("NTCP")
|
|
||||||
{%- endtrans %}</i></b>
|
|
||||||
<p>{% trans -%}
|
|
||||||
In Java 1.4, a set of "New I/O" packages was introduced, allowing Java
|
|
||||||
developers to take advantage of the operating system's nonblocking IO
|
|
||||||
capabilities - allowing you to maintain a large number of concurrent IO
|
|
||||||
operations without requiring a separate thread for each. There is much
|
|
||||||
promise with this approach, as we can scalable handle a large number of
|
|
||||||
concurrent connections and we don't have to write a mini-TCP stack with
|
|
||||||
UDP. However, the NIO packages have not proven themselves to be battle-ready,
|
|
||||||
as the Freenet developer's found. In addition, requiring NIO support would
|
|
||||||
mean we can't run on any of the open source JVMs like <a href="http://www.kaffe.org/">Kaffe</a>,
|
|
||||||
as <a href="http://www.classpath.org/">GNU/Classpath</a> has only limited
|
|
||||||
support for NIO. <i>(note: this may not be the case anymore, as there
|
|
||||||
has been some progress on Classpath's NIO, but it is an unknown quantity)</i>
|
|
||||||
{%- endtrans %}</p>
|
|
||||||
<p>{% trans link='http://www.eecs.harvard.edu/~mdw/proj/java-nbio/' -%}
|
|
||||||
Another alternative along the same lines is the <a href="{{ link }}">Non
|
|
||||||
Blocking I/O</a> package - essentially a cleanroom NIO implementation
|
|
||||||
(written before NIO was around). It works by using some native OS code
|
|
||||||
to do the nonblocking IO, passing off events through Java. It seems to
|
|
||||||
be working with Kaffe, though there doesn't seem to be much development
|
|
||||||
activity on it lately (likely due to 1.4's NIO deployment).
|
|
||||||
{%- endtrans %}</p>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<ul class="targetlist">
|
<ul class="targetlist">
|
||||||
<li>
|
<li>
|
||||||
<h3 id="netdb">{% trans -%}
|
<h3 id="netdb">{% trans -%}
|
||||||
@@ -240,118 +64,6 @@ in mind. We will have some work to do, but we can put it off for later.
|
|||||||
</ul>
|
</ul>
|
||||||
<h2 id="security">{{ _('Security / anonymity') }}</h2>
|
<h2 id="security">{{ _('Security / anonymity') }}</h2>
|
||||||
<ul class="targetlist">
|
<ul class="targetlist">
|
||||||
<li>
|
|
||||||
<h3 id="tunnelId">{% trans -%}
|
|
||||||
Per-hop tunnel id & new permuted TunnelVerificationStructure encryption
|
|
||||||
{%- endtrans %}</h3>
|
|
||||||
<b><i>{% trans tunnelimpl=site_url('docs/tunnels/implementation') -%}
|
|
||||||
Addressed in I2P 0.5 as documented <a href="{{ tunnelimpl }}">elsewhere</a>
|
|
||||||
{%- endtrans %}</i></b>
|
|
||||||
<p>{% trans -%}
|
|
||||||
Right now, if Alice builds a four hop inbound tunnel starting at Elvis,
|
|
||||||
going to Dave, then to Charlie, then Bob, and finally Alice (A<--B<--C<--D<--E),
|
|
||||||
all five of them will know they are participating in tunnel "123", as
|
|
||||||
the messages are tagged as such. What we want to do is give each hop their
|
|
||||||
own unique tunnel hop ID - Charlie will receive messages on tunnel 234
|
|
||||||
and forward them to tunnel 876 on Bob. The intent is to prevent Bob or
|
|
||||||
Charlie from knowing that they are in Alice's tunnel, as if each hop in
|
|
||||||
the tunnel had the same tunnel ID, collusion attacks aren't much work.
|
|
||||||
{%- endtrans %}</p>
|
|
||||||
<p>{% trans -%}
|
|
||||||
Adding a unique tunnel ID per hop isn't hard, but by itself, insufficient.
|
|
||||||
If Dave and Bob are under the control of the same attacker, they wouldn't
|
|
||||||
be able to tell they are in the same tunnel due to the tunnel ID, but
|
|
||||||
would be able to tell by the message bodies and verification structures
|
|
||||||
by simply comparing them. To prevent that, the tunnel must use layered
|
|
||||||
encryption along the path, both on the payload of the tunneled message
|
|
||||||
and on the verification structure (used to prevent simple tagging attacks).
|
|
||||||
This requires some simple modifications to the TunnelMessage, as well
|
|
||||||
as the inclusion of per-hop secret keys delivered during tunnel creation
|
|
||||||
and given to the tunnel's gateway. We must fix a maximum tunnel length
|
|
||||||
(e.g. 16 hops) and instruct the gateway to encrypt the message to each
|
|
||||||
of the 16 delivered secret keys, in reverse order, and to encrypt the
|
|
||||||
signature of the hash of the (encrypted) payload at each step. The gateway
|
|
||||||
then sends that 16-step encrypted message, along with a 16-step and 16-wide
|
|
||||||
encrypted mapping to the first hop, which then decrypts the mapping and
|
|
||||||
the payload with their secret key, looking in the 16-wide mapping for
|
|
||||||
the entry associated with their own hop (keyed by the per-hop tunnel ID)
|
|
||||||
and verifying the payload by checking it against the associated signed
|
|
||||||
hash.
|
|
||||||
{%- endtrans %}</p>
|
|
||||||
<p>{% trans -%}
|
|
||||||
The tunnel gateway does still have more information than the other peers
|
|
||||||
in the tunnel, and compromising both the gateway and a tunnel participant
|
|
||||||
would allow those peers to collude, exposing the fact that they are both
|
|
||||||
in the same tunnel. In addition, neighboring peers know that they are
|
|
||||||
in the same tunnel anyway, as they know who they send the message to (and
|
|
||||||
with IP-based transports without restricted routes, they know who they
|
|
||||||
got it from). However, the above two techniques significantly increase
|
|
||||||
the cost of gaining meaningful samples when dealing with longer tunnels.
|
|
||||||
{%- endtrans %}</p>
|
|
||||||
</li></ul>
|
|
||||||
<ul class="targetlist">
|
|
||||||
<li>
|
|
||||||
<h3 id="ordering">{% trans -%}
|
|
||||||
Strict ordering of participants within tunnels
|
|
||||||
{%- endtrans %}</h3>
|
|
||||||
<b><i>{{ _('Implemented in release 0.6.2') }}</i></b></li>
|
|
||||||
</ul>
|
|
||||||
<div style="margin-left:25px">
|
|
||||||
<p>{% trans link='http://article.gmane.org/gmane.network.i2p/22/',
|
|
||||||
pdf1='http://forensics.umass.edu/pubs/wright-tissec.pdf',
|
|
||||||
pdf2='http://forensics.umass.edu/pubs/wright.tissec.2008.pdf' -%}
|
|
||||||
As Connelly <a href="{{ link }}">proposed</a> to deal with the
|
|
||||||
<a href="{{ pdf1 }}">predecessor attack</a> <a href="{{ pdf2 }}">(2008
|
|
||||||
update)</a>, keeping the order of peers within our tunnels consistent
|
|
||||||
(aka whenever Alice creates a tunnel with both Bob and Charlie in it,
|
|
||||||
Bob's next hop is always Charlie), we address the issue as Bob doesn't
|
|
||||||
get to substantially sample Alice's peer selection group. We may even
|
|
||||||
want to explicitly allow Bob to participate in Alice's tunnels in only
|
|
||||||
one way - receiving a message from Dave and sending it to Charlie - and
|
|
||||||
if any of those peers are not available to participate in the tunnel (due
|
|
||||||
to overload, network disconnection, etc), avoid asking Bob to participate
|
|
||||||
in any tunnels until they are back online.
|
|
||||||
{%- endtrans %}</p>
|
|
||||||
<p>{% trans -%}
|
|
||||||
More analysis is necessary for revising the tunnel creation - at the
|
|
||||||
moment, we simply select and order randomly within the peer's top tier
|
|
||||||
of peers (ones with fast + high capacity).
|
|
||||||
{%- endtrans %}</p>
|
|
||||||
<p>{% trans -%}
|
|
||||||
Adding a strict ordering to peers in a tunnel also improves the anonymity
|
|
||||||
of peers with 0-hop tunnels, as otherwise the fact that a peer's gateway
|
|
||||||
is always the same would be particularly damning. However, peers with
|
|
||||||
0-hop tunnels may want to periodically use a 1-hop tunnel to simulate
|
|
||||||
the failure of a normally reliable gateway peer (so every MTBF*(tunnel
|
|
||||||
duration) minutes, use a 1-hop tunnel).
|
|
||||||
{%- endtrans %}</p>
|
|
||||||
</div>
|
|
||||||
<ul class="targetlist"><li>
|
|
||||||
<h3 id="tunnelLength">Randomly permuted tunnel lengths</h3>
|
|
||||||
<b><i>{% trans tunnelimpl=site_url('docs/tunnels/implementation') -%}
|
|
||||||
Addressed in I2P 0.5 as documented <a href="{{ tunnelimpl }}">elsewhere</a>
|
|
||||||
{%- endtrans %}</i></b></li>
|
|
||||||
</ul>
|
|
||||||
<ul class="targetlist">
|
|
||||||
<!-- <li style="list-style: none; display: inline"> -->
|
|
||||||
<p>{% trans -%}
|
|
||||||
Without tunnel length permutation, if someone were to somehow detect that
|
|
||||||
a destination had a particular number of hops, it might be able to use that
|
|
||||||
information to identify the router the destination is located on, per the
|
|
||||||
predecessor attack. For instance, if everyone has 2-hop tunnels, if Bob
|
|
||||||
receives a tunnel message from Charlie and forwards it to Alice, Bob knows
|
|
||||||
Alice is the final router in the tunnel. If Bob were to identify what destination
|
|
||||||
that tunnel served (by means of colluding with the gateway and harvesting
|
|
||||||
the network database for all of the LeaseSets), he would know the router
|
|
||||||
on which that destination is located (and without restricted routes, that
|
|
||||||
would mean what IP address the destination is on).
|
|
||||||
{%- endtrans %}</p>
|
|
||||||
<p>{% trans -%}
|
|
||||||
It is to counter user behavior that tunnel lengths should be permuted,
|
|
||||||
using algorithms based on the length requested (for example, the 1/MTBF
|
|
||||||
length change for 0-hop tunnels outlined above).
|
|
||||||
{%- endtrans %}</p>
|
|
||||||
<!-- </li> -->
|
|
||||||
<li>
|
<li>
|
||||||
<h3 id="fullRestrictedRoutes">{% trans -%}
|
<h3 id="fullRestrictedRoutes">{% trans -%}
|
||||||
Full blown n-hop restricted routes with optional trusted links
|
Full blown n-hop restricted routes with optional trusted links
|
||||||
|
Reference in New Issue
Block a user