Browse Source

cmd/tailscaled: allow running the SOCKS5 and HTTP proxies on the same port.

Fixes #3248

Signed-off-by: David Anderson <[email protected]>
David Anderson 4 years ago
parent
commit
6e584ffa33

+ 1 - 0
cmd/tailscaled/depaware.txt

@@ -199,6 +199,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
      💣 tailscale.com/net/netstat                                    from tailscale.com/ipn/ipnserver
         tailscale.com/net/packet                                     from tailscale.com/net/tstun+
         tailscale.com/net/portmapper                                 from tailscale.com/cmd/tailscaled+
+        tailscale.com/net/proxymux                                   from tailscale.com/cmd/tailscaled
         tailscale.com/net/socks5                                     from tailscale.com/net/socks5/tssocks
         tailscale.com/net/socks5/tssocks                             from tailscale.com/cmd/tailscaled
         tailscale.com/net/stun                                       from tailscale.com/net/netcheck+

+ 41 - 13
cmd/tailscaled/tailscaled.go

@@ -34,6 +34,7 @@ import (
 	"tailscale.com/logtail"
 	"tailscale.com/net/dns"
 	"tailscale.com/net/netns"
+	"tailscale.com/net/proxymux"
 	"tailscale.com/net/socks5/tssocks"
 	"tailscale.com/net/tstun"
 	"tailscale.com/paths"
@@ -302,8 +303,7 @@ func run() error {
 	}
 	pol.Logtail.SetLinkMonitor(linkMon)
 
-	socksListener := mustStartTCPListener("SOCKS5", args.socksAddr)
-	httpProxyListener := mustStartTCPListener("HTTP proxy", args.httpProxyAddr)
+	socksListener, httpProxyListener := mustStartProxyListeners(args.socksAddr, args.httpProxyAddr)
 
 	e, useNetstack, err := createEngine(logf, linkMon)
 	if err != nil {
@@ -516,18 +516,46 @@ func newNetstack(logf logger.Logf, e wgengine.Engine) (*netstack.Impl, error) {
 	return netstack.Create(logf, tunDev, e, magicConn)
 }
 
-func mustStartTCPListener(name, addr string) net.Listener {
-	if addr == "" {
-		return nil
+// mustStartProxyListeners creates listeners for local SOCKS and HTTP
+// proxies, if the respective addresses are not empty. socksAddr and
+// httpAddr can be the same, in which case socksListener will receive
+// connections that look like they're speaking SOCKS and httpListener
+// will receive everything else.
+//
+// socksListener and httpListener can be nil, if their respective
+// addrs are empty.
+func mustStartProxyListeners(socksAddr, httpAddr string) (socksListener, httpListener net.Listener) {
+	if socksAddr == httpAddr && socksAddr != "" && !strings.HasSuffix(socksAddr, ":0") {
+		ln, err := net.Listen("tcp", socksAddr)
+		if err != nil {
+			log.Fatalf("proxy listener: %v", err)
+		}
+		return proxymux.SplitSOCKSAndHTTP(ln)
 	}
-	ln, err := net.Listen("tcp", addr)
-	if err != nil {
-		log.Fatalf("%v listener: %v", name, err)
+
+	var err error
+	if socksAddr != "" {
+		socksListener, err = net.Listen("tcp", socksAddr)
+		if err != nil {
+			log.Fatalf("SOCKS5 listener: %v", err)
+		}
+		if strings.HasSuffix(socksAddr, ":0") {
+			// Log kernel-selected port number so integration tests
+			// can find it portably.
+			log.Printf("SOCKS5 listening on %v", socksListener.Addr())
+		}
 	}
-	if strings.HasSuffix(addr, ":0") {
-		// Log kernel-selected port number so integration tests
-		// can find it portably.
-		log.Printf("%v listening on %v", name, ln.Addr())
+	if httpAddr != "" {
+		httpListener, err = net.Listen("tcp", httpAddr)
+		if err != nil {
+			log.Fatalf("HTTP proxy listener: %v", err)
+		}
+		if strings.HasSuffix(httpAddr, ":0") {
+			// Log kernel-selected port number so integration tests
+			// can find it portably.
+			log.Printf("HTTP proxy listening on %v", httpListener.Addr())
+		}
 	}
-	return ln
+
+	return socksListener, httpListener
 }

+ 1 - 0
tstest/integration/tailscaled_deps_test_darwin.go

@@ -22,6 +22,7 @@ import (
 	_ "tailscale.com/net/interfaces"
 	_ "tailscale.com/net/netns"
 	_ "tailscale.com/net/portmapper"
+	_ "tailscale.com/net/proxymux"
 	_ "tailscale.com/net/socks5/tssocks"
 	_ "tailscale.com/net/tshttpproxy"
 	_ "tailscale.com/net/tstun"

+ 1 - 0
tstest/integration/tailscaled_deps_test_freebsd.go

@@ -22,6 +22,7 @@ import (
 	_ "tailscale.com/net/interfaces"
 	_ "tailscale.com/net/netns"
 	_ "tailscale.com/net/portmapper"
+	_ "tailscale.com/net/proxymux"
 	_ "tailscale.com/net/socks5/tssocks"
 	_ "tailscale.com/net/tshttpproxy"
 	_ "tailscale.com/net/tstun"

+ 1 - 0
tstest/integration/tailscaled_deps_test_linux.go

@@ -22,6 +22,7 @@ import (
 	_ "tailscale.com/net/interfaces"
 	_ "tailscale.com/net/netns"
 	_ "tailscale.com/net/portmapper"
+	_ "tailscale.com/net/proxymux"
 	_ "tailscale.com/net/socks5/tssocks"
 	_ "tailscale.com/net/tshttpproxy"
 	_ "tailscale.com/net/tstun"

+ 1 - 0
tstest/integration/tailscaled_deps_test_openbsd.go

@@ -22,6 +22,7 @@ import (
 	_ "tailscale.com/net/interfaces"
 	_ "tailscale.com/net/netns"
 	_ "tailscale.com/net/portmapper"
+	_ "tailscale.com/net/proxymux"
 	_ "tailscale.com/net/socks5/tssocks"
 	_ "tailscale.com/net/tshttpproxy"
 	_ "tailscale.com/net/tstun"

+ 1 - 0
tstest/integration/tailscaled_deps_test_windows.go

@@ -26,6 +26,7 @@ import (
 	_ "tailscale.com/net/interfaces"
 	_ "tailscale.com/net/netns"
 	_ "tailscale.com/net/portmapper"
+	_ "tailscale.com/net/proxymux"
 	_ "tailscale.com/net/socks5/tssocks"
 	_ "tailscale.com/net/tshttpproxy"
 	_ "tailscale.com/net/tstun"