here's some content that might help someone who wants to put together an application developer's guide for I2P - I dont have time to polish this up before I leave, but thought it might be of use to someone. Feel free to tear this up, edit like mad, or just read it :)

Application development guide

Why write I2P specific code?

Using mihi's I2PTunnel application, you can hook up application instances and have them talk to each other over standard TCP sockets. In plain client-server scenarios, this is an effective technique for many simple protocols, but for distributed systems where each peer may contact a number of other peers (instead of just a single server), or for systems that expose TCP or IP information within the communication protocols themselves, there are problems.

With I2PTunnel, you need to explicitly instantiate an I2PTunnel for each peer you want to contact - if you are building a distributed instant messenger application, that means you need to have each peer create an I2PTunnel 'client' pointing at each peer it wants to contact, plus a single I2PTunnel 'server' to receive other peer's connections. This process can of course be automated, but there are nontrivial overheads involved in running more than just a few I2PTunnel instances. 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 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 (host and port).

Applications that are designed to work with I2P can take advantage of its built in data security and optional pseudonymous authentication. All data sent over the network is transparently end to end encrypted (not even the router's get the cleartext), and any application using the ministreaming or datagram functionality has all of that data authenticated by the sending destination's public key. As an aside, environments where anonymity instead of pseudonymity is required are trivially accomodated by either using the I2CP directly, SAM RAW sessions, or by simply creating a new sending destination whenever needed).

Another important thing to remember is that I2P is simply a communication system - what data is sent and what is done with that data is outside of its scope. Applications that are used on top of I2P should be carefully sanitized of any insecure or identifying data or protocols (hostnames, port numbers, time zone, character set, etc). This in and of itself is often a daunting task, as analyzing the safety of a system that has had anonymity and security strapped on to it is no small feat, giving significant incentive to learn from the experiences of the traditional application base, but design the application and its communication protocols with I2P's anonymity and security in mind.

There are also efficiency considerations to review when determining how to interact on top of I2P. The ministreaming library and things built on top of it 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 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 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. The ministreaming library itself uses a functional but inefficient scheme for dealing with reliable and in order delivery by requiring the equivilant of an ACK after each message which must traverse the network end to end again (though there are plans for improving this with a more efficient and robust algorithm). Given that as the current state, an application that uses one of the I2P message oriented protocols can in some situations get substantially better performance.

Important ideas

There are a few changes that require adjusting to when using I2P:

Destination ~= host+port

An application running on I2P sends messages from and receives messages to a unique cryptographically secure end point - a "destination". In TCP or UDP terms, a destination could (largely) be considered the equivilant of a hostname plus port number pair, though there are a few differences.

Anonymity and confidentiality

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 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.

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 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.

I2P datagrams can be up to 32KB

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 entire request or response, allowing them to transparently operate in I2P as a UDP-like application without having to write fragmentation, resends, etc.

Integration techniques

There are four means of sending data over I2P, each with their own pros and cons.

SAM

SAM is the Simple Anonymous Messaging 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 and event based handling. SAM supports three styles of operation:

I2PTunnel

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 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 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.

ministreaming and datagrams

For applications written in Java, the simplest way to go is to use the libraries that the SAM bridge and I2PTunnel applications use. The streaming functionality is exposed in the 'ministreaming' library, which is centered on the I2PSocketManager, the I2PSocket, and the I2PServerSocket.

For applications that want to use repliable datagrams, they can be built with the I2PDatagramMaker and parsed on the receiving side by the I2PDatagramDissector. In turn, these are sent and received through an I2PSession.

Applications that want to use raw datagrams simply send directly through the I2PSession's sendMessage(...) method, receiving notification of available messages through the I2PSessionListener and then fetching those messages by calling receiveMessage(...).

I2CP

I2CP 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, 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 write a C SAM library instead.