From 0d2ae7b73f841833fe76521f1f38fc4c5192db34 Mon Sep 17 00:00:00 2001 From: Jeromy Date: Wed, 6 Apr 2016 18:41:59 -0700 Subject: [PATCH] don't break listener on failed msmux negotiation --- p2p/net/conn/dial_test.go | 48 +++++++++++++++++++++++++++++++++++++++ p2p/net/conn/listen.go | 3 ++- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/p2p/net/conn/dial_test.go b/p2p/net/conn/dial_test.go index c91fd5b..2179cbd 100644 --- a/p2p/net/conn/dial_test.go +++ b/p2p/net/conn/dial_test.go @@ -1,6 +1,7 @@ package conn import ( + "bytes" "fmt" "io" "net" @@ -349,3 +350,50 @@ func TestMultistreamHeader(t *testing.T) { t.Fatal(err) } } + +func TestFailedAccept(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + p1 := tu.RandPeerNetParamsOrFatal(t) + + l1, err := Listen(ctx, p1.Addr, p1.ID, p1.PrivKey) + if err != nil { + t.Fatal(err) + } + + p1.Addr = l1.Multiaddr() // Addr has been determined by kernel. + + done := make(chan struct{}) + go func() { + defer close(done) + con, err := net.Dial("tcp", l1.Addr().String()) + if err != nil { + t.Error("first dial failed: ", err) + } + + // write some garbage + con.Write(bytes.Repeat([]byte{255}, 1000)) + + con.Close() + + con, err = net.Dial("tcp", l1.Addr().String()) + if err != nil { + t.Error("second dial failed: ", err) + } + defer con.Close() + + err = msmux.SelectProtoOrFail(SecioTag, con) + if err != nil { + t.Error("msmux select failed: ", err) + } + }() + + c, err := l1.Accept() + if err != nil { + t.Fatal("connections after a failed accept should still work: ", err) + } + + c.Close() + <-done +} diff --git a/p2p/net/conn/listen.go b/p2p/net/conn/listen.go index 33b0975..3d81cba 100644 --- a/p2p/net/conn/listen.go +++ b/p2p/net/conn/listen.go @@ -106,7 +106,8 @@ func (l *listener) Accept() (net.Conn, error) { _, _, err = l.mux.Negotiate(maconn) if err != nil { - return nil, err + log.Info("negotiation of crypto protocol failed: ", err) + continue } c, err := newSingleConn(ctx, l.local, "", maconn) -- GitLab