-
Notifications
You must be signed in to change notification settings - Fork 329
Description
Currently DerpCodec has the Frame::SendPacket frame, this contains a packet: Bytes which is actually 1-or-more datagrams, each prefixed with a big-endian 16-bit datagram length.
The problem is that the MagicSock (via AsyncUdpSocket) sends datagrams either as individual datagrams or as a GSO datagram. The latter has the semantics that there is a known "stride", each datagram is "stride" bytes long, the last datagram in the sequence could be smaller.
Currently these datagrams end up being split in the AsyncUdpSocket, which requires copying. They are then turned into the u16be-prefixed packets by PacketizeIter which will again involve copying. The PacketizeIter forces all datagrams sent via the relay to be copied, even those that are not GSO.
On the receiving path the u16be prefix also needs stripping of course.
This would all be much better if there was a Frame::SendGsoPacket or something which would include the stride. In this case the data could be sent without any copying and also on the receive path can be passed back to the AsyncUdpSocket unmodified using GRO. The only concern is that the max frame size should not be exceeded, but the max frame size of the MagicSock should be communicated correctly using the GSO/GRO socket options that already exist and then Quinn will not produce GSO packets larger than allowed.
Only the receive path could potentially end up with GRO size that is smaller than the sender's GSO size (because it must be the min between the UDP socket and relay max_frame_size for the MagicSock). In that case the receiver size will pay the cost of breaking up the packet. But overall this is probably worth it as this would be rather rare.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status