Overview
The I2P Streaming Library provides reliable, in-order, and authenticated data delivery on top of I2P’s unreliable message layer — analogous to TCP over IP. It is used by nearly all interactive I2P applications such as web browsing, IRC, email, and file sharing.
It ensures reliable transmission, congestion control, retransmission, and flow control across I2P’s high-latency anonymous tunnels. Each stream is fully encrypted end-to-end between destinations.
Core Design Principles
The streaming library implements a one-phase connection setup, where SYN, ACK, and FIN flags may carry data payloads in the same message. This minimizes round-trips in high-latency environments — a small HTTP transaction can complete in a single round-trip.
Congestion control and retransmission are modeled after TCP but adapted for I2P’s environment. Window sizes are message-based, not byte-based, and tuned for tunnel latency and overhead. The protocol supports slow start, congestion avoidance, and exponential backoff similar to TCP’s AIMD algorithm.
Architecture
The streaming library operates between applications and the I2CP interface.
| Layer | Responsibility |
|---|---|
| Application | Standard I2PSocket and I2PServerSocket usage |
| Streaming Library | Connection setup, sequencing, retransmission, and flow control |
| I2CP | Tunnel creation, routing, and message handling |
| I2NP / Router Layer | Transport through tunnels |
Most users access it via I2PSocketManager, I2PTunnel, or SAMv3. The library transparently handles destination management, tunnel usage, and retransmissions.
Packet Format
+-----------------------------------------------+
| Send Stream ID (4B) | Receive Stream ID (4B) |
+-----------------------------------------------+
| Sequence Number (4B) | Ack Through (4B) |
+-----------------------------------------------+
| NACK Count (1B) | optional NACK list (4B each)
+-----------------------------------------------+
| Flags (1B) | Option Size (1B) | Options ... |
+-----------------------------------------------+
| Payload ... |
Header Details
- Stream IDs: 32-bit values uniquely identifying local and remote streams.
- Sequence Number: Starts at 0 for SYN, increments per message.
- Ack Through: Acknowledges all messages up to N, excluding those in the NACK list.
- Flags: Bitmask controlling state and behavior.
- Options: Variable-length list for RTT, MTU, and protocol negotiation.
Key Flags
| Flag | Purpose |
|---|---|
| SYN | Connection initiation |
| ACK | Acknowledge received packets |
| FIN | Graceful close |
| RST | Reset connection |
| FROM_INCLUDED | Sender’s destination included |
| SIGNATURE_INCLUDED | Message signed by sender |
| ECHO / ECHO_REPLY | Ping/Pong keepalive |
Flow Control and Reliability
Streaming uses message-based windowing, unlike TCP’s byte-based approach. The number of unacknowledged packets allowed in flight equals the current window size (default 128).
Mechanisms
- Congestion control: Slow start and AIMD-based avoidance.
- Choke/Unchoke: Flow control signaling based on buffer occupancy.
- Retransmission: RFC 6298-based RTO calculation with exponential backoff.
- Duplicate filtering: Ensures reliability over potentially reordered messages.
Typical configuration values:
| Parameter | Default | Description |
|---|---|---|
maxWindowSize | 128 | Max unacknowledged messages |
maxMessageSize | 1730 | Maximum payload bytes per message |
initialRTO | 9000 ms | Initial retransmission timeout |
inactivityTimeout | 90000 ms | Idle connection timeout |
connectTimeout | 300000 ms | Connection establishment timeout |
Connection Establishment
- Initiator sends a SYN (optionally with payload and FROM_INCLUDED).
- Responder replies with SYN+ACK (may include payload).
- Initiator sends final ACK confirming establishment.
Optional initial payloads allow data transmission before full handshake completion.
Implementation Details
Retransmission and Timeout
The retransmission algorithm follows RFC 6298.
- Initial RTO: 9s
- Min RTO: 100ms
- Max RTO: 45s
- Alpha: 0.125
- Beta: 0.25
Control Block Sharing
Recent connections to the same peer reuse previous RTT and window data for faster ramp-up, avoiding “cold start” latency. Control blocks expire after several minutes.
MTU and Fragmentation
- Default MTU: 1730 bytes (fits two I2NP messages).
- ECIES destinations: 1812 bytes (reduced overhead).
- Minimum supported MTU: 512 bytes.
Payload size excludes the 22-byte minimum streaming header.
Version History
| Router Version | Feature |
|---|---|
| 0.7.1 | Protocol numbers defined in I2CP |
| 0.9.11 | Variable-length signatures |
| 0.9.12 | ECDSA signature support |
| 0.9.15 | Ed25519 signature support |
| 0.9.18 | Ping/Pong payloads |
| 0.9.20 | FROM_INCLUDED not required in RESET |
| 0.9.36 | Protocol enforcement enabled by default |
| 0.9.39 | OFFLINE_SIGNATURE support |
| 0.9.58 | Bob’s hash added to NACK field in SYN |
| 2.10.0 | Post-Quantum hybrid encryption (experimental) |
Application-Level Usage
Java Example
Properties props = new Properties();
props.setProperty("i2p.streaming.maxWindowSize", "512");
I2PSocketManager mgr = I2PSocketManagerFactory.createManager(props);
I2PSocket socket = mgr.connect(destination);
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
SAMv3 and i2pd Support
- SAMv3: Provides STREAM and DATAGRAM modes for non-Java clients.
- i2pd: Exposes identical streaming parameters via configuration file options (e.g.
i2p.streaming.maxWindowSize,profile, etc).
Choosing Between Streaming and Datagrams
| Use Case | Recommended Transport | Reason |
|---|---|---|
| HTTP, IRC, Email | Streaming | Requires reliability |
| DNS | Repliable Datagram | Single request/response |
| Telemetry, Logging | Raw Datagram | Best-effort acceptable |
| P2P DHT | Datagram | High connection churn |
Security and Post-Quantum Future
Streaming sessions are end-to-end encrypted at the I2CP layer.
Post-quantum hybrid encryption (ML-KEM + X25519) is supported experimentally in 2.10.0 but disabled by default.