def on_response_received(self, transaction): # Update the id of the remote node. transaction.response_node.id_20 = transaction.response["r"]["id"] # Add the node that reponded to us. We most likely already have this one. self._server.remote_nodes.add(transaction.response_node) # A find_node or get_peers response may carry extra nodes. if transaction.query["q"] == "find_node" or transaction.query["q"] == "get_peers": nodes = transaction.response["r"].get("nodes", "") for i in xrange(0, len(nodes), 26): id_26 = nodes[i : i + 26] if not self._server.remote_nodes.get_node(id_26): self._server.remote_nodes.add(Node.from_id_26(id_26))
def _receiver(self): """ Run in a different thread, and have as only goal to receive messages, parse them, and put them into a thread safe queue for further handling """ while True: try: # Receive message raw_message, connect_info = self._sock.recvfrom(4096) message = bdecode(raw_message) # print "Received f " + str(connect_info) + ":\t" + str(message) # This is a query from another peer. if message['y'] == 'q': # Retrieve or create source node. id_26 = message['a']['id'] + socket.inet_aton(connect_info[0]) + struct.pack(r'!H', connect_info[1]) source_node = self.remote_nodes.get_node(id_26) or Node.from_id_26(id_26) transaction = Transaction(query=message, query_node=source_node, response_node=self.node) # create transaction self._running_transactions[transaction.id] = transaction # Add it to running transactions for handler in self.on_query_received: handler(transaction) # Notify listeners elif message['y'] == 'e': raise Exception # This is a response to a transaction we started. elif message['y'] == 'r': transaction = self._running_transactions.pop(message["t"]) # pop transaction transaction.response = message for handler in self.on_response_received: handler(transaction) # Notify listeners else: raise Exception except socket.timeout: pass except BTFailure: pass except: print traceback.format_exc()