From 0e96d273d9ff199579a2f697cc96af7fe8bbb3b3 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Wed, 29 Mar 2017 18:33:20 -0700 Subject: [PATCH] peer: enforce strict timeout on opening handshake MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit modifies the logic around the opening p2p handshake to enforce a strict timeout around the receipt of the responding init message. Before this commit, it was possible for the daemon and certain RPC calls to deadlock as if a peer connected, but didn’t respond with an init msg, then we’d be sitting there waiting for them to respond. With this commit, we’ll now time out, kill the connection and then possible attempt to re-connect if the connection was persistent. --- peer.go | 26 +++++++++++++++++++++++--- server.go | 3 --- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/peer.go b/peer.go index c9fcb9ad..ac7d9119 100644 --- a/peer.go +++ b/peer.go @@ -296,11 +296,31 @@ func (p *peer) Start() error { // Before we launch any of the helper goroutines off the peer struct, // we'll first ensure proper adherance to the p2p protocl. The init // message MUST be sent before any other message. - msg, _, err := p.readNextMessage() - if err != nil { - return err + readErr := make(chan error, 1) + msgChan := make(chan lnwire.Message, 1) + go func() { + msg, _, err := p.readNextMessage() + if err != nil { + readErr <- err + msgChan <- nil + } + readErr <- nil + msgChan <- msg + }() + + select { + // In order to avoid blocking indefinately, we'll give the other peer + // an upper timeout of 5 seconds to respond before we bail out early. + case <-time.After(time.Second * 5): + return fmt.Errorf("peer did not complete handshake within 5 " + + "seconds") + case err := <-readErr: + if err != nil { + return err + } } + msg := <-msgChan if msg, ok := msg.(*lnwire.Init); ok { if err := p.handleInitMsg(msg); err != nil { return err diff --git a/server.go b/server.go index c892535f..45173c7d 100644 --- a/server.go +++ b/server.go @@ -550,9 +550,6 @@ func (s *server) peerConnected(conn net.Conn, connReq *connmgr.ConnReq, inbound if err := p.Start(); err != nil { srvrLog.Errorf("unable to start peer: %v", err) - if p.connReq != nil { - s.connMgr.Remove(p.connReq.ID()) - } p.Disconnect() return }