github.com/bytom/bytom@v1.1.2-0.20221014091027-bbcba3df6075/p2p/security/score.go (about)

     1  package security
     2  
     3  import (
     4  	"sync"
     5  
     6  	log "github.com/sirupsen/logrus"
     7  )
     8  
     9  const (
    10  	defaultBanThreshold  = uint32(100)
    11  	defaultWarnThreshold = uint32(50)
    12  
    13  	LevelMsgIllegal              = 0x01
    14  	levelMsgIllegalPersistent    = uint32(20)
    15  	levelMsgIllegalTransient     = uint32(0)
    16  	LevelConnException           = 0x02
    17  	levelConnExceptionPersistent = uint32(0)
    18  	levelConnExceptionTransient  = uint32(20)
    19  )
    20  
    21  type PeersBanScore struct {
    22  	peers map[string]*DynamicBanScore
    23  	mtx   sync.Mutex
    24  }
    25  
    26  func NewPeersScore() *PeersBanScore {
    27  	return &PeersBanScore{
    28  		peers: make(map[string]*DynamicBanScore),
    29  	}
    30  }
    31  
    32  func (ps *PeersBanScore) DelPeer(ip string) {
    33  	ps.mtx.Lock()
    34  	defer ps.mtx.Unlock()
    35  
    36  	delete(ps.peers, ip)
    37  }
    38  
    39  func (ps *PeersBanScore) Increase(ip string, level byte, reason string) bool {
    40  	ps.mtx.Lock()
    41  	defer ps.mtx.Unlock()
    42  
    43  	var persistent, transient uint32
    44  	switch level {
    45  	case LevelMsgIllegal:
    46  		persistent = levelMsgIllegalPersistent
    47  		transient = levelMsgIllegalTransient
    48  	case LevelConnException:
    49  		persistent = levelConnExceptionPersistent
    50  		transient = levelConnExceptionTransient
    51  	default:
    52  		return false
    53  	}
    54  	banScore, ok := ps.peers[ip]
    55  	if !ok {
    56  		banScore = &DynamicBanScore{}
    57  		ps.peers[ip] = banScore
    58  	}
    59  	score := banScore.Increase(persistent, transient)
    60  	if score > defaultBanThreshold {
    61  		log.WithFields(log.Fields{"module": logModule, "address": ip, "score": score, "reason": reason}).Errorf("banning and disconnecting")
    62  		return true
    63  	}
    64  
    65  	if score > defaultWarnThreshold {
    66  		log.WithFields(log.Fields{"module": logModule, "address": ip, "score": score, "reason": reason}).Warning("ban score increasing")
    67  	}
    68  	return false
    69  }