ban connections to/from bad peers for an hour
authorForrest Voight <forrest@forre.st>
Mon, 27 Feb 2012 02:57:02 +0000 (21:57 -0500)
committerForrest Voight <forrest@forre.st>
Mon, 27 Feb 2012 03:14:45 +0000 (22:14 -0500)
p2pool/bitcoin/p2p.py
p2pool/p2p.py

index 7312d3c..a26f763 100644 (file)
@@ -54,7 +54,7 @@ class BaseProtocol(protocol.Protocol):
             except:
                 print 'RECV', command, payload[:100].encode('hex') + ('...' if len(payload) > 100 else '')
                 log.err(None, 'Error handling message: (see RECV line)')
-                self.transport.loseConnection()
+                self.badPeerHappened()
     
     def packetReceived(self, command, payload2):
         handler = getattr(self, 'handle_' + command, None)
@@ -65,6 +65,9 @@ class BaseProtocol(protocol.Protocol):
         
         handler(**payload2)
     
+    def badPeerHappened(self):
+        self.transport.loseConnection()
+    
     def sendPacket(self, command, payload2):
         if len(command) >= 12:
             raise ValueError('command too long')
index 01b1df1..849891b 100644 (file)
@@ -67,6 +67,10 @@ class Protocol(bitcoin_p2p.BaseProtocol):
         
         bitcoin_p2p.BaseProtocol.packetReceived(self, command, payload2)
     
+    def badPeerHappened(self):
+        self.transport.loseConnection()
+        self.node.bans[self.transport.getPeer().host] = time.time() + 60*60
+    
     def _timeout(self):
         if self.transport.connected:
             print 'Connection timed out, disconnecting from %s:%i' % self.addr
@@ -221,6 +225,8 @@ class ServerFactory(protocol.ServerFactory):
     def buildProtocol(self, addr):
         if sum(self.conns.itervalues()) >= self.max_conns or self.conns.get(self._host_to_ident(addr.host), 0) >= 3:
             return None
+        if addr.host in self.node.bans and self.node.bans[addr.host] > time.time():
+            return None
         p = Protocol(self.node, True)
         p.factory = self
         return p
@@ -316,7 +322,11 @@ class ClientFactory(protocol.ClientFactory):
                 if len(self.conns) < self.desired_conns and len(self.attempts) < self.max_attempts and self.node.addr_store:
                     (host, port), = self.node.get_good_peers(1)
                     
-                    if self._host_to_ident(host) not in self.attempts:
+                    if self._host_to_ident(host) in self.attempts:
+                        pass
+                    elif host in self.node.bans and self.node.bans[host] > time.time():
+                        pass
+                    else:
                         #print 'Trying to connect to', host, port
                         reactor.connectTCP(host, port, self, timeout=5)
             except:
@@ -355,6 +365,7 @@ class Node(object):
         
         self.nonce = random.randrange(2**64)
         self.peers = {}
+        self.bans = {} # address -> end_time
         self.clientfactory = ClientFactory(self, desired_outgoing_conns, max_outgoing_attempts)
         self.serverfactory = ServerFactory(self, max_incoming_conns)
         self.running = False