mirror of
https://github.com/tailscale/tailscale.git
synced 2025-02-19 19:38:40 +00:00
magicsock: set the don't fragment sockopt (#8715)
This sets the Don't Fragment flag, for now behind the TS_DEBUG_ENABLE_PMTUD envknob. Updates #311. Signed-off-by: Val <valerie@tailscale.com> Signed-off-by: salman <salman@tailscale.com>
This commit is contained in:
parent
16bc9350e3
commit
99e06d3544
@ -47,6 +47,8 @@ var (
|
|||||||
// debugRingBufferMaxSizeBytes overrides the default size of the endpoint
|
// debugRingBufferMaxSizeBytes overrides the default size of the endpoint
|
||||||
// history ringbuffer.
|
// history ringbuffer.
|
||||||
debugRingBufferMaxSizeBytes = envknob.RegisterInt("TS_DEBUG_MAGICSOCK_RING_BUFFER_MAX_SIZE_BYTES")
|
debugRingBufferMaxSizeBytes = envknob.RegisterInt("TS_DEBUG_MAGICSOCK_RING_BUFFER_MAX_SIZE_BYTES")
|
||||||
|
// debugPMTUD enables path MTU discovery. Currently only sets the Don't Fragment sockopt.
|
||||||
|
debugPMTUD = envknob.RegisterBool("TS_DEBUG_ENABLE_PMTUD")
|
||||||
// Hey you! Adding a new debugknob? Make sure to stub it out in the debugknob_stubs.go
|
// Hey you! Adding a new debugknob? Make sure to stub it out in the debugknob_stubs.go
|
||||||
// file too.
|
// file too.
|
||||||
)
|
)
|
||||||
|
@ -20,6 +20,7 @@ func debugAlwaysDERP() bool { return false }
|
|||||||
func debugUseDERPHTTP() bool { return false }
|
func debugUseDERPHTTP() bool { return false }
|
||||||
func debugEnableSilentDisco() bool { return false }
|
func debugEnableSilentDisco() bool { return false }
|
||||||
func debugSendCallMeUnknownPeer() bool { return false }
|
func debugSendCallMeUnknownPeer() bool { return false }
|
||||||
|
func debugPMTUD() bool { return false }
|
||||||
func debugUseDERPAddr() string { return "" }
|
func debugUseDERPAddr() string { return "" }
|
||||||
func debugUseDerpRouteEnv() string { return "" }
|
func debugUseDerpRouteEnv() string { return "" }
|
||||||
func debugUseDerpRoute() opt.Bool { return "" }
|
func debugUseDerpRoute() opt.Bool { return "" }
|
||||||
|
35
wgengine/magicsock/dontfrag_darwin.go
Normal file
35
wgengine/magicsock/dontfrag_darwin.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// Copyright (c) Tailscale Inc & AUTHORS
|
||||||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
//go:build darwin && !ios
|
||||||
|
|
||||||
|
package magicsock
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
"tailscale.com/types/nettype"
|
||||||
|
)
|
||||||
|
|
||||||
|
func setDontFragment(pconn nettype.PacketConn, network string) (err error) {
|
||||||
|
if c, ok := pconn.(*net.UDPConn); ok {
|
||||||
|
rc, err := c.SyscallConn()
|
||||||
|
if err == nil {
|
||||||
|
rc.Control(func(fd uintptr) {
|
||||||
|
if network == "udp4" {
|
||||||
|
err = syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IP, unix.IP_DONTFRAG, 1)
|
||||||
|
}
|
||||||
|
if network == "udp6" {
|
||||||
|
err = syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IPV6, unix.IPV6_DONTFRAG, 1)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func CanPMTUD() bool {
|
||||||
|
return debugPMTUD() // only if the envknob is for now.
|
||||||
|
}
|
24
wgengine/magicsock/dontfrag_default.go
Normal file
24
wgengine/magicsock/dontfrag_default.go
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// Copyright (c) Tailscale Inc & AUTHORS
|
||||||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
//go:build (!linux && !darwin) || android || ios
|
||||||
|
|
||||||
|
package magicsock
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"tailscale.com/types/nettype"
|
||||||
|
)
|
||||||
|
|
||||||
|
// setDontFragment sets the dontfragment sockopt on pconn on the platforms that support it,
|
||||||
|
// for both IPv4 and IPv6.
|
||||||
|
// (C.f. https://datatracker.ietf.org/doc/html/rfc3542#section-11.2 for IPv6 fragmentation)
|
||||||
|
func setDontFragment(pconn nettype.PacketConn, network string) (err error) {
|
||||||
|
return errors.New("setting don't fragment bit not supported on this OS")
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanPMTUD returns whether this platform supports performing peet path MTU discovery.
|
||||||
|
func CanPMTUD() bool {
|
||||||
|
return false
|
||||||
|
}
|
34
wgengine/magicsock/dontfrag_linux.go
Normal file
34
wgengine/magicsock/dontfrag_linux.go
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
// Copyright (c) Tailscale Inc & AUTHORS
|
||||||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
//go:build linux && !android
|
||||||
|
|
||||||
|
package magicsock
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"tailscale.com/types/nettype"
|
||||||
|
)
|
||||||
|
|
||||||
|
func setDontFragment(pconn nettype.PacketConn, network string) (err error) {
|
||||||
|
if c, ok := pconn.(*net.UDPConn); ok {
|
||||||
|
rc, err := c.SyscallConn()
|
||||||
|
if err == nil {
|
||||||
|
rc.Control(func(fd uintptr) {
|
||||||
|
if network == "udp4" {
|
||||||
|
err = syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IP, syscall.IP_MTU_DISCOVER, syscall.IP_PMTUDISC_DO)
|
||||||
|
}
|
||||||
|
if network == "udp6" {
|
||||||
|
err = syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IPV6, syscall.IP_MTU_DISCOVER, syscall.IP_PMTUDISC_DO)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func CanPMTUD() bool {
|
||||||
|
return debugPMTUD() // only if the envknob is enabled, for now.
|
||||||
|
}
|
@ -2233,6 +2233,16 @@ func (c *Conn) bindSocket(ruc *RebindingUDPConn, network string, curPortFate cur
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
trySetSocketBuffer(pconn, c.logf)
|
trySetSocketBuffer(pconn, c.logf)
|
||||||
|
|
||||||
|
if CanPMTUD() {
|
||||||
|
err = setDontFragment(pconn, network)
|
||||||
|
if err != nil {
|
||||||
|
c.logf("magicsock: set dontfragment failed for %v port %d: %v", network, port, err)
|
||||||
|
// TODO disable PMTUD in this case. We don't expect the setsockopt to fail on
|
||||||
|
// supported platforms, but we might as well be paranoid.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Success.
|
// Success.
|
||||||
if debugBindSocket() {
|
if debugBindSocket() {
|
||||||
c.logf("magicsock: bindSocket: successfully listened %v port %d", network, port)
|
c.logf("magicsock: bindSocket: successfully listened %v port %d", network, port)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user