This is a combination of a number of things we want that we expect to make packet build more robust. This approach was independently inspired, but was confirmed to also be used by picoquic for its packet building.
Current packet building
The current packet builder pads Initial datagrams inside the final packet of the, possibly coalesced, datagram. This means that to build the datagram it needs to know before finishing a packet whether another packet will be coalesced into the datagram.
- This is brittle, because you need to be sure a non-empty packet will be produced. E.g. there needs to be enough space for whatever will be sent, an abstract minimal amount of space is not enough.
- This is redundant, because you then actually need to build the packet as well.
- The cost of this carries on long after the handshake is completed.
Proposal
- Whenever a long-header packet is written, finish it without padding.
- Packet building always starts, no need to predict if something can be written.
- If a packet is empty, the header is removed again from the buffer.
- To expand a datagram containing an Initial packet, use random bytes outside of the last packet.
This is expected to be more robust because there is only one place, populate_packet, that needs to decide if something can be written into the packet. The checks on how to finish a next packet or start building a new one disappear. No more state is shared between those iterations.
Security
The amount of information an observer of an in-flight packet can deduce is still the same: For the very first client-initiated Initial packet an on-wire observer can always decrypt it. If the server uses this technique the random data is indistinguishable from a packet, so it will look like the coalesced Handshake or Data packet just continues to the end.
This is a combination of a number of things we want that we expect to make packet build more robust. This approach was independently inspired, but was confirmed to also be used by picoquic for its packet building.
Current packet building
The current packet builder pads Initial datagrams inside the final packet of the, possibly coalesced, datagram. This means that to build the datagram it needs to know before finishing a packet whether another packet will be coalesced into the datagram.
Proposal
This is expected to be more robust because there is only one place,
populate_packet, that needs to decide if something can be written into the packet. The checks on how to finish a next packet or start building a new one disappear. No more state is shared between those iterations.Security
The amount of information an observer of an in-flight packet can deduce is still the same: For the very first client-initiated Initial packet an on-wire observer can always decrypt it. If the server uses this technique the random data is indistinguishable from a packet, so it will look like the coalesced Handshake or Data packet just continues to the end.