datagram and applications updates
This commit is contained in:
@@ -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 %}
|
||||
|
@@ -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>
|
||||
|
||||
|
||||
|
||||
|
@@ -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>
|
||||
|
Reference in New Issue
Block a user