Copy proposal 163 to the spec

and add application guidelines.
Update size recommendations reflecting modern transport limitations.
This commit is contained in:
zzz
2025-04-16 08:46:44 -04:00
parent c22e5f1cda
commit 5242a5831c

View File

@ -3,8 +3,8 @@ Datagram Specification
======================
.. meta::
:category: Protocols
:lastupdated: February 2019
:accuratefor: 0.9.39
:lastupdated: 2025-04
:accuratefor: 0.9.66
.. contents::
@ -14,11 +14,122 @@ Overview
See [DATAGRAMS]_ for an overview of the Datagrams API.
The following types are defined. The standard protocol numbers
are listed, however any other protocol numbers may be used other than
the streaming protocol number (6), application-specific.
========= ======== ========== ============== ================== =====
Type Protocol Repliable? Authenticated? Replay Prevention? As Of
========= ======== ========== ============== ================== =====
Raw 18 no no no
Datagram1 17 yes yes no
Datagram2 19 yes yes yes 0.9.66
Datagram3 20 yes no no 0.9.66
========= ======== ========== ============== ================== =====
Support for Datagram2 and Datagram3 in various router and library implementations
is TBD. Check the documentation for those implementations.
Application Design
------------------
All uses of datagrams are application-specific.
As authenticated datagrams carry substantial overhead,
a typical application uses both authenticated and non-authenticated datagrams.
A typical design is to send single authenticated datagram
containing a token from the client to the server.
The server replies with an unauthenticated datagram containing the same token.
Any subsequent communication, before token timeout, uses raw datagrams.
Applications send and receive datagrams using protocol and port numbers
via the I2CP API [I2CP]_ or SAMv3 [SAMv3]_.
Datagrams are, of course, unreliable. Applications must design for unreliable
delivery. Within I2P, delivery is reliable hop-to-hop
if the next hop is reachable, as the NTCP2 and SSU2
transports provide reliablity. However, end-to-end delivery is
not reliable, as I2NP messages may be dropped within any hop due
to queue limits, expirations, timeouts, bandwidth limits,
or unreachable next-hops.
Datagram Size
-------------
The nominal size limit for I2NP messages, including datagrams, is 64 KB.
Garlic and tunnel message overhead reduce somewhat.
However, all I2NP messages must be fragmented into 1 KB tunnel messages.
The drop probability of a n KB I2NP message is the exponential function of
the drop probability of a single tunnel message, p ** n.
As fragmentation results in a burst of tunnel messages,
actual drop probability is much higher than the exponential
function would imply, due to queue limits and active queue management
(AQM, CoDel or similar) in router implementations.
Recommended typical max size to ensure reliable delivery is a few KB,
or at the most 10 KB.
With careful analysis of overhead sizes at all protocol layers (except transport),
developers should set a max payload size
that will fit precisely in one, two, or three tunnel messages.
This will maximize efficiency and reliability.
Overhead at various layers includes the gzip header,
I2NP header, garlic message header, garlic encryption,
tunnel message header, tunnel message fragmentation headers,
and others.
See streaming MTU calculations in Proposal 144 [Prop144]_
and ConnectionOptions.java in the Java I2P source for examples.
SAM Considerations
------------------
Applications send and receive datagrams using protocol and port numbers
via the I2CP API or SAM. Specifying protocol and port numbers
via SAM requires SAM v3.2 or higher.
Using both datagrams and streaming (UDP and TCP) on the same SAM session (tunnels)
requires SAM v3.3 or higher.
Using multiple datagram types on the same SAM session (tunnels)
requires SAM v3.3 or higher.
SAM v3.3 is only supported by the Java I2P router at this time.
SAM support for Datagram2 and Datagram3 in various router and library implementations
is TBD. Check the documentation for those implementations.
Note that sizes over a typical 1500 byte network MTU will prohibit
SAM applications from transporting unfragmented packets to/from
the SAM server, if the application and server are on separate computers.
Typically, this is not the case, they are both on localhost,
where the MTU is 65536 or higher.
If a SAM application is expected to be separated on a different
computer from the server, max payload for a repliable datagram is
slightly under 1 KB.
PQ Considerations
-----------------
If the MLDSA portion of the Post-Quantum proposal [Prop169]_ is implemented,
overhead will increase substantially.
The size of a destination + signature will increase from 391 + 64 = 455 bytes
to a minimum of 3739 for MLDSA44 and a maximum of 7226 for MLDSA87.
The practical effects of this are to be determined.
Datagram3, with authentication provided by the router, may be a solution.
.. _raw:
Non-Repliable Datagrams
=======================
Raw (Non-Repliable) Datagrams
=============================
Non-repliable datagrams have no 'from' address and are not authenticated. They
are also called "raw" datagrams. Strictly speaking, they are not "datagrams"
@ -27,6 +138,10 @@ However, SAM and the I2PTunnel classes support "raw datagrams".
The standard I2CP protocol number for raw datagrams is PROTO_DATAGRAM_RAW (18).
The format is not specified here, it is defined by the application.
For completeness, we include a picture of the format below.
Format
------
@ -37,22 +152,22 @@ Format
| payload...
+----+----+----+----+----//
length: 0 - unlimited (see notes)
length: 0 - about 64 KB (see notes)
{% endhighlight %}
Notes
-----
The practical length is limited by lower layers of protocols - the tunnel
message spec [TUNMSG]_ limits messages to about 61.2 KB and the transports
[TRANSPORT]_ currently limit messages to about 32 KB, although this may be
raised in the future.
The practical length is limited by both overhead at various layers and reliability.
.. _repliable:
Repliable Datagrams
===================
Datagram1 (Repliable)
=====================
Repliable datagrams contain a 'from' address and a signature. These add at
least 427 bytes of overhead.
@ -104,7 +219,7 @@ Format
The signature may be verified by the signing public key of $from
payload :: The data
Length: 0 to about 31.5 KB (see notes)
Length: 0 to about 63 KB (see notes)
Total length: Payload length + 427+
{% endhighlight %}
@ -112,9 +227,7 @@ Format
Notes
-----
* The practical length is limited by lower layers of protocols - the transports
[TRANSPORT]_ currently limit messages to about 32 KB, so the data length here
is limited to about 31.5 KB.
* The practical length is limited by both overhead at various layers and reliability.
* See important notes about the reliability of large datagrams [DATAGRAMS]_. For
best results, limit the payload to about 10 KB or less.
@ -125,12 +238,235 @@ Notes
for LS2 (proposal 123). A new protocol with flags must be defined for that.
.. _datagram2:
Datagram2
=========
The Datagram2 format is as specified in Proposal 163 [Prop163]_.
The I2CP protocol number for Datagram2 is 19.
Datagram2 is intended as a replacement for Datagram1.
It adds the following features to Datagram1:
- Replay prevention
- Offline signature support
- Flags and options fields for extensibility
Note that the signature calculation algorithm for Datagram2
is substantially different than for Datagram1.
Format
------
.. raw:: html
{% highlight lang='dataspec' -%}
+----+----+----+----+----+----+----+----+
| |
~ from ~
~ ~
| |
+----+----+----+----+----+----+----+----+
| flags | options (optional) |
+----+----+ +
~ ~
~ ~
+----+----+----+----+----+----+----+----+
| |
~ offline_signature (optional) ~
~ expires, sigtype, pubkey, offsig ~
| |
+----+----+----+----+----+----+----+----+
| |
~ payload ~
~ ~
| |
+----+----+----+----+----+----+----+----+
| |
~ signature ~
~ ~
| |
+----+----+----+----+----+----+----+----+
from :: a `Destination`
length: 387+ bytes
The originator and (unless offline signed) signer of the datagram
flags :: (2 bytes)
Bit order: 15 14 ... 3 2 1 0
Bits 3-0: Version: 0x02 (0 0 1 0)
Bit 4: If 0, no options; if 1, options mapping is included
Bit 5: If 0, no offline sig; if 1, offline signed
Bits 15-6: unused, set to 0 for compatibility with future uses
options :: (2+ bytes if present)
If flag indicates options are present, a `Mapping`
containing arbitrary text options
offline_signature ::
If flag indicates offline keys, the offline signature section,
as specified in the Common Structures Specification,
with the following 4 fields. Length: varies by online and offline
sig types, typically 102 bytes for Ed25519
This section can, and should, be generated offline.
expires :: Expires timestamp
(4 bytes, big endian, seconds since epoch, rolls over in 2106)
sigtype :: Transient sig type (2 bytes, big endian)
pubkey :: Transient signing public key (length as implied by sig type),
typically 32 bytes for Ed25519 sig type.
offsig :: a `Signature`
Signature of expires timestamp, transient sig type,
and public key, by the destination public key,
length: 40+ bytes, as implied by the Signature type, typically
64 bytes for Ed25519 sig type.
payload :: The data
Length: 0 to about 61 KB (see notes)
signature :: a `Signature`
Signature type must match the signing public key type of $from
(if no offline signature) or the transient sigtype
(if offline signed)
length: 40+ bytes, as implied by the Signature type, typically
64 bytes for Ed25519 sig type.
The `Signature` of the payload and other fields as specified below.
The signature is verified by the signing public key of $from
(if no offline signature) or the transient pubkey
(if offline signed)
{% endhighlight %}
Total length: minimum 433 + payload length;
typical length for X25519 senders and without offline signatures:
457 + payload length.
Note that the message will typically be compressed with gzip at the I2CP layer,
which will result in significant savings if the from destination is compressible.
Note: The offline signature format is the same as in the Common Structures spec [Common]_ and [Streaming]_.
Signatures
----------
The signature is over the following fields.
- Prelude: The 32-byte hash of the target destination (not included in the datagram)
- flags
- options (if present)
- offline_signature (if present)
- payload
In repliable datagram, for the DSA_SHA1 key type, the signature was over the
SHA-256 hash of the payload, not the payload itself; here, the signature is
always over the fields above (NOT the hash), regardless of key type.
ToHash Verification
-------------------
Receivers must verify the signature (using their destination hash)
and discard the datagram on failure, for replay prevention.
.. _datagram3:
Datagram3
=========
The Datagram3 format is as specified in Proposal 163 [Prop163]_.
The I2CP protocol number for Datagram3 is 20.
Datagram3 is intended as an enhanced version of raw datagrams.
It adds the following features to raw datagrams:
- Repliability
- Flags and options fields for extensibility
Datagram3 is NOT authenticated.
In a future proposal, authentication may be provided by
the router's ratchet layer, and authentication status
would be passed to the client.
Format
------
.. raw:: html
{% highlight lang='dataspec' -%}
+----+----+----+----+----+----+----+----+
| |
~ fromhash ~
~ ~
| |
+----+----+----+----+----+----+----+----+
| flags | options (optional) |
+----+----+ +
~ ~
~ ~
+----+----+----+----+----+----+----+----+
| |
~ payload ~
~ ~
| |
+----+----+----+----+----+----+----+----+
fromhash :: a `Hash`
length: 32 bytes
The originator of the datagram
flags :: (2 bytes)
Bit order: 15 14 ... 3 2 1 0
Bits 3-0: Version: 0x03 (0 0 1 1)
Bit 4: If 0, no options; if 1, options mapping is included
Bits 15-5: unused, set to 0 for compatibility with future uses
options :: (2+ bytes if present)
If flag indicates options are present, a `Mapping`
containing arbitrary text options
payload :: The data
Length: 0 to about 61 KB (see notes)
{% endhighlight %}
Total length: minimum 34 + payload length.
References
==========
.. [DATAGRAMS]
{{ site_url('docs/api/datagrams', True) }}
.. [I2CP]
{{ site_url('docs/protocol/i2cp', True) }}
.. [Prop144]
{{ proposal_url('144') }}
.. [Prop163]
{{ proposal_url('163') }}
.. [Prop169]
{{ proposal_url('163') }}
.. [SAMv3]
{{ site_url('docs/api/samv3') }}
.. [TRANSPORT]
{{ site_url('docs/transport', True) }}