peer: enforce strict timeout on opening handshake
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.
This commit is contained in:
parent
98d5dde9b2
commit
0e96d273d9
26
peer.go
26
peer.go
@ -296,11 +296,31 @@ func (p *peer) Start() error {
|
|||||||
// Before we launch any of the helper goroutines off the peer struct,
|
// Before we launch any of the helper goroutines off the peer struct,
|
||||||
// we'll first ensure proper adherance to the p2p protocl. The init
|
// we'll first ensure proper adherance to the p2p protocl. The init
|
||||||
// message MUST be sent before any other message.
|
// message MUST be sent before any other message.
|
||||||
msg, _, err := p.readNextMessage()
|
readErr := make(chan error, 1)
|
||||||
if err != nil {
|
msgChan := make(chan lnwire.Message, 1)
|
||||||
return err
|
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 msg, ok := msg.(*lnwire.Init); ok {
|
||||||
if err := p.handleInitMsg(msg); err != nil {
|
if err := p.handleInitMsg(msg); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -550,9 +550,6 @@ func (s *server) peerConnected(conn net.Conn, connReq *connmgr.ConnReq, inbound
|
|||||||
|
|
||||||
if err := p.Start(); err != nil {
|
if err := p.Start(); err != nil {
|
||||||
srvrLog.Errorf("unable to start peer: %v", err)
|
srvrLog.Errorf("unable to start peer: %v", err)
|
||||||
if p.connReq != nil {
|
|
||||||
s.connMgr.Remove(p.connReq.ID())
|
|
||||||
}
|
|
||||||
p.Disconnect()
|
p.Disconnect()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user