diff --git a/server.go b/server.go index bed4de95..9f4c54d3 100644 --- a/server.go +++ b/server.go @@ -1651,6 +1651,12 @@ func (s *server) handleAddPeerMsg(state *peerState, sp *serverPeer) bool { } } + // Update the address' last seen time if the peer has acknowledged + // our version and has sent us its version as well. + if sp.VerAckReceived() && sp.VersionKnown() && sp.NA() != nil { + s.addrManager.Connected(sp.NA()) + } + return true } @@ -1665,30 +1671,27 @@ func (s *server) handleDonePeerMsg(state *peerState, sp *serverPeer) { } else { list = state.outboundPeers } + + // Regardless of whether the peer was found in our list, we'll inform + // our connection manager about the disconnection. This can happen if we + // process a peer's `done` message before its `add`. + if !sp.Inbound() { + if sp.persistent { + s.connManager.Disconnect(sp.connReq.ID()) + } else { + s.connManager.Remove(sp.connReq.ID()) + go s.connManager.NewConnReq() + } + } + if _, ok := list[sp.ID()]; ok { if !sp.Inbound() && sp.VersionKnown() { state.outboundGroups[addrmgr.GroupKey(sp.NA())]-- } - if !sp.Inbound() && sp.connReq != nil { - s.connManager.Disconnect(sp.connReq.ID()) - } delete(list, sp.ID()) srvrLog.Debugf("Removed peer %s", sp) return } - - if sp.connReq != nil { - s.connManager.Disconnect(sp.connReq.ID()) - } - - // Update the address' last seen time if the peer has acknowledged - // our version and has sent us its version as well. - if sp.VerAckReceived() && sp.VersionKnown() && sp.NA() != nil { - s.addrManager.Connected(sp.NA()) - } - - // If we get here it means that either we didn't know about the peer - // or we purposefully deleted it. } // handleBanPeerMsg deals with banning peers. It is invoked from the @@ -2025,14 +2028,19 @@ func (s *server) outboundPeerConnected(c *connmgr.ConnReq, conn net.Conn) { p, err := peer.NewOutboundPeer(newPeerConfig(sp), c.Addr.String()) if err != nil { srvrLog.Debugf("Cannot create outbound peer %s: %v", c.Addr, err) - s.connManager.Disconnect(c.ID()) + if c.Permanent { + s.connManager.Disconnect(c.ID()) + } else { + s.connManager.Remove(c.ID()) + go s.connManager.NewConnReq() + } + return } sp.Peer = p sp.connReq = c sp.isWhitelisted = isWhitelisted(conn.RemoteAddr()) sp.AssociateConnection(conn) go s.peerDoneHandler(sp) - s.addrManager.Attempt(sp.NA()) } // peerDoneHandler handles peer disconnects by notifiying the server that it's @@ -2802,6 +2810,9 @@ func newServer(listenAddrs, agentBlacklist, agentWhitelist []string, continue } + // Mark an attempt for the valid address. + s.addrManager.Attempt(addr.NetAddress()) + addrString := addrmgr.NetAddressKey(addr.NetAddress()) return addrStringToNetAddr(addrString) }