Automatic GSO deactivation no longer works
## Context
https://github.com/quinn-rs/quinn/pull/2565 changed GRO and GSO probing to use the transport socket instead of creating throwaways.
It introduced a logic error with regards to the automatic GSO deactivation, preventing `quinn` from working at all with network drivers that do not support segmentation offloading when this feature is enabled in the `TransportConfig`.
Previously, [GSO was probed on the throwaway socket](https://github.com/quinn-rs/quinn/blob/d51b17a29bd0d310bb4bd90307b9cfa841ac9cbb/quinn-udp/src/unix.rs#L1020-L1029) using `set_socket_option`, but the option was not activated on the transport socket. `quinn` instead relies on the possibility to set `UDP_SEGMENT` in the `cmsg` given to `sendmsg` (this is documented in [`man udp`](https://man7.org/linux/man-pages/man7/udp.7.html)).
When `quinn` detects a possible GSO error, it resets `max_gso_segments` to 1, so that `prepare_msg` no longer puts `UDP_SEGMENT`, effectively disabling GSO for this specific batch.
## Bug
With https://github.com/quinn-rs/quinn/pull/2565, the option is set on the transport socket (if the kernel accepted it), so the special `cmsg` handling no longer works and `quinn` ends up asking for segmentation offload forever.
This can be reproduced by disabling UDP segmentation on the interface (`ethtool -K virbr0 tx-udp-segmentation off`) and running `quinn/perf` over that interface: the client is stuck and keeps trying to send the initial frame.
## Solutions
I'm not sure which direction should be preferred for a fix. I think we could:
1. call `set_socket_option` to explicitly disable GSO when needed (but then we don't need the special `cmsg` handling)
2. call `set_socket_option` to return disable GSO after probing
3. revert to using a throwaway socket for GSO (I don't believe GRO is impacted)
9 条评论