forked from I2P_Developers/i2p.www
propagate from branch 'i2p.www' (head 2df62e69107d5013915619b4a7116fb920e9638d)
to branch 'i2p.www.str4d' (head 316dc8ab7159c0ac13be0c8f192b3376123e5523)
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
{%- macro change_lang(lang) -%}
|
||||
{%- if request.endpoint == 'site_show' -%}{{ url_for('site_show', lang=lang, page=page) }}
|
||||
{%- elif request.endpoint == 'spec_show' -%}{{ url_for('spec_show', name=name) }}
|
||||
{%- elif request.endpoint == 'blog_index' -%}
|
||||
{%- if category -%}{{ url_for('blog_index', lang=lang, category=category) }}
|
||||
{%- else -%}{{ url_for('blog_index', lang=lang) }}
|
||||
|
@@ -29,23 +29,7 @@
|
||||
<li><a href="{{ site_url('docs/how/elgamal-aes') }}"><div class="menuitem"><span>{{ _('ElGamal/AES+SessionTags') }}</span></div></a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="has-sub"><div class="menuitem"><span>{{ _('Specifications') }}</span></div>
|
||||
<ul>
|
||||
<li><a href="{{ site_url('docs/spec/blockfile') }}"><div class="menuitem"><span>{{ _('Blockfile') }}</span></div></a></li>
|
||||
<li><a href="{{ site_url('docs/spec/common-structures') }}"><div class="menuitem"><span>{{ _('Common structures') }}</span></div></a></li>
|
||||
<li><a href="{{ site_url('docs/spec/configuration') }}"><div class="menuitem"><span>{{ _('Configuration files') }}</span></div></a></li>
|
||||
<li><a href="{{ site_url('docs/spec/datagrams') }}"><div class="menuitem"><span>{{ _('Datagrams') }}</span></div></a></li>
|
||||
<li><a href="{{ site_url('docs/spec/geoip') }}"><div class="menuitem"><span>{{ _('GeoIP files') }}</span></div></a></li>
|
||||
<li><a href="{{ site_url('docs/spec/i2cp') }}"><div class="menuitem"><span>I2CP</span></div></a></li>
|
||||
<li><a href="{{ site_url('docs/spec/i2np') }}"><div class="menuitem"><span>I2NP</span></div></a></li>
|
||||
<li><a href="{{ site_url('docs/spec/plugin') }}"><div class="menuitem"><span>{{ _('Plugins') }}</span></div></a></li>
|
||||
<li><a href="{{ site_url('docs/spec/ssu') }}"><div class="menuitem"><span>SSU</span></div></a></li>
|
||||
<li><a href="{{ site_url('docs/spec/streaming') }}"><div class="menuitem"><span>{{ _('Streaming library') }}</span></div></a></li>
|
||||
<li><a href="{{ site_url('docs/spec/tunnel-creation') }}"><div class="menuitem"><span>{{ _('Tunnel creation') }}</span></div></a></li>
|
||||
<li><a href="{{ site_url('docs/spec/tunnel-message') }}"><div class="menuitem"><span>{{ _('Tunnel messages') }}</span></div></a></li>
|
||||
<li><a href="{{ site_url('docs/spec/updates') }}"><div class="menuitem"><span>{{ _('Software updates') }}</span></div></a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="{{ url_for('spec_index') }}"><div class="menuitem"><span>{{ _('Specifications') }}</span></div></a></li>
|
||||
<li class="has-sub"><div class="menuitem"><span>{{ _('API') }}</span></div>
|
||||
<ul>
|
||||
<li><a href="{{ site_url('docs/api/i2ptunnel') }}"><div class="menuitem"><span>I2PTunnel</span></div></a></li>
|
||||
|
@@ -1,523 +0,0 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %}{% trans %}Low-level Cryptography Details{% endtrans %}{% endblock %}
|
||||
{% block lastupdated %}{% trans %}December 2014{% endtrans %}{% endblock %}
|
||||
{% block accuratefor %}0.9.17{% endblock %}
|
||||
{% block content %}
|
||||
<p>{% trans -%}
|
||||
This page specifies the low-level details of the cryptography in I2P.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans elgamalaes=site_url('docs/how/elgamal-aes') -%}
|
||||
There are a handful of cryptographic algorithms in use within I2P, but we have
|
||||
reduced them to a bare minimum to deal with our needs - one symmetric algorithm
|
||||
one asymmetric algorithm, one signing algorithm, and one hashing algorithm. However,
|
||||
we do combine them in some particular ways to provide message integrity (rather than
|
||||
relying on a MAC). In addition, as much as we hate doing anything new in regards to
|
||||
cryptography, we can't seem to find a reference discussing (or even naming) the
|
||||
technique used in <a href="{{ elgamalaes }}">ElGamal/AES+SessionTag</a> (but we're sure others have done it).
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h2><a name="elgamal">{% trans %}ElGamal encryption{% endtrans %}</a></h2>
|
||||
|
||||
<p>{% trans %}
|
||||
ElGamal is used for asymmetric encryption.
|
||||
ElGamal is used in several places in I2P:
|
||||
{%- endtrans %}</p>
|
||||
<ul>
|
||||
<li>{% trans tunnelcreation=site_url('docs/spec/tunnel-creation') -%}
|
||||
To encrypt router-to-router <a href="{{ tunnelcreation }}">Tunnel Build Messages</a>
|
||||
{%- endtrans %}</li>
|
||||
<li>{% trans elgamalaes=site_url('docs/how/elgamal-aes'), commonstructures=site_url('docs/spec/common-structures') -%}
|
||||
For end-to-end (destination-to-destination) encryption as a part of <a href="{{ elgamalaes }}">ElGamal/AES+SessionTag</a>
|
||||
using the encryption key in the <a href="{{ commonstructures }}#struct_LeaseSet">LeaseSet</a>
|
||||
{%- endtrans %}</li>
|
||||
<li>{% trans netdb=site_url('docs/how/network-database'), elgamalaes=site_url('docs/how/elgamal-aes') -%}
|
||||
For encryption of some <a href="{{ netdb }}#delivery">netDb stores and queries sent to floodfill routers</a>
|
||||
as a part of <a href="{{ elgamalaes }}">ElGamal/AES+SessionTag</a>
|
||||
(destination-to-router or router-to-router).
|
||||
{%- endtrans %}</li>
|
||||
</ul>
|
||||
|
||||
<p>{% trans -%}
|
||||
We use common primes for 2048 ElGamal encryption and decryption, as given by <a href="http://tools.ietf.org/html/rfc3526">IETF RFC-3526</a>.
|
||||
We currently only use ElGamal to encrypt the IV and session key in a single block, followed by the
|
||||
AES encrypted payload using that key and IV.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans -%}
|
||||
The unencrypted ElGamal contains:
|
||||
{%- endtrans %}</p>
|
||||
{% highlight lang='dataspec' %}
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|nonz| H(data) |
|
||||
+----+ +
|
||||
| |
|
||||
+ +
|
||||
| |
|
||||
+ +
|
||||
| |
|
||||
+ +----+----+----+----+----+----+----+
|
||||
| | data...
|
||||
+----+----+----+-//
|
||||
{% endhighlight %}
|
||||
|
||||
<p>{% trans -%}
|
||||
The H(data) is the SHA256 of the data that is encrypted in the ElGamal block,
|
||||
and is preceded by a nonzero byte.
|
||||
This byte could be random, but as implemented it is always 0xFF.
|
||||
It could possibly be used for flags in the future.
|
||||
The data encrypted in the block may be up to 222 bytes long.
|
||||
As the encrypted data may contain a substantial number of zeros if the
|
||||
cleartext is smaller than 222 bytes, it is recommended that higher layers pad
|
||||
the cleartext to 222 bytes with random data.
|
||||
Total length: typically 255 bytes.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans -%}
|
||||
The encrypted ElGamal contains:
|
||||
{%- endtrans %}</p>
|
||||
</p>
|
||||
{% highlight lang='dataspec' %}
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| zero padding... | |
|
||||
+----+----+----+-//-+----+ +
|
||||
| |
|
||||
+ +
|
||||
| ElG encrypted part 1 |
|
||||
~ ~
|
||||
| |
|
||||
+ +----+----+----+----+----+----+----+
|
||||
| | zero padding... | |
|
||||
+----+----+----+----+-//-+----+ +
|
||||
| |
|
||||
+ +
|
||||
| ElG encrypted part 2 |
|
||||
~ ~
|
||||
| |
|
||||
+ +----+----+----+----+----+----+
|
||||
| +
|
||||
+----+----+
|
||||
{% endhighlight %}
|
||||
|
||||
<p>{% trans -%}
|
||||
Each encrypted part is prepended with zeros to a size of exactly 257 bytes.
|
||||
Total length: 514 bytes.
|
||||
In typical usage, higher layers pad the cleartext data to 222 bytes,
|
||||
resulting in an unencrypted block of 255 bytes.
|
||||
This is encoded as two 256-byte encrypted parts,
|
||||
and there is a single byte of zero padding before each part at this layer.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans url='https://github.com/i2p/i2p.i2p/tree/master/core/java/src/net/i2p/crypto/ElGamalEngine.java' -%}
|
||||
See <a href="{{ url }}">the ElGamal code</a>.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans -%}
|
||||
The shared prime is the
|
||||
<a href="http://tools.ietf.org/html/rfc3526#section-3">[Oakley prime for 2048 bit keys]</a>
|
||||
{%- endtrans %}</p>
|
||||
<pre>
|
||||
2^2048 - 2^1984 - 1 + 2^64 * { [2^1918 pi] + 124476 }
|
||||
</pre>
|
||||
<p>{% trans -%}
|
||||
or as a hexadecimal value:
|
||||
{%- endtrans %}</p>
|
||||
<pre>
|
||||
FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1
|
||||
29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD
|
||||
EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245
|
||||
E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED
|
||||
EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D
|
||||
C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F
|
||||
83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D
|
||||
670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B
|
||||
E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9
|
||||
DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510
|
||||
15728E5A 8AACAA68 FFFFFFFF FFFFFFFF
|
||||
</pre>
|
||||
<p>{% trans -%}
|
||||
Using 2 as the generator.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h3><a name="exponent">{% trans %}Short Exponent{% endtrans %}</a></h3>
|
||||
<p>{% trans commonstructures=site_url('docs/spec/common-structures') -%}
|
||||
While the standard exponent size is 2048 bits (256 bytes) and the I2P
|
||||
<a href="{{ commonstructures }}#type_PrivateKey">PrivateKey</a>
|
||||
is a full 256 bytes, in some cases
|
||||
we use the short exponent size of 226 bits (28.25 bytes).
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans pdf='http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.14.5952&rep=rep1&type=pdf',
|
||||
benchmarks=site_url('misc/benchmarks'),
|
||||
oldbenchmarks='http://www.eskimo.com/~weidai/benchmarks.html' -%}
|
||||
This should be safe for use with the Oakley primes, per
|
||||
<a href="{{ pdf }}">On Diffie-Hellman Key Agreement with Short Exponents - van Oorschot, Weiner</a>
|
||||
at EuroCrypt 96, and <a href="{{ benchmarks }}">crypto++'s benchmarks</a>.
|
||||
Benchmarks originally at <a rel="nofollow" href="{{ oldbenchmarks }}">this link, now dead</a>,
|
||||
rescued from <a href="http://www.archive.org/">the wayback machine</a>, dated Apr 23, 2008.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans book='http://www.springerlink.com/content/2jry7cftp5bpdghm/',
|
||||
fulltext='http://books.google.com/books?id=cXyiNZ2_Pa0C&lpg=PA173&ots=PNIz3dWe4g&pg=PA173#v=onepage&q&f=false',
|
||||
thread='http://groups.google.com/group/sci.crypt/browse_thread/thread/1855a5efa7416677/339fa2f945cc9ba0#339fa2f945cc9ba0' -%}
|
||||
Also, <a href="{{ book }}">Koshiba & Kurosawa: Short Exponent Diffie-Hellman Problems</a> (PKC 2004, LNCS 2947, pp. 173-186)
|
||||
<a href="{{ fulltext }}">(full text on Google Books)</a> apparently supports this, according to
|
||||
<a href="{{ thread }}">this sci.crypt thread</a>.
|
||||
The remainder of the PrivateKey is padded with zeroes.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans -%}
|
||||
Prior to release 0.9.8, all routers used the short exponent.
|
||||
As of release 0.9.8, 64-bit x86 routers use a full 2048-bit exponent.
|
||||
Other routers continue to use the short exponent due to concerns about processor load.
|
||||
The transition to a longer exponent for these platforms is a topic for further study.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h4>{% trans %}Obsolescence{% endtrans %}</h4>
|
||||
<p>{% trans -%}
|
||||
The vulnerability of the network to an ElGamal attack and the impact of transitioning to a longer bit length is to be studied.
|
||||
It may be quite difficult to make any change backward-compatible.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
|
||||
<h2><a name="AES">AES</a></h2>
|
||||
|
||||
<p>{% trans -%}
|
||||
AES is used for symmetric encryption, in several cases:
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<ul>
|
||||
<li>{% trans -%}
|
||||
For <a href="#transports">transport encryption</a> after DH key exchange
|
||||
{%- endtrans %}</li>
|
||||
|
||||
<li>{% trans elgamalaes=site_url('docs/how/elgamal-aes') -%}
|
||||
For end-to-end (destination-to-destination) encryption as a part of <a href="{{ elgamalaes }}">ElGamal/AES+SessionTag</a>
|
||||
{%- endtrans %}</li>
|
||||
|
||||
<li>{% trans netdb=site_url('docs/how/network-database'), elgamalaes=site_url('docs/how/elgamal-aes') -%}
|
||||
For encryption of some <a href="{{ netdb }}#delivery">netDb stores and queries sent to floodfill routers</a>
|
||||
as a part of <a href="{{ elgamalaes }}">ElGamal/AES+SessionTag</a>
|
||||
(destination-to-router or router-to-router).
|
||||
{%- endtrans %}</li>
|
||||
|
||||
<li>{% trans tunnelrouting=site_url('docs/how/tunnel-routing') -%}
|
||||
For encryption of <a href="{{ tunnelrouting }}#testing">periodic tunnel test messages</a> sent from the router to itself, through its own tunnels.
|
||||
{%- endtrans %}</li>
|
||||
</ul>
|
||||
|
||||
<p>{% trans rfc2313='http://tools.ietf.org/html/rfc2313',
|
||||
code1='https://github.com/i2p/i2p.i2p/tree/master/core/java/src/net/i2p/crypto/CryptixAESEngine.java',
|
||||
code2='https://github.com/i2p/i2p.i2p/tree/master/core/java/src/net/i2p/crypto/CryptixRijndael_Algorithm.java',
|
||||
code3='https://github.com/i2p/i2p.i2p/tree/master/core/java/src/net/i2p/crypto/ElGamalAESEngine.java' -%}
|
||||
We use AES with 256 bit keys and 128 bit blocks in CBC mode.
|
||||
The padding used is specified in <a href="{{ rfc2313 }}">IETF RFC-2313 (PKCS#5 1.5, section 8.1 (for block type 02))</a>.
|
||||
In this case, padding exists of pseudorandomly generated octets to match 16 byte blocks.
|
||||
Specifically, see <a href="{{ code1 }}">[the CBC code]</a> and the Cryptix AES
|
||||
<a href="{{ code2 }}">[implementation]</a>, as well as the padding, found in the
|
||||
<a href="{{ code3 }}">ElGamalAESEngine.getPadding</a> function.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<!-- *********************************************************************************
|
||||
Believe it or not, we don't do this any more. If we ever did. safeEncode() and safeDecode() are unused.
|
||||
|
||||
<p>
|
||||
In all cases, we know the size of the data to be sent, and we AES encrypt the following:
|
||||
<p>
|
||||
<pre>
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| H(data) |
|
||||
+ +
|
||||
| |
|
||||
+ +
|
||||
| |
|
||||
+ +
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| size | data ... |
|
||||
+----+----+----+----+ +
|
||||
| |
|
||||
~ ~
|
||||
| |
|
||||
+ +
|
||||
| |
|
||||
+ +----//---+----+
|
||||
| | |
|
||||
+----+----+----//---+----+ +
|
||||
| Padding to 16 bytes |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|
||||
H(data): 32-byte SHA-256 Hash of the data
|
||||
|
||||
size: 4-byte Integer, number of data bytes to follow
|
||||
|
||||
data: payload
|
||||
|
||||
padding: random data, to a multiple of 16 bytes
|
||||
|
||||
</pre>
|
||||
<p>
|
||||
After the data comes an application-specified number of randomly generated padding bytes.
|
||||
This application-specified number is rounded up to a multiple of 16.
|
||||
The entire segment (from H(data) through the end of the random bytes) is AES encrypted
|
||||
(256 bit CBC w/ PKCS#5).
|
||||
|
||||
<p>
|
||||
This code is implemented in the safeEncrypt and safeDecrypt methods of
|
||||
AESEngine but it is unused.
|
||||
</p>
|
||||
|
||||
*************************************************************** -->
|
||||
|
||||
|
||||
<h4>{% trans %}Obsolescence{% endtrans %}</h4>
|
||||
<p>{% trans -%}
|
||||
The vulnerability of the network to an AES attack and the impact of transitioning to a longer bit length is to be studied.
|
||||
It may be quite difficult to make any change backward-compatible.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h4>{% trans %}References{% endtrans %}</h4>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="{{ get_url('blog_post', slug='2006/02/07/status') }}">{% trans %}Feb. 7, 2006 Status Notes{% endtrans %}</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2><a name="sig">{% trans %}Digital Signatures{% endtrans %}</a></h2>
|
||||
|
||||
<p>{% trans -%}
|
||||
DSA is the default signature algorithm, but we are in the process of migrating to more secure algorithms. See below.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h3><a name="DSA">DSA</a></h3>
|
||||
|
||||
<p>{% trans code='https://github.com/i2p/i2p.i2p/tree/master/core/java/src/net/i2p/crypto/DSAEngine.java' -%}
|
||||
Signatures are generated and verified with 1024 bit DSA (L=1024, N=160), as implemented in
|
||||
<a href="{{ code }}">[DSAEngine]</a>.
|
||||
DSA was chosen because it is much faster for signatures than ElGamal.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h4>SEED</h4>
|
||||
|
||||
<p>160 bit</p>
|
||||
|
||||
<pre>
|
||||
86108236b8526e296e923a4015b4282845b572cc
|
||||
</pre>
|
||||
|
||||
<h4>Counter</h4>
|
||||
|
||||
<pre>
|
||||
33
|
||||
</pre>
|
||||
<p>
|
||||
<H4>DSA prime (p)</H4>
|
||||
|
||||
<p>1024 bit</p>
|
||||
|
||||
<p>
|
||||
<pre>
|
||||
9C05B2AA 960D9B97 B8931963 C9CC9E8C 3026E9B8 ED92FAD0
|
||||
A69CC886 D5BF8015 FCADAE31 A0AD18FA B3F01B00 A358DE23
|
||||
7655C496 4AFAA2B3 37E96AD3 16B9FB1C C564B5AE C5B69A9F
|
||||
F6C3E454 8707FEF8 503D91DD 8602E867 E6D35D22 35C1869C
|
||||
E2479C3B 9D5401DE 04E0727F B33D6511 285D4CF2 9538D9E3
|
||||
B6051F5B 22CC1C93
|
||||
</pre>
|
||||
<p>
|
||||
<H4>DSA quotient (q)</H4>
|
||||
|
||||
<p>
|
||||
<pre>
|
||||
A5DFC28F EF4CA1E2 86744CD8 EED9D29D 684046B7
|
||||
</pre>
|
||||
<p>
|
||||
<H4>DSA generator (g)</H4>
|
||||
|
||||
<p>1024 bit</p>
|
||||
|
||||
<p>
|
||||
<pre>
|
||||
0C1F4D27 D40093B4 29E962D7 223824E0 BBC47E7C 832A3923
|
||||
6FC683AF 84889581 075FF908 2ED32353 D4374D73 01CDA1D2
|
||||
3C431F46 98599DDA 02451824 FF369752 593647CC 3DDC197D
|
||||
E985E43D 136CDCFC 6BD5409C D2F45082 1142A5E6 F8EB1C3A
|
||||
B5D0484B 8129FCF1 7BCE4F7F 33321C3C B3DBB14A 905E7B2B
|
||||
3E93BE47 08CBCC82
|
||||
</pre>
|
||||
|
||||
<p>{% trans commonstructures=site_url('docs/spec/common-structures') -%}
|
||||
The <a href="{{ commonstructures }}#type_SigningPublicKey">Signing Public Key</a> is 1024 bits.
|
||||
The <a href="{{ commonstructures }}#type_SigningPrivateKey">Signing Private Key</a> is 160 bits.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
|
||||
<h4>{% trans %}Obsolescence{% endtrans %}</h4>
|
||||
<p>{% trans pdf='http://csrc.nist.gov/publications/nistpubs/800-57/sp800-57-Part1-revised2_Mar08-2007.pdf' -%}
|
||||
<a href="{{ pdf }}">NIST 800-57</a>
|
||||
recommends a minimum of (L=2048, N=224) for usage beyond 2010.
|
||||
This may be mitigated somewhat by the "cryptoperiod", or lifespan of a given key.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans -%}
|
||||
The prime number was chosen <a href="#choosing_constants">in 2003</a>,
|
||||
and the person that chose the number (TheCrypto) is currently no longer an I2P developer.
|
||||
As such, we do not know if the prime chosen is a 'strong prime'.
|
||||
If a larger prime is chosen for future purposes, this should be a strong prime, and we will document the construction process.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
|
||||
<h4>{% trans %}References{% endtrans %}</h4>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="{{ get_url('meetings_show', id=51) }}">{% trans num=51 %}Meeting {{ num }}{% endtrans %}</a>
|
||||
<li>
|
||||
<a href="{{ get_url('meetings_show', id=52) }}">{% trans num=52 %}Meeting {{ num }}{% endtrans %}</a>
|
||||
<li>
|
||||
<a name="choosing_constants" href="http://article.gmane.org/gmane.comp.security.invisiblenet.iip.devel/343">{% trans %}Choosing the constants{% endtrans %}</a>
|
||||
<li>
|
||||
<a href="http://en.wikipedia.org/wiki/Digital_Signature_Algorithm">DSA</a>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<h2>{% trans %}New Signature Algorithms{% endtrans %}</h2>
|
||||
<p>{% trans -%}
|
||||
As of release 0.9.12, the router supports additional signature algorithms that are more secure than 1024-bit DSA.
|
||||
The first usage is for Destinations; support for Router Identities was added in release 0.9.16.
|
||||
Support for migrating existing Destinations from old to new signatures will be added in a future release.
|
||||
Signature type is encoded in the Destination and Router Identity, so that new signature algorithms
|
||||
or curves may be added at any time.
|
||||
The current supported signature types are as follows:
|
||||
{%- endtrans %}</p>
|
||||
<ul>
|
||||
<li>DSA-SHA1</li>
|
||||
<li>ECDSA-SHA256-P256</li>
|
||||
<li>ECDSA-SHA384-P384</li>
|
||||
<li>ECDSA-SHA512-P521</li>
|
||||
<li>RSA-SHA256-2048</li>
|
||||
<li>RSA-SHA384-3072</li>
|
||||
<li>RSA-SHA512-4096</li>
|
||||
<li>EdDSA-SHA512-Ed25519 (as of release 0.9.15)</li>
|
||||
</ul>
|
||||
|
||||
<h3>ECDSA</h3>
|
||||
|
||||
<p>{% trans -%}
|
||||
ECDSA uses the standard NIST curves and standard SHA-2 hashes.
|
||||
We will migrate new destinations to ECDSA-SHA256-P256 in the 0.9.16 - 0.9.19 release time frame.
|
||||
Usage for Router Identities is supported as of release 0.9.16 and migration may occur in early 2015.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
|
||||
<h3>RSA</h3>
|
||||
|
||||
<p>{% trans -%}
|
||||
Standard RSA PKCS#1 v1.5 (RFC 2313) with the public exponent F4 = 65537.
|
||||
RSA is now used for signing all out-of-band trusted content, including router updates, reseeding, plugins, and news.
|
||||
The signatures are embedded in the "su3" format documented on the router updates page.
|
||||
4096-bit keys are recommended and used by all known signers.
|
||||
RSA is not used, or planned for use, in any in-network Destinations or Router Identities.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
|
||||
<h3>EdDSA 25519</h3>
|
||||
|
||||
<p>{% trans -%}
|
||||
Standard EdDSA using curve 25519 and standard 512-bit SHA-2 hashes.
|
||||
Supported as of release 0.9.15.
|
||||
Migration for Destinations and Router Identities is scheduled for mid-2015.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
|
||||
|
||||
<H2><a name="SHA256">SHA256</a></H2>
|
||||
|
||||
<p>{% trans code='https://github.com/i2p/i2p.i2p/tree/master/core/java/src/net/i2p/crypto/SHA256Generator.java' -%}
|
||||
Hashes within I2P are plain old SHA256, as implemented in
|
||||
<a href="{{ code }}">[SHA256Generator]</a>
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h4>{% trans %}Obsolescence{% endtrans %}</h4>
|
||||
<p>{% trans -%}
|
||||
The vulnerability of the network to a SHA-256 attack and the impact of transitioning to a longer hash is to be studied.
|
||||
It may be quite difficult to make any change backward-compatible.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h4>{% trans %}References{% endtrans %}</h4>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="http://en.wikipedia.org/wiki/SHA-2">SHA-2</a>
|
||||
</ul>
|
||||
|
||||
<h2 id="transports">{% trans %}Transports{% endtrans %}</h2>
|
||||
<p>{% trans -%}
|
||||
At the lowest protocol layer,
|
||||
point-to-point inter-router communication is protected by the transport layer security.
|
||||
Both transports use 256 byte (2048 bit) Diffie-Hellman key exchange
|
||||
using
|
||||
<a href="#elgamal">the same shared prime and generator as specified above for ElGamal</a>,
|
||||
followed by symmetric AES encryption as described above.
|
||||
This provides
|
||||
<a href="http://en.wikipedia.org/wiki/Perfect_forward_secrecy">perfect forward secrecy</a>
|
||||
on the transport links.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h3><a name="tcp">{% trans %}NTCP connections{% endtrans %}</a></h3>
|
||||
|
||||
<p>{% trans elgamalaes=site_url('docs/how/elgamal-aes') -%}
|
||||
NTCP connections are negotiated with a 2048 Diffie-Hellman implementation,
|
||||
using the router's identity to proceed with a station to station agreement, followed by
|
||||
some encrypted protocol specific fields, with all subsequent data encrypted with AES
|
||||
(as above).
|
||||
The primary reason to do the DH negotiation instead of using <a href="{{ elgamalaes }}">ElGamalAES+SessionTag</a> is that it provides '<a href="http://en.wikipedia.org/wiki/Perfect_forward_secrecy">(perfect) forward secrecy</a>', while <a href="{{ elgamalaes }}">ElGamalAES+SessionTag</a> does not.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans -%}
|
||||
In order to migrate to a more standardized implementation (TLS/SSL or even SSH), the following issues must be addressed:
|
||||
{%- endtrans %}</p>
|
||||
<ol>
|
||||
<li>{% trans -%}
|
||||
Can we somehow reestablish sessions securely (ala session tags) or do we need to do full negotiation each time?
|
||||
{%- endtrans %}</li>
|
||||
<li>{% trans -%}
|
||||
Can we simplify/avoid the x509 or other certificate formats and use our own RouterInfo structure (which
|
||||
contains the ElGamal and DSA keys)?
|
||||
{%- endtrans %}</li>
|
||||
</ol>
|
||||
<p>{% trans ntcp=site_url('docs/transport/ntcp') -%}
|
||||
See <a href="{{ ntcp }}">the NTCP specification</a> for details.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h3><a name="udp">{% trans %}UDP connections{% endtrans %}</a></h3>
|
||||
<p>{% trans -%}
|
||||
SSU (the UDP transport) encrypts each packet with AES256/CBC with both an explicit IV and MAC
|
||||
(HMAC-MD5-128) after agreeing upon an ephemeral session key through a 2048 bit
|
||||
Diffie-Hellman exchange, station-to-station authentication with the other
|
||||
router's DSA key, plus each network message has their own hash for local integrity
|
||||
checking.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans ssu=site_url('docs/transport/ssu') -%}
|
||||
See <a href="{{ ssu }}#keys">the SSU specification</a> for details.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans statusnotes=get_url('blog_post', slug='2005/07/05/status') -%}
|
||||
WARNING - I2P's HMAC-MD5-128 used in SSU is apparently non-standard.
|
||||
Apparently, an early version of SSU used HMAC-SHA256, and then it was switched
|
||||
to MD5-128 for performance reasons, but left the 32-byte buffer size intact.
|
||||
See HMACGenerator.java and
|
||||
<a href="{{ statusnotes }}">the 2005-07-05 status notes</a>
|
||||
for details.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
|
||||
<h2>{% trans %}References{% endtrans %}</h2>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="http://csrc.nist.gov/publications/nistpubs/800-57/sp800-57-Part1-revised2_Mar08-2007.pdf">NIST 800-57</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
{% endblock %}
|
@@ -39,13 +39,13 @@ If you find any inaccuracies in the documents linked below, please
|
||||
<li><a href="{{ site_url('get-involved/develop/applications') }}">Application Development Overview and Guide</a></li>
|
||||
<li><a href="{{ site_url('docs/naming') }}">{{ _('Naming and Addressbook') }}</a></li>
|
||||
<li><a href="{{ site_url('docs/plugins') }}">{{ _('Plugins Overview') }}</a></li>
|
||||
<li><a href="{{ site_url('docs/spec/plugin') }}">{{ _('Plugin Specification') }}</a></li>
|
||||
<li><a href="{{ spec_url('plugin') }}">{{ _('Plugin Specification') }}</a></li>
|
||||
<li><a href="{{ site_url('docs/applications/managed-clients') }}">{{ _('Managed Clients') }}</a></li>
|
||||
<li><a href="{{ site_url('docs/applications/embedding') }}">{{ _('Embedding the router in your application') }}</a></li>
|
||||
<li><a href="{{ site_url('docs/applications/bittorrent') }}">{{ _('Bittorrent over I2P') }}</a></li>
|
||||
<li><a href="{{ site_url('docs/api/i2pcontrol') }}">{{ _('I2PControl Plugin API') }}</a></li>
|
||||
<li><a href="{{ site_url('docs/spec/blockfile') }}">{{ _('hostsdb.blockfile Format') }}</a></li>
|
||||
<li><a href="{{ site_url('docs/spec/configuration') }}">{{ _('Configuration File Format') }}</a></li>
|
||||
<li><a href="{{ spec_url('blockfile') }}">{{ _('hostsdb.blockfile Format') }}</a></li>
|
||||
<li><a href="{{ spec_url('configuration') }}">{{ _('Configuration File Format') }}</a></li>
|
||||
</ul>
|
||||
|
||||
<h3>{% trans %}Application Layer API and Protocols{% endtrans %}</h3>
|
||||
@@ -55,7 +55,7 @@ If you find any inaccuracies in the documents linked below, please
|
||||
</li><li>
|
||||
<a href="{{ site_url('docs/api/i2ptunnel') }}">I2PTunnel</a>
|
||||
</li><li>
|
||||
<a href="{{ site_url('docs/spec/configuration') }}">{{ _('I2PTunnel Configuration') }}</a></li>
|
||||
<a href="{{ spec_url('configuration') }}">{{ _('I2PTunnel Configuration') }}</a></li>
|
||||
</li><li>
|
||||
<a href="{{ site_url('docs/api/socks') }}">SOCKS Proxy</a>
|
||||
</li><li>
|
||||
@@ -85,11 +85,11 @@ HTTP Bidir Proxy
|
||||
<ul><li>
|
||||
<a href="{{ site_url('docs/api/streaming') }}">{{ _('Streaming Library') }}</a>
|
||||
</li><li>
|
||||
<a href="{{ site_url('docs/spec/streaming') }}">{{ _('Streaming Protocol Specification') }}</a>
|
||||
<a href="{{ spec_url('streaming') }}">{{ _('Streaming Protocol Specification') }}</a>
|
||||
</li><li>
|
||||
<a href="http://{{ i2pconv('i2p-javadocs.i2p') }}/net/i2p/client/streaming/package-summary.html">{{ _('Streaming Javadoc') }}</a>
|
||||
</li><li>
|
||||
<a href="{{ site_url('docs/spec/datagrams') }}">{{ _('Datagrams') }}</a>
|
||||
<a href="{{ spec_url('datagrams') }}">{{ _('Datagrams') }}</a>
|
||||
</li><li>
|
||||
<a href="http://{{ i2pconv('i2p-javadocs.i2p') }}/net/i2p/client/datagram/package-summary.html">{{ _('Datagram Javadoc') }}</a>
|
||||
</li></ul>
|
||||
@@ -102,11 +102,11 @@ Traditionally used only by Java applications and higher-level APIs.
|
||||
<ul><li>
|
||||
<a href="{{ site_url('docs/protocol/i2cp') }}">{{ _('I2CP - I2P Control Protocol / API overview') }}</a>
|
||||
</li><li>
|
||||
<a href="{{ site_url('docs/spec/i2cp') }}">{{ _('I2CP Specification') }}</a>
|
||||
<a href="{{ spec_url('i2cp') }}">{{ _('I2CP Specification') }}</a>
|
||||
</li><li>
|
||||
<a href="http://{{ i2pconv('i2p-javadocs.i2p') }}/net/i2p/client/package-summary.html">{{ _('I2CP API Javadoc') }}</a>
|
||||
</li><li>
|
||||
<a href="{{ site_url('docs/spec/common-structures') }}">{{ _('Common data structures specification') }}</a>
|
||||
<a href="{{ spec_url('common-structures') }}">{{ _('Common data structures specification') }}</a>
|
||||
</li><li>
|
||||
<a href="http://{{ i2pconv('i2p-javadocs.i2p') }}/net/i2p/data/package-summary.html">{{ _('Data Structures Javadoc') }}</a>
|
||||
</li></ul>
|
||||
@@ -124,7 +124,7 @@ Traditionally used only by Java applications and higher-level APIs.
|
||||
<li><a href="{{ site_url('docs/how/network-database') }}">{{ _('Network database overview, details, and threat analysis') }}</a></li>
|
||||
<li><a href="{{ site_url('docs/how/cryptography') }}#SHA256">{{ _('Cryptographic hashes') }}</a></li>
|
||||
<li><a href="{{ site_url('docs/how/cryptography') }}#sig">{{ _('Cryptographic signatures') }}</a></li>
|
||||
<li><a href="{{ site_url('docs/spec/updates') }}">{{ _('Router reseed specification') }}</a></li>
|
||||
<li><a href="{{ spec_url('updates') }}">{{ _('Router reseed specification') }}</a></li>
|
||||
</ul>
|
||||
|
||||
<h3>{% trans %}Router Message Protocol{% endtrans %}</h3>
|
||||
@@ -132,11 +132,11 @@ Traditionally used only by Java applications and higher-level APIs.
|
||||
<ul><li>
|
||||
<a href="{{ site_url('docs/protocol/i2np') }}">{{ _('I2NP - I2P Network Protocol Overview') }}</a>
|
||||
</li><li>
|
||||
<a href="{{ site_url('docs/spec/i2np') }}">{{ _('I2NP Specification') }}</a>
|
||||
<a href="{{ spec_url('i2np') }}">{{ _('I2NP Specification') }}</a>
|
||||
</li><li>
|
||||
<a href="http://{{ i2pconv('i2p-javadocs.i2p') }}/net/i2p/data/i2np/package-summary.html">{{ _('I2NP Javadoc') }}</a>
|
||||
</li><li>
|
||||
<a href="{{ site_url('docs/spec/common-structures') }}">{{ _('Common data structures specification') }}</a>
|
||||
<a href="{{ spec_url('common-structures') }}">{{ _('Common data structures specification') }}</a>
|
||||
</li><li>
|
||||
<a href="http://{{ i2pconv('i2p-javadocs.i2p') }}/net/i2p/data/package-summary.html">{{ _('Data Structures Javadoc') }}</a>
|
||||
</li></ul>
|
||||
@@ -150,8 +150,8 @@ Traditionally used only by Java applications and higher-level APIs.
|
||||
<li><a href="{{ site_url('docs/tunnels/implementation') }}">{{ _('Tunnel building and encryption') }}</a></li>
|
||||
<li><a href="{{ site_url('docs/how/elgamal-aes') }}">{{ _('ElGamal/AES') }}</a> {{ _('for build request encryption') }}</li>
|
||||
<li><a href="{{ site_url('docs/how/cryptography') }}">{{ _('ElGamal and AES cryptography details') }}</a></li>
|
||||
<li><a href="{{ site_url('docs/spec/tunnel-creation') }}">{{ _('Tunnel building specification') }}</a></li>
|
||||
<li><a href="{{ site_url('docs/spec/tunnel-message') }}">{{ _('Low-level tunnel message specification') }}</a></li>
|
||||
<li><a href="{{ spec_url('tunnel-creation') }}">{{ _('Tunnel building specification') }}</a></li>
|
||||
<li><a href="{{ spec_url('tunnel-message') }}">{{ _('Low-level tunnel message specification') }}</a></li>
|
||||
<li><a href="{{ site_url('docs/tunnels/unidirectional') }}">{{ _('Unidirectional Tunnels') }}</a></li>
|
||||
<li><a href="{{ url_for('static', filename='pdf/I2P-PET-CON-2009.1.pdf') }}">{{ _('Peer Profiling and Selection in the I2P Anonymous Network') }}</a>
|
||||
{{ _('2009 paper (pdf), not current but still generally accurate') }}</li>
|
||||
@@ -166,7 +166,7 @@ Traditionally used only by Java applications and higher-level APIs.
|
||||
</li><li>
|
||||
<a href="{{ site_url('docs/transport/ssu') }}">SSU</a> {{ _('UDP-based transport overview') }}
|
||||
</li><li>
|
||||
<a href="{{ site_url('docs/spec/ssu') }}">{{ _('SSU specification') }}</a>
|
||||
<a href="{{ spec_url('ssu') }}">{{ _('SSU specification') }}</a>
|
||||
</li><li>
|
||||
<a href="{{ site_url('docs/how/cryptography') }}#tcp">{{ _('NTCP transport encryption') }}</a>
|
||||
</li><li>
|
||||
@@ -181,9 +181,9 @@ Traditionally used only by Java applications and higher-level APIs.
|
||||
|
||||
<h3>{% trans %}Other Router Topics{% endtrans %}</h3>
|
||||
<ul><li>
|
||||
<a href="{{ site_url('docs/spec/updates') }}">{{ _('Router software updates') }}</a>
|
||||
<a href="{{ spec_url('updates') }}">{{ _('Router software updates') }}</a>
|
||||
</li><li>
|
||||
<a href="{{ site_url('docs/spec/updates') }}">{{ _('Router reseed specification') }}</a>
|
||||
<a href="{{ spec_url('updates') }}">{{ _('Router reseed specification') }}</a>
|
||||
</li><li>
|
||||
<a href="{{ site_url('misc/jbigi') }}">{{ _('Native BigInteger Library') }}</a>
|
||||
</li><li>
|
||||
@@ -191,9 +191,9 @@ Traditionally used only by Java applications and higher-level APIs.
|
||||
</li><li>
|
||||
<a href="{{ site_url('about/performance') }}">{{ _('Performance') }}</a>
|
||||
</li><li>
|
||||
<a href="{{ site_url('docs/spec/configuration') }}">{{ _('Configuration File Format') }}</a></li>
|
||||
<a href="{{ spec_url('configuration') }}">{{ _('Configuration File Format') }}</a></li>
|
||||
</li><li>
|
||||
<a href="{{ site_url('docs/spec/geoip') }}">GeoIP File Format</a></li>
|
||||
<a href="{{ spec_url('geoip') }}">GeoIP File Format</a></li>
|
||||
</li></ul>
|
||||
|
||||
<h3>{% trans %}Developer's Guides and Resources{% endtrans %}</h3>
|
||||
|
@@ -1,230 +0,0 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %}{% trans %}Blockfile and Hosts Database Specification{% endtrans %}{% endblock %}
|
||||
{% block lastupdated %}{% trans %}November 2014{% endtrans %}{% endblock %}
|
||||
{% block accuratefor %}0.9.17{% endblock %}
|
||||
{% block content %}
|
||||
<h3>{% trans %}Overview{% endtrans %}</h3>
|
||||
<p>{% trans naming=site_url('docs/naming') -%}
|
||||
This document specifies
|
||||
the I2P blockfile file format
|
||||
and the tables in the hostsdb.blockfile used by the Blockfile <a href="{{ naming }}">Naming Service</a>.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans -%}
|
||||
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.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans url='http://www.metanotion.net/software/sandbox/block.html' -%}
|
||||
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="{{ url }}">Metanotion Blockfile Database</a>.
|
||||
First we will define the file format, then the use of that format by the BlockfileNamingService.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h3>{% trans %}Blockfile Format{% endtrans %}</h3>
|
||||
<p>{% trans -%}
|
||||
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.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans -%}
|
||||
All 2-byte integer values are unsigned.
|
||||
All 4-byte integer values (page numbers) are signed and negative values are illegal.
|
||||
All integer values are stored in network byte order (big endian).
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans -%}
|
||||
The database is designed to be opened and accessed by a single thread.
|
||||
The BlockfileNamingService provides synchronization.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans -%}
|
||||
Superblock format:
|
||||
{%- endtrans %}</p>
|
||||
{% highlight %}
|
||||
Byte Contents
|
||||
0-5 Magic number 0x3141de493250 ("1A" 0xde "I2P")
|
||||
6 Major version 0x01
|
||||
7 Minor version 0x02
|
||||
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)
|
||||
Used for new skip lists.
|
||||
24-27 Page size As of version 1.2. Prior to 1.2, 1024 is assumed.
|
||||
28-1023 unused
|
||||
{% endhighlight %}
|
||||
|
||||
<p>{% trans -%}
|
||||
Skip list block page format:
|
||||
{%- endtrans %}</p>
|
||||
{% highlight %}
|
||||
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-29 Span size - As of version 1.2. Max number of key/value pairs per span.
|
||||
Prior to that, specified for all skiplists in the superblock.
|
||||
Used for new spans in this skip list.
|
||||
30-1023 unused
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
<p>{% trans -%}
|
||||
Skip level block page format is as follows.
|
||||
All levels have a span. Not all spans have levels.
|
||||
{%- endtrans %}</p>
|
||||
{% highlight %}
|
||||
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
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
<p>{% trans -%}
|
||||
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.
|
||||
{%- endtrans %}</p>
|
||||
{% highlight %}
|
||||
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
|
||||
{% endhighlight %}
|
||||
|
||||
<p>{% trans -%}
|
||||
Span Continuation block page format:
|
||||
{%- endtrans %}</p>
|
||||
{% highlight %}
|
||||
Byte Contents
|
||||
0-3 Magic number 0x434f4e54 "CONT"
|
||||
4-7 Next continuation page or 0
|
||||
8-1023 key/value structures
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
<p>{% trans -%}
|
||||
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.
|
||||
{%- endtrans %}</p>
|
||||
{% highlight %}
|
||||
Byte Contents
|
||||
0-1 key length in bytes
|
||||
2-3 value length in bytes
|
||||
4- key data
|
||||
value data
|
||||
{% endhighlight %}
|
||||
|
||||
<p>{% trans -%}
|
||||
Free list block page format:
|
||||
{%- endtrans %}</p>
|
||||
{% highlight %}
|
||||
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
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
<p>{% trans -%}
|
||||
Free page block format:
|
||||
{%- endtrans %}</p>
|
||||
{% highlight %}
|
||||
Byte Contents
|
||||
0-7 Magic number 0x7e2146524545217e "~!FREE!~"
|
||||
8-1023 unused
|
||||
{% endhighlight %}
|
||||
|
||||
<p>{% trans -%}
|
||||
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.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h3>{% trans %}Blockfile Naming Service Tables{% endtrans %}</h3>
|
||||
<p>{% trans -%}
|
||||
The tables created and used by the BlockfileNamingService are as follows.
|
||||
The maximum number of entries per span is 16.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h4>{% trans %}Properties Skiplist{% endtrans %}</h4>
|
||||
<p>{% trans INFO='"%%__INFO__%%"' -%}
|
||||
{{ INFO }} is the master database skiplist with String/Properties key/value entries containing only one entry:
|
||||
{%- endtrans %}</p>
|
||||
<pre>
|
||||
"info": a Properties (UTF-8 String/String Map), serialized as a <a href="{{ site_url('docs/spec/common-structures') }}#type_Mapping">Mapping</a>:
|
||||
"version": "3"
|
||||
"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>{% trans %}Reverse Lookup Skiplist{% endtrans %}</h4>
|
||||
<p>{% trans REVERSE='"%%__REVERSE__%%"' -%}
|
||||
{{ REVERSE }} is the reverse lookup skiplist with Integer/Properties key/value entries
|
||||
(as of database version 2):
|
||||
{%- endtrans %}</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/spec/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>{% trans %}hosts.txt, userhosts.txt, and privatehosts.txt Skiplists{% endtrans %}</h4>
|
||||
<p>{% trans -%}
|
||||
For each host database, there is a skiplist containing
|
||||
the hosts for that database.
|
||||
The keys/values in these skiplists are as follows:
|
||||
{%- endtrans %}</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/spec/common-structures') }}#type_Mapping">Mapping</a>
|
||||
followed by a binary Destination (serialized <a href="{{ site_url('docs/spec/common-structures') }}#struct_Destination">as usual</a>).
|
||||
</pre>
|
||||
|
||||
<p>{% trans -%}
|
||||
The DestEntry Properties typically contains:
|
||||
{%- endtrans %}</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>{% trans -%}
|
||||
Hostname keys are stored in lower-case and always end in ".i2p".
|
||||
{%- endtrans %}</p>
|
||||
|
||||
|
||||
{% endblock %}
|
File diff suppressed because it is too large
Load Diff
@@ -1,414 +0,0 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %}{% trans %}Configuration File Specification{% endtrans %}{% endblock %}
|
||||
{% block lastupdated %}{% trans %}February 2016{% endtrans %}{% endblock %}
|
||||
{% block accuratefor %}0.9.25{% endblock %}
|
||||
{% block content %}
|
||||
<h2>{% trans %}Overview{% endtrans %}</h2>
|
||||
<p>{% trans -%}
|
||||
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.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
|
||||
<h2>{% trans %}General Format{% endtrans %}</h2>
|
||||
<p>{% trans url='http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Properties.html#load%28java.io.InputStream%29' -%}
|
||||
An I2P configuration file is formatted as specified in
|
||||
<a href="{{ url }}">Java Properties</a>
|
||||
with the following exceptions:
|
||||
{%- endtrans %}</p>
|
||||
<ul>
|
||||
<li>{% trans %}Encoding must be UTF-8{% endtrans %}</li>
|
||||
<li>{% trans %}Does not use or recognize any escapes, including '\', so lines may not be continued{% endtrans %}</li>
|
||||
<li>{% trans %}'#' or ';' starts a comment, but '!' does not{% endtrans %}</li>
|
||||
<li>{% trans %}'#' starts a comment in any position but ';' must be in column 1 to start a comment{% endtrans %}</li>
|
||||
<li>{% trans %}Leading and trailing whitespace is not trimmed on keys{% endtrans %}</li>
|
||||
<li>{% trans %}Leading and trailing whitespace is trimmed on values{% endtrans %}</li>
|
||||
<li>{% trans %}'=' is the only key-termination character (not ':' or whitespace){% endtrans %}</li>
|
||||
<li>{% trans %}Lines without '=' are ignored. As of release 0.9.10, keys with a value of "" are supported.{% endtrans %}</li>
|
||||
<li>{% trans %}As there are no escapes, keys may not contain '#', '=', or '\n', or start with ';'{% endtrans %}</li>
|
||||
<li>{% trans %}As there are no escapes, values may not contain '#' or '\n', or start or end with '\r' or whitespace{% endtrans %}</li>
|
||||
</ul>
|
||||
|
||||
<p>{% trans -%}
|
||||
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.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans url='http://'+i2pconv('i2p-javadocs.i2p')+'/net/i2p/data/DataHelper.html',
|
||||
commonstructures=site_url('docs/spec/common-structures') -%}
|
||||
Reads and writes are implemented in
|
||||
<a href="{{ url }}">DataHelper loadProps() and storeProps()</a>.
|
||||
Note that the file format is significantly different than the
|
||||
serialized format for I2P protocols specified in
|
||||
<a href="{{ commonstructures }}#type_Mapping">Mapping</a>.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h2>{% trans %}Core library and router{% endtrans %}</h2>
|
||||
|
||||
<h3>{% trans %}Clients{% endtrans %} (clients.config)</h3>
|
||||
<p>{% trans -%}
|
||||
Configured via /configclients in the router console.
|
||||
{%- endtrans %}</p>
|
||||
<p>
|
||||
The format is as follows:
|
||||
</p><p>
|
||||
Lines are of the form clientApp.x.prop=val, where x is the app number.
|
||||
App numbers MUST start with 0 and be consecutive.
|
||||
</p><p>
|
||||
Properties are as follows:
|
||||
<pre>
|
||||
main: Full class name. Required. The constructor or main() method in this
|
||||
class will be run, depending on whether the client is managed or unmanaged.
|
||||
See below for details.
|
||||
name: Name to be displayed on console.
|
||||
args: Arguments to the main class, separated by spaces or tabs.
|
||||
Arguments containing spaces or tabs may be quoted with ' or "
|
||||
delay: Seconds before starting, default 120
|
||||
onBoot: {true|false}, default false, forces a delay of 0,
|
||||
overrides delay setting
|
||||
startOnLoad: {true|false} Is the client to be run at all?
|
||||
Default true
|
||||
</pre>
|
||||
</p><p>
|
||||
The following additional properties are used only by plugins:
|
||||
<pre>
|
||||
stopargs: Arguments to stop the client.
|
||||
uninstallargs: Arguments to uninstall the client.
|
||||
classpath: Additional classpath elements for the client,
|
||||
separated by commas.
|
||||
</pre>
|
||||
</p><p>
|
||||
The following substitutions are made in the args, stopargs,
|
||||
uninstallargs, and classpath lines, for plugins only:
|
||||
<pre>
|
||||
$I2P: The base I2P install directory
|
||||
$CONFIG: The user's configuration directory (e.g. ~/.i2p)
|
||||
$PLUGIN: This plugin's directory (e.g. ~/.i2p/plugins/foo)
|
||||
</pre>
|
||||
</p><p>
|
||||
All properties except "main" are optional.
|
||||
Lines starting with "#" are comments.
|
||||
</p><p>
|
||||
If the delay is less than zero, the client is run immediately,
|
||||
in the same thread, so that exceptions may be propagated to the console.
|
||||
In this case, the client should either throw an exception, return quickly,
|
||||
or spawn its own thread.
|
||||
If the delay is greater than or equal to zero, it will be run
|
||||
in a new thread, and exceptions will be logged but not propagated
|
||||
to the console.
|
||||
</p>
|
||||
<p>
|
||||
Clients may be "managed" or "unmanaged".
|
||||
</p>
|
||||
|
||||
|
||||
<h3>{% trans %}Logger{% endtrans %} (logger.config)</h3>
|
||||
<p>{% trans -%}
|
||||
Configured via /configlogging in the router console.
|
||||
{%- endtrans %}</p>
|
||||
<p>
|
||||
{% trans -%}
|
||||
Properties are as follows:
|
||||
{%- endtrans %}
|
||||
<pre>
|
||||
# Default 20
|
||||
logger.consoleBufferSize=n
|
||||
# Default from locale; format as specified by Java SimpleDateFormat
|
||||
logger.dateFormat=HH:mm:ss.SSS
|
||||
# Default ERROR
|
||||
logger.defaultLevel=CRIT|ERROR|WARN|INFO|DEBUG
|
||||
# Default true
|
||||
logger.displayOnScreen=true|false
|
||||
# Default true
|
||||
logger.dropDuplicates=true|false
|
||||
# Default false
|
||||
logger.dropOnOverflow=true|false
|
||||
# As of 0.9.18. Default 29 (seconds)
|
||||
logger.flushInterval=nnn
|
||||
# d = date, c = class, t = thread name, p = priority, m = message
|
||||
logger.format={dctpm}*
|
||||
# Max to buffer before flushing. Default 1024
|
||||
logger.logBufferSize=n
|
||||
# Default logs/log-@.txt; @ replaced with number
|
||||
logger.logFileName=name
|
||||
logger.logFilenameOverride=name
|
||||
# Default 10M
|
||||
logger.logFileSize=nnn[K|M|G]
|
||||
# Highest file number. Default 2
|
||||
logger.logRotationLimit=n
|
||||
# Default CRIT
|
||||
logger.minimumOnScreenLevel=CRIT|ERROR|WARN|INFO|DEBUG
|
||||
logger.record.{class}=CRIT|ERROR|WARN|INFO|DEBUG
|
||||
</pre>
|
||||
</p>
|
||||
|
||||
<h3>{% trans %}Individual Plugin{% endtrans %} (xxx/plugin.config)</h3>
|
||||
<p>{% trans pluginspec=site_url('docs/spec/plugin') -%}
|
||||
See <a href="{{ pluginspec }}">the plugin specification</a>.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h3>{% trans %}Plugins{% endtrans %} (plugins.config)</h3>
|
||||
<p>{% trans -%}
|
||||
Enable/disable for each installed plugin.
|
||||
{%- endtrans %}
|
||||
{% trans -%}
|
||||
Properties are as follows:
|
||||
{%- endtrans %}
|
||||
<pre>
|
||||
plugin.{name}.startOnLoad=true|false
|
||||
</pre>
|
||||
</p>
|
||||
|
||||
<h3>{% trans %}Webapps{% endtrans %} (webapps.config)</h3>
|
||||
<p>{% trans -%}
|
||||
Enable/disable for each installed webapp.
|
||||
{%- endtrans %}
|
||||
{% trans -%}
|
||||
Properties are as follows:
|
||||
{%- endtrans %}
|
||||
<pre>
|
||||
webapps.{name}.classpath=[space- or comma-separated paths]
|
||||
webapps.{name}.startOnLoad=true|false
|
||||
</pre>
|
||||
</p>
|
||||
|
||||
<h3>{% trans %}Router{% endtrans %} (router.config)</h3>
|
||||
<p>{% trans -%}
|
||||
Configured via /configadvanced in the router console.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h2>{% trans %}Applications{% endtrans %}</h2>
|
||||
|
||||
<h3>{% trans %}Addressbook{% endtrans %} (addressbook/config.txt)</h3>
|
||||
<p>{% trans -%}
|
||||
See documentation in SusiDNS.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h3>I2PSnark (i2psnark.config)</h3>
|
||||
<p>{% trans -%}
|
||||
Configured via the application gui.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h3>I2PTunnel (i2ptunnel.config)</h3>
|
||||
<p>{% trans -%}
|
||||
Configured via the /i2ptunnel application in the router console.
|
||||
{%- endtrans %}
|
||||
{% trans -%}
|
||||
Properties are as follows:
|
||||
{%- endtrans %}
|
||||
<pre>
|
||||
# Display description for UI
|
||||
tunnel.N.description=
|
||||
|
||||
# Router IP address or host name. Ignored if in router context.
|
||||
tunnel.N.i2cpHost=127.0.0.1
|
||||
|
||||
# Router I2CP port. Ignored if in router context.
|
||||
tunnel.N.i2cpPort=nnnn
|
||||
|
||||
# For clients only. Local listen IP address or host name.
|
||||
tunnel.N.interface=127.0.0.1
|
||||
|
||||
# For clients only. Local listen port.
|
||||
tunnel.N.listenPort=nnnn
|
||||
|
||||
# Display name for UI
|
||||
tunnel.N.name=
|
||||
|
||||
# Servers only. Default false. Originate connections to local server with a unique IP per-remote-destination.
|
||||
tunnel.N.option.enableUniqueLocal=true|false
|
||||
|
||||
# Servers only. The maximum size of the thread pool, default 65. Ignored for standard servers.
|
||||
tunnel.N.option.i2ptunnel.blockingHandlerCount=nnn
|
||||
|
||||
# HTTP client only. Whether to use allow SSL connections to i2p addresses. Default false.
|
||||
tunnel.N.option.i2ptunnel.httpclient.allowInternalSSL=true|false
|
||||
|
||||
# HTTP client only. Whether to disable address helper links. Default false.
|
||||
tunnel.N.option.i2ptunnel.httpclient.disableAddressHelper=true|false
|
||||
|
||||
# HTTP client only. Comma- or space-separated list of jump server URLs.
|
||||
tunnel.N.option.i2ptunnel.httpclient.jumpServers=http://example.i2p/jump
|
||||
|
||||
# HTTP client only. Whether to pass Accept* headers through. Default false.
|
||||
tunnel.N.option.i2ptunnel.httpclient.sendAccept=true|false
|
||||
|
||||
# HTTP client only. Whether to pass Referer headers through. Default false.
|
||||
tunnel.N.option.i2ptunnel.httpclient.sendReferer=true|false
|
||||
|
||||
# HTTP client only. Whether to pass User-Agent headers through. Default false.
|
||||
tunnel.N.option.i2ptunnel.httpclient.sendUserAgent=true|false
|
||||
|
||||
# HTTP client only. Whether to pass Via headers through. Default false.
|
||||
tunnel.N.option.i2ptunnel.httpclient.sendVia=true|false
|
||||
|
||||
# HTTP client only. Comma- or space-separated list of in-network SSL outproxies.
|
||||
tunnel.N.option.i2ptunnel.httpclient.SSLOutproxies=example.i2p
|
||||
|
||||
# SOCKS client only. Comma- or space-separated list of in-network outproxies for any ports not specified.
|
||||
tunnel.N.option.i2ptunnel.socks.proxy.default=example.i2p
|
||||
|
||||
# SOCKS client only. Comma- or space-separated list of in-network outproxies for port NNNN.
|
||||
tunnel.N.option.i2ptunnel.socks.proxy.NNNN=example.i2p
|
||||
|
||||
# HTTP client only. Whether to use a registered local outproxy plugin. Default true.
|
||||
tunnel.N.option.i2ptunnel.useLocalOutproxy=true|false
|
||||
|
||||
# Servers only. Whether to use a thread pool. Default true. Ignored for standard servers, always false.
|
||||
tunnel.N.option.i2ptunnel.usePool=true|false
|
||||
|
||||
# IRC Server only. Only used if fakeHostname contains a %c.
|
||||
# If unset, cloak with a random value that is persistent for
|
||||
# the life of this tunnel. If set, cloak with the hash of this passphrase.
|
||||
# Use to have consistent mangling across restarts, or for multiple IRC servers cloak consistently to
|
||||
# be able to track users even when they switch servers.
|
||||
# Note: don't quote or put spaces in the passphrase, the i2ptunnel gui can't handle it.
|
||||
tunnel.N.option.ircserver.cloakKey=
|
||||
|
||||
# IRC Server only. Set the fake hostname sent by I2PTunnel,
|
||||
# %f is the full B32 destination hash, %c is the cloaked hash.
|
||||
tunnel.N.option.ircserver.fakeHostname=%f.b32.i2p
|
||||
|
||||
# IRC Server only. Default user.
|
||||
tunnel.N.option.ircserver.method=user|webirc
|
||||
|
||||
# IRC Server only. The password to use for the webirc protocol.
|
||||
# Note: don't quote or put spaces in the passphrase, the i2ptunnel gui can't handle it.
|
||||
tunnel.N.option.ircserver.webircPassword=
|
||||
|
||||
# IRC Server only.
|
||||
tunnel.N.option.ircserver.webircSpoofIP=
|
||||
|
||||
# For clients only. Alias for the the private key in the keystore for the SSL socket.
|
||||
# Will be autogenerated if a new key is created.
|
||||
tunnel.N.option.keyAlias=
|
||||
|
||||
# For clients only. Password for the private key for the SSL socket.
|
||||
# Will be autogenerated if a new key is created.
|
||||
tunnel.N.option.keyPassword=
|
||||
|
||||
# For clients only. Path to the keystore file containing the private key for the SSL socket.
|
||||
# Will be autogenerated if a new keystore is created.
|
||||
# Relative to $(I2P_CONFIG_DIR)/keystore/ if not absolute.
|
||||
tunnel.N.option.keystoreFile=i2ptunnel-(random string).ks
|
||||
|
||||
# For clients only. Password for the keystore containing the private key for the SSL socket.
|
||||
# Default is "changeit"
|
||||
tunnel.N.option.keystorePassword=changeit
|
||||
|
||||
# HTTP Server only. Max number of POSTs allowed for one destination per postCheckTime. Default 0 (unlimited)
|
||||
tunnel.N.option.maxPosts=nnn
|
||||
|
||||
# HTTP Server only. Max number of POSTs allowed for all destinations per postCheckTime. Default 0 (unlimited)
|
||||
tunnel.N.option.maxTotalPosts=nnn
|
||||
|
||||
# HTTP Clients only. Whether to send authorization to an outproxy. Default false.
|
||||
tunnel.N.option.outproxyAuth=true|false
|
||||
|
||||
# HTTP Clients only. The password for the outproxy authorization.
|
||||
tunnel.N.option.outproxyPassword=
|
||||
|
||||
# HTTP Clients only. The username for the outproxy authorization.
|
||||
tunnel.N.option.outproxyUsername=
|
||||
|
||||
# HTTP Clients only. Whether to send authorization to an outproxy. Default false.
|
||||
tunnel.N.option.outproxyAuth=true|false
|
||||
|
||||
# Clients only. Whether to store a destination in a private key file and reuse it. Default false.
|
||||
tunnel.N.option.persistentClientKey=true|false
|
||||
|
||||
# HTTP Server only. Time period for banning POSTs from a single destination after maxPosts is exceeded, in seconds. Default 1800 seconds.
|
||||
tunnel.N.option.postBanTime=nnn
|
||||
|
||||
# HTTP Server only. Time period for checking maxPosts and maxTotalPosts, in seconds. Default 300 seconds.
|
||||
tunnel.N.option.postCheckTime=nnn
|
||||
|
||||
# HTTP Server only. Time period for banning all POSTs after maxTotalPosts is exceeded, in seconds. Default 600 seconds.
|
||||
tunnel.N.option.postTotalBanTime=nnn
|
||||
|
||||
# HTTP Clients only. Whether to require local authorization for the proxy. Default false. "true" is the same as "basic".
|
||||
tunnel.N.option.proxyAuth=true|false|basic|digest
|
||||
|
||||
# HTTP Clients only. The MD5 of the password for local authorization for user USER.
|
||||
tunnel.N.option.proxy.auth.USER.md5=
|
||||
|
||||
# HTTP Servers only. Whether to reject incoming connections apparently via an inproxy. Default false.
|
||||
tunnel.N.option.rejectInproxy=true|false
|
||||
|
||||
# HTTP Servers only. Whether to reject incoming connections containing a referer header. Default false. Since 0.9.25.
|
||||
tunnel.N.option.rejectReferer=true|false
|
||||
|
||||
# HTTP Servers only. Whether to reject incoming connections containing specific user-agent headers. Default false. Since 0.9.25.
|
||||
# See tunnel.N.option.userAgentRejectList
|
||||
tunnel.N.option.rejectUserAgents=true|false
|
||||
|
||||
# Servers only. Overrides targetHost and targetPort for incoming port NNNN.
|
||||
tunnel.N.option.targetForPort.NNNN=hostnameOrIP:nnnn
|
||||
|
||||
# HTTP Servers only. Comma-separated list of strings to match in the user-agent header. Since 0.9.25.
|
||||
# Example: "Mozilla,Opera". Case-sensitive. See tunnel.N.option.rejectuserAgents
|
||||
tunnel.N.option.userAgentRejectList=string1[,string2]*
|
||||
|
||||
# Default false. For servers, use SSL for connections to local server.
|
||||
# For clients, SSL is required for connections from local clients.
|
||||
tunnel.N.option.useSSL=false
|
||||
|
||||
# Each option is passed to I2CP and streaming with "tunnel.N.option." stripped off. See those docs.
|
||||
tunnel.N.option.*=
|
||||
|
||||
# For servers and clients with persistent keys only. Absolute path or relative to config directory.
|
||||
tunnel.N.privKeyFile=filename
|
||||
|
||||
# For proxies only. Comma- or space-separated host names.
|
||||
tunnel.N.proxyList=example.i2p[,example2.i2p]
|
||||
|
||||
# For clients only. Default false.
|
||||
tunnel.N.sharedClient=true|false
|
||||
|
||||
# For HTTP servers only. Host name to be passed to the local server in the HTTP headers.
|
||||
# Default is the base 32 hostname.
|
||||
tunnel.N.spoofedHost=example.i2p
|
||||
|
||||
# For HTTP servers only. Host name to be passed to the local server in the HTTP headers.
|
||||
# Overrides above setting for incoming port NNNN, to allow virtual hosts.
|
||||
tunnel.N.spoofedHost.NNNN=example.i2p
|
||||
|
||||
# Default true
|
||||
tunnel.N.startOnLoad=true|false
|
||||
|
||||
# For clients only. Comma- or space-separated host names or host:port.
|
||||
tunnel.N.targetDestination=example.i2p[:nnnn][,example2.i2p[:nnnn]]
|
||||
|
||||
# For servers only. Local IP address or host name to connect to.
|
||||
tunnel.N.targetHost=
|
||||
|
||||
# For servers only. Port on targetHost to connect to.
|
||||
tunnel.N.targetPort=nnnn
|
||||
|
||||
# The type of i2ptunnel
|
||||
tunnel.N.type=client|connectclient|httpbidirserver|httpclient|httpserver|ircclient|ircserver|
|
||||
server|socksirctunnel|sockstunnel|streamrclient|streamrserver
|
||||
|
||||
</pre>
|
||||
Note: Each 'N' is a tunnel number starting with 0.
|
||||
There may not be any gaps in numbering.
|
||||
</p>
|
||||
|
||||
<h3>{% trans %}Router Console{% endtrans %}</h3>
|
||||
<p>{% trans -%}
|
||||
The router console uses the router.config file.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h3>SusiMail (susimail.config)</h3>
|
||||
<p>{% trans -%}
|
||||
See post on zzz.i2p.
|
||||
{%- endtrans %}</p>
|
||||
<!--
|
||||
<h3>Systray (systray.config)</h3>
|
||||
<p>
|
||||
TBD
|
||||
</p>
|
||||
-->
|
||||
{% endblock %}
|
@@ -1,109 +0,0 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %}{% trans %}Datagram Specification{% endtrans %}{% endblock %}
|
||||
{% block lastupdated %}{% trans %}July 2014{% endtrans %}{% endblock %}
|
||||
{% block accuratefor %}0.9.14{% endblock %}
|
||||
{% block content %}
|
||||
<p><a href="{{ site_url('docs/api/datagrams') }}">{% trans -%}
|
||||
See the Datagrams page for an overview of the Datagrams API.
|
||||
{%- endtrans %}</a></p>
|
||||
|
||||
<h2 id="spec">{% trans %}Specification{% endtrans %}</h2>
|
||||
|
||||
<h3 id="raw">{% trans %}Non-Repliable Datagrams{% endtrans %}</h3>
|
||||
<p>{% trans -%}
|
||||
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".
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h4>{% trans %}Format{% endtrans %}</h4>
|
||||
{% highlight lang='dataspec' %}
|
||||
+----+----+----+----+----//
|
||||
| payload...
|
||||
+----+----+----+----+----//
|
||||
|
||||
length: 0 - unlimited (see notes)
|
||||
{% endhighlight %}
|
||||
|
||||
<h4>{% trans %}Notes{% endtrans %}</h4>
|
||||
<p>{% trans tunnelmessage=site_url('docs/spec/tunnel-message'),
|
||||
transports=site_url('docs/transport') -%}
|
||||
The practical length is limited by lower layers of protocols - the
|
||||
<a href="{{ tunnelmessage }}#notes">tunnel message spec</a>
|
||||
limits messages to about 61.2 KB and the
|
||||
<a href="{{ transports }}">transports</a>
|
||||
currently limit messages to about 32 KB, although this may be raised in the future.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h3 id="repliable">{% trans %}Repliable Datagrams{% endtrans %}</h3>
|
||||
<p>{% trans -%}
|
||||
Repliable datagrams contain a 'from' address and a signature. These add at least 427 bytes of overhead.
|
||||
{%- endtrans %}</p>
|
||||
<h4>Format</h4>
|
||||
{% highlight lang='dataspec' %}
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| from |
|
||||
+ +
|
||||
| |
|
||||
~ ~
|
||||
~ ~
|
||||
| |
|
||||
+ +
|
||||
| |
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| signature |
|
||||
+ +
|
||||
| |
|
||||
+ +
|
||||
| |
|
||||
+ +
|
||||
| |
|
||||
+ +
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| payload...
|
||||
+----+----+----+----//
|
||||
|
||||
|
||||
from :: a `Destination`
|
||||
length: 387+ bytes
|
||||
The originator and signer of the datagram
|
||||
|
||||
signature :: a `Signature`
|
||||
Signature type must match the signing public key type of $from
|
||||
length: 40+ bytes, as implied by the Signature type.
|
||||
For the default DSA_SHA1 key type:
|
||||
The DSA `Signature` of the SHA-256 hash of the payload.
|
||||
For other key types:
|
||||
The `Signature` of the payload.
|
||||
The signature may be verified by the signing public key of $from
|
||||
|
||||
payload :: The data
|
||||
Length: 0 to ~31.5 KB (see notes)
|
||||
|
||||
Total length: Payload length + 427+
|
||||
{% endhighlight %}
|
||||
|
||||
<h4>{% trans %}Notes{% endtrans %}</h4>
|
||||
<ul>
|
||||
<li>{% trans transports=site_url('docs/transport') -%}
|
||||
The practical length is limited by lower layers of protocols - the
|
||||
<a href="{{ transports }}">transports</a>
|
||||
currently limit messages to about 32 KB, so the data length here is limited to about
|
||||
31.5 KB.
|
||||
{%- endtrans %}</li>
|
||||
<li>{% trans dgrams=site_url('docs/api/datagrams') -%}
|
||||
See <a href="{{ dgrams }}">important notes</a> about the reliability of large datagrams.
|
||||
For best results, limit the payload to about 10 KB or less.
|
||||
{%- endtrans %}</li>
|
||||
<li>{% trans -%}
|
||||
Signatures for types other than DSA_SHA1 were redefined in release 0.9.14.
|
||||
{%- endtrans %}</li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
{% endblock %}
|
@@ -1,81 +0,0 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %}{% trans %}GeoIP File Specification{% endtrans %}{% endblock %}
|
||||
{% block lastupdated %}{% trans %}December 2013{% endtrans %}{% endblock %}
|
||||
{% block accuratefor %}0.9.9{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
<h2>{% trans %}Overview{% endtrans %}</h2>
|
||||
<p>{% trans -%}
|
||||
This page specifies the format of the various GeoIP files,
|
||||
used by the router to look up a country for an IP.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
|
||||
<h2>{% trans %}Country Name (countries.txt) Format{% endtrans %}</h2>
|
||||
<p>{% trans -%}
|
||||
This format is easily generated from data files available from many public sources.
|
||||
For example:
|
||||
{%- endtrans %}</p>
|
||||
{% highlight lang='bash' %}
|
||||
$ wget http://geolite.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip
|
||||
$ unzip GeoIPCountryCSV.zip
|
||||
$ cut -d, -f5,6 < GeoIPCountryWhois.csv |sed 's/"//g' | sort | uniq > countries.txt
|
||||
{% endhighlight %}
|
||||
<ul>
|
||||
<li>Encoding is UTF-8
|
||||
<li>'#' in column 1 specifies a comment line
|
||||
<li>Entry lines are CountryCode,CountryName
|
||||
<li>CountryCode is the ISO two-letter code, upper case
|
||||
<li>CountryName is in English
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>{% trans %}IPv4 (geoip.txt) Format{% endtrans %}</h2>
|
||||
<p>{% trans -%}
|
||||
This format is borrowed from Tor and is easily generated from data files available from many public sources.
|
||||
For example:
|
||||
{%- endtrans %}</p>
|
||||
{% highlight lang='bash' %}
|
||||
$ wget http://geolite.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip
|
||||
$ unzip GeoIPCountryCSV.zip
|
||||
$ cut -d, -f3-5 < GeoIPCountryWhois.csv|sed 's/"//g' > geoip.txt
|
||||
$ cut -d, -f5,6 < GeoIPCountryWhois.csv |sed 's/"//g' | sort | uniq > countries.txt
|
||||
{% endhighlight %}
|
||||
<ul>
|
||||
<li>Encoding is ASCII
|
||||
<li>'#' in column 1 specifies a comment line
|
||||
<li>Entry lines are FromIP,ToIP,CountryCode
|
||||
<li>FromIP and ToIP are unsigned integer representations of the 4-byte IP
|
||||
<li>CountryCode is the ISO two-letter code, upper case
|
||||
<li>Entry lines must be sorted by numeric FromIP
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>{% trans %}IPv6 (geoipv6.dat.gz) Format{% endtrans %}</h2>
|
||||
<p>{% trans -%}
|
||||
This is a compressed binary format designed for I2P.
|
||||
The file is gzipped. Ungzipped format:
|
||||
{%- endtrans %}</p>
|
||||
{% highlight %}
|
||||
Bytes 0-9: Magic number "I2PGeoIPv6"
|
||||
Bytes 10-11: Version (0x0001)
|
||||
Bytes 12-15 Options (0x00000000) (future use)
|
||||
Bytes 16-23: Creation date (ms since 1970-01-01)
|
||||
Bytes 24-xx: Optional comment (UTF-8) terminated by zero byte
|
||||
Bytes xx-255: null padding
|
||||
Bytes 256-: 18 byte records:
|
||||
8 byte from (/64)
|
||||
8 byte to (/64)
|
||||
2 byte ISO country code LOWER case (ASCII)
|
||||
{% endhighlight %}
|
||||
<p>{% trans %}NOTES:{% endtrans %}</p>
|
||||
<ul>
|
||||
<li>Data must be sorted (SIGNED long twos complement), no overlap.
|
||||
So the order is 80000000 ... FFFFFFFF 00000000 ... 7FFFFFFF.
|
||||
<li>
|
||||
The GeoIPv6.java class contains a program to generate this format from
|
||||
public sources such as the Maxmind GeoLite data.
|
||||
<li>
|
||||
IPv6 GeoIP lookup is supported as of release 0.9.8.
|
||||
</ul>
|
||||
{% endblock %}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,607 +0,0 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %}I2P Plugin Specification{% endblock %}
|
||||
{% block lastupdated %}February 2016{% endblock %}
|
||||
{% block accuratefor %}0.9.25{% endblock %}
|
||||
{% block content %}
|
||||
<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>
|
||||
As of release 0.9.15, the <a href="updates">su3 file format</a> is supported and is preferred.
|
||||
This format enables stronger signing keys.
|
||||
|
||||
|
||||
<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 <a href="{{ site_url('docs/spec/updates') }}">signed update (sud) file</a> containing the following:
|
||||
<h4>
|
||||
Standard .sud header prepended to the zip file, containing the following:
|
||||
</h4>
|
||||
<pre>
|
||||
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
|
||||
</pre>
|
||||
<h4>
|
||||
Zip file containing the following:
|
||||
</h4>
|
||||
<h5>
|
||||
plugin.config file
|
||||
</h5>
|
||||
<p>
|
||||
This file is required. It is a
|
||||
<a href="{{ site_url('docs/spec/configuration') }}">standard I2P configuration file</a>,
|
||||
containing the following properties:
|
||||
</p>
|
||||
</p><p>
|
||||
The following four are required properties.
|
||||
The first three must be identical to those in the installed plugin for an update plugin.
|
||||
<pre>
|
||||
|
||||
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 '=')
|
||||
Omit for SU3 format.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
</pre>
|
||||
Values for the following properties are displayed on /configclients in the router console if present:
|
||||
<pre>
|
||||
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)
|
||||
updateURL.su3 (http://foo.i2p/foo.su3)
|
||||
The location of the su3-format update file, as of 0.9.15
|
||||
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.
|
||||
|
||||
</pre>
|
||||
The following properties are used to add a link on the console summary bar:
|
||||
<pre>
|
||||
|
||||
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)
|
||||
|
||||
|
||||
</pre>
|
||||
The following optional properties may be used to add a custom icon on the console:
|
||||
<pre>
|
||||
|
||||
console-icon (supported as of 0.9.20) Only for webapps.
|
||||
A path within the webapp to a 32x32 image, e.g. /icon.png
|
||||
Applies to all webapps in the plugin.
|
||||
|
||||
icon-code (supported as of 0.9.25)
|
||||
Provides a console icon for plugins without web resources.
|
||||
A B64 string produced by calling 'net.i2p.data.Base64 encode FILE'
|
||||
on a 32x32 image png file.
|
||||
|
||||
</pre>
|
||||
The following properties are used by the plugin installer:
|
||||
<pre>
|
||||
|
||||
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,
|
||||
configures the plugin 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)
|
||||
|
||||
</pre>
|
||||
The following property is used for translation plugins:
|
||||
<pre>
|
||||
langs=xx,yy,Klingon,... (unimplemented) (yy is the country flag)
|
||||
|
||||
</pre>
|
||||
<h5>
|
||||
Application Directories and Files
|
||||
</h5>
|
||||
<p>
|
||||
Each of the following directories or files is optional, but something must be there or it won't do anything:
|
||||
</p>
|
||||
<pre>
|
||||
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
|
||||
</pre>
|
||||
<h5>
|
||||
clients.config file
|
||||
</h5>
|
||||
<p>
|
||||
This file is optional,
|
||||
and specifies clients that will be run when a plugin is started.
|
||||
It uses the same format as the router's clients.config file.
|
||||
See the <a href="{{ site_url('docs/spec/configuration') }}">clients.config configuration file specification</a>
|
||||
for more information about the format and important details
|
||||
about how clients are started and stopped.
|
||||
</p>
|
||||
<pre>
|
||||
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 unmanaged 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.
|
||||
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
|
||||
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.
|
||||
As of release 0.9.14.1,
|
||||
if there is no matching key, the installation fails, unless an advanced router property is set to allow all keys.</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 (somewhat 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://{{ i2pconv('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>
|
||||
As of release 0.9.4, the router supports "managed" plugin clients.
|
||||
Managed plugin clients are instantiated and started by the <code>ClientAppManager</code>.
|
||||
The ClientAppManager maintains a reference to the client and receives updates on the client's state.
|
||||
Managed plugin client are preferred, as it is much easier to implement state tracking
|
||||
and to start and stop a client. It also is much easier to avoid static references in the client code
|
||||
which could lead to excessive memory usage after a client is stopped.
|
||||
See the <a href="{{ site_url('docs/spec/configuration') }}">clients.config configuration file specification</a>
|
||||
for more information on writing a managed client.
|
||||
</p><p>
|
||||
For "unmanaged" plugin clients,
|
||||
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://{{ i2pconv('zzz.i2p') }}/topics/141">{{ i2pconv('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://{{ i2pconv('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.
|
||||
<li>
|
||||
The router sets the JVM time zone to UTC. If a plugin needs to know the user's actual time zone,
|
||||
it is stored by the router in the I2PAppContext property "i2p.systemTimeZone".
|
||||
</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:
|
||||
<table>
|
||||
<tr><th>Jar<th>Contains<th>Usage
|
||||
<tr><td>commons-logging.jar
|
||||
<td>Apache Logging<td>For plugins requiring Apache logging.
|
||||
Prior to Jetty 6 (release 0.9),
|
||||
this contained Apache Commons Logging only.
|
||||
From release 0.9 to release 0.9.23,
|
||||
this contained both Commons Logging and Tomcat JULI.
|
||||
As of release 0.9.24.
|
||||
this contains Apache Tomcat JULI logging only.
|
||||
|
||||
<tr><td>commons-el.jar
|
||||
<td>JSP Expression Language<td>For plugins with JSPs that use EL
|
||||
|
||||
<tr><td>i2p.jar
|
||||
<td>Core API<td>Almost all plugins will need
|
||||
|
||||
<tr><td>i2ptunnel.jar
|
||||
<td>I2PTunnel<td>For plugins with HTTP or other servers
|
||||
|
||||
<tr><td>jasper-compiler.jar
|
||||
<td>nothing<td>Empty since Jetty 6 (release 0.9)
|
||||
|
||||
<tr><td>jasper-runtime.jar
|
||||
<td>Jasper Complier and Runtime, and some Tomcat utils<td>Needed for plugins with JSPs
|
||||
|
||||
<tr><td>javax.servlet.jar
|
||||
<td>Servlet API<td>Needed for plugins with JSPs
|
||||
|
||||
<tr><td>jbigi.jar
|
||||
<td>Binaries<td>No plugin should need
|
||||
|
||||
<tr><td>mstreaming.jar
|
||||
<td>Streaming API<td>Almost all plugins will need
|
||||
|
||||
<tr><td>org.mortbay.jetty.jar
|
||||
<td>Jetty Base<td>Only plugins starting their own Jetty instance will need.
|
||||
Recommended way of starting Jetty is with net.i2p.jetty.JettyStart in jetty-i2p.jar.
|
||||
|
||||
<tr><td>router.jar
|
||||
<td>Router<td>Only plugins using router context will need; most will not
|
||||
|
||||
<tr><td>sam.jar
|
||||
<td>SAM<td>No plugin should need
|
||||
|
||||
<tr><td>streaming.jar
|
||||
<td>Streaming Implementation<td>Almost all plugins will need
|
||||
|
||||
<tr><td>systray.jar
|
||||
<td>URL Launcher<td>Most plugins should not need
|
||||
|
||||
<tr><td>systray4j.jar
|
||||
<td>Systray<td>No plugin should need
|
||||
|
||||
<tr><td>wrapper.jar
|
||||
<td>Router<td>Most plugins should not need
|
||||
|
||||
</table>
|
||||
|
||||
<p>
|
||||
The following jars in $I2P/lib can be assumed to be present for all I2P installations,
|
||||
no matter how old or how new the original installation,
|
||||
but are not necessarily in the classpath:
|
||||
<p>
|
||||
<table>
|
||||
<tr><th>Jar<th>Contains<th>Usage
|
||||
<tr><td>jstl.jar
|
||||
<td>Standard Taglib<td>For plugins using JSP tags
|
||||
|
||||
<tr><td>standard.jar
|
||||
<td>Standard Taglib<td>For plugins using JSP tags
|
||||
|
||||
</table>
|
||||
|
||||
<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://{{ i2pconv('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>
|
||||
I2P has required Java 7 since release 0.9.24 (January 2016).
|
||||
I2P has required Java 6 since release 0.9.12 (April 2014).
|
||||
Any I2P users on the latest release should be running a 1.7 (7.0) JVM.
|
||||
In early 2016,
|
||||
unless you require 1.7 language or library features, you should create your plugin so it works on 1.6.
|
||||
Later in the year, most of the network will be on 0.9.24 or higher with Java 7.
|
||||
<p>
|
||||
If your plugin <b>does not require 1.7</b>:
|
||||
<ul>
|
||||
<li>
|
||||
Ensure that all java and jsp files are compiled with source="1.6" target="1.6",
|
||||
or source="1.5" target="1.5",
|
||||
<li>
|
||||
Ensure that all bundled library jars are also for 1.6 or lower.
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
If your plugin <b>requires 1.7</b>:
|
||||
<ul>
|
||||
<li>
|
||||
Note that on your download page.
|
||||
<li>
|
||||
Add min-java-version=1.7 to your plugin.config
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
In any case, you <b>must</b> set a bootclasspath when compiling with Java 8
|
||||
to prevent runtime crashes.
|
||||
</p>
|
||||
|
||||
|
||||
<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 %}
|
File diff suppressed because it is too large
Load Diff
@@ -1,169 +0,0 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %}{% trans %}Streaming Library Specification{% endtrans %}{% endblock %}
|
||||
{% block lastupdated %}{% trans %}June 2015{% endtrans %}{% endblock %}
|
||||
{% block accuratefor %}0.9.20{% endblock %}
|
||||
{% block content %}
|
||||
<p><a href="{{ site_url('docs/api/streaming') }}">{% trans -%}
|
||||
See the Streaming page for an overview of the Streaming Library.
|
||||
{%- endtrans %}</a></p>
|
||||
|
||||
<h2>{% trans %}Protocol Specification{% endtrans %}</h2>
|
||||
<h3>{% trans %}Packet Format{% endtrans %}</h3>
|
||||
<p>{% trans -%}
|
||||
The format of a single packet in the streaming protocol is:
|
||||
{%- endtrans %}</p>
|
||||
{% highlight lang='dataspec' %}
|
||||
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| send Stream ID | rcv Stream ID |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| sequence Num | ack Through |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| nc | NACKs ...
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| rd | flags | opt size| opt data
|
||||
+----+----+----+----+----+----+----+----+
|
||||
... |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| payload ...
|
||||
+----+----+----+-//
|
||||
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
<table>
|
||||
<tr><th>{{ _('Field') }}<th>{{ _('Length') }}<th>{{ _('Contents') }}
|
||||
<tr><td>sendStreamId <td>4 byte <a href="{{ site_url('docs/spec/common-structures') }}#type_Integer">Integer</a>
|
||||
<td>Random number selected by the packet recipient before sending the first SYN reply packet
|
||||
and constant for the life of the connection.
|
||||
0 in the SYN message sent by the connection originator, and in subsequent messages, until a SYN reply is received,
|
||||
containing the peer's stream ID.
|
||||
|
||||
<tr><td>receiveStreamId <td>4 byte <a href="{{ site_url('docs/spec/common-structures') }}#type_Integer">Integer</a>
|
||||
<td>Random number selected by the packet originator before sending the first SYN packet
|
||||
and constant for the life of the connection. May be 0 if unknown, for example in a RESET packet.
|
||||
|
||||
<tr><td>sequenceNum <td>4 byte <a href="{{ site_url('docs/spec/common-structures') }}#type_Integer">Integer</a><td>
|
||||
The sequence for this message, starting at 0 in the SYN message,
|
||||
and incremented by 1 in each message except for plain ACKs and retransmissions.
|
||||
If the sequenceNum is 0 and the SYN flag is not set, this is a plain ACK
|
||||
packet that should not be ACKed.
|
||||
|
||||
<tr><td>ackThrough <td>4 byte <a href="{{ site_url('docs/spec/common-structures') }}#type_Integer">Integer</a><td>
|
||||
The highest packet sequence number that was received
|
||||
on the receiveStreamId. This field is ignored on the initial
|
||||
connection packet (where receiveStreamId is the unknown id) or
|
||||
if the NO_ACK flag set.
|
||||
All packets up to and including this sequence number are ACKed,
|
||||
EXCEPT for those listed in NACKs below.
|
||||
|
||||
<tr><td>NACK count<td>1 byte <a href="{{ site_url('docs/spec/common-structures') }}#type_Integer">Integer</a><td>
|
||||
The number of 4-byte NACKs in the next field
|
||||
|
||||
<tr><td>NACKs <td>n * 4 byte <a href="{{ site_url('docs/spec/common-structures') }}#type_Integer">Integers</a><td>
|
||||
Sequence numbers less than ackThrough that are not yet received.
|
||||
Two NACKs of a packet is a request for a 'fast retransmit' of that packet.
|
||||
|
||||
<tr><td>resendDelay<td>1 byte <a href="{{ site_url('docs/spec/common-structures') }}#type_Integer">Integer</a><td>
|
||||
How long is the creator of this packet going to wait before
|
||||
resending this packet (if it hasn't yet been ACKed). The
|
||||
value is seconds since the packet was created.
|
||||
Currently ignored on receive.
|
||||
|
||||
<tr><td>flags <td>2 byte value<td>
|
||||
See below.
|
||||
|
||||
<tr><td>option size<td>2 byte <a href="{{ site_url('docs/spec/common-structures') }}#type_Integer">Integer</a><td>
|
||||
The number of bytes in the next field
|
||||
|
||||
<tr><td>option data<td>0 or more bytes<td>
|
||||
As specified by the flags. See below.
|
||||
|
||||
<tr><td>payload <td>remaining packet size<td>
|
||||
</table>
|
||||
|
||||
<h3>{% trans %}Flags and Option Data Fields{% endtrans %}</h3>
|
||||
<p>{% trans -%}
|
||||
The flags field above specifies some metadata about the packet, and in
|
||||
turn may require certain additional data to be included. The flags are
|
||||
as follows. Any data structures specified must be added to the options area
|
||||
in the given order.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>
|
||||
Bit order: 15....0 (15 is MSB)
|
||||
</p>
|
||||
<table>
|
||||
<tr><th>Bit<th>Flag<th>Option Order<th>Option Data<th>Function
|
||||
<tr><td>0<td>SYNCHRONIZE<td align="center">--<td align="center">--<td>
|
||||
Similar to TCP SYN. Set in the initial packet and in the first response.
|
||||
FROM_INCLUDED and SIGNATURE_INCLUDED must be set also.
|
||||
<tr><td>1<td>CLOSE<td align="center">--<td align="center">--<td>
|
||||
Similar to TCP FIN. If the response to a SYNCHRONIZE fits in a single message, the response
|
||||
will contain both SYNCHRONIZE and CLOSE.
|
||||
SIGNATURE_INCLUDED must be set also.
|
||||
<tr><td>2<td>RESET<td align="center">--<td align="center">--<td>
|
||||
Abnormal close.
|
||||
SIGNATURE_INCLUDED must be set also.
|
||||
Prior to release 0.9.20, due to a bug, FROM_INCLUDED must also be set.
|
||||
<tr><td>3<td>SIGNATURE_INCLUDED<td align="center">4<td>variable length <a href="{{ site_url('docs/spec/common-structures') }}#type_Signature">Signature</a>
|
||||
<td>
|
||||
Currently sent only with SYNCHRONIZE, CLOSE, and RESET, where it is required,
|
||||
and with ECHO, where it is required for a ping.
|
||||
The signature uses the Destination's <a href="{{ site_url('docs/spec/common-structures') }}#type_SigningPublicKey">signing keys</a>
|
||||
to sign the entire header and payload with the space in the option data field
|
||||
for the signature being set to all zeroes.
|
||||
<br>
|
||||
Prior to release 0.9.11, the signature was always 40 bytes.
|
||||
As of release 0.9.11, the signature may be variable-length, see below for details.
|
||||
<tr><td>4<td>SIGNATURE_REQUESTED<td align="center">--<td align="center">--<td>
|
||||
Unused. Requests every packet in the other direction to have SIGNATURE_INCLUDED
|
||||
<tr><td>5<td>FROM_INCLUDED<td align="center">2<td>387+ byte <a href="{{ site_url('docs/spec/common-structures') }}#struct_Destination">Destination</a>
|
||||
<td>
|
||||
Currently sent only with SYNCHRONIZE, where it is required,
|
||||
and with ECHO, where it is required for a ping.
|
||||
Prior to release 0.9.20, due to a bug, must also be sent with RESET.
|
||||
<tr><td>6<td>DELAY_REQUESTED<td align="center">1<td>2 byte <a href="{{ site_url('docs/spec/common-structures') }}#type_Integer">Integer</a><td>
|
||||
Optional delay.
|
||||
How many milliseconds the sender of this packet wants the recipient
|
||||
to wait before sending any more data.
|
||||
A value greater than 60000 indicates choking.
|
||||
<tr><td>7<td>MAX_PACKET_SIZE_INCLUDED<td align="center">3<td>2 byte <a href="{{ site_url('docs/spec/common-structures') }}#type_Integer">Integer</a><td>
|
||||
Currently sent with SYNCHRONIZE only.
|
||||
Was also sent in retransmitted packets until release 0.9.1.
|
||||
<tr><td>8<td>PROFILE_INTERACTIVE<td align="center">--<td align="center">--<td>
|
||||
Unused or ignored; the interactive profile is unimplemented.
|
||||
<tr><td>9<td>ECHO<td align="center">--<td align="center">--<td>
|
||||
Unused except by ping programs.
|
||||
If set, most other options are ignored. See
|
||||
<a href="{{ site_url('docs/api/streaming') }}">the streaming docs</a>.
|
||||
<tr><td>10<td>NO_ACK<td align="center">--<td align="center">--<td>
|
||||
This flag simply tells the recipient to ignore the ackThrough field in the header.
|
||||
Currently set in the inital SYN packet, otherwise the ackThrough field is always valid.
|
||||
Note that this does not save any space, the ackThrough field is before the flags
|
||||
and is always present.
|
||||
<tr><td>11-15<td>unused<td><td><td>
|
||||
Set to zero for compatibility with future uses.
|
||||
</table>
|
||||
|
||||
<h4>Variable Length Signature Notes</h4>
|
||||
<p>
|
||||
Prior to release 0.9.11, the signature in the option field was always 40 bytes.
|
||||
As of release 0.9.11, the signature is variable length.
|
||||
The Signature type and length are inferred from the type of key used in the FROM_INCLUDED option
|
||||
and the <a href="{{ site_url('docs/spec/common-structures') }}#type_Signature">Signature documentation</a>.
|
||||
<ul><li>
|
||||
When a packet contains both FROM_INCLUDED and SIGNATURE_INCLUDED (as in SYNCHRONIZE), the inference may be made directly.
|
||||
</li><li>
|
||||
When a packet does not contain FROM_INCLUDED, the inference must be made from a previous SYNCHRONIZE packet.
|
||||
</li><li>
|
||||
When a packet does not contain FROM_INCLUDED, and there was no previous SYNCHRONIZE packet
|
||||
(for example a stray CLOSE or RESET packet), the inference can be made from the length of the remaining options
|
||||
(since SIGNATURE_INCLUDED is the last option), but the packet will probably be discarded anyway, since there is no FROM available
|
||||
to validate the signature.
|
||||
If more option fields are defined in the future, they must be accounted for.
|
||||
</li></ul>
|
||||
</p>
|
||||
|
||||
|
||||
{% endblock %}
|
@@ -1,355 +0,0 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %}Tunnel Creation{% endblock %}
|
||||
{% block lastupdated %}January 2016{% endblock %}
|
||||
{% block accuratefor %}0.9.24{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
This page documents the current tunnel build implementation.
|
||||
|
||||
<h2 id="tunnelCreate.overview">Tunnel Creation Specification</h2>
|
||||
|
||||
<p>
|
||||
This document specifies the details of the encrypted tunnel build messages
|
||||
used to create tunnels using a "non-interactive telescoping" method.
|
||||
See <a href="{{ site_url('docs/tunnels/implementation') }}">the tunnel build document</a>
|
||||
for an overview of the process, including peer selection and ordering methods.
|
||||
|
||||
<p>The tunnel creation is accomplished by a single message passed along
|
||||
the path of peers in the tunnel, rewritten in place, and transmitted
|
||||
back to the tunnel creator. This single tunnel message is made up
|
||||
of a variable number of records (up to 8) - one for each potential peer in
|
||||
the tunnel. Individual records are asymmetrically
|
||||
<a href="{{ site_url('docs/how/cryptography') }}#elgamal">(ElGamal)</a>
|
||||
encrypted to be
|
||||
read only by a specific peer along the path, while an additional
|
||||
symmetric layer of encryption
|
||||
<a href="{{ site_url('docs/how/cryptography') }}#AES">(AES)</a>
|
||||
is added at each hop so as to expose
|
||||
the asymmetrically encrypted record only at the appropriate time.</p>
|
||||
|
||||
<h3 id="number">Number of Records</h3>
|
||||
Not all records must contain valid data.
|
||||
The build message for a 3-hop tunnel, for example, may contain more records
|
||||
to hide the actual length of the tunnel from the participants.
|
||||
There are two build message types. The original
|
||||
<a href="{{ site_url('docs/spec/i2np') }}#msg_TunnelBuild">Tunnel Build Message</a> (TBM)
|
||||
contains 8 records, which is more than enough for any practical tunnel length.
|
||||
The newer
|
||||
<a href="{{ site_url('docs/spec/i2np') }}#msg_VariableTunnelBuild">Variable Tunnel Build Message</a> (VTBM)
|
||||
contains 1 to 8 records. The originator may trade off the size of the message
|
||||
with the desired amount of tunnel length obfuscation.
|
||||
<p>
|
||||
In the current network, most tunnels are 2 or 3 hops long.
|
||||
The current implementation uses a 5-record VTBM to build tunnels of 4 hops or less,
|
||||
and the 8-record TBM for longer tunnels.
|
||||
The 5-record VTBM (which, when fragmented, fits in three 1KB tunnel messaages) reduces network traffic
|
||||
and increases build sucess rate, because smaller messages are less likely to be dropped.
|
||||
<p>
|
||||
The reply message must be the same type and length as the build message.
|
||||
|
||||
|
||||
<h3 id="tunnelCreate.requestRecord">Request Record Specification</h3>
|
||||
|
||||
Also specified in the
|
||||
<a href="{{ site_url('docs/spec/i2np') }}#struct_BuildRequestRecord">I2NP Specification</a>
|
||||
|
||||
<p>Cleartext of the record, visible only to the hop being asked:</p><pre>
|
||||
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: AES-256 reply IV
|
||||
byte 184: flags
|
||||
bytes 185-188: request time (in hours since the epoch, rounded down)
|
||||
bytes 189-192: next message ID
|
||||
bytes 193-221: uninterpreted / random padding</pre>
|
||||
|
||||
<p>The next tunnel ID and next router identity hash fields are used to
|
||||
specify the next hop in the tunnel, though for an outbound tunnel
|
||||
endpoint, they specify where the rewritten tunnel creation reply
|
||||
message should be sent. In addition, the next message ID specifies the
|
||||
message ID that the message (or reply) should use.</p>
|
||||
|
||||
<p>
|
||||
The tunnel layer key, tunnel IV key, reply key, and reply IV
|
||||
are each random 32-byte values generated by the creator,
|
||||
for use in this build request record only.
|
||||
</p>
|
||||
|
||||
<p>The flags field contains the following:
|
||||
<pre>
|
||||
Bit order: 76543210 (bit 7 is MSB)
|
||||
bit 7: if set, allow messages from anyone
|
||||
bit 6: if set, allow messages to anyone, and send the reply to the
|
||||
specified next hop in a Tunnel Build Reply Message
|
||||
bits 5-0: Undefined, must set to 0 for compatibility with future options
|
||||
</pre>
|
||||
<p>
|
||||
Bit 7 indicates that the hop will be an inbound gateway (IBGW).
|
||||
Bit 6 indicates that the hop will be an outbound endpoint (OBEP).
|
||||
If neither bit is set, the hop will be an intermediate participant.
|
||||
Both cannot be set at once.
|
||||
</p>
|
||||
|
||||
<h4>Request Record Creation</h4>
|
||||
<p>
|
||||
Every hop gets a random Tunnel ID.
|
||||
The current and next-hop Tunnel IDs are filled in.
|
||||
Every record gets a random tunnel IV key, reply IV, layer key, and reply key.
|
||||
</p>
|
||||
|
||||
|
||||
<h4 id="encryption">Request Record Encryption</h4>
|
||||
|
||||
<p>That cleartext record is <a href="{{ site_url('docs/how/cryptography') }}#elgamal">ElGamal 2048 encrypted</a> with the hop's
|
||||
public encryption key and formatted into a 528 byte record:</p><pre>
|
||||
bytes 0-15: First 16 bytes of the SHA-256 of the current hop's router identity
|
||||
bytes 16-527: ElGamal-2048 encrypted request record</pre>
|
||||
<p>
|
||||
In the 512-byte encrypted record,
|
||||
the ElGamal data contains bytes 1-256 and 258-513 of the
|
||||
<a href="{{ site_url('docs/how/cryptography') }}#elgamal">514-byte ElGamal encrypted block</a>.
|
||||
The two padding bytes from the block (the zero bytes at locations 0 and 257) are removed.
|
||||
</p>
|
||||
<p>Since the cleartext uses the full field, there is no need for
|
||||
additional padding beyond <code>SHA256(cleartext) + cleartext</code>.</p>
|
||||
|
||||
<p>
|
||||
Each 528-byte record is then iteratively encrypted
|
||||
(using AES decryption, with the reply key and reply IV for each hop) so that the router identity will only be in cleartext
|
||||
for the hop in question.
|
||||
</p>
|
||||
|
||||
<h3 id="tunnelCreate.hopProcessing">Hop Processing and Encryption</h3>
|
||||
|
||||
<p>When a hop receives a TunnelBuildMessage, it looks through the
|
||||
records contained within it for one starting with their own identity
|
||||
hash (trimmed to 16 bytes). It then decrypts the ElGamal block from
|
||||
that record and retrieves the protected cleartext. At that point,
|
||||
they make sure the tunnel request is not a duplicate by feeding the
|
||||
AES-256 reply key into a Bloom filter.
|
||||
Duplicates or invalid requests are dropped.
|
||||
Records that are not stamped with the current hour,
|
||||
or the previous hour if shortly after the top of the hour,
|
||||
must be dropped.
|
||||
For example, take the hour in the timestamp, convert to a full time,
|
||||
then if it's more than 65 minutes behind or 5 minutes ahead of the
|
||||
current time, it is invalid.
|
||||
The Bloom filter must have a duration of at least one hour
|
||||
(plus a few minutes, to allow for clock skew),
|
||||
so that duplicate records in the current hour that are not rejected
|
||||
by checking the hour timestamp in the record, will be rejected by the filter.
|
||||
</p>
|
||||
|
||||
<p>After deciding whether they will agree to participate in the tunnel
|
||||
or not, they replace the record that had contained the request with
|
||||
an encrypted reply block. All other records are <a href="{{ site_url('docs/how/cryptography') }}#AES">AES-256
|
||||
encrypted</a> with the included reply key and IV. Each is
|
||||
AES/CBC encrypted separately with the same reply key and reply IV.
|
||||
The CBC mode is not continued (chained) across records.</p>
|
||||
|
||||
<p>
|
||||
Each hop knows only its own response.
|
||||
If it agrees, it will maintain the tunnel until expiration,
|
||||
even if it will not be used,
|
||||
as it cannot know whether all other hops agreed.
|
||||
</p>
|
||||
|
||||
|
||||
<h4 id="tunnelCreate.replyRecord">Reply Record Specification</h4>
|
||||
|
||||
<p>After the current hop reads their record, they replace it with a
|
||||
reply record stating whether or not they agree to participate in the
|
||||
tunnel, and if they do not, they classify their reason for
|
||||
rejection. This is simply a 1 byte value, with 0x0 meaning they
|
||||
agree to participate in the tunnel, and higher values meaning higher
|
||||
levels of rejection.
|
||||
<p>
|
||||
The following rejection codes are defined:
|
||||
<ul>
|
||||
<li>
|
||||
TUNNEL_REJECT_PROBABALISTIC_REJECT = 10
|
||||
<li>
|
||||
TUNNEL_REJECT_TRANSIENT_OVERLOAD = 20
|
||||
<li>
|
||||
TUNNEL_REJECT_BANDWIDTH = 30
|
||||
<li>
|
||||
TUNNEL_REJECT_CRIT = 50
|
||||
</ul>
|
||||
To hide other causes, such as router shutdown, from peers, the current implementation
|
||||
uses TUNNEL_REJECT_BANDWIDTH for almost all rejections.
|
||||
|
||||
<p>
|
||||
The reply is encrypted with the AES session
|
||||
key delivered to it in the encrypted block, padded with 495 bytes of random data
|
||||
to reach the full record size.
|
||||
The padding is placed before the status byte:
|
||||
</p><pre>
|
||||
AES-256-CBC(SHA-256(padding+status) + padding + status, key, IV)
|
||||
|
||||
bytes 0-31 : SHA-256 of bytes 32-527
|
||||
bytes 32-526 : Random padding
|
||||
byte 527 : Reply value
|
||||
</pre>
|
||||
<p>
|
||||
This is also described in the
|
||||
<a href="{{ site_url('docs/spec/i2np') }}#struct_BuildResponseRecord">I2NP spec</a>.
|
||||
</p>
|
||||
|
||||
<h3 id="tunnelCreate.requestPreparation">Tunnel Build Message Preparation</h3>
|
||||
|
||||
<p>When building a new Tunnel Build Message, all of the Build Request Records must first be
|
||||
built and asymmetrically encrypted using
|
||||
<a href="{{ site_url('docs/how/cryptography') }}#elgamal">ElGamal</a>.
|
||||
Each record is then
|
||||
premptively decrypted with the reply keys and IVs of the hops earlier in the
|
||||
path, using
|
||||
<a href="{{ site_url('docs/how/cryptography') }}#AES">AES</a>.
|
||||
That decryption should be run in reverse order so that the
|
||||
asymmetrically encrypted data will show up in the clear at the
|
||||
right hop after their predecessor encrypts it.</p>
|
||||
|
||||
<p>The excess records not needed for individual requests are simply
|
||||
filled with random data by the creator.</p>
|
||||
|
||||
<h3 id="tunnelCreate.requestDelivery">Tunnel Build Message Delivery</h3>
|
||||
|
||||
<p>For outbound tunnels, the delivery is done directly from the tunnel
|
||||
creator to the first hop, packaging up the TunnelBuildMessage as if
|
||||
the creator was just another hop in the tunnel. For inbound
|
||||
tunnels, the delivery is done through an existing outbound tunnel.
|
||||
The outbound tunnel is generally from the same pool as the new tunnel being built.
|
||||
If no outbound tunnel is available in that pool, an outbound exploratory tunnel is used.
|
||||
At startup, when no outbound exploratory tunnel exists yet, a fake 0-hop
|
||||
outbound tunnel is used.</p>
|
||||
|
||||
<h3 id="tunnelCreate.endpointHandling">Tunnel Build Message Endpoint Handling</h3>
|
||||
|
||||
<p>
|
||||
For creation of an outbound tunnel,
|
||||
when the request reaches an outbound endpoint (as determined by the
|
||||
'allow messages to anyone' flag), the hop is processed as usual,
|
||||
encrypting a reply in place of the record and encrypting all of the
|
||||
other records, but since there is no 'next hop' to forward the
|
||||
TunnelBuildMessage on to, it instead places the encrypted reply
|
||||
records into a
|
||||
<a href="{{ site_url('docs/spec/i2np') }}#msg_TunnelBuildReply">TunnelBuildReplyMessage</a>
|
||||
or
|
||||
<a href="{{ site_url('docs/spec/i2np') }}#msg_VariableTunnelBuildReply">VariableTunnelBuildReplyMessage</a>
|
||||
(the type of message and number of records must match that of the request)
|
||||
and delivers it to the
|
||||
reply tunnel specified within the request record. That reply tunnel
|
||||
forwards the Tunnel Build Reply Message back to the tunnel creator,
|
||||
<a href="{{ site_url('docs/tunnels/implementation') }}#tunnel.operation">just as for any other message</a>.
|
||||
The tunnel creator then
|
||||
processes it, as described below.</p>
|
||||
|
||||
<p>The reply tunnel was selected by the creator as follows:
|
||||
Generally it is an inbound tunnel from the same pool as the new outbound tunnel being built.
|
||||
If no inbound tunnel is available in that pool, an inbound exploratory tunnel is used.
|
||||
At startup, when no inbound exploratory tunnel exists yet, a fake 0-hop
|
||||
inbound tunnel is used.</p>
|
||||
|
||||
<p>
|
||||
For creation of an inbound tunnel,
|
||||
when the request reaches the inbound endpoint (also known as the
|
||||
tunnel creator), there is no need to generate an explicit Tunnel Build Reply Message, and
|
||||
the router processes each of the replies, as below.</p>
|
||||
|
||||
<h3 id="tunnelCreate.replyProcessing">Tunnel Build Reply Message Processing</h3>
|
||||
|
||||
<p>To process the reply records, the creator simply has to AES decrypt
|
||||
each record individually, using the reply key and IV of each hop in
|
||||
the tunnel after the peer (in reverse order). This then exposes the
|
||||
reply specifying whether they agree to participate in the tunnel or
|
||||
why they refuse. If they all agree, the tunnel is considered
|
||||
created and may be used immediately, but if anyone refuses, the
|
||||
tunnel is discarded.</p>
|
||||
|
||||
<p>
|
||||
The agreements and rejections are noted in each peer's
|
||||
<a href="{{ site_url('docs/how/peer-selection') }}">profile</a>, to be used in future assessments
|
||||
of peer tunnel capacity.
|
||||
|
||||
|
||||
<h2 id="tunnelCreate.notes">History and Notes</h2>
|
||||
<p>
|
||||
This strategy came about during a discussion on the I2P mailing list
|
||||
between Michael Rogers, Matthew Toseland (toad), and jrandom regarding
|
||||
the predecessor attack. See: <ul>
|
||||
<li><a href="http://osdir.com/ml/network.i2p/2005-10/msg00138.html">Summary</a></li>
|
||||
<li><a href="http://osdir.com/ml/network.i2p/2005-10/msg00129.html">Reasoning</a></li>
|
||||
</ul></li>
|
||||
It was introduced in release 0.6.1.10 on 2006-02-16, which was the last time
|
||||
a non-backward-compatible change was made in I2P.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Notes:
|
||||
<ul>
|
||||
<li>This design does not prevent two hostile peers within a tunnel from
|
||||
tagging one or more request or reply records to detect that they are
|
||||
within the same tunnel, but doing so can be detected by the tunnel
|
||||
creator when reading the reply, causing the tunnel to be marked as
|
||||
invalid.</li>
|
||||
<li>This design does not include a proof of work on the asymmetrically
|
||||
encrypted section, though the 16 byte identity hash could be cut in
|
||||
half with the latter replaced by a hashcash function of up to 2^64
|
||||
cost.</li>
|
||||
<li>This design alone does not prevent two hostile peers within a tunnel from
|
||||
using timing information to determine whether they are in the same
|
||||
tunnel. The use of batched and synchronized request delivery
|
||||
could help (batching up requests and sending them off on the
|
||||
(ntp-synchronized) minute). However, doing so lets peers 'tag' the
|
||||
requests by delaying them and detecting the delay later in the
|
||||
tunnel, though perhaps dropping requests not delivered in a small
|
||||
window would work (though doing that would require a high degree of
|
||||
clock synchronization). Alternately, perhaps individual hops could
|
||||
inject a random delay before forwarding on the request?</li>
|
||||
<li>Are there any nonfatal methods of tagging the request?</li>
|
||||
<li>
|
||||
The timestamp with a one-hour resolution is used for replay prevention.
|
||||
The constraint was not enforced until release 0.9.16.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="ref">References</h2>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="http://forensics.umass.edu/pubs/wright-tissec.pdf">Predecessor
|
||||
attack</a>
|
||||
<li>
|
||||
<a href="http://forensics.umass.edu/pubs/wright.tissec.2008.pdf">2008
|
||||
update</a>
|
||||
<li>
|
||||
<a href="http://www-users.cs.umn.edu/~hopper/hashing_it_out.pdf">Hashing it out in Public</a>
|
||||
</ul>
|
||||
|
||||
<h2 id="future">Future Work</h2>
|
||||
<ul>
|
||||
<li>
|
||||
In the current implementation, the originator leaves one record empty
|
||||
for itself. Thus a message of n records can only build a
|
||||
tunnel of n-1 hops.
|
||||
This appears to be necessary for inbound tunnels (where the next-to-last hop
|
||||
can see the hash prefix for the next hop), but not for outbound tunnels.
|
||||
This is to be researched and verified.
|
||||
If it is possible to use the remaining record without compromising anonymity,
|
||||
we should do so.
|
||||
<li>
|
||||
Further analysis of possible tagging and timing attacks described in the above notes.
|
||||
</li><li>
|
||||
Use only VTBM; do not select old peers that don't support it.
|
||||
</li><li>
|
||||
The Build Request Record does not specify a tunnel lifetime or expiration;
|
||||
each hop expires the tunnel after 10 minutes, which is a network-wide hardcoded constant.
|
||||
We could use a bit in the flag field
|
||||
and take 4 (or 8) bytes out of the padding to specify a lifetime or expiration.
|
||||
The requestor would only specify this option if all participants supported it.
|
||||
</li></ul>
|
||||
|
||||
|
||||
{% endblock %}
|
@@ -1,318 +0,0 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %}Tunnel Message Specification{% endblock %}
|
||||
{% block lastupdated %}February 2014{% endblock %}
|
||||
{% block accuratefor %}0.9.11{% endblock %}
|
||||
{% block content %}
|
||||
<p>
|
||||
This document specifies the format of tunnel messages.
|
||||
For general information about tunnels see
|
||||
<a href="{{ site_url('docs/tunnels/implementation') }}">the tunnel documentation</a>.
|
||||
</p>
|
||||
|
||||
<h2>Message preprocessing</h2>
|
||||
|
||||
|
||||
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="{{ site_url('docs/protocol/i2np') }}">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="{{ site_url('docs/tunnels/implementation') }}">the tunnel documentation</a>.
|
||||
|
||||
<h2 id="msg_Tunnel">Tunnel Message (Encrypted)</h2>
|
||||
These are the contents of a tunnel data message after encryption.
|
||||
{% highlight lang='dataspec' %}
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| Tunnel ID | IV |
|
||||
+----+----+----+----+ +
|
||||
| |
|
||||
+ +----+----+----+----+
|
||||
| | |
|
||||
+----+----+----+----+ +
|
||||
| |
|
||||
+ Encrypted Data +
|
||||
~ ~
|
||||
| |
|
||||
+ +-------------------+
|
||||
| |
|
||||
+----+----+----+----+
|
||||
{% endhighlight %}
|
||||
|
||||
<h4>Definition</h4>
|
||||
{% highlight lang='dataspec' %}
|
||||
Tunnel ID :: `TunnelId`
|
||||
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
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
<h2>Tunnel Message (Decrypted)</h2>
|
||||
These are the contents of a tunnel data message when decrypted.
|
||||
{% highlight lang='dataspec' %}
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| Tunnel ID | IV |
|
||||
+----+----+----+----+ +
|
||||
| |
|
||||
+ +----+----+----+----+
|
||||
| | Checksum |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| nonzero padding... |
|
||||
~ ~
|
||||
| |
|
||||
+ +----+
|
||||
| |zero|
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
| Delivery Instructions 1 |
|
||||
~ ~
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
+ I2NP Message Fragment 1 +
|
||||
| |
|
||||
~ ~
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
| Delivery Instructions 2... |
|
||||
~ ~
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
+ I2NP Message Fragment 2... +
|
||||
| |
|
||||
~ ~
|
||||
| |
|
||||
+ +-------------------+
|
||||
| |
|
||||
+----+----+----+----+
|
||||
{% endhighlight %}
|
||||
|
||||
<h4>Definition</h4>
|
||||
{% highlight lang='dataspec' %}
|
||||
Tunnel ID :: `TunnelId`
|
||||
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 contents of the message (after the zero byte) + IV)
|
||||
|
||||
Nonzero padding ::
|
||||
0 or more bytes
|
||||
random nonzero data for padding
|
||||
|
||||
Zero ::
|
||||
1 byte
|
||||
the value 0x00
|
||||
|
||||
Delivery Instructions :: `TunnelMessageDeliveryInstructions`
|
||||
length varies but is typically 7, 39, 43, or 47 bytes
|
||||
Indicates the fragment and the routing for the fragment
|
||||
|
||||
Message Fragment ::
|
||||
1 to 996 bytes, actual maximum depends on delivery instruction size
|
||||
A partial or full I2NP Message
|
||||
|
||||
total size: 1028 Bytes
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
<h4>Notes</h4>
|
||||
<ul><li>
|
||||
The padding, if any, must be before the instruction/message pairs.
|
||||
There is no provision for padding at the end.
|
||||
</li><li>
|
||||
The checksum does NOT cover the padding or the zero byte.
|
||||
Take the message starting at the first delivery instructions, concatenate the IV,
|
||||
and take the Hash of that.
|
||||
</li></ul>
|
||||
|
||||
|
||||
<h2 id="struct_TunnelMessageDeliveryInstructions">Tunnel Message 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>
|
||||
This specification is for Delivery Instructions inside Tunnel Messages only.
|
||||
Note that "Delivery Instructions" are also used inside
|
||||
<a href="{{ site_url('docs/spec/i2np') }}#struct_GarlicClove">Garlic Cloves</a>,
|
||||
where the format is significantly different.
|
||||
See the
|
||||
<a href="{{ site_url('docs/spec/i2np') }}#struct_GarlicCloveDeliveryInstructions">I2NP documentation</a>
|
||||
for details.
|
||||
Do NOT use the following specification for Garlic Clove Delivery Instructions!
|
||||
|
||||
|
||||
<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 (unfragmented) I2NP message, and the instructions are:</p>
|
||||
{% highlight lang='dataspec' %}
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|flag| Tunnel ID (opt) | |
|
||||
+----+----+----+----+----+ +
|
||||
| |
|
||||
+ +
|
||||
| To Hash (optional) |
|
||||
+ +
|
||||
| |
|
||||
+ +--------------+
|
||||
| |dly | Message
|
||||
+----+----+----+----+----+----+----+----+
|
||||
ID (opt) |extended opts (opt)| size |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
{% endhighlight %}
|
||||
|
||||
<h4>Definition</h4>
|
||||
{% highlight lang='dataspec' %}
|
||||
flag ::
|
||||
1 byte
|
||||
Bit order: 76543210
|
||||
bit 7: 0 to specify an initial fragment or an unfragmented message
|
||||
bits 6-5: delivery type
|
||||
0x0 = LOCAL, 0x01 = TUNNEL, 0x02 = ROUTER, 0x03 = unused, invalid
|
||||
Note: LOCAL is used for inbound tunnels only, unimplemented for outbound tunnels
|
||||
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, set to 0 for compatibility with future uses
|
||||
|
||||
Tunnel ID :: `TunnelId`
|
||||
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
|
||||
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)
|
||||
|
||||
Message ID ::
|
||||
4 bytes
|
||||
Optional, present if this message is the first of 2 or more fragments
|
||||
(i.e. if the fragmented bit is 1)
|
||||
An ID that uniquely identifies all fragments as belonging to a single message
|
||||
(the current implementation uses `I2NPMessageHeader.msg_id`)
|
||||
|
||||
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
|
||||
|
||||
Total length: Typical length is:
|
||||
3 bytes for LOCAL delivery (tunnel message);
|
||||
35 bytes for ROUTER / DESTINATION delivery or 39 bytes for TUNNEL delivery (unfragmented tunnel message);
|
||||
39 bytes for ROUTER delivery or 43 bytes for TUNNEL delivery (first fragment)
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
<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>
|
||||
{% highlight lang='dataspec' %}
|
||||
+----+----+----+----+----+----+----+
|
||||
|frag| Message ID | size |
|
||||
+----+----+----+----+----+----+----+
|
||||
{% endhighlight %}
|
||||
|
||||
<h4>Definition</h4>
|
||||
{% highlight lang='dataspec' %}
|
||||
frag ::
|
||||
1 byte
|
||||
Bit order: 76543210
|
||||
binary 1nnnnnnd
|
||||
bit 7: 1 to indicate this is a follow-on fragment
|
||||
bits 6-1: nnnnnn is the 6 bit fragment number from 1 to 63
|
||||
bit 0: d is 1 to indicate the last fragment, 0 otherwise
|
||||
|
||||
Message ID ::
|
||||
4 bytes
|
||||
Identifies the fragment sequence that this fragment belongs to.
|
||||
This will match the message ID of an initial fragment (a fragment
|
||||
with flag bit 7 set to 0 and flag bit 3 set to 1).
|
||||
|
||||
size ::
|
||||
2 bytes
|
||||
the length of the fragment that follows
|
||||
valid values: 1 to 996
|
||||
|
||||
total length: 7 bytes
|
||||
{% endhighlight %}
|
||||
|
||||
<h3><a href="http://{{ i2pconv('i2p-javadocs.i2p') }}/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 %}
|
@@ -1,572 +0,0 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %}{% trans %}I2P Software Update Specification{% endtrans %}{% endblock %}
|
||||
{% block lastupdated %}{% trans %}May 2015{% endtrans %}{% endblock %}
|
||||
{% block accuratefor %}0.9.20{% endblock %}
|
||||
{% block content %}
|
||||
<h3>{% trans %}Overview{% endtrans %}</h3>
|
||||
<p>{% trans -%}
|
||||
I2P uses a simple, yet secure, system for automated software update.
|
||||
The router console periodically pulls a news file from a configurable I2P URL.
|
||||
There is a hardcoded backup URL pointing to the project website, in case
|
||||
the default project news host goes down.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans -%}
|
||||
The contents of the news file are displayed on the home page of the router console.
|
||||
In addition, the news file contains the most recent version number of the software.
|
||||
If the version is higher than the router's version number, it will
|
||||
display an indication to the user that an update is available.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans -%}
|
||||
The router may optionally download, or download and install, the new version
|
||||
if configured to do so.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h3>{% trans %}Old News File Specification{% endtrans %}</h3>
|
||||
<p>{% trans -%}
|
||||
This format is replaced by the su3 news format as of release 0.9.17.
|
||||
{%- endtrans %}</p>
|
||||
<p>{% trans -%}
|
||||
The news.xml file may contain the following elements:
|
||||
{%- endtrans %}</p>
|
||||
<pre>
|
||||
<i2p.news date="$Date: 2010-01-22 00:00:00 $" />
|
||||
<i2p.release version="0.7.14" date="2010/01/22" minVersion="0.6" />
|
||||
</pre>
|
||||
|
||||
<p>{% trans -%}
|
||||
Parameters in the i2p.release entry are as follows.
|
||||
All keys are case-insensitive. All values must be enclosed in double quotes.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
date: The release date of the router version. Unused. Format not specified.
|
||||
</li><li>
|
||||
minJavaVersion: The minimum version of Java required to run the current version.
|
||||
As of release 0.9.9.
|
||||
</li><li>
|
||||
minVersion: The minimum version of the router required to update to the current version.
|
||||
If a router is older than this, the user must (manually?) update to an intermediate version first.
|
||||
As of release 0.9.9.
|
||||
</li><li>
|
||||
su3Clearnet: One or more HTTP URLs where the .su3 update file may
|
||||
be found on the clearnet (non-I2P).
|
||||
Multiple URLs must be separated by a space or comma.
|
||||
As of release 0.9.9.
|
||||
</li><li>
|
||||
su3SSL: One or more HTTPS URLs where the .su3 update file may
|
||||
be found on the clearnet (non-I2P).
|
||||
Multiple URLs must be separated by a space or comma.
|
||||
As of release 0.9.9.
|
||||
</li><li>
|
||||
sudTorrent: The magnet link for the .sud (non-pack200) torrent of the update.
|
||||
As of release 0.9.4.
|
||||
</li><li>
|
||||
su2Torrent: The magnet link for the .su2 (pack200) torrent of the update.
|
||||
As of release 0.9.4.
|
||||
</li><li>
|
||||
su3Torrent: The magnet link for the .su3 (new format) torrent of the update.
|
||||
As of release 0.9.9.
|
||||
</li><li>
|
||||
version: Required. The latest current router version available.
|
||||
</li></ul>
|
||||
|
||||
<p>{% trans -%}
|
||||
The elements may be included inside XML comments to prevent interpretation by browsers.
|
||||
The i2p.release element and version are required. All others are optional.
|
||||
NOTE: Due to parser limitations an entire element must be on a single line.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
|
||||
<h3>{% trans %}Update File Specification{% endtrans %}</h3>
|
||||
<p>{% trans -%}
|
||||
As of release 0.9.9, the signed update file, named i2pupdate.su3, will
|
||||
use the "su3" file format specified below.
|
||||
Approved release signers will use 4096-bit RSA keys.
|
||||
The X.509 public key certificates for these signers are distributed in the router installation packages.
|
||||
The updates may contain certificates for new, approved signers, and/or contain
|
||||
a list of certificates to delete for revocation.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
|
||||
<h3>{% trans %}Old Update File Specification{% endtrans %}</h3>
|
||||
<p>{% trans -%}
|
||||
This format is obsolete as of release 0.9.9.
|
||||
{%- endtrans %}</p>
|
||||
<p>{% trans -%}
|
||||
The signed update file, traditionally named i2pupdate.sud,
|
||||
is simply a zip file with a prepended 56 byte header.
|
||||
The header contains:
|
||||
{%- endtrans %}</p>
|
||||
<ul>
|
||||
<li>{% trans commonstructures=site_url('docs/spec/common-structures') -%}
|
||||
A 40-byte <a href="{{ commonstructures }}#type_signature">DSA signature</a>
|
||||
{%- endtrans %}</li>
|
||||
<li>{% trans -%}
|
||||
A 16-byte I2P version in UTF-8, padded with trailing zeroes if necessary
|
||||
{%- endtrans %}</li>
|
||||
</ul>
|
||||
|
||||
<p>{% trans commonstructures=site_url('docs/spec/common-structures') -%}
|
||||
The signature covers only the zip archive - not the prepended version.
|
||||
The signature must match one of the <a href="{{ commonstructures }}#type_SigningPublicKey">DSA public keys</a> configured into the router,
|
||||
which has a hardcoded default list of keys of the current project release managers.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans -%}
|
||||
For version comparison purposes, version fields contain [0-9]*, field separators are
|
||||
'-', '_', and '.', and all other characters are ignored.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans -%}
|
||||
As of version 0.8.8, the version must also be specified as a zip file comment in UTF-8,
|
||||
without the trailing zeroes.
|
||||
The updating router verifes that the version in the header (not covered by the signature)
|
||||
matches the version in the zip file comment, which is covered by the signature.
|
||||
This prevents spoofing of the version number in the header.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h3>{% trans %}Download and Installation{% endtrans %}</h3>
|
||||
<p>{% trans -%}
|
||||
The router first downloads the header of the update file from one in a configurable list of I2P URLs,
|
||||
using the built-in HTTP client and proxy,
|
||||
and checks that the version is newer.
|
||||
This prevents the problem of update hosts that do not have the latest file.
|
||||
The router then downloads the full update file.
|
||||
The router verifies that the update file version is newer before installation.
|
||||
It also, of course, verifies the signature, and
|
||||
verifes that the zip file comment matches the header version, as explained above.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans -%}
|
||||
The zip file is extracted and copied to "i2pupdate.zip" in the I2P configuration directory (~/.i2p on Linux).
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans -%}
|
||||
As of release 0.7.12, the router supports Pack200 decompression.
|
||||
Files inside the zip archive with a .jar.pack or .war.pack suffix
|
||||
are transparently decompressed to a .jar or .war file.
|
||||
Update files containing .pack files are traditionally named with a '.su2' suffix.
|
||||
Pack200 shrinks the update files by about 60%.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans -%}
|
||||
As of release 0.8.7, the router will delete the libjbigi.so and libjcpuid.so files
|
||||
if the zip archive contains a lib/jbigi.jar file, so that the new files will
|
||||
be extracted from jbigi.jar.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans -%}
|
||||
As of release 0.8.12, if the zip archive contains a file deletelist.txt, the router will
|
||||
delete the files listed there. The format is:
|
||||
{%- endtrans %}</p>
|
||||
<ul>
|
||||
<li>{% trans %}One file name per line{% endtrans %}</li>
|
||||
<li>{% trans %}All file names are relative to the installation directory; no absolute file names allowed, no files starting with ".."{% endtrans %}</li>
|
||||
<li>{% trans %}Comments start with '#'{% endtrans %}</li>
|
||||
</ul>
|
||||
|
||||
<p>{% trans -%}
|
||||
The router will then delete the deletelist.txt file.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
|
||||
|
||||
<h3 id="su3">{% trans %}SU3 File Specification{% endtrans %}</h3>
|
||||
|
||||
<p>{% trans -%}
|
||||
This specification is used for router updates as of release 0.9.9, reseed data as of release 0.9.14,
|
||||
plugins as of release 0.9.15, and the news file as of release 0.9.17.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h4>{% trans %}Issues with the previous .sud/.su2 format:{% endtrans %}</h4>
|
||||
<ul>
|
||||
<li>{% trans -%}
|
||||
No magic number or flags
|
||||
{%- endtrans %}</li>
|
||||
<li>{% trans -%}
|
||||
No way to specify compression, pack200 or not, or signing algo
|
||||
{%- endtrans %}</li>
|
||||
<li>{% trans -%}
|
||||
Version is not covered by signature, so it is enforced by requiring it
|
||||
to be in the zip file comment (for router files) or in the plugin.config
|
||||
file (for plugins)
|
||||
{%- endtrans %}</li>
|
||||
<li>{% trans -%}
|
||||
Signer not specified so verifier must try all known keys
|
||||
{%- endtrans %}</li>
|
||||
<li>{% trans -%}
|
||||
Signature-before-data format requires two passes to generate file
|
||||
{%- endtrans %}</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h4>{% trans %}Goals:{% endtrans %}</h4>
|
||||
|
||||
<ul>
|
||||
<li>{% trans -%}
|
||||
Fix above problems
|
||||
{%- endtrans %}</li>
|
||||
<li>{% trans -%}
|
||||
Migrate to more secure signature algorithm
|
||||
{%- endtrans %}</li>
|
||||
<li>{% trans -%}
|
||||
Keep version info in same format and offset for compatibility with
|
||||
existing version checkers
|
||||
{%- endtrans %}</li>
|
||||
<li>{% trans -%}
|
||||
One-pass signature verification and file extraction
|
||||
{%- endtrans %}</li>
|
||||
</ul>
|
||||
|
||||
<h4>{% trans %}Specification:{% endtrans %}</h4>
|
||||
|
||||
<table><tr>
|
||||
<th>Bytes<th>Contents
|
||||
<tr><td>
|
||||
0-5 <td>Magic number "I2Psu3"
|
||||
<tr><td>
|
||||
6 <td>unused = 0
|
||||
<tr><td>
|
||||
7 <td>su3 file format version = 0
|
||||
<tr><td>
|
||||
8-9 <td>Signature type
|
||||
<ul><li>0x0000 = DSA-SHA1
|
||||
</li><li>0x0001 = ECDSA-SHA256-P256
|
||||
</li><li>0x0002 = ECDSA-SHA384-P384
|
||||
</li><li>0x0003 = ECDSA-SHA512-P521
|
||||
</li><li>0x0004 = RSA-SHA256-2048
|
||||
</li><li>0x0005 = RSA-SHA384-3072
|
||||
</li><li>0x0006 = RSA-SHA512-4096
|
||||
</li></ul>
|
||||
<tr><td>
|
||||
10-11 <td>Signature length, e.g. 40 (0x0028) for DSA-SHA1.
|
||||
Must match that specified for the signature type on the
|
||||
<a href="{{ site_url('docs/spec/common-structures') }}#type_Signature">common structures page</a>.
|
||||
<tr><td>
|
||||
12 <td>unused = 0
|
||||
<tr><td>
|
||||
13 <td>Version length (in bytes not chars, including padding)
|
||||
must be at least 16 (0x10) for compatibility
|
||||
<tr><td>
|
||||
14 <td>unused = 0
|
||||
<tr><td>
|
||||
15 <td>Signer ID length (in bytes not chars)
|
||||
<tr><td>
|
||||
16-23 <td>Content length (not including header or sig)
|
||||
<tr><td>
|
||||
24 <td>unused = 0
|
||||
<tr><td>
|
||||
25 <td>File type
|
||||
<ul><li>0x00 = zip file
|
||||
</li><li>0x01 = xml file (as of 0.9.15)
|
||||
</li><li>0x02 = html file (as of 0.9.17)
|
||||
</li><li>0x03 = xml.gz file (as of 0.9.17)
|
||||
</li></ul>
|
||||
<tr><td>
|
||||
26 <td>unused = 0
|
||||
<tr><td>
|
||||
27 <td>Content type
|
||||
<ul><li>0x00 = unknown
|
||||
</li><li>0x01 = router update
|
||||
</li><li>0x02 = plugin or plugin update
|
||||
</li><li>0x03 = reseed data
|
||||
</li><li>0x04 = news feed (as of 0.9.15)
|
||||
</li></ul>
|
||||
<tr><td>
|
||||
28-39 <td>unused = 0
|
||||
<tr><td>
|
||||
40-55+ <td>Version, UTF-8 padded with trailing 0x00, 16 bytes minimum, length specified at byte 13.
|
||||
Do not append 0x00 bytes if the length is 16 or more.
|
||||
<tr><td>
|
||||
xx+ <td>ID of signer, (e.g. "zzz@mail.i2p") UTF-8, not padded, length specified at byte 15
|
||||
<tr><td>
|
||||
xx+ <td>Content: Length specified in header at bytes 16-23,
|
||||
format specified in header at byte 25,
|
||||
content specified in header at byte 27
|
||||
<tr><td>
|
||||
xx+ <td>Signature: Length is specified in header at bytes 10-11, covers everything starting at byte 0
|
||||
</table>
|
||||
|
||||
<p>{% trans -%}
|
||||
All unused fields must be set to 0 for compatibility with future versions.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
|
||||
<h4>{% trans %}Signature Details{% endtrans %}</h4>
|
||||
<p>
|
||||
The signature covers the entire header starting at byte 0,
|
||||
through the end of the content.
|
||||
We use raw signatures. Take the hash of the data (using the hash type
|
||||
implied by the signature type at bytes 8-9) and pass that
|
||||
to a "raw" sign or verify function (e.g. "NONEwithRSA" in Java).
|
||||
<p></p>
|
||||
While signature verification and content extraction may be implemented in one pass,
|
||||
an implementation must read and buffer the first 10 bytes to determine the hash type
|
||||
before starting to verify.
|
||||
<p></p>
|
||||
Signature lengths for the various signature types are specified on the
|
||||
<a href="{{ site_url('docs/spec/common-structures') }}#type_Signature">common structures page</a>.
|
||||
Pad the signature with leading zeros if necessary.
|
||||
See <a href="{{ site_url('docs/how/cryptography') }}#sig">the cryptography details page</a>
|
||||
for parameters of the various signature types.
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
<h4>{% trans %}Notes{% endtrans %}</h4>
|
||||
<p>
|
||||
The content type specifies the trust domain.
|
||||
For each content type, clients maintain a set of X.509 public key certificates for
|
||||
parties trusted to sign that content.
|
||||
Only certificates for the specified content type may be used.
|
||||
The certificate is looked up by the ID of the signer.
|
||||
Clients must verify that the content type is that expected for the application.
|
||||
<p></p>
|
||||
All values are in network byte order (big endian).
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>{% trans %}SU3 Router Update File Specification{% endtrans %}</h3>
|
||||
|
||||
<p><b>SU3 Details:</b></p>
|
||||
<ul><li>
|
||||
SU3 Content Type: 1 (ROUTER UPDATE)
|
||||
</li><li>
|
||||
SU3 File Type: 0 (ZIP)
|
||||
</li><li>
|
||||
SU3 Version: The router version
|
||||
</li><li>
|
||||
Jar and war files in the zip are compressed with pack200 as documented above for "su2" files.
|
||||
If the client does not support pack200, it must download the update in a "sud" format.
|
||||
</li></ul>
|
||||
|
||||
<p><b>Notes:</b></p>
|
||||
<ul><li>
|
||||
For releases, the SU3 version is the "base" router version, e.g. "0.9.20".
|
||||
</li><li>
|
||||
For development builds, which are supported as of release 0.9.20,
|
||||
the SU3 version is the "full" router version, e.g. "0.9.20-5" or "0.9.20-5-rc".
|
||||
See RouterVersion.java.
|
||||
</li></ul>
|
||||
|
||||
|
||||
|
||||
<h3>{% trans %}SU3 Reseed File Specification{% endtrans %}</h3>
|
||||
<p>{% trans -%}
|
||||
As of 0.9.14, reseed data is delivered in an "su3" file format.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h4>{% trans %}Goals:{% endtrans %}</h4>
|
||||
|
||||
<ul>
|
||||
<li>{% trans -%}
|
||||
Signed files with strong signatures and trusted certificates
|
||||
to prevent man-in-the-middle attacks that could boot victims into a separate, untrusted network.
|
||||
{%- endtrans %}</li>
|
||||
<li>{% trans -%}
|
||||
Use su3 file format already used for updates, reseeding, and plugins
|
||||
{%- endtrans %}</li>
|
||||
<li>{% trans -%}
|
||||
Single compressed file to speed up reseeding, which was slow to fetch 200 files
|
||||
{%- endtrans %}</li>
|
||||
</ul>
|
||||
|
||||
<h4>{% trans %}Specification:{% endtrans %}</h4>
|
||||
|
||||
<p><ol>
|
||||
<li>{% trans -%}
|
||||
The file must be named "i2pseeds.su3".
|
||||
{%- endtrans %}</li>
|
||||
<li>{% trans -%}
|
||||
The file must be in the same directory as the router infos on the web server.
|
||||
{%- endtrans %}</li>
|
||||
<li>{% trans -%}
|
||||
A router will first try to fetch (index URL)/i2pseeds.su3; if that fails it will fetch the index URL
|
||||
and then fetch the individual router info files found in the links.
|
||||
{%- endtrans %}</li>
|
||||
</ol></p>
|
||||
|
||||
<p><b>SU3 Details:</b></p>
|
||||
<ul><li>
|
||||
SU3 Content Type: 3 (RESEED)
|
||||
</li><li>
|
||||
SU3 File Type: 0 (ZIP)
|
||||
</li><li>
|
||||
SU3 Version: Seconds since the epoch, in ASCII (date +%s)
|
||||
</li><li>
|
||||
Router info files in the zip file must be at the "top level". No directories are in the zip file.
|
||||
</li><li>
|
||||
Router info files must be named "routerInfo-(44 character base 64 router hash).dat", as in the old reseed mechanism.
|
||||
The I2P base 64 alphabet must be used.
|
||||
</li></ul>
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>{% trans %}SU3 Plugin File Specification{% endtrans %}</h3>
|
||||
|
||||
<p>{% trans -%}
|
||||
As of 0.9.15, plugins may be packaged in an "su3" file format.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p><b>SU3 Details:</b></p>
|
||||
<ul><li>
|
||||
SU3 Content Type: 2 (PLUGIN)
|
||||
</li><li>
|
||||
SU3 File Type: 0 (ZIP)
|
||||
See <a href="plugin">the plugin specification</a> for details.
|
||||
</li><li>
|
||||
SU3 Version: The plugin version, must match that in plugin.config.
|
||||
</li><li>
|
||||
Jar and war files in the zip are compressed with pack200 as documented above for "su2" files.
|
||||
</li></ul>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>{% trans %}SU3 News File Specification{% endtrans %}</h3>
|
||||
<p>{% trans -%}
|
||||
As of 0.9.17, the news is delivered in an "su3" file format.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h4>{% trans %}Goals:{% endtrans %}</h4>
|
||||
|
||||
<ul>
|
||||
<li>{% trans -%}
|
||||
Signed news with strong signatures and trusted certificates
|
||||
{%- endtrans %}</li>
|
||||
<li>{% trans -%}
|
||||
Use su3 file format already used for updates, reseeding, and plugins
|
||||
{%- endtrans %}</li>
|
||||
<li>{% trans -%}
|
||||
Standard XML format for use with standard parsers
|
||||
{%- endtrans %}</li>
|
||||
<li>{% trans -%}
|
||||
Standard Atom format for use with standard feed readers and generators
|
||||
{%- endtrans %}</li>
|
||||
<li>{% trans -%}
|
||||
Sanitization and verification of HTML before displaying on console
|
||||
{%- endtrans %}</li>
|
||||
<li>{% trans -%}
|
||||
Suitable for easy implementation on Android and other platforms without an HTML console
|
||||
{%- endtrans %}</li>
|
||||
</ul>
|
||||
|
||||
<h4>{% trans %}Specification:{% endtrans %}</h4>
|
||||
|
||||
<p><b>SU3 Details:</b></p>
|
||||
<ul><li>
|
||||
SU3 Content Type: 4 (NEWS)
|
||||
</li><li>
|
||||
SU3 File Type: 1 (XML) or 3 (XML.GZ)
|
||||
</li><li>
|
||||
SU3 Version: Seconds since the epoch, in ASCII (date +%s)
|
||||
</li><li>
|
||||
File Format: XML or gzipped XML, containing an <a href="http://tools.ietf.org/html/rfc4287">RFC 4287 (Atom) XML Feed</a>.
|
||||
Charset must be UTF-8.
|
||||
</li></ul>
|
||||
|
||||
|
||||
<p><b>Atom <feed> Details:</b></p>
|
||||
The following <feed> elements are used:
|
||||
<ul><li>
|
||||
<entry> A news item. See below.
|
||||
</li><li>
|
||||
<i2p:release> I2P update metadata. See below.
|
||||
</li><li>
|
||||
<updated> Timestamp for the feed (conforming to
|
||||
<a href="http://tools.ietf.org/html/rfc4287">RFC 4287 (Atom) section 3.3</a> and
|
||||
<a href="http://tools.ietf.org/html/rfc3339">RFC 3339</a>. (required)
|
||||
</li></ul>
|
||||
|
||||
|
||||
<p><b>Atom <entry> Details:</b></p>
|
||||
Each Atom <entry> in the news feed may be parsed and displayed in the router console.
|
||||
The following elements are used:
|
||||
<ul><li>
|
||||
<author> (optional) containing:
|
||||
<ul><li>
|
||||
<name> The name of the entry author
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<content> Content, must be type="xhtml".
|
||||
The XHTML will be sanitized with a whitelist of allowed elements
|
||||
and a blacklist of disallowed attributes.
|
||||
Clients may ignore an element, or the enclosing entry, or the entire feed
|
||||
when a non-whitelisted element is encountered. (required)
|
||||
</li><li>
|
||||
<link> Link for further information (optional)
|
||||
</li><li>
|
||||
<summary> Short summary, suitable for a tooltip (optional)
|
||||
</li><li>
|
||||
<title> Title of the news entry (required)
|
||||
</li><li>
|
||||
<updated> Timestamp for this entry (conforming to
|
||||
<a href="http://tools.ietf.org/html/rfc4287">RFC 4287 (Atom) section 3.3</a> and
|
||||
<a href="http://tools.ietf.org/html/rfc3339">RFC 3339</a>. (required)
|
||||
</li></ul>
|
||||
|
||||
|
||||
<p><b>Atom <i2p:release> Details:</b></p>
|
||||
There must be at least one <i2p:release> entity in the feed. Each contains the following attributes and entities:
|
||||
<ul><li>
|
||||
date (attribute): Timestamp for this entry (conforming to
|
||||
<a href="http://tools.ietf.org/html/rfc4287">RFC 4287 (Atom) section 3.3</a> and
|
||||
<a href="http://tools.ietf.org/html/rfc3339">RFC 3339</a>. (required)
|
||||
The date also may be in truncated format yyyy-mm-dd (without the 'T'); this is the "full-date" format in RFC 3339.
|
||||
In this format the time is assumed to be 00:00:00 UTC for any processing.
|
||||
</li><li>
|
||||
minJavaVersion (attribute): If present, the minimum version of Java required to run the current version.
|
||||
</li><li>
|
||||
minVersion (attribute):
|
||||
If present, the minimum version of the router required to update to the current version.
|
||||
If a router is older than this, the user must (manually?) update to an intermediate version first.
|
||||
</li><li>
|
||||
<i2p:version> Required. The latest current router version available.
|
||||
</li><li>
|
||||
<i2p:update> An update file (one or more). It must contain at least one child.
|
||||
<ul><li>
|
||||
type (attribute): "sud", "su2", or "su3". Must be unique across all <i2p:update> elements.
|
||||
</li><li>
|
||||
<i2p:clearnet> Out-of-network direct download links (zero or more)
|
||||
<ul><li>
|
||||
href (attribute): a standard clearnet http link
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<i2p:clearnetssl> Out-of-network direct download links (zero or more)
|
||||
<ul><li>
|
||||
href (attribute): a standard clearnet https link
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<i2p:torrent> In-network magnet link
|
||||
<ul><li>
|
||||
href (attribute): a magnet link
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<i2p:url> In-network direct download links (zero or more)
|
||||
<ul><li>
|
||||
href (attribute): an in-network http .i2p link
|
||||
</li></ul>
|
||||
</li></ul>
|
||||
</li></ul>
|
||||
|
||||
|
||||
|
||||
<h3>{% trans %}Future Work{% endtrans %}</h3>
|
||||
<ul>
|
||||
<li>{% trans -%}
|
||||
The router update mechanism is part of the web router console.
|
||||
There is currently no provision for updates of an embedded router lacking the router console.
|
||||
{%- endtrans %}</li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
{% endblock %}
|
@@ -1,76 +0,0 @@
|
||||
!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
|
||||
!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
|
||||
!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/
|
||||
!_TAG_PROGRAM_NAME Exuberant Ctags //
|
||||
!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/
|
||||
!_TAG_PROGRAM_VERSION 5.9~svn20110310 //
|
||||
BandwidthLimits docs/spec/i2cp.html 588;" m
|
||||
Boolean docs/spec/common-structures.html 74;" t
|
||||
BuildRequestRecord docs/spec/i2np.html 183;" s
|
||||
BuildResponseRecord docs/spec/i2np.html 353;" s
|
||||
Certificate docs/spec/common-structures.html 296;" t
|
||||
CreateLeaseSet docs/spec/i2cp.html 630;" m
|
||||
CreateSession docs/spec/i2cp.html 668;" m
|
||||
Data docs/spec/i2np.html 1118;" m
|
||||
DatabaseLookup docs/spec/i2np.html 688;" m
|
||||
DatabaseSearchReply docs/spec/i2np.html 835;" m
|
||||
DatabaseStore docs/spec/i2np.html 590;" m
|
||||
Date docs/spec/common-structures.html 51;" t
|
||||
DeliveryInstructions docs/spec/common-structures.html 1010;" s
|
||||
DeliveryStatus docs/spec/i2np.html 910;" m
|
||||
DestLookup docs/spec/i2cp.html 697;" m
|
||||
DestReply docs/spec/i2cp.html 719;" m
|
||||
Destination docs/spec/common-structures.html 639;" s
|
||||
Disconnect docs/spec/i2cp.html 763;" m
|
||||
Garlic docs/spec/i2np.html 948;" m
|
||||
GarlicClove docs/spec/i2np.html 395;" s
|
||||
GarlicCloveDeliveryInstructions docs/spec/i2np.html 454;" s
|
||||
GetBandwidthLimits docs/spec/i2cp.html 783;" m
|
||||
GetDate docs/spec/i2cp.html 802;" m
|
||||
Hash docs/spec/common-structures.html 257;" t
|
||||
HostLookup docs/spec/i2cp.html 840;" m
|
||||
HostReply docs/spec/i2cp.html 889;" m
|
||||
I2CPMessageHeader docs/spec/i2cp.html 302;" s
|
||||
I2NPMessageHeader docs/spec/i2np.html 93;" s
|
||||
Integer docs/spec/common-structures.html 41;" t
|
||||
KeysAndCert docs/spec/common-structures.html 549;" s
|
||||
Lease docs/spec/common-structures.html 668;" s
|
||||
LeaseSet docs/spec/common-structures.html 713;" s
|
||||
Mapping docs/spec/common-structures.html 461;" t
|
||||
MessageId docs/spec/i2cp.html 324;" s
|
||||
MessagePayload docs/spec/i2cp.html 921;" m
|
||||
MessageStatus docs/spec/i2cp.html 943;" m
|
||||
Payload docs/spec/i2cp.html 344;" s
|
||||
PrivateKey docs/spec/common-structures.html 102;" t
|
||||
PublicKey docs/spec/common-structures.html 89;" t
|
||||
ReceiveMessageBegin docs/spec/i2cp.html 1048;" m
|
||||
ReceiveMessageEnd docs/spec/i2cp.html 1077;" m
|
||||
ReconfigureSession docs/spec/i2cp.html 1103;" m
|
||||
ReportAbuse docs/spec/i2cp.html 1133;" m
|
||||
RequestLeaseSet docs/spec/i2cp.html 1164;" m
|
||||
RequestVariableLeaseSet docs/spec/i2cp.html 1197;" m
|
||||
RouterAddress docs/spec/common-structures.html 843;" s
|
||||
RouterIdentity docs/spec/common-structures.html 613;" s
|
||||
RouterInfo docs/spec/common-structures.html 910;" s
|
||||
SendMessage docs/spec/i2cp.html 1225;" m
|
||||
SendMessageExpires docs/spec/i2cp.html 1272;" m
|
||||
SessionConfig docs/spec/i2cp.html 366;" s
|
||||
SessionId docs/spec/i2cp.html 398;" s
|
||||
SessionKey docs/spec/common-structures.html 115;" t
|
||||
SessionStatus docs/spec/i2cp.html 1403;" m
|
||||
SessionTag docs/spec/common-structures.html 269;" t
|
||||
SetDate docs/spec/i2cp.html 1437;" m
|
||||
Signature docs/spec/common-structures.html 214;" t
|
||||
SigningPrivateKey docs/spec/common-structures.html 171;" t
|
||||
SigningPublicKey docs/spec/common-structures.html 128;" t
|
||||
String docs/spec/common-structures.html 62;" t
|
||||
Tunnel docs/spec/tunnel-message.html 34;" m
|
||||
TunnelBuild docs/spec/i2np.html 1144;" m
|
||||
TunnelBuildReply docs/spec/i2np.html 1177;" m
|
||||
TunnelData docs/spec/i2np.html 1044;" m
|
||||
TunnelGateway docs/spec/i2np.html 1084;" m
|
||||
TunnelId docs/spec/common-structures.html 281;" t
|
||||
TunnelMessageDeliveryInstructions docs/spec/tunnel-message.html 159;" s
|
||||
VariableTunnelBuild docs/spec/i2np.html 1190;" m
|
||||
VariableTunnelBuildReply docs/spec/i2np.html 1220;" m
|
||||
sampleDatagrams docs/spec/ssu.html 1062;" a
|
40
i2p2www/pages/spec/index.html
Normal file
40
i2p2www/pages/spec/index.html
Normal file
@@ -0,0 +1,40 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %}I2P Specification Documents{% endblock %}
|
||||
{% block content %}
|
||||
This page provides the specifications for various components of the I2P network
|
||||
and router software. These are living documents, and the specifications are
|
||||
updated as modifications are made to the network and software.
|
||||
|
||||
<ul><li>
|
||||
"Last updated" is the last date when the specification given within a document
|
||||
was altered in any way, except for changes to the "accurate for" information.
|
||||
</li><li>
|
||||
The "accurate for" column gives the version of the I2P network and reference
|
||||
Java implementation that the document is verified to be valid for. Because the
|
||||
documents are usually only updated when changes are made, the listed versions
|
||||
can sometimes be several releases behind. This does not mean that documents with
|
||||
old listed versions are necessarily inaccurate, but small differences may creep
|
||||
in during the course of development. Periodic reviews are conducted to update
|
||||
the "accurate for" information.
|
||||
</li></ul>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>Title</th>
|
||||
<th>Last updated</th>
|
||||
<th>Accurate for</th>
|
||||
<th>Link</th>
|
||||
</tr>
|
||||
{% for spec in specs %}
|
||||
<tr>
|
||||
<td>{{ spec.title }}</td>
|
||||
<td><time>{{ spec.lastupdated }}</time></td>
|
||||
<td>{{ spec.accuratefor }}</td>
|
||||
<td>
|
||||
<a href="{{ url_for('spec_show', name=spec.name) }}">HTML</a> |
|
||||
<a href="{{ url_for('spec_show_txt', name=spec.name) }}">TXT</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endblock %}
|
15
i2p2www/pages/spec/show.html
Normal file
15
i2p2www/pages/spec/show.html
Normal file
@@ -0,0 +1,15 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{%- from "global/macros" import render_categories with context -%}
|
||||
{% block title %}{{ title }}{% endblock %}
|
||||
{% block lastupdated %}{{ meta.lastupdated }}{% endblock %}
|
||||
{% block accuratefor %}{{ meta.accuratefor }}{% endblock %}
|
||||
{% block content_nav %}
|
||||
{% autoescape false %}
|
||||
{{ toc }}
|
||||
{% endautoescape %}
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
{% autoescape false %}
|
||||
{{ body }}
|
||||
{% endautoescape %}
|
||||
{% endblock %}
|
Reference in New Issue
Block a user