ssh: don't start goroutines handling forwarded connections until needed

The extra goroutines were distracting while debugging something else,
especially as I wasn't using that feature. This also saves a bit of
memory.

Change-Id: Ia6489e64bbd3d5a6ff699a25018676d8ff8bd2e4
Reviewed-on: https://go-review.googlesource.com/112635
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Han-Wen Nienhuys <hanwen@google.com>
diff --git a/ssh/client.go b/ssh/client.go
index 6fd1994..ae6ca77 100644
--- a/ssh/client.go
+++ b/ssh/client.go
@@ -19,6 +19,8 @@
 type Client struct {
 	Conn
 
+	handleForwardsOnce sync.Once // guards calling (*Client).handleForwards
+
 	forwards        forwardList // forwarded tcpip connections from the remote side
 	mu              sync.Mutex
 	channelHandlers map[string]chan NewChannel
@@ -60,8 +62,6 @@
 		conn.Wait()
 		conn.forwards.closeAll()
 	}()
-	go conn.forwards.handleChannels(conn.HandleChannelOpen("forwarded-tcpip"))
-	go conn.forwards.handleChannels(conn.HandleChannelOpen("forwarded-streamlocal@openssh.com"))
 	return conn
 }
 
diff --git a/ssh/tcpip.go b/ssh/tcpip.go
index acf1717..80d35f5 100644
--- a/ssh/tcpip.go
+++ b/ssh/tcpip.go
@@ -90,10 +90,19 @@
 	rport uint32
 }
 
+// handleForwards starts goroutines handling forwarded connections.
+// It's called on first use by (*Client).ListenTCP to not launch
+// goroutines until needed.
+func (c *Client) handleForwards() {
+	go c.forwards.handleChannels(c.HandleChannelOpen("forwarded-tcpip"))
+	go c.forwards.handleChannels(c.HandleChannelOpen("forwarded-streamlocal@openssh.com"))
+}
+
 // ListenTCP requests the remote peer open a listening socket
 // on laddr. Incoming connections will be available by calling
 // Accept on the returned net.Listener.
 func (c *Client) ListenTCP(laddr *net.TCPAddr) (net.Listener, error) {
+	c.handleForwardsOnce.Do(c.handleForwards)
 	if laddr.Port == 0 && isBrokenOpenSSHVersion(string(c.ServerVersion())) {
 		return c.autoPortListenWorkaround(laddr)
 	}