datagram and applications updates

This commit is contained in:
zzz
2013-05-27 19:06:04 +00:00
parent 5512a5bf18
commit b8ec3d7cbe
3 changed files with 105 additions and 58 deletions

View File

@@ -3,6 +3,8 @@
{% block content %}
<h1>Application Development Guide</h1>
Last updated May 2013, current as of router version 0.9.6
<h2>Contents</h2>
<ul>
<li><a href="#why">Why write I2P-specific code?</a></li>
@@ -45,10 +47,10 @@
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 -
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 several KB. 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
by using (best effort) datagrams without having to worry about MTU detection or
fragmentation of messages under 32KB.
fragmentation of messages.
</p>
<div class="box" id="tunnel.serverclient" style="text-align:center">
@@ -84,9 +86,8 @@
<p>
Applications written in Java and accessible/runnable
using an HTML interface via the standard webapps/app.war
may be considered for inclusion in the i2p distribution.
I2P supports a standard <a href="plugins">plugins interface</a> for developers
so that applications may be easily integrated and distributed.
</p>
<h2 id="concepts">Important concepts</h2>
@@ -105,22 +106,22 @@ plus port number pair, though there are a few differences. </p>
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>
<li>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 it can even "multihome" - operate on multiple routers at
once). This is quite different from the TCP or UDP world where a single end point (port)
must stay on a single host.</li>
<li>
<p>
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
I2P destinations are ugly and large - behind the scenes, they contain a 2048 bit ElGamal
public key for encryption, a 1024 bit DSA public key for signing, and a variable size
certificate, which may contain proof of work or blinded data.
</p>
<p>
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
globally uniqueness (since they're stored locally at each person's machine as "hosts.txt")
and the current mechanism is not especially scalable nor secure (updates to one host file are
manually managed within Monotone, and as such, anyone with commit rights on the repository can
change the destinations). There may be some secure, human readable, scalable, and globally
and pretty names (e.g. "irc.duck.i2p"), but those techniques do not guarantee
globally uniqueness (since they're stored locally in a database on each person's machine)
and the current mechanism is not especially scalable nor secure (updates to the host list are
managed using "subscriptions" to naming services).
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,
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.
@@ -128,26 +129,38 @@ since there are those who don't think such a beast is possible.
</li>
</ul>
<p>
While most applications do not need to distinguish protocols and ports,
I2P <i>does</i> support them. Complex applications may specify a protocol,
from port, and to port, on a per-message basis, to multiplex traffic on
a single destination.
See the <a href="datagrams">datagram page</a> for details.
Simple applications operate by listening for "all protocols" on "all ports" of a destination.
</p>
<h3>Anonymity and confidentiality</h3>
<p>A useful thing to remember is that I2P has transparent end to end encryption
<p>I2P has transparent end to end encryption
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
library, Alice knows for certain that Bob's destination is the one who sent the data. </p>
<p>Of course, another useful thing to remember is that I2P transparently anonymizes the
<p>Of course, I2P transparently anonymizes the
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
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
to expose.</p>
<h3>I2P datagrams can be up to 32KB</h3>
<h3>I2P datagrams can be up to several KB</h3>
<p>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
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
UDP, applications don't need to worry about MTU detection and can simply fire off large datagrams.
While the upper limit is nominally 32 KB, the message is fragmented for transport, thus dropping
the reliability of the whole. Datagrams over about 10 KB are not currently recommended.
See the <a href="datagrams">datagram page</a> for details.
For many applications, 10 KB of data is sufficient for an
entire request or response, allowing them to transparently operate in I2P as a UDP-like
application without having to write fragmentation, resends, etc.</p>
@@ -175,7 +188,7 @@ found at this <a href="http://bob.i2p/">eepsite</a>.</p>
<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 recommended.</i></p>
<p>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
that bridge multiplex all of its I2P traffic, transparently coordinating the encryption/decryption
@@ -206,20 +219,27 @@ that fixes some of the problems in <a href="sam.html">SAM</a>.
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'
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 8-bit clean, and are
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
their own unique I2P destination and their own set of tunnels, keys, etc.</p>
<h3>Ministreaming</h3>
<p><i>Not recommended</i></p>
<h3>SOCKS</h3>
<p>
It was possible to write I2P applications in Java using the ministreaming library.
However, the Streaming library has superceded this, and provides better functionality.
I2P supports a SOCKS V4 and V5 proxy.
Outbound connections work well. Inbound (server) and UDP functionality may be incomplete
and untested.
</p>
<h3>Ministreaming</h3>
<p><i>Removed</i></p>
<p>
There used to be a simple "ministreaming" library,
but now ministreaming.jar contains only the interfaces for the full streaming library.
</p>
<h3>Datagrams</h3>
<p><i>Not recommended</i></p>
<p><i>Recommended for UDP-like applications</i></p>
The <a href="datagrams">Datagram library</a> allows sending UDP-like packets.
It's possible to use:
<ul>
@@ -245,12 +265,15 @@ If you are using Java, you can start development with the <a href="#start.stream
Using another programming language, SAM or BOB can be used.
<h3 id="start.streaming">Developing with the streaming library</h3>
<p>
The following example shows how to create TCP-like client and server applications
using the streaming library.
Development using the streaming library requires the following libraries in your classpath:
This will require the following libraries in your classpath:
<ul>
<li>$I2P/lib/streaming.jar: the streaming library itself.</li>
<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>
<li>$I2P/lib/streaming.jar: The streaming library itself</li>
<li>$I2P/lib/mstreaming.jar: Factory and interfaces for the streaming library</li>
<li>$I2P/lib/i2p.jar: Standard I2P classes, data structures, API, and utilities</li>
</ul>
<p>
@@ -261,7 +284,10 @@ Using another programming language, SAM or BOB can be used.
<p>
We will start by initializing the server application. This requires getting an I2PSocketManager
and creating an I2PServerSocket.
In addition, we will ask the I2PSocketManager for an I2PSession, so we can find out the Destination we use.
We will not provide the I2PSocketManagerFactory with the saved keys for an existing Destination,
so it will create a new Destination for us.
So we will ask the I2PSocketManager for an I2PSession, so we can find out the Destination that
was created, as we will need to copy and paste that information later so the client can connect to us.
</p>
<div class="box">
<pre>
@@ -279,7 +305,8 @@ Using another programming language, SAM or BOB can be used.
I2PSocketManager manager = I2PSocketManagerFactory.createManager();
I2PServerSocket serverSocket = manager.getServerSocket();
I2PSession session = manager.getSession();
System.out.println(session.getMyDestination().toBase64()); //Print the base64 string, the regular string would look like garbage.
//Print the base64 string, the regular string would look like garbage.
System.out.println(session.getMyDestination().toBase64());
//The additional main method code comes here...
}
@@ -323,7 +350,8 @@ Using another programming language, SAM or BOB can be used.
I2PSocketManager manager = I2PSocketManagerFactory.createManager();
I2PServerSocket serverSocket = manager.getServerSocket();
I2PSession session = manager.getSession();
System.out.println(session.getMyDestination().toBase64()); //Print the base64 string, the regular string would look like garbage.
//Print the base64 string, the regular string would look like garbage.
System.out.println(session.getMyDestination().toBase64());
</pre>
<pre><b>
@@ -345,8 +373,10 @@ Using another programming language, SAM or BOB can be used.
try {
I2PSocket sock = this.socket.accept();
if(sock != null) {
BufferedReader br = new BufferedReader(new InputStreamReader(sock.getInputStream())); //Receive from clients
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(sock.getOutputStream())); //Send to clients
//Receive from clients
BufferedReader br = new BufferedReader(new InputStreamReader(sock.getInputStream()));
//Send to clients
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(sock.getOutputStream()));
String line = br.readLine();
if(line != null) {
System.out.println("Received from client: " + line);
@@ -413,8 +443,6 @@ Using another programming language, SAM or BOB can be used.
import java.io.OutputStreamWriter;
import java.net.ConnectException;
import java.net.NoRouteToHostException;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.i2p.I2PException;
import net.i2p.client.streaming.I2PSocket;
import net.i2p.client.streaming.I2PSocketManager;
@@ -428,37 +456,42 @@ Using another programming language, SAM or BOB can be used.
I2PSocketManager manager = I2PSocketManagerFactory.createManager();
System.out.println("Please enter a Destination:");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String destinationString = null;
String destinationString;
try {
destinationString = br.readLine();
} catch (IOException ex) {
System.out.println("Failed to get a Destination string.");
return;
}
Destination destination = null;
Destination destination;
try {
destination = new Destination(destinationString);
} catch (DataFormatException ex) {
System.out.println("Destination string incorrectly formatted.");
return;
}
I2PSocket socket = null;
I2PSocket socket;
try {
socket = manager.connect(destination);
} catch (I2PException ex) {
System.out.println("General I2P exception occurred!");
return;
} catch (ConnectException ex) {
System.out.println("Failed to connect!");
return;
} catch (NoRouteToHostException ex) {
System.out.println("Couldn't find host!");
return;
} catch (InterruptedIOException ex) {
System.out.println("Sending/receiving was interrupted!");
return;
}
try {
//Write to server
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
bw.write("Hello I2P!\n");
bw.flush(); //Flush to make sure everything got sent
//Flush to make sure everything got sent
bw.flush();
//Read from server
BufferedReader br2 = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String s = null;
@@ -486,8 +519,8 @@ Using another programming language, SAM or BOB can be used.
Congratulations, you have successfully communicated over I2P!
</p>
<h2>Existing Applications in Development</h2>
Contact us if you would like to help.
<h2>Existing Applications</h2>
Contact us if you would like to contribute.
<ul>
<li>
<a href="http://i2pbote.i2p/">I2P-Bote</a> - contact HungryHobo
@@ -496,31 +529,31 @@ Contact us if you would like to help.
</li><li>
<a href="http://www.imule.i2p/">IMule</a>
</li><li>
<a href="http://forum.i2p/viewforum.php?f=25">I2Phex</a> - contact Complication
<a href="http://forum.i2p/viewforum.php?f=25">I2Phex</a>
<!--<a href="http://forum.i2p2.de/viewforum.php?f=25">(outside I2P)</a> -->
</li><li>I2PRufus - contact codevoid
</li><li>I2P-BT - contact sponge
</li><li><a href="http://bob.i2p">BOB</a> - contact sponge
</li></ul>
<p>
See also all the plugins on <a href="http://plugins.i2p/">plugins.i2p</a>,
the applications and source code listed on <a href="http://echelon.i2p/">echelon.i2p</a>,
and the application code hosted on <a href="http://git.repo.i2p/">git.repo.i2p</a>.
</p><p>
See also the bundled applications in the I2P distribution - SusiMail and I2PSnark.
</p>
<h2>Application Ideas</h2>
<ul>
<li>NNTP server - there have been some in the past, none at the moment
</li><li>Jabber server - there have been some in the past, and there is one at the moment, with access to the public internet
</li><li>PGP Key server and/or proxy
</li><li>Download manager / eepget scheduler -
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),
but there isn't any sort of user interface to it. A web based UI would be
great.
</li><li>Content Distribution / DHT applications - help out with <a href="http://feedspace.i2p/">feedspace</a>,
</li><li>Content Distribution / DHT applications - resurrect feedspace,
port dijjer, look for alternatives
</li><li>Help out with <a href="http://syndie.i2p2.de/">Syndie</a> development
</li><li>Web-based applications - The sky is the limit for hosting web-server-based
applications such as blogs, pastebins, storage, tracking, feeds, etc.
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 -
bogobot, pants, proxyscript, q, stasher, socks proxy, i2ping
</li><li>Resurrect some old apps, several previously in the i2p source package -
bogobot, pants, proxyscript, q, stasher, socks proxy, i2ping, feedspace
</li></ul>
{% endblock %}

View File

@@ -2,7 +2,7 @@
{% block title %}Datagram Specification{% endblock %}
{% block content %}
Updated August 2010, current as of router version 0.8
Last updated May 2013, current as of router version 0.9.6
<h2>Datagram Overview</h2>
<p>Datagrams build upon the base <a href="i2cp.html">I2CP</a> to provide authenticated
@@ -34,6 +34,8 @@ The application designer should carefully consider the tradeoff of repliable vs.
datagrams. Also, the datagram size will affect reliability, due to tunnel fragmentation into 1KB
tunnel messages. The more message fragments, the more likely that one of them will be dropped
by an intermediate hop. Messages larger than a few KB are not recommended.
Over about 10 KB, the delivery probablility drops dramatically.
Messages over 16 KB cannot be delivered over NTCP, dropping delivery chances even more.
</p>
<p>
Also note that the various overheads added by lower layers, in particular asymmetric
@@ -47,7 +49,8 @@ the ElGamal Session Tag parameters.
<h3>I2CP Protocol Number and Ports</h3>
<p>
The standard I2CP protocol number for datagrams is 17. Applications may or may not choose to set the
The standard I2CP protocol number for datagrams is PROTO_DATAGRAM (17).
Applications may or may not choose to set the
protocol in the I2CP header. It is not set by default.
It must be set to demultiplex datagram and streaming traffic received on the same Destination.
</p>
@@ -61,8 +64,13 @@ the <a href="i2cp.html#format">I2CP page</a>.
<p>
There is no method within the datagram API to specify whether it is non-repliable (raw)
or repliable. The application should be designed to expect the appropriate type.
The I2CP protocol number or port could also be used by the application to
The I2CP protocol number or port should be used by the application to
indicate datagram type.
The I2CP protocol numbers PROTO_DATAGRAM (signed) and PROTO_DATAGRAM_RAW are defined in the
<a href="http://docs.i2p-projekt.de/javadoc/net/i2p/client/I2PSession.html">I2PSession API</a>
for this purpose. A common design pattern in client/server datagram applications is to
use signed datagrams for a request which includes a nonce, and use a raw datagram
for the reply, returning the nonce from the request.
</p>
<p>
The protocols and ports may be set in I2CP's
@@ -161,11 +169,14 @@ Total length: Payload length + 427+
</pre>
<h4>Notes</h4>
<ul><li>
The practical length is limited by lower layers of protocols - the
<a href="transports.html">transports</a>
currently limit messages to about 32 KB, so the data length here is limited to about
31.5 KB.
</li><li>
See important notes above about the reliability of large datagrams.
</ul>

View File

@@ -32,6 +32,9 @@ If you find any inaccuracies in the documents linked below, please
<h3>Application-Layer Topics</h3>
<ul>
<li>
<a href="applications.html">Application Development Overview and Guide</a>
</li>
<li><a href="naming.html">Naming and Addressbook</a></li>
<li><a href="plugins.html">Plugins Overview</a></li>
<li><a href="plugin_spec.html">Plugin Specification</a></li>