| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- package p2p
- import (
- "net"
- )
- const (
- severityThreshold = 10
- )
- type DisconnectRequest struct {
- addr net.Addr
- reason DiscReason
- }
- type PeerErrorHandler struct {
- quit chan chan bool
- address net.Addr
- peerDisconnect chan DisconnectRequest
- severity int
- peerErrorChan chan *PeerError
- blacklist Blacklist
- }
- func NewPeerErrorHandler(address net.Addr, peerDisconnect chan DisconnectRequest, peerErrorChan chan *PeerError, blacklist Blacklist) *PeerErrorHandler {
- return &PeerErrorHandler{
- quit: make(chan chan bool),
- address: address,
- peerDisconnect: peerDisconnect,
- peerErrorChan: peerErrorChan,
- blacklist: blacklist,
- }
- }
- func (self *PeerErrorHandler) Start() {
- go self.listen()
- }
- func (self *PeerErrorHandler) Stop() {
- q := make(chan bool)
- self.quit <- q
- <-q
- }
- func (self *PeerErrorHandler) listen() {
- for {
- select {
- case peerError, ok := <-self.peerErrorChan:
- if ok {
- logger.Debugf("error %v\n", peerError)
- go self.handle(peerError)
- } else {
- return
- }
- case q := <-self.quit:
- q <- true
- return
- }
- }
- }
- func (self *PeerErrorHandler) handle(peerError *PeerError) {
- reason := DiscReason(' ')
- switch peerError.Code {
- case P2PVersionMismatch:
- reason = DiscIncompatibleVersion
- case PubkeyMissing, PubkeyInvalid:
- reason = DiscInvalidIdentity
- case PubkeyForbidden:
- reason = DiscUselessPeer
- case InvalidMsgCode, PacketTooShort, PayloadTooShort, MagicTokenMismatch, EmptyPayload, ProtocolBreach:
- reason = DiscProtocolError
- case PingTimeout:
- reason = DiscReadTimeout
- case WriteError, MiscError:
- reason = DiscNetworkError
- case InvalidGenesis, InvalidNetworkId, InvalidProtocolVersion:
- reason = DiscSubprotocolError
- default:
- self.severity += self.getSeverity(peerError)
- }
- if self.severity >= severityThreshold {
- reason = DiscSubprotocolError
- }
- if reason != DiscReason(' ') {
- self.peerDisconnect <- DisconnectRequest{
- addr: self.address,
- reason: reason,
- }
- }
- }
- func (self *PeerErrorHandler) getSeverity(peerError *PeerError) int {
- switch peerError.Code {
- case ReadError:
- return 4 //tolerate 3 :)
- default:
- return 1
- }
- }
|