aboutsummaryrefslogtreecommitdiffstats
path: root/p2p/peer_error_handler.go
diff options
context:
space:
mode:
authorzelig <viktor.tron@gmail.com>2014-10-23 23:57:54 +0800
committerzelig <viktor.tron@gmail.com>2014-10-23 23:57:54 +0800
commit771fbcc02e6d10cdf4cda2e8ec8ea23f11066feb (patch)
tree15a966dbe15e2f8388f69b396e613c7759b06f6d /p2p/peer_error_handler.go
parent119c5b40a7ed1aea1c871c0cb56956b8ef9303d9 (diff)
downloaddexon-771fbcc02e6d10cdf4cda2e8ec8ea23f11066feb.tar.gz
dexon-771fbcc02e6d10cdf4cda2e8ec8ea23f11066feb.tar.zst
dexon-771fbcc02e6d10cdf4cda2e8ec8ea23f11066feb.zip
initial commit of p2p package
Diffstat (limited to 'p2p/peer_error_handler.go')
-rw-r--r--p2p/peer_error_handler.go101
1 files changed, 101 insertions, 0 deletions
diff --git a/p2p/peer_error_handler.go b/p2p/peer_error_handler.go
new file mode 100644
index 000000000..ca6cae4db
--- /dev/null
+++ b/p2p/peer_error_handler.go
@@ -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
+ }
+}