Migrated over various specifications

This commit is contained in:
str4d
2012-12-11 02:35:16 +00:00
parent 244f749529
commit d7a531a461
9 changed files with 113 additions and 101 deletions

View File

@@ -53,6 +53,18 @@
<li><a href="{{ site_url('docs/transport/ssu') }}"><span>{{ _('SSU') }}</span></a></li>
</ul>
</li>
<li class="has-sub"><a href="#"><span>{{ _('Specifications') }}</span></a>
<ul>
<li><a href="{{ site_url('docs/specs/blockfile') }}"><span>{{ _('Blockfile') }}</span></a></li>
<li><a href="{{ site_url('docs/specs/common_structures') }}"><span>{{ _('Common structures') }}</span></a></li>
<li><a href="{{ site_url('docs/specs/configuration') }}"><span>{{ _('Configuration files') }}</span></a></li>
<li><a href="{{ site_url('docs/specs/datagrams') }}"><span>{{ _('Datagrams') }}</span></a></li>
<li><a href="{{ site_url('docs/specs/i2cp') }}"><span>I2CP</span></a></li>
<li><a href="{{ site_url('docs/specs/i2np') }}"><span>I2NP</span></a></li>
<li><a href="{{ site_url('docs/specs/plugin') }}"><span>{{ _('Plugins') }}</span></a></li>
<li><a href="{{ site_url('docs/specs/tunnel_message') }}"><span>{{ _('Tunnel messages') }}</span></a></li>
</ul>
</li>
<li><a href="{{ site_url('docs/papers') }}"><span>{{ _('Papers and presentations') }}</span></a></li>
</ul>
</li>

View File

@@ -0,0 +1,216 @@
{% extends "global/layout.html" %}
{% block title %}I2P Blockfile Specification{% endblock %}
{% block content %}
<h2>
Blockfile and Hosts Database Specification
</h2>
<p>
Page last updated January 2012, current as of router version 0.8.12
<h3>Overview</h3>
<p>
This document specifies
the I2P blockfile file format
and the tables in the hostsdb.blockfile used by the Blockfile <a href="naming.html">Naming Service</a>.
</p><p>
The blockfile provides fast Destination lookup in a compact format. While the blockfile page overhead is substantial,
the destinations are stored in binary rather than in Base 64 as in the hosts.txt format.
In addition, the blockfile provides the capability of arbitrary metadata storage
(such as added date, source, and comments) for each entry.
The metadata may be used in the future to provide advanced addressbook features.
The blockfile storage requirement is a modest increase over the hosts.txt format, and the blockfile provides
approximately 10x reduction in lookup times.
</p><p>
A blockfile is simply on-disk storage of multiple sorted maps (key-value pairs),
implemented as skiplists.
The blockfile format is adopted from the
<a href="http://www.metanotion.net/software/sandbox/block.html">Metanotion Blockfile Database</a>.
First we will define the file format, then the use of that format by the BlockfileNamingService.
<h3>Blockfile Format</h3>
<p>
The original blockfile spec was modified to add magic numbers to each page.
The file is structured in 1024-byte pages. Pages are numbered starting from 1.
The "superblock" is always at page 1, i.e. starting at byte 0 in the file.
The metaindex skiplist is always at page 2, i.e. starting at byte 1024 in the file.
</p><p>
All 2-byte integer values are unsigned.
All 4-byte integer values (page numbers) are signed and negative values are illegal.
</p><p>
The database is designed to be opened and accessed by a single thread.
The BlockfileNamingService provides synchronization.
</p>
<p>
Superblock format:
</p>
<pre>
Byte Contents
0-5 Magic number 0x3141de493250 ("1A" 0xde "I2P")
6 Major version 0x01
7 Minor version 0x01
8-15 File length Total length in bytes
16-19 First free list page
20-21 Mounted flag 0x01 = yes
22-23 Span size max number of key/value pairs per span (16 for hostsdb)
24-1023 unused
</pre>
<p>
Skip list block page format:
</p>
<pre>
Byte Contents
0-7 Magic number 0x536b69704c697374 "SkipList"
8-11 First span page
12-15 First level page
16-19 Size (total number of keys - may only be valid at startup)
20-23 Spans (total number of spans - may only be valid at startup)
24-27 Levels (total number of levels - may only be valid at startup)
28-1023 unused
</pre>
<p>
Skip level block page format is as follows.
All levels have a span. Not all spans have levels.
</p>
<pre>
Byte Contents
0-7 Magic number 0x42534c6576656c73 "BSLevels"
8-9 Max height
10-11 Current height
12-15 Span page
16- Next level pages ('current height' entries, 4 bytes each, lowest first)
remaining bytes unused
</pre>
<p>
Skip span block page format is as follows.
Key/value structures are sorted by key within each span and across all spans.
Key/value structures are sorted by key within each span.
Spans other than the first span may not be empty.
</p>
<pre>
Byte Contents
0-3 Magic number 0x5370616e "Span"
4-7 First continuation page or 0
8-11 Previous span page or 0
12-15 Next span page or 0
16-17 Max keys (16 for hostsdb)
18-19 Size (current number of keys)
20-1023 key/value structures
</pre>
<p>
Span Continuation block page format:
</p>
<pre>
Byte Contents
0-3 Magic number 0x434f4e54 "CONT"
4-7 Next continuation page or 0
8-1023 key/value structures
</pre>
<p>
Key/value structure format is as follows.
Key and value lengths must not be split across pages, i.e. all 4 bytes must be on the same page.
If there is not enough room the last 1-3 bytes of a page are unused and the lengths will
be at offset 8 in the continuation page.
Key and value data may be split across pages.
Max key and value lengths are 65535 bytes.
</p>
<pre>
Byte Contents
0-1 key length in bytes
2-3 value length in bytes
4- key data
value data
</pre>
<p>
Free list block page format:
</p>
<pre>
Byte Contents
0-7 Magic number 0x2366724c69737423 "#frList#"
8-11 Next free list block or 0 if none
12-15 Number of valid free pages in this block (0 - 252)
16-1023 Free pages (4 bytes each), only the first (valid number) are valid
</pre>
<p>
Free page block format:
</p>
<pre>
Byte Contents
0-7 Magic number 0x7e2146524545217e "~!FREE!~"
8-1023 unused
</pre>
<p>
The metaindex (located at page 2) is a mapping of US-ASCII strings to 4-byte integers.
The key is the name of the skiplist and the value is the page index of the skiplist.
</p>
<h3>Blockfile Naming Service Tables</h3>
<p>
The tables created and used by the BlockfileNamingService are as follows.
The maximum number of entries per span is 16.
</p>
<h4>Properties Skiplist</h4>
<p>
"%%__INFO__%%" is the master database skiplist with String/Properties key/value entries containing only one entry:
</p>
<pre>
"info": a Properties (UTF-8 String/String Map), serialized as a <a href="{{ site_url('docs/specs/common_structures') }}#type_Mapping">Mapping</a>:
"version": "2"
"created": Java long time (ms)
"upgraded": Java long time (ms) (as of database version 2)
"lists": Comma-separated list of host databases, to be
searched in-order for lookups. Almost always "privatehosts.txt,userhosts.txt,hosts.txt".
</pre>
<h4>Reverse Lookup Skiplist</h4>
<p>
"%%__REVERSE__%%" is the reverse lookup skiplist with Integer/Properties key/value entries
(as of database version 2):
</p>
<pre>
The skiplist keys are 4-byte Integers, the first 4 bytes of the hash of the Destination.
The skiplist values are each a Properties (a UTF-8 String/String Map) serialized as a <a href="{{ site_url('docs/specs/common_structures') }}#type_Mapping">Mapping</a>
There may be multiple entries in the properties, each one is a reverse mapping,
as there may be more than one hostname for a given destination,
or there could be collisions with the same first 4 bytes of the hash.
Each property key is a hostname.
Each property value is the empty string.
</pre>
<h4>hosts.txt, userhosts.txt, and privatehosts.txt Skiplists</h4>
<p>
For each host database, there is a skiplist containing
the hosts for that database.
The keys/values in these skiplists are as follows:
</p>
<pre>
key: a UTF-8 String (the hostname)
value: a DestEntry, which is a Properties (a UTF-8 String/String Map) serialized as a <a href="{{ site_url('docs/specs/common_structures') }}#type_Mapping">Mapping</a>
followed by a binary Destination (serialized <a href="{{ site_url('docs/specs/common_structures') }}#struct_Destination">as usual</a>).
</pre>
<p>
The DestEntry Properties typically contains:
</p>
<pre>
"a": The time added (Java long time in ms)
"s": The original source of the entry (typically a file name or subscription URL)
others: TBD
</pre>
<p>
Hostname keys are stored in lower-case and always end in ".i2p".
{% endblock %}

View File

@@ -0,0 +1,685 @@
{% extends "global/layout.html" %}
{% block title %}Common structure Specification{% endblock %}
{% block content %}
Updated March 2012, current as of router version 0.8.13
<h1>Data types Specification</h1>
<p>
This document describes some data types common to all I2P protocols, like
<a href="i2np.html">I2NP</a>,
<a href="i2cp.html">I2CP</a>,
<a href="{{ site_url('docs/transport/ssu') }}">SSU</a>,
etc.
</p>
<h2 id="type_Integer">Integer</h2>
<h4>Description</h4>
<p>
Represents a non-negative integer.
</p>
<h4>Contents</h4>
<p>
1 to 8 bytes in network byte order representing an unsigned integer
</p>
<h2 id="type_Date">Date</h2>
<h4>Description</h4>
<p>
The number of milliseconds since midnight on January 1, 1970 in the GMT timezone.
If the number is 0, the date is undefined or null.
</p>
<h4>Contents</h4>
<p>
8 byte <a href="#type_Integer">Integer</a>
</p>
<h2 id="type_String">String</h2>
<h4>Description</h4>
<p>
Represents a UTF-8 encoded string.
</p>
<h4>Contents</h4>
<p>
1 or more bytes where the first byte is the number of bytes (not characters!)
in the string and the remaining 0-255 bytes are the non-null terminated UTF-8 encoded character array.
Length limit is 255 bytes (not characters). Length may be 0.
</p>
<h2 id="type_Boolean">Boolean</h2>
<h4>Description</h4>
<p>
A boolean value, supporting null/unknown representation
0=false, 1=true, 2=unknown/null
</p>
<h4>Contents</h4>
<p>
1 byte <a href="#type_Integer">Integer</a>
</p>
<h4>Notes</h4>
Deprecated - unused
<h2 id="type_PublicKey">PublicKey</h2>
<h4>Description</h4>
<p>
This structure is used in ElGamal encryption, representing only the exponent, not the primes, which are constant and defined in
<a href="{{ site_url('docs/how/cryptography') }}#elgamal">the cryptography specification</a>.
</p>
<h4>Contents</h4>
<p>
256 bytes
</p>
<h4><a href="http://docs.i2p-projekt.de/javadoc/net/i2p/data/PublicKey.html">Javadoc</a></h4>
<h2 id="type_PrivateKey">PrivateKey</h2>
<h4>Description</h4>
<p>
This structure is used in ElGamal decryption, representing only the exponent, not the primes which are constant and defined in
<a href="{{ site_url('docs/how/cryptography') }}#elgamal">the cryptography specification</a>.
</p>
<h4>Contents</h4>
<p>
256 bytes
</p>
<h4><a href="http://docs.i2p-projekt.de/javadoc/net/i2p/data/PrivateKey.html">Javadoc</a></h4>
<h2 id="type_SessionKey">SessionKey</h2>
<h4>Description</h4>
<p>
This structure is used for AES256 encryption and decryption.
</p>
<h4>Contents</h4>
<p>
32 bytes
</p>
<h4><a href="http://docs.i2p-projekt.de/javadoc/net/i2p/data/SessionKey.html">Javadoc</a></h4>
<h2 id="type_SigningPublicKey">SigningPublicKey</h2>
<h4>Description</h4>
<p>
This structure is used for verifying <a href="{{ site_url('docs/how/cryptography') }}#DSA">DSA</a> signatures.
</p>
<h4>Contents</h4>
<p>
128 bytes
</p>
<h4><a href="http://docs.i2p-projekt.de/javadoc/net/i2p/data/SigningPublicKey.html">Javadoc</a></h4>
<h2 id="type_SigningPrivateKey">SigningPrivateKey</h2>
<h4>Description</h4>
<p>
This structure is used for creating <a href="{{ site_url('docs/how/cryptography') }}#DSA">DSA</a> signatures.
</p>
<h4>Contents</h4>
<p>
20 bytes
</p>
<h4><a href="http://docs.i2p-projekt.de/javadoc/net/i2p/data/SigningPrivateKey.html">Javadoc</a></h4>
<h2 id="type_Signature">Signature</h2>
<h4>Description</h4>
<p>
This structure represents the <a href="{{ site_url('docs/how/cryptography') }}#DSA">DSA</a> signature of some data.
</p>
<h4>Contents</h4>
<p>
40 bytes
</p>
<h4><a href="http://docs.i2p-projekt.de/javadoc/net/i2p/data/Signature.html">Javadoc</a></h4>
<h2 id="type_Hash">Hash</h2>
<h4>Description</h4>
<p>
Represents the SHA256 of some data.
</p>
<h4>Contents</h4>
<p>
32 bytes
</p>
<h4><a href="http://docs.i2p-projekt.de/javadoc/net/i2p/data/Hash.html">Javadoc</a></h4>
<h2 id="type_SessionTag">Session Tag</h2>
<h4>Description</h4>
<p>
A random number
</p>
<h4>Contents</h4>
<p>
32 bytes
</p>
<h4><a href="http://docs.i2p-projekt.de/javadoc/net/i2p/data/SessionTag.html">Javadoc</a></h4>
<h2 id="type_TunnelId">TunnelId</h2>
<h4>Description</h4>
<p>
Defines an identifier that is unique to each router in a tunnel.
</p>
<h4>Contents</h4>
<p>
4 byte <a href="#type_Integer">Integer</a>
</p>
<h4><a href="http://docs.i2p-projekt.de/javadoc/net/i2p/data/TunnelID.html">Javadoc</a></h4>
<h2 id="type_Certificate">Certificate</h2>
<h4>Description</h4>
<p>
A certificate is a container for various receipts or proof of works used throughout the I2P network.
</p>
<h4>Contents</h4>
<p>
1 byte <a href="#type_Integer">Integer</a> specifying certificate type, followed by a 2 <a href="#type_Integer">Integer</a> specifying the size of the certificate payload, then that many bytes.
</p>
<pre>
{% filter escape %}
+----+----+----+----+----+--//
|type| length | payload
+----+----+----+----+----+--//
type :: Integer
length -> 1 byte
case 0 -> NULL
case 1 -> HASHCASH
case 2 -> HIDDEN
case 3 -> SIGNED
case 4 -> MULTIPLE
length :: Integer
length -> 2 bytes
payload :: data
length -> $length bytes
{% endfilter %}
</pre>
<h4>Notes</h4>
<ul>
<li>
For <a href="#struct_RouterIdentity">Router Identities</a>, the Certificate is always NULL, no others are currently implemented.
</li><li>
For <a href="{{ site_url('docs/specs/i2np') }}#struct_GarlicClove">Garlic Cloves</a>, the Certificate is always NULL, no others are currently implemented.
</li><li>
For <a href="{{ site_url('docs/specs/i2np') }}#msg_Garlic">Garlic Messages</a>, the Certificate is always NULL, no others are currently implemented.
</li><li>
For <a href="#struct_Destination">Destinations</a>, the Certificate may be non-NULL,
however non-NULL certs are not widely used, and any checking is left to the application-level.
</li></ul>
<h4><a href="http://docs.i2p-projekt.de/javadoc/net/i2p/data/Certificate.html">Javadoc</a></h4>
<h2 id="type_Mapping">Mapping</h2>
<h4>Description</h4>
<p>
A set of key/value mappings or properties
</p>
<h4>Contents</h4>
<p>
A 2-byte size Integer followed by a series of String=String; pairs
</p>
<pre>
{% filter escape %}
+----+----+----+----+----+----+----+----+
| size |key string (len + data) | = |
+----+----+----+----+----+----+----+----+
| val string (len + data) | ; | ...
+----+----+----+----+----+----+----+
size :: Integer
length -> 2 bytes
Total number of bytes that follow
key string :: String
A string (one byte length followed by UTF-8 encoded characters)
= :: A single byte containing '='
val string :: String
A string (one byte length followed by UTF-8 encoded characters)
; :: A single byte containing ';'
{% endfilter %}
</pre>
<h4>Notes</h4>
<ul>
<li>
The encoding isn't optimal - we either need the '=' and ';' characters, or the string lengths, but not both
<li>
Some documentation says that the strings may not include '=' or ';' but this encoding supports them
<li>
Strings are defined to be UTF-8 but in the current implementation, I2CP uses UTF-8 but I2NP does not.
For example,
UTF-8 strings in a RouterInfo options mapping in a I2NP Database Store Message will be corrupted.
<li>
Mappings contained in I2NP messages (i.e. in a RouterAddress or RouterInfo)
must be sorted by key so that the signature will be invariant.
<li>
Key and value string length limits are 255 bytes (not characters) each, plus the length byte. Length byte may be 0.
<li>
Total length limit is 65535 bytes, plus the 2 byte size field, or 65537 total.
</ul>
<h4><a href="http://docs.i2p-projekt.de/javadoc/net/i2p/data/DataHelper.html">Javadoc</a></h4>
<h1>Common structure specification</h1>
<h2 id="struct_RouterIdentity">RouterIdentity</h2>
<h4>Description</h4>
<p>
Defines the way to uniquely identify a particular router
</p>
<h4>Contents</h4>
<p>
<a href="#type_PublicKey">PublicKey</a> followed by <a href="#type_SigningPublicKey">SigningPublicKey</a> and then a <a href="#type_Certificate">Certificate</a>
</p>
<pre>
{% filter escape %}
+----+----+----+----+----+----+----+----+
| public_key |
+ +
| |
~ ~
~ ~
| |
+----+----+----+----+----+----+----+----+
| signing_key |
+ +
| |
~ ~
~ ~
| |
+----+----+----+----+----+----+----+----+
| certificate |
+----+----+----+--//
public_key :: PublicKey
length -> 256 bytes
signing_key :: SigningPublicKey
length -> 128 bytes
certificate :: Certificate
length -> >= 3 bytes
Total length: 387+ bytes
{% endfilter %}
</pre>
<h4>Notes</h4>
The certificate for a RouterIdentity is currently unused and is always NULL.
<h4><a href="http://docs.i2p-projekt.de/javadoc/net/i2p/data/RouterIdentity.html">Javadoc</a></h4>
<h2 id="struct_Destination">Destination</h2>
<h4>Description</h4>
<p>
A Destination defines a particular endpoint to which messages can be directed for secure delivery.
</p>
<h4>Contents</h4>
<p>
<a href="#type_PublicKey">PublicKey</a> followed by a <a href="#type_SigningPublicKey">SigningPublicKey</a> and then a <a href="#type_Certificate">Certificate</a>
</p>
<pre>
{% filter escape %}
+----+----+----+----+----+----+----+----+
| public_key |
+ +
| |
~ ~
~ ~
| |
+----+----+----+----+----+----+----+----+
| signing_public_key |
+ +
| |
~ ~
~ ~
| |
+----+----+----+----+----+----+----+----+
| certificate
+---//
public_key :: PublicKey
length -> 256 bytes
signing_public_key :: SigningPublicKey
length -> 128 bytes
certificate :: Certificate
length -> >= 3 bytes
Total length: 387+ bytes
{% endfilter %}
</pre>
<h4><a href="http://docs.i2p-projekt.de/javadoc/net/i2p/data/Destination.html">Javadoc</a></h4>
<h2 id="struct_Lease">Lease</h2>
<h4>Description</h4>
<p>
Defines the authorization for a particular tunnel to receive messages targeting a <a href="#struct_Destination">Destination</a>.
</p>
<h4>Contents</h4>
<p>
SHA256 <a href="#type_Hash">Hash</a> of the
<a href="#struct_RouterIdentity">RouterIdentity</a> of the gateway router, then the <a href="#type_TunnelId">TunnelId</a>, and finally an end <a href="#type_Date">Date</a>
</p>
<pre>
{% filter escape %}
+----+----+----+----+----+----+----+----+
| tunnel_gw |
+ +
| |
+ +
| |
+ +
| |
+----+----+----+----+----+----+----+----+
| tunnel_id | end_date
+----+----+----+----+----+----+----+----+
|
+----+----+----+----+
tunnel_gw :: Hash of the RouterIdentity of the tunnel gateway
length -> >= 32 bytes
tunnel_id :: TunnelId
length -> 4 bytes
end_date :: Date
length -> 8 bytes
{% endfilter %}
</pre>
<h4>Notes</h4>
<ul>
<li>
Total size: 44 bytes
</li></ul>
<h4><a href="http://docs.i2p-projekt.de/javadoc/net/i2p/data/Lease.html">Javadoc</a></h4>
<h2 id="struct_LeaseSet">LeaseSet</h2>
<h4>Description</h4>
<p>
Contains all of the currently authorized <a href="#struct_Lease">Lease</a>s for a particular <a href="#struct_Destination">Destination</a>, the <a href="#type_PublicKey">PublicKey</a> to which garlic messages can be encrypted,
and then the <a href="#type_SigningPublicKey">public key</a> that can be used to revoke this particular version of the structure. The <a href="#struct_LeaseSet">LeaseSet</a> is one of the two structures stored in the network database(
the other being <a href="#struct_RouterInfo">RouterInfo</a>), and is keyed under the SHA256 of the contained <a href="#struct_Destination">Destination</a>.
</p>
<h4>Contents</h4>
<p>
<a href="#struct_Destination">Destination</a>, followed by a <a href="#type_PublicKey">PublicKey</a> for encryption, then a <a href="#type_SigningPublicKey">SigningPublicKey</a> which can be used to revoke this version of the <a href="#struct_LeaseSet">LeaseSet</a>,
then a 1 byte <a href="#type_Integer">Integer</a> specifying how many <a href="#struct_Lease">Lease</a> structures are in the set, followed by the actual <a href="#struct_Lease">Lease</a> structures and finally a <a href="#type_Signature">Signature</a> of the previous
bytes signed by the <a href="#struct_Destination">Destination's</a> <a href="#type_SigningPrivateKey">SigningPrivateKey</a>
<pre>
{% filter escape %}
+----+----+----+----+----+----+----+----+
| destination |
+ +
| |
~ ~
~ ~
| |
+----+----+----+----+----+----+----+----+
| encryption_key |
+ +
| |
~ ~
~ ~
| |
+----+----+----+----+----+----+----+----+
| signing_key |
+ +
| |
~ ~
~ ~
| |
+----+----+----+----+----+----+----+----+
|num | Lease 0 |
+----+ +
| |
~ ~
~ ~
| |
+----+----+----+----+----+----+----+----+
| Lease 1 |
+ +
| |
~ ~
~ ~
~ ~
~ ~
| |
+----+----+----+----+----+----+----+----+
| Lease ($num-1) |
+ +
| |
~ ~
~ ~
| |
+----+----+----+----+----+----+----+----+
| signature |
+ +
| |
+ +
| |
+ +
| |
+ +
| |
+----+----+----+----+----+----+----+----+
destination :: Destination
length -> >= 387 bytes
encryption_key :: PublicKey
length -> 256 bytes
signing_key :: SigningPublicKey
length -> 128 bytes
num :: Integer
length -> 1 byte
value: 0 <= num <= 6
leases :: [Lease]
length -> >= $num*44 bytes
signature :: Signature
length -> 40 bytes
{% endfilter %}
</pre>
<h4>Notes</h4>
<ul><li>
The public key of the destination was used for the old i2cp-to-i2cp encryption
which was disabled in version 0.6, it is currently unused?
</li><li>
The encryption key is used for end-to-end <a href="{{ site_url('docs/how/elgamalaes') }}">ElGamal/AES+SessionTag</a> encryption.
It is currently generated anew at every router startup, it is not persistent.
</li><li>
The signature may be verified using the signing public key of the destination.
</li><li>
The signing_key is currently unused. It was intended for LeaseSet revocation, which is unimplemented.
It is currently generated anew at every router startup, it is not persistent.
</li></ul>
<h4><a href="http://docs.i2p-projekt.de/javadoc/net/i2p/data/LeaseSet.html">Javadoc</a></h4>
<h2 id="struct_RouterAddress">RouterAddress</h2>
<h4>Description</h4>
<p>
This structure defines the means to contact a router through a transport protocol.
</p>
<h4>Contents</h4>
<p>
1 byte <a href="#type_Integer">Integer</a> defining the relative cost of using the address, where 0 is free and 255 is expensive, followed by the expiration <a href="#type_Date">Date</a> after which the address should not be used, or if null, the address never expires.
After that comes a <a href="#type_String">String</a> defining the transport protocol this router address uses. Finally there is a <a href="#type_Mapping">Mapping</a> containing all of the transport specific options necessary to establish the connection, such as
IP address, port number, email address, URL, etc.
</p>
<pre>
{% filter escape %}
+----+
|cost|
+----+----+----+----+----+----+----+----+
| expiration |
+----+----+----+----+--//+----+----+----+
| transport_style |
+----+----+----+----+--//+----+----+----+
| options |
+----+----+----+----+--//+----+----+----+
cost :: Integer
length -> 1 byte
case 0 -> free
case 255 -> expensive
expiration :: Date
length -> 8 bytes
case null -> never expires
transport_style :: String
length -> 1-256 bytes
options :: Mapping
{% endfilter %}
</pre>
<h4>Notes</h4>
<ul>
<li>
Cost is typically 5 or 6 for SSU, and 10 or 11 for NTCP.
</li><li>
Expiration is currently unused, always null (all zeroes))
</li></ul>
<h4><a href="http://docs.i2p-projekt.de/javadoc/net/i2p/data/RouterAddress.html">Javadoc</a></h4>
<h2 id="struct_RouterInfo">RouterInfo</h2>
<h4>Description</h4>
<p>
Defines all of the data that a router wants to publish for the network to see. The <a href="#struct_RouterInfo">RouterInfo</a> is one of two structures stored in the network database(the other being <a href="#struct_LeaseSet">LeaseSet</a>, and is keyed under the SHA256 of
the contained <a href="#struct_RouterIdentity">RouterIdentity</a>.
</p>
<h4>Contents</h4>
<p>
<a href="#struct_RouterIdentity">RouterIdentity</a> followed by the <a href="#type_Date">Date</a>, when the entry was published
</p>
<pre>
{% filter escape %}
+----+----+----+----+----+----+----+----+
| router_ident |
+ +
| |
~ ~
~ ~
| |
+----+----+----+----+----+----+----+----+
| published |
+----+----+----+----+----+----+----+----+
|size| RouterAddress 0 |
+----+ +
| |
~ ~
~ ~
| |
+----+----+----+----+----+----+----+----+
| RouterAddress 1 |
+ +
| |
~ ~
~ ~
~ ~
~ ~
| |
+----+----+----+----+----+----+----+----+
| RouterAddress ($size-1) |
+ +
| |
~ ~
~ ~
| |
+----+----+----+----+-//-+----+----+----+
|psiz| options |
+----+----+----+----+-//-+----+----+----+
| signature |
+ +
| |
+ +
| |
+ +
| |
+ +
| |
+----+----+----+----+----+----+----+----+
router_ident :: RouterIdentity
length -> >= 387 bytes
published :: Date
length -> 8 bytes
size :: Integer
length -> 1 byte
addresses :: [RouterAddress]
length -> >= $size*267 bytes
peer_size :: Integer
length -> 1 byte
value -> 0
options :: Mapping
signature :: Signature
length -> 40 bytes
{% endfilter %}
</pre>
<h4>Notes</h4>
The peer_size Integer may be followed by a list of that many router hashes.
This is currently unused. It was intended for a form of restricted routes, which is unimplemented.
<p>
The signature may be verified using the signing public key of the router_ident.
<h4><a href="http://docs.i2p-projekt.de/javadoc/net/i2p/data/RouterInfo.html">Javadoc</a></h4>
<h2 id="struct_DeliveryInstructions">Delivery Instructions</h2>
Defined in the <a href="{{ site_url('docs/specs/tunnel_message') }}#delivery">Tunnel Message Specification</a>.
{% endblock %}

View File

@@ -0,0 +1,105 @@
{% extends "global/layout.html" %}
{% block title %}Configuration File Specification{% endblock %}
{% block content %}
Updated September 2012, current as of router version 0.9.2
<h2>Overview</h2>
<p>
This page provides a general specification of I2P configuration files,
used by the router and various applications.
It also gives an overview of the information contained in the various files,
and links to detailed documentation where available.
</p>
<h2>General Format</h2>
<p>
An I2P configuration file is formatted as specified in
<a href="http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Properties.html#load%28java.io.InputStream%29">Java Properties</a>
with the following exceptions:
<ul>
<li>Encoding must be UTF-8
<li>Does not use or recognize any escapes, including '\', so lines may not be continued
<li>'#' or ';' starts a comment, but '!' does not
<li>'#' starts a comment in any position but ';' must be in column 1 to start a comment
<li>Leading and trailing whitespace is not trimmed on keys
<li>Leading and trailing whitespace is trimmed on values
<li>'=' is the only key-termination character (not ':' or whitespace)
<li>Lines without '=' are ignored. It does not store the key with a value of ""
<li>As there are no escapes,
keys may not contain '#', '=', or '\n', or start with ';'
<li>As there are no escapes,
values may not contain '#' or '\n', or start or end with '\r' or whitespace
</ul>
</p><p>
The file need not be sorted, but most applications do sort by key when
writing to the file, for ease of reading and manual editing.
</p><p>
Reads and writes are implemented in
<a href="http://docs.i2p-projekt.de/javadoc/net/i2p/data/DataHelper.html">DataHelper loadProps() and storeProps()</a>.
Note that the file format is significantly different than the
serialized format for I2P protocols specified in
<a href="{{ site_url('docs/specs/common_structures') }}#type_Mapping">Mapping</a>.
</p>
<h2>Core library and router</h2>
<h3>Clients (clients.config)</h3>
<p>
Configured via /configclients in the router console.
</p>
<h3>Logger (logger.config)</h3>
<p>
Configured via /configlogging in the router console.
</p>
<h3>Individual Plugin (xxx/plugin.config)</h3>
<p>
See <a href="{{ site_url('docs/specs/plugin') }}">the plugin specification</a>.
</p>
<h3>Plugins (plugins.config)</h3>
<p>
Enable/disable for each installed plugin..
</p>
<h3>Router (router.config)</h3>
<p>
Configured via /configadvanced in the router console.
</p>
<h2>Applications</h2>
<h3>Addressbook (addressbook/config.txt)</h3>
<p>
See documentation in SusiDNS.
</p>
<h3>I2PSnark (i2psnark.config)</h3>
<p>
Configured via the application gui.
</p>
<h3>I2PTunnel (i2ptunnel.config)</h3>
<p>
Configured via the /i2ptunnel application in the router console.
</p>
<h3>Router Console</h3>
<p>
The router console uses the router.config file.
</p>
<h3>SusiMail (susimail.config)</h3>
<p>
See post on zzz.i2p.
</p>
<h3>Systray (systray.config)</h3>
<p>
TBD
</p>
{% endblock %}

View File

@@ -0,0 +1,172 @@
{% extends "global/layout.html" %}
{% block title %}Datagram Specification{% endblock %}
{% block content %}
Updated August 2010, current as of router version 0.8
<h2>Datagram Overview</h2>
<p>Datagrams build upon the base <a href="i2cp.html">I2CP</a> to provide authenticated
and repliable messages in a standard format. This lets applications reliably read
the "from" address out of a datagram and know that the address really sent the
message. This is necessary for some applications since the base I2P message is
completely raw - it has no "from" address (unlike IP packets). In addition, the
message and sender are authenticated by signing the payload.</p>
<p>
Datagrams, like <a href="{{ site_url('docs/api/streaming') }}">streaming library packets</a>,
are an application-level construct.
These protocols are independent of the low-level <a href="{{ site_url('docs/transport') }}">transports</a>;
the protocols are converted to I2NP messages by the router, and
either protocol may be carried by either transport.
</p>
<h2>Application Guide</h2>
<p>Applications written in Java may use the
<a href="http://docs.i2p-projekt.de/javadoc/net/i2p/client/datagram/package-summary.html">datagram API</a>,
while applications in other languages
can use <a href="{{ site_url('docs/api/sam') }}">SAM</a>'s datagram support.
There is also limited support in i2ptunnel in the <a href="{{ site_url('docs/api/socks') }}">SOCKS proxy</a>,
the 'streamr' tunnel types, and udpTunnel classes.
</p>
<h3>Datagram Length</h3>
<p>
The application designer should carefully consider the tradeoff of repliable vs. non-repliable
datagrams. Also, the datagram size will affect reliability, due to tunnel fragmentation into 1KB
tunnel messages. The more message fragments, the more likely that one of them will be dropped
by an intermediate hop. Messages larger than a few KB are not recommended.
</p>
<p>
Also note that the various overheads added by lower layers, in particular asymmetric
<a href="{{ site_url('docs/how/elgamalaes') }}">ElGamal/AES</a>, place a large burden on intermittent messages
such as used by a Kademlia-over-UDP application. The implementations are currently tuned
for frequent traffic using the streaming library. There are a high number
of session tags delivered, and a short session tag lifetime, for example.
There are currently no configuration parameters available within I2CP to tune
the ElGamal Session Tag parameters.
</p>
<h3>I2CP Protocol Number and Ports</h3>
<p>
The standard I2CP protocol number for datagrams is 17. Applications may or may not choose to set the
protocol in the I2CP header. It is not set by default.
It must be set to demultiplex datagram and streaming traffic received on the same Destination.
</p>
<p>
As datagrams are not connection-oriented, the application may require
port numbers to correlate datagrams with particular peers or communications sessions,
as is traditional with UDP over IP.
Applications may add 'from' and 'to' ports to the I2CP (gzip) header as described in
the <a href="i2cp.html#format">I2CP page</a>.
</p>
<p>
There is no method within the datagram API to specify whether it is non-repliable (raw)
or repliable. The application should be designed to expect the appropriate type.
The I2CP protocol number or port could also be used by the application to
indicate datagram type.
</p>
<p>
The protocols and ports may be set in I2CP's
<a href="http://docs.i2p-projekt.de/javadoc/net/i2p/client/I2PSession.html">I2PSession API</a>,
as implemented in
<a href="http://docs.i2p-projekt.de/javadoc/net/i2p/client/I2PSessionMuxedImpl.html">I2PSessionMuxedImpl</a>.
</p>
<h3>Data Integrity</h3>
Data integrity is assured by the gzip CRC-32 checksum implemented in
<a href="i2cp.html#format">the I2CP layer</a>.
There is no checksum field in the datagram protocol.
<h3>Packet Encapsulation</h3>
Each datagram is sent through I2P as a single message (or as an individual clove in a
<a href="{{ site_url('docs/how/garlicrouting') }}">Garlic Message</a>).
Message encapsulation is implemented in the underlying
<a href="i2cp.html">I2CP</a>,
<a href="i2np.html">I2NP</a>, and
<a href="{{ site_url('docs/specs/tunnel_message') }}">tunnel message</a> layers.
There is no packet delimiter mechanism or length field in the datagram protocol.
<h2 id="spec">Specification</h2>
<h3 id="raw">Non-Repliable Datagrams</h3>
Non-repliable datagrams have no 'from' address and are not authenticated.
They are also called "raw" datagrams.
Strictly speaking, they are not "datagrams" at all, they are just raw data.
They are not handled by the datagram API.
However, SAM and the I2PTunnel classes support "raw datagrams".
<h4>Format</h4>
<pre>
+----+----+----+----+----//
| payload...
+----+----+----+----+----//
Length: 0 - unlimited (see notes)
</pre>
<h4>Notes</h4>
The practical length is limited by lower layers of protocols - the
<a href="{{ site_url('docs/specs/tunnel_message') }}#notes">tunnel message spec</a>
limits messages to about 61.2 KB and the
<a href="{{ site_url('docs/transport') }}">transports</a>
currently limit messages to about 32 KB, although this may be raised in the future.
<h3 id="repliable">Repliable Datagrams</h3>
Repliable datagrams contain a 'from' address and a signature. These add 427 bytes of overhead.
<h4>Format</h4>
<pre>
+----+----+----+----+----+----+----+----+
| from |
+ +
| |
~ ~
~ ~
| |
+ +
| |
| |
+----+----+----+----+----+----+----+----+
| signature |
+ +
| |
+ +
| |
+ +
| |
+ +
| |
+----+----+----+----+----+----+----+----+
| payload...
+----+----+----+----//
from :: a <a href="{{ site_url('docs/specs/common_structures') }}#type_Destination">Destination</a>
length: 387+ bytes
The originator and signer of the datagram
signature :: a <a href="{{ site_url('docs/specs/common_structures') }}#type_Signature">Signature</a>
length: 40 bytes
The <a href="{{ site_url('docs/how/cryptography') }}#DSA">DSA</a> signature of the SHA256 hash of the payload, which may be verified by the
DSA signing public key of the 'from' Destination
payload :: The data
Length: 0 - 32 KB (see notes)
Total length: Payload length + 427+
</pre>
<h4>Notes</h4>
The practical length is limited by lower layers of protocols - the
<a href="{{ site_url('docs/transport') }}">transports</a>
currently limit messages to about 32 KB, so the data length here is limited to about
31.5 KB.
{% endblock %}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,472 @@
{% extends "global/layout.html" %}
{% block title %}I2P Plugin Specification{% endblock %}
{% block content %}
<h2>
Specification Version 0.18
2012-03-15
</h2>
<p>
Page last updated March 2012, current as of router version 0.8.13-13
<h3>Overview</h3>
<p>
This document specifies
a .xpi2p file format (like the Firefox .xpi), but with a simple
plugin.config description file instead of an XML install.rdf file.
This file format is used for both initial plugin installs and plugin updates.
<p>
In addition, this document provides a brief overview of how the router installs plugins,
and policies and guidelines for plugin developers.
<p>
The basic .xpi2p file format is the same as a i2pupdate.sud file
(the format used for router updates),
but the installer will let the user install the
addon even if it doesn't know the signer's key yet.
<p>
The standard directory structure will let users install the following types of addons:
<ul>
<li>
console webapps
<li>
new eepsite with cgi-bin, webapps
<li>
console themes
<li>
console translations
<li>
Java programs
<li>
Java programs in a separate JVM
<li>
Any shell script or program
</ul>
<p>
A plugin installs all its files in ~/.i2p/plugins/name/ (%APPDIR%\I2P\plugins\name\ on Windows). The installer will prevent
installation anywhere else, although the plugin can access libraries elsewhere when running.
<p>
This should be viewed only as a way to make installation, uninstallation, and upgrading easier,
and to lessen basic inter-plugin conflicts.
<p>
There is essentially no security model once the plugin is running, however. The plugin runs
in the same JVM and with the same permissions as the router, and has full access to the file
system, the router, executing external programs, etc.
<h3>Details</h3>
<p>
foo.xpi2p is a sud file containing the following:
<pre>
Standard .sud header prepended to the zip file, containing the following:
40-byte <a href="{{ site_url('docs/how/cryptography') }}#DSA">DSA signature</a>
16-byte plugin version in UTF-8, padded with trailing zeroes if necessary
Zip file containing the following:
(REQUIRED) plugin.config file:
(standard I2P config file, UTF-8 containing key=value lines, comments start with #)
Containing the following properties:
(* = required)
The first three must be identical to those in the installed plugin for an update plugin.
*name (will be installed in this directory name)
For native plugins, you may want separate names in different packages -
foo-windows and foo-linux, for example
*key (<a href="{{ site_url('docs/how/cryptography') }}#DSA">DSA public key</a> as 172 B64 chars ending with '=')
*signer (yourname@mail.i2p recommended)
*version (must be in a format VersionComparator can parse, e.g. 1.2.3-4)
16 bytes max (must match sud version)
Valid number separators are '.', '-', and '_'
This must be greater than the one in the installed plugin for an update plugin.
The following items are displayed on configclients.jsp if present:
date (Java time - long int)
author (yourname@mail.i2p recommended)
websiteURL (http://foo.i2p/)
updateURL (http://foo.i2p/foo.xpi2p)
The update checker will check bytes 41-56 at this URL
to determine whether a newer version is available
( Should the checker fetch with ?currentVersion=1.2.3?...
No. If the dev wants to have the URL contain the current version, just
set it in the config file, and remember to change it every release)
description
description_xx (for language xx)
license
disableStop=true
Default false.
If true, the stop button will not be shown. Use this if there are no
webapps and no clients with stopargs.
The following items are used to add a link on the console summary bar:
consoleLinkName (will be added to summary bar)
consoleLinkName_xx (for language xx)
consoleLinkURL (/appname/index.jsp)
consoleLinkTooltip (supported as of 0.7.12-6)
consoleLinkTooltip_xx (lang xx as of 0.7.12-6)
The following items are used by the plugin installer:
type (app/theme/locale/webapp/...) (unimplemented, probably not necessary)
min-i2p-version
max-i2p-version
min-java-version
min-jetty-version (supported as of 0.8.13, use 6 for Jetty 6 webapps)
max-jetty-version (supported as of 0.8.13, use 5.99999 for Jetty 5 webapps)
required-platform-OS (unimplemented - perhaps will be displayed only, not verified)
other-requirements (unimplemented e.g. python x.y - not verified by the installer, just displayed to the user)
dont-start-at-install=true
Default false.
Won't start the plugin when it is installed or updated. On initial installation, sets the plugin as so the user must manually start it. An update will not change the user's preference to start it if they choose to do so.
router-restart-required=true
Default false.
This does not restart the router or the plugin on an update, it just informs the user that a restart is required.
It has no effect on initial plugin installation.
update-only=true
Default false.
If true, will fail if an installation does not exist.
install-only=true
Default false.
If true, will fail if an installation exists.
min-installed-version (to update over, if an installation exists)
max-installed-version (to update over, if an installation exists)
depends=plugin1,plugin2,plugin3 (unimplemented - is this too hard? proposed by sponge)
depends-version=0.3.4,,5.6.7 (unimplemented)
The following item is used for translation plugins:
langs=xx,yy,Klingon,... (unimplemented) (yy is the country flag)
Each of the following directories or files is optional, but something must be there or it won't do anything:
console/
locale/
Only jars containing new resource bundles (translations) for apps in the base I2P installation.
Bundles for this plugin should go inside console/webapp/foo.war or lib/foo.jar
themes/
New themes for the router console
Place each theme in a subdirectory.
webapps/
(See important notes below about webapps)
.wars
These will be run at install time unless disabled in webapps.config
The war name does not have to be the same as the plugin name.
Do not duplicate war names in the base I2P installation.
webapps.config
Same format as router's webapps.config
Also used to specify additional jars in $PLUGIN/lib/ or $I2P/lib for the webapp classpath,
with webapps.warname.classpath=$PLUGIN/lib/foo.jar,$I2P/lib/bar.jar
NOTE: Currently, the classpath line is only loaded if the warname is
the same as the plugin name.
NOTE: Prior to router version 0.7.12-9, the router looked for plugin.warname.startOnLoad instead
of webapps.warname.startOnLoad. For compatibility with older router versions, a plugin
wishing to disable a war should include both lines.
eepsite/
(See important notes below about eepsites)
cgi-bin/
docroot/
logs/
webapps/
jetty.xml
The installer will have to do variable substitution in here to set the path
The location and name of this file doesn't really matter, as long as it is set in
clients.config - it may be more convenient to be up one level from here
(that's what the zzzot plugin does)
lib/
Put any jars here, and specify them in a classpath line in console/webapps.config and/or clients.config
clients.config (same format as router's clients.config)
These will be run when a plugin is started
Start at client #0, number consecutively
New property clientApp.0.stopargs=foo bar stop baz
If present, the class will be called with these args to stop the client
All stop tasks are called with zero delay
Note: The router can't tell if your clients are running or not.
Each should handle stopping an app that isn't running without complaint.
That probably goes for starting a client that is already started too.
New property clientApp.0.uninstallargs=foo bar uninstall baz
If present, the class will be called with these args just before deleting $PLUGIN
All uninstall tasks are called with zero delay
New property clientApp.0.classpath=$I2P/lib/foo.bar,$PLUGIN/lib/bar.jar
The plugin runner will do variable substitution in the args and stopargs lines as follows:
$I2P => i2p base installation dir;
$CONFIG => i2p config dir (typically ~/.i2p)
$PLUGIN => this plugin's installation dir (typically ~/.i2p/plugins/appname)
(See important notes below about running shell scripts or external programs)
</pre>
<h3>Plugin installer tasks</h3>
This lists what happens when a plugin is installed by I2P.
<ul>
<li>The .xpi2p file is downloaded.</li>
<li>The .sud signature is verified against stored keys.
If there is no matching key, the .sud is extracted, the key is loaded from the properties, then verified and stored.</li>
<li>Verify the integrity of the zip file.</li>
<li>Extract the plugin.config file.</li>
<li>Verify the I2P version, to make sure the plugin will work.</li>
<li>Check that webapps don't duplicate the existing $I2P applications.</li>
<li>Stop the existing plugin (if present).</li>
<li>Verify that the install directory does not exist yet if update=false, or ask to overwrite.</li>
<li>Verify that the install directory does exist if update=true, or ask to create.</li>
<li>Unzip the plugin in to appDir/plugins/name/</li>
<li>Add the plugin to plugins.config</li>
</ul>
<h3>
Plugin starter tasks
</h3>
This lists what happens when plugins are started.
First, plugins.config is checked to see which plugins need to be started.
For each plugin:
<ul>
<li>Check clients.config, and load and start each item (add the configured jars to the classpath).</li>
<li>Check console/webapp and console/webapp.config. Load and start required items (add the configured jars to the classpath).</li>
<li>Add console/locale/foo.jar to the translation classpath if present.</li>
<li>Add console/theme to the theme search path if present.</li>
<li>Add the summary bar link.</li>
</ul>
<h3>
Console webapp notes
</h3>
<p>
Console webapps with background tasks should implement a ServletContextListener
(see seedless or i2pbote for examples), or override destroy() in the servlet,
so that they can be stopped.
As of router version 0.7.12-3, console webapps will always be stopped before they
are restarted, so you do not need to worry about multiple instances,
as long as you do this.
Also as of router version 0.7.12-3, console webapps will be stopped at router shutdown.
<p>
Don't bundle library jars in the webapp; put them in lib/ and put a classpath in webapps.config.
Then you can make separate install and update plugins, where the update plugin does not
contain the library jars.
<p>
Don't include .java or .jsp files; otherwise jetty will recompile them at installation.
<p>
For now, a webapp needing to add classpath files in $PLUGIN must be the same name as the plugin.
For example, a webapp in plugin foo must be named foo.war.
<h3>
Eepsite notes
</h3>
<p>
It isn't clear how to have a plugin install to an existing eepsite.
The router has no hook to the eepsite, and it may or may not be running,
and there may be more than one.
Better is to start your own Jetty instance and I2PTunnel instance,
for a brand new eepsite.
<p>
It can instantiate a new I2PTunnel (kinda like the i2ptunnel CLI does),
but it won't appear in the i2ptunnel gui of course, that's a different instance.
But that's ok. Then you can start and stop i2ptunnel and jetty together.
<p>
So don't count on the router to automatically merge this with some existing eepsite. It probably won't happen.
Start a new I2PTunnel and Jetty from clients.config.
The best examples of this are the zzzot and pebble plugins,
available at <a href="http://stats.i2p/i2p/plugins/">zzz's plugins page</a>.
<p>
How to get path substitution into jetty.xml?
See zzzot and pebble plugins for examples.
<h3>
Client start/stop notes
</h3>
<p>
The router has no way to monitor the state of clients started via clients.config.
The plugin author should handle multiple start or stop calls gracefully, if at all possible,
by keeping a static state table, or using PID files, etc.
Avoid logging or exceptions on multiple starts or stops.
This also goes for a stop call without a previous start.
As of router version 0.7.12-3, plugins will be stopped at router shutdown,
which means that all clients with stopargs in clients.config will be called,
whether or not they were previously started.
<h3>
Shell script and external program notes
</h3>
<p>
To run shell scripts or other external programs, see <a href="http://zzz.i2p/topics/141">zzz.i2p</a>
<p>
To work on both Windows and Linux, write a small Java class that checks the OS type, then
runs ShellCommand on either the .bat or a .sh file you provide.
<p>
External programs won't be stopped when the router stops, and a second copy will
fire up when the router starts. To work around this, you could
write a wrapper class or shell script that does the usual storage of the PID
in a PID file, and check for it on start.
<h3>
Other plugin guidelines
</h3>
<ul>
<li>
See i2p.scripts branch or any of the sample plugins on zzz's page for a xpi2p file generator to make it easy.
<li>
Pack200 of jars and wars is strongly recommended for plugins, it generally shrinks plugins by 60-65%.
See any of the sample plugins on zzz's page for an example.
Pack200 unpacking is supported on routers 0.7.11-5 or higher, which is essentially all routers that
support plugins at all.
<li>
Plugins should not attempt to write anywhere in $I2P as it may be readonly, and that isn't good policy anyway.
<li>
Plugins may write to $CONFIG but keeping files in $PLUGIN only is recommended.
All files in $PLUGIN will be deleted at uninstall.
Files elsewhere will not be deleted at uninstall unless the plugin does it explicitly
with a client in clients.config run with uninstallargs.
If the user may want to save data after uninstallation, the uninstallargs hook
could ask.
<li>
$CWD may be anywhere; do not assume it is in a particular place, do not attempt to read or write files relative to $CWD.
<li>
Java programs should find out where they are with the directory getters in I2PAppContext.
<li>
Plugin directory is I2PAppContext.getGlobalContext().getAppDir().getAbsolutePath() + "/plugins/" + appname,
or put a $PLUGIN argument in the args line in clients.config.
There is no reliable way to find the i2p install or config or plugin directory without using the
context API in i2p.jar.
<li>
See <a href="http://zzz.i2p/topics/16">Howto</a> for info on generating signing keys and generating/verifying keys and sud files
<li>
All config files must be UTF-8.
<li>
To run in a separate JVM, use ShellCommand with java -cp foo:bar:baz my.main.class arg1 arg2 arg3.
Of course, it will be a lot harder to stop the plugin then...
But with some trickery with PID files it should be possible.
<li>
As an alternative to stopargs in clients.config,
a Java client may register a shutdown hook with I2PAppContext.addShutdownTask().
But this wouldn't shut down a plugin when upgrading, so stopargs is recommended.
Also, set all created threads to daemon mode.
<li>
Do not include classes duplicating those in the standard installation. Extend the classes if necessary.
<li>
Beware of the different classpath definitions in wrapper.config between old and new installations -
see classpath section below.
<li>
Clients will reject duplicate keys with different keynames, and duplicate keynames with different keys,
and different keys or keynames in upgrade packages. Safeguard your keys. Only generate them once.
<li>
Do not modify the plugin.config file at runtime as it will be overwritten on upgrade.
Use a different config file in the directory for storing runtime configuration.
<li>
In general, plugins should not require access to $I2P/lib/router.jar. Do not access router classes,
unless you are doing something special.
The router may in the future implement a restricted classpath for plugins that prevents
access to router classes.
<li>
Since each version must be higher than the one before, you could enhance your build
script to add a build number to the end of the version.
This helps for testing. Most of zzz's plugins have that feature, check build.xml for an example.
<li>
Plugins must never call System.exit().
<li>
Please respect licenses by meeting license requirements for any software you bundle.
</ul>
<h3>
Classpaths
</h3>
The following jars in $I2P/lib can be assumed to be in the standard classpath for all I2P installations,
no matter how old or how new the original installation:
<p>
i2p.jar, router.jar, jbigi.jar, sam.jar, mstreaming.jar, streaming.jar, i2ptunnel.jar,
org.mortbay.jetty.jar, javax.servlet.jar, jasper-compiler.jar, jasper-runtime.jar,
commons-logging.jar, commons-el.jar, wrapper.jar, systray.jar, systray4j.jar
<p>
Anything not listed above may not be present in everybody's classpath, even if you
have it in the classpath in YOUR version of i2p.
If you need any jar not listed above, add $I2P/lib/foo.jar to the classpath specified
in clients.config or webapps.config in your plugin.
<p>
Previously, a classpath entry specified in clients.config was added to the classpath for
the entire JVM.
However, as of 0.7.13-3, this was fixed using class loaders, and now, as originally intended,
the specified classpath in clients.config is only for the particular thread.
See the section on JVM crashes below, and
<a href="http://zzz.i2p/topics/633">this thread on zzz.i2p</a> for background.
Therefore, specify the full required classpath for each client.
<h3>
Java Version Notes
</h3>
While most I2P users are running a 1.6 (6.0) JVM, we support 1.5 (5.0) and higher JVMs.
Unless you require 1.6 features, you should create your plugin so it works on 1.5.
<p>
If your plugin <b>does not require 1.6</b>:
<ul>
<li>
Ensure that all java and jsp files are compiled with source="1.5" target="1.5".
<li>
Ensure that all bundled library jars are also for 1.5 or lower.
<li>
If you are using pack200, any 1.6 classes in a jar will
cause pack200 to create a 1.6 pack format, and
plugin installation will fail on a 1.5 system
with the misleading message "plugin is corrupt".
</ul>
<p>
If your plugin <b>requires 1.6</b>:
<ul>
<li>
Note that on your download page.
<li>
Add min-java-version=1.6 to your plugin.config
<li>
If you are using pack200, plugin installation will fail on a 1.5 system
with the misleading message "plugin is corrupt".
</ul>
<h3>
JVM Crashes When Updating
</h3>
Note - this should all be fixed now.
<p>
The JVM has a tendency to crash when updating jars in a plugin if that plugin was running
since i2p was started (even if the plugin was later stopped).
This may have been fixed with the class loader implementation in 0.7.13-3, but it may not.
For further testing.
<p>
The safest is to design your plugin with the jar inside the war (for a webapp), or to require a restart
after update, or don't update the jars in your plugin.
<p>
Due to the way class loaders work inside a webapp, it _may_ be safe to have external jars if
you specify the classpath in webapps.config.
More testing is required to verify this.
Don't specify the classpath with a 'fake' client in clients.config if it's only
needed for a webapp - use webapps.config instead.
<p>
The least safe, and apparently the source of most crashes, is clients with plugin jars specified
in the classpath in clients.config.
<p>
None of this should be a problem on initial install - you should not ever have to require a restart
for an initial install of a plugin.
{% endblock %}

View File

@@ -0,0 +1,323 @@
{% extends "global/layout.html" %}
{% block title %}Tunnel Message Specification{% endblock %}
{% block content %}
Updated October 2011 for release 0.8.10
<h1>Tunnel Message Specification</h1>
This document specifies the format of tunnel messages.
For general information about tunnels see
<a href="tunnel-alt.html">the tunnel documentation</a>.
<h2>Message preprocessing</h3>
A <i>tunnel gateway</i> is the entrance, or first hop, of a tunnel.
For an outbound tunnel, the gateway is the creator of the tunnel.
For an inbound tunnel, the gateway is at the opposite end from the creator of the tunnel.
<p>
A gateway <i>preprocesses</i> <a href="i2np.html">I2NP messages</a>
by fragmenting and combining them into tunnel messages.
<p>
While I2NP messages are variable size from 0 to almost 64 KB,
tunnel messages are fixed-size, approximately 1 KB.
Fixed message size
restricts several types of attacks that are possible from
observing message size.
<p>
After the tunnel messages are created, they are encrypted as described in
<a href="tunnel-alt.html">the tunnel documentation</a>.
<h2 id="msg_Data">Tunnel Message (Encrypted)</h2>
These are the contents of a tunnel data message after encryption.
<pre>
{% filter escape %}
+----+----+----+----+----+----+----+----+
| Tunnel ID | IV |
+----+----+----+----+ +
| |
+ +----+----+----+----+
| | |
+----+----+----+----+ +
| |
+ Encrypted Data +
~ ~
| |
+ +-------------------+
| |
+----+----+----+----+
{% endfilter %}
</pre>
<h4>Definition</h4>
<pre>
{% filter escape %}
Tunnel ID:
4 bytes
The ID of the next hop
IV:
16 bytes
The initialization vector
Encrypted Data
1008 bytes
The encrypted tunnel message
Total Size: 1028 Bytes
{% endfilter %}
</pre>
<h2 id="msg_Data">Tunnel Message (Decrypted)</h2>
These are the contents of a tunnel data message when decrypted.
<pre>
{% filter escape %}
+----+----+----+----+----+----+----+----+
| Tunnel ID | IV |
+----+----+----+----+ +
| |
+ +----+----+----+----+
| | Checksum |
+----+----+----+----+----+----+----+----+
| nonzero padding.. |
~ ~
| |
+ +----+
| |zero|
+----+----+----+----+----+----+----+----+
| |
| Delivery Instructions 1 |
~ ~
| |
+----+----+----+----+----+----+----+----+
| |
+ I2NP Message Fragment 1 +
| |
~ ~
| |
+----+----+----+----+----+----+----+----+
| |
| Delivery Instructions 2... |
~ ~
| |
+----+----+----+----+----+----+----+----+
| |
+ I2NP Message Fragment 2... +
| |
~ ~
| |
+ +-------------------+
| |
+----+----+----+----+
{% endfilter %}
</pre>
<h4>Definition</h4>
<pre>
Tunnel ID:
4 bytes
The ID of the next hop
IV:
16 bytes
The initialization vector
Checksum:
4 bytes
The first 4 bytes of the SHA256 hash of the remaining contents of the message concatenated with the IV
Nonzero padding:
0 or more bytes
Random nonzero data for padding
Zero:
1 byte
The value 0x00
Delivery Instructions:
Length varies but is typically 7, 39, 43, or 47 bytes
Indicates the fragment and the routing for the fragment
See <a href="#delivery">below</a> for specification
Message Fragment:
1 to 996 bytes, actual maximum depends on delivery instruction size
A partial or full I2NP Message
Total Size: 1028 Bytes
</pre>
<p>Note that the padding, if any, must be before the instruction/message pairs.
there is no provision for padding at the end.</p>
<h2 id="delivery">Delivery Instructions</h2>
<p>The instructions are encoded with a single control byte, followed by any
necessary additional information. The first bit (MSB) in that control byte determines
how the remainder of the header is interpreted - if it is not set, the message
is either not fragmented or this is the first fragment in the message. If it is
set, this is a follow on fragment.</p>
<p>
Note that Delivery Instructions are also used inside
<a href="{{ site_url('docs/specs/i2np') }}#struct_GarlicClove">Garlic Cloves</a>,
where the format is slightly different. In a Garlic Clove,
messages are not fragmented, and the fragment bit in the flag byte is
redefined. See the
<a href="{{ site_url('docs/specs/i2np') }}#struct_GarlicClove">Garlic Clove documentation</a>
for more details.
<h3>First Fragment Delivery Instructions</h3>
<p>If the MSB of the first byte is 0, this is an initial I2NP message fragment,
or a complete I2NP message, and the instructions are:</p>
<pre>
{% filter escape %}
+----+----+----+----+----+----+----+----+
|flag| Tunnel ID (opt) | |
+----+----+----+----+----+ +
| |
+ +
| To Hash (optional) |
+ +
| |
+ +--------------+
| |dly | Msg... |
+----+----+----+----+----+----+----+----+
|..ID(opt)| ext opts... (opt) | size |
+----+----+----+----+----+----+----+----+
{% endfilter %}
</pre>
<h4>Definition</h4>
<pre>
flag:
1 byte
Bit order: 76543210
bit 7: 0 to specify an initial fragment
bits 6-5: delivery type
For tunnel messages:
0x0 = LOCAL, 0x01 = TUNNEL, 0x02 = ROUTER, 0x03 = unused
For garlic cloves:
0x0 = LOCAL, 0x01 = DESTINATION, 0x02 = ROUTER, 0x03 = TUNNEL
bit 4: delay included? Unimplemented, always 0
If 1, a delay byte is included
bit 3: fragmented? If 0, the message is not fragmented, what follows is the entire message
If 1, the message is fragmented, and the instructions contain a Message ID
bit 2: extended options? Unimplemented, always 0
If 1, extended options are included
bits 1-0: reserved
Tunnel ID:
4 bytes
Optional, present if delivery type is TUNNEL
The destination tunnel ID
To Hash:
32 bytes
Optional, present if delivery type is DESTINATION, ROUTER, or TUNNEL
If DESTINATION, the SHA256 Hash of the destination
If ROUTER, the SHA256 Hash of the router
If TUNNEL, the SHA256 Hash of the gateway router
Delay:
1 byte (tunnel message) or 4 bytes (garlic clove)
Optional, present if delay included flag is set
In tunnel messages: Unimplemented, never present; original specification:
bit 7: type (0 = strict, 1 = randomized)
bits 6-0: delay exponent (2^value minutes)
In garlic cloves: Not fully implemented. A 4 byte integer specifying the delay in seconds.
Message ID:
4 bytes
Optional, present if this message is the first of 2 or more fragments
An ID that uniquely identifies all fragments as belonging to a single message
(the current implementation uses the <a href="{{ site_url('docs/specs/i2np') }}#struct_header">I2NP Message ID</a>)
Extended Options:
2 or more bytes
Optional, present if extend options flag is set
Unimplemented, never present; original specification:
One byte length and then that many bytes
size:
2 bytes
The length of the fragment that follows
Valid values: 1 to approx. 960 in a tunnel message; 1 to 64K - 1 in a garlic clove
Total length: Typical length is:
3 bytes for LOCAL delivery (garlic clove);
35 bytes for ROUTER / DESTINATION delivery or 39 bytes for TUNNEL delivery (unfragmented or garlic clove);
39 bytes for ROUTER delivery or 43 bytes for TUNNEL delivery (first fragment)
</pre>
<h3>Follow-on Fragment Delivery Instructions</h3>
<p>If the MSB of the first byte is 1, this is a follow-on fragment, and the instructions are:</p>
<pre>
{% filter escape %}
+----+----+----+----+----+----+----+
|frag| Message ID | size |
+----+----+----+----+----+----+----+
{% endfilter %}
</pre>
<h4>Definition</h4>
<pre>
{% filter escape %}
frag:
1 byte
Binary 1nnnnnnd
The first bit is 1 to indicate this is a follow-on fragment
nnnnnn is the 6 bit fragment number from 1 to 63
d is 1 to indicate the last fragment, 0 otherwise
Message ID:
4 bytes
The same ID specified in the first fragment
size:
2 bytes
The length of the fragment that follows
Valid values: 1 to 996
Total length: 7 bytes
{% endfilter %}
</pre>
<h3><a href="http://docs.i2p-projekt.de/javadoc/net/i2p/data/i2np/DeliveryInstructions.html">Delivery Instructions Javadoc</a></h3>
<h2 id="notes">Notes</h2>
<h3>I2NP Message Maximum Size</h3>
<p>
While the maximum I2NP message size is nominally 64 KB, the size is further constrained by the
method of fragmenting I2NP messages into multiple 1 KB tunnel messages.
The maximum number of fragments is 64, and the initial fragment may not
be perfectly aligned at the start of a tunnel message.
So the message must nominally fit in 63 fragments.
<p>
The maximum size of an initial fragment is 956 bytes (assuming TUNNEL delivery mode);
the maximum size of a follow-on fragment is 996 bytes.
Therefore the maximum size is approximately 956 + (62 * 996) = 62708 bytes, or 61.2 KB.
</p>
<h3>Ordering, Batching, Packing</h3>
Tunnel messages may be dropped or reordered.
The tunnel gateway, who creates tunnel messages, is free to implement any
batching, mixing, or reordering strategy to fragment I2NP messages and
efficiently pack fragments into tunnel messages.
In general, an optimal packing is not possible (the "packing problem").
The gateways may implement various delay and reordering strategies.
<h3>Cover Traffic</h3>
Tunnel messages may contain only padding (i.e. no delivery instructions or message fragments at all)
for cover traffic. This is unimplemented.
{% endblock %}