mirror of
https://github.com/qdm12/gluetun.git
synced 2026-05-07 04:20:12 +02:00
be92aa2ac4
- Existing option `WIREGUARD_MTU` , if set, disables PMTUD and is used - New option `PMTUD_ICMP_ADDRESSES=1.1.1.1,8.8.8.8` and `PMTUD_TCP_ADDRESSES=1.1.1.1:443,8.8.8.8:443` - ICMP PMTUD now targets external-by-default IP addresses - New TCP PMTUD (binary search only) as a second MTU confirmation and fallback mechanism. - Force set TCP MSS to MTU - IP header - TCP base header - "magic 20 bytes" 🎆 - Fix #3108
54 lines
1.6 KiB
Go
54 lines
1.6 KiB
Go
package icmp
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"net"
|
|
"net/netip"
|
|
"time"
|
|
|
|
"github.com/qdm12/gluetun/internal/pmtud/constants"
|
|
)
|
|
|
|
// PathMTUDiscover discovers the path MTU to the given IP address
|
|
// using ICMP.
|
|
// It first tries to get the next hop MTU using ICMP messages.
|
|
// If that fails, it falls back to sending echo requests with
|
|
// different packet sizes to find the maximum MTU.
|
|
// The function returns [ErrMTUNotFound] if the MTU could not be determined.
|
|
func PathMTUDiscover(ctx context.Context, ip netip.Addr,
|
|
physicalLinkMTU uint32, timeout time.Duration, logger Logger,
|
|
) (mtu uint32, err error) {
|
|
if ip.Is4() {
|
|
logger.Debug("finding IPv4 next hop MTU")
|
|
mtu, err = findIPv4NextHopMTU(ctx, ip, physicalLinkMTU, timeout, logger)
|
|
switch {
|
|
case err == nil:
|
|
return mtu, nil
|
|
case errors.Is(err, net.ErrClosed) || errors.Is(err, ErrCommunicationAdministrativelyProhibited): // blackhole
|
|
default:
|
|
return 0, fmt.Errorf("finding IPv4 next hop MTU: %w", err)
|
|
}
|
|
} else {
|
|
logger.Debug("requesting IPv6 ICMP packet-too-big reply")
|
|
mtu, err = getIPv6PacketTooBig(ctx, ip, physicalLinkMTU, timeout, logger)
|
|
switch {
|
|
case err == nil:
|
|
return mtu, nil
|
|
case errors.Is(err, net.ErrClosed): // blackhole
|
|
default:
|
|
return 0, fmt.Errorf("getting IPv6 packet-too-big message: %w", err)
|
|
}
|
|
}
|
|
|
|
// Fall back method: send echo requests with different packet
|
|
// sizes and check which ones succeed to find the maximum MTU.
|
|
logger.Debug("falling back to sending different sized echo packets")
|
|
minMTU := constants.MinIPv4MTU
|
|
if ip.Is6() {
|
|
minMTU = constants.MinIPv6MTU
|
|
}
|
|
return pmtudMultiSizes(ctx, ip, minMTU, physicalLinkMTU, timeout, logger)
|
|
}
|