initial commit of p2p package
This commit is contained in:
101
p2p/peer_error_handler.go
Normal file
101
p2p/peer_error_handler.go
Normal file
@ -0,0 +1,101 @@
|
||||
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
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user