def __init__(self, my_node, querier, bootstrap_lookup_f, bootstrap_nodes):
        self.my_node = my_node
        self.querier = querier
        self.bootstrap_lookup = bootstrap_lookup_f
        #Copy the bootstrap list
        self.bootstrap_nodes = [n for n in bootstrap_nodes]

        self.table = RoutingTable(my_node, NODES_PER_BUCKET)
        self.ping_msg = message.OutgoingPingQuery(my_node.id)
        self.find_closest_msg = message.OutgoingFindNodeQuery(
            my_node.id, my_node.id)
        #This must be called by an external party: self.do_bootstrap()
        #After initializing callbacks

        # maintenance variables
        #        self.last_maintenance_index = -1

        self.maintenance_mode = BOOTSTRAP_MODE
        self.lookup_mode = False

        self._query_received_queue = _QueryReceivedQueue(self.table)
        self._found_nodes_queue = _FoundNodesQueue(self.table)

        self.maintenance_tasks = [
            self._ping_a_staled_rnode, self._ping_a_query_received_node,
            self._ping_a_found_node
        ]
Esempio n. 2
0
 def __init__(self, my_id, target):
     GetPeersLookup.__init__(self, my_id, target, None)
     self.bootstrap_alpha = 4
     self.normal_alpha = 4
     self.normal_m = 1
     self.slowdown_alpha = 4
     self.slowdown_m = 1
     self._get_peers_msg = message.OutgoingFindNodeQuery(my_id, target)
Esempio n. 3
0
    def send_query_and_get_response(self, querier_, later_delay=0):
        ping_msg = message.OutgoingPingQuery(tc.CLIENT_ID)
        msg = message.OutgoingFindNodeQuery(tc.CLIENT_ID,
                                                 tc.CLIENT_ID)
        if later_delay:
            task = querier_.send_query_later(later_delay,
                                             msg,
                                             tc.EXTERNAL_NODE,
                                             self.on_response,
                                             self.on_timeout,
                                             self.on_error,
                                             tc.TIMEOUT_DELAY)
            # This second query is just to have two elements
            # in the querier_.pending[tc.EXTERNAL_ADDR] list
            task = querier_.send_query_later(later_delay,
                                             msg,
                                             tc.EXTERNAL_NODE,
                                             self.on_response,
                                             self.on_timeout,
                                             self.on_error,
                                             tc.TIMEOUT_DELAY)
        else:
            node_ = (querier_ == self.querier_mock) and tc.SERVER_NODE
            query = querier_.send_query(ping_msg, node_ or tc.EXTERNAL_NODE,
                                        self.on_response,
                                        self.on_timeout, self.on_error,
                                        timeout_delay=tc.TIMEOUT_DELAY)
        # querier creates TID
        msg_tid = '\0\0'
        if querier_ is self.querier_mock:
            # server gets query
            # the server creates the response
            pong_msg = message.OutgoingPingResponse(tc.SERVER_ID)
            pong_msg_data = pong_msg.encode(msg_tid)
            # the client gets the response
            # rpc_m decodes msg and calls callback
            pong_msg = message.IncomingMsg(pong_msg_data)
            querier_.on_response_received(pong_msg, tc.SERVER_ADDR)
        if later_delay:
            ok_(not self.got_response)
            ok_(not self.got_timeout)
            time.sleep(later_delay*2)
        time.sleep(tc.TIMEOUT_DELAY+.1)
        ### It crashed (timeout_task.cancelled??????)


        #TODO2: move the 'real' tests to integration
        
        ###############################################
        ### A DHT node must be running on peer_addr ###
        ###############################################
        ok_(self.got_response)
        ok_(not self.got_timeout)
Esempio n. 4
0
 def setup(self):
     self.queries = [
         m.OutgoingPingQuery(tc.CLIENT_ID),
         m.OutgoingFindNodeQuery(tc.CLIENT_ID, tc.TARGET_ID),
         m.OutgoingGetPeersQuery(tc.CLIENT_ID, tc.INFO_HASH),
         m.OutgoingAnnouncePeerQuery(tc.CLIENT_ID, tc.INFO_HASH, tc.BT_PORT,
                                     tc.TOKEN),
     ]
     self.responses = [
         m.OutgoingPingResponse(tc.SERVER_ID),
         m.OutgoingFindNodeResponse(tc.SERVER_ID, tc.NODES),
         m.OutgoingGetPeersResponse(tc.SERVER_ID, tc.TOKEN, tc.NODES,
                                    tc.PEERS),
         m.OutgoingAnnouncePeerResponse(tc.SERVER_ID),
     ]
Esempio n. 5
0
 def test_find_node(self):
     #client
     outgoing_query = m.OutgoingFindNodeQuery(tc.CLIENT_ID, tc.NODE_ID)
     data = outgoing_query.encode(tc.TID)
     #server
     incoming_query = m.IncomingMsg(data, tc.CLIENT_ADDR)
     assert incoming_query.type is m.QUERY
     outgoing_response = m.OutgoingFindNodeResponse(tc.SERVER_ID, tc.NODES)
     data = outgoing_response.encode(incoming_query.tid)
     #client
     incoming_response = m.IncomingMsg(data, tc.SERVER_ADDR)
     eq_(incoming_response.type, m.RESPONSE)
     #incoming_response.sanitize_response(outgoing_query.query)
     for n1, n2 in zip(tc.NODES, incoming_response.all_nodes):
         eq_(n1, n2)
Esempio n. 6
0
 def test_return_response_for_find_node(self):
     # client side
     query_msg = message.OutgoingFindNodeQuery(tc.CLIENT_ID, tc.TARGET_ID)
     # querier encodes
     query_data = query_msg.encode(tc.TID)
     # server side
     # rpc_manager.datagram_received() decodes
     query_msg = message.IncomingMsg(query_data)
     # rpc calls responder
     assert not self.notification_callback_done
     response_msg = self.responder.on_query_received(
         query_msg, tc.CLIENT_ADDR)
     response_data = response_msg.encode(query_msg.tid)
     assert self.notification_callback_done
     expected_msg = message.OutgoingFindNodeResponse(tc.SERVER_ID, tc.NODES)
     expected_data = expected_msg.encode(tc.TID)
     eq_(response_data, expected_data)
 def _send_maintenance_ping(self, node_):
     m_bucket, r_bucket = self.table.buckets[0]
     if m_bucket.there_is_room() and r_bucket.there_is_room():
         target = identifier.RandomId()
         msg = message.OutgoingFindNodeQuery(self.my_node.id, target)
         m_bucket, r_bucket = self.table.buckets[0]
         print 'FIND_NODE(%d:%d:%d)' % (0, len(m_bucket), len(r_bucket)),
     else:
         print 'PING',
         msg = self.ping_msg
     if node_.id:
         m_bucket, r_bucket = self.table.buckets[0]
         print 'to %r - %d:%d:%d --' % (node_.addr,
                                        node_.log_distance(self.my_node),
                                        len(m_bucket), len(r_bucket))
     else:
         print 'to UNKNOWN id'
     self.querier.send_query(msg, node_)
Esempio n. 8
0
 def test_find_node_with_error(self):
     # Client creates a query
     fn_msg = message.OutgoingFindNodeQuery(tc.CLIENT_ID, tc.TARGET_ID)
     # the destination's ID is unknown
     q = Query(fn_msg, node.Node(tc.SERVER_ADDR))
     # Querier.register_query sets a TID and timeout_task
     q.tid = tc.TID
     q.timeout_task = minitwisted.Task(TIMEOUT_DELAY, None)
     q.query_ts = time.time()
     # The query is sent
     # The server creates a response
     fn_r_out = message.OutgoingErrorMsg(message.GENERIC_E)
     bencoded_fn_r = fn_r_out.encode(tc.TID)
     time.sleep(1)
     # The client receives the bencoded message
     fn_r_in = message.IncomingMsg(bencoded_fn_r, tc.SERVER_ADDR)
     q.on_error_received(fn_r_in)
     assert 1 < q.rtt < 1.1
     assert q.lookup_obj is None
    def __init__(self, my_node, querier, bootstrap_nodes):
        self.my_node = my_node
        self.querier = querier
        #Copy the bootstrap list
        self.bootstrap_nodes = [n for n in bootstrap_nodes]

        self.main = RoutingTable(my_node, NODES_PER_BUCKET)
        self.replacement = RoutingTable(my_node, NODES_PER_BUCKET)
        self.ping_msg = message.OutgoingPingQuery(my_node.id)
        self.find_node_msg = message.OutgoingFindNodeQuery(
            my_node.id, my_node.id)
        self.mode = BOOTSTRAP_MODE
        self.num_concurrent_refresh_msgs = 0
        #This must be called by an external party: self.do_bootstrap()
        #After initializing callbacks

        # Add myself to the routing table
        rnode = self.main.add(my_node)
        self._reset_refresh_task(rnode)
Esempio n. 10
0
    def test_msg_exhanges(self):
        self._exchange_msgs(m.OutgoingPingQuery(tc.CLIENT_ID),
                            m.OutgoingPingResponse(tc.SERVER_ID))

        self._exchange_msgs(
            m.OutgoingFindNodeQuery(tc.CLIENT_ID, tc.TARGET_ID),
            m.OutgoingFindNodeResponse(tc.SERVER_ID, tc.NODES))

        # Test different combinations of token, nodes and peers
        self._exchange_msgs(
            m.OutgoingGetPeersQuery(tc.CLIENT_ID, tc.INFO_HASH),
            m.OutgoingGetPeersResponse(tc.SERVER_ID, tc.TOKEN, tc.NODES,
                                       tc.PEERS))
        self._exchange_msgs(
            m.OutgoingGetPeersQuery(tc.CLIENT_ID, tc.INFO_HASH),
            m.OutgoingGetPeersResponse(tc.SERVER_ID, tc.TOKEN, tc.NODES))
        self._exchange_msgs(
            m.OutgoingGetPeersQuery(tc.CLIENT_ID, tc.INFO_HASH),
            m.OutgoingGetPeersResponse(tc.SERVER_ID, tc.TOKEN, peers=tc.PEERS))
        assert_raises(AssertionError, m.OutgoingGetPeersResponse, tc.SERVER_ID,
                      tc.TOKEN)
        self._exchange_msgs(
            m.OutgoingGetPeersQuery(tc.CLIENT_ID, tc.INFO_HASH),
            m.OutgoingGetPeersResponse(tc.SERVER_ID, peers=tc.PEERS))
        self._exchange_msgs(
            m.OutgoingGetPeersQuery(tc.CLIENT_ID, tc.INFO_HASH),
            m.OutgoingGetPeersResponse(tc.SERVER_ID, nodes=tc.NODES))
        self._exchange_msgs(
            m.OutgoingGetPeersQuery(tc.CLIENT_ID, tc.INFO_HASH),
            m.OutgoingGetPeersResponse(tc.SERVER_ID,
                                       nodes=tc.NODES,
                                       peers=tc.PEERS))
        assert_raises(AssertionError, m.OutgoingGetPeersResponse, tc.SERVER_ID)

        self._exchange_msgs(
            m.OutgoingAnnouncePeerQuery(tc.CLIENT_ID, tc.INFO_HASH, tc.BT_PORT,
                                        tc.TOKEN),
            m.OutgoingAnnouncePeerResponse(tc.SERVER_ID))
 def _send_maintenance_ping(self, node_):
     if node_.id:
         log_distance = self.table.find_next_bucket_with_room_index(node_)
     else:
         # Bootstrap nodes don't have id
         log_distance = 0
     if 0:  #log_distance:
         target = self.my_node.id.generate_close_id(log_distance)
         msg = message.OutgoingFindNodeQuery(self.my_node.id, target)
         m_bucket, r_bucket = self.table.buckets[log_distance]
         print '[%f] FIND_NODE(%d:%d:%d)' % (time.time(), log_distance,
                                             len(m_bucket), len(r_bucket)),
     else:
         print '[%f] PING' % (time.time()),
         msg = self.ping_msg
     if node_.id:
         m_bucket, r_bucket = self.table.get_buckets(node_)
         print 'to (%r) %d:%d:%d --' % (node_.addr,
                                        node_.log_distance(self.my_node),
                                        len(m_bucket), len(r_bucket))
     else:
         print 'to UNKNOWN id'
     self.querier.send_query(msg, node_)
Esempio n. 12
0
        b_err = m.OutgoingErrorMsg(error_code).encode(tc.TID)

        logger.info(
            "TEST LOGGING ** IGNORE EXPECTED INFO ** Unknown error: %r",
            error_code)
        _ = m.IncomingMsg(b_err, tc.CLIENT_ADDR)

    def test_nodes2(self):
        response = m.OutgoingGetPeersResponse(tc.CLIENT_ID, peers=tc.PEERS)
        response._dict[m.RESPONSE][m.NODES2] = mt.compact_nodes2(tc.NODES)
        bencoded = response.encode(tc.TID)
        m.IncomingMsg(bencoded, tc.CLIENT_ADDR)


b_ping_q = m.OutgoingPingQuery(tc.CLIENT_ID).encode(tc.TID)
b_fn_q = m.OutgoingFindNodeQuery(tc.CLIENT_ID, tc.NODE_ID).encode(tc.TID)
b_gp_q = m.OutgoingGetPeersQuery(tc.CLIENT_ID, tc.INFO_HASH).encode(tc.TID)
b_ap_q = m.OutgoingAnnouncePeerQuery(tc.CLIENT_ID, tc.INFO_HASH, tc.BT_PORT,
                                     tc.TOKEN).encode(tc.TID)


class TestSanitizeQueryError:
    def setup(self):
        self.ping_d = m.IncomingMsg(b_ping_q, tc.CLIENT_ADDR)._msg_dict
        self.fn_d = m.IncomingMsg(b_fn_q, tc.CLIENT_ADDR)._msg_dict
        self.gp_d = m.IncomingMsg(b_gp_q, tc.CLIENT_ADDR)._msg_dict
        self.ap_d = m.IncomingMsg(b_ap_q, tc.CLIENT_ADDR)._msg_dict

    def test_weird_msg(self):
        self.ping_d[m.ARGS] = []
        assert_raises(m.MsgError, m.IncomingMsg, bencode.encode(self.ping_d),
Esempio n. 13
0
 def __init__(self, my_id, querier, max_parallel_queries, target, nodes):
     GetPeersLookup.__init__(self, my_id, querier, max_parallel_queries,
                             target, None, nodes)
     self._get_peers_msg = message.OutgoingFindNodeQuery(my_id,
                                                         target)