[freenet-dev] Packet size proposal
Matthew Toseland
toad at amphibian.dyndns.org
Thu Mar 6 20:09:15 UTC 2008
Our current approach to packet sizes has several major disadvantages. I will
explain them in a moment, first, here's what we do:
All messages are held for up to 100ms for coalescing as many messages as
possible into one packet, and are sent in priority order. We send a packet
anyway if we have more than MTU-100 bytes of data to send. Base overhead is a
minimum of 27 bytes, plus one byte per ack/resend request/etc. After that,
the packet is padded to the next 64 byte boundary, and then we add between 0
and 63 bytes. This is all random padding. Bulk and block transfers are split
into 1024 byte blocks, which are passed to the coalescing queue as often as
congestion control and bandwidth limiting will allow.
Most messages are between 8 and ~14 bytes. CHK found, CHK data insert, and
some opennet messages, are up to 42 bytes. Messages which include keys range
from 52 to 107 bytes (SSK keys are 64 bytes, CHK keys are 32). The last phase
of swapping involves 188 byte messages. Block and bulk transfer messages, SSK
requests, pubkeys, and inserts, and times-last-few-messages-were-received (on
connect, to identify if we are NATed) messages, are over 1024 bytes, some of
them quite a lot over it.
By rewriting the transport layer, we can reduce the base overhead to maybe
10-16 bytes. The hash (32 bytes) will be replaced by a MAC of the same size.
We could reduce its size for smaller packets, at the cost of some security.
We could limit the security cost by doing a MAC at a higher layer (after
reassembling a stream), but this won't work if there isn't a stream to
reassemble: right now, there isn't, short packets contain a few short
messages and a few acks. We could implement an in-order stream to put the
short messages in, and then do a MAC before passing them on, but that would
cost quite a bit of latency.
The original design goals were to minimise request latency, and maximise block
transfer efficiency.
Problems with current system
===================
Security:
- We remain fairly vulnerable to traffic analysis based on packet size.
Because a few messages are HUGE, they can probably be traced across the
network by a global passive traffic analyser. We're being reasonably open
about this since They undoubtedly already know this!
- Stego transports will not work well with the current approach. We want a
transport mimicing realplayer streams to have packet sizes equivalent to
those of realplayer streams, for example.
Reliability:
- Those few messages may not fit within the available MTU. This will cause
*severe* problems on some connections.
Performance:
- Because block transfer data is sent in large chunks, it is usually not
combined with small messages. Therefore, the small messages are heavily
padded (as well as suffering the significant crypto overhead on their own).
Of course, the big packets have a relatively low overhead.
Proposed solution
=============
All big messages are converted into streams. Small messages such as
FNPAccepted should remain as messages.
The packet size does not depend directly on the details of the pending
messages. We determine the packet size by reference to a target profile, of
whatever we are trying to mimic (e.g. some realplayer codecs send a lot of
660 byte packets; some send a lot of 330 byte packets; skype sends a lot of
68 byte packets). If we're not using a steganographic transport, there are
other means to decide on a packet size - a fixed 256 bytes maybe, or a range.
However, this only applies if we are currently sending streams to the node.
If we not, we have essentially the same problem we have now: high packet
overhead. The only way to solve this at this level would be to bundle
messages into a stream anyway, but that would cost latency... However, not
having any streams in progress is IMHO the result of a higher level problem.
With the new transport layer, all packets are subject to both bandwidth
limiting and congestion control.
Streams (including bulk and block transfers) are no longer sent in 1kB chunks.
They are sent in byte ranges. A packet containing a few messages will be
padded up to the target size by adding data from streams (in priority order,
of course), not by adding random data.
Advantages of proposed solution
=====================
Security:
- Greatly reduced vulnerability to traffic analysis. No information can be
derived from the size of an outgoing packet.
- Compatible with most packet-based stego transports, although for really
small packets some changes would be needed.
Reliability:
- Compatible with any MTU down to modem sizes (576 bytes).
Performance:
- For any peer which has a transfer in progress (including e.g. SSK
inserts/requests), we should achieve a very good payload percentage. However,
if there are no pending streams, we don't achieve good results: if there are
no steganographic concerns, and no pending streams, we could send packets as
we do now (big enough to fit the messages to send plus some padding).
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://emu.freenetproject.org/pipermail/devl/attachments/20080306/687c31db/attachment.pgp
More information about the Devl
mailing list