Context
#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 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).
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 #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:
- call
set_socket_option to explicitly disable GSO when needed (but then we don't need the special cmsg handling)
- call
set_socket_option to return disable GSO after probing
- revert to using a throwaway socket for GSO (I don't believe GRO is impacted)
Context
#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
quinnfrom working at all with network drivers that do not support segmentation offloading when this feature is enabled in theTransportConfig.Previously, GSO was probed on the throwaway socket using
set_socket_option, but the option was not activated on the transport socket.quinninstead relies on the possibility to setUDP_SEGMENTin thecmsggiven tosendmsg(this is documented inman udp).When
quinndetects a possible GSO error, it resetsmax_gso_segmentsto 1, so thatprepare_msgno longer putsUDP_SEGMENT, effectively disabling GSO for this specific batch.Bug
With #2565, the option is set on the transport socket (if the kernel accepted it), so the special
cmsghandling no longer works andquinnends 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 runningquinn/perfover 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:
set_socket_optionto explicitly disable GSO when needed (but then we don't need the specialcmsghandling)set_socket_optionto return disable GSO after probing