Bittorrent over I2P
There are several bittorrent clients and trackers on I2P. As I2P addressing uses a Destination instead of an IP and port, minor changes are required to tracker and client software for operation on I2P. These changes are specified below. Note carefully the guidelines for compatibility with older I2P clients and trackers.
This page specifies protocol details common to all clients and trackers. Specific clients and trackers may implement other unique features or protocols.
We welcome additional ports of client and tracker software to I2P.
Clients generally include a fake port=6881 parameter in the announce, for compatibility with older trackers. Trackers may ignore the port parameter, and should not require it.
The ip parameter is the base 64 of the client's Destination, using the I2P Base 64 alphabet [A-Z][a-z][0-9]-~. Destinations are 387+ bytes, so the Base 64 is 516+ bytes. Clients generally append ".i2p" to the Base 64 Destination for compatibility with older trackers. Trackers should not require an appended ".i2p".
Other parameters are the same as in standard bittorrent.
While all current Destinations for clients are exactly 387 bytes, a tracker should not presume that will always be so. A reasonable maximum to assume, for now, is 475 bytes. As the tracker must decode the Base64 to deliver compact responses (see below), the tracker should probably decode and reject bad Base64 when announced.
The default response type is non-compact. Clients may request a compact response with the parameter compact=1. A tracker may, but is not required to, return a compact response when requested.
Developers of new I2P clients are strongly encouraged to implemenent announces over their own tunnel rather than the HTTP client proxy at port 4444. Doing so is both more efficient and it allows destination enforcement by the tracker (see below).
There are no known I2P clients or trackers that currently support UDP announce/responses.
Non-Compact Tracker Responses
The non-compact response is just as in standard bittorrent, with an I2P "ip".
Trackers generally include a fake port key, or use the port from the announce, for compatibility with older clients. Clients must ignore the port parameter, and should not require it.
The value of the ip key is the base 64 of the client's Destination, as described above. Trackers generally append ".i2p" to the Base 64 Destination if it wasn't in the announce ip, for compatibility with older clients. Clients should not require an appended ".i2p" in the responses.
Other response keys and values are the same as in standard bittorrent.
Compact Tracker Responses
In the compact response, the value of the "peers" dictionary key is a single byte string, whose length is a multiple of 32 bytes. This string contains the concatenated 32-byte SHA-256 Hashes of the binary Destinations of the peers. This hash must be computed by the tracker, unless destination enforcement (see below) is used, in which case the hash delivered in the X-I2P-DestHash or X-I2P-DestB32 HTTP headers may be converted to binary and stored. The peers key may be absent, or the peers value may be zero-length.
While compact response support is optional for both clients and trackers, it is highly recommended as it reduces the nominal response size by over 90%.
Some, but not all, I2P bittorrent clients announce over their own tunnels. Trackers may choose to prevent spoofing by requiring this, and verifying the client's Destination using HTTP headers added by the I2PTunnel HTTP Server tunnel. The headers are X-I2P-DestHash, X-I2P-DestB64, and X-I2P-DestB32, which are different formats for the same information. These headers cannot be spoofed by the client. A tracker enforcing destinations need not require the ip announce parameter at all.
As several clients use the HTTP proxy instead of their own tunnel for announces, destination enforcement will prevent usage by those clients unless or until those clients are converted to announcing over their own tunnel.
Unfortunately, as the network grows, so will the amount of maliciousness, so we expect that all trackers will eventually enforce destinations. Both tracker and client developers should anticipate it.
Announce Host Names
Announce URL host names in torrent files generally follow the I2P naming standards. In addition to host names from address books and ".b32.i2p" Base 32 hostnames, the full Base 64 Destination (with [or without?] ".i2p" appended) should be supported. Non-open trackers should recognize their own host name in any of these formats.
To preserve anonymity, clients should generally ignore non-I2P announce URLs in torrent files.
Client-to-client connections use the standard protocol over TCP. There are no known I2P clients that currently support uTP communication.
I2P uses 387+ byte Destinations for addresses, as explained above.
If the client has only the hash of the destination (such as from a compact response or PEX), it must perform a lookup by encoding it with Base 32, appending ".b32.i2p", and querying the Naming Service, which will return the full Destination if available.
If the client has a peer's full Destination it received in a non-compact response, it should use it directly in the connection setup. Do not convert a Destination back to a Base 32 hash for lookup, this is quite inefficient.
To preserve anonymity, I2P bittorrent clients generally do not support non-I2P announces or peer connections. I2P HTTP outproxies often block announces. There are no known SOCKS outproxies supporting bittorrent traffic.
To prevent usage by non-I2P clients via an HTTP inproxy, I2P trackers often block accesses or announces that contain an X-Forwarded-For HTTP header. Trackers should reject standard network announces with IPv4 or IPv6 IPs, and not deliver them in responses.
I2P PEX is based on ut_pex. As there does not appear to be a formal specification of ut_pex available, it may be necessary to review the libtorrent source for assistance. It is an extension message, identified as "i2p_pex" in the extension handshake. It contains a bencoded dictionary with up to 3 keys, "added", "added.f", and "dropped". The added and dropped values are each a single byte string, whose length is a multiple of 32 bytes. These byte strings are the concatenated SHA-256 Hashes of the binary Destinations of the peers. This is the same format as the peers dictionary value in the i2p compact response format specified above. The added.f value, if present, is the same as in ut_pex.
DHT support is included in the i2psnark client as of version 0.9.2. Preliminary differences from BEP 5 are described below, and are subject to change. Contact the I2P developers if you wish to develop a client supporting DHT.
Unlike standard DHT, I2P DHT does not use a bit in the options handshake, or the PORT message. It is advertised with an extension message, identified as "i2p_dht" in the extension handshake. It contains a bencoded dictionary with two keys, "port" and "rport", both integers.
The UDP (datagram) port listed in the compact node info is used to receive repliable (signed) datagrams. This is used for queries, except for announces. We call this the "query port". This is the "port" value from the extension message. Queries use I2CP protocol number 17.
In addition to that UDP port, we use a second datagram port equal to the query port + 1. This is used to receive unsigned (raw) datagrams for replies, errors, and announces. This port provides increased efficiency since replies contain tokens sent in the query, and need not be signed. We call this the "response port". This is the "rport" value from the extension message. It must be 1 + the query port. Responses and announces use I2CP protocol number 18.
Compact peer info is 32 bytes (32 byte SHA256 Hash) instead of 4 byte IP + 2 byte port. There is no peer port. In a response, the "values" key is a list of strings, each containing a single compact peer info.
Compact node info is 54 bytes (20 byte SHA1 Hash + 32 byte SHA256 Hash + 2 byte port) instead of 20 byte SHA1 Hash + 4 byte IP + 2 byte port. In a response, the "nodes" key is a single byte string with concatenated compact node info.
Secure node ID requirement: To make various DHT attacks more difficult, the first 4 bytes of the Node ID must match the first 4 bytes of the destination Hash, and the next two bytes of the Node ID must match the next two bytes of the destination hash exclusive-ORed with the port.
In a torrent file, the trackerless torrent dictionary "nodes" key is TBD. It could be a list of 32 byte binary strings (SHA256 Hashes) instead of a list of lists containing a host string and a port integer. Alternatives: A single byte string with concatenated hashes, or a list of strings alone.
Datagram (UDP) Trackers
UDP tracker support in clients and trackers is not yet available. Preliminary differences from BEP 15 are described below, and are subject to change. Contact the I2P developers if you wish to develop a client or tracker supporting datagram announces.
A UDP tracker listens on two ports. The "query port" is the advertised port, and is used to receive repliable (signed) datagrams, for the connect request only. The "response port" is used to receive unsigned (raw) datagrams, and is the source port for all replies. The response port is arbitrary. A client sends and receives on a single port only. It receives only unsigned (raw) datagrams. Raw datagrams provides increased efficiency for replies since they contain tokens sent in the query, and need not be signed.
In the announce request, the 4-byte IP is replaced by a 32-byte hash, and the port is still present, although it may be ignored by the tracker. In the announce response, each 4-byte IP and 2-byte port is replaced by a 32-byte hash (compact peer info), and no port is present. The client sends the announce request and scrape request to the source port in the announce response packet. The connect request, connect response, scrape request, scrape response, and error response are the same as in BEP 15.
Source addresses in I2P cannot be spoofed, so it is possible to use a simplified protocol with 2 packets instead of 4, omitting the connect request and response. In this case, the announce request would be a repliable datagram sent to the tracker's query port, and the tracker would not require a response port. While this is more efficient, it would be more difficult to modify an existing tracker to support this mode. The URL for the 4-packet-mode tracker would use standard "udp://" prefix. The URL for a modified 2-packet-mode tracker would require a different prefix if both modes are supported in I2P.