Added translation tags to get-involved/develop/* and get-involved/*.html

This commit is contained in:
str4d
2013-01-20 03:24:37 +00:00
parent af00580342
commit 637123d387
10 changed files with 924 additions and 666 deletions

View File

@@ -1,120 +1,130 @@
{% extends "global/layout.html" %} {% extends "global/layout.html" %}
{% block title %}Application Development{% endblock %} {% block title %}{{ _('Application Development') }}{% endblock %}
{% block content %} {% block content %}
<h1>Application Development Guide</h1> <h1>{{ _('Application Development Guide') }}</h1>
<h2>Contents</h2> <h2>{{ _('Contents') }}</h2>
<ul> <ul>
<li><a href="#why">Why write I2P-specific code?</a></li> <li><a href="#why">{{ _('Why write I2P-specific code?') }}</a></li>
<li><a href="#concepts">Important concepts</a></li> <li><a href="#concepts">{{ _('Important concepts') }}</a></li>
<li><a href="#options">Development options</a></li> <li><a href="#options">{{ _('Development options') }}</a></li>
<li><a href="#start"><b>Start developing - a simple guide</b></a></li> <li><a href="#start"><b>{{ _('Start developing - a simple guide') }}</b></a></li>
</ul> </ul>
<h2 id="why">Why write I2P-specific code?</h2> <h2 id="why">{{ _('Why write I2P-specific code?') }}</h2>
<p> <p>{% trans i2ptunnel=site_url('docs/api/i2ptunnel') -%}
There are multiple ways to use applications in I2P. There are multiple ways to use applications in I2P.
Using <a href="/i2ptunnel.html">I2PTunnel</a>, Using <a href="{{ i2ptunnel }}">I2PTunnel</a>,
you can use regular applications without needing to program explicit I2P support. you can use regular applications without needing to program explicit I2P support.
This is very effective for client-server scenario's, This is very effective for client-server scenario's,
where you need to connect to a single website. where you need to connect to a single website.
You can simply create a tunnel using I2PTunnel to connect to that website, as shown in <a href="#tunnel.serverclient">Figure 1</a>. You can simply create a tunnel using I2PTunnel to connect to that website, as shown in <a href="#tunnel.serverclient">Figure 1</a>.
</p> {%- endtrans %}</p>
<p> <p>{% trans -%}
If your application is distributed, it will require connections to a large amount of peers. If your application is distributed, it will require connections to a large amount of peers.
Using I2PTunnel, you will need to create a new tunnel for each peer you want to contact, Using I2PTunnel, you will need to create a new tunnel for each peer you want to contact,
as shown in <a href="#tunnel.peertopeer">Figure 2</a>. as shown in <a href="#tunnel.peertopeer">Figure 2</a>.
This process can of course be automated, but running a lot of I2PTunnel instances creates a large amount of overhead. This process can of course be automated, but running a lot of I2PTunnel instances creates a large amount of overhead.
In addition, with many protocols you will need to force everyone to In addition, with many protocols you will need to force everyone to
use the same set of ports for all peers - e.g. if you want to reliably run DCC use the same set of ports for all peers - e.g. if you want to reliably run DCC
chat, everyone needs to agree that port 10001 is Alice, port 10002 is Bob, port chat, everyone needs to agree that port 10001 is Alice, port 10002 is Bob, port
10003 is Charlie, and so on, since the protocol includes TCP/IP specific information 10003 is Charlie, and so on, since the protocol includes TCP/IP specific information
(host and port). (host and port).
</p> {%- endtrans %}</p>
<p> <p>{% trans -%}
General network applications often send a lot of additional data that could be used to identify users. General network applications often send a lot of additional data that could be used to identify users.
Hostnames, port numbers, time zones, character sets, etc. are often sent without informing the user. Hostnames, port numbers, time zones, character sets, etc. are often sent without informing the user.
As such, designing the network protocol specifically with anonymity in mind As such, designing the network protocol specifically with anonymity in mind
can avoid compromising user identities. can avoid compromising user identities.
</p> {%- endtrans %}</p>
<p> <p>{% trans -%}
There are also efficiency considerations to review when determining how to There are also efficiency considerations to review when determining how to
interact on top of I2P. The streaming library and things built on top of it interact on top of I2P. The streaming library and things built on top of it
operate with handshakes similar to TCP, while the core I2P protocols (I2NP and I2CP) operate with handshakes similar to TCP, while the core I2P protocols (I2NP and I2CP)
are strictly message based (like UDP or in some instances raw IP). The important are strictly message based (like UDP or in some instances raw IP). The important
distinction is that with I2P, communication is operating over a long fat network - distinction is that with I2P, communication is operating over a long fat network -
each end to end message will have nontrivial latencies, but may contain payloads each end to end message will have nontrivial latencies, but may contain payloads
of up to 32KB. An application that needs a simple request and response can get rid of up to 32KB. An application that needs a simple request and response can get rid
of any state and drop the latency incurred by the startup and teardown handshakes of any state and drop the latency incurred by the startup and teardown handshakes
by using (best effort) datagrams without having to worry about MTU detection or by using (best effort) datagrams without having to worry about MTU detection or
fragmentation of messages under 32KB. fragmentation of messages under 32KB.
</p> {%- endtrans %}</p>
<div class="box" id="tunnel.serverclient" style="text-align:center"> <div class="box" id="tunnel.serverclient" style="text-align:center">
<img src="{{ url_for('static', filename='images/i2ptunnel_serverclient.png') }}" alt="Creating a server-client connection using I2PTunnel only requires creating a single tunnel." title="Creating a server-client connection using I2PTunnel only requires creating a single tunnel." /> <img src="{{ url_for('static', filename='images/i2ptunnel_serverclient.png') }}" alt="{{ _('Creating a server-client connection using I2PTunnel only requires creating a single tunnel.') }}" title="{{ _('Creating a server-client connection using I2PTunnel only requires creating a single tunnel.') }}" />
<br /><br /> <br /><br />
Figure 1: Creating a server-client connection using I2PTunnel only requires creating a single tunnel. {{ _('Figure 1:') }} {{ _('Creating a server-client connection using I2PTunnel only requires creating a single tunnel.') }}
</div> </div>
<br/> <br/>
<div class="box" id="tunnel.peertopeer" style="text-align:center"> <div class="box" id="tunnel.peertopeer" style="text-align:center">
<img src="{{ url_for('static', filename='images/i2ptunnel_peertopeer.png') }}" alt="Setting up connections for a peer-to-peer applications requires a very large amount of tunnels." title="Setting up connections for a peer-to-peer applications requires a very large amount of tunnels." /> <img src="{{ url_for('static', filename='images/i2ptunnel_peertopeer.png') }}" alt="{{ _('Setting up connections for a peer-to-peer applications requires a very large amount of tunnels.') }}" title="{{ _('Setting up connections for a peer-to-peer applications requires a very large amount of tunnels.') }}" />
<br /><br /> <br /><br />
Figure 2: Setting up connections for a peer-to-peer applications requires a very large amount of tunnels. {{ _('Figure 2:') }} {{ _('Setting up connections for a peer-to-peer applications requires a very large amount of tunnels.') }}
</div> </div>
<br/> <br/>
In summary, a number of reasons to write I2P-specific code: {% trans -%}
<ul> In summary, a number of reasons to write I2P-specific code:
<li> {%- endtrans %}
Creating a large amount of I2PTunnel instances consumes a non-trivial amount of resources, <ul>
which is problematic for distributed applications (a new tunnel is required for each peer). <li>{% trans -%}
</li> Creating a large amount of I2PTunnel instances consumes a non-trivial amount of resources,
<li> which is problematic for distributed applications (a new tunnel is required for each peer).
General network protocols often send a lot of additional data that can be used to identify users. {%- endtrans %}</li>
Programming specifically for I2P allows the creation of a network protocol <li>{% trans -%}
that does not leak such information, keeping users anonymous and secure. General network protocols often send a lot of additional data that can be used to identify users.
</li> Programming specifically for I2P allows the creation of a network protocol
<li> that does not leak such information, keeping users anonymous and secure.
Network protocols designed for use on the regular internet can be inefficient {%- endtrans %}</li>
on I2P, which is a network with a much higher latency. <li>{% trans -%}
</li> Network protocols designed for use on the regular internet can be inefficient
</ul> on I2P, which is a network with a much higher latency.
{%- endtrans %}</li>
</ul>
<p> <p>{% trans -%}
Applications written in Java and accessible/runnable Applications written in Java and accessible/runnable
using an HTML interface via the standard webapps/app.war using an HTML interface via the standard webapps/app.war
may be considered for inclusion in the i2p distribution. may be considered for inclusion in the i2p distribution.
</p> {%- endtrans %}</p>
<h2 id="concepts">Important concepts</h2> <h2 id="concepts">{{ _('Important concepts') }}</h2>
<p>There are a few changes that require adjusting to when using I2P:</p> <p>{% trans -%}
There are a few changes that require adjusting to when using I2P:
{%- endtrans %}</p>
<h3>Destination ~= host+port</h3> <h3>{{ _('Destination ~= host+port') }}</h3>
<p>An application running on I2P sends messages from and receives messages to a <p>{% trans -%}
An application running on I2P sends messages from and receives messages to a
unique cryptographically secure end point - a "destination". In TCP or UDP unique cryptographically secure end point - a "destination". In TCP or UDP
terms, a destination could (largely) be considered the equivalent of a hostname terms, a destination could (largely) be considered the equivalent of a hostname
plus port number pair, though there are a few differences. </p> plus port number pair, though there are a few differences.
{%- endtrans %}</p>
<ul> <ul>
<li>An I2P destination itself is a cryptographic construct - all data sent to one is <li>{% trans -%}
An I2P destination itself is a cryptographic construct - all data sent to one is
encrypted as if there were universal deployment of IPsec with the (anonymized) encrypted as if there were universal deployment of IPsec with the (anonymized)
location of the end point signed as if there were universal deployment of DNSSEC. </li> location of the end point signed as if there were universal deployment of DNSSEC.
<li>I2P destinations are mobile identifiers - they can be moved from one I2P router {%- endtrans %}</li>
<li>{% trans -%}
I2P destinations are mobile identifiers - they can be moved from one I2P router
to another (or with some special software, it can even operate on multiple routers at to another (or with some special software, it can even operate on multiple routers at
once). This is quite different from the TCP or UDP world where a single end point (port) once). This is quite different from the TCP or UDP world where a single end point (port)
must stay on a single host.</li> must stay on a single host.
{%- endtrans %}</li>
<li> <li>
<p> <p>{% trans -%}
I2P destinations are ugly and large - behind the scenes, they contain a 2048bit ElGamal I2P destinations are ugly and large - behind the scenes, they contain a 2048bit ElGamal
public key for encryption, a 1024bit DSA public key for signing, and a variable size public key for encryption, a 1024bit DSA public key for signing, and a variable size
certificate, which may contain proof of work or blinded data. certificate, which may contain proof of work or blinded data.
</p> {%- endtrans %}</p>
<p> <p>{% trans naming=site_url('docs/naming') -%}
There are existing ways to refer to these large and ugly destinations by short There are existing ways to refer to these large and ugly destinations by short
and pretty names (e.g. "irc.duck.i2p"), but at the moment those techniques do not guarantee and pretty names (e.g. "irc.duck.i2p"), but at the moment those techniques do not guarantee
globally uniqueness (since they're stored locally at each person's machine as "hosts.txt") globally uniqueness (since they're stored locally at each person's machine as "hosts.txt")
@@ -123,146 +133,174 @@ manually managed within Monotone, and as such, anyone with commit rights on the
change the destinations). There may be some secure, human readable, scalable, and globally change the destinations). There may be some secure, human readable, scalable, and globally
unique, naming system some day, but applications shouldn't depend upon it being in place, unique, naming system some day, but applications shouldn't depend upon it being in place,
since there are those who don't think such a beast is possible. since there are those who don't think such a beast is possible.
<a href="naming.html">Further information on the naming system</a> is available. <a href="{{ naming }}">Further information on the naming system</a> is available.
</p> {%- endtrans %}</p>
</li> </li>
</ul> </ul>
<h3>Anonymity and confidentiality</h3> <h3>{{ _('Anonymity and confidentiality') }}</h3>
<p>A useful thing to remember is that I2P has transparent end to end encryption <p>{% trans -%}
A useful thing to remember is that I2P has transparent end to end encryption
and authentication for all data passed over the network - if Bob sends to Alice's destination, and authentication for all data passed over the network - if Bob sends to Alice's destination,
only Alice's destination can receive it, and if Bob is using the datagrams or streaming only Alice's destination can receive it, and if Bob is using the datagrams or streaming
library, Alice knows for certain that Bob's destination is the one who sent the data. </p> library, Alice knows for certain that Bob's destination is the one who sent the data.
{%- endtrans %}</p>
<p>Of course, another useful thing to remember is that I2P transparently anonymizes the <p>{% trans -%}
Of course, another useful thing to remember is that I2P transparently anonymizes the
data sent between Alice and Bob, but it does nothing to anonymize the content of what they data sent between Alice and Bob, but it does nothing to anonymize the content of what they
send. For instance, if Alice sends Bob a form with her full name, government IDs, and send. For instance, if Alice sends Bob a form with her full name, government IDs, and
credit card numbers, there is nothing I2P can do. As such, protocols and applications should credit card numbers, there is nothing I2P can do. As such, protocols and applications should
keep in mind what information they are trying to protect and what information they are willing keep in mind what information they are trying to protect and what information they are willing
to expose.</p> to expose.
{%- endtrans %}</p>
<h3>I2P datagrams can be up to 32KB</h3> <h3>{{ _('I2P datagrams can be up to 32KB') }}</h3>
<p>Applications that use I2P datagrams (either raw or repliable ones) can essentially be thought <p>{% trans -%}
Applications that use I2P datagrams (either raw or repliable ones) can essentially be thought
of in terms of UDP - the datagrams are unordered, best effort, and connectionless - but unlike of in terms of UDP - the datagrams are unordered, best effort, and connectionless - but unlike
UDP, applications don't need to worry about MTU detection and can simply fire off 32KB datagrams UDP, applications don't need to worry about MTU detection and can simply fire off 32KB datagrams
(31KB when using the repliable kind). For many applications, 32KB of data is sufficient for an (31KB when using the repliable kind). For many applications, 32KB of data is sufficient for an
entire request or response, allowing them to transparently operate in I2P as a UDP-like entire request or response, allowing them to transparently operate in I2P as a UDP-like
application without having to write fragmentation, resends, etc.</p> application without having to write fragmentation, resends, etc.
{%- endtrans %}</p>
<h2 id="options">Development options</h2> <h2 id="options">{{ _('Development options') }}</h2>
<p>There are several means of sending data over I2P, each with their own pros and cons. <p>{% trans -%}
There are several means of sending data over I2P, each with their own pros and cons.
The streaming lib is the recommended interface, used by the majority of I2P applications. The streaming lib is the recommended interface, used by the majority of I2P applications.
</p> {%- endtrans %}</p>
<h3>Streaming Lib</h3> <h3>{{ _('Streaming Lib') }}</h3>
<p> <p>{% trans streaming=site_url('docs/api/streaming') -%}
The <a href="streaming.html">full streaming library</a> is now the standard The <a href="{{ streaming }}">full streaming library</a> is now the standard
interface. It allows programming using TCP-like sockets, as explained in the <a href="#start.streaming">Streaming development guide</a>. interface. It allows programming using TCP-like sockets, as explained in the <a href="#start.streaming">Streaming development guide</a>.
</p> {%- endtrans %}</p>
<h3>BOB</h3> <h3>BOB</h3>
<p>BOB is the <a href="BOB.html">Basic Open Bridge</a>, <p>{% trans bob=site_url('docs/api/bob'), boburl=i2pconv('bob.i2p') -%}
BOB is the <a href="{{ bob }}">Basic Open Bridge</a>,
allowing an application in any language to make streaming connections allowing an application in any language to make streaming connections
to and from I2P. At this point in time it lacks UDP support, but UDP support to and from I2P. At this point in time it lacks UDP support, but UDP support
is planned in the near future. BOB also contains several tools, such as is planned in the near future. BOB also contains several tools, such as
destination key generation, and verification that an address conforms to destination key generation, and verification that an address conforms to
I2P specifications. Up to date info and applications that use BOB can be I2P specifications. Up to date info and applications that use BOB can be
found at this <a href="http://{{ i2pconv('bob.i2p') }}/">eepsite</a>.</p> found at this <a href="http://{{ boburl }}/">eepsite</a>.
{%- endtrans %}</p>
<h3>SAM, SAM V2, SAM V3</h3> <h3>SAM, SAM V2, SAM V3</h3>
<p><i>SAM is not recommended. SAM V2 is okay, SAM V3 is beta.</i></p> <p><i>{{ _('SAM is not recommended. SAM V2 is okay, SAM V3 is beta.') }}</i></p>
<p>SAM is the <a href="sam">Simple Anonymous Messaging</a> protocol, allowing an <p>{% trans sam=site_url('docs/api/sam') -%}
SAM is the <a href="{{ sam }}">Simple Anonymous Messaging</a> protocol, allowing an
application written in any language to talk to a SAM bridge through a plain TCP socket and have application written in any language to talk to a SAM bridge through a plain TCP socket and have
that bridge multiplex all of its I2P traffic, transparently coordinating the encryption/decryption that bridge multiplex all of its I2P traffic, transparently coordinating the encryption/decryption
and event based handling. SAM supports three styles of operation:</p> and event based handling. SAM supports three styles of operation:
{%- endtrans %}</p>
<ul> <ul>
<li>streams, for when Alice and Bob want to send data to each other reliably and in order</li> <li>{% trans -%}
<li>repliable datagrams, for when Alice wants to send Bob a message that Bob can reply to</li> streams, for when Alice and Bob want to send data to each other reliably and in order
<li>raw datagrams, for when Alice wants to squeeze the most bandwidth and performance as possible, {%- endtrans %}</li>
and Bob doesn't care whether the data's sender is authenticated or not (e.g. the data transferred <li>{% trans -%}
is self authenticating)</li> repliable datagrams, for when Alice wants to send Bob a message that Bob can reply to
{%- endtrans %}</li>
<li>{% trans -%}
raw datagrams, for when Alice wants to squeeze the most bandwidth and performance as possible,
and Bob doesn't care whether the data's sender is authenticated or not (e.g. the data transferred
is self authenticating)
{%- endtrans %}</li>
</ul> </ul>
<p>SAM V3 aims at the same goal as SAM and SAM V2, but does not require <p>{% trans -%}
SAM V3 aims at the same goal as SAM and SAM V2, but does not require
multiplexing/demultiplexing. Each I2P stream is handled by its own socket between the application multiplexing/demultiplexing. Each I2P stream is handled by its own socket between the application
and the SAM bridge. Besides, datagrams can be sent and received by the application through datagram and the SAM bridge. Besides, datagrams can be sent and received by the application through datagram
communications with the SAM bridge. communications with the SAM bridge.
{%- endtrans %}</p>
</p> <p>{% trans sam=site_url('docs/api/sam'), samv2=site_url('docs/api/samv2'), samv3=site_url('docs/api/samv3') -%}
<a href="{{ samv2 }}">SAM V2</a> is a new version used by imule
<p> that fixes some of the problems in <a href="{{ sam }}">SAM</a>.
<a href="samv2.html">SAM V2</a> is a new version used by imule
that fixes some of the problems in <a href="sam.html">SAM</a>.
<br /> <br />
<a href="samv3.html">SAM V3</a> is used by imule since version 1.4.0. <a href="{{ samv3 }}">SAM V3</a> is used by imule since version 1.4.0.
</p> {%- endtrans %}</p>
<h3>I2PTunnel</h3> <h3>I2PTunnel</h3>
<p>The I2PTunnel application allows applications to build specific TCP-like tunnels to peers <p>{% trans -%}
The I2PTunnel application allows applications to build specific TCP-like tunnels to peers
by creating either I2PTunnel 'client' applications (which listen on a specific port and connect by creating either I2PTunnel 'client' applications (which listen on a specific port and connect
to a specific I2P destination whenever a socket to that port is opened) or I2PTunnel 'server' to a specific I2P destination whenever a socket to that port is opened) or I2PTunnel 'server'
applications (which listen to a specific I2P destination and whenever it gets a new I2P applications (which listen to a specific I2P destination and whenever it gets a new I2P
connection it outproxies to a specific TCP host/port). These streams are 8bit clean and are connection it outproxies to a specific TCP host/port). These streams are 8bit clean and are
authenticated and secured through the same streaming library that SAM uses, but there is a authenticated and secured through the same streaming library that SAM uses, but there is a
nontrivial overhead involved with creating multiple unique I2PTunnel instances, since each have nontrivial overhead involved with creating multiple unique I2PTunnel instances, since each have
their own unique I2P destination and their own set of tunnels, keys, etc.</p> their own unique I2P destination and their own set of tunnels, keys, etc.
{%- endtrans %}</p>
<h3>Ministreaming</h3> <h3>Ministreaming</h3>
<p><i>Not recommended</i></p> <p><i>{{ _('Not recommended') }}</i></p>
<p> <p>{% trans -%}
It was possible to write I2P applications in Java using the ministreaming library. It was possible to write I2P applications in Java using the ministreaming library.
However, the Streaming library has superceded this, and provides better functionality. However, the Streaming library has superceded this, and provides better functionality.
</p> {%- endtrans %}</p>
<h3>Datagrams</h3> <h3>{{ _('Datagrams') }}</h3>
<p><i>Not recommended</i></p> <p><i>{{ _('Not recommended') }}</i></p>
The <a href="datagrams">Datagram library</a> allows sending UDP-like packets. <p>{% trans datagrams=site_url('docs/spec/datagrams') -%}
The <a href="{{ datagrams }}">Datagram library</a> allows sending UDP-like packets.
It's possible to use: It's possible to use:
{%- endtrans %}</p>
<ul> <ul>
<li>Repliable datagrams</li> <li>{{ _('Repliable datagrams') }}</li>
<li>Raw datagrams</li> <li>{{ _('Raw datagrams') }}</li>
</ul> </ul>
<h3>I2CP</h3> <h3>I2CP</h3>
<p><i>Not recommended</i></p> <p><i>{{ _('Not recommended') }}</i></p>
<p><a href="i2cp">I2CP</a> itself is a language independent protocol, but to implement an I2CP library <p>{% trans i2cp=site_url('docs/protocol/i2cp') -%}
<a href="{{ i2cp }}">I2CP</a> itself is a language independent protocol, but to implement an I2CP library
in something other than Java there is a significant amount of code to be written (encryption routines, in something other than Java there is a significant amount of code to be written (encryption routines,
object marshalling, asynchronous message handling, etc). While someone could write an I2CP library in object marshalling, asynchronous message handling, etc). While someone could write an I2CP library in
C or something else, it would most likely be more useful to use the C SAM library instead. C or something else, it would most likely be more useful to use the C SAM library instead.
</p> {%- endtrans %}</p>
<h3>Web Applications</h3> <h3>{{ _('Web Applications') }}</h3>
<p>{% trans -%}
I2P comes with the Jetty webserver, and configuring to use the Apache server instead is straightforward. I2P comes with the Jetty webserver, and configuring to use the Apache server instead is straightforward.
Any standard web app technology should work. Any standard web app technology should work.
{%- endtrans %}</p>
<h2 id="start">Start developing - a simple guide</h2> <h2 id="start">{{ _('Start developing - a simple guide') }}</h2>
<p>{% trans -%}
Developing using I2P requires a working I2P installation and a development environment of your own choice. Developing using I2P requires a working I2P installation and a development environment of your own choice.
If you are using Java, you can start development with the <a href="#start.streaming">streaming library</a> or datagram library. If you are using Java, you can start development with the <a href="#start.streaming">streaming library</a> or datagram library.
Using another programming language, SAM or BOB can be used. Using another programming language, SAM or BOB can be used.
{%- endtrans %}</p>
<h3 id="start.streaming">Developing with the streaming library</h3> <h3 id="start.streaming">{{ _('Developing with the streaming library') }}</h3>
Development using the streaming library requires the following libraries in your classpath: <p>{% trans -%}
<ul> Development using the streaming library requires the following libraries in your classpath:
<li>$I2P/lib/streaming.jar: the streaming library itself.</li> {%- endtrans %}</p>
<li>$I2P/lib/mstreaming.jar: the ministreaming library is used as the base for the streaming library.</li> <ul>
<li>$I2P/lib/i2p.jar: some standard I2P classes (like the Destination class) are very convenient when developing.</li> <li>$I2P/lib/streaming.jar: {{ _('the streaming library itself.') }}</li>
</ul> <li>$I2P/lib/mstreaming.jar: {{ _('the ministreaming library is used as the base for the streaming library.') }}</li>
<li>$I2P/lib/i2p.jar: {{ _('some standard I2P classes (like the Destination class) are very convenient when developing.') }}</li>
</ul>
<p> <p>{% trans -%}
Network communication requires the usage of I2P network sockets. Network communication requires the usage of I2P network sockets.
To demonstrate this, we will create an application where a client can send text messages to a server, To demonstrate this, we will create an application where a client can send text messages to a server,
who will print the messages and send them back to the client. In other words, the server will function as an echo. who will print the messages and send them back to the client. In other words, the server will function as an echo.
</p> {%- endtrans %}</p>
<p> <p>{% trans -%}
We will start by initializing the server application. This requires getting an I2PSocketManager We will start by initializing the server application. This requires getting an I2PSocketManager
and creating an I2PServerSocket. and creating an I2PServerSocket.
In addition, we will ask the I2PSocketManager for an I2PSession, so we can find out the Destination we use. In addition, we will ask the I2PSocketManager for an I2PSession, so we can find out the Destination we use.
</p> {%- endtrans %}</p>
<div class="box"> <div class="box">
<pre> <pre>
package i2p.echoserver; package i2p.echoserver;
@@ -286,16 +324,16 @@ Using another programming language, SAM or BOB can be used.
} }
</pre> </pre>
<br /><br /> <br /><br />
<p style="text-align:center">Code example 1: initializing the server application.</p> <p style="text-align:center">{{ _('Code example 1: initializing the server application.') }}</p>
</div> </div>
<p> <p>{% trans -%}
Once we have an I2PServerSocket, we can create I2PSocket instances to accept connections from clients. Once we have an I2PServerSocket, we can create I2PSocket instances to accept connections from clients.
In this example, we will create a single I2PSocket instance, that can only handle one client at a time. In this example, we will create a single I2PSocket instance, that can only handle one client at a time.
A real server would have to be able to handle multiple clients. A real server would have to be able to handle multiple clients.
To do this, multiple I2PSocket instances would have to be created, each in separate threads. To do this, multiple I2PSocket instances would have to be created, each in separate threads.
Once we have created the I2PSocket instance, we read data, print it and send it back to the client. Once we have created the I2PSocket instance, we read data, print it and send it back to the client.
The bold code is the new code we add. The bold code is the new code we add.
</p> {%- endtrans %}</p>
<div class="box"> <div class="box">
<pre> <pre>
package i2p.echoserver; package i2p.echoserver;
@@ -374,12 +412,14 @@ Using another programming language, SAM or BOB can be used.
} }
</b></pre> </b></pre>
<br /><br /> <br /><br />
<p style="text-align:center">Code example 2: accepting connections from clients and handling messages.</p> <p style="text-align:center">{{ _('Code example 2: accepting connections from clients and handling messages.') }}</p>
</div> </div>
When you run the above server code, it should print something like this (but without the line endings, it should just be <p>{% trans -%}
one huge block of characters): When you run the above server code, it should print something like this (but without the line endings, it should just be
one huge block of characters):
{%- endtrans %}
<pre id="start.streaming.destination"> <pre id="start.streaming.destination">
y17s~L3H9q5xuIyyynyWahAuj6Jeg5VC~Klu9YPquQvD4vlgzmxn4yy~5Z0zVvKJiS2Lk y17s~L3H9q5xuIyyynyWahAuj6Jeg5VC~Klu9YPquQvD4vlgzmxn4yy~5Z0zVvKJiS2Lk
poPIcB3r9EbFYkz1mzzE3RYY~XFyPTaFQY8omDv49nltI2VCQ5cx7gAt~y4LdWqkyk3au poPIcB3r9EbFYkz1mzzE3RYY~XFyPTaFQY8omDv49nltI2VCQ5cx7gAt~y4LdWqkyk3au
@@ -390,16 +430,18 @@ Using another programming language, SAM or BOB can be used.
BOF6kbxV7NPRPnivbNekd1E1GUq08ltDPVMO1pKJuGMsFyZC4Q~osZ8nI59ryouXgn97Q BOF6kbxV7NPRPnivbNekd1E1GUq08ltDPVMO1pKJuGMsFyZC4Q~osZ8nI59ryouXgn97Q
5ZDEO8-Iazx50~yUQTRgLMOTC5hqnAAAA 5ZDEO8-Iazx50~yUQTRgLMOTC5hqnAAAA
</pre> </pre>
This is the base64-representation of the server Destination. The client will need this string to reach the server. {% trans -%}
This is the base64-representation of the server Destination. The client will need this string to reach the server.
{%- endtrans %}</p>
<p> <p>{% trans -%}
Now, we will create the client application. Again, a number of steps are required for initialization. Now, we will create the client application. Again, a number of steps are required for initialization.
Again, we will need to start by getting an I2PSocketManager. Again, we will need to start by getting an I2PSocketManager.
We won't use an I2PSession and an I2PServerSocket this time. We won't use an I2PSession and an I2PServerSocket this time.
Instead, we will use the server Destination string to start our connection. Instead, we will use the server Destination string to start our connection.
We will ask the user for the Destination string, and create an I2PSocket using this string. We will ask the user for the Destination string, and create an I2PSocket using this string.
Once we have an I2PSocket, we can start sending and receiving data to and from the server. Once we have an I2PSocket, we can start sending and receiving data to and from the server.
</p> {%- endtrans %}</p>
<div class="box"> <div class="box">
<pre> <pre>
package i2p.echoclient; package i2p.echoclient;
@@ -474,20 +516,22 @@ Using another programming language, SAM or BOB can be used.
} }
</pre> </pre>
<br /><br /> <br /><br />
<p style="text-align:center">Code example 3: starting the client and connecting it to the server application.</p> <p style="text-align:center">{{ _('Code example 3: starting the client and connecting it to the server application.') }}</p>
</div> </div>
<p> <p>{% trans -%}
Finally, you can run both the server and the client application. Finally, you can run both the server and the client application.
First, start the server application. It will print a Destination string (like shown <a href="#start.streaming.destination">above</a>). First, start the server application. It will print a Destination string (like shown <a href="#start.streaming.destination">above</a>).
Next, start the client application. When it requests a Destination string, you can enter the string printed by the server. Next, start the client application. When it requests a Destination string, you can enter the string printed by the server.
The client will then send 'Hello I2P!' (along with a newline) to the server, who will print the message and send it back to the client. The client will then send 'Hello I2P!' (along with a newline) to the server, who will print the message and send it back to the client.
</p> {%- endtrans %}</p>
<p> <p>{% trans -%}
Congratulations, you have successfully communicated over I2P! Congratulations, you have successfully communicated over I2P!
</p> {%- endtrans %}</p>
<h2>Existing Applications in Development</h2> <h2>{{ _('Existing Applications in Development') }}</h2>
<p>{% trans -%}
Contact us if you would like to help. Contact us if you would like to help.
{%- endtrans %}</p>
<ul> <ul>
<li> <li>
<a href="http://{{ i2pconv('i2pbote.i2p') }}/">I2P-Bote</a> - contact HungryHobo <a href="http://{{ i2pconv('i2pbote.i2p') }}/">I2P-Bote</a> - contact HungryHobo
@@ -502,24 +546,40 @@ Contact us if you would like to help.
</li><li><a href="http://{{ i2pconv('bob.i2p') }}">BOB</a> - contact sponge </li><li><a href="http://{{ i2pconv('bob.i2p') }}">BOB</a> - contact sponge
</li></ul> </li></ul>
<h2>Application Ideas</h2> <h2>{{ _('Application Ideas') }}</h2>
<ul> <ul>
<li>NNTP server - there have been some in the past, none at the moment <li>{% trans -%}
</li><li>Jabber server - there have been some in the past, and there is one at the moment, with access to the public internet NNTP server - there have been some in the past, none at the moment
</li><li>PGP Key server and/or proxy {%- endtrans %}</li>
</li><li>Download manager / eepget scheduler - <li>{% trans -%}
Jabber server - there have been some in the past, and there is one at the moment, with access to the public internet
{%- endtrans %}</li>
<li>{% trans -%}
PGP Key server and/or proxy
{%- endtrans %}</li>
<li>{% trans -%}
Download manager / eepget scheduler -
We use eepget to fetch lots of things reliably over i2p, and there's already an We use eepget to fetch lots of things reliably over i2p, and there's already an
implementation of a sequential download manager (net.i2p.util.EepGetScheduler), implementation of a sequential download manager (net.i2p.util.EepGetScheduler),
but there isn't any sort of user interface to it. A web based UI would be but there isn't any sort of user interface to it. A web based UI would be
great. great.
</li><li>Content Distribution / DHT applications - help out with <a href="http://{{ i2pconv('feedspace.i2p') }}/">feedspace</a>, {%- endtrans %}</li>
<li>{% trans feedspace=i2pconv('feedspace.i2p') -%}
Content Distribution / DHT applications - help out with <a href="http://{{ feedspace }}">feedspace</a>,
port dijjer, look for alternatives port dijjer, look for alternatives
</li><li>Help out with <a href="http://syndie.i2p2.de/">Syndie</a> development {%- endtrans %}</li>
</li><li>Web-based applications - The sky is the limit for hosting web-server-based <li>{% trans -%}
Help out with <a href="http://syndie.i2p2.de/">Syndie</a> development
{%- endtrans %}</li>
<li>{% trans -%}
Web-based applications - The sky is the limit for hosting web-server-based
applications such as blogs, pastebins, storage, tracking, feeds, etc. applications such as blogs, pastebins, storage, tracking, feeds, etc.
Any web or CGI technology such as Perl, PHP, Python, or Ruby will work. Any web or CGI technology such as Perl, PHP, Python, or Ruby will work.
</li><li>Resurrect some old apps - in the i2p source package - {%- endtrans %}</li>
<li>{% trans -%}
Resurrect some old apps - in the i2p source package -
bogobot, pants, proxyscript, q, stasher, socks proxy, i2ping bogobot, pants, proxyscript, q, stasher, socks proxy, i2ping
</li></ul> {%- endtrans %}</li>
</ul>
{% endblock %} {% endblock %}

View File

@@ -1,17 +1,23 @@
{% extends "global/layout.html" %} {% extends "global/layout.html" %}
{% block title %}I2P Developer's MTN Keys{% endblock %} {% block title %}{% trans %}I2P Developer's MTN Keys{% endtrans %}{% endblock %}
{% block content %} {% block content %}
<h1>MTN Keys</h1> <h1>{{ _('MTN Keys') }}</h1>
<p>Monotone servers used by the I2P project require two types of keys to be used. <p>{% trans -%}
Monotone servers used by the I2P project require two types of keys to be used.
{%- endtrans %}</p>
<ul> <ul>
<li><a href="#commit">Commit Keys</a> to sign changes checked-in to the respository; and</li> <li>{% trans %}<a href="#commit">Commit Keys</a> to sign changes checked-in to the respository; and{% endtrans %}</li>
<li><a href="#transport">Transport Keys</a> to push changes to remote servers.</li> <li>{% trans %}<a href="#transport">Transport Keys</a> to push changes to remote servers.{% endtrans %}</li>
</ul> </ul>
<p>Everyone that uses Monotone to checkout the I2P codebase will need to <a href="monotone#obtaining-and-deploying-developers-keys">import</a> the <p>{% trans monotone=site_url('get-involved/guides/monotone') -%}
developer commit keys, but only Monotone <a href="monotone#operating-a-monotone-server">server operators</a> will need to import the <a href="#transport">transport keys</a>.</p> Everyone that uses Monotone to checkout the I2P codebase will need to
<a href="{{ monotone }}#obtaining-and-deploying-developers-keys">import</a> the
developer commit keys, but only Monotone <a href="{{ monotone }}#operating-a-monotone-server">
server operators</a> will need to import the <a href="#transport">transport keys</a>.
{%- endtrans %}</p>
<h3 id="commit">Developer Commit keys</h3> <h3 id="commit">{{ _('Developer Commit keys') }}</h3>
<pre> <pre>
[pubkey jrandom@i2p.net] [pubkey jrandom@i2p.net]
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOLw05kZbux5KLdp MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOLw05kZbux5KLdp
@@ -223,8 +229,11 @@ rIeB7/2uVOpe+3FrFgUzIiWsx6I2yiNI3TscDvQsa5wG0Z2G4BbHXj
ONyiUzzO+j2TWPs3x35r2LCy8plRzPAswCF1GaIEjJCce5zwIDAQAB ONyiUzzO+j2TWPs3x35r2LCy8plRzPAswCF1GaIEjJCce5zwIDAQAB
[end] [end]
</pre> </pre>
<h3 id="transport">Developer Transport Keys</h3> <h3 id="transport">{{ _('Developer Transport Keys') }}</h3>
<p><b>Note:</b> Transport keys are only needed for setting up a <a href="monotone#operating-a-monotone-server">Monotone server</a>.</p> <p>{% trans monotone=site_url('get-involved/guides/monotone') -%}
<b>Note:</b> Transport keys are only needed for setting up a
<a href="{{ monotone }}#operating-a-monotone-server">Monotone server</a>.
{%- endtrans %}</p>
<pre> <pre>
[pubkey zzz-transport@mail.i2p] [pubkey zzz-transport@mail.i2p]

View File

@@ -1,15 +1,20 @@
{% extends "global/layout.html" %} {% extends "global/layout.html" %}
{% block title %}License Agreements{% endblock %} {% block title %}{{ _('License Agreements') }}{% endblock %}
{% block content %} {% block content %}
<p>For more information see <a href="{{ site_url('develop/licenses') }}">licenses.html</a>. <p>{% trans licenses=site_url('get-involved/develop/licenses') -%}
</p><p>Following is a monotonerc file defining the current trust list. For more information see <a href="{{ licenses }}">the licenses page</a>.
{%- endtrans %}</p>
<p>{% trans -%}
Following is a monotonerc file defining the current trust list.
Developers must use this file in ~/.monotone/monotonerc or Developers must use this file in ~/.monotone/monotonerc or
_MTN/montonerc in their i2p.i2p workspace. _MTN/montonerc in their i2p.i2p workspace.
{%- endtrans %}
{% include "include/monotonerc.html" %} {% include "include/monotonerc.html" %}
</p><p>Agreements: </p>
<p>{{ _('Agreements') }}:
<pre> <pre>
Complication: Complication:

View File

@@ -1,30 +1,34 @@
{% extends "global/layout.html" %} {% extends "global/layout.html" %}
{% block title %}Licenses{% endblock %} {% block title %}{{ _('Licenses') }}{% endblock %}
{% block content %} {% block content %}
<h1>I2P Software Licenses</h1> <h1>{{ _('I2P Software Licenses') }}</h1>
<p> <p>{% trans threatmodel=site_url('docs/how/threat-model') -%}
As required by our As required by our
<a href="{{ site_url('docs/how/threatmodel') }}">threat model</a> (among other reasons), the <a href="{{ threatmodel }}">threat model</a> (among other reasons), the
software developed to support the anonymous communication software developed to support the anonymous communication
network we call I2P must be freely available, open source, network we call I2P must be freely available, open source,
and user modifiable. To meet these criteria, we make use of and user modifiable. To meet these criteria, we make use of
a variety of legal and software engineering techniques so a variety of legal and software engineering techniques so
as to remove as many barriers to entry for those considering as to remove as many barriers to entry for those considering
making use of or contributing to the I2P effort.</p> making use of or contributing to the I2P effort.
{%- endtrans %}</p>
<p>While the information below may be more confusing than just simply <p>{% trans -%}
While the information below may be more confusing than just simply
stating "I2P is BSD", "I2P is GPL", or "I2P is public domain", stating "I2P is BSD", "I2P is GPL", or "I2P is public domain",
the short answer to the question "How is I2P licensed?" is this:</p> the short answer to the question "How is I2P licensed?" is this:
{%- endtrans %}</p>
<h2>All software bundled in the I2P distributions will allow:</h2> <h2>{{ _('All software bundled in the I2P distributions will allow:') }}</h2>
<ol> <ol>
<li>use without fee</li> <li>{{ _('use without fee') }}</li>
<li>use with no restrictions on how, when, where, why, or by whom is running it</li> <li>{{ _('use with no restrictions on how, when, where, why, or by whom is running it') }}</li>
<li>access to the source code without fee</li> <li>{{ _('access to the source code without fee') }}</li>
<li>modifications to the source</li> <li>{{ _('modifications to the source') }}</li>
</ol> </ol>
<p>Most of the software guarantees much more - the ability of <b>anyone</b> to <p>{% trans -%}
Most of the software guarantees much more - the ability of <b>anyone</b> to
distribute the modified source however they choose. However, not all of the distribute the modified source however they choose. However, not all of the
software bundled provides this freedom - the GPL restricts the ability of software bundled provides this freedom - the GPL restricts the ability of
developers who wish to integrate I2P with their own applications that are not developers who wish to integrate I2P with their own applications that are not
@@ -33,26 +37,29 @@ increasing the resources in the commons, I2P is best served by removing any
barriers that stand in the way of its adoption - if a developer considering whether barriers that stand in the way of its adoption - if a developer considering whether
they can integrate I2P with their application has to stop and check with their lawyer, they can integrate I2P with their application has to stop and check with their lawyer,
or conduct a code audit to make sure their own source can be released as GPL-compatible, or conduct a code audit to make sure their own source can be released as GPL-compatible,
we lose out.</p> we lose out.
{%- endtrans %}</p>
<h2>Component licenses</h2> <h2>{{ _('Component licenses') }}</h2>
<p>The I2P distribution contains several resources, reflecting the partitioning of <p>{% trans -%}
The I2P distribution contains several resources, reflecting the partitioning of
the source code into components. Each component has its own license, which all the source code into components. Each component has its own license, which all
developers who contribute to it agree to - either by explicitly declaring the release developers who contribute to it agree to - either by explicitly declaring the release
of code committed under a license compatible with that component, or by implicitly of code committed under a license compatible with that component, or by implicitly
releasing the code committed under the component's primary license. Each of these releasing the code committed under the component's primary license. Each of these
components has a lead developer who has the final say as to what license is compatible components has a lead developer who has the final say as to what license is compatible
with the component's primary license, and the I2P project manager has the final say as with the component's primary license, and the I2P project manager has the final say as
to what licenses meet the above four guarantees for inclusion in the I2P distribution.</p> to what licenses meet the above four guarantees for inclusion in the I2P distribution.
{%- endtrans %}</p>
<table border="1"> <table border="1">
<tr> <tr>
<td valign="top" align="left"><b>Component</b></td> <td valign="top" align="left"><b>{{ _('Component') }}</b></td>
<td valign="top" align="left"><b>Source path</b></td> <td valign="top" align="left"><b>{{ _('Source path') }}</b></td>
<td valign="top" align="left"><b>Resource</b></td> <td valign="top" align="left"><b>{{ _('Resource') }}</b></td>
<td valign="top" align="left"><b>Primary license</b></td> <td valign="top" align="left"><b>{{ _('Primary license') }}</b></td>
<td valign="top" align="left"><b>Alternate licenses</b></td> <td valign="top" align="left"><b>{{ _('Alternate licenses') }}</b></td>
<td valign="top" align="left"><b>Lead developer</b></td> <td valign="top" align="left"><b>{{ _('Lead developer') }}</b></td>
</tr> </tr>
<tr> <tr>
<td valign="top" align="left"><b>I2P SDK</b></td> <td valign="top" align="left"><b>I2P SDK</b></td>
@@ -261,11 +268,13 @@ to what licenses meet the above four guarantees for inclusion in the I2P distrib
</tr> </tr>
</table> </table>
<h3><a id="java_exception">GPL + java exception</a></h3> <h3><a id="java_exception">{{ _('GPL + java exception') }}</a></h3>
<p>While it may be redundant, just for clarity the <p>{% trans -%}
While it may be redundant, just for clarity the
<a href="http://www.fsf.org/licenses/gpl.html">GPL</a>'ed code included within <a href="http://www.fsf.org/licenses/gpl.html">GPL</a>'ed code included within
I2PTunnel and other apps must be released under the GPL with an additional "exception" I2PTunnel and other apps must be released under the GPL with an additional "exception"
explicitly authorizing the use of Java's standard libraries:</p> explicitly authorizing the use of Java's standard libraries:
{%- endtrans %}</p>
<p><code>In addition, as a special exception, XXXX gives permission to link the <p><code>In addition, as a special exception, XXXX gives permission to link the
code of this program with the proprietary Java implementation provided by Sun code of this program with the proprietary Java implementation provided by Sun
@@ -276,36 +285,46 @@ file, you may extend this exception to your version of the file, but you are not
obligated to do so. If you do not wish to do so, delete this exception statement obligated to do so. If you do not wish to do so, delete this exception statement
from your version.</code></p> from your version.</code></p>
<p>All source code under each component will by default be licensed under the <p>{% trans -%}
All source code under each component will by default be licensed under the
primary license, unless marked otherwise in the code. All of the above is primary license, unless marked otherwise in the code. All of the above is
summary of the license terms - please see the specific license for the component summary of the license terms - please see the specific license for the component
or source code in question for authoritative terms. Component source locations and or source code in question for authoritative terms. Component source locations and
resource packaging may be changed if the repository is reorganized.</p> resource packaging may be changed if the repository is reorganized.
{%- endtrans %}</p>
<h2><a id="commit">Commit privileges</a></h2> <h2><a id="commit">{{ _('Commit privileges') }}</a></h2>
<p> <p>{% trans monotone=site_url('get-involved/guides/monotone') -%}
Developers may push changes to a distributed monotone repository if you Developers may push changes to a distributed monotone repository if you
receive permission from the person running that repository. receive permission from the person running that repository.
See the <a href="monotone.html">Monotone Page</a> for details. See the <a href="{{ monotone }}">Monotone Page</a> for details.
</p> {%- endtrans %}</p>
<p> <p>{% trans -%}
However, to have changes included in a release, developers However, to have changes included in a release, developers
must be trusted by the release manager (currently zzz). must be trusted by the release manager (currently zzz).
In addition, they must explicitly agree with the above terms to be trusted. In addition, they must explicitly agree with the above terms to be trusted.
That means that they must send one of the release managers a signed message affirming that:</p> That means that they must send one of the release managers a signed message affirming that:
{%- endtrans %}</p>
<ul> <ul>
<li>Unless marked otherwise, all code I commit is implicitly licensed under <li>{% trans -%}
the component's primary license</li> Unless marked otherwise, all code I commit is implicitly licensed under
<li>If specified in the source, the code may be explicitly licensed under one the component's primary license
of the component's alternate licenses</li> {%- endtrans %}</li>
<li>I have the right to release the code I commit under the terms I <li>{% trans -%}
am committing it</li> If specified in the source, the code may be explicitly licensed under one
of the component's alternate licenses
{%- endtrans %}</li>
<li>{% trans -%}
I have the right to release the code I commit under the terms I
am committing it
{%- endtrans %}</li>
</ul> </ul>
<p>If anyone is aware of any instances where the above conditions are not met, <p>{% trans licenseagreements=site_url('get-involved/develop/license-agreements') -%}
If anyone is aware of any instances where the above conditions are not met,
please contact the component lead and/or an I2P release manager with further please contact the component lead and/or an I2P release manager with further
information. information.
<a href="{{ site_url('develop/license-agreements') }}">See developers' license agreements</a>. <a href="{{ licenseagreements }}">See developers' license agreements</a>.
</p> {%- endtrans %}</p>
{% endblock %} {% endblock %}

View File

@@ -1,7 +1,9 @@
{% extends "global/layout.html" %} {% extends "global/layout.html" %}
{% block title %}Release Signing Key{% endblock %} {% block title %}{{ _('Release Signing Key') }}{% endblock %}
{% block content %} {% block content %}
<p>{% trans -%}
Releases 0.7.6 and later are signed by zzz. His public key is: Releases 0.7.6 and later are signed by zzz. His public key is:
{%- endtrans %}</p>
<p> <p>
<pre> <pre>
-----BEGIN PGP PUBLIC KEY BLOCK----- -----BEGIN PGP PUBLIC KEY BLOCK-----
@@ -35,8 +37,9 @@ njMu9ueCFbsjme7nwsz96PdazJcHAKCce17hGI25QNXDZyHohrjha6IxDg==
-----END PGP PUBLIC KEY BLOCK----- -----END PGP PUBLIC KEY BLOCK-----
</pre> </pre>
<p> <p>{% trans -%}
Releases 0.6.1.31 through 0.7.5 were signed by Complication. His public key is: Releases 0.6.1.31 through 0.7.5 were signed by Complication. His public key is:
{%- endtrans %}</p>
<p> <p>
<pre> <pre>
-----BEGIN PGP SIGNED MESSAGE----- -----BEGIN PGP SIGNED MESSAGE-----

View File

@@ -1,22 +1,24 @@
{% extends "global/layout.html" %} {% extends "global/layout.html" %}
{% block title %}Signed Developer Keys{% endblock %} {% block title %}{{ _('Signed Developer Keys') }}{% endblock %}
{% block content %} {% block content %}
<p>Keys for zzz, Complication and welterde are provided clearsigned. The key for jrandom must be <p>{% trans -%}
verified differently, since he's away, and only left a binary detached Keys for zzz, Complication and welterde are provided clearsigned. The key for jrandom must be
signature for his key. verified differently, since he's away, and only left a binary detached
signature for his key.
{%- endtrans %}</p>
<ol> <ol>
<li><a href="signedkeys#monotone-keys-for-zzz">Monotone keys for zzz</a></li> <li><a href="signedkeys#monotone-keys-for-zzz">{{ _('Monotone keys for zzz') }}</a></li>
<li><a href="#monotone-keys-for-welterde">Monotone keys for welterde</a></li> <li><a href="#monotone-keys-for-welterde">{{ _('Monotone keys for welterde') }}</a></li>
<li><a href="#monotone-keys-for-complication">Monotone keys for Complication</a></li> <li><a href="#monotone-keys-for-complication">{{ _('Monotone keys for Complication') }}</a></li>
<li><a href="#monotone-keys-for-jrandom">Monotone keys for jrandom</a></li> <li><a href="#monotone-keys-for-jrandom">{{ _('Monotone keys for jrandom') }}</a></li>
<li><a href="#other-developer-keys">Others</a></li> <li><a href="#other-developer-keys">{{ _('Others') }}</a></li>
</ol> </ol>
<h3 id="monotone-keys-for-zzz">Monotone keys for zzz</h3> <h3 id="monotone-keys-for-zzz">{{ _('Monotone keys for zzz') }}</h3>
<p> <p>{% trans -%}
<u>Tip:</u> To find zzz's GPG key, on his eepsite locate the key `0xA76E0BED`, with <u>Tip:</u> To find zzz's GPG key, on his eepsite locate the key `0xA76E0BED`, with
the name `zzz@mail.i2p` and the fingerprint `4456 EBBE C805 63FE 57E6 B310 4155 the name `zzz@mail.i2p` and the fingerprint `4456 EBBE C805 63FE 57E6 B310 4155
76BA A76E 0BED`. 76BA A76E 0BED`.
</p> {%- endtrans %}</p>
<code><pre> <code><pre>
-----BEGIN PGP SIGNED MESSAGE----- -----BEGIN PGP SIGNED MESSAGE-----
@@ -42,13 +44,13 @@
</pre></code> </pre></code>
<h3 id="monotone-keys-for-welterde">Monotone keys for welterde</h3> <h3 id="monotone-keys-for-welterde">{{ _('Monotone keys for welterde') }}</h3>
<p> <p>{% trans -%}
<b>Tip:</b> To find welterde's GPG key, on public keyservers locate the key <b>Tip:</b> To find welterde's GPG key, on public keyservers locate the key
`0x62E011A1`, with the name `welterde@arcor.de` and the fingerprint `6720 FD81 `0x62E011A1`, with the name `welterde@arcor.de` and the fingerprint `6720 FD81
3872 6DFC 6016 64D1 EBBC 0374 62E0 11A1`. 3872 6DFC 6016 64D1 EBBC 0374 62E0 11A1`.
</p> {%- endtrans %}</p>
<code><pre> <code><pre>
-----BEGIN PGP SIGNED MESSAGE----- -----BEGIN PGP SIGNED MESSAGE-----
@@ -74,13 +76,13 @@
</pre></code> </pre></code>
<h3 id="monotone-keys-for-complication">Monotone keys for Complication</h3> <h3 id="monotone-keys-for-complication">{{ _('Monotone keys for Complication') }}</h3>
<p> <p>{% trans -%}
<b>Tip:</b> To find Complication's GPG key, on his eepsite locate the key <b>Tip:</b> To find Complication's GPG key, on his eepsite locate the key
`0x79FCCE33`, with the name `complication@mail.i2p` and the fingerprint `73CF `0x79FCCE33`, with the name `complication@mail.i2p` and the fingerprint `73CF
2862 87A7 E7D2 19FF DB66 FA1D FC6B 79FC CE33`. 2862 87A7 E7D2 19FF DB66 FA1D FC6B 79FC CE33`.
</p> {%- endtrans %}</p>
<code><pre> <code><pre>
-----BEGIN PGP SIGNED MESSAGE----- -----BEGIN PGP SIGNED MESSAGE-----
@@ -109,27 +111,27 @@
-----END PGP SIGNATURE----- -----END PGP SIGNATURE-----
</pre></code> </pre></code>
<h3 id="monotone-keys-for-jrandom">Monotone keys for jrandom</h3> <h3 id="monotone-keys-for-jrandom">{{ _('Monotone keys for jrandom') }}</h3>
<p> <p>{% trans -%}
<b>Tip:</b> To find jrandom's GPG key for Syndie releases, on public keyservers locate <b>Tip:</b> To find jrandom's GPG key for Syndie releases, on public keyservers locate
the key `0x393F2DF9`, with the name `syndie-dist-key@i2p.net` and the the key `0x393F2DF9`, with the name `syndie-dist-key@i2p.net` and the
fingerprint `AE89 D080 0E85 72F0 B777 B2ED C2FA 68C0 393F 2DF9`. fingerprint `AE89 D080 0E85 72F0 B777 B2ED C2FA 68C0 393F 2DF9`.
</p> {%- endtrans %}</p>
<p> <p>{% trans -%}
Jrandom had to leave unexpectedly in the end of 2007. His commit key was Jrandom had to leave unexpectedly in the end of 2007. His commit key was
deployed in the Syndie Monotone repository, in a file named `mtn-committers`. deployed in the Syndie Monotone repository, in a file named `mtn-committers`.
That file also had a GPG signature, `mtn-committers.sig`, but it was a binary That file also had a GPG signature, `mtn-committers.sig`, but it was a binary
detached signature. I am going to supply both files in GPG ASCII-armoured form detached signature. I am going to supply both files in GPG ASCII-armoured form
below. below.
</p> {%- endtrans %}</p>
<p> <p>{% trans -%}
First, the file `mtn-committers` containing jrandom's Monotone key. Save as First, the file `mtn-committers` containing jrandom's Monotone key. Save as
`mtn-committers.asc` and unpack it using `gpg --output mtn-committers --dearmor `mtn-committers.asc` and unpack it using `gpg --output mtn-committers --dearmor
mtn-committers.asc`: mtn-committers.asc`:
</p> {%- endtrans %}</p>
<code><pre> <code><pre>
-----BEGIN PGP ARMORED FILE----- -----BEGIN PGP ARMORED FILE-----
@@ -146,12 +148,12 @@
-----END PGP ARMORED FILE----- -----END PGP ARMORED FILE-----
</pre></code> </pre></code>
<p> <p>{% trans -%}
Now the file `mtn-committers.sig`, containing the GPG signature. Save as Now the file `mtn-committers.sig`, containing the GPG signature. Save as
`mtn-committers.sig.asc` and unpack it using `gpg --output mtn-committers.sig `mtn-committers.sig.asc` and unpack it using `gpg --output mtn-committers.sig
--dearmor mtn-committers.sig.asc`. Use it to verify the above supplied --dearmor mtn-committers.sig.asc`. Use it to verify the above supplied
`mtn-committers` file: `mtn-committers` file:
</p> {%- endtrans %}</p>
<code><pre> <code><pre>
-----BEGIN PGP ARMORED FILE----- -----BEGIN PGP ARMORED FILE-----
@@ -164,8 +166,10 @@
-----END PGP ARMORED FILE----- -----END PGP ARMORED FILE-----
</pre></code> </pre></code>
<h3 id="other-developer-keys">Others</h3> <h3 id="other-developer-keys">{{ _('Others') }}</h3>
Some of the developers have included their Monotone keys in their <a href="license-agreements">signed license agreement</a>. <p>{% trans licenseagreements=site_url('get-involved/develop/license-agreements') -%}
Some of the developers have included their Monotone keys in their <a href="{{ licenseagreements }}">signed license agreement</a>.
{%- endtrans %}</p>
{% endblock %} {% endblock %}

View File

@@ -1,17 +1,22 @@
{% extends "global/layout.html" %} {% extends "global/layout.html" %}
{% block title %}Donate{% endblock %} {% block title %}{{ _('Donate') }}{% endblock %}
{% block content %}<p>Thank you for your interest in contributing to I2P! {% block content %}
<p>{% trans -%}
Thank you for your interest in contributing to I2P!
The details of how you The details of how you
can make your contribution are provided below.</p> can make your contribution are provided below.
{%- endtrans %}</p>
<h2><a href="http://www.paypal.com/">PayPal</a></h2> <h2><a href="http://www.paypal.com/">PayPal</a></h2>
<br /> <br />
You can donate direct via PayPal to the account "echelon@i2pmail.org".<br /> {% trans account='echelon@i2pmail.org' -%}
You can donate direct via PayPal to the account "{{ account }}".
{%- endtrans %}<br />
<br /> <br />
<table> <table>
<tr> <tr>
<td>One time donation:</td> <td>{{ _('One time donation:') }}</td>
<td> <td>
<form action="https://www.paypal.com/cgi-bin/webscr" method="post"><fieldset style="border:none;"> <form action="https://www.paypal.com/cgi-bin/webscr" method="post"><fieldset style="border:none;">
<input type="hidden" name="cmd" value="_s-xclick" /> <input type="hidden" name="cmd" value="_s-xclick" />
@@ -25,7 +30,7 @@ You can donate direct via PayPal to the account "echelon@i2pmail.org".<br />
</tr> </tr>
<tr> <tr>
<td>Donate 10 &euro;/month for 12 months: </td> <td>{{ _('Donate 10 &euro;/month for 12 months:') }}</td>
<td> <td>
<form action="https://www.paypal.com/cgi-bin/webscr" method="post"> <form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<fieldset style="border:none;"> <fieldset style="border:none;">
@@ -33,43 +38,43 @@ You can donate direct via PayPal to the account "echelon@i2pmail.org".<br />
<input type="hidden" name="hosted_button_id" value="3031934" /> <input type="hidden" name="hosted_button_id" value="3031934" />
<input type="hidden" name="no_note" value="0" /> <input type="hidden" name="no_note" value="0" />
<input type="hidden" name="no_shipping" value="1" /> <input type="hidden" name="no_shipping" value="1" />
<input type="image" src="https://www.paypal.com/en_US/i/btn/btn_subscribeCC_LG.gif" style="border:0;" name="submit" alt="I2P donation" /> <input type="image" src="https://www.paypal.com/en_US/i/btn/btn_subscribeCC_LG.gif" style="border:0;" name="submit" alt="{{ _('I2P donation ') }}" />
<img alt="" style="border:0;width:1;height:1" src="https://www.paypal.com/de_DE/i/scr/pixel.gif" /></fieldset> <img alt="" style="border:0;width:1;height:1" src="https://www.paypal.com/de_DE/i/scr/pixel.gif" /></fieldset>
</form> </form>
</td> </td>
</tr> </tr>
<tr> <tr>
<td>Donate 20 &euro;/month for 12 months: </td> <td>{{ _('Donate 20 &euro;/month for 12 months:') }}</td>
<td> <td>
<form action="https://www.paypal.com/cgi-bin/webscr" method="post"> <form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<fieldset style="border:none;"> <fieldset style="border:none;">
<input type="hidden" name="cmd" value="_s-xclick" /> <input type="hidden" name="cmd" value="_s-xclick" />
<input type="hidden" name="hosted_button_id" value="KALQ2V9SQF348" /> <input type="hidden" name="hosted_button_id" value="KALQ2V9SQF348" />
<input type="image" src="https://www.paypal.com/en_US/i/btn/btn_subscribeCC_LG.gif" style="border:0;" name="submit" alt="I2P donation" /> <input type="image" src="https://www.paypal.com/en_US/i/btn/btn_subscribeCC_LG.gif" style="border:0;" name="submit" alt="{{ _('I2P donation ') }}" />
<img alt="" style="border:0;width:1;height:1" src="https://www.paypal.com/de_DE/i/scr/pixel.gif" /></fieldset> <img alt="" style="border:0;width:1;height:1" src="https://www.paypal.com/de_DE/i/scr/pixel.gif" /></fieldset>
</form> </form>
</td> </td>
</tr> </tr>
<tr> <tr>
<td>Donate 30 &euro;/month for 12 months: </td> <td>{{ _('Donate 30 &euro;/month for 12 months:') }}</td>
<td> <td>
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" > <form action="https://www.paypal.com/cgi-bin/webscr" method="post" >
<fieldset style="border:none;"> <fieldset style="border:none;">
<input type="hidden" name="cmd" value="_s-xclick" /> <input type="hidden" name="cmd" value="_s-xclick" />
<input type="hidden" name="hosted_button_id" value="QSU89XWKB7N3U" /> <input type="hidden" name="hosted_button_id" value="QSU89XWKB7N3U" />
<input type="image" src="https://www.paypal.com/en_US/i/btn/btn_subscribeCC_LG.gif" style="border:0;" name="submit" alt="I2P donation" /> <input type="image" src="https://www.paypal.com/en_US/i/btn/btn_subscribeCC_LG.gif" style="border:0;" name="submit" alt="{{ _('I2P donation ') }}" />
<img alt="" style="border:0;width:1;height:1" src="https://www.paypal.com/de_DE/i/scr/pixel.gif" /></fieldset> <img alt="" style="border:0;width:1;height:1" src="https://www.paypal.com/de_DE/i/scr/pixel.gif" /></fieldset>
</form> </form>
</td> </td>
</tr> </tr>
<tr> <tr>
<td>Donate 50 &euro;/month for 12 months: </td> <td>{{ _('Donate 50 &euro;/month for 12 months:') }}</td>
<td> <td>
<form action="https://www.paypal.com/cgi-bin/webscr" method="post"> <form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<fieldset style="border:none;"> <fieldset style="border:none;">
<input type="hidden" name="cmd" value="_s-xclick" /> <input type="hidden" name="cmd" value="_s-xclick" />
<input type="hidden" name="hosted_button_id" value="8ENENJMVN6TL8" /> <input type="hidden" name="hosted_button_id" value="8ENENJMVN6TL8" />
<input type="image" src="https://www.paypal.com/en_US/i/btn/btn_subscribeCC_LG.gif" style="border:0;" name="submit" alt="I2P donation" /> <input type="image" src="https://www.paypal.com/en_US/i/btn/btn_subscribeCC_LG.gif" style="border:0;" name="submit" alt="{{ _('I2P donation ') }}" />
<img alt="" style="border:0;width:1;height:1" src="https://www.paypal.com/de_DE/i/scr/pixel.gif" /></fieldset> <img alt="" style="border:0;width:1;height:1" src="https://www.paypal.com/de_DE/i/scr/pixel.gif" /></fieldset>
</form> </form>
</td> </td>
@@ -78,18 +83,26 @@ You can donate direct via PayPal to the account "echelon@i2pmail.org".<br />
<br /> <br />
<h2><a href="http://www.flattr.com/">Flattr</a></h2> <h2><a href="http://www.flattr.com/">Flattr</a></h2>
<a href="http://flattr.com/thing/13523/Invisible-Internet-Project-I2P"> <a href="http://flattr.com/thing/13523/Invisible-Internet-Project-I2P">
<img src="http://api.flattr.com/button/button-static-50x60.png" title="Flattr this" style="border:0;" alt="Flattr this" /></a> <img src="http://api.flattr.com/button/button-static-50x60.png" title="{{ _('Flattr this') }}" style="border:0;" alt="{{ _('Flattr this') }}" /></a>
<br /> <br />
<br /> <br />
<h2><a href="http://www.bitcoin.org/">Bitcoin</a></h2> <h2><a href="http://www.bitcoin.org/">Bitcoin</a></h2>
<p>As of December 2010, eche|on has been running a <a href="http://www.bitcoin.org">Bitcoin</a> account for the I2P project. <p>{% trans account='1HkJCceXf7of1sTNRVJbXiZHfDTLL71Siy' -%}
As of December 2010, eche|on has been running a <a href="http://www.bitcoin.org">Bitcoin</a> account for the I2P project.
If you'd like to donate using Bitcoin, just transfer your desired amount of coins to the account If you'd like to donate using Bitcoin, just transfer your desired amount of coins to the account
<b>1HkJCceXf7of1sTNRVJbXiZHfDTLL71Siy</b> and leave eche|on a note if you'd like your donation to be mentioned on the I2P webpage.<br /> <b>{{ account }}</b> and leave eche|on a note if you'd like your donation to be mentioned on the I2P webpage.
</p> {%- endtrans %}</p>
<p>If you want to keep more or less anonymous, the option to send money via mail is also available. But it is less secure <p>{% trans -%}
as the envelope can be lost on the way to us. </p> If you want to keep more or less anonymous, the option to send money via mail is also available. But it is less secure
<p>If you'd like to donate via snail mail, send an email to <a href="mailto:echelon@i2pmail.org?subject=information about snailmail donation">echelon@i2pmail.org</a> as the envelope can be lost on the way to us.
and you'll receive an email with instructions detailing how to proceed.</p> {%- endtrans %}</p>
<p>{% trans email='echelon@i2pmail.org' -%}
If you'd like to donate via snail mail, send an email to <a href="mailto:{{ email }}?subject=information about snailmail donation">{{ email }}</a>
and you'll receive an email with instructions detailing how to proceed.
{%- endtrans %}</p>
<p>In the meantime, feel free to take a look at the generous donations that have been given in support of the I2P Project at the <a href="{{ site_url('volunteer/halloffame') }}">hall of fame</a>.</p> <p>{% trans halloffame=site_url('about/hall-of-fame') -%}
In the meantime, feel free to take a look at the generous donations that have been
given in support of the I2P Project at the <a href="{{ halloffame }}">hall of fame</a>.
{%- endtrans %}</p>
{% endblock %} {% endblock %}

View File

@@ -1,52 +1,77 @@
{% extends "global/layout.html" %} {% extends "global/layout.html" %}
{% block title %}Get Involved!{% endblock %} {% block title %}{% trans %}Get Involved!{% endtrans %}{% endblock %}
{% block content %} {% block content %}
<h1>We need your help!</h1> <h1>{% trans %}We need your help!{% endtrans %}</h1>
<p>To get involved, please feel free to join us on the #i2p IRC channel (on <p>{% trans -%}
irc.freenode.net, or within I2P on irc.freshcoffee.i2p or irc.postman.i2p).</p> To get involved, please feel free to join us on the #i2p IRC channel (on
<p>If you're interested in joining our <a href="{{ site_url('about/team') }}">team</a>, please get in irc.freenode.net, or within I2P on irc.freshcoffee.i2p or irc.postman.i2p).
touch as we're always looking for eager contributors!</p> {%- endtrans %}</p>
<p> <p>{% trans team=site_url('about/team') -%}
If you're interested in joining our <a href="{{ team }}">team</a>, please get in
touch as we're always looking for eager contributors!
{%- endtrans %}</p>
<p>{% trans -%}
We need help in many areas, and you don't need to know Java to contribute! We need help in many areas, and you don't need to know Java to contribute!
Here's a list to help you get started!</p> Here's a list to help you get started!
{%- endtrans %}</p>
<ul> <ul>
<li><b>Spread the Word!</b> &mdash; <li><b>{% trans %}Spread the Word!{% endtrans %}</b> &mdash;
{% trans -%}
Tell people about I2P on forums, blogs, and comments to articles. Tell people about I2P on forums, blogs, and comments to articles.
Fix up the Wikipedia article about I2P in your language. Fix up the Wikipedia article about I2P in your language.
Tell your friends. Tell your friends.
</li><li><b>Testing</b> &mdash; {%- endtrans %}
Run the latest builds from <a href="monotone.html">monotone</a> </li><li><b>{{ _('Testing') }}</b> &mdash;
and report results on #i2p or as bugs on <a href="http://trac.i2p2.de/report/1">Trac</a>. {% trans monotone=site_url('get-involved/guides/monotone'), trac=i2pconv('trac.i2p2.i2p') -%}
</li><li><b>Documentation</b> &mdash; Run the latest builds from <a href="{{ monotone }}">monotone</a>
and report results on #i2p or as bugs on <a href="http://{{ trac }}/report/1">Trac</a>.
{%- endtrans %}
</li><li><b>{{ _('Documentation') }}</b> &mdash;
{% trans -%}
Help fix the parts of the website that are outdated or incomplete. Help fix the parts of the website that are outdated or incomplete.
Translate pages into other languages. Translate pages into other languages.
</li><li><b>Pictures</b> &mdash; {%- endtrans %}
</li><li><b>{{ _('Pictures') }}</b> &mdash;
{% trans -%}
Make some more pictures, fix the old ones on the website Make some more pictures, fix the old ones on the website
</li><li><b>Content</b> &mdash; {%- endtrans %}
</li><li><b>{{ _('Content') }}</b> &mdash;
{% trans -%}
Make an eepsite! Add some content! Contribute to the community! Make an eepsite! Add some content! Contribute to the community!
</li><li><b>Services</b> &mdash; {%- endtrans %}
</li><li><b>{{ _('Services') }}</b> &mdash;
{% trans -%}
Run a service on an eepsite. It could be a proxy, a forum, a tracker, Run a service on an eepsite. It could be a proxy, a forum, a tracker,
a naming service, a search engine, an eepsite monitor... many of these a naming service, a search engine, an eepsite monitor... many of these
aren't that hard. aren't that hard.
</li><li><b>Applications</b> &mdash; {%- endtrans %}
</li><li><b>{{ _('Applications') }}</b> &mdash;
{% trans apps=site_url('get-involved/develop/applications') -%}
Write or port applications for I2P! There's some guidelines and Write or port applications for I2P! There's some guidelines and
a list of ideas on the <a href="applications.html">applications page</a>. a list of ideas on the <a href="{{ apps }}">applications page</a>.
</li><li><b>Coding</b> &mdash; {%- endtrans %}
</li><li><b>{{ _('Coding') }}</b> &mdash;
{% trans trac=i2pconv('trac.i2p2.i2p'), zzz=i2pconv('zzz.i2p'), newdevs=site_url('get-involved/guides/new-developers') -%}
There's plenty to do if you know Java or are ready to learn. There's plenty to do if you know Java or are ready to learn.
Check for open tickets on <a href="http://trac.i2p2.de/report/1">Trac</a> Check for open tickets on <a href="http://{{ trac }}/report/1">Trac</a>
or the TODO list on <a href="http://zzz.i2p/">zzz.i2p</a> for or the TODO list on <a href="http://{{ zzz }}">{{ zzz }}</a> for
some ideas on where to start. some ideas on where to start.
See the <a href="{{ site_url('get-involved/guides/newdevelopers') }}">new developer's guide</a> for details. See the <a href="{{ newdevs }}">new developer's guide</a> for details.
</li><li><b>Translation</b> &mdash; {%- endtrans %}
</li><li><b>{{ _('Translation') }}</b> &mdash;
{% trans newtrans=site_url('get-involved/guides/new-translators') -%}
Help translate the website and the software into your language. Help translate the website and the software into your language.
See the <a href="{{ site_url('get-involved/guides/newtranslators') }}">new translator's guide</a> for details. See the <a href="{{ newtrans }}">new translator's guide</a> for details.
</li><li><b>Analysis</b> &mdash; {%- endtrans %}
</li><li><b>{{ _('Analysis') }}</b> &mdash;
{% trans threatmodel=site_url('docs/how/threat-model') -%}
Study or test the code to look for vulnerabilities. Study or test the code to look for vulnerabilities.
Both anonymity vulnerabilities from the various Both anonymity vulnerabilities from the various
<a href="{{ site_url('docs/how/threatmodel') }}">threat models</a>, <a href="{{ threatmodel }}">threat models</a>,
and DOS and other weaknesses due to securities holes, and DOS and other weaknesses due to securities holes,
need researching. need researching.
</li><li><b><a href="{{ site_url('get-involved/donate') }}">Donate</a></b> {%- endtrans %}
</li><li><b><a href="{{ site_url('get-involved/donate') }}">{{ _('Donate') }}</a></b>
</li></ul> </li></ul>
{% endblock %} {% endblock %}

View File

@@ -1,34 +1,42 @@
{% extends "global/layout.html" %} {% extends "global/layout.html" %}
{% block title %}Roadmap{% endblock %} {% block title %}{{ _('Roadmap') }}{% endblock %}
{% block content %} {% block content %}
<h2 id="v0.9">0.9</h2> <h2 id="v0.9">0.9</h2>
<ul> <ul>
<li>Include some seed data in the distribution so a central reseed location isn't required?</li> <li>{% trans -%}
<li>Reachability Mapping / handle peers partially reachable / enhanced <a href="{{ site_url('get-involved/todo') }}#fullRestrictedRoutes">restricted routes</a></li> Include some seed data in the distribution so a central reseed location isn't required?
<li>Improve help pages and website</li> {%- endtrans %}</li>
<li>More translations</li> <li>{% trans todo=site_url('get-involved/todo') -%}
<li>SSU disconnect message</li> Reachability Mapping / handle peers partially reachable / enhanced <a href="{{ todo }}#fullRestrictedRoutes">restricted routes</a>
<li>Iterative floodfill lookups</li> {%- endtrans %}</li>
<li>{% trans %}Improve help pages and website{% endtrans %}</li>
<li>{% trans %}More translations{% endtrans %}</li>
<li>{% trans %}SSU disconnect message{% endtrans %}</li>
<li>{% trans %}Iterative floodfill lookups{% endtrans %}</li>
</ul> </ul>
<h2 id="v1.0">1.0</h2> <h2 id="v1.0">1.0</h2>
<ul> <ul>
<li>Full review of anonymity issues and other vulnerabilities</li> <li>{% trans %}Full review of anonymity issues and other vulnerabilities{% endtrans %}</li>
<li>Reduce memory usage, remove debugging overhead, make it run better on slow and embedded machines</li> <li>{% trans -%}
<li>Docs</li> Reduce memory usage, remove debugging overhead, make it run better on slow and embedded machines
{%- endtrans %}</li>
<li>{{ _('Docs') }}</li>
</ul> </ul>
<h2 id="v2.0">2.0</h2> <h2 id="v2.0">2.0</h2>
<ul> <ul>
<li>Full restricted routes</li> <li>{% trans %}Full restricted routes{% endtrans %}</li>
</ul> </ul>
<h2 id="v3.0">3.0</h2> <h2 id="v3.0">3.0</h2>
<ul> <ul>
<li>Tunnel mixing and padding</li> <li>{% trans %}Tunnel mixing and padding{% endtrans %}</li>
<li>User defined message delays</li> <li>{% trans %}User defined message delays{% endtrans %}</li>
</ul> </ul>
<p>Please see the <a href="{{ site_url('get-involved/todo') }}">TODO</a> list for more detailed info about some of these tasks.</p> <p>{% trans todo=site_url('get-involved/todo') -%}
Please see the <a href="{{ todo }}">TODO</a> list for more detailed info about some of these tasks.
{%- endtrans %}</p>
{% endblock %} {% endblock %}

View File

@@ -1,349 +1,461 @@
{% extends "global/layout.html" %} {% extends "global/layout.html" %}
{% block title %}To Do List{% endblock %} {% block title %}{{ _('To Do List') }}{% endblock %}
{% block content %} {% block content %}
<h1>I2P Project Targets</h1> <h1>{{ _('I2P Project Targets') }}</h1>
<p>Below is a more detailed (yet still incomplete) discussion of the major areas <p>{% trans roadmap=site_url('get-involved/roadmap'), volunteer=site_url('get-involved') -%}
of future development on the core I2P network, spanning the plausibly planned Below is a more detailed (yet still incomplete) discussion of the major areas
releases. This does not include stego transports, porting to wireless devices, of future development on the core I2P network, spanning the plausibly planned
or tools to secure the local machine, nor does it include client applications releases. This does not include stego transports, porting to wireless devices,
that will be essential in I2P's success. There are probably other things that or tools to secure the local machine, nor does it include client applications
will come up, especially as I2P gets more peer review, but these are the main that will be essential in I2P's success. There are probably other things that
'big things'. See also <a href="{{ site_url('get-involved/roadmap') }}">the roadmap</a>. Want to help? will come up, especially as I2P gets more peer review, but these are the main
<a href="{{ site_url('get-involved') }}">Get involved</a>! </p> 'big things'. See also <a href="{{ roadmap }}">the roadmap</a>. Want to help?
<br /> <a href="{{ volunteer }}">Get involved</a>!
<h2>Core functionality <span class="permalink"><a href="#core">[link]</a></span></h2> {%- endtrans %}</p>
<h2>{{ _('Core functionality') }} <span class="permalink"><a href="#core">[{{ _('link') }}]</a></span></h2>
<ul class="targetlist"> <ul class="targetlist">
<li><a href="#nat">NAT/Firewall bridging via 1-hop restricted routes</a></li> <li><a href="#nat">{% trans -%}
<li><a href="#transport">High degree transport layer with UDP, NBIO, or NIO</a></li> NAT/Firewall bridging via 1-hop restricted routes
<li><a href="#netdb">NetworkDB and profile tuning and ejection policy for {%- endtrans %}</a></li>
large nets</a></li> <li><a href="#transport">{% trans -%}
High degree transport layer with UDP, NBIO, or NIO
{%- endtrans %}</a></li>
<li><a href="#netdb">{% trans -%}
NetworkDB and profile tuning and ejection policy for large nets
{%- 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">Per-hop tunnel id &amp; new permuted TunnelVerificationStructure <li><a href="#tunnelId">{% trans -%}
encryption</a></li> Per-hop tunnel id &amp; new permuted TunnelVerificationStructure encryption
<li><a href="#ordering">Strict ordering of participants within tunnels</a></li> {%- endtrans %}</a></li>
<li><a href="#tunnelLength">Randomly permuted tunnel lengths</a></li> <li><a href="#ordering">{% trans -%}
<li><a href="#fullRestrictedRoutes">Full blown n-hop restricted routes with Strict ordering of participants within tunnels
optional trusted links</a></li> {%- endtrans %}</a></li>
<li><a href="#hashcash">Hashcash for routerIdentity, destination, and tunnel <li><a href="#tunnelLength">{% trans -%}
request</a></li> Randomly permuted tunnel lengths
<li><a href="#batching">Advanced tunnel operation (batching/mixing/throttling/padding)</a></li> {%- endtrans %}</a></li>
<li><a href="#stop">Stop &amp; go mix w/ garlics &amp; tunnels</a></li> <li><a href="#fullRestrictedRoutes">{% trans -%}
Full blown n-hop restricted routes with optional trusted links
{%- endtrans %}</a></li>
<li><a href="#hashcash">{% trans -%}
Hashcash for routerIdentity, destination, and tunnel request
{%- endtrans %}</a></li>
<li><a href="#batching">{% trans -%}
Advanced tunnel operation (batching/mixing/throttling/padding)
{%- endtrans %}</a></li>
<li><a href="#stop">{% trans -%}
Stop &amp; go mix w/ garlics &amp; tunnels
{%- endtrans %}</a></li>
</ul> </ul>
<h2>Performance <span class="permalink"><a href="performance.html">[link]</a></span></h2> <h2>{{ _('Performance') }} <span class="permalink"><a href="performance.html">[{{ _('link') }}]</a></span></h2>
<h2 id="core">Core functionality</h2>
<h2 id="core">{{ _('Core functionality') }}</h2>
<ul class="targetlist"> <ul class="targetlist">
<li> <li>
<h3 id="nat">NAT/Firewall bridging via 1-hop restricted routes</h3> <h3 id="nat">{% trans -%}
NAT/Firewall bridging via 1-hop restricted routes
{%- endtrans %}</h3>
</li> </li>
<!-- <li style="list-style: none; display: inline"> --> <!-- <li style="list-style: none; display: inline"> -->
<b><i>Implemented in I2P 0.6.0.6</i></b> <b><i>{{ _('Implemented in I2P 0.6.0.6') }}</i></b>
<p>The functionality of allowing routers to fully participate within the network <p>{% trans -%}
while behind firewalls and NATs that they do not control requires some basic The functionality of allowing routers to fully participate within the network
restricted route operation (since those peers will not be able to receive while behind firewalls and NATs that they do not control requires some basic
inbound connections). To do this successfully, you consider peers one of restricted route operation (since those peers will not be able to receive
two ways:</p> inbound connections). To do this successfully, you consider peers one of
two ways:
{%- endtrans %}</p>
<!-- </li> --> <!-- </li> -->
</ul> </ul>
<ul> <ul>
<li><b>Peers who have reachable interfaces</b> - these peers do not need to <li>{% trans -%}
do anything special</li> <b>Peers who have reachable interfaces</b> - these peers do not need to
<li><b>Peers who do not have reachable interfaces</b> - these peers must build do anything special
a tunnel pointing at them where the gateway is one of the peers they have {%- endtrans %}</li>
established a connection with who has both a publicly reachable interface <li>{% trans -%}
and who has agreed to serve as their 'introducer'.</li> <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> </ul>
<div style="margin-left:25px;"> <div style="margin-left:25px;">
<p>To do this, peers who have no IP address simply connect to a few peers, <p>{% trans -%}
build a tunnel through them, and publish a reference to those tunnels within To do this, peers who have no IP address simply connect to a few peers,
their RouterInfo structure in the network database.</p> build a tunnel through them, and publish a reference to those tunnels within
<p>When someone wants to contact any particular router, they first must get their RouterInfo structure in the network database.
its RouterInfo from the network database, which will tell them whether they {%- endtrans %}</p>
can connect directly (e.g. the peer has a publicly reachable interface) <p>{% trans -%}
or whether they need to contact them indirectly. Direct connections occur When someone wants to contact any particular router, they first must get
as normal, while indirect connections are done through one of the published its RouterInfo from the network database, which will tell them whether they
tunnels.</p> can connect directly (e.g. the peer has a publicly reachable interface)
<p>When a router just wants to get a message or two to a specific hidden peer, or whether they need to contact them indirectly. Direct connections occur
they can just use the indirect tunnel for sending the payload. However, as normal, while indirect connections are done through one of the published
if the router wants to talk to the hidden peer often (for instance, as part tunnels.
of a tunnel), they will send a garlic routed message through the indirect {%- endtrans %}</p>
tunnel to that hidden peer which unwraps to contain a message which should <p>{% trans -%}
be sent to the originating router. That hidden peer then establishes an When a router just wants to get a message or two to a specific hidden peer,
outbound connection to the originating router and from then on, those two they can just use the indirect tunnel for sending the payload. However,
routers can talk to each other directly over that newly established direct if the router wants to talk to the hidden peer often (for instance, as part
connection.</p> of a tunnel), they will send a garlic routed message through the indirect
<p>Of course, that only works if the originating peer can receive connections tunnel to that hidden peer which unwraps to contain a message which should
(they aren't also hidden). However, if the originating peer is hidden, they be sent to the originating router. That hidden peer then establishes an
can simply direct the garlic routed message to come back to the originating outbound connection to the originating router and from then on, those two
peer's inbound tunnel.</p> routers can talk to each other directly over that newly established direct
<p>This is not meant to provide a way for a peer's IP address to be concealed, connection.
merely as a way to let people behind firewalls and NATs fully operate within {%- endtrans %}</p>
the network. Concealing the peer's IP address adds a little more work, as <p>{% trans -%}
described <a href="#fullRestrictedRoutes">below.</a></p> Of course, that only works if the originating peer can receive connections
<p>With this technique, any router can participate as any part of a tunnel. (they aren't also hidden). However, if the originating peer is hidden, they
For efficiency purposes, a hidden peer would be a bad choice for an inbound can simply direct the garlic routed message to come back to the originating
gateway, and within any given tunnel, two neighboring peers wouldn't want peer's inbound tunnel.
to be hidden. But that is not technically necessary.</p> {%- 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> </div>
<ul class="targetlist"> <ul class="targetlist">
<li> <li>
<h3 id="transport">High degree transport layer with UDP, NBIO, or NIO</h3> <h3 id="transport">{% trans -%}
<b><i>Both UDP and NIO have been Implemented in I2P</i></b> High degree transport layer with UDP, NBIO, or NIO
<p>Standard TCP communication in Java generally requires blocking socket {%- endtrans %}</h3>
calls, and to keep a blocked socket from hanging the entire system, those <b><i>{{ _('Both UDP and NIO have been Implemented in I2P') }}</i></b>
blocking calls are done on their own threads. Our current TCP transport <p>{% trans -%}
is implemented in a naive fashion - for each peer we are talking to, we Standard TCP communication in Java generally requires blocking socket
have one thread reading and one thread writing. The reader thread simply calls, and to keep a blocked socket from hanging the entire system, those
loops a bunch of read() calls, building I2NP messages and adding them blocking calls are done on their own threads. Our current TCP transport
to our internal inbound message queue, and the writer thread pulls messages is implemented in a naive fashion - for each peer we are talking to, we
off a per-connection outbound message queue and shoves the data through have one thread reading and one thread writing. The reader thread simply
write() calls.</p> loops a bunch of read() calls, building I2NP messages and adding them
<p>We do this fairly efficiently, from a CPU perspective - at any time, to our internal inbound message queue, and the writer thread pulls messages
almost all of these threads are sitting idle, blocked waiting for something off a per-connection outbound message queue and shoves the data through
to do. However, each thread consumes real resources (on older Linux kernels, write() calls.
for instance, each thread would often be implemented as a fork()'ed process). {%- endtrans %}</p>
As the network grows, the number of peers each router will want to talk <p>{% trans -%}
with will increase (remember, I2P is fully connected, meaning that any We do this fairly efficiently, from a CPU perspective - at any time,
given peer should know how to get a message to any other peer, and restricted almost all of these threads are sitting idle, blocked waiting for something
route support will probably not significantly reduce the number of connections to do. However, each thread consumes real resources (on older Linux kernels,
necessary). This means that with a 100,000 router network, each router for instance, each thread would often be implemented as a fork()'ed process).
will have up to 199,998 threads just to deal with the TCP connections!</p> As the network grows, the number of peers each router will want to talk
<p>Obviously, that just won't work. We need to use a transport layer that with will increase (remember, I2P is fully connected, meaning that any
can scale. In Java, we have two main camps:</p> 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> <h4>UDP</h4>
<b><i>Implemented in I2P 0.6 ("SSU") as documented <a href="{{ site_url('docs/transport/ssu') }}">elsewhere</a></i></b> <b><i>{% trans ssu=site_url('docs/transport/ssu') -%}
<p>Sending and receiving UDP datagrams is a connectionless operation - if Implemented in I2P 0.6 ("SSU") as documented <a href="{{ ssu }}">elsewhere</a>
we are communicating with 100,000 peers, we simply stick the UDP packets {%- endtrans %}</i></b>
in a queue and have a single thread pulling them off the queue and shoving <p>{% trans -%}
them out the pipe (and to receive, have a single thread pulling in any Sending and receiving UDP datagrams is a connectionless operation - if
UDP packets received and adding them to an inbound queue).</p> we are communicating with 100,000 peers, we simply stick the UDP packets
<p>However, moving to UDP means losing the benefits of TCP's ordering, congestion in a queue and have a single thread pulling them off the queue and shoving
control, MTU discovery, etc. Implementing that code will take significant them out the pipe (and to receive, have a single thread pulling in any
work, however I2P doesn't need it to be as strong as TCP. Specifically, UDP packets received and adding them to an inbound queue).
a while ago I was taking some measurements in the simulator and on the {%- endtrans %}</p>
live net, and the vast majority of messages transferred would fit easily <p>{% trans -%}
within a single unfragmented UDP packet, and the largest of the messages However, moving to UDP means losing the benefits of TCP's ordering, congestion
would fit within 20-30 packets. As mule pointed out, TCP adds a significant control, MTU discovery, etc. Implementing that code will take significant
overhead when dealing with so many small packets, as the ACKs are within work, however I2P doesn't need it to be as strong as TCP. Specifically,
an order of magnitude in size. With UDP, we can optimize the transport a while ago I was taking some measurements in the simulator and on the
for both efficiency and resilience by taking into account I2P's particular live net, and the vast majority of messages transferred would fit easily
needs.</p> within a single unfragmented UDP packet, and the largest of the messages
<p>It will be a lot of work though.</p> would fit within 20-30 packets. As mule pointed out, TCP adds a significant
<h4>NIO or NBIO</h4> overhead when dealing with so many small packets, as the ACKs are within
<b><i>NIO Implemented in I2P 0.6.1.22 ("NTCP")</i></b> an order of magnitude in size. With UDP, we can optimize the transport
<p>In Java 1.4, a set of "New I/O" packages was introduced, allowing Java for both efficiency and resilience by taking into account I2P's particular
developers to take advantage of the operating system's nonblocking IO needs.
capabilities - allowing you to maintain a large number of concurrent IO {%- endtrans %}</p>
operations without requiring a separate thread for each. There is much <p>{% trans -%}
promise with this approach, as we can scalable handle a large number of It will be a lot of work though.
concurrent connections and we don't have to write a mini-TCP stack with {%- endtrans %}</p>
UDP. However, the NIO packages have not proven themselves to be battle-ready, <h4>{{ _('NIO or NBIO') }}</h4>
as the Freenet developer's found. In addition, requiring NIO support would <b><i>{% trans -%}
mean we can't run on any of the open source JVMs like <a href="http://www.kaffe.org/">Kaffe</a>, NIO Implemented in I2P 0.6.1.22 ("NTCP")
as <a href="http://www.classpath.org/">GNU/Classpath</a> has only limited {%- endtrans %}</i></b>
support for NIO. <i>(note: this may not be the case anymore, as there <p>{% trans -%}
has been some progress on Classpath's NIO, but it is an unknown quantity)</i></p> In Java 1.4, a set of "New I/O" packages was introduced, allowing Java
<p>Another alternative along the same lines is the <a href="http://www.eecs.harvard.edu/~mdw/proj/java-nbio/">Non developers to take advantage of the operating system's nonblocking IO
Blocking I/O</a> package - essentially a cleanroom NIO implementation capabilities - allowing you to maintain a large number of concurrent IO
(written before NIO was around). It works by using some native OS code operations without requiring a separate thread for each. There is much
to do the nonblocking IO, passing off events through Java. It seems to promise with this approach, as we can scalable handle a large number of
be working with Kaffe, though there doesn't seem to be much development concurrent connections and we don't have to write a mini-TCP stack with
activity on it lately (likely due to 1.4's NIO deployment).</p> 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> </li>
</ul> </ul>
<ul class="targetlist"> <ul class="targetlist">
<li> <li>
<h3 id="netdb">NetworkDB and profile tuning and ejection policy for large <h3 id="netdb">{% trans -%}
nets</h3> NetworkDB and profile tuning and ejection policy for large nets
<p>Within the current network database and profile management implementation, {%- endtrans %}</h3>
we have taken the liberty of some practical shortcuts. For instance, we <p>{% trans -%}
don't have the code to drop peer references from the K-buckets, as we Within the current network database and profile management implementation,
don't have enough peers to even plausibly fill any of them, so instead, we have taken the liberty of some practical shortcuts. For instance, we
we just keep the peers in whatever bucket is appropriate. Another example don't have the code to drop peer references from the K-buckets, as we
deals with the peer profiles - the memory required to maintain each peer's don't have enough peers to even plausibly fill any of them, so instead,
profile is small enough that we can keep thousands of full blown profiles we just keep the peers in whatever bucket is appropriate. Another example
in memory without problems. While we have the capacity to use trimmed deals with the peer profiles - the memory required to maintain each peer's
down profiles (which we can maintain 100s of thousands in memory), we profile is small enough that we can keep thousands of full blown profiles
don't have any code to deal with moving a profile from a "minimal profile" in memory without problems. While we have the capacity to use trimmed
to a "full profile", a "full profile" to a "minimal profile", or to simply down profiles (which we can maintain 100s of thousands in memory), we
eject a profile altogether. It just wouldn't be practical to write that don't have any code to deal with moving a profile from a "minimal profile"
code yet, since we aren't going to need it for a while.</p> to a "full profile", a "full profile" to a "minimal profile", or to simply
<p>That said, as the network grows we are going to want to keep these considerations eject a profile altogether. It just wouldn't be practical to write that
in mind. We will have some work to do, but we can put it off for later.</p> code yet, since we aren't going to need it for a while.
{%- endtrans %}</p>
<p>{% trans -%}
That said, as the network grows we are going to want to keep these considerations
in mind. We will have some work to do, but we can put it off for later.
{%- endtrans %}</p>
</li> </li>
</ul> </ul>
<h2 id="security">Security / anonymity</h2> <h2 id="security">{{ _('Security / anonymity') }}</h2>
<ul class="targetlist"> <ul class="targetlist">
<li> <li>
<h3 id="tunnelId">Per-hop tunnel id &amp; new permuted TunnelVerificationStructure <h3 id="tunnelId">{% trans -%}
encryption</h3> Per-hop tunnel id &amp; new permuted TunnelVerificationStructure encryption
<b><i>Addressed in I2P 0.5 as documented <a href="tunnel-alt.html">elsewhere</a></i></b> {%- endtrans %}</h3>
<p>Right now, if Alice builds a four hop inbound tunnel starting at Elvis, <b><i>{% trans tunnelimpl=site_url('docs/tunnels/implementation') -%}
going to Dave, then to Charlie, then Bob, and finally Alice (A&lt;--B&lt;--C&lt;--D&lt;--E), Addressed in I2P 0.5 as documented <a href="{{ tunnelimpl }}">elsewhere</a>
all five of them will know they are participating in tunnel "123", as {%- endtrans %}</i></b>
the messages are tagged as such. What we want to do is give each hop their <p>{% trans -%}
own unique tunnel hop ID - Charlie will receive messages on tunnel 234 Right now, if Alice builds a four hop inbound tunnel starting at Elvis,
and forward them to tunnel 876 on Bob. The intent is to prevent Bob or going to Dave, then to Charlie, then Bob, and finally Alice (A&lt;--B&lt;--C&lt;--D&lt;--E),
Charlie from knowing that they are in Alice's tunnel, as if each hop in all five of them will know they are participating in tunnel "123", as
the tunnel had the same tunnel ID, collusion attacks aren't much work. the messages are tagged as such. What we want to do is give each hop their
</p> own unique tunnel hop ID - Charlie will receive messages on tunnel 234
<p>Adding a unique tunnel ID per hop isn't hard, but by itself, insufficient. and forward them to tunnel 876 on Bob. The intent is to prevent Bob or
If Dave and Bob are under the control of the same attacker, they wouldn't Charlie from knowing that they are in Alice's tunnel, as if each hop in
be able to tell they are in the same tunnel due to the tunnel ID, but the tunnel had the same tunnel ID, collusion attacks aren't much work.
would be able to tell by the message bodies and verification structures {%- endtrans %}</p>
by simply comparing them. To prevent that, the tunnel must use layered <p>{% trans -%}
encryption along the path, both on the payload of the tunneled message Adding a unique tunnel ID per hop isn't hard, but by itself, insufficient.
and on the verification structure (used to prevent simple tagging attacks). If Dave and Bob are under the control of the same attacker, they wouldn't
This requires some simple modifications to the TunnelMessage, as well be able to tell they are in the same tunnel due to the tunnel ID, but
as the inclusion of per-hop secret keys delivered during tunnel creation would be able to tell by the message bodies and verification structures
and given to the tunnel's gateway. We must fix a maximum tunnel length by simply comparing them. To prevent that, the tunnel must use layered
(e.g. 16 hops) and instruct the gateway to encrypt the message to each encryption along the path, both on the payload of the tunneled message
of the 16 delivered secret keys, in reverse order, and to encrypt the and on the verification structure (used to prevent simple tagging attacks).
signature of the hash of the (encrypted) payload at each step. The gateway This requires some simple modifications to the TunnelMessage, as well
then sends that 16-step encrypted message, along with a 16-step and 16-wide as the inclusion of per-hop secret keys delivered during tunnel creation
encrypted mapping to the first hop, which then decrypts the mapping and and given to the tunnel's gateway. We must fix a maximum tunnel length
the payload with their secret key, looking in the 16-wide mapping for (e.g. 16 hops) and instruct the gateway to encrypt the message to each
the entry associated with their own hop (keyed by the per-hop tunnel ID) of the 16 delivered secret keys, in reverse order, and to encrypt the
and verifying the payload by checking it against the associated signed signature of the hash of the (encrypted) payload at each step. The gateway
hash.</p> then sends that 16-step encrypted message, along with a 16-step and 16-wide
<p>The tunnel gateway does still have more information than the other peers encrypted mapping to the first hop, which then decrypts the mapping and
in the tunnel, and compromising both the gateway and a tunnel participant the payload with their secret key, looking in the 16-wide mapping for
would allow those peers to collude, exposing the fact that they are both the entry associated with their own hop (keyed by the per-hop tunnel ID)
in the same tunnel. In addition, neighboring peers know that they are and verifying the payload by checking it against the associated signed
in the same tunnel anyway, as they know who they send the message to (and hash.
with IP-based transports without restricted routes, they know who they {%- endtrans %}</p>
got it from). However, the above two techniques significantly increase <p>{% trans -%}
the cost of gaining meaningful samples when dealing with longer tunnels.</p> 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> </li></ul>
<ul class="targetlist"> <ul class="targetlist">
<li> <li>
<h3 id="ordering">Strict ordering of participants within tunnels</h3> <h3 id="ordering">{% trans -%}
<b><i>Implemented in release 0.6.2</i></b></li> Strict ordering of participants within tunnels
{%- endtrans %}</h3>
<b><i>{{ _('Implemented in release 0.6.2') }}</i></b></li>
</ul> </ul>
<div style="margin-left:25px"> <div style="margin-left:25px">
<p>As Connelly <a href="http://article.gmane.org/gmane.network.i2p/22/">proposed</a> <p>{% trans link='http://article.gmane.org/gmane.network.i2p/22/',
to deal with the <a href="http://prisms.cs.umass.edu/brian/pubs/wright-tissec.pdf">predecessor pdf1='http://prisms.cs.umass.edu/brian/pubs/wright-tissec.pdf',
attack</a> <a href="http://prisms.cs.umass.edu/brian/pubs/wright.tissec.2008.pdf">(2008 pdf2='http://prisms.cs.umass.edu/brian/pubs/wright.tissec.2008.pdf' -%}
update)</a>, keeping the order of peers within our tunnels consistent As Connelly <a href="{{ link }}">proposed</a> to deal with the
(aka whenever Alice creates a tunnel with both Bob and Charlie in it, <a href="{{ pdf1 }}">predecessor attack</a> <a href="{{ pdf2 }}">(2008
Bob's next hop is always Charlie), we address the issue as Bob doesn't update)</a>, keeping the order of peers within our tunnels consistent
get to substantially sample Alice's peer selection group. We may even (aka whenever Alice creates a tunnel with both Bob and Charlie in it,
want to explicitly allow Bob to participate in Alice's tunnels in only Bob's next hop is always Charlie), we address the issue as Bob doesn't
one way - receiving a message from Dave and sending it to Charlie - and get to substantially sample Alice's peer selection group. We may even
if any of those peers are not available to participate in the tunnel (due want to explicitly allow Bob to participate in Alice's tunnels in only
to overload, network disconnection, etc), avoid asking Bob to participate one way - receiving a message from Dave and sending it to Charlie - and
in any tunnels until they are back online.</p> if any of those peers are not available to participate in the tunnel (due
<p>More analysis is necessary for revising the tunnel creation - at the to overload, network disconnection, etc), avoid asking Bob to participate
moment, we simply select and order randomly within the peer's top tier in any tunnels until they are back online.
of peers (ones with fast + high capacity).</p> {%- endtrans %}</p>
<p>Adding a strict ordering to peers in a tunnel also improves the anonymity <p>{% trans -%}
of peers with 0-hop tunnels, as otherwise the fact that a peer's gateway More analysis is necessary for revising the tunnel creation - at the
is always the same would be particularly damning. However, peers with moment, we simply select and order randomly within the peer's top tier
0-hop tunnels may want to periodically use a 1-hop tunnel to simulate of peers (ones with fast + high capacity).
the failure of a normally reliable gateway peer (so every MTBF*(tunnel {%- endtrans %}</p>
duration) minutes, use a 1-hop tunnel).</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> </div>
<ul class="targetlist"><li> <ul class="targetlist"><li>
<h3 id="tunnelLength">Randomly permuted tunnel lengths</h3> <h3 id="tunnelLength">Randomly permuted tunnel lengths</h3>
<b><i>Addressed in I2P 0.5 as documented <a href="tunnel-alt.html">elsewhere</a></i></b></li> <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>
<ul class="targetlist"> <ul class="targetlist">
<!-- <li style="list-style: none; display: inline"> --> <!-- <li style="list-style: none; display: inline"> -->
<p>Without tunnel length permutation, if someone were to somehow detect that <p>{% trans -%}
a destination had a particular number of hops, it might be able to use that Without tunnel length permutation, if someone were to somehow detect that
information to identify the router the destination is located on, per the a destination had a particular number of hops, it might be able to use that
predecessor attack. For instance, if everyone has 2-hop tunnels, if Bob information to identify the router the destination is located on, per the
receives a tunnel message from Charlie and forwards it to Alice, Bob knows predecessor attack. For instance, if everyone has 2-hop tunnels, if Bob
Alice is the final router in the tunnel. If Bob were to identify what destination receives a tunnel message from Charlie and forwards it to Alice, Bob knows
that tunnel served (by means of colluding with the gateway and harvesting Alice is the final router in the tunnel. If Bob were to identify what destination
the network database for all of the LeaseSets), he would know the router that tunnel served (by means of colluding with the gateway and harvesting
on which that destination is located (and without restricted routes, that the network database for all of the LeaseSets), he would know the router
would mean what IP address the destination is on).</p> on which that destination is located (and without restricted routes, that
<p>It is to counter user behavior that tunnel lengths should be permuted, would mean what IP address the destination is on).
using algorithms based on the length requested (for example, the 1/MTBF {%- endtrans %}</p>
length change for 0-hop tunnels outlined above).</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> <li>
<h3 id="fullRestrictedRoutes">Full blown n-hop restricted routes with optional <h3 id="fullRestrictedRoutes">{% trans -%}
trusted links</h3> Full blown n-hop restricted routes with optional trusted links
<p>The restricted route functionality described before was simply a functional {%- endtrans %}</h3>
issue - how to let peers who would not otherwise be able to communicate <p>{% trans -%}
do so. However, the concept of allowing restricted routes includes additional The restricted route functionality described before was simply a functional
capabilities. For instance, if a router absolutely cannot risk communicating issue - how to let peers who would not otherwise be able to communicate
directly with any untrusted peers, they can set up trusted links through do so. However, the concept of allowing restricted routes includes additional
those peers, using them to both send and receive all of its messages. capabilities. For instance, if a router absolutely cannot risk communicating
Those hidden peers who want to be completely isolated would also refuse directly with any untrusted peers, they can set up trusted links through
to connect to peers who attempt to get them to (as demonstrated by the those peers, using them to both send and receive all of its messages.
garlic routing technique outlined before) - they can simply take the garlic Those hidden peers who want to be completely isolated would also refuse
clove that has a request for delivery to a particular peer and tunnel to connect to peers who attempt to get them to (as demonstrated by the
route that message out one of the hidden peer's trusted links with instructions garlic routing technique outlined before) - they can simply take the garlic
to forward it as requested.</p> clove that has a request for delivery to a particular peer and tunnel
route that message out one of the hidden peer's trusted links with instructions
to forward it as requested.
{%- endtrans %}</p>
</li> </li>
<li> <li>
<h3 id="hashcash">Hashcash for routerIdentity, destination, and tunnel request</h3> <h3 id="hashcash">{% trans -%}
<p>Within the network, we will want some way to deter people from consuming Hashcash for routerIdentity, destination, and tunnel request
too many resources or from creating so many peers to mount a <a href="http://citeseer.ist.psu.edu/douceur02sybil.html">Sybil</a> {%- endtrans %}</h3>
attack. Traditional techniques such as having a peer see who is requesting <p>{% trans link='http://citeseer.ist.psu.edu/douceur02sybil.html' -%}
a resource or running a peer aren't appropriate for use within I2P, as Within the network, we will want some way to deter people from consuming
doing so would compromise the anonymity of the system. Instead, we want too many resources or from creating so many peers to mount a <a href="{{ link }}">Sybil</a>
to make certain requests "expensive".</p> attack. Traditional techniques such as having a peer see who is requesting
<p><a href="http://www.hashcash.org/">Hashcash</a> is one technique that a resource or running a peer aren't appropriate for use within I2P, as
we can use to anonymously increase the "cost" of doing certain activities, doing so would compromise the anonymity of the system. Instead, we want
such as creating a new router identity (done only once on installation), to make certain requests "expensive".
creating a new destination (done only once when creating a service), or {%- endtrans %}</p>
requesting that a peer participate in a tunnel (done often, perhaps 2-300 <p>{% trans -%}
times per hour). We don't know the "correct" cost of each type of certificate <a href="http://www.hashcash.org/">Hashcash</a> is one technique that
yet, but with some research and experimentation, we could set a base level we can use to anonymously increase the "cost" of doing certain activities,
that is sufficiently expensive while not an excessive burden for people such as creating a new router identity (done only once on installation),
with few resources.</p> creating a new destination (done only once when creating a service), or
<p>There are a few other algorithms that we can explore for making those requesting that a peer participate in a tunnel (done often, perhaps 2-300
requests for resources "nonfree", and further research on that front is times per hour). We don't know the "correct" cost of each type of certificate
appropriate.</p> yet, but with some research and experimentation, we could set a base level
that is sufficiently expensive while not an excessive burden for people
with few resources.
{%- endtrans %}</p>
<p>{% trans -%}
There are a few other algorithms that we can explore for making those
requests for resources "nonfree", and further research on that front is
appropriate.
{%- endtrans %}</p>
</li> </li>
<li> <li>
<h3 id="batching">Advanced tunnel operation (batching/mixing/throttling/padding)</h3> <h3 id="batching">{% trans -%}
<p>To powerful passive external observers as well as large colluding internal Advanced tunnel operation (batching/mixing/throttling/padding)
observers, standard tunnel routing is vulnerable to traffic analysis attacks {%- endtrans %}</h3>
- simply watching the size and frequency of messages being passed between <p>{% trans pdf='http://freehaven.net/doc/sync-batching/sync-batching.pdf' -%}
routers. To defend against these, we will want to essentially turn some To powerful passive external observers as well as large colluding internal
of the tunnels into its own mix cascade - delaying messages received at observers, standard tunnel routing is vulnerable to traffic analysis attacks
the gateway and passing them in batches, reordering them as necessary, - simply watching the size and frequency of messages being passed between
and injecting dummy messages (indistinguishable from other "real" tunnel routers. To defend against these, we will want to essentially turn some
messages by peers in the path). There has been a significant amount of of the tunnels into its own mix cascade - delaying messages received at
<a href="http://freehaven.net/doc/sync-batching/sync-batching.pdf">research</a> the gateway and passing them in batches, reordering them as necessary,
on these algorithms that we can lean on prior to implementing the various and injecting dummy messages (indistinguishable from other "real" tunnel
tunnel mixing strategies.</p> messages by peers in the path). There has been a significant amount of
<p>In addition to the anonymity aspects of more varied tunnel operation, <a href="{{ pdf }}">research</a>
there is a functional dimension as well. Each peer only has a certain on these algorithms that we can lean on prior to implementing the various
amount of data they can route for the network, and to keep any particular tunnel mixing strategies.
tunnel from consuming an unreasonable portion of that bandwidth, they {%- endtrans %}</p>
will want to include some throttles on the tunnel. For instance, a tunnel <p>{% trans -%}
may be configured to throttle itself after passing 600 messages (1 per In addition to the anonymity aspects of more varied tunnel operation,
second), 2.4MB (4KBps), or exceeding some moving average (8KBps for the there is a functional dimension as well. Each peer only has a certain
last minute). Excess messages may be delayed or summarily dropped. With amount of data they can route for the network, and to keep any particular
this sort of throttling, peers can provide ATM-like QoS support for their tunnel from consuming an unreasonable portion of that bandwidth, they
tunnels, refusing to agree to allocate more bandwidth than the peer has will want to include some throttles on the tunnel. For instance, a tunnel
available.</p> may be configured to throttle itself after passing 600 messages (1 per
<p>In addition, we may want to implement code to dynamically reroute tunnels second), 2.4MB (4KBps), or exceeding some moving average (8KBps for the
to avoid failed peers or to inject additional hops into the path. This last minute). Excess messages may be delayed or summarily dropped. With
can be done by garlic routing a message to any particular peer in a tunnel this sort of throttling, peers can provide ATM-like QoS support for their
with instructions to redefine the next-hop in the tunnel.</p> tunnels, refusing to agree to allocate more bandwidth than the peer has
available.
{%- endtrans %}</p>
<p>{% trans -%}
In addition, we may want to implement code to dynamically reroute tunnels
to avoid failed peers or to inject additional hops into the path. This
can be done by garlic routing a message to any particular peer in a tunnel
with instructions to redefine the next-hop in the tunnel.
{%- endtrans %}</p>
</li> </li>
<li> <li>
<h3 id="stop">Stop &amp; go mix w/ garlics &amp; tunnels</h3> <h3 id="stop">{% trans -%}
<p>Beyond the per-tunnel batching and mixing strategy, there are further Stop &amp; go mix w/ garlics &amp; tunnels
capabilities for protecting against powerful attackers, such as allowing {%- endtrans %}</h3>
each step in a garlic routed path to define a delay or window in which <p>{% trans -%}
it should be forwarded on. This would enable protections against the long Beyond the per-tunnel batching and mixing strategy, there are further
term intersection attack, as a peer could send a message that looks perfectly capabilities for protecting against powerful attackers, such as allowing
standard to most peers that pass it along, except at any peers where the each step in a garlic routed path to define a delay or window in which
clove exposed includes delay instructions.</p> it should be forwarded on. This would enable protections against the long
term intersection attack, as a peer could send a message that looks perfectly
standard to most peers that pass it along, except at any peers where the
clove exposed includes delay instructions.
{%- endtrans %}</p>
</li> </li>
</ul> </ul>
<h2 id="performance">Performance</h2> <h2 id="performance">{{ _('Performance') }}</h2>
<p> <p>{% trans futureperf=site_url('about/performance/future') -%}
Performance related improvements are listed on the Performance related improvements are listed on the
<a href="performance.html">Performance</a> page. <a href="{{ futureperf }}">Performance</a> page.
</p> {%- endtrans %}</p>
{% endblock %} {% endblock %}