mirror of
https://github.com/outbackdingo/firezone.git
synced 2026-01-27 18:18:55 +00:00
Generic Segmentation Offload (GSO) is a clever way of reducing the number of syscalls made when a you want to send a lot of packets with the same length to the same recipient. The way this works is that the packets are concatenated and passed to the kernel as a single packet together with the `segment_size` as an out-of-band argument. The component managing this batching in `connlib` is called `GsoQueue`. In #8772, we made the order in which these batches are sent to the kernel explicit by prioritising batches with smaller segments. What we overlooked with that strategy is that in a particular GSO batch, the last packet is actually allowed to be of a different length. For example, say the user is downloading an image of 4500Kb. With our MTU of 1280, we have a payload size of 1252. This results in three fully-filled packets and one packet of 744 bytes. With the change in #8772, the small packet of 744 bytes will be transferred first, followed by the "train" of fully filled packets. To fix this, we flip the order here and transfer batches or larger sizes first. The original problem we attempted to mitigate in #8772 no longer exists now that we merged #7590. We will simply suspend now if the UDP socket isn't ready contrary to dropping the next batch. By flipping the order here, we guarantee that batches with a larger size are sent before batches with a smaller size. This should also imply that the encapsulated IP packets of e.g. an image arrive in the correct order (with the smallest packet last as it is part of a smaller batch). What we don't guarantee with this is that there won't be any other IP packets sent "in the middle" of such a batch. This shouldn't be a problem though as we are simply interleaving packets of different TCP / UDP connections with each other which already happens on the regular Internet anyway.
Connlib
Firezone's connectivity library shared by all clients.
Building Connlib
You shouldn't need to build connlib directly; it's typically built as a dependency of one of the other Firezone components. See READMEs in those directories for relevant instructions.