I2CP

The I2P Client Protocol (I2CP) exposes a strong separation of concerns between
the router and any client that wishes to communicate over the network. It enables
secure and asynchronous messaging by sending and receiving messages over a
single TCP socket.
With I2CP, a client application tells the
router who they are (their "destination"), what anonymity, reliability, and
latency tradeoffs to make, and where to send messages. In turn the router uses
I2CP to tell the client when any messages have arrived, and to request authorization
for some tunnels to be used.

The protocol itself is implemented in Java, to provide the
Client SDK.
This SDK is exposed in the i2p.jar package, which implements the client-side of I2CP.
Clients should never need to access the router.jar package, which contains the
router itself and the router-side of I2CP.
There is also a C library implementation.
A non-Java client would also have to implement the
streaming library for TCP-style connections.

Applications can take advantage of the base I2CP plus the
streaming and datagram libraries
by using the Simple Anonymous Messaging or BOB protocols,
which do not require clients to deal with any sort of cryptography.
Also, clients may access the network by one of several proxies -
HTTP, CONNECT, and SOCKS 4/4a/5.
Alternatively, Java clients may access those libraries in ministreaming.jar and streaming.jar.
So there are several options for both Java and non-Java applications.

In a standard I2P installation, port 7654 is used by external java clients to communicate
with the local router via I2CP.
By default, the router binds to address 127.0.0.1. To bind to 0.0.0.0, set the
router advanced configuration option i2cp.tcp.bindAllInterfaces=true and restart.
Clients in the same JVM as the router pass messages directly to the router
through an internal JVM interface.

The router also supports external connections over SSL.
While SSL is not the default, it is strongly recommended for any traffic that may
be exposed to the open Internet. The authorization user/password (if any), the
Private Key and
Signing Private Key for the
Destination
are all transmitted in-the-clear unless SSL is enabled.

I2CP-Protokollspezifikation

I2CP-Initialisierung

When a client connects to the router, it first sends a single protocol version byte (0x2A).
Then it sends a GetDate Message and waits for the SetDate Message response.
Next, it sends a CreateSession Message containing the session configuration.
It next awaits a RequestLeaseSet Message from the router, indicating that inbound tunnels
have been built, and responds with a CreateLeaseSetMessage containing the signed LeaseSet.
The client may now initiate or receive connections from other I2P destinations.

The timeout (ms) for all sent messages. Unused.
See the protocol specification for per-message settings.

crypto.lowTagThreshold

0.9.2

1-128

30

Minimum number of ElGamal/AES Session Tags before we send more.
Recommended: approximately tagsToSend * 2/3

crypto.tagsToSend

0.9.2

1-128

40

Number of ElGamal/AES Session Tags to send at a time.
For clients with relatively low bandwidth per-client-pair (IRC, some UDP apps), this may be set lower.

explicitPeers

null

Comma-separated list of Base 64 Hashes of peers to build tunnels through; for debugging only

i2cp.dontPublishLeaseSet

true, false

false

Should generally be set to true for clients and false for servers

i2cp.fastReceive

0.9.4

true, false

false

If true, the router just sends the MessagePayload instead
of sending a MessageStatus and awaiting a ReceiveMessageBegin.

i2cp.leaseSetEncType

0.9.38

0

0-65535,...

0

The encryption type to be used, as of 0.9.38.
Interpreted client-side, but also passed to the router in the
SessionConfig, to declare intent and check support.
As of 0.9.39, may be comma-separated values for multiple types.
See PublicKey in common strutures spec for values.
See proposals 123, 144, and 145.

i2cp.leaseSetOfflineExpiration

0.9.38

The expiration of the offline signature, 4 bytes,
seconds since the epoch.
See proposal 123.

i2cp.leaseSetOfflineSignature

0.9.38

The base 64 of the offline signature.
See proposal 123.

i2cp.leaseSetTransientPublicKey

0.9.38

[type:]b64 The base 64 of the transient private key,
prefixed by an optional sig type number or name,
default DSA_SHA1.
See proposal 123.

i2cp.leaseSetType

0.9.38

1,3,5,7

1-255

1

The type of leaseset to be sent in the CreateLeaseSet2 Message.
Interpreted client-side, but also passed to the router in the
SessionConfig, to declare intent and check support.
See proposal 123.

i2cp.messageReliability

BestEffort, None

BestEffort

Guaranteed is disabled;
None implemented in 0.8.1; the streaming lib default is None as of 0.8.1, the client side default is None as of 0.9.4

i2cp.password

0.8.2

string

For authorization, if required by the router.
If the client is running in the same JVM as a router, this option is not required.
Warning - username and password are sent in the clear to the router, unless using SSL (i2cp.SSL=true).
Authorization is only recommended when using SSL.

i2cp.username

0.8.2

string

inbound.allowZeroHop

true, false

true

If incoming zero hop tunnel is allowed

outbound.allowZeroHop

true, false

true

If outgoing zero hop tunnel is allowed

inbound.backupQuantity

Zahl von 0 bis 3

Keine Begrenzung

0

Number of redundant fail-over for tunnels in

outbound.backupQuantity

Zahl von 0 bis 3

Keine Begrenzung

0

Number of redundant fail-over for tunnels out

inbound.IPRestriction

Zahl von 0 bis 4

0 an 4

2

Number of IP bytes to match to determine if
two routers should not be in the same tunnel. 0 to disable.

outbound.IPRestriction

Zahl von 0 bis 4

0 an 4

2

Number of IP bytes to match to determine if
two routers should not be in the same tunnel. 0 to disable.

inbound.length

Zahl von 0 bis 3

0 an 7

3

Länge der eingehenden Tunnel

outbound.length

Zahl von 0 bis 3

0 an 7

3

Länge der ausgehenden Tunnel

inbound.lengthVariance

Zahl von -1 bis 2

-7 an 7

0

Random amount to add or subtract to the length of tunnels in.
A positive number x means add a random amount from 0 to x inclusive.
A negative number -x means add a random amount from -x to x inclusive.
The router will limit the total length of the tunnel to 0 to 7 inclusive.
The default variance was 1 prior to release 0.7.6.

outbound.lengthVariance

Zahl von -1 bis 2

-7 an 7

0

Random amount to add or subtract to the length of tunnels out.
A positive number x means add a random amount from 0 to x inclusive.
A negative number -x means add a random amount from -x to x inclusive.
The router will limit the total length of the tunnel to 0 to 7 inclusive.
The default variance was 1 prior to release 0.7.6.

inbound.nickname

string

Name of tunnel - generally used in routerconsole, which will
use the first few characters of the Base64 hash of the destination by default.

outbound.nickname

string

Name of tunnel - generally ignored unless inbound.nickname is unset.

outbound.priority

0.9.4

Zahl von -25 bis 25

-25 an 25

0

Priority adjustment for outbound messages.
Higher is higher priority.

inbound.quantity

Zahl von 1 bis 3

1 an 16

2

Number of tunnels in.
Limit was increased from 6 to 16 in release 0.9; however, numbers higher than 6 are
incompatible with older releases.

outbound.quantity

Zahl von 1 bis 3

Keine Begrenzung

2

Number of tunnels out

inbound.randomKey

0.9.17

Base 64 encoding of 32 random bytes

Used for consistent peer ordering across restarts.

outbound.randomKey

0.9.17

Base 64 encoding of 32 random bytes

inbound.*

Any other options prefixed with "inbound." are stored
in the "unknown options" properties of the inbound tunnel pool's settings.

outbound.*

Any other options prefixed with "outbound." are stored
in the "unknown options" properties of the outbound tunnel pool's settings.

shouldBundleReplyInfo

0.9.2

true, false

true

Set to false to disable ever bundling a reply LeaseSet.
For clients that do not publish their LeaseSet, this option must be true
for any reply to be possible. "true" is also recommended for multihomed servers
with long connection times.

Setting to "false" may save significant outbound bandwidth, especially if
the client is configured with a large number of inbound tunnels (Leases).
If replies are still required, this may shift the bandwidth burden to
the far-end client and the floodfill.
There are several cases where "false" may be appropriate:

Unidirectional communication, no reply required

LeaseSet is published and higher reply latency is acceptable

LeaseSet is published, client is a "server", all connections are inbound
so the connecting far-end destination obviously has the leaseset already.
Connections are either short, or it is acceptable for latency on a long-lived
connection to temporarily increase while the other end re-fetches the LeaseSet
after expiration.
HTTP servers may fit these requirements.

Note: As of release 0.7.7, option names and values must use UTF-8 encoding.
This is primarily useful for nicknames.
Prior to that release, options with multi-byte characters were corrupted.
Since options are encoded in a Mapping,
all option names and values are limited to 255 bytes (not characters) maximum.

Client-side Options

The following options are interpreted on the client side,
and will be interpreted if passed to the I2PSession via the I2PClient.createSession() call.
The streaming lib should also pass these options through to I2CP.
Other implementations may have different defaults.

Client-side Options

Option

As Of Release

Empfohlene Argumente

Allowable Range

Standard

Beschreibung

i2cp.closeIdleTime

0.7.1

1800000

300000 minimum

(ms) Idle time required (default 30 minutes)

i2cp.closeOnIdle

0.7.1

true, false

false

Close I2P session when idle

i2cp.encryptLeaseSet

0.7.1

true, false

false

Encrypt the lease

i2cp.fastReceive

0.9.4

true, false

true

If true, the router just sends the MessagePayload instead
of sending a MessageStatus and awaiting a ReceiveMessageBegin.

i2cp.gzip

0.6.5

true, false

true

Gzip ausgehende Daten

i2cp.leaseSetEncType

0.9.38

0

0-65535,...

0

The encryption type to be used, as of 0.9.38.
Interpreted client-side, but also passed to the router in the
SessionConfig, to declare intent and check support.
As of 0.9.39, may be comma-separated values for multiple types.
See PublicKey in common strutures spec for values.
See proposals 123, 144, and 145.

i2cp.leaseSetKey

0.7.1

For encrypted leasesets. Base 64 SessionKey (44 characters)

i2cp.leaseSetPrivateKey

0.9.18

Base 64 private key for encryption.
Optionally preceded by the key type and ':'.
Only "ELGAMAL_2048:" is supported, which is the default.
I2CP will generate the public key from the private key.
Use for persistent leaseset keys across restarts.

i2cp.leaseSetSigningPrivateKey

0.9.18

Base 64 private key for signatures.
Optionally preceded by the key type and ':'.
DSA_SHA1 is the default.
Key type must match the signature type in the destination.
I2CP will generate the public key from the private key.
Use for persistent leaseset keys across restarts.

i2cp.leaseSetType

0.9.38

1,3,5,7

1-255

1

The type of leaseset to be sent in the CreateLeaseSet2 Message.
Interpreted client-side, but also passed to the router in the
SessionConfig, to declare intent and check support.
See proposal 123.

i2cp.messageReliability

BestEffort, None

None

Guaranteed is disabled;
None implemented in 0.8.1; None is the default as of 0.9.4

i2cp.reduceIdleTime

0.7.1

1200000

300000 minimum

(ms) Idle time required (default 20 minutes, minimum 5 minutes)

i2cp.reduceOnIdle

0.7.1

true, false

false

Die Anzahl der Tunnel bei Leerlauf reduzieren.

i2cp.reduceQuantity

0.7.1

1

1 an 5

1

Tunnel quantity when reduced (applies to both inbound and outbound)

i2cp.SSL

0.8.3

true, false

false

Connect to the router using SSL.
If the client is running in the same JVM as a router, this option is ignored, and the client connects to that router internally.

i2cp.tcp.host

127.0.0.1

Router hostname.
If the client is running in the same JVM as a router, this option is ignored, and the client connects to that router internally.

i2cp.tcp.port

1-65535

7654

Router I2CP port.
If the client is running in the same JVM as a router, this option is ignored, and the client connects to that router internally.

Note: All arguments, including numbers, are strings. True/false values are case-insensitive strings.
Anything other than case-insensitive "true" is interpreted as false.
All option names are case-sensitive.

I2CP-Nutzdatenformat und Multiplexverfahren

The end-to-end messages handled by I2CP (i.e. the data sent by the client in a
SendMessageMessage
and received by the client in a
MessagePayloadMessage)
are gzipped with a standard 10-byte gzip
header beginning with 0x1F 0x8B 0x08 as
specified by RFC 1952.
As of release 0.7.1, I2P uses ignored portions of the gzip header to include
protocol, from-port, and to-port information, thus supporting streaming and
datagrams on the same destination, and allowing query/response using datagrams
to work reliably in the presence of multiple channels.