sendQueue: ignore "datagram too large" error (#3328)

This commit introduces additional platform-dependent checking when the
kernel returns an error. Previously, the session is terminated when
PingFrame sends a discovery packet larger than the limit. With this
commit, the error is checked, and if it is "datagram too large", the
error is ignored.

Additionally,
1. This commit re-enables MTU discovery on Windows unless it
is disabled explicitly by user (Undo #3276),
2. Set IP_DONTFRAGMENT and IPV6_DONTFRAG with error checking on Windows,
   and
3. Set IP_MTU_DISCOVERY to PMTUDISC_DO for both IPv4 and IPv6 on Linux
   so that the kernel will return "message too long".

Fixes #3273 #3327
This commit is contained in:
Rachel Chen
2022-02-20 00:21:32 -08:00
committed by GitHub
parent f3b098775e
commit fd2c345152
15 changed files with 124 additions and 57 deletions

View File

@@ -130,10 +130,6 @@ func (e *errCloseForRecreating) Error() string {
var sessionTracingID uint64 // to be accessed atomically
func nextSessionTracingID() uint64 { return atomic.AddUint64(&sessionTracingID, 1) }
func pathMTUDiscoveryEnabled(config *Config) bool {
return !disablePathMTUDiscovery && !config.DisablePathMTUDiscovery
}
// A Session is a QUIC session
type session struct {
// Destination connection ID used during the handshake.
@@ -755,7 +751,7 @@ func (s *session) maybeResetTimer() {
deadline = s.idleTimeoutStartTime().Add(s.idleTimeout)
}
}
if s.handshakeConfirmed && pathMTUDiscoveryEnabled(s.config) {
if s.handshakeConfirmed && !s.config.DisablePathMTUDiscovery {
if probeTime := s.mtuDiscoverer.NextProbeTime(); !probeTime.IsZero() {
deadline = utils.MinTime(deadline, probeTime)
}
@@ -819,7 +815,7 @@ func (s *session) handleHandshakeConfirmed() {
s.sentPacketHandler.SetHandshakeConfirmed()
s.cryptoStreamHandler.SetHandshakeConfirmed()
if pathMTUDiscoveryEnabled(s.config) {
if !s.config.DisablePathMTUDiscovery {
maxPacketSize := s.peerParams.MaxUDPPayloadSize
if maxPacketSize == 0 {
maxPacketSize = protocol.MaxByteCount
@@ -1780,7 +1776,7 @@ func (s *session) sendPacket() (bool, error) {
s.sendQueue.Send(packet.buffer)
return true, nil
}
if pathMTUDiscoveryEnabled(s.config) && s.mtuDiscoverer.ShouldSendProbe(now) {
if !s.config.DisablePathMTUDiscovery && s.mtuDiscoverer.ShouldSendProbe(now) {
packet, err := s.packer.PackMTUProbePacket(s.mtuDiscoverer.GetPing())
if err != nil {
return false, err