Overview
The I2P Streaming Library provides reliable, in-order, authenticated transport over I2P’s message layer, similar to TCP over IP.
It sits above the I2CP protocol and is used by nearly all interactive I2P applications, including HTTP proxies, IRC, BitTorrent, and email.
Core Characteristics
- One-phase connection setup using SYN, ACK, and FIN flags that can be bundled with payload data to reduce round-trips.
- Sliding-window congestion control, with slow start and congestion avoidance tuned for I2P’s high-latency environment.
- Packet compression (default 4KB compressed segments) balancing retransmission cost and fragmentation latency.
- Fully authenticated, encrypted, and reliable channel abstraction between I2P destinations.
This design enables small HTTP requests and responses to complete in a single round-trip.
A SYN packet may carry the request payload, while the responder’s SYN/ACK/FIN may contain the full response body.
API Basics
The Java streaming API mirrors standard Java socket programming:
I2PSocketManager mgr = I2PSocketManagerFactory.createManager(host, port, options);
I2PSocket socket = mgr.connect(destination);
I2PServerSocket server = mgr.getServerSocket();
I2PSocketManagerFactorynegotiates or reuses a router session via I2CP.- If no key is provided, a new destination is automatically generated.
- Developers can pass I2CP options (e.g., tunnel lengths, encryption types, or connection settings) through the
optionsmap. I2PSocketandI2PServerSocketmirror standard JavaSocketinterfaces, making migration straightforward.
Full Javadocs are available from the I2P router console or here.
Configuration and Tuning
You can pass configuration properties when creating a socket manager via:
I2PSocketManagerFactory.createManager(host, port, properties);
Key Options
| Option | Description | Default |
|---|---|---|
i2p.streaming.maxWindowSize | Maximum send window (bytes) | 128 KB |
i2p.streaming.initialRTO | Initial retransmission timeout | 9s |
i2p.streaming.inactivityTimeout | Timeout before connection close | 90s |
i2p.streaming.enforceProtocol | Enforce protocol ID (prevents confusion) | true |
i2p.streaming.congestionAlgorithm | Congestion control method | Default (AIMD TCP-like) |
i2p.streaming.disableRejectLogging | Disable logging rejected packets | false |
Behavior by Workload
| Workload | Recommended Settings |
|---|---|
| HTTP-like | Default parameters are ideal. |
| Bulk Transfer | Increase window size to 256 KB or 512 KB; lengthen timeouts. |
| Real-time Streaming | Lower tunnel length to 1-2 hops; adjust RTO downwards. |
Newer features since version 0.9.4 include reject log suppression, DSA list support (0.9.21), and mandatory protocol enforcement (0.9.36).
Routers since 2.10.0 include post-quantum hybrid encryption (ML-KEM + X25519) at the transport layer.
Protocol Details
Each stream is identified by a Stream ID. Packets carry control flags similar to TCP: SYNCHRONIZE, ACK, FIN, and RESET.
Packets may contain both data and control flags simultaneously, improving efficiency for short-lived connections.
Connection Lifecycle
- SYN sent — initiator includes optional data.
- SYN/ACK response — responder includes optional data.
- ACK finalization — establishes reliability and session state.
- FIN/RESET — used for orderly closure or abrupt termination.
Fragmentation and Reordering
Because I2P tunnels introduce latency and message reordering, the library buffers packets from unknown or early-arriving streams.
Buffered messages are stored until synchronization completes, ensuring complete, in-order delivery.
Protocol Enforcement
The option i2p.streaming.enforceProtocol=true (default since 0.9.36) ensures connections use the correct I2CP protocol number, preventing conflicts between multiple subsystems sharing one destination.
Interoperability and Best Practices
The streaming protocol coexists with the Datagram API, giving developers the choice between connection-oriented and connectionless transports.
| Use Case | Recommended Transport |
|---|---|
| Reliable, ordered data (HTTP, IRC, FTP) | Streaming |
| Connectionless or lossy data (DNS, telemetry) | Datagram |
Shared Clients
Applications can reuse existing tunnels by running as shared clients, allowing multiple services to share the same destination.
While this reduces overhead, it increases cross-service correlation risk—use with care.
Congestion Control
- The streaming layer continuously adapts to network latency and throughput via RTT-based feedback.
- Applications perform best when routers are contributing peers (participating tunnels enabled).
- TCP-like congestion control mechanisms prevent overloading slow peers and help balance bandwidth use across tunnels.
Latency Considerations
Because I2P adds several hundred milliseconds of base latency, applications should minimize round-trips.
Bundle data with connection setup where possible (e.g., HTTP requests in SYN).
Avoid designs relying on many small sequential exchanges.
Testing and Compatibility
- Always test against both Java I2P and i2pd to ensure full compatibility.
- Although the protocol is standardized, minor implementation differences may exist.
- Handle older routers gracefully—many peers still run pre-2.0 versions.
- Monitor connection stats using
I2PSocket.getOptions()andgetSession()to read RTT and retransmission metrics.
Performance depends heavily on tunnel configuration:
- Short tunnels (1–2 hops) → lower latency, reduced anonymity.
- Long tunnels (3+ hops) → higher anonymity, increased RTT.
Key Improvements (2.0.0–2.10.0)
| Feature | Introduced | Description |
|---|---|---|
| Persistent ACK Bundling | 2.0.0 | Optimized round-trip reduction for HTTP workloads. |
| Adaptive Window Scaling | 2.3.0 | Improved large file transfer stability. |
| Thread Pooling and Socket Reuse | 2.5.0 | Reduced per-connection overhead. |
| Protocol Enforcement Default | 0.9.36 | Ensures correct stream usage. |
| Hybrid ML-KEM Ratchet | 2.10.0 | Adds post-quantum hybrid encryption layer. |
| i2pd Streaming API Compatibility Fixes | 2.9.0 | Full parity with Java I2P library behavior. |
Summary
The I2P Streaming Library is the backbone of all reliable communication within I2P.
It ensures in-order, authenticated, encrypted message delivery and provides a near drop-in replacement for TCP in anonymous environments.
To achieve optimal performance:
- Minimize round-trips with SYN+payload bundling.
- Tune window and timeout parameters for your workload.
- Favor shorter tunnels for latency-sensitive applications.
- Use congestion-friendly designs to avoid overloading peers.