From 040a0d51219a73469cd508ebb9d1207a77d35690 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Wed, 13 May 2020 22:35:17 -0700 Subject: [PATCH] derp/derphttp: don't use x/net/proxy for SOCKS on iOS We don't want those extra dependencies on iOS, at least yet. Especially since there's no way to set the relevant environment variables so it's just bloat with no benefits. Perhaps we'll need to do SOCKS on iOS later, but probably differently if/when so. Updates #227 Signed-off-by: Brad Fitzpatrick --- derp/derphttp/derphttp_client.go | 20 ++++++++++++-------- derp/derphttp/socks.go | 20 ++++++++++++++++++++ 2 files changed, 32 insertions(+), 8 deletions(-) create mode 100644 derp/derphttp/socks.go diff --git a/derp/derphttp/derphttp_client.go b/derp/derphttp/derphttp_client.go index cf3be053f..bcaa08ea4 100644 --- a/derp/derphttp/derphttp_client.go +++ b/derp/derphttp/derphttp_client.go @@ -24,7 +24,6 @@ import ( "sync" "time" - "golang.org/x/net/proxy" "tailscale.com/derp" "tailscale.com/net/dnscache" "tailscale.com/net/tlsdial" @@ -149,11 +148,10 @@ func (c *Client) connect(ctx context.Context, caller string) (client *derp.Clien host := c.url.Hostname() hostOrIP := host - var d dialer = new(net.Dialer) - var usingProxy bool - if cd, ok := proxy.FromEnvironmentUsing(d).(dialer); ok { - usingProxy = d != cd - d = cd + var stdDialer dialer = new(net.Dialer) + var dialer = stdDialer + if wrapDialer != nil { + dialer = wrapDialer(dialer) } if c.DNSCache != nil { @@ -161,12 +159,14 @@ func (c *Client) connect(ctx context.Context, caller string) (client *derp.Clien if err == nil { hostOrIP = ip.String() } - if err != nil && !usingProxy { + if err != nil && dialer == stdDialer { + // Return an error if we're not using a dial + // proxy that can do DNS lookups for us. return nil, err } } - tcpConn, err = d.DialContext(ctx, "tcp", net.JoinHostPort(hostOrIP, urlPort(c.url))) + tcpConn, err = dialer.DialContext(ctx, "tcp", net.JoinHostPort(hostOrIP, urlPort(c.url))) if err != nil { return nil, fmt.Errorf("dial of %q: %v", host, err) } @@ -326,3 +326,7 @@ func (c *Client) closeForReconnect(brokenClient *derp.Client) { } var ErrClientClosed = errors.New("derphttp.Client closed") + +// wrapDialer, if non-nil, specifies a function to wrap a dialer in a +// SOCKS-using dialer. It's set conditionally by socks.go. +var wrapDialer func(dialer) dialer diff --git a/derp/derphttp/socks.go b/derp/derphttp/socks.go new file mode 100644 index 000000000..24e0fee1b --- /dev/null +++ b/derp/derphttp/socks.go @@ -0,0 +1,20 @@ +// Copyright (c) 2020 Tailscale Inc & AUTHORS All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !ios + +package derphttp + +import "golang.org/x/net/proxy" + +func init() { + wrapDialer = wrapSocks +} + +func wrapSocks(d dialer) dialer { + if cd, ok := proxy.FromEnvironmentUsing(d).(dialer); ok { + return cd + } + return d +}