Esempio n. 1
0
    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()
Esempio n. 2
0
    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()
Esempio n. 3
0
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)
Esempio n. 4
0
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)