Files
i2p.www/www.i2p2/pages/i2np_spec.html

616 lines
18 KiB
HTML
Raw Normal View History

{% extends "_layout.html" %}
{% block title %}I2NP Specification{% endblock %}
{% block content %}
<h1>I2P Network Protocol (I2NP) Specification</h1>
<p>
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.
</p>
2010-07-17 22:39:20 +00:00
<h2 id="structures">Common structures</h2>
<h3 id="struct_header">I2NP message header</h3>
<pre>
{% filter escape %}
+----+----+----+----+----+----+----+----+
|type| msg-id | expiration
+----+----+----+----+----+----+----+----+
date | size |chks|
+----+----+----+----+----+----+----+----+
| data .....
+----+---//
{% endfilter %}
</pre>
<h4>Definition</h4>
<pre>
{% 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
2010-07-25 18:14:17 +00:00
SHA256 hash truncated to the first byte
2010-07-17 22:39:20 +00:00
data:
$size bytes
actual message contents
{% endfilter %}
</pre>
2010-07-17 22:54:03 +00:00
<h3 id="struct_BuildRequestRecord">BuildRequestRecord</h3>
<pre>
{% 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...
+----+----+----+--//
encrypted:
+----+----+----+----+----+----+----+----+
| toPeer |
+ +
| |
+----+----+----+----+----+----+----+----+
| encrypted data ... |
+----+----+----+----+----+----+----+----+
2010-07-17 22:54:03 +00:00
{% endfilter %}
</pre>
<h4>Definition</h4>
<pre>
{% filter escape %}
unencrypted:
2010-07-17 22:54:03 +00:00
* 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
encrypted:
bytes 0-15: SHA-256-128(SHA256 hash truncated to 128bit) of the current hop's identity (the toPeer parameter)
bytes 15-527: ElGamal-2048 encrypted block
2010-07-17 22:54:03 +00:00
{% endfilter %}
</pre>
<h3 id="struct_BuildResponseRecord">BuildResponseRecord</h3>
<pre>
{% filter escape %}
unencrypted:
+----+----+----+----+----+----+----+----+
| random data... |
| |
+ +----+
| |ret |
+----+----+----+----+----+----+----+----+
{% endfilter %}
</pre>
<h4>Definition</h4>
<pre>
{% filter escape %}
unencrypted:
bytes 0-526: random data
byte 527 : reply
encrypted:
bytes 0-527: AES-encrypted record(note: same size as BuildRequestRecord!)
{% endfilter %}
</pre>
<h2 id="messages">Messages</h2>
<table border=1>
<tr>
<td>Message</td>
<td>Type</td>
</tr>
<tr>
<td><a href="#msg_DatabaseStore">DatabaseStore</a></td>
<td align="right">1</td>
</tr>
<tr>
<td><a href="#msg_DatabaseLookup">DatabaseLookup</a></td>
<td align="right">2</td>
</tr>
<tr>
<td><a href="#msg_DatabaseSearchReply">DatabaseSearchReply</a></td>
<td align="right">3</td>
</tr>
2010-07-17 21:49:22 +00:00
<tr>
<td><a href="#msg_DeliveryStatus">DeliveryStatus</a></td>
<td align="right">10</td>
</tr>
2010-07-17 21:57:47 +00:00
<tr>
<td><a href="#msg_Garlic">Garlic</a></td>
<td align="right">11</td>
</tr>
2010-07-17 22:05:48 +00:00
<tr>
<td><a href="#msg_TunnelData">TunnelData</a></td>
<td align="right">18</td>
</tr>
2010-07-17 22:10:45 +00:00
<tr>
<td><a href="#msg_TunnelGateway">TunnelGateway</a></td>
<td align="right">19</td>
</tr>
2010-07-17 22:20:41 +00:00
<tr>
<td><a href="#msg_Data">Data</a></td>
<td align="right">20</td>
</tr>
2010-07-17 22:39:20 +00:00
<tr>
<td><a href="#msg_TunnelBuild">TunnelBuild</a></td>
<td align="right">21</td>
</tr>
2010-07-25 19:31:28 +00:00
<tr>
<td><a href="#msg_TunnelBuildReply">TunnelBuildReply</a></td>
<td align="right">22</td>
</tr>
<tr>
<td><a href="#msg_VariableTunnelBuild">VariableTunnelBuild</a></td>
<td align="right">23</td>
</tr>
<tr>
<td><a href="#msg_VariableTunnelBuildReply">VariableTunnelBuildReply</a></td>
<td align="right">24</td>
</tr>
</table>
<h3 id="msg_DatabaseStore">DatabaseStore</h3>
<pre>
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 ...
+----+-------------------+---------\\
</pre>
<h4>Definition</h4>
<pre>
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)
</pre>
<h3 id="msg_DatabaseLookup">DatabaseLookup</h3>
<pre>
{% 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 %}
</pre>
<h4>Definition</h4>
<pre>
{% 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 %}
</pre>
<h3 id="msg_DatabaseSearchReply">DatabaseSearchReply</h3>
<pre>
{% filter escape %}
+----+----+----+----+----+----+----+----+
| SHA256 hash as query key |
+ +
| |
+ +
| |
+ +
| |
+----+----+----+----+----+----+----+----+
|num | peer hash $1 |
+----+ +
| |
+ +
| |
+ +
| |
+ +----+----+----+----+----+----+----+
| | |
+----+.... $num peer hashes
+ +----+----+----+----+----+----+----+
| | from |
+----+ +
| |
+ +
| |
+ +
| |
+ +----+----+----+----+----+----+----+
| |
+----+
{% endfilter %}
<h4>Definition</h4>
<pre>
{% 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
2010-07-17 22:20:41 +00:00
{% endfilter %}
</pre>
2010-07-17 21:49:22 +00:00
<h3 id="msg_DeliveryStatus">DeliveryStatus</h3>
<pre>
{% filter escape %}
+----+----+----+----+----+----+----+----+----+----+----+----+
|msg-id | arrival-time |
+----+----+----+----+----+----+----+----+----+----+----+----+
{% endfilter %}
</pre>
<h4>Definition</h4>
<pre>
{% 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 %}
</pre>
2010-07-17 21:57:47 +00:00
<h3 id="msg_Garlic">Garlic</h3>
<pre>
{% filter escape %}
2010-07-25 21:01:44 +00:00
encrypted:
2010-07-17 21:57:47 +00:00
+----+----+----+----+----+----+----+----+
2010-07-25 21:01:44 +00:00
|length | tag |
+----+----+----+----+ +
| |
+ +
| |
+ +
| |
+ +----+----+----+----+
|
2010-07-17 21:57:47 +00:00
{% endfilter %}
</pre>
<h4>Definition</h4>
<pre>
{% filter escape %}
length:
4 bytes
number of bytes that follow
data:
$length bytes
2010-07-25 21:01:44 +00:00
elgamal en
2010-07-17 21:57:47 +00:00
{% endfilter %}
</pre>
2010-07-17 22:05:48 +00:00
<h3 id="msg_TunnelData">TunnelData</h3>
<pre>
{% filter escape %}
+----+----+----+----+----+----+----+----+
| tunnelId | data |
+----+----+----+----+ |
| |
| |
+----+----+----+----+----+----+----+----+
{% endfilter %}
</pre>
<h4>Definition</h4>
<pre>
{% filter escape %}
tunnelId:
4 bytes
identifies the tunnel this message is directed at
data:
1024 bytes
payload data.. fixed to 1024 bytes
{% endfilter %}
</pre>
2010-07-17 22:10:45 +00:00
<h3 id="msg_TunnelGateway">TunnelGateway</h3>
<pre>
{% filter escape %}
+----+----+----+----+----+----+--\\----+
| tunnelId | length | data...|
+----+----+----+----+----+----+--\\----+
{% endfilter %}
</pre>
<h4>Definition</h4>
<pre>
2010-07-17 22:20:41 +00:00
{% filter escape %}
2010-07-17 22:10:45 +00:00
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 %}
</pre>
2010-07-17 22:20:41 +00:00
{% endblock %}
<h3 id="msg_Data">Data</h3>
<pre>
{% filter escape %}
+----+----+----+----+----+---//--+
| length | data... |
+----+----+----+----+----+---//--+
{% endfilter %}
</pre>
<h4>Definition</h4>
<pre>
{% filter escape %}
length:
4 bytes
length of the payload
data:
$length bytes
actual payload of this message
{% endfilter %}
</pre>
2010-07-17 22:39:20 +00:00
<h3 id="msg_TunnelBuild">TunnelBuild</h3>
<pre>
{% filter escape %}
2010-07-25 18:34:24 +00:00
+----+----+----+----+----+----+----+----+
| Record 0 ... |
| |
+----+----+----+----+----+----+----+----+
| Record 1 ... |
.....
+----+----+----+----+----+----+----+----+
| Record 7 ... |
| |
+----+----+----+----+----+----+----+----+
{% endfilter %}
</pre>
<h4>Definition</h4>
<pre>
{% filter escape %}
Just 8 records attached together
Record size: 528 bytes
Total size: 8*528 = 4224 bytes
2010-07-17 22:39:20 +00:00
{% endfilter %}
2010-07-25 18:34:24 +00:00
</pre>
2010-07-17 22:39:20 +00:00
2010-07-25 19:31:28 +00:00
<h3 id="msg_TunnelBuildReply">TunnelBuildReply</h3>
<pre>
{% filter escape %}
same format as TunnelBuild message
{% endfilter %}
</pre>
<h3 id="msg_VariableTunnelBuild">VariableTunnelBuild</h3>
<pre>
{% filter escape %}
+----+----+----+----+----+----+----+----+
|num | ....
{% endfilter %}
</pre>
<h4>Definition</h4>
<pre>
2010-07-25 21:01:44 +00:00
{% filter escape %}
2010-07-25 19:31:28 +00:00
same format as TunnelBuildMessage, except for the addition of an "num" field in front and $num number of records instead of 8
{% endfilter %}
</pre>
<h3 id="msg_VariableTunnelBuildReply">VariableTunnelBuildReply</h3>
<pre>
{% filter escape %}
same format as VariableTunnelBuild message
{% endfilter %}
</pre>