From 012632404abdeb80eb0006c0712722563f3c6ab2 Mon Sep 17 00:00:00 2001 From: Ng Wei Han <47109095+weiihann@users.noreply.github.com> Date: Mon, 8 Jan 2024 16:34:02 +0800 Subject: [PATCH] p2p: no peer reconnect if explicitly disconnected (#2115) --- p2p/server.go | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/p2p/server.go b/p2p/server.go index 3eee8796a2..d9c5cc5bcf 100644 --- a/p2p/server.go +++ b/p2p/server.go @@ -225,7 +225,8 @@ type Server struct { checkpointAddPeer chan *conn // State of run loop and listenLoop. - inboundHistory expHeap + inboundHistory expHeap + disconnectEnodeSet map[enode.ID]struct{} } type peerOpFunc func(map[enode.ID]*Peer) @@ -513,6 +514,7 @@ func (srv *Server) Start() (err error) { srv.removetrusted = make(chan *enode.Node) srv.peerOp = make(chan peerOpFunc) srv.peerOpDone = make(chan struct{}) + srv.disconnectEnodeSet = make(map[enode.ID]struct{}) if err := srv.setupLocalNode(); err != nil { return err @@ -836,6 +838,9 @@ running: case pd := <-srv.delpeer: // A peer disconnected. d := common.PrettyDuration(mclock.Now() - pd.created) + if !pd.requested && pd.err == DiscRequested { + srv.disconnectEnodeSet[pd.ID()] = struct{}{} + } delete(peers, pd.ID()) srv.log.Debug("Removing p2p peer", "peercount", len(peers), "id", pd.ID(), "duration", d, "req", pd.requested, "err", pd.err) srv.dialsched.peerRemoved(pd.rw) @@ -889,6 +894,11 @@ func (srv *Server) addPeerChecks(peers map[enode.ID]*Peer, inboundCount int, c * if len(srv.Protocols) > 0 && countMatchingProtocols(srv.Protocols, c.caps) == 0 { return DiscUselessPeer } + + if _, ok := srv.disconnectEnodeSet[c.node.ID()]; ok { + return errors.New("explicitly disconnected peer previously") + } + // Repeat the post-handshake checks because the // peer set might have changed since those checks were performed. return srv.postHandshakeChecks(peers, inboundCount, c) @@ -967,6 +977,7 @@ func (srv *Server) checkInboundConn(remoteIP net.IP) error { if remoteIP == nil { return nil } + // Reject connections that do not match NetRestrict. if srv.NetRestrict != nil && !srv.NetRestrict.Contains(remoteIP) { return fmt.Errorf("not in netrestrict list")