les: ban bad light client

This commit is contained in:
rjl493456442 2020-03-12 20:32:24 +08:00
parent 13712f52d8
commit 89778cc947
3 changed files with 46 additions and 4 deletions

View file

@ -1030,6 +1030,24 @@ func (ps *clientPeerSet) allPeers() []*clientPeer {
return list return list
} }
// banPeer terminates the connection and bans re-connection
// or dialing in the short future.
func (ps *clientPeerSet) banPeer(id string) error {
ps.lock.Lock()
defer ps.lock.Unlock()
peer := ps.peers[id]
if peer == nil {
return errNotRegistered
}
delete(ps.peers, id)
for _, sub := range ps.subscribers {
sub.unregisterPeer(peer)
}
peer.Ban()
return nil
}
// close disconnects all peers. No new peers can be registered // close disconnects all peers. No new peers can be registered
// after close has returned. // after close has returned.
func (ps *clientPeerSet) close() { func (ps *clientPeerSet) close() {
@ -1181,6 +1199,24 @@ func (ps *serverPeerSet) allPeers() []*serverPeer {
return list return list
} }
// banPeer terminates the connection and bans re-connection
// or dialing in the short future.
func (ps *serverPeerSet) banPeer(id string) error {
ps.lock.Lock()
defer ps.lock.Unlock()
peer := ps.peers[id]
if peer == nil {
return errNotRegistered
}
delete(ps.peers, id)
for _, sub := range ps.subscribers {
sub.unregisterPeer(peer)
}
peer.Ban()
return nil
}
// close disconnects all peers. No new peers can be registered // close disconnects all peers. No new peers can be registered
// after close has returned. // after close has returned.
func (ps *serverPeerSet) close() { func (ps *serverPeerSet) close() {

View file

@ -108,7 +108,7 @@ func (h *serverHandler) runPeer(version uint, p *p2p.Peer, rw p2p.MsgReadWriter)
return h.handle(peer) return h.handle(peer)
} }
func (h *serverHandler) handle(p *clientPeer) error { func (h *serverHandler) handle(p *clientPeer) (err error) {
p.Log().Debug("Light Ethereum peer connected", "name", p.Name()) p.Log().Debug("Light Ethereum peer connected", "name", p.Name())
// Execute the LES handshake // Execute the LES handshake
@ -152,7 +152,12 @@ func (h *serverHandler) handle(p *clientPeer) error {
connectedAt := mclock.Now() connectedAt := mclock.Now()
defer func() { defer func() {
wg.Wait() // Ensure all background task routines have exited. wg.Wait() // Ensure all background task routines have exited.
h.server.peers.unregister(p.id)
if err == errTooManyInvalidRequest {
h.server.peers.banPeer(p.id)
} else {
h.server.peers.unregister(p.id)
}
h.server.clientPool.disconnect(p) h.server.clientPool.disconnect(p)
clientConnectionGauge.Update(int64(h.server.peers.len())) clientConnectionGauge.Update(int64(h.server.peers.len()))
connectionTimer.Update(time.Duration(mclock.Now() - connectedAt)) connectionTimer.Update(time.Duration(mclock.Now() - connectedAt))

View file

@ -123,7 +123,8 @@ type dialScheduler struct {
historyTimer mclock.Timer historyTimer mclock.Timer
historyTimerTime mclock.AbsTime historyTimerTime mclock.AbsTime
// The bannedHistory keeps all recently banned nodes which won't be dialed for a short time // The bannedHistory keeps all recently banned nodes
// which won't be dialed for a short time
bannedHistory expHeap bannedHistory expHeap
// for logStats // for logStats
@ -288,7 +289,7 @@ loop:
d.updateStaticPool(c.node.ID()) d.updateStaticPool(c.node.ID())
case c := <-d.banPeerCh: case c := <-d.banPeerCh:
// If it's not a static node and been banned, // If it's not a static node and has been banned,
// add to the blacklist for dialing. // add to the blacklist for dialing.
if d.static[c.node.ID()] == nil { if d.static[c.node.ID()] == nil {
remoteIP := netutil.AddrIP(c.fd.RemoteAddr()) remoteIP := netutil.AddrIP(c.fd.RemoteAddr())