2012-11-10 21:53:08 +00:00
{% extends "global/layout.html" %}
2010-08-22 02:18:28 +00:00
{% block title %}Streaming Library{% endblock %}
2012-12-14 03:41:29 +00:00
{% block lastupdated %}November 2012{% endblock %}
{% block accuratefor %}0.9.3{% endblock %}
2008-02-10 14:17:56 +00:00
{% block content %}
< h2 > Overview< / h2 >
< p >
The streaming library is technically part of the "application" layer,
as it is not a core router function.
In practice, however, it provides a vital function for almost all
existing I2P applications, by providing a TCP-like
2010-03-21 19:41:10 +00:00
streams over I2P, and allowing existing apps to be easily ported to I2P.
2010-08-22 02:18:28 +00:00
The other end-to-end transport library for client communication is the
< a href = "datagrams.html" > datagram library< / a > .
2008-02-10 14:17:56 +00:00
< / p >
< p > The streaming library is a layer on top of the core
2010-08-22 02:18:28 +00:00
< a href = "i2cp.html" > I2CP API< / a > that allows reliable, in-order, and authenticated streams
2008-02-10 14:17:56 +00:00
of messages to operate across an unreliable, unordered, and unauthenticated
message layer. Just like the TCP to IP relationship, this streaming
functionality has a whole series of tradeoffs and optimizations available, but
rather than embed that functionality into the base I2P code, it has been factored
2008-02-10 22:43:33 +00:00
off into its own library both to keep the TCP-esque complexities separate and to
2010-03-21 19:41:10 +00:00
allow alternative optimized implementations.< / p >
2008-02-10 14:17:56 +00:00
< p >
2010-08-22 02:18:28 +00:00
In consideration of the relatively high cost of messages,
the streaming library's protocol for scheduling and delivering those messages has been optimized to
2008-02-10 14:17:56 +00:00
allow individual messages passed to contain as much information as is available.
For instance, a small HTTP transaction proxied through the streaming library can
2008-11-15 16:12:21 +00:00
be completed in a single round trip - the first messages bundle a SYN, FIN, and
the small HTTP request payload, and the reply bundles the SYN,
FIN, ACK, and the HTTP response payload. While an additional
2008-02-10 14:17:56 +00:00
ACK must be transmitted to tell the HTTP server that the SYN/FIN/ACK has been
2008-11-15 16:12:21 +00:00
received, the local HTTP proxy can often deliver the full response to the browser
2008-02-10 14:17:56 +00:00
immediately.
< / p >
< p >
2010-08-22 02:18:28 +00:00
The streaming library bears much resemblance to an
2008-02-10 14:17:56 +00:00
abstraction of TCP, with its sliding windows, congestion control algorithms
(both slow start and congestion avoidance), and general packet behavior (ACK,
SYN, FIN, RST, rto calculation, etc).
< / p >
< p >
2010-08-22 02:18:28 +00:00
The streaming library is
a robust library
which is optimized for operation over I2P.
It has a one-phase setup, and
it contains a full windowing implementation.
2008-02-10 14:17:56 +00:00
< / p >
2010-08-22 02:18:28 +00:00
< h2 id = "api" > API< / h2 >
2008-02-10 14:17:56 +00:00
< p >
2010-08-22 02:18:28 +00:00
The streaming library API provides a standard socket paradigm to Java applications.
The lower-level
< a href = "i2cp.html" > I2CP< / a >
API is completely hidden, except that applications may pass
< a href = "i2cp.html#options" > I2CP parameters< / a > through the streaming library,
to be interpreted by I2CP.
2008-02-10 14:17:56 +00:00
< / p >
2010-08-22 02:18:28 +00:00
< p >
The standard interface to the streaming lib is for the application to use the
2011-06-26 19:09:30 +00:00
< a href = "http://docs.i2p-projekt.de/javadoc/net/i2p/client/streaming/I2PSocketManagerFactory.html" > I2PSocketManagerFactory< / a >
2010-08-22 02:18:28 +00:00
to create an
2011-06-26 19:09:30 +00:00
< a href = "http://docs.i2p-projekt.de/javadoc/net/i2p/client/streaming/I2PSocketManager.html" > I2PSocketManager< / a > .
2010-08-22 02:18:28 +00:00
The application then asks the socket manager for an
2011-06-26 19:09:30 +00:00
< a href = "http://docs.i2p-projekt.de/javadoc/net/i2p/client/streaming/I2PSession.html" > I2PSession< / a > ,
2010-08-22 02:18:28 +00:00
which will cause a connection to the router via
< a href = "i2cp.html" > I2CP< / a > .
The application can then setup connections with an
2011-06-26 19:09:30 +00:00
< a href = "http://docs.i2p-projekt.de/javadoc/net/i2p/client/streaming/I2PSocket.html" > I2PSocket< / a >
2010-08-22 02:18:28 +00:00
or receive connections with an
2011-06-26 19:09:30 +00:00
< a href = "http://docs.i2p-projekt.de/javadoc/net/i2p/client/streaming/I2PServerSocket.html" > I2PServerSocket< / a > .
2010-08-22 02:18:28 +00:00
< / p >
< p >
Here are the
2011-06-26 19:09:30 +00:00
< a href = "http://docs.i2p-projekt.de/javadoc/net/i2p/client/streaming/package-summary.html" > full streaming library Javadocs< / a > .
2008-02-10 14:17:56 +00:00
< / p >
< p >
2010-08-22 02:18:28 +00:00
For a good example of usage, see the i2psnark code.
< / p >
2009-11-07 23:23:29 +00:00
2010-08-22 02:18:28 +00:00
2010-08-28 22:30:59 +00:00
< h3 id = "options" > Options and Defaults< / h3 >
2010-08-22 02:18:28 +00:00
< p >
2010-08-28 22:30:59 +00:00
The options and current default values are listed below.
Options are case-sensitive and may be set for the whole router, for a particular client, or for an individual socket on a
2008-11-15 16:12:21 +00:00
per-connection basis.
2010-08-28 22:30:59 +00:00
Many values are tuned for HTTP performance over typical I2P conditions. Other applications such
2008-02-10 14:17:56 +00:00
as peer-to-peer services are strongly encouraged to
modify as necessary, by setting the options and passing them via the call to
2011-06-26 19:09:30 +00:00
< a href = "http://docs.i2p-projekt.de/javadoc/net/i2p/client/streaming/I2PSocketManagerFactory.html" > I2PSocketManagerFactory< / a > .createManager(_i2cpHost, _i2cpPort, opts).
2008-02-10 14:17:56 +00:00
Time values are in ms.
< / p >
2008-03-25 21:56:26 +00:00
< p >
2010-08-22 02:18:28 +00:00
Note that higher-layer APIs, such as
2012-11-10 21:53:08 +00:00
< a href = "{{ site_url('docs/api/samv3') }}" > SAM< / a > ,
< a href = "{{ site_url('docs/api/bob') }}" > BOB< / a > , and
< a href = "{{ site_url('docs/api/i2ptunnel') }}" > I2PTunnel< / a > ,
2010-08-22 02:18:28 +00:00
may override these defaults with their own defaults.
2010-08-28 22:30:59 +00:00
Also note that many options only apply to servers listening for incoming connections.
2012-09-28 18:07:46 +00:00
< / p > < p >
As of release 0.9.1, most, but not all, options may be changed on an active socket manager or session.
See the javadocs for details.
2008-03-25 21:56:26 +00:00
< / p >
2008-11-15 16:12:21 +00:00
2010-08-22 02:18:28 +00:00
< table >
2010-08-28 22:30:59 +00:00
< tr > < th > Option< / th > < th > Default< / th > < th > Notes< / th >
< / tr >
< tr > < td > i2cp.accessList< / td > < td > null< / td > < td > Comma- or space-separated list of Base64 peer Hashes used for either access list or blacklist
2012-06-19 20:27:54 +00:00
As of release 0.7.13.
2010-08-28 22:30:59 +00:00
< / td > < / tr > < tr > < td > i2cp.enableAccessList< / td > < td > false
< / td > < td > Use the access list as a whitelist for incoming connections
2012-06-19 20:27:54 +00:00
As of release 0.7.13.
2010-08-28 22:30:59 +00:00
< / td > < / tr > < tr > < td > i2cp.enableBlackList< / td > < td > false
< / td > < td > Use the access list as a blacklist for incoming connections
2012-06-19 20:27:54 +00:00
As of release 0.7.13.
2010-08-28 22:30:59 +00:00
< / td > < / tr > < tr > < td > i2p.streaming.answerPings< / td > < td > true< / td > < td > Whether to respond to incoming pings
2012-09-28 18:07:46 +00:00
< / td > < / tr > < tr > < td > i2p.streaming.blacklist< / td > < td > null< / td > < td > Comma- or space-separated list of Base64 peer Hashes to be
blacklisted for incoming connections to ALL destinations in the context.
This option must be set in the context properties, NOT in the createManager() options argument.
Note that setting this in the router context will not affect clients outside the
router in a separate JVM and context.
As of release 0.9.3.
2010-10-06 17:13:55 +00:00
< / td > < / tr > < tr > < td > i2p.streaming.bufferSize< / td > < td > 64K< / td > < td >
How much transmit data (in bytes) will be accepted that hasn't been written out yet.
2010-08-22 02:18:28 +00:00
< / td > < / tr > < tr > < td > i2p.streaming.congestionAvoidanceGrowthRateFactor< / td > < td > 1
2010-08-28 22:30:59 +00:00
< / td > < td >
When we're in congestion avoidance, we grow the window size at the rate
of 1/(windowSize*factor). In standard TCP, window sizes are in bytes,
while in I2P, window sizes are in messages.
A higher number means slower growth.
< / td > < / tr > < tr > < td > i2p.streaming.connectDelay< / td > < td > -1
< / td > < td >
How long to wait after instantiating a new con
before actually attempting to connect. If this is
< = 0, connect immediately with no initial data. If greater than 0, wait
until the output stream is flushed, the buffer fills,
or that many milliseconds pass, and include any initial data with the SYN.
2010-10-06 17:13:55 +00:00
< / td > < / tr > < tr > < td > i2p.streaming.connectTimeout< / td > < td > 5*60*1000< / td > < td >
How long to block on connect, in milliseconds. Negative means indefinitely. Default is 5 minutes.
2012-11-02 16:38:15 +00:00
< / td > < / tr > < tr > < td > i2p.streaming.disableRejectLogging< / td > < td > false< / td > < td >
Whether to disable warnings in the logs when an incoming connection is rejected due to connection limits.
As of release 0.9.4.
2012-06-19 20:27:54 +00:00
< / td > < / tr > < tr > < td > i2p.streaming.enforceProtocol< / td > < td > false< / td > < td > Whether to listen only for the streaming protocol.
Setting to true will prohibit communication with Destinations earlier than release 0.7.1
(released March 2009). Set to true if running multiple protocols on this Destination.
As of release 0.9.1.
2010-08-28 22:30:59 +00:00
< / td > < / tr > < tr > < td > i2p.streaming.inactivityAction< / td > < td > 2 (send) < / td > < td > (0=noop, 1=disconnect)
What to do on an inactivity timeout - do nothing, disconnect, or send a duplicate ack.
< / td > < / tr > < tr > < td > i2p.streaming.inactivityTimeout< / td > < td > 90*1000
< / td > < / tr > < tr > < td > i2p.streaming.initialAckDelay< / td > < td > 2000
< / td > < / tr > < tr > < td > i2p.streaming.initialResendDelay< / td > < td > 1000
< / td > < td >
The initial value of the resend delay field in the packet header, times 1000.
Not fully implemented; see below.
< / td > < / tr > < tr > < td > i2p.streaming.initialRTT< / td > < td > 8000 < / td > < td > (if no < a href = "#sharing" > sharing data< / a > available)
< / td > < / tr > < tr > < td > i2p.streaming.initialWindowSize< / td > < td > 6< / td > < td > (if no < a href = "#sharing" > sharing data< / a > available)
In standard TCP, window sizes are in bytes, while in I2P, window sizes are in messages.
< / td > < / tr > < tr > < td > i2p.streaming.maxConcurrentStreams< / td > < td > -1 < / td > < td > (0 or negative value means unlimited)
This is a total limit for incoming and outgoing combined.
< / td > < / tr > < tr > < td > i2p.streaming.maxConnsPerMinute< / td > < td > 0 < / td > < td > Incoming connection limit (per peer; 0 means disabled)
2012-06-19 20:27:54 +00:00
As of release 0.7.14.
2010-08-28 22:30:59 +00:00
< / td > < / tr > < tr > < td > i2p.streaming.maxConnsPerHour< / td > < td > 0 < / td > < td > (per peer; 0 means disabled)
2012-06-19 20:27:54 +00:00
As of release 0.7.14.
2010-08-28 22:30:59 +00:00
< / td > < / tr > < tr > < td > i2p.streaming.maxConnsPerDay< / td > < td > 0 < / td > < td > (per peer; 0 means disabled)
2012-06-19 20:27:54 +00:00
As of release 0.7.14.
2010-08-28 22:30:59 +00:00
< / td > < / tr > < tr > < td > i2p.streaming.maxMessageSize< / td > < td > 1730< / td > < td > The MTU in bytes.
< / td > < / tr > < tr > < td > i2p.streaming.maxResends< / td > < td > 8
< / td > < td >
Maximum number of retransmissions before failure.
< / td > < / tr > < tr > < td > i2p.streaming.maxTotalConnsPerMinute< / td > < td > 0 < / td > < td > Incoming connection limit (all peers; 0 means disabled)
2012-06-19 20:27:54 +00:00
As of release 0.7.14.
2010-08-28 22:30:59 +00:00
< / td > < / tr > < tr > < td > i2p.streaming.maxTotalConnsPerHour< / td > < td > 0 < / td > < td > (all peers; 0 means disabled)
Use with caution as exceeding this will disable a server for a long time.
2012-06-19 20:27:54 +00:00
As of release 0.7.14.
2010-08-28 22:30:59 +00:00
< / td > < / tr > < tr > < td > i2p.streaming.maxTotalConnsPerDay< / td > < td > 0 < / td > < td > (all peers; 0 means disabled)
Use with caution as exceeding this will disable a server for a long time.
2012-06-19 20:27:54 +00:00
As of release 0.7.14.
2010-08-28 22:30:59 +00:00
< / td > < / tr > < tr > < td > i2p.streaming.maxWindowSize< / td > < td > 128
< / td > < / tr > < tr > < td > i2p.streaming.profile< / td > < td > 1 (bulk)< / td > < td > (2=interactive not supported)
This doesn't currently do anything, but setting it to a value other than 1 will cause an error.
2010-10-06 17:13:55 +00:00
< / td > < / tr > < tr > < td > i2p.streaming.readTimeout< / td > < td > -1
< / td > < td >
How long to block on read, in milliseconds. Negative means indefinitely.
2010-08-22 02:18:28 +00:00
< / td > < / tr > < tr > < td > i2p.streaming.slowStartGrowthRateFactor< / td > < td > 1
2010-08-28 22:30:59 +00:00
< / td > < td >
When we're in slow start, we grow the window size at the rate
of 1/(factor). In standard TCP, window sizes are in bytes,
while in I2P, window sizes are in messages.
A higher number means slower growth.
2010-10-06 17:13:55 +00:00
< / td > < / tr > < tr > < td > i2p.streaming.writeTimeout< / td > < td > -1
< / td > < td >
How long to block on write/flush, in milliseconds. Negative means indefinitely.
2010-08-22 02:18:28 +00:00
< / td > < / tr >
< / table >
2008-02-10 14:17:56 +00:00
2008-03-25 21:56:26 +00:00
2010-08-22 02:18:28 +00:00
< h2 > Protocol Specification< / h2 >
< h3 > Packet Format< / h3 >
2008-03-25 21:56:26 +00:00
< p >
2010-08-28 22:30:59 +00:00
The format of a single packet in the streaming protocol is:
< pre >
+----+----+----+----+----+----+----+----+
| send Stream ID | rcv Stream ID |
+----+----+----+----+----+----+----+----+
| sequence Num | ack Through |
+----+----+----+----+----+----+----+----+
| nc | NACKs ...
+----+----+----+----+----+----+----+----+
| rd | flags | opt size| opt data
+----+----+----+----+----+----+----+----+
... |
+----+----+----+----+----+----+----+----+
| payload ...
+----+----+----+----//
< / pre >
2009-11-07 23:23:29 +00:00
< table >
< tr > < th > Field< th > Length< th > Contents
2010-08-22 02:18:28 +00:00
< tr > < td > sendStreamId < td > 4 byte < a href = "common_structures_spec.html#type_Integer" > Integer< / a > < td > Random number selected by the connection recipient
2009-11-07 23:23:29 +00:00
and constant for the life of the connection.
2010-08-22 02:18:28 +00:00
0 in the SYN message sent by the originator, and in subsequent messages, until a SYN reply is received,
2010-10-16 13:57:58 +00:00
containing the peer's stream ID.
2010-08-22 02:18:28 +00:00
< tr > < td > receiveStreamId < td > 4 byte < a href = "common_structures_spec.html#type_Integer" > Integer< / a > < td > Random number selected by the connection originator
and constant for the life of the connection. May be 0 if unknown, for example in a RESET packet.
2009-11-07 23:23:29 +00:00
2010-08-22 02:18:28 +00:00
< tr > < td > sequenceNum < td > 4 byte < a href = "common_structures_spec.html#type_Integer" > Integer< / a > < td >
2009-11-07 23:23:29 +00:00
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.
2010-08-22 02:18:28 +00:00
If the sequenceNum is 0 and the SYN flag is not set, this is a plain ACK
2009-11-07 23:23:29 +00:00
packet that should not be ACKed.
2010-08-22 02:18:28 +00:00
< tr > < td > ackThrough < td > 4 byte < a href = "common_structures_spec.html#type_Integer" > Integer< / a > < td >
2009-11-07 23:23:29 +00:00
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
2010-08-22 02:18:28 +00:00
if the NO_ACK flag set.
2010-03-21 19:41:10 +00:00
All packets up to and including this sequence number are ACKed,
2009-11-07 23:23:29 +00:00
EXCEPT for those listed in NACKs below.
2010-08-22 02:18:28 +00:00
< tr > < td > NACK count< td > 1 byte < a href = "common_structures_spec.html#type_Integer" > Integer< / a > < td >
The number of 4-byte NACKs in the next field
2009-11-07 23:23:29 +00:00
2010-08-22 02:18:28 +00:00
< tr > < td > NACKs < td > n * 4 byte < a href = "common_structures_spec.html#type_Integer" > Integers< / a > < td >
2009-11-07 23:23:29 +00:00
Sequence numbers less than ackThrough that are not yet received.
2009-11-08 03:36:54 +00:00
Two NACKs of a packet is a request for a 'fast retransmit' of that packet.
2009-11-07 23:23:29 +00:00
2010-08-22 02:18:28 +00:00
< tr > < td > resendDelay< td > 1 byte < a href = "common_structures_spec.html#type_Integer" > Integer< / a > < td >
2009-11-07 23:23:29 +00:00
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.
2010-08-22 02:18:28 +00:00
Currently ignored on receive.
2009-11-07 23:23:29 +00:00
< tr > < td > flags < td > 2 byte value< td >
See below.
2010-08-22 02:18:28 +00:00
< tr > < td > option size< td > 2 byte < a href = "common_structures_spec.html#type_Integer" > Integer< / a > < td >
The number of bytes in the next field
2009-11-07 23:23:29 +00:00
2010-08-22 02:18:28 +00:00
< tr > < td > option data< td > 0 or more bytes< td >
As specified by the flags. See below.
2009-11-07 23:23:29 +00:00
< tr > < td > payload < td > remaining packet size< td >
< / table >
2008-03-25 21:56:26 +00:00
2010-08-28 22:30:59 +00:00
< h3 > Flags and Option Data Fields< / h3 >
2008-03-25 21:56:26 +00:00
< p > The flags field above specifies some metadata about the packet, and in
turn may require certain additional data to be included. The flags are
2010-08-22 02:18:28 +00:00
as follows. Any data structures specified must be added to the options area
in the given order.< / p >
< p >
Bit order: 15....0 (15 is MSB)
< / p >
2009-11-07 23:23:29 +00:00
< table >
2010-08-22 02:18:28 +00:00
< tr > < th > Bit< th > Flag< th > Option Data< th > Function
< tr > < td > 0< td > SYNCHRONIZE< td align = "center" > --< td >
2010-10-16 13:57:58 +00:00
Similar to TCP SYN. Set in the initial packet and in the first response.
2012-09-28 18:07:46 +00:00
FROM_INCLUDED and SIGNATURE_INCLUDED must be set also.
2010-08-22 02:18:28 +00:00
< tr > < td > 1< td > CLOSE< 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.
2012-09-28 18:07:46 +00:00
SIGNATURE_INCLUDED must be set also.
2010-08-22 02:18:28 +00:00
< tr > < td > 2< td > RESET< td align = "center" > --< td >
2009-11-07 23:23:29 +00:00
Abnormal close.
2012-09-28 18:07:46 +00:00
SIGNATURE_INCLUDED must be set also.
2010-08-22 02:18:28 +00:00
< tr > < td > 3< td > SIGNATURE_INCLUDED< td > 40 byte < a href = "common_structures_spec.html#type_Signature" > DSA Signature< / a >
< td >
2012-09-28 18:07:46 +00:00
Currently sent only with SYNCHRONIZE, CLOSE, and RESET, where it is required.
2010-08-22 02:18:28 +00:00
The signature uses the Destination's < a href = "common_structures_spec.html#type_SigningPublicKey" > DSA signing keys< / a >
to sign the entire header and payload with the 40-byte space in the option data field
2009-11-07 23:23:29 +00:00
for the signature being set to all zeroes.
2010-08-22 02:18:28 +00:00
< tr > < td > 4< td > SIGNATURE_REQUESTED< td align = "center" > --< td >
Unused. Requests every packet in the other direction to have SIGNATURE_INCLUDED
< tr > < td > 5< td > FROM_INCLUDED< td > 387+ byte < a href = "common_structures_spec.html#struct_Destination" > Destination< / a >
< td >
Currently sent only with SYNCHRONIZE, where it is required.
< tr > < td > 6< td > DELAY_REQUESTED< td > 2 byte < a href = "common_structures_spec.html#type_Integer" > Integer< / a > < td >
2009-11-07 23:23:29 +00:00
Optional delay.
How many milliseconds the sender of this packet wants the recipient
2009-11-08 03:36:54 +00:00
to wait before sending any more data.
A value greater than 60000 indicates choking.
2010-08-22 02:18:28 +00:00
< tr > < td > 7< td > MAX_PACKET_SIZE_INCLUDED< td > 2 byte < a href = "common_structures_spec.html#type_Integer" > Integer< / a > < td >
2012-06-29 18:15:43 +00:00
Currently sent with SYNCHRONIZE only.
Was also sent in retransmitted packets until release 0.9.1.
2010-08-22 02:18:28 +00:00
< tr > < td > 8< td > PROFILE_INTERACTIVE< td align = "center" > --< td >
Unused or ignored; the interactive profile is unimplemented.
< tr > < td > 9< td > ECHO< td align = "center" > --< td >
2009-11-07 23:23:29 +00:00
Unused except by ping programs
2010-08-22 02:18:28 +00:00
< tr > < td > 10< td > NO_ACK< td align = "center" > --< td >
2009-11-07 23:23:29 +00:00
This flag simply tells the recipient to ignore the ackThrough field in the header.
2010-08-22 02:18:28 +00:00
Currently unused, the ackThrough field is always valid.
2009-11-07 23:23:29 +00:00
< tr > < td > 11-15< td > unused< td > < td >
< / table >
2010-08-22 02:18:28 +00:00
< h2 > Implementation Details< / h2 >
2008-03-25 21:56:26 +00:00
2010-08-22 02:18:28 +00:00
< h3 > Setup< / h3 >
< p >
The initiator sends a packet with the SYNCHRONIZE flag set. This packet may contain the initial data as well.
The peer replies with a packet with the SYNCHRONIZE flag set. This packet may contain the initial response data as well.
< / p >
< p >
The initiator may send additional data packets, up to the initial window size, before receiving the SYNCHRONIZE response.
These packets will also have the send Stream ID field set to 0.
Recipients must buffer packets received on unknown streams for a short period of time, as they may
arrive out of order, in advance of the SYNCHRONIZE packet.
< / p >
2008-03-25 21:56:26 +00:00
2010-08-22 02:18:28 +00:00
< h3 > MTU Selection and Negotiation< / h3 >
< p >
The maximum message size (also called the MTU / MRU) is negotiated to the lower value supported by
the two peers. As tunnel messages are padded to 1KB, a poor MTU selection will lead to
a large amount of overhead.
The MTU is specified by the option i2p.streaming.maxMessageSize.
The current default MTU of 1730 was chosen to fit precisely into two 1K I2NP tunnel messages,
including overhead for the typical case.
< / p >
2009-03-01 05:05:18 +00:00
< p >
2010-08-22 02:18:28 +00:00
The first message in a connection includes a 387 byte (typical) Destination added by the streaming layer,
2010-08-28 22:30:59 +00:00
and usually a 898 byte (typical) LeaseSet, and Session keys, bundled in the Garlic message by the router.
(The LeaseSet and Session Keys will not be bundled if an ElGamal Session was previously established).
Therefore, the goal of fitting a complete HTTP request in a single 1KB I2NP message is not always attainable.
2010-08-22 02:18:28 +00:00
However, the selection of the MTU, together with careful implementation of fragmentation
and batching strategies in the tunnel gateway processor, are important factors in network bandwidth,
latency, reliability, and efficiency, especially for long-lived connections.
< / p >
< h3 > Data Integrity< / h3 >
Data integrity is assured by the gzip CRC-32 checksum implemented in
< a href = "i2cp.html#format" > the I2CP layer< / a > .
There is no checksum field in the streaming protocol.
2010-08-28 22:30:59 +00:00
< h3 > Packet Encapsulation< / h3 >
Each packet is sent through I2P as a single message (or as an individual clove in a
2012-11-10 21:53:08 +00:00
< a href = "{{ site_url('docs/how/garlicrouting') }}" > Garlic Message< / a > ).
2010-08-28 22:30:59 +00:00
Message encapsulation is implemented in the underlying
< a href = "i2cp.html" > I2CP< / a > ,
< a href = "i2np.html" > I2NP< / a > , and
2010-10-15 01:43:50 +00:00
< a href = "tunnel_message_spec.html" > tunnel message< / a > layers.
2010-08-28 22:30:59 +00:00
There is no packet delimiter mechanism or payload length field in the streaming protocol.
2010-08-22 02:18:28 +00:00
< h3 > Windowing< / h3 >
< p >
The streaming lib uses standard slow-start (exponential window growth) and congestion avoidance (linear window growth)
phases, with exponential backoff.
2010-10-16 13:57:58 +00:00
Windowing and acknowledgments use packet count, not byte count.
2010-08-22 02:18:28 +00:00
< / p >
< h3 > Close< / h3 >
< p >
Any packet, including one with the SYNCHRONIZE flag set, may have the CLOSE flag sent as well.
The connection is not closed until the peer responds with the CLOSE flag.
CLOSE packets may contain data as well.
< / p >
< h3 id = "sharing" > Control Block Sharing< / h3 >
< p >
The streaming lib supports "TCP" Control Block sharing.
2009-03-01 05:05:18 +00:00
This shares two important streaming lib parameters
(window size and round trip time)
across connections to the same remote peer.
This is used for "temporal" sharing at connection open/close time,
2010-08-22 02:18:28 +00:00
not "ensemble" sharing during a connection (See
< a href = "http://www.ietf.org/rfc/rfc2140.txt" > RFC 2140< / a > ).
2009-03-01 05:05:18 +00:00
There is a separate share per ConnectionManager (i.e. per local Destination)
so that there is no information leakage to other Destinations on the
same router.
2010-08-22 02:18:28 +00:00
The share data for a given peer expires after a few minutes.
2009-03-01 05:05:18 +00:00
< / p >
2010-08-22 02:18:28 +00:00
< h3 id = "other" > Other Parameters< / h3 >
The following parameters are hardcoded, but may be of interest for analysis:
< ul >
2010-08-28 22:30:59 +00:00
< li > MIN_RESEND_DELAY = 2*1000 (minimum RTO)
< li > MAX_RESEND_DELAY = 45*1000 (maximum RTO)
2010-08-22 02:18:28 +00:00
< li > MIN_WINDOW_SIZE = 1
< li > TREND_COUNT = 3
< li > RTT_DAMPENING = 0.875
2010-08-28 22:30:59 +00:00
< li > MIN_MESSAGE_SIZE = 512 (minimum MTU)
2010-08-22 02:18:28 +00:00
< li > INBOUND_BUFFER_SIZE = maxMessageSize * (maxWindowSize + 2)
< li > INITIAL_TIMEOUT = 1.5 * initialRTT
< li > PASSIVE_FLUSH_DELAY = 250
2010-08-28 22:30:59 +00:00
< li > Maximum RTT estimate: 60*1000
2010-08-22 02:18:28 +00:00
< / ul >
< / p >
< h3 > History< / h3 >
2008-11-15 16:12:21 +00:00
< p >
2010-08-22 02:18:28 +00:00
The streaming library has grown organically for I2P - first mihi implemented the
"mini streaming library" as part of I2PTunnel, which was limited to a window
size of 1 message (requiring an ACK before sending the next one), and then it was
refactored out into a generic streaming interface (mirroring TCP sockets) and the
full streaming implementation was deployed with a sliding window protocol and
optimizations to take into account the high bandwidth x delay product. Individual
streams may adjust the maximum packet size and other options. The default
message size is selected to fit precisely in two 1K I2NP tunnel messages,
and is a reasonable tradeoff between the bandwidth costs of
2010-08-28 22:30:59 +00:00
retransmitting lost messages, and the latency and overhead of multiple messages.
2010-08-22 02:18:28 +00:00
< / p >
2010-08-30 00:57:54 +00:00
< h2 id = "future" > Future Work< / h2 >
2010-08-22 02:18:28 +00:00
The behavior of the streaming library has a profound impact on
application-level performance, and as such, is an important
area for further analysis.
< ul >
< li >
Additional tuning of the streaming lib parameters may be necessary.
< / li >
< li >
Another area for research is the interaction of the streaming lib with the
NTCP and SSU transport layers.
2012-11-10 21:53:08 +00:00
See < a href = "{{ site_url('docs/transport/ntcp/discussion') }}" > the NTCP discussion page< / a > for details.
2010-08-22 02:18:28 +00:00
< / li >
< li >
The interaction of the routing algorithms with the streaming lib strongly affects performance.
In particular, random distribution of messages to multiple tunnels in a pool
2010-08-28 22:30:59 +00:00
leads to a high degree of out-of-order delivery which results in smaller window
2010-10-15 01:43:50 +00:00
sizes than would otherwise be the case. The router currently routes
messages for a single from/to destination pair through a consistent set
of tunnels, until tunnel expiration or delivery failure. The router's
failure and tunnel selection algorithms should be reviewed for possible
improvements.
2010-08-22 02:18:28 +00:00
< / li >
< li >
The data in the first SYN packet may exceed the receiver's MTU.
< / li >
< li >
The DELAY_REQUESTED field could be used more.
< / li >
< li >
Duplicate initial SYNCHRONIZE packets on short-lived streams may not be recognized and removed.
< / li >
< li >
2010-08-28 22:30:59 +00:00
Don't send the MTU in a retransmission.
< / li >
< li >
Data is sent along unless the outbound window is full.
(i.e. no-Nagle or TCP_NODELAY)
Probably should have a configuration option for this.
< / li >
< li >
zzz has added debug code to the streaming library to log packets in a wireshark-compatible
(pcap) format; Use this to further analyze performance.
The format may require enhancement to map more streaming lib parameters to TCP fields.
< / li >
< li >
2008-11-15 16:12:21 +00:00
There are proposals to replace the streaming lib with standard TCP
(or perhaps a null layer together with raw sockets).
This would unfortunately be incompatible with the streaming lib
but it would be good to compare the performance of the two.
2010-08-22 02:18:28 +00:00
< / li >
< / ul >
2008-03-25 21:56:26 +00:00
2008-02-10 14:17:56 +00:00
{% endblock %}