{% extends "_layout.html" %} {% block title %}I2NP Specification{% endblock %} {% block content %}

I2P Network Protocol (I2NP) Specification

The I2P Network Protocol (I2NP), which is sandwiched between I2CP and the various I2P transport protocols, manages the routing and mixing of messages between routers, as well as the selection of what transports to use when communicating with a peer for which there are multiple common transports supported.

Common structures

I2NP message header

{% filter escape %}
+----+----+----+----+----+----+----+----+
|type| msg-id            | expiration
+----+----+----+----+----+----+----+----+
 date                    | size    |chks|
+----+----+----+----+----+----+----+----+
| data .....
+----+---//
{% endfilter %}

Definition

{% filter escape %}
type:
     1 byte
     identifies the message type(see table below)

msg-id:
       4 bytes
       uniquely identifies this message(for some time at least)

expiration:
           8 bytes
           date this message will expire

size:
     2 bytes
     length of the payload

chks:
     1 byte
     checksum of the payload
     TODO: algorithm

data:
     $size bytes
     actual message contents
{% endfilter %}

BuildRequestRecord

{% filter escape %}
Cleartext:
+----+----+----+----+----+----+----+----+
| receive tunnelId  | local routerInfo  |
+----+----+----+----+ hash              +
|                                       |
+                                       +
|                                       |
+                                       +
|                                       |
+                   +----+----+----+----+
|                   | send tunnelId     |
+----+----+----+----+----+----+----+----+
| nexthop routerInfo hash               |
+                                       +
|                                       |
+                                       +
|                                       |
+                                       +
|                                       |
+----+----+----+----+----+----+----+----+
| AES256 tunnel layer key               |
+                                       +
|                                       |
+                                       +
|                                       |
+                                       +
|                                       |
+----+----+----+----+----+----+----+----+
| AES256 tunnel IV key                  |
+                                       +
|                                       |
+                                       +
|                                       |
+                                       +
|                                       |
+----+----+----+----+----+----+----+----+
| AES256 reply key                      |
+                                       +
|                                       |
+                                       +
|                                       |
+                                       +
|                                       |
+----+----+----+----+----+----+----+----+
| reply IV                              |
+                                       +
|                                       |
+----+----+----+----+----+----+----+----+
|flag| request time      | next msg-id
+----+----+----+----+----+----+----+----+
     | padding...
+----+----+----+--//
{% endfilter %}

Definition

{% filter escape %}
 *   bytes     0-3: tunnel ID to receive messages as                                                                                                                                                                
 *   bytes    4-35: local router identity hash                                                                                                                                                                      
 *   bytes   36-39: next tunnel ID                                                                                                                                                                                  
 *   bytes   40-71: next router identity hash                                                                                                                                                                       
 *   bytes  72-103: AES-256 tunnel layer key                                                                                                                                                                        
 *   bytes 104-135: AES-256 tunnel IV key                                                                                                                                                                           
 *   bytes 136-167: AES-256 reply key                                                                                                                                                                               
 *   bytes 168-183: reply IV                                                                                                                                                                                        
 *   byte      184: flags                                                                                                                                                                                           
 *   bytes 185-188: request time (in hours since the epoch)                                                                                                                                                         
 *   bytes 189-192: next message ID                                                                                                                                                                                 
 *   bytes 193-222: uninterpreted / random padding
Taken from i2p.i2p/router/java/src/net/i2p/data/i2np/BuildRequestRecord.java
{% endfilter %}

Messages

Message Type
DatabaseStore 1
DatabaseLookup 2
DatabaseSearchReply 3
DeliveryStatus 10
Garlic 11
TunnelData 18
TunnelGateway 19
Data 20
TunnelBuild 21

DatabaseStore

with reply token:
+----+----+----+----+----+----+----+----+
| SHA256 Hash as key                    |
+                                       +
|                                       |
+                                       +
|                                       |
+                                       +
|                                       |
+----+----+----+----+----+----+----+----+
|type| reply token       | reply tunnel-
+----+----+----+----+----+----+----+----+
 Id  | SHA256 of the gateway RouterInfo |
+----+                                  +
|                                       |
+                                       +
|                                       |
+                                       +
|                                       |
+    +----+----+----+----+----+----+----+
|    | data ...
+----+--------\\

with reply token == 0:
+----+----+----+----+----+----+----+----+
| SHA256 Hash as key                    |
+                                       +
|                                       |
+                                       +
|                                       |
+                                       +
|                                       |
+----+----+----+----+----+----+----+----+
|type| reply token       | data ...
+----+-------------------+---------\\

Definition

key:
    32 bytes
    SHA256 hash

type:
     1 byte
     type identifier
     mapping:
             0    RouterInfo
             1    LeaseSet

reply token:
            4 bytes
            TODO: find out what this does

reply tunnelId:
               4 bytes
               only included if reply token > 0
               TODO: what this tunnel information is needed for

reply gateway:
              32 bytes
              Hash of the routerInfo entry to reach the gateway
              only included if reply token > 0
              TODO: what this tunnel information is needed for

data:
     rest of the message(could be anything)

DatabaseLookup

{% filter escape %}
if flag==TRUE
+----+----+----+----+----+----+----+----+
| SHA256 hash as the key to look up     |
+                                       +
|                                       |
+                                       +
|                                       |
+                                       +
|                                       |
+----+----+----+----+----+----+----+----+
| SHA256 hash of the routerInfo         |
+ who is asking                         +
|                                       |
+                                       +
|                                       |
+                                       +
|                                       |
+----+----+----+----+----+----+----+----+
|flag| reply tunnelId    |size     |    |
+----+----+----+----+----+----+----+    +
| SHA256 of $key1 to exclude            |
+                                       +
|                                       |
+                                       +
|                                       |
+                                  +----+
|                                  |    |
+----+----+----+----+----+----+----+    +
| SHA256 of $key2 to exclude            |
....
{% endfilter %}

Definition

{% filter escape %}
key:
    32 bytes
    SHA256 hash of the object to lookup

from:
     32 bytes
     SHA256 hash of the routerInfo entry this request came from(and to which the reply should be sent)

flag:
     1 byte
     mapping:
             0  FALSE => send reply directly
             1  TRUE  => send reply to some tunnel

reply tunnelId:
               2 bytes
               only included if flag==TRUE
               tunnelId of the tunnel to send the reply to

size:
     2 bytes
     number of peers to exclude from the lookup(TODO: whatever this means)

excludedPeers:
              rest of the message are $size SHA256 hashes of 32 bytes each(total $size*32 bytes)
{% endfilter %}

DatabaseSearchReply

{% filter escape %}
+----+----+----+----+----+----+----+----+
| SHA256 hash as query key              |
+                                       +
|                                       |
+                                       +
|                                       |
+                                       +
|                                       |
+----+----+----+----+----+----+----+----+
|num | peer hash $1                     |
+----+                                  +
|                                       |
+                                       +
|                                       |
+                                       +
|                                       |
+    +----+----+----+----+----+----+----+
|    |                                  |
+----+.... $num peer hashes

+    +----+----+----+----+----+----+----+
|    | from                             |
+----+                                  +
|                                       |
+                                       +
|                                       |
+                                       +
|                                       |
+    +----+----+----+----+----+----+----+
|    |
+----+


{% endfilter %}

Definition

{% filter escape %}
key:
    32 bytes
    SHA256 of the object being searched

num:
    1 byte
    number of peer hashes that follow

peer hash:
          32 bytes
          SHA256 of the RouterInfo that the other router thinks are close to the key
          $num entries

from:
     32 bytes
     SHA256 of the RouterInfo of the router this reply was sent from
{% endfilter %}

DeliveryStatus

{% filter escape %}
+----+----+----+----+----+----+----+----+----+----+----+----+
|msg-id             | arrival-time                          |
+----+----+----+----+----+----+----+----+----+----+----+----+
{% endfilter %}

Definition

{% filter escape %}
msg-id:
       4 bytes
       unique ID of the message we deliver the DeliveryStatus for(see common I2NP header for details)

arrival-time:
             8 bytes
             time the message was successfully delivered
{% endfilter %}

Garlic

{% filter escape %}
+----+----+----+----+----+----+----+----+
|length             | .... data
+----+----+----+----+--\\
{% endfilter %}

Definition

{% filter escape %}
length:
       4 bytes
       number of bytes that follow

data:
     $length bytes
     $some data
{% endfilter %}

TunnelData

{% filter escape %}
+----+----+----+----+----+----+----+----+
| tunnelId          | data              |
+----+----+----+----+                   |
|                                       |

|                                       |
+----+----+----+----+----+----+----+----+
{% endfilter %}

Definition

{% filter escape %}
tunnelId:
         4 bytes
         identifies the tunnel this message is directed at

data:
     1024 bytes
     payload data.. fixed to 1024 bytes
{% endfilter %}

TunnelGateway

{% filter escape %}
+----+----+----+----+----+----+--\\----+
| tunnelId          | length  | data...|
+----+----+----+----+----+----+--\\----+
{% endfilter %}

Definition

{% filter escape %}
tunnelId:
         4 bytes
         identifies the tunnel this message is directed at

length:
       2 bytes
       length of the payload

data:
     $length bytes
     actual payload of this message
{% endfilter %}
{% endblock %}

Data

{% filter escape %}
+----+----+----+----+----+---//--+
| length            | data...    |
+----+----+----+----+----+---//--+   
{% endfilter %}

Definition

{% filter escape %}
length:
       4 bytes
       length of the payload

data:
     $length bytes
     actual payload of this message
{% endfilter %}

TunnelBuild

{% filter escape %}
...
{% endfilter %}