mirror of
https://github.com/qdm12/gluetun.git
synced 2026-05-09 20:29:23 +02:00
Path MTU discovery fixes and improvements (#3109)
- 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
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
package settings
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/netip"
|
||||
"strings"
|
||||
|
||||
"github.com/qdm12/gosettings"
|
||||
"github.com/qdm12/gosettings/reader"
|
||||
"github.com/qdm12/gotree"
|
||||
)
|
||||
|
||||
// PMTUD contains settings to configure Path MTU Discovery.
|
||||
type PMTUD struct {
|
||||
// ICMPAddresses is the redundancy list of addresses to use
|
||||
// for ICMP path MTU discovery. Each address MUST handle ICMP
|
||||
// packets for PMTUD to work.
|
||||
// It cannot be nil in the internal state.
|
||||
ICMPAddresses []netip.Addr `json:"icmp_addresses"`
|
||||
// TCPAddresses is the redundancy list of addresses to use
|
||||
// for TCP path MTU discovery. Each address MUST have a listening
|
||||
// TCP server on the port specified.
|
||||
// It cannot be nil in the internal state.
|
||||
TCPAddresses []netip.AddrPort `json:"tcp_addresses"`
|
||||
}
|
||||
|
||||
var (
|
||||
ErrPMTUDICMPAddressNotValid = errors.New("PMTUD ICMP address is not valid")
|
||||
ErrPMTUDTCPAddressNotValid = errors.New("PMTUD TCP address is not valid")
|
||||
)
|
||||
|
||||
// Validate validates PMTUD settings.
|
||||
func (p PMTUD) validate() (err error) {
|
||||
for i, addr := range p.ICMPAddresses {
|
||||
if !addr.IsValid() {
|
||||
return fmt.Errorf("%w: at index %d", ErrPMTUDICMPAddressNotValid, i)
|
||||
}
|
||||
}
|
||||
for i, addr := range p.TCPAddresses {
|
||||
if !addr.IsValid() {
|
||||
return fmt.Errorf("%w: at index %d", ErrPMTUDTCPAddressNotValid, i)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *PMTUD) copy() (copied PMTUD) {
|
||||
return PMTUD{
|
||||
ICMPAddresses: gosettings.CopySlice(p.ICMPAddresses),
|
||||
TCPAddresses: gosettings.CopySlice(p.TCPAddresses),
|
||||
}
|
||||
}
|
||||
|
||||
func (p *PMTUD) overrideWith(other PMTUD) {
|
||||
p.ICMPAddresses = gosettings.OverrideWithSlice(p.ICMPAddresses, other.ICMPAddresses)
|
||||
p.TCPAddresses = gosettings.OverrideWithSlice(p.TCPAddresses, other.TCPAddresses)
|
||||
}
|
||||
|
||||
func (p *PMTUD) setDefaults() {
|
||||
defaultICMPAddresses := []netip.Addr{
|
||||
netip.AddrFrom4([4]byte{1, 1, 1, 1}),
|
||||
netip.AddrFrom4([4]byte{8, 8, 8, 8}),
|
||||
}
|
||||
p.ICMPAddresses = gosettings.DefaultSlice(p.ICMPAddresses, defaultICMPAddresses)
|
||||
|
||||
const tlsPort = 443
|
||||
defaultTCPAddresses := []netip.AddrPort{
|
||||
netip.AddrPortFrom(netip.AddrFrom4([4]byte{1, 1, 1, 1}), tlsPort),
|
||||
netip.AddrPortFrom(netip.AddrFrom4([4]byte{8, 8, 8, 8}), tlsPort),
|
||||
}
|
||||
p.TCPAddresses = gosettings.DefaultSlice(p.TCPAddresses, defaultTCPAddresses)
|
||||
}
|
||||
|
||||
func (p PMTUD) String() string {
|
||||
return p.toLinesNode().String()
|
||||
}
|
||||
|
||||
func (p PMTUD) toLinesNode() (node *gotree.Node) {
|
||||
node = gotree.New("Path MTU discovery:")
|
||||
|
||||
addrs := make([]string, len(p.ICMPAddresses))
|
||||
for i, addr := range p.ICMPAddresses {
|
||||
addrs[i] = addr.String()
|
||||
}
|
||||
node.Appendf("ICMP addresses: %s", strings.Join(addrs, ", "))
|
||||
|
||||
addrs = make([]string, len(p.TCPAddresses))
|
||||
for i, addr := range p.TCPAddresses {
|
||||
addrs[i] = addr.String()
|
||||
}
|
||||
node.Appendf("TCP addresses: %s", strings.Join(addrs, ", "))
|
||||
return node
|
||||
}
|
||||
|
||||
func (p *PMTUD) read(r *reader.Reader) (err error) {
|
||||
p.ICMPAddresses, err = r.CSVNetipAddresses("PMTUD_ICMP_ADDRESSES")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
p.TCPAddresses, err = r.CSVNetipAddrPorts("PMTUD_TCP_ADDRESSES")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user