Overview
This is the specification of the I2P Control Protocol (I2CP), the low-level interface between clients and the router. Java clients will use the I2CP client API, which implements this protocol.
There are no known non-Java implementations of a client-side library that implements I2CP. Additionally, socket-oriented (streaming) applications would need an implementation of the streaming protocol, but there are no non-Java libraries for that either. Therefore, non-Java clients should instead use the higher-layer protocol SAM [SAMv3], for which libraries exist in several languages.
This is a low-level protocol supported both internally and externally by the Java I2P router. The protocol is only serialized if the client and router are not in the same JVM; otherwise, I2CP message Java objects are passed via an internal JVM interface. I2CP is also supported externally by the C++ router i2pd.
More information is on the I2CP Overview page [I2CP].
Sessions
The protocol was designed to handle multiple "sessions", each with a 2-byte session ID, over a single TCP connection, however, Multiple sessions were not implemented until version 0.9.21. See the multisession section below. Do not attempt to use multiple sessions on a single I2CP connection with routers older than version 0.9.21.
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.
Example Message Sequences
Note: The examples below do not show the Protocol Byte (0x2a) that must be sent from the client to the router when first connecting. More information about connection initialization is on the I2CP Overview page [I2CP].
Standard Session Establish
Client Router
---------------------> Get Date Message
Set Date Message <---------------------
---------------------> Create Session Message
Session Status Message <---------------------
Request LeaseSet Message <---------------------
---------------------> Create LeaseSet Message
Get Bandwidth Limits (Simple Session)
Client Router
---------------------> Get Bandwidth Limits Message
Bandwidth Limits Message <---------------------
Destination Lookup (Simple Session)
Client Router
---------------------> Dest Lookup Message
Dest Reply Message <---------------------
Outgoing Message
Existing session, with i2cp.messageReliability=none
Client Router
---------------------> Send Message Message
Existing session, with i2cp.messageReliability=none and nonzero nonce
Client Router
---------------------> Send Message Message
Message Status Message <---------------------
(succeeded)
Existing session, with i2cp.messageReliability=BestEffort
Client Router
---------------------> Send Message Message
Message Status Message <---------------------
(accepted)
Message Status Message <---------------------
(succeeded)
Incoming Message
Existing session, with i2cp.fastReceive=true (as of 0.9.4)
Client Router
Message Payload Message <---------------------
Existing session, with i2cp.fastReceive=false
Client Router
Message Status Message <---------------------
(available)
---------------------> Receive Message Begin Message
Message Payload Message <---------------------
---------------------> Receive Message End Message
Multisession Notes
Multiple sessions on a single I2CP connection are supported as of router version 0.9.21. The first session that is created is the "primary session". Additional sessions are "subsessions". Subsessions are used to support multiple destinations sharing a common set of tunnels. The initial application is for the primary session to use ECDSA signing keys, while the subsession uses DSA signing keys for communication with old eepsites.
Subsessions share the same inbound and outbound tunnel pools as the primary session. Subsessions must use the same encryption keys as the primary session. This applies both to the LeaseSet encryption keys and the (unused) Destination encryption keys. Subsessions must use different signing keys in the destination, so the destination hash is different from the primary session. As subsessions use the same encryption keys and tunnels as the primary session, it is apparent to all that the Destinations are running on the same router, so the usual anti-correlation anonymity guarantees do not apply.
Subsessions are created by sending a CreateSession message and receiving a SessionStatus message in reply, as usual. Subsessions must be created after the primary session is created. The SessionStatus response will, on success, contain a unique Session ID, distinct from the ID for the primary session. While CreateSession messages should be processed in-order, there is no sure way to correlate a CreateSession message with the response, so a client should not have multiple CreateSession messages outstanding simultaneously. SessionConfig options for the subsession may not be honored where they are different from the primary session. In particular, since subsessions use the same tunnel pool as the primary session, tunnel options may be ignored.
The router will send separate RequestVariableLeaseSet messages for each Destination to the client, and the client must reply with a CreateLeaseSet message for each. The leases for the two Destinations will not necessarily be identical, even though they are selected from the same tunnel pool.
A subsession may be destroyed with the DestroySession message as usual. This will not destroy the primary session or stop the I2CP connection. Destroying the primary session will, however, destroy all subsessions and stop the I2CP connection. A Disconnect message destroys all sessions.
Note that most, but not all, I2CP messages contain a Session ID. For the ones that do not, clients may need additional logic to properly handle router responses. DestLookup and DestReply do not contain Session IDs; use the newer HostLookup and HostReply instead. GetBandwidthLimts and BandwidthLimits do not contain session IDs, however the response is not session-specific.
Support for multiple sessions is preliminary and subject to change. Support may not be complete in other parts of the API and user interface, particularly streaming and i2ptunnel. Current support is primarily for clients (i.e. Destinations that do not publish their leaseset or accept incoming connections), and is incomplete and untested for servers. Future releases may provide additional features and options.
Version Notes
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.
The exchanged version information is the "core" API version or I2CP protocol version, and is not necessarily the router version.
A basic summary of the I2CP protocol versions is as follows. For details, see below.
Version | Required I2CP Features |
---|---|
0.9.62 | MessageStatus message Loopback error code |
0.9.43 | BlindingInfo message supported Additional HostReply message failure codes |
0.9.41 | EncryptedLeaseSet options MessageStatus message Meta LS error code |
0.9.39 | CreateLeaseSet2 message and options supported Dest/LS key certs w/ RedDSA Ed25519 sig type supported |
0.9.38 | Preliminary CreateLeaseSet2 message supported (abandoned) |
0.9.21 | Multiple sessions on a single I2CP connection supported |
0.9.20 | Additional SetDate messages may be sent to the client at any time |
0.9.16 | Authentication, if enabled, is required via GetDate before all other messages |
0.9.15 | Dest/LS key certs w/ EdDSA Ed25519 sig type supported |
0.9.14 | Per-message override of messageReliability=none with nonzero nonce |
0.9.12 | Dest/LS key certs w/ ECDSA P-256, P-384, and P-521 sig types supported Note: RSA sig types also supported as of this version, but currently unused |
0.9.11 | Host Lookup and Host Reply messages supported Authentication mapping in Get Date message supported |
0.9.7 | Request Variable Lease Set message supported |
0.9.5 | Additional Message Status codes defined |
0.9.4 | Send Message nonce=0 allowed Fast receive mode is the default |
0.9.2 | Send Message Expires flag tag bits supported |
0.9 | Supports up to 16 leases in a lease set (6 previously) |
0.8.7 | Get Date and Set Date version strings included. If not present, the client or router is version 0.8.6 or older. |
0.8.4 | Send Message Expires flag bits supported |
0.8.3 | Dest Lookup and Get Bandwidth messages supported in standard session Concurrent Dest Lookup messages supported |
0.8.1 | i2cp.messageReliability=none supported |
0.7.2 | Get Bandwidth Limits and Bandwidth Limits messages supported |
0.7.1 | Send Message Expires message supported Reconfigure Session message supported Ports and protocol numbers in gzip header |
0.7 | Dest Lookup and Dest Reply messages supported |
0.6.5 or lower | All messages and features not listed above |
Common structures
I2CP message header
Description
Common header to all I2CP messages, containing the message length and message type.
Contents
Notes
Actual message length limit is about 64 KB.
Message ID
Description
Uniquely identifies a message waiting on a particular router at a point in time. This is always generated by the router and is NOT the same as the nonce generated by the client.
Contents
- 4 byte [Integer]
Notes
Message IDs are unique within a session only; they are not globally unique.
Payload
Description
This structure is the content of a message being delivered from one Destination to another.
Contents
- 4 byte [Integer] length
- That many bytes
Notes
The payload is in a gzip format as specified on the I2CP Overview page [I2CP-FORMAT].
Actual message length limit is about 64 KB.
Session Config
Description
Defines the configuration options for a particular client session.
Contents
- [Destination]
- [Mapping] of options
- Creation [Date]
- [Signature] of the previous 3 fields, signed by the [SigningPrivateKey]
Notes
- The options are specified on the I2CP Overview page [I2CP-OPTIONS].
- The [Mapping] must be sorted by key so that the signature will be validated correctly in the router.
- The creation date must be within +/- 30 seconds of the current time when processed by the router, or the config will be rejected.
Offline Signatures
- If the [Destination] is offline signed, the [Mapping] must contain the three options i2cp.leaseSetOfflineExpiration, i2cp.leaseSetTransientPublicKey, and i2cp.leaseSetOfflineSignature. The [Signature] is then generated by the transient [SigningPrivateKey] and is verified with the [SigningPublicKey] specified in i2cp.leaseSetTransientPublicKey. See [I2CP-OPTIONS] for details.
Session ID
Description
Uniquely identifies a session on a particular router at a point in time.
Contents
- 2 byte [Integer]
Notes
Session ID 0xffff is used to indicate "no session", for example for hostname lookups.
Messages
See also the I2CP Javadocs [I2CP-JAVADOCS].
Message Types
Message | Direction | Type | Since |
---|---|---|---|
BandwidthLimitsMessage | R -> C | 23 | 0.7.2 |
BlindingInfoMessage | C -> R | 42 | 0.9.43 |
CreateLeaseSetMessage | C -> R | 4 | |
CreateLeaseSet2Message | C -> R | 41 | 0.9.39 |
CreateSessionMessage | C -> R | 1 | |
DestLookupMessage | C -> R | 34 | 0.7 |
DestReplyMessage | R -> C | 35 | 0.7 |
DestroySessionMessage | C -> R | 3 | |
DisconnectMessage | bidir. | 30 | |
GetBandwidthLimitsMessage | C -> R | 8 | 0.7.2 |
GetDateMessage | C -> R | 32 | |
HostLookupMessage | C -> R | 38 | 0.9.11 |
HostReplyMessage | R -> C | 39 | 0.9.11 |
MessagePayloadMessage | R -> C | 31 | |
MessageStatusMessage | R -> C | 22 | |
ReceiveMessageBeginMessage | C -> R | 6 | |
ReceiveMessageEndMessage | C -> R | 7 | |
ReconfigureSessionMessage | C -> R | 2 | 0.7.1 |
ReportAbuseMessage | bidir. | 29 | |
RequestLeaseSetMessage | R -> C | 21 | |
RequestVariableLeaseSetMessage | R -> C | 37 | 0.9.7 |
SendMessageMessage | C -> R | 5 | |
SendMessageExpiresMessage | C -> R | 36 | 0.7.1 |
SessionStatusMessage | R -> C | 20 | |
SetDateMessage | R -> C | 33 |
BandwidthLimitsMessage
Description
Tell the client what the bandwidth limits are.
Sent from Router to Client in response to a GetBandwidthLimitsMessage.
Contents
- 4 byte [Integer] Client inbound limit (KBps)
- 4 byte [Integer] Client outbound limit (KBps)
- 4 byte [Integer] Router inbound limit (KBps)
- 4 byte [Integer] Router inbound burst limit (KBps)
- 4 byte [Integer] Router outbound limit (KBps)
- 4 byte [Integer] Router outbound burst limit (KBps)
- 4 byte [Integer] Router burst time (seconds)
- Nine 4-byte [Integer] (undefined)
Notes
The client limits may be the only values set, and may be the actual router limits, or a percentage of the router limits, or specific to the particular client, implementation-dependent. All the values labeled as router limits may be 0, implementation-dependent. As of release 0.7.2.
BlindingInfoMessage
Description
Advise the router that a Destination is blinded, with optional lookup password and optional private key for decryption. See proposals 123 and 149 for details.
The router needs to know if a destination is blinded. If it is blinded and uses a secret or per-client authentication, it needs to have that information as well.
A Host Lookup of a new-format b32 address ("b33") tells the router that the address is blinded, but there's no mechanism to pass the secret or private key to the router in the Host Lookup message. While we could extend the Host Lookup message to add that information, it's cleaner to define a new message.
This message provides a programmatic way for the client to tell the router. Otherwise, the user would have to manually configure each destination.
Usage
Before a client sends a message to a blinded destination, it must either lookup the "b33" in a Host Lookup message, or send a Blinding Info message. If the blinded destination requires a secret or per-client authentication, the client must send a Blinding Info message.
The router does not send a reply to this message. Sent from Client to Router.
Contents
- Session ID
- 1 byte [Integer] Flags
- Bit order: 76543210
- Bit 0: 0 for everybody, 1 for per-client
- Bits 3-1: Authentication scheme, if bit 0 is set to 1 for per-client, otherwise 000
- 000: DH client authentication (or no per-client authentication)
- 001: PSK client authentication
- Bit 4: 1 if secret required, 0 if no secret required
- Bits 7-5: Unused, set to 0 for future compatibility
- 1 byte [Integer] Endpoint type
- Type 0 is a [Hash]
- Type 1 is a hostname [String]
- Type 2 is a [Destination]
- Type 3 is a Sig Type and [SigningPublicKey]
- 2 byte [Integer] Blinded Signature Type
- 4 byte [Integer] Expiration Seconds since epoch
- Endpoint: Data as specified, one of
Type 0: 32 byte [Hash]
Type 1: host name [String]
Type 2: binary [Destination]
- Type 3: 2 byte [Integer] signature type, followed by
[SigningPublicKey] (length as implied by sig type)
- [PrivateKey] Decryption key Only present if flag bit 0 is set to 1. A 32-byte ECIES_X25519 private key, little-endian
- [String] Lookup Password Only present if flag bit 4 is set to 1.
Notes
- As of release 0.9.43.
- The Hash endpoint type is probably not useful unless the router can do a reverse lookup in the address book to get the Destination.
- The hostname endpoint type is probably not useful unless the router can do a lookup in the address book to get the Destination.
CreateLeaseSetMessage
Description
This message is sent in response to a RequestLeaseSetMessage or RequestVariableLeaseSetMessage and contains all of the [Lease] structures that should be published to the I2NP Network Database.
Sent from Client to Router.
Contents
- Session ID
- DSA [SigningPrivateKey] or 20 bytes ignored
- [PrivateKey]
- [LeaseSet]
Notes
The SigningPrivateKey matches the [SigningPublicKey] from within the LeaseSet, only if the signing key type is DSA. This is for LeaseSet revocation, which is unimplemented and is unlikely to ever be implemented. If the signing key type is not DSA, this field contains 20 bytes of random data. The length of this field is always 20 bytes, it does not ever equal the length of a non-DSA signing private key.
The PrivateKey matches the [PublicKey] from the LeaseSet. The PrivateKey is necessary for decrypting garlic routed messages.
Revocation is unimplemented. Connection to multiple routers is unimplemented in any client library.
CreateLeaseSet2Message
Description
This message is sent in response to a RequestLeaseSetMessage or RequestVariableLeaseSetMessage and contains all of the [Lease] structures that should be published to the I2NP Network Database.
Sent from Client to Router. Since release 0.9.39. Per-client authentication for EncryptedLeaseSet supported as of 0.9.41. MetaLeaseSet is not yet supported via I2CP. See proposal 123 for more information.
Contents
- Session ID
- One byte type of lease set to follow.
- Type 1 is a [LeaseSet]
- Type 3 is a [LeaseSet2]
- Type 5 is a [EncryptedLeaseSet]
- Type 7 is a [MetaLeaseSet]
- [LeaseSet] or [LeaseSet2] or [EncryptedLeaseSet] or [MetaLeaseSet]
- One byte number of private keys to follow.
- [PrivateKey] list. One for each public key in the lease set, in the same order. (Not present for Meta LS2)
- Encryption type (2 byte [Integer])
- Encryption key length (2 byte [Integer])
- Encryption [PrivateKey] (number of bytes specified)
Notes
The PrivateKeys match each of the [PublicKey] from the LeaseSet. The PrivateKeys are necessary for decrypting garlic routed messages.
See proposal 123 for more information on Encrypted LeaseSets.
The contents and format for MetaLeaseSet are preliminary and subject to change. There is no protocol specified for administration of multiple routers. See proposal 123 for more information.
The signing private key, previously defined for revocation and unused, is not present in LS2.
Preliminary version with message type 40 was in 0.9.38 but the format was changed. Type 40 is abandoned and is unsupported. Type 41 not valid until 0.9.39.
CreateSessionMessage
Description
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 SessionStatusMessage.
Contents
Notes
- This is the second message sent by the client. Previously the client sent a GetDateMessage and received a SetDateMessage response.
- If the Date in the Session Config is too far (more than +/- 30 seconds) 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.
- The [Mapping] in the Session Config must be sorted by key so that the signature will be validated correctly in the router.
DestLookupMessage
Description
Sent from Client to Router. The router responds with a DestReplyMessage.
Contents
- SHA-256 [Hash]
Notes
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.
HostLookupMessage is preferred as of release 0.9.11.
DestReplyMessage
Description
Sent from Router to Client in response to a DestLookupMessage.
Contents
- [Destination] on success, or [Hash] on failure
Notes
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. To correlate a Destination response with a request, take the Hash of the Destination. Prior to release 0.8.3, the response was empty on failure.
DestroySessionMessage
Description
This message is sent from a client to destroy a session.
Sent from Client to Router. The router responds with a SessionStatusMessage.
Contents
Notes
The router at this point should release all resources related to the session.
DisconnectMessage
Description
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.
Contents
- Reason [String]
Notes
Only implemented in the router-to-client direction. Disconnecting probably does end a session, in practice.
GetBandwidthLimitsMessage
Description
Request that the router state what its current bandwidth limits are.
Sent from Client to Router. The router responds with a BandwidthLimitsMessage.
Contents
None
Notes
As of release 0.7.2.
As of release 0.8.3, supported in both I2PSimpleSession and in standard sessions.
GetDateMessage
Description
Sent from Client to Router. The router responds with a SetDateMessage.
Notes
- 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.
- As of release 0.9.11, the authentication [Mapping] may be included, with the keys i2cp.username and i2cp.password. The Mapping need not be sorted as this message is not signed. Prior to and including 0.9.10, authentication is included in the Session Config Mapping, and no authentication is enforced for GetDateMessage, GetBandwidthLimitsMessage, or DestLookupMessage. When enabled, authentication via GetDateMessage is required before any other messages as of release 0.9.16. This is only useful outside router context. This is an incompatible change, but will only affect sessions outside router context with authentication, which should be rare.
HostLookupMessage
Description
Sent from Client to Router. The router responds with a HostReplyMessage.
This replaces the DestLookupMessage and adds a request ID, a timeout, and host name lookup support. As it also supports Hash lookups, it may be used for all lookups if the router supports it. For host name lookups, the router will query its context's naming service. This is only useful if the client is outside the router's context. Inside router context, the client should query the naming service itself, which is much more efficient.
Contents
Notes
- As of release 0.9.11. Use DestLookupMessage for older routers.
- The session ID and request ID will be returned in the HostReplyMessage. Use 0xFFFF for the session ID if there is no session.
- Timeout is useful for Hash lookups. Recommended minimum 10,000 (10 sec.). In the future it may also be useful for remote naming service lookups. The value may be not be honored for local host name lookups, which should be fast.
- The request type is 0 for Hash and 1 for host name.
- Base 32 host name lookup is supported but it is preferred to convert it to a Hash first.
HostReplyMessage
Description
Sent from Router to Client in response to a HostLookupMessage.
Contents
- Session ID
- 4 byte [Integer] request ID
- 1 byte [Integer] result code
- 0: Success
- 1: Failure
- 2: Lookup password required (as of 0.9.43)
- 3: Private key required (as of 0.9.43)
- 4: Lookup password and private key required (as of 0.9.43)
- 5: Leaseset decryption failure (as of 0.9.43)
- [Destination], only present if result code is zero.
Notes
- As of release 0.9.11. See HostLookupMessage notes.
- The session ID and request ID are those from the HostLookupMessage.
- The result code is 0 for success, 1-255 for failure. 1 indicates a generic failure. As of 0.9.43, the additional failure codes 2-5 were defined to support extended errors for "b33" lookups. See proposals 123 and 149 for additional information.
MessagePayloadMessage
Description
Deliver the payload of a message to the client.
Sent from Router to Client. If i2cp.fastReceive=true, which is not the default, the client responds with a ReceiveMessageEndMessage.
Contents
Notes
MessageStatusMessage
Description
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 ReceiveMessageBeginMessage. For an outgoing message, this is a response to a SendMessageMessage or SendMessageExpiresMessage.
Contents
- Session ID
- Message ID generated by the router
- 1 byte [Integer] status
- 4 byte [Integer] size
- 4 byte [Integer] nonce previously generated by the client
Notes
Through version 0.9.4, 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.
As of router version 0.9.5, additional status codes are defined, however they are not necessarily implemented. See [MSM-JAVADOCS] for details. All status codes:
Status Code | As Of Release | Name | Description |
---|---|---|---|
0 | Available | For incoming messages only. All other status codes below are for outgoing messages. The included size is the size in bytes of the available message. This is unused in "fast receive" mode, which is the default as of release 0.9.4. |
|
1 | Accepted | Outgoing message accepted by the local router for delivery. The included nonce matches the nonce in the SendMessageMessage, and the included Message ID will be used for subsequent success or failure notification. | |
2 | Best Effort Success | Probable success (unused) | |
3 | Best Effort Failure | Probable failure | |
4 | Guaranteed Success | Probable success | |
5 | Guaranteed Failure | Generic failure, specific cause unknown. May not really be a guaranteed failure. | |
6 | 0.9.5 | Local Success | Local delivery successful. The destination was another client on the same router. |
7 | 0.9.5 | Local Failure | Local delivery failure. The destination was another client on the same router. |
8 | 0.9.5 | Router Failure | The local router is not ready, has shut down, or has major problems. This is a guaranteed failure. |
9 | 0.9.5 | Network Failure | The local computer apparently has no network connectivity at all. This is a guaranteed failure. |
10 | 0.9.5 | Bad Session | The I2CP session is invalid or closed. This is a guaranteed failure. |
11 | 0.9.5 | Bad Message | The message payload is invalid or zero-length or too big. This is a guaranteed failure. |
12 | 0.9.5 | Bad Options | Something is invalid in the message options, or the expiration is in the past or too far in the future. This is a guaranteed failure. |
13 | 0.9.5 | Overflow Failure | Some queue or buffer in the router is full and the message was dropped. This is a guaranteed failure. |
14 | 0.9.5 | Message Expired | The message expired before it could be sent. This is a guaranteed failure. |
15 | 0.9.5 | Bad Local Leaseset | The client has not yet signed a [LeaseSet], or the local keys are invalid, or it has expired, or it does not have any tunnels in it. This is a guaranteed failure. |
16 | 0.9.5 | No Local Tunnels | Local problems. No outbound tunnel to send through, or no inbound tunnel if a reply is required. This is a guaranteed failure. |
17 | 0.9.5 | Unsupported Encryption | The certs or options in the [Destination] or its [LeaseSet] indicate that it uses an encryption format that we don't support, so we can't talk to it. This is a guaranteed failure. |
18 | 0.9.5 | Bad Destination | Something is wrong with the far-end [Destination]. Bad format, unsupported options, certificates, etc. This is a guaranteed failure. |
19 | 0.9.5 | Bad Leaseset | We got the far-end [LeaseSet] but something strange is wrong with it. Unsupported options or certificates, no tunnels, etc. This is a guaranteed failure. |
20 | 0.9.5 | Expired Leaseset | We got the far-end [LeaseSet] but it's expired and we can't get a new one. This is a guaranteed failure. |
21 | 0.9.5 | No Leaseset | Could not find the far-end [LeaseSet]. This is a common failure, equivalent to a DNS lookup failure. This is a guaranteed failure. |
22 | 0.9.41 | Meta Leaseset | The far-end destination's lease set was a meta lease set, and cannot be sent to. The client should request the meta lease set's contents with a HostLookupMessage, and select one of the hashes contained within to look up and send to. This is a guaranteed failure. |
23 | 0.9.62 | Loopback Denied | The message was attempted to be sent from and to the same destination or session. This is a guaranteed failure. |
When status = 1 (accepted), the nonce matches the nonce in the SendMessageMessage, and the included Message ID will be used for subsequent success or failure notification. Otherwise, the nonce may be ignored.
ReceiveMessageBeginMessage
Description
Request the router to deliver a message that it was previously notified of. Sent from Client to Router. The router responds with a MessagePayloadMessage.
Contents
- Session ID
- Message ID
Notes
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.
This is unused in "fast receive" mode, which is the default as of release 0.9.4.
ReceiveMessageEndMessage
Description
Tell the router that delivery of a message was completed successfully and that the router can discard the message.
Sent from Client to Router.
Contents
- Session ID
- Message ID
Notes
The ReceiveMessageEndMessage is sent after a MessagePayloadMessage fully delivers a message's payload.
This is unused in "fast receive" mode, which is the default as of release 0.9.4.
ReconfigureSessionMessage
Description
Sent from Client to Router to update the session configuration. The router responds with a SessionStatusMessage.
Contents
Notes
- As of release 0.7.1.
- If the Date in the Session Config is too far (more than +/- 30 seconds) from the router's current time, the session will be rejected.
- The [Mapping] in the Session Config must be sorted by key so that the signature will be validated correctly in the router.
- Some configuration options may only be set in the CreateSessionMessage, and changes here will not be recognized by the router. Changes to tunnel options inbound.* and outbound.* are always recognized.
- In general, the router should merge the updated config with the current config, so the updated config only needs to contain the new or changed options. However, because of the merge, options may not be removed in this manner; they must be set explicitly to the desired default value.
ReportAbuseMessage
Description
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 banlist some of the peers that sent it messages delivering the attack.
Sent either from router to client or from client to router.
Contents
- Session ID
- 1 byte [Integer] abuse severity (0 is minimally abusive, 255 being extremely abusive)
- Reason [String]
- Message ID
Notes
Unused. Not fully implemented. Both router and client can generate a ReportAbuseMessage, but neither has a handler for the message when received.
RequestLeaseSetMessage
Description
Request that a client authorize the inclusion of a particular set of inbound tunnels. Sent from Router to Client. The client responds with a CreateLeaseSetMessage.
The first of these messages sent on a session is a signal to the client that tunnels are built and ready for traffic. The router must not send the first of these messages until at least one inbound AND one outbound tunnel have been built. Clients should timeout and destroy the session if the first of these messages is not received after some time (recommended: 5 minutes or more).
Contents
- Session ID
- 1 byte [Integer] number of tunnels
- That many pairs of:
- End [Date]
Notes
This requests a [LeaseSet] with all [Leases] set to expire at the same time. For client versions 0.9.7 or higher, RequestVariableLeaseSetMessage is preferred.
RequestVariableLeaseSetMessage
Description
Request that a client authorize the inclusion of a particular set of inbound tunnels.
Sent from Router to Client. The client responds with a CreateLeaseSetMessage or CreateLeaseSet2Message.
The first of these messages sent on a session is a signal to the client that tunnels are built and ready for traffic. The router must not send the first of these messages until at least one inbound AND one outbound tunnel have been built. Clients should timeout and destroy the session if the first of these messages is not received after some time (recommended: 5 minutes or more).
Contents
- Session ID
- 1 byte [Integer] number of tunnels
- That many [Leases]
Notes
This requests a [LeaseSet] with an individual expiration time for each [Lease].
As of release 0.9.7. For clients before that release, use RequestLeaseSetMessage.
SendMessageMessage
Description
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 MessageStatusMessage.
Contents
- Session ID
- [Destination]
- Payload
- 4 byte [Integer] nonce
Notes
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 MessageStatusMessage 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 MessageStatusMessage, i.e. it acts as if i2cp.messageReliability=none for this message only.
Prior to release 0.9.14, a session with i2cp.messageReliability=none could not be overridden on a per-message basis. As of release 0.9.14, in a session with i2cp.messageReliability=none, the client may request delivery of a MessageStatusMessage with the delivery success or failure by setting the nonce to a nonzero value. The router will not send the "accepted" MessageStatusMessage but it will later send the client a MessageStatusMessage with the same nonce, and a success or failure value.
SendMessageExpiresMessage
Description
Sent from Client to Router. Same as SendMessageMessage, except includes an expiration and options.
Contents
- Session ID
- [Destination]
- Payload
- 4 byte [Integer] nonce
- 2 bytes of flags (options)
- Expiration [Date] truncated from 8 bytes to 6 bytes
Notes
As of release 0.7.1.
In "best effort" mode, 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.
Prior to release 0.9.14, a session with i2cp.messageReliability=none could not be overridden on a per-message basis. As of release 0.9.14, in a session with i2cp.messageReliability=none, the client may request delivery of a Message Status Message with the delivery success or failure by setting the nonce to a nonzero value. The router will not send the "accepted" Message Status Message but it will later send the client a Message Status Message with the same nonce, and a success or failure value.
Flags Field
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-11
- Unused, must be zero
- Bits 10-9
- Message Reliability Override (Unimplemented, to be removed).
Field value | Description |
---|---|
00 | Use session setting i2cp.messageReliability (default) |
01 | Use "best effort" message reliability for this message, overriding the session setting. The router will send one or more MessageStatusMessages in response. Unused. Use a nonzero nonce value to override a session setting of "none". |
10 | Use "guaranteed" message reliability for this message, overriding the session setting. The router will send one or more MessageStatusMessages in response. Unused. Use a nonzero nonce value to override a session setting of "none". |
11 | Unused. Use a nonce value of 0 to force "none" and override a session setting of "best effort" or "guaranteed". |
- Bit 8
- If 1, don't bundle a lease set in the garlic with this message. If 0, the router may bundle a lease set at its discretion.
- Bits 7-4
- Low tag threshold. If there are less than this many tags available, send more. This is advisory and does not force tags to be delivered.
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. This is advisory and does not force tags to be delivered.
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 |
SessionStatusMessage
Description
Instruct the client as to the status of its session.
Sent from Router to Client, in response to a CreateSessionMessage, ReconfigureSessionMessage, or DestroySessionMessage. In all cases, including in response to CreateSessionMessage, the router should respond immediately (do not wait for tunnels to be built).
Contents
- Session ID
- 1 byte [Integer] status
Status | Since | Name | Definition |
---|---|---|---|
0 | Destroyed | The session with the given ID is terminated. May be a response to a DestroySessionMessage. | |
1 | Created | In response to a CreateSessionMessage, a new session with the given ID is now active. | |
2 | Updated | In response to a ReconfigureSessionMessage, an existing session with the given ID has been reconfigured. | |
3 | Invalid | In response to a CreateSessionMessage, the configuration is invalid. The included session ID should be ignored. In response to a ReconfigureSessionMessage, the new configuration is invalid for the session with the given ID. |
|
4 | 0.9.12 | Refused | In response to a CreateSessionMessage, the router was unable to create the session, perhaps due to limits being exceeded. The included session ID should be ignored. |
Notes
Status values are defined above. If the status is Created, the Session ID is the identifier to be used for the rest of the session.
Set Date
Description
The current date and time. Sent from Router to Client as a part of the initial handshake. As of release 0.9.20, may also be sent at any time after the handshake to notify the client of a clock shift.
Notes
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.
Additional SetDate messages will not be sent to clients in the same JVM.
References
[Date] | (1, 2, 3, 4) http://i2project.net/spec/common-structures#type-date |
[Destination] | (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) http://i2project.net/spec/common-structures#struct-destination |
[EncryptedLeaseSet] | (1, 2) http://i2project.net/spec/common-structures#struct-encryptedleaseset |
[Hash] | (1, 2, 3, 4, 5, 6) http://i2project.net/spec/common-structures#type-hash |
[I2CP] | (1, 2) http://i2project.net/en/docs/protocol/i2cp |
[I2CP-FORMAT] | http://i2project.net/en/docs/protocol/i2cp#format |
[I2CP-OPTIONS] | (1, 2) http://i2project.net/en/docs/protocol/i2cp#options |
[I2CP-JAVADOCS] | http://docs.i2p-projekt.de/javadoc/net/i2p/data/i2cp/package-summary.html |
[Integer] | (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34) http://i2project.net/spec/common-structures#type-integer |
[Leases] | (1, 2) |
[Lease] | (1, 2, 3) http://i2project.net/spec/common-structures#struct-lease |
[LeaseSet] | (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) http://i2project.net/spec/common-structures#struct-leaseset |
[LeaseSet2] | (1, 2) http://i2project.net/spec/common-structures#struct-leaseset2 |
[Mapping] | (1, 2, 3, 4, 5, 6, 7) http://i2project.net/spec/common-structures#type-mapping |
[MetaLeaseSet] | (1, 2) http://i2project.net/spec/common-structures#struct-metaleaseset |
[MSM-JAVADOCS] | http://docs.i2p-projekt.de/javadoc/net/i2p/data/i2cp/MessageStatusMessage.html |
[PrivateKey] | (1, 2, 3, 4) http://i2project.net/spec/common-structures#type-privatekey |
[PublicKey] | (1, 2) http://i2project.net/spec/common-structures#type-publickey |
[RouterIdentity] | http://i2project.net/spec/common-structures#struct-routeridentity |
[SAMv3] | /en/docs/api/samv3 |
[Signature] | (1, 2) http://i2project.net/spec/common-structures#type-signature |
[SigningPrivateKey] | (1, 2, 3) http://i2project.net/spec/common-structures#type-signingprivatekey |
[SigningPublicKey] | (1, 2, 3, 4) http://i2project.net/spec/common-structures#type-signingpublickey |
[String] | (1, 2, 3, 4, 5, 6, 7, 8) http://i2project.net/spec/common-structures#type-string |
[TunnelId] | http://i2project.net/spec/common-structures#type-tunnelid |