def __init__(self, routing_table_class=TreeRoutingTable, node_id=None): node_id = (node_id if node_id is not None else random.getrandbits(160)) # Verify the node_id is valid basic_coder.encode_network_id(node_id) KRPC_Sender.__init__(self, routing_table_class, node_id) # Datastore is used for storing peers on torrents self._datastore = MemoryDataStore(self._reactor) self._token_generator = _TokenGenerator()
def __init__(self, routing_table_class=TreeRoutingTable, node_id=None): node_id = node_id if node_id is not None else random.getrandbits(160) # Verify the node_id is valid basic_coder.encode_network_id(node_id) KRPC_Sender.__init__(self, routing_table_class, node_id) # Datastore is used for storing peers on torrents self._datastore = MemoryDataStore(self._reactor) self._token_generator = _TokenGenerator()
class KRPC_Responder(KRPC_Sender): implements(IKRPC_Responder) def __init__(self, routing_table_class=TreeRoutingTable, node_id=None): node_id = (node_id if node_id is not None else random.getrandbits(160)) # Verify the node_id is valid basic_coder.encode_network_id(node_id) KRPC_Sender.__init__(self, routing_table_class, node_id) # Datastore is used for storing peers on torrents self._datastore = MemoryDataStore(self._reactor) self._token_generator = _TokenGenerator() def ping_Received(self, query, address): # The ping response needs no additional protocol # data, so build_response() is empty response = query.build_response() self.sendResponse(response, address) def find_node_Received(self, query, address): target_node = self.routing_table.get_node(query.target_id) # If we have the target node, return it # otherwise return the nodes closest to the target ID if target_node is not None: nodes = [target_node] else: nodes = self.routing_table.get_closest_nodes(query.target_id) # Include the nodes in the response response = query.build_response(nodes=nodes) self.sendResponse(response, address) def get_peers_Received(self, query, address): nodes = None peers = self._datastore.get(query.target_id) # Check if we have peers for the target infohash # If we don't, return the closest nodes in our routing table instead if len(peers) == 0: peers = None nodes = self.routing_table.get_closest_nodes(query.target_id) # Generate a token that we can recalculate # later (upon receiving an announce_peer query token = self._token_generator.generate(query, address) # Attach the peers, nodes, and token to the response message response = query.build_response(nodes=nodes, peers=peers, token=token) self.sendResponse(response, address) def announce_peer_Received(self, query, address): token = query.token token_is_valid = self._token_generator.verify(query, address, token) if token_is_valid: # If the token is valid, we authenticate # the querying node to store itself as a peer # in our datastore node_ip, node_port = address peer_address = (node_ip, query.port) self._datastore.put(query.target_id, peer_address) # announce_peer responses have no additional # data (and serve just as a confirmation) response = query.build_response() self.sendResponse(response, address) else: log.msg("Invalid token/query/querier combination in" " announce_peerReceived") def ping(self, address, timeout=None): timeout = timeout or constants.rpctimeout query = Query() query.rpctype = "ping" return self.sendQuery(query, address, timeout) def find_node(self, address, node_id, timeout=None): timeout = timeout or constants.rpctimeout query = Query() query.rpctype = "find_node" query.target_id = node_id return self.sendQuery(query, address, timeout) def get_peers(self, address, target_id, timeout=None): timeout = timeout or constants.rpctimeout query = Query() query.rpctype = "get_peers" query.target_id = target_id return self.sendQuery(query, address, timeout) def announce_peer(self, address, target_id, token, port, timeout=None): timeout = timeout or constants.rpctimeout query = Query() query.rpctype = "announce_peer" query.target_id = target_id query.token = token query.port = port return self.sendQuery(query, address, timeout)
class KRPC_Responder(KRPC_Sender): implements(IKRPC_Responder) def __init__(self, routing_table_class=TreeRoutingTable, node_id=None): node_id = node_id if node_id is not None else random.getrandbits(160) # Verify the node_id is valid basic_coder.encode_network_id(node_id) KRPC_Sender.__init__(self, routing_table_class, node_id) # Datastore is used for storing peers on torrents self._datastore = MemoryDataStore(self._reactor) self._token_generator = _TokenGenerator() def ping_Received(self, query, address): # The ping response needs no additional protocol # data, so build_response() is empty response = query.build_response() self.sendResponse(response, address) def find_node_Received(self, query, address): target_node = self.routing_table.get_node(query.target_id) # If we have the target node, return it # otherwise return the nodes closest to the target ID if target_node is not None: nodes = [target_node] else: nodes = self.routing_table.get_closest_nodes(query.target_id) # Include the nodes in the response response = query.build_response(nodes=nodes) self.sendResponse(response, address) def get_peers_Received(self, query, address): nodes = None peers = self._datastore.get(query.target_id) # Check if we have peers for the target infohash # If we don't, return the closest nodes in our routing table instead if len(peers) == 0: peers = None nodes = self.routing_table.get_closest_nodes(query.target_id) # Generate a token that we can recalculate # later (upon receiving an announce_peer query token = self._token_generator.generate(query, address) # Attach the peers, nodes, and token to the response message response = query.build_response(nodes=nodes, peers=peers, token=token) self.sendResponse(response, address) def announce_peer_Received(self, query, address): token = query.token token_is_valid = self._token_generator.verify(query, address, token) if token_is_valid: # If the token is valid, we authenticate # the querying node to store itself as a peer # in our datastore node_ip, node_port = address peer_address = (node_ip, query.port) self._datastore.put(query.target_id, peer_address) # announce_peer responses have no additional # data (and serve just as a confirmation) response = query.build_response() self.sendResponse(response, address) else: log.msg("Invalid token/query/querier combination in" " announce_peerReceived") def ping(self, address, timeout=None): timeout = timeout or constants.rpctimeout query = Query() query.rpctype = "ping" return self.sendQuery(query, address, timeout) def find_node(self, address, node_id, timeout=None): timeout = timeout or constants.rpctimeout query = Query() query.rpctype = "find_node" query.target_id = node_id return self.sendQuery(query, address, timeout) def get_peers(self, address, target_id, timeout=None): timeout = timeout or constants.rpctimeout query = Query() query.rpctype = "get_peers" query.target_id = target_id return self.sendQuery(query, address, timeout) def announce_peer(self, address, target_id, token, port, timeout=None): timeout = timeout or constants.rpctimeout query = Query() query.rpctype = "announce_peer" query.target_id = target_id query.token = token query.port = port return self.sendQuery(query, address, timeout)