net/netns: refactor the sync.Once usage a bit

pull/427/head
Brad Fitzpatrick 5 years ago
parent e7ae6a2e06
commit 1e837b8e81

@ -28,12 +28,20 @@ import (
// wgengine/router/router_linux.go. // wgengine/router/router_linux.go.
const tailscaleBypassMark = 0x20000 const tailscaleBypassMark = 0x20000
// checkIPRule runs the ipRuleAvailable check exactly once. // ipRuleOnce is the sync.Once & cached value for ipRuleAvailable.
var checkIPRule sync.Once var ipRuleOnce struct {
sync.Once
v bool
}
// ipRuleAvailable is true if and only if the 'ip rule' command works. // ipRuleAvailable reports whether the 'ip rule' command works.
// If it doesn't, we have to use SO_BINDTODEVICE on our sockets instead. // If it doesn't, we have to use SO_BINDTODEVICE on our sockets instead.
var ipRuleAvailable bool func ipRuleAvailable() bool {
ipRuleOnce.Do(func() {
ipRuleOnce.v = exec.Command("ip", "rule").Run() == nil
})
return ipRuleOnce.v
}
// defaultRouteInterface returns the name of the network interface that owns // defaultRouteInterface returns the name of the network interface that owns
// the default route, not including any tailscale interfaces. We only use // the default route, not including any tailscale interfaces. We only use
@ -98,18 +106,13 @@ func ignoreErrors() bool {
// It's intentionally the same signature as net.Dialer.Control // It's intentionally the same signature as net.Dialer.Control
// and net.ListenConfig.Control. // and net.ListenConfig.Control.
func control(network, address string, c syscall.RawConn) error { func control(network, address string, c syscall.RawConn) error {
checkIPRule.Do(func() {
_, err := exec.Command("ip", "rule").Output()
ipRuleAvailable = (err == nil)
})
if skipPrivileged.Get() { if skipPrivileged.Get() {
// We can't set socket marks without CAP_NET_ADMIN on linux, // We can't set socket marks without CAP_NET_ADMIN on linux,
// skip as requested. // skip as requested.
return nil return nil
} }
if ipRuleAvailable { if ipRuleAvailable() {
var controlErr error var controlErr error
err := c.Control(func(fd uintptr) { err := c.Control(func(fd uintptr) {
controlErr = unix.SetsockoptInt(int(fd), controlErr = unix.SetsockoptInt(int(fd),

Loading…
Cancel
Save