On Wednesday 24 March 2010 17:42:12 Evan Daniel wrote: > The current FNP protocol leaves a bit to be desired. It has more > overhead than we'd like, it can only pad packets with random data (not > useful bulk transfers), it doesn't handle small MTUs, and its > congestion avoidance isn't as TCP-compatible as we'd like. > > The most immediate problem is probably that it would make a transport > plugin infrastructure overly complicated. For example, a lot of > interesting steganographic transports (VoIP, chat, and video game > imitators, for example) have a low MTU. That means the plugins would > need to support packet fragmenting and reassembly, or add another > layer between FNP and the transport plugins. Neither solution is > particularly desirable. > > Toad and I have talked about this some on IRC. I've written up a > partial draft proposal that draws heavily on the old "New protocol" > proposal, but makes some improvements (I hope ;) ). You can find it > at http://new-wiki.freenetproject.org/User:Evanbd/New_Packet_Format_Proposal > . Comments are very welcome, especially from anyone well versed in > network theory.
The MAC may need to be lengthened, or to scale depending on packet size. There is some doubt about hash-then-encrypt, I was told after much searching that an outer hash is better, but in any case, it needs to not be computable by a snooper. If a short MAC is not sufficient to guarantee that the message has not been tampered with then we need to consider alternatives for small packets such as MACing at a higher level. We need to research this before deploying small MACs. We discussed this extensively on IRC, evanbd will be writing up a new proposal soon. Denial of service attacks are potentially a problem because fragmentation is initiated by the sender, and could use a significant amount of memory if the sender is malicious. We can avoid this by setting (and publishing to the other side) limits on both the number of message ID's in flight and the total bytes cached by the recipient. The latter should be no more than 128K per peer, for now, because we are not including block transfers (32KB) in this: They will be recipient-originated. Hence the size limit for sender-initiated messages can be very small, say 4KB. It may still be necessary to support an explicit NACK of a message causing it to be resent by the sender; certainly the sender should not forget the data in the message until the whole message has been acked. For the time being, we should keep the current DMT message format, although in the long term we can probably improve on it. Re padding, IMHO we don't need an explicit padding message type - we either declare the number of messages at the beginning (which presumably costs us one byte), or we override the message length to indicate last message?? Dunno, if the message type is only one byte it would be feasible; we can do different changes at different times anyhow. Ack timing is indeed a problem - we probably don't want to give timings for each packet. Although we could probably get away with 2 bytes or even 1 in many cases? If we are only using them to calculate the average ping time then we probably only need one ack timing for all the acks, being the average, which could be a part of the format? We might also consider compressing the high-level 8-byte UID's that are sent in almost all messages - probably by the recipient telling the sender that it is allocating a short-ID for the long ID, and then the sender using the short-ID. Packets, not message fragments, are acked, right? This will save a lot of space on the network level, although it means the sender will need to track exactly what was in each packet he sent. This could be a significant amount of memory on high bandwidth * latency connections; this might be significant relative to what we have to keep anyway for data in progress on connections with small packet sizes (e.g. mimicing skype). There is no "inner sequence number", and there is no way for the receiver to know whether a packet was resent; if the packet doesn't get acked, the sender resends *its contents*, and these are discarded or accepted based on message ID's and ranges; in any case the packet will be acked. As I have already mentioned IMHO sender-initiated streams should be limited to 4KB (whereas recipient-initiated can be big but will usually be <2^24-1). Very late packets will be dropped because the recipient won't recognise them; they are outside of the window within which we recognise the precomputed encrypted message sequence numbers, I believe this is discussed on the old new packet format page? In any case, we don't have to change the crypto and the message packing at the same time; the principle that if a packet is severely delayed, it will be dropped, is reasonable; the sender will then resend it, if it hasn't been acked. There is only one resend per packet number, which simplifies life significantly and is the right choice; resending creates a new packet and a new packet number. The new crypto design is clearly much better than the old one. In the new crypto design, we use the IV key to encrypt (ECB mode) the sequence number, creating the IV for the whole packet, then we simply put the packet sequence number at the beginning so it is the sequence number XORed with the IV's first four bytes (the packet being PCFB encrypted since it's variable length). In the old design, we have a full hash at the beginning of the packet, and within the rest of the packet we have a fixed 12 bytes of random data to randomise the hash! As I see it, when the receiver drops a partially assembled message (a highly undesirable operation that should not happen in normal non-malicious use), because of either the fragment window ( == maximum number of partially assembled messages in flight ), or the buffer limit ( = bytes of partially assembled messages), we need an explicit NACK of that message (and the range we are dropping??). In any case the sender knows what has been acked and can thus keep on resending messages that are not ACKed, and refuse to allocate new message numbers while it has a window full of stuff that hasn't been ACKed yet. IMHO reliable delivery is an essential building block of all the higher level stuff: We can't just drop messages. And yes, clearly once we have assembled a fragmented message and passed it on, we can never accept that message again. Meaning until it falls out of the window we will need to remember the fact that we have accepted it. This can however be implemented very efficiently. 8192 seems arbitrary, I can see why it makes sense with the bit fields ... With regards to congestion control, IMHO we should keep the current TCP-like peer-level congestion control for now. This seems to work, and should co-operate with TCP reasonably well i.e. not flood out TCP traffic nor be too easily flooded out by it. Retransmission: TCP retransmits after 4 RTTs unconditionally and after receiving an ack for a later packet. IMHO this is a good model. Our current code does all sorts of wierd things with explicit retransmit requests and so on, which isn't a good model. Given that we only have the message size on the first fragment, we can't allocate a buffer for the whole message if we receive the second fragment first. Not including the size on later fragments may be important for byte scavenging, so that determines the matter. However, especially on transports with small packets, the memory overhead of keeping each fragment in memory separately may be significant. As you mentioned we probably need 3 classes. Each will need a separate message ID sequence, its own message window size, and its own size limits; sender-initiated fragmented messages can have a 4KB limit, block transfers may be a fixed size or may have a ~ 35K limit, bulk transfers can be huge. Each will presumably need its own length byte and sequence number in the packet; if we have a flags byte we can maybe avoid these in most cases. I am uncertain about prioritising SSK inserts and transferring everything at once. It makes a certain amount of sense but there may be problems... Agreed about fixed per-peer allocation. > > We currently have two potential gsoc students who are interested in > transport plugins. We should improve FNP in parallel with that, imho. > It's also possible that one of them could work on FNP and the other > on transport plugins, if there is interest. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 197 bytes Desc: This is a digitally signed message part. URL: <https://emu.freenetproject.org/pipermail/devl/attachments/20100401/6d552530/attachment.pgp>
