{% extends "_layout.html" %} {% block title %}I2CP Specification{% endblock %} {% block content %} Updated November 2012, current as of router version 0.9.3
This page specified the I2P Control Protocol (I2CP), which is the interface between clients and the router. Java clients will use the I2CP client API, which implements this protocol. Non-Java clients will most likely use a higher-layer protocol such as SAM or BOB.
The protocol is only serialized if the client and router are not in the same JVM; otherwise, I2CP message objects are passed via an internal JVM interface.
More information is on the I2CP Overview page.
The protocol was designed to handle multiple "sessions", each with a 2-byte session ID, over a single TCP connection. This does not appear to be fully implemented. Do not attempt to use multiple sessions on a single I2CP connection.
It also appears that there are some provisions for a single client to talk to multiple routers over separate connections. This is also untested, and probably not useful.
It does not appear that there is currently a way for a session to be maintained after a disconnect, or to be recovered on a different I2CP connection.
{% filter escape %} Client Router ---------------------> Protocol Byte (0x2a) ---------------------> Get Date Message Set Date Message <--------------------- ---------------------> Create Session Message Session Status Message <--------------------- Request LeaseSet Message <--------------------- ---------------------> Create LeaseSet Message {% endfilter %}
{% filter escape %} Client Router ---------------------> Protocol Byte (0x2a) ---------------------> Get Bandwidth Limits Message Bandwidth Limits Message <--------------------- {% endfilter %}
{% filter escape %} Client Router ---------------------> Protocol Byte (0x2a) ---------------------> Dest Lookup Message Dest Reply Message <--------------------- {% endfilter %}
Existing session, with i2cp.messageReliability=none
{% filter escape %} Client Router ---------------------> Send Message Message {% endfilter %}
Existing session, with i2cp.messageReliability=BestEffort
{% filter escape %} Client Router ---------------------> Send Message Message Message Status Message <--------------------- (accepted) Message Status Message <--------------------- (succeeded) {% endfilter %}
Existing session, with i2cp.fastReceive=true (as of 0.9.4)
{% filter escape %} Client Router Message Payload Message <--------------------- {% endfilter %}
Existing session, with i2cp.fastReceive=false
{% filter escape %} Client Router Message Status Message <--------------------- (available) ---------------------> Receive Message Begin Message Message Payload Message <--------------------- ---------------------> Receive Message End Message {% endfilter %}
The initial protocol version byte (0x2a) sent by the client is not expected to change. Prior to release 0.8.7, the router's version information was not available to the client, thus preventing new clients from working with old routers. As of release 0.8.7, the two parties' protocol version strings are exchanged in the Get/Set Date Messages. Going forward, clients may use this information to communicate correctly with old routers. Clients and routers should not send messages that are unsupported by the other side, as they generally disconnect the session upon reception of an unsupported message.
Common header to all I2CP messages, containing the message length and message type.
Actual message length limit is about 64 KB.
Uniquely identifies a message waiting on a particular router at a point in time.
Message IDs are unique within a session only; they are not globally unique.
This structure is the content of a message being delivered from one Destination to another.
The payload is in a gzip format as specified on the I2CP Overview page.
Defines the configuration options for a particular client session.
The options are specified on the I2CP Overview page.
Uniquely identifies a session on a particular router at a point in time.
Message | Direction | Type |
---|---|---|
BandwidthLimitsMessage | R->C | 23 |
CreateLeaseSetMessage | C->R | 4 |
CreateSessionMessage | C->R | 1 |
DestLookupMessage | C->R | 34 |
DestReplyMessage | R->C | 35 |
DestroySessionMessage | C->R | 3 |
DisconnectMessage | bidir. | 30 |
GetBandwidthLimitsMessage | C->R | 8 |
GetDateMessage | C->R | 32 |
MessagePayloadMessage | R->C | 31 |
MessageStatusMessage | R->C | 22 |
ReceiveMessageBeginMessage | C->R | 6 |
ReceiveMessageEndMessage | C->R | 7 |
ReconfigureSessionMessage | C->R | 2 |
ReportAbuseMessage | bidir. | 29 |
RequestLeaseSetMessage | R->C | 21 |
SendMessageMessage | C->R | 5 |
SendMessageExpiresMessage | C->R | 36 |
SessionStatusMessage | R->C | 20 |
SetDateMessage | R->C | 33 |
Tell the client what the bandwidth limits are. Sent from Router to Client in response to a Get Bandwidth Limits Message.
Currently, the client limits are the only values set, and are actually the router limits. All the values labeled as router limits are always 0. As of release 0.7.2.
This message is sent in response to a RequestLeaseSetMessage and contains all of the Lease structures that should be published to the I2NP Network Database. Sent from Client to Router.
The SigningPrivateKey matches the SigningPublicKey from within the LeaseSet, as does the PrivateKey with the PublicKey. The Signing keys are necessary to allow the router to revoke the LeaseSet if the client goes offline, and the normal keys are necessary for decrypting garlic routed messages. The LeaseSet granted may include Lease structures for tunnels pointing at another router if the client is actively connected to multiple routers with Leases granted to each. Really? Revocation is unimplemented. Connection to multiple routers is untested.
This message is sent from a client to initiate a session, where a session is defined as a single Destination's connection to the network, to which all messages for that Destination will be delivered and from which all messages that Destination sends to any other Destination will be sent through. Sent from Client to Router. The router responds with a Session Status Message.
The second message sent by the client after sending the Get Date Message and receiving the Set Date Message response. If the Date in the Session Config is too far from the router's current time, the session will be rejected. If there is already a session on the router for this Destination, the session will be rejected.
Sent from Client to Router. The router responds with a Dest Reply Message.
As of release 0.7. As of release 0.8.3, multiple outstanding lookups are supported, and lookups are supported in both I2PSimpleSession and in standard sessions.
Sent from Router to Client in response to a Dest Lookup Message.
As of release 0.7. As of release 0.8.3, the requested Hash is returned if the lookup failed, so that the client may have multiple lookups outstanding and correlate the replies to the lookups. Prior to release 0.8.3, the response was empty on failure.
This message is sent from a client to destroy a session. Sent from Client to Router. The router responds with a Session Status Message.
The router at this point should release all resources related to the session.
Tell the other party that there are problems and the current connection is about to be destroyed. This does not necessarily end a session. Sent either from router to client or from client to router.
Only implemented in the router-to-client direction. Disconnecting probably does end a session, in practice.
Request that the router state what its current bandwidth limits are. Sent from Client to Router. The router responds with a Bandwidth Limits Message.
As of release 0.7.2. As of release 0.8.3, supported in both I2PSimpleSession and in standard sessions.
Sent from Client to Router. The router responds with a Set Date Message.
Generally the first message sent by the client after sending the protocol version byte. The version string is included as of release 0.8.7. This is only useful if the client and router are not in the same JVM. If it is not present, the client is version 0.8.6 or earlier.
Deliver the payload of a message to the client. Sent from Router to Client. The client responds with a Receive Message End Message.
Notify the client of the delivery status of an incoming or outgoing message. Sent from Router to Client. If this message indicates that an incoming message is available, the client responds with a Receive Message Begin Message. For an outgoing message, this is a response to a Send Message Message or Send Message Expires Message.
The known status values are 0 for message is available, 1 for accepted, 2 for best effort succeeded, 3 for best effort failed, 4 for guaranteed succeeded, 5 for guaranteed failed. The size Integer specifies the size of the available message and is only relevant for status = 0. Even though guaranteed is unimplemented, (best effort is the only service), the current router implementation uses the guaranteed status codes, not the best effort codes.
When status = 1 (accepted), the nonce matches the nonce in the Send Message Message, and the included Message ID will be used for subsequent success or failure notification. Otherwise, the nonce may be ignored.
Request the router to deliver a message that it was previously notified of. Sent from Client to Router. The router responds with a Message Payload Message.
The ReceiveMessageBeginMessage is sent as a response to a MessageStatusMessage stating that a new message is available for pickup. If the message id specified in the ReceiveMessageBeginMessage is invalid or incorrect, the router may simply not reply, or it may send back a DisconnectMessage.
Tell the router that delivery of a message was completed successfully and that the router can discard the message. Sent from Client to Router.
The ReceiveMessageBeginMessage is sent after a MessagePayloadMessage fully delivers a message's payload.
Sent from Client to Router to update the session configuration. The router responds with a Session Status Message.
As of release 0.7.1.
Tell the other party (client or router) that they are under attack, potentially with reference to a particular messageId. If the router is under attack, the client may decide to migrate to another router, and if a client is under attack, the router may rebuild its routers or shitlist some of the peers that sent it messages delivering the attack. Sent either from router to client or from client to router.
Unused. Not fully implemented. Both router and client can generate Report Abuse Messages, but neither has a handler for the message when received.
Request that a client authorize the inclusion of a particular set of inbound tunnels. Sent from Router to Client. The client responds with a Create LeaseSet Message.
This is how a client sends a message (the payload) to the Destination. The router will use a default expiration. Sent from Client to Router. The router responds with a Message Status Message.
As soon as the SendMessageMessage arrives fully intact, the router should return a MessageStatusMessage stating that it has been accepted for delivery. That message will contain the same nonce sent here. Later on, based on the delivery guarantees of the session configuration, the router may additionally send back another MessageStatusMessage updating the status.
As of release 0.8.1, the router does not send either Message Status Message if i2cp.messageReliability=none.
Prior to release 0.9.4, a nonce value of 0 was not allowed. As of release 0.9.4, a nonce value of 0 is allowed, and tells to the router that it should not send either Message Status Message, i.e. it acts as if i2cp.messageReliability=none for this message only.
Sent from Client to Router. Same as Send Message Message, except includes an expiration.
As of release 0.7.1.
As soon as the SendMessageExpiresMessage arrives fully intact, the router should return a MessageStatusMessage stating that it has been accepted for delivery. That message will contain the same nonce sent here. Later on, based on the delivery guarantees of the session configuration, the router may additionally send back another MessageStatusMessage updating the status.
As of release 0.8.1, the router does not send either Message Status Message if i2cp.messageReliability=none.
Prior to release 0.9.4, a nonce value of 0 was not allowed. As of release 0.9.4, a nonce value of 0 is allowed, and tells the router that it should not send either Message Status Message, i.e. it acts as if i2cp.messageReliability=none for this message only.
As of release 0.8.4, the upper two bytes of the Date are redefined to contain flags. The flags must default to all zeros for backward compatibility. The Date will not encroach on the flags field until the year 10889. The flags may be used by the application to provide hints to the router as to whether a LeaseSet and/or ElGamal/AES Session Tags should be delivered with the message. The settings will significantly affect the amount of protocol overhead and the reliability of message delivery. The individual flag bits are defined as follows, as of release 0.9.2. Definitions are subject to change. Use the SendMessageOptions class to construct the flags.
Bit order: 15...0
Bits 15-9: Unused, must be zero
Bit 8: If 1, don't send lease set
Bits 7-4: Low tag threshold. If there are less than this many tags available, send more.
Field value | Tag threshold |
---|---|
0000 | Use session key manager settings |
0001 | 2 |
0010 | 3 |
0011 | 6 |
0100 | 9 |
0101 | 14 |
0110 | 20 |
0111 | 27 |
1000 | 35 |
1001 | 45 |
1010 | 57 |
1011 | 72 |
1100 | 92 |
1101 | 117 |
1110 | 147 |
1111 | 192 |
Bits 3-0: Number of tags to send if required.
Field value | Tags to send |
---|---|
0000 | Use session key manager settings |
0001 | 2 |
0010 | 4 |
0011 | 6 |
0100 | 8 |
0101 | 12 |
0110 | 16 |
0111 | 24 |
1000 | 32 |
1001 | 40 |
1010 | 51 |
1011 | 64 |
1100 | 80 |
1101 | 100 |
1110 | 125 |
1111 | 160 |
Instruct the client as to the status of its session. Sent from Router to Client.
Status values include 0 for destroyed, 1 for created, 2 for updated, and 3 for invalid session. If created, the Session ID is the identifier to be used for the rest of the session.
The current date and time. Sent from Router to Client as a part of the initial handshake.
This is generally the first message sent by the router. The version string is included as of release 0.8.7. This is only useful if the client and router are not in the same JVM. If it is not present, the router is version 0.8.6 or earlier.
{% endblock %}