ssh: soft code internal channel size for testing purposes

Change-Id: I2ee0ed4ba82d2d156a7896551dea04b28cdeceb0
Reviewed-on: https://go-review.googlesource.com/35184
Run-TryBot: Han-Wen Nienhuys <hanwen@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Adam Langley <agl@golang.org>
diff --git a/ssh/channel.go b/ssh/channel.go
index 6d709b5..195530e 100644
--- a/ssh/channel.go
+++ b/ssh/channel.go
@@ -461,8 +461,8 @@
 		pending:          newBuffer(),
 		extPending:       newBuffer(),
 		direction:        direction,
-		incomingRequests: make(chan *Request, 16),
-		msg:              make(chan interface{}, 16),
+		incomingRequests: make(chan *Request, chanSize),
+		msg:              make(chan interface{}, chanSize),
 		chanType:         chanType,
 		extraData:        extraData,
 		mux:              m,
diff --git a/ssh/client.go b/ssh/client.go
index c841e8d..c97f297 100644
--- a/ssh/client.go
+++ b/ssh/client.go
@@ -40,7 +40,7 @@
 		return nil
 	}
 
-	ch = make(chan NewChannel, 16)
+	ch = make(chan NewChannel, chanSize)
 	c.channelHandlers[channelType] = ch
 	return ch
 }
diff --git a/ssh/handshake.go b/ssh/handshake.go
index 03c950d..e68e058 100644
--- a/ssh/handshake.go
+++ b/ssh/handshake.go
@@ -19,6 +19,11 @@
 // messages are wrong when using ECDH.
 const debugHandshake = false
 
+// chanSize sets the amount of buffering SSH connections. This is
+// primarily for testing: setting chanSize=0 uncovers deadlocks more
+// quickly.
+const chanSize = 16
+
 // keyingTransport is a packet based transport that supports key
 // changes. It need not be thread-safe. It should pass through
 // msgNewKeys in both directions.
@@ -90,7 +95,7 @@
 		conn:          conn,
 		serverVersion: serverVersion,
 		clientVersion: clientVersion,
-		incoming:      make(chan []byte, 16),
+		incoming:      make(chan []byte, chanSize),
 		requestKex:    make(chan struct{}, 1),
 		startKex:      make(chan *pendingKex, 1),
 
diff --git a/ssh/handshake_test.go b/ssh/handshake_test.go
index 530d7d2..e61348f 100644
--- a/ssh/handshake_test.go
+++ b/ssh/handshake_test.go
@@ -249,9 +249,25 @@
 	defer trC.Close()
 	defer trS.Close()
 
+	done := make(chan int, 1)
+	const numPacket = 5
+	go func() {
+		defer close(done)
+		j := 0
+		for ; j < numPacket; j++ {
+			if _, err := trS.readPacket(); err != nil {
+				break
+			}
+		}
+
+		if j != numPacket {
+			t.Errorf("got %d, want 5 messages", j)
+		}
+	}()
+
 	<-checker.called
 
-	for i := 0; i < 5; i++ {
+	for i := 0; i < numPacket; i++ {
 		packet := make([]byte, 251)
 		packet[0] = msgRequestSuccess
 		if err := trC.writePacket(packet); err != nil {
@@ -263,18 +279,7 @@
 		}
 
 	}
-
-	j := 0
-	for ; j < 5; j++ {
-		_, err := trS.readPacket()
-		if err != nil {
-			break
-		}
-	}
-
-	if j != 5 {
-		t.Errorf("got %d, want 5 messages", j)
-	}
+	<-done
 }
 
 type syncChecker struct {
@@ -305,12 +310,19 @@
 	if err := trS.writePacket(packet); err != nil {
 		t.Fatalf("writePacket: %v", err)
 	}
+
 	// While we read out the packet, a key change will be
 	// initiated.
-	if _, err := trC.readPacket(); err != nil {
-		t.Fatalf("readPacket(client): %v", err)
-	}
+	done := make(chan int, 1)
+	go func() {
+		defer close(done)
+		if _, err := trC.readPacket(); err != nil {
+			t.Fatalf("readPacket(client): %v", err)
+		}
 
+	}()
+
+	<-done
 	<-sync.called
 }
 
diff --git a/ssh/mux.go b/ssh/mux.go
index f3a3ddd..27a527c 100644
--- a/ssh/mux.go
+++ b/ssh/mux.go
@@ -116,9 +116,9 @@
 func newMux(p packetConn) *mux {
 	m := &mux{
 		conn:             p,
-		incomingChannels: make(chan NewChannel, 16),
+		incomingChannels: make(chan NewChannel, chanSize),
 		globalResponses:  make(chan interface{}, 1),
-		incomingRequests: make(chan *Request, 16),
+		incomingRequests: make(chan *Request, chanSize),
 		errCond:          newCond(),
 	}
 	if debugMux {