Ejemplo n.º 1
0
    def test(self):
        # Sender doesn't use private flag
        ping_public = m.OutgoingPingQuery(tc.CLIENT_ID)
        bencoded_public = ping_public.encode(tc.TID)
        # Sender uses private flag PRIVATE1
        m.private_dht_name = 'PRIVATE1'
        ping_private1 = m.OutgoingPingQuery(tc.CLIENT_ID)
        bencoded_private1 = ping_private1.encode(tc.TID)
        # Sender uses private flag PRIVATE1
        m.private_dht_name = 'PRIVATE2'
        ping_private2 = m.OutgoingPingQuery(tc.CLIENT_ID)
        bencoded_private2 = ping_private2.encode(tc.TID)

        # Receiver in the public DHT accepts messages (ignores private flag)
        m.private_dht_name = None
        m.IncomingMsg(bencoded_public, tc.CLIENT_ADDR)
        m.IncomingMsg(bencoded_private1, tc.CLIENT_ADDR)
        m.IncomingMsg(bencoded_private2, tc.CLIENT_ADDR)

        # Receiver in the private DHT accepts ONLY messages from the
        # private DHT it belongs to
        m.private_dht_name = 'PRIVATE1'
        assert_raises(m.MsgError, m.IncomingMsg, bencoded_public,
                      tc.CLIENT_ADDR)
        m.IncomingMsg(bencoded_private1, tc.CLIENT_ADDR)
        assert_raises(m.MsgError, m.IncomingMsg, bencoded_private2,
                      tc.CLIENT_ADDR)
Ejemplo n.º 2
0
 def test_no_callback_for_type(self):
     msg = message.OutgoingPingQuery(tc.CLIENT_ID)
     msg_data = msg.encode(tc.TID)
     self.s._on_datagram_received(msg_data, tc.CLIENT_ADDR)
     ok_(not self.got_query)
     ok_(not self.got_response)
     ok_(not self.got_routing_response)
Ejemplo n.º 3
0
    def _setup(self):
        global time
        time = querier.time = MockTime()

        self.ping_msg = message.OutgoingPingQuery(tc.CLIENT_ID)
        ping_r_out = message.OutgoingPingResponse(tc.SERVER_ID)
        self.ping_r_in = message.IncomingMsg(ping_r_out.encode(tc.TID),
                                             tc.SERVER_ADDR)
        fn_r_out = message.OutgoingFindNodeResponse(tc.SERVER_ID,
                                                    nodes2=tc.NODES)
        self.fn_r_in = message.IncomingMsg(fn_r_out.encode(tc.TID),
                                           tc.SERVER_ADDR)

        self.got_response = False
        self.got_error = False
        self.got_timeout = False

        self.got_routing_response = False
        self.got_routing_error = False
        self.got_routing_timeout = False
        self.got_routing_nodes_found = False

        timeout_task = minitwisted.Task(1, self.on_timeout, tc.SERVER_NODE)
        self.query = querier.Query(tc.TID, self.ping_msg.query, tc.SERVER_NODE,
                                   timeout_task)
Ejemplo n.º 4
0
    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
        ]
Ejemplo n.º 5
0
 def send_query_and_get_timeout(self, querier):
     ping_msg = message.OutgoingPingQuery(tc.CLIENT_ID)
     query = querier.send_query(ping_msg, tc.DEAD_NODE,
                                self.on_response,
                                self.on_timeout, self.on_error,
                                timeout_delay=tc.TIMEOUT_DELAY)
     if querier is self.querier_mock:
         query.timeout_task.fire_callbacks()
     time.sleep(tc.TIMEOUT_DELAY + .1)
     assert not self.got_response and self.got_timeout
Ejemplo n.º 6
0
    def test_querier_responder(self):
        # client
        # setup
        self.c.add_msg_callback(message.RESPONSE, self.on_response_received)
        self.c.add_msg_callback(message.RESPONSE,
                                self.on_routing_response_received)
        self.c.add_msg_callback(message.ERROR, self.on_error_received)
        self.c.add_timeout_callback(self.on_routing_timeout)

        # server
        # setup
        self.s.add_msg_callback(message.QUERY, self.on_query_received)

        # client creates and sends query
        t_task = self.c.get_timeout_task(tc.SERVER_ADDR, tc.TIMEOUT_DELAY,
                                         self.on_timeout)
        msg = message.OutgoingPingQuery(tc.CLIENT_ID)
        msg_data = msg.encode(tc.TID)
        self.c.send_msg_to(msg_data, tc.SERVER_ADDR)
        # client sets up timeout

        # server receives query, creates response and sends it back
        self.s._on_datagram_received(msg_data, tc.CLIENT_ADDR)
        # rpc_manager would send the message back automatically
        ok_(self.got_query)
        self.got_query = False
        msg = message.OutgoingPingResponse(tc.SERVER_ID)
        msg_data = msg.encode(tc.TID)
        self.s.send_msg_to(msg_data, tc.CLIENT_ADDR)

        # client gets response
        self.c._on_datagram_received(msg_data, tc.SERVER_ADDR)
        ok_(self.got_response)
        self.got_response = False
        ok_(self.got_routing_response)
        self.got_routing_response = False

        # client gets error
        msg_data = message.OutgoingErrorMsg(message.GENERIC_E).encode(tc.TID)
        self.c._on_datagram_received(msg_data, tc.SERVER_ADDR)
        ok_(self.got_error)
        self.got_error = False

        # client gets timeout
        t_task.fire_callbacks()
        ok_(self.got_timeout)
        self.got_timeout = False
        ok_(self.got_routing_timeout)
        self.got_routing_timeout = False

        # server gets invalid message
        self.s._on_datagram_received('zzz', tc.CLIENT_ADDR)
        ok_(not self.got_query)
        ok_(not self.got_response)
        ok_(not self.got_routing_response)
Ejemplo n.º 7
0
 def test_ping_with_timeout(self):
     # Client creates a query
     ping_msg = message.OutgoingPingQuery(tc.CLIENT_ID)
     q = Query(ping_msg, tc.SERVER_NODE)
     timeout_task = minitwisted.Task(TIMEOUT_DELAY, None)
     # Client registers query
     bencoded_msg = self.querier.register_query(q, timeout_task)
     # Client sends bencoded_msg
     time.sleep(3)
     # The server never responds and the timeout is triggered
     stored_q = self.querier.on_timeout(tc.SERVER_ADDR)
     assert stored_q is q
Ejemplo n.º 8
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)
Ejemplo n.º 9
0
 def test_ping(self):
     #client
     outgoing_query = m.OutgoingPingQuery(tc.CLIENT_ID)
     data = outgoing_query.encode(tc.TID)  # query_manager would do it
     #server
     incoming_query = m.IncomingMsg(data)
     assert incoming_query.type is m.QUERY
     outgoing_response = m.OutgoingPingResponse(tc.SERVER_ID)
     data = outgoing_response.encode(incoming_query.tid)
     #client
     incoming_response = m.IncomingMsg(data)
     assert incoming_response.type is m.RESPONSE
     incoming_response.sanitize_response(outgoing_query.query)
Ejemplo n.º 10
0
 def test_errors(self):
     # client side
     query_msg = message.OutgoingPingQuery(tc.CLIENT_ID)
     # querier.send_query() encodes
     query_data = query_msg.encode(tc.TID)
     # server side
     # rpc_manager.datagram_received() decodes and calls responder (callback)
     query_msg = message.IncomingMsg(query_data)
     ## 'xxxxxx' is not a valid QUERY
     query_msg.query = 'zzzzzzzz'
     assert not self.notification_callback_done
     ok_(
         self.responder.on_query_received(query_msg, tc.CLIENT_ADDR) is None
     )
Ejemplo n.º 11
0
 def do_maintenance(self):
     self.maintenance_counter += 1
     maintenance_delay = .0000001
     if self.maintenance_counter == 1:
         # bootstrap ping
         msg = message.OutgoingPingQuery(self.my_node.id)
         queries_to_send = [Query(msg, tc.SERVER_NODE)]
         maintenance_lookup_target = None
     elif self.maintenance_counter == 2:
         queries_to_send = []
         maintenance_lookup_target = tc.CLIENT_ID
     else:
         queries_to_send = []
         maintenance_lookup_target = None
     return (maintenance_delay, queries_to_send, maintenance_lookup_target)
Ejemplo n.º 12
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),
     ]
Ejemplo n.º 13
0
 def test_error(self):
     # Client creates a query
     ping_msg = message.OutgoingPingQuery(tc.CLIENT_ID)
     q = Query(ping_msg, tc.SERVER_NODE)
     timeout_task = minitwisted.Task(TIMEOUT_DELAY, None)
     # Client registers query
     bencoded_msg = self.querier.register_query(q, timeout_task)
     # Client sends bencoded_msg
     time.sleep(1)
     # Server gets bencoded_msg and creates response
     ping_r_msg_out = message.OutgoingErrorMsg(message.GENERIC_E)
     bencoded_r = ping_r_msg_out.encode(tc.TID)
     # The client receives the bencoded message
     ping_r_in = message.IncomingMsg(bencoded_r, tc.SERVER_ADDR)
     stored_q = self.querier.on_error_received(ping_r_in, tc.SERVER_ADDR)
     assert stored_q is None
Ejemplo n.º 14
0
    def test_return_response_for_ping(self):
        # client side
        query_msg = message.OutgoingPingQuery(tc.CLIENT_ID)
        # rpc_manager.sendto() encodes
        query_data = query_msg.encode(tc.TID)
        # server side
        # rpc_manager.datagram_received() decodes
        query_msg = message.IncomingMsg(query_data)
        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.OutgoingPingResponse(tc.SERVER_ID)
        expected_data = expected_msg.encode(tc.TID)
        eq_(response_data, expected_data)
Ejemplo n.º 15
0
    def send_query_and_get_error(self, querier):


        ping_msg = message.OutgoingPingQuery()
        query = querier.send_query(ping_msg, tc.EXTERNAL_NODE,
                                   self.on_response,
                                   self.on_timeout, self.on_error,
                                   timeout_delay=tc.TIMEOUT_DELAY)
        if querier is self.querier_mock:
            # the server creates the response
            error_msg = message.OutgoingErrorMsg(ping_msg.tid,
                                                 message.GENERIC_E)
            error_data = error_msg.encode()
            # rpc_m decodes the response received
            _, _, error_msg_dict = message.decode(error_data)
            # rpc_m notifies of the message (callback)
            querier.on_error_received(error_msg_dict, tc.EXTERNAL_NODE)
        time.sleep(tc.TIMEOUT_DELAY + .1)
Ejemplo n.º 16
0
 def test_ping_with_response(self):
     # Client creates a query
     ping_msg = message.OutgoingPingQuery(tc.CLIENT_ID)
     q = Query(ping_msg, tc.SERVER_NODE)
     # 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
     time.sleep(1)
     # The server creates a response
     ping_r_msg_out = message.OutgoingPingResponse(tc.SERVER_ID)
     bencoded_r = ping_r_msg_out.encode(tc.TID)
     # The client receives the bencoded message
     ping_r_in = message.IncomingMsg(bencoded_r, tc.SERVER_ADDR)
     q.on_response_received(ping_r_in)
     assert 1 < q.rtt < 1.1
     assert q.lookup_obj is None
Ejemplo n.º 17
0
    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)
Ejemplo n.º 18
0
    def test_unsolicited_response(self):
        # We have a pending response from NO_ADDR (TID \0\0)
        # but we get a response with different TID

        # client
        ping = message.OutgoingPingQuery(tc.CLIENT_ID)
        self.querier.send_query(ping, tc.SERVER_NODE, self.on_response,
                                self.on_error, self.on_timeout,
                                tc.TIMEOUT_DELAY)
        ok_(not self.got_response)
        ok_(not self.got_routing_response)
        ok_(not self.got_routing_nodes_found)
        # server
        pong = message.OutgoingPingResponse(tc.SERVER_ID)
        pong_in = message.IncomingMsg(pong.encode(tc.TID))
        # client
        self.querier.on_response_received(pong_in, tc.SERVER_ADDR)
        ok_(not self.got_response)
        ok_(not self.got_routing_response)
        ok_(not self.got_routing_nodes_found)
Ejemplo n.º 19
0
    def _test_ping_error(self):
        outgoing_query = m.OutgoingPingQuery(tc.CLIENT_ID)
        outgoing_query.tid = tc.TID
        # TID and ARGS ID are None
        assert_raises(m.MsgError, outgoing_query.encode)
        logger.error(
            "**IGNORE 2 ERROR LOGS** This exception was raised by a test")

        outgoing_query = m.OutgoingPingQuery()
        outgoing_query.my_id = tc.CLIENT_ID
        #outgoing_query.tid = tc.TID
        assert_raises(m.MsgError, outgoing_query.encode)
        logger.error(
            "**IGNORE 2 ERROR LOGS** This exception was raised by a test")

        outgoing_query = m.OutgoingPingQuery()
        #outgoing_query.my_id = tc.CLIENT_ID
        outgoing_query.tid = tc.TID
        assert_raises(m.MsgError, outgoing_query.encode)
        logger.error(
            "**IGNORE 2 ERROR LOGS** This exception was raised by a test")

        outgoing_query = m.OutgoingPingQuery()
        assert_raises(m.MsgError, outgoing_query.__setattr__, 'my_id', '')
        logger.error(
            "**IGNORE 2 ERROR LOGS** This exception was raised by a test")

        outgoing_query = m.OutgoingPingQuery()
        outgoing_query.my_id = tc.CLIENT_ID
        outgoing_query.tid = 567
        data = outgoing_query.encode()
        assert_raises(m.MsgError, m.decode, data)
        logger.error(
            "**IGNORE 2 ERROR LOGS** This exception was raised by a test")

        outgoing_query = m.OutgoingPingQuery()
        outgoing_query.my_id = tc.CLIENT_ID
        outgoing_query.tid = tc.TID
        data = outgoing_query.encode()
        data += 'this string ruins the bencoded msg'
        assert_raises(m.MsgError, m.decode, data)
        logger.error(
            "**IGNORE 2 ERROR LOGS** This exception was raised by a test")

        outgoing_response = m.OutgoingPingResponse(tc.TID, tc.SERVER_ID)
        outgoing_response.tid = None
        assert_raises(m.MsgError, outgoing_response.encode)
        logger.error(
            "**IGNORE ERROR LOGS** This exception was raised by a test")
Ejemplo n.º 20
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))
Ejemplo n.º 21
0
 def test_printing(self):
     out_msg = m.OutgoingPingQuery(tc.CLIENT_ID)
     in_msg = m.IncomingMsg(out_msg.encode(tc.TID), tc.CLIENT_ADDR)
     str(out_msg)
     repr(out_msg)
     repr(in_msg)
Ejemplo n.º 22
0
 def setup(self):
     b_ping = m.OutgoingPingQuery(tc.CLIENT_ID).encode(tc.TID)
     self.msg_d = m.IncomingMsg(b_ping, tc.CLIENT_ADDR)._msg_dict
Ejemplo n.º 23
0
        error_code = (999, "some weird error string")
        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] = []