Prevent BitTorrent nodes from infiltrating the DHT.
authorCameron Dale <camrdale@gmail.com>
Sat, 21 Jun 2008 19:59:43 +0000 (12:59 -0700)
committerCameron Dale <camrdale@gmail.com>
Sat, 21 Jun 2008 20:35:36 +0000 (13:35 -0700)
apt_p2p_Khashmir/actions.py
apt_p2p_Khashmir/krpc.py
apt_p2p_Khashmir/util.py

index c49959f..8542706 100644 (file)
@@ -196,8 +196,16 @@ class ActionBase:
         if self.finished or self.answered.has_key(node.id):
             # a day late and a dollar short
             return
-        self.answered[node.id] = 1
-        self.processResponse(dict)
+        try:
+            # Process the response
+            self.processResponse(dict)
+            self.answered[node.id] = 1
+        except Exception, e:
+            # Unexpected error with the response
+            log.msg("action %s failed on %s/%s: %r" % (self.action, node.host, node.port, e))
+            if node.id != self.caller.node.id:
+                self.caller.nodeFailed(node)
+            self.failed[node.id] = 1
         if self.outstanding.has_key(node.id):
             self.outstanding_results -= self.outstanding[node.id]
             del self.outstanding[node.id]
@@ -220,6 +228,8 @@ class ActionBase:
         Not called by default, but suitable for being called by
         L{processResponse} in a recursive node search.
         """
+        if nodes and type(nodes) != list:
+            raise ValueError, "got a malformed response, from bittorrent perhaps"
         for compact_node in nodes:
             node_contact = uncompact(compact_node)
             node = self.caller.Node(node_contact)
index c3dcfb6..9290cac 100644 (file)
@@ -100,6 +100,8 @@ def verifyMessage(msg):
             raise KrpcError, (KRPC_ERROR_MALFORMED_PACKET, "response not specified")
         if type(msg[RSP]) != dict:
             raise KrpcError, (KRPC_ERROR_MALFORMED_PACKET, "response is not a dictionary")
+#        if 'nodes' in msg[RSP] and type(msg[RSP]['nodes']) != list:
+#            raise KrpcError, (KRPC_ERROR_MALFORMED_PACKET, "wrong type of node, this is not bittorrent")
     elif msg[TYP] == ERR:
         if ERR not in msg:
             raise KrpcError, (KRPC_ERROR_MALFORMED_PACKET, "error not specified")
@@ -117,6 +119,8 @@ def verifyMessage(msg):
         raise KrpcError, (KRPC_ERROR_MALFORMED_PACKET, "no transaction ID specified")
     if type(msg[TID]) != str:
         raise KrpcError, (KRPC_ERROR_MALFORMED_PACKET, "transaction id is not a string")
+    if len(msg[TID]) != 20:
+        raise KrpcError, (KRPC_ERROR_MALFORMED_PACKET, "wrong type of node, this is not bittorrent")
 
 class hostbroker(protocol.DatagramProtocol):
     """The factory for the KRPC protocol.
@@ -349,7 +353,7 @@ class KRPC:
             msg = bdecode(data)
         except Exception, e:
             if self.config.get('SPEW', False):
-                log.msg("krpc bdecode error: ")
+                log.msg("krpc bdecode error from %r: " % (addr, ))
                 log.err(e)
             return
 
@@ -357,8 +361,7 @@ class KRPC:
         try:
             verifyMessage(msg)
         except Exception, e:
-            log.msg("krpc message verification error: ")
-            log.err(e)
+            log.msg("krpc message verification error from %r: %r" % (addr, e))
             return
 
         if self.config.get('SPEW', False):
index dba9d8b..8c010ba 100644 (file)
@@ -36,7 +36,7 @@ def uncompact(s):
     @raise ValueError: if the compact representation doesn't exist
     """
     if (len(s) != HASH_LENGTH+6):
-        raise ValueError
+        raise ValueError, "not compact node info: %r" % (s, )
     id = s[:HASH_LENGTH]
     host = '.'.join([str(ord(i)) for i in s[HASH_LENGTH:(HASH_LENGTH+4)]])
     port = (ord(s[HASH_LENGTH+4]) << 8) | ord(s[HASH_LENGTH+5])