mirror of
https://github.com/qdm12/gluetun.git
synced 2026-05-10 04:30:20 +02:00
hotfix(pmtud/tcp): block kernel from racing to send RST packets
- this makes PMTUD TCP reliable - this only works on kernels with the mark module - on kernels without the mark module, the icmp pmtud mtu found is used
This commit is contained in:
+15
-2
@@ -7,11 +7,14 @@ import (
|
||||
"net/netip"
|
||||
"time"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/firewall"
|
||||
"github.com/qdm12/gluetun/internal/pmtud/constants"
|
||||
"github.com/qdm12/gluetun/internal/pmtud/icmp"
|
||||
"github.com/qdm12/gluetun/internal/pmtud/tcp"
|
||||
)
|
||||
|
||||
var ErrPMTUDFailICMPAndTCP = errors.New("PMTUD failed with both ICMP and TCP")
|
||||
|
||||
// PathMTUDiscover discovers the maximum MTU using both ICMP and TCP.
|
||||
// Multiple ICMP addresses and TCP addresses can be specified for redundancy.
|
||||
// ICMP PMTUD is run first. If successful, the range of possible MTU values to
|
||||
@@ -23,7 +26,7 @@ import (
|
||||
// If the logger is nil, a no-op logger is used.
|
||||
// It returns [ErrMTUNotFound] if the MTU could not be determined.
|
||||
func PathMTUDiscover(ctx context.Context, icmpAddrs []netip.Addr, tcpAddrs []netip.AddrPort,
|
||||
physicalLinkMTU uint32, tryTimeout time.Duration, logger Logger) (
|
||||
physicalLinkMTU uint32, tryTimeout time.Duration, fw tcp.Firewall, logger Logger) (
|
||||
mtu uint32, err error,
|
||||
) {
|
||||
if physicalLinkMTU == 0 {
|
||||
@@ -67,13 +70,23 @@ func PathMTUDiscover(ctx context.Context, icmpAddrs []netip.Addr, tcpAddrs []net
|
||||
const mtuMargin = 150
|
||||
minMTU = max(maxPossibleMTU-mtuMargin, minMTU)
|
||||
}
|
||||
mtu, err = tcp.PathMTUDiscover(ctx, addrPort, minMTU, maxPossibleMTU, logger)
|
||||
mtu, err = tcp.PathMTUDiscover(ctx, addrPort, minMTU, maxPossibleMTU, fw, logger)
|
||||
if err != nil {
|
||||
if errors.Is(err, firewall.ErrMarkMatchModuleMissing) {
|
||||
logger.Debugf("aborting TCP path MTU discovery: %s", err)
|
||||
if icmpSuccess {
|
||||
return maxPossibleMTU, nil // only rely on ICMP PMTUD results
|
||||
}
|
||||
return 0, fmt.Errorf("%w", ErrPMTUDFailICMPAndTCP)
|
||||
}
|
||||
logger.Debugf("TCP path MTU discovery to %s failed: %s", addrPort, err)
|
||||
continue
|
||||
}
|
||||
logger.Debugf("TCP path MTU discovery to %s found maximum valid MTU %d", addrPort, mtu)
|
||||
return mtu, nil
|
||||
}
|
||||
|
||||
// TCP PMTUD failed for all addresses for external reasons,
|
||||
// so do not take the risk and return an error.
|
||||
return 0, fmt.Errorf("TCP path MTU discovery: last error: %w", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user