diff --git a/derp/derphttp/derphttp_client.go b/derp/derphttp/derphttp_client.go index c63644bb1..365ac09e4 100644 --- a/derp/derphttp/derphttp_client.go +++ b/derp/derphttp/derphttp_client.go @@ -27,6 +27,7 @@ "inet.af/netaddr" "tailscale.com/derp" "tailscale.com/net/dnscache" + "tailscale.com/net/netns" "tailscale.com/net/tlsdial" "tailscale.com/tailcfg" "tailscale.com/types/key" @@ -296,7 +297,7 @@ func (c *Client) dialURL(ctx context.Context) (net.Conn, error) { host := c.url.Hostname() hostOrIP := host - var stdDialer dialer = new(net.Dialer) + var stdDialer dialer = netns.Dialer() var dialer = stdDialer if wrapDialer != nil { dialer = wrapDialer(dialer) @@ -345,7 +346,7 @@ func (c *Client) dialRegion(ctx context.Context, reg *tailcfg.DERPRegion) (net.C } func (c *Client) dialContext(ctx context.Context, proto, addr string) (net.Conn, error) { - var stdDialer dialer = new(net.Dialer) + var stdDialer dialer = netns.Dialer() var dialer = stdDialer if wrapDialer != nil { dialer = wrapDialer(dialer) diff --git a/net/netns/netns.go b/net/netns/netns.go index e204a0d1b..009425994 100644 --- a/net/netns/netns.go +++ b/net/netns/netns.go @@ -23,6 +23,13 @@ func Listener() *net.ListenConfig { return &net.ListenConfig{Control: control} } +// Dialer returns a new net.Dialer with its Control hook func +// initialized as necessary to run in a logical network namespace that +// doesn't route back into Tailscale. +func Dialer() *net.Dialer { + return &net.Dialer{Control: control} +} + // control marks c as necessary to dial in a separate network namespace. // // It's intentionally the same signature as net.Dialer.Control