diff --git a/common/repeat_timer.go b/common/repeat_timer.go index ce491f20a..2822b9683 100644 --- a/common/repeat_timer.go +++ b/common/repeat_timer.go @@ -6,6 +6,7 @@ import "sync" /* RepeatTimer repeatedly sends a struct{}{} to .Ch after each "dur" period. It's good for keeping connections alive. +A RepeatTimer must be Stop()'d or it will keep a goroutine alive. */ type RepeatTimer struct { Ch chan time.Time diff --git a/p2p/switch.go b/p2p/switch.go index 7def88dc4..f522a9a23 100644 --- a/p2p/switch.go +++ b/p2p/switch.go @@ -156,13 +156,16 @@ func (sw *Switch) Stop() { } // NOTE: This performs a blocking handshake before the peer is added. +// CONTRACT: Iff error is returned, peer is nil, and conn is immediately closed. func (sw *Switch) AddPeerWithConnection(conn net.Conn, outbound bool) (*Peer, error) { // First, perform handshake peerNodeInfo, err := peerHandshake(conn, sw.nodeInfo) if err != nil { + conn.Close() return nil, err } if err := sw.nodeInfo.CompatibleWith(peerNodeInfo); err != nil { + conn.Close() return nil, err } @@ -183,6 +186,7 @@ func (sw *Switch) AddPeerWithConnection(conn net.Conn, outbound bool) (*Peer, er log.Info("Added peer", "peer", peer) } else { log.Info("Ignoring duplicate peer", "peer", peer) + peer.stop() // will also close conn return nil, ErrSwitchDuplicatePeer }