def __init__(self, my_id, querier_, max_parallel_queries, info_hash, callback_f, bootstrap_nodes, bt_port=None): logger.debug('New lookup (info_hash: %r)' % info_hash) self._my_id = my_id self._querier = querier_ self._max_parallel_queries = max_parallel_queries self._get_peers_msg = message.OutgoingGetPeersQuery( my_id, info_hash) self._callback_f = callback_f self._lookup_queue = _LookupQueue(info_hash, max_parallel_queries * 2) self.nodes_to_query = self._lookup_queue.bootstrap(bootstrap_nodes) self._info_hash = info_hash self._bt_port = bt_port self._lock = threading.RLock() self._num_parallel_queries = 0 self._is_done = False self.num_queries = 0 self.num_responses = 0 self.num_timeouts = 0 self.num_errors = 0
def test_dont_query_myself(self): logger.debug('test start') msg = message.OutgoingGetPeersQuery(tc.CLIENT_ID, tc.INFO_HASH_ZERO) expected = [ Query(msg, tc.NODES_LD_IH[159][0]), Query(msg, tc.NODES_LD_IH[158][1]), Query(msg, tc.NODES_LD_IH[157][3]), Query(msg, tc.NODES_LD_IH[155][4]), ] result = self.lookup.start() return for i, r, e in zip(range(len(result)), result, expected): eq_(r.msg.info_hash, e.msg.info_hash) eq_(r.dstnode, e.dstnode) #OUTDATED!!!!!!!!!!!!!!!!!!!!!!!!! # Ongoing queries to (sorted: oldest first): # 155-4, 157-3, # Queued nodes to query (sorted by log_distance to info_hash): # 158-1, 159-0 # Notice 159-2 is kicked out from the queue eq_(self.lookup.num_parallel_queries, 4) nodes = [Node(tc.CLIENT_ADDR, self.lookup._my_id)] self.lookup.on_response_received( *_gen_nodes_args(tc.NODES_LD_IH[157][3], nodes)) return eq_(self.lookup._get_announce_candidates(), [ tc.NODES_LD_IH[157][3], ]) # This response triggers a new query to 158-1 (ignoring myself) eq_(self.lookup.num_parallel_queries, 2) # Ongoing queries to (sorted: oldest first): # 155-4, 158-1 # Queued nodes to query (sorted by log_distance to info_hash): # 159-0 self.lookup.on_timeout(tc.NODES_LD_IH[155][4]) # This timeout triggers a new query (to 159-0) eq_(self.lookup.num_parallel_queries, 2) self.lookup.on_timeout(tc.NODES_LD_IH[158][1]) # No more nodes to send queries to eq_(self.lookup.num_parallel_queries, 1) ok_(not self.lookup.is_done) self.lookup.on_timeout(tc.NODES_LD_IH[159][0]) # No more nodes to send queries to eq_(self.lookup.num_parallel_queries, 0) ok_(self.lookup.is_done)
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), ]
def setup(self): self.got_peers = None self.bootstrap_nodes = [ tc.NODES_LD_IH[159][0], tc.NODES_LD_IH[158][1], tc.CLIENT_NODE, tc.NODES_LD_IH[157][3], tc.NODES_LD_IH[155][4], ] self.lookup = lookup_manager.GetPeersLookup(tc.CLIENT_ID, tc.INFO_HASH_ZERO, self._callback, self.bootstrap_nodes) self.get_peers_msg = message.OutgoingGetPeersQuery( tc.CLIENT_ID, tc.INFO_HASH_ZERO)
def test_get_peers_nodes(self): #client outgoing_query = m.OutgoingGetPeersQuery(tc.CLIENT_ID, tc.INFO_HASH) 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.OutgoingGetPeersResponse(tc.SERVER_ID, tc.TOKEN, tc.NODES) data = outgoing_response.encode(incoming_query.tid) #client incoming_response = m.IncomingMsg(data, tc.SERVER_ADDR) assert incoming_response.type is m.RESPONSE #incoming_response.sanitize_response(outgoing_query.query) for n1, n2 in zip(tc.NODES, incoming_response.all_nodes): assert n1 == n2
def test_get_peers_peers(self): #client outgoing_query = m.OutgoingGetPeersQuery(tc.CLIENT_ID, tc.INFO_HASH) data = outgoing_query.encode(tc.TID) #server incoming_query = m.IncomingMsg(data) assert incoming_query.type is m.QUERY outgoing_response = m.OutgoingGetPeersResponse(tc.SERVER_ID, tc.TOKEN, peers=tc.PEERS) 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) for p1, p2 in zip(tc.PEERS, incoming_response.peers): assert p1[0] == p2[0] assert p1[1] == p2[1]
def test_return_response_for_get_peers_when_no_peers(self): # client side query_msg = message.OutgoingGetPeersQuery(tc.CLIENT_ID, tc.NODE_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.OutgoingGetPeersResponse(tc.SERVER_ID, self.token_m.get(), nodes2=tc.NODES) expected_data = expected_msg.encode(query_msg.tid) eq_(response_data, expected_data)
def test_get_peers_with_response(self): # Client creates a query fn_msg = message.OutgoingGetPeersQuery(tc.CLIENT_ID, tc.INFO_HASH) # the destination's ID is unknown # This query belongs to a lookup q = Query(fn_msg, node.Node(tc.SERVER_ADDR), LOOKUP_OBJ) # 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.OutgoingGetPeersResponse(tc.SERVER_ID, nodes=tc.NODES) 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_response_received(fn_r_in) assert 1 < q.rtt < 1.1 assert q.lookup_obj is LOOKUP_OBJ
def __init__(self, my_id, querier_, max_parallel_queries, info_hash, callback_f, bootstrap_nodes, bt_port=None): log.debug('New lookup (info_hash: %r)' % info_hash) self._my_id = my_id self._querier = querier_ self._max_parallel_queries = max_parallel_queries self._get_peers_msg = message.OutgoingGetPeersQuery( my_id, info_hash) self._callback_f = callback_f self._lookup_queue = _LookupQueue(info_hash, max_parallel_queries * 2) self._lookup_queue.add(bootstrap_nodes) self._num_parallel_queries = 0 self._info_hash = info_hash self._bt_port = bt_port self._lock = threading.RLock() self._announce_candidates = [] self._num_responses_with_peers = 0 self._is_done = False
def test_return_response_for_get_peers_when_peers(self): # server's tracker has peers for peer in tc.PEERS: self.tracker.put(tc.INFO_HASH, peer) # client side query_msg = message.OutgoingGetPeersQuery(tc.CLIENT_ID, tc.INFO_HASH) # 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.OutgoingGetPeersResponse(tc.SERVER_ID, self.token_m.get(), peers=tc.PEERS) expected_data = expected_msg.encode(tc.TID) eq_(response_data, expected_data)
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))
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), tc.CLIENT_ADDR)