remove peer immediately instead of probing when its bad during search

This commit is contained in:
Victor Shyba 2019-05-13 02:52:24 -03:00
parent 0075dcc2c0
commit 18af2dcd4e
3 changed files with 11 additions and 5 deletions

View file

@ -181,6 +181,9 @@ class IterativeFinder:
if added >= constants.alpha: if added >= constants.alpha:
break break
origin_address = (peer.address, peer.udp_port) origin_address = (peer.address, peer.udp_port)
if self.peer_manager.peer_is_good(peer) is False:
self.protocol.remove_peer(peer)
continue
if origin_address in self.exclude: if origin_address in self.exclude:
continue continue
if peer.node_id == self.protocol.node_id: if peer.node_id == self.protocol.node_id:

View file

@ -376,12 +376,16 @@ class KademliaProtocol(DatagramProtocol):
self.routing_table.buckets[bucket_index].remove_peer(to_replace) self.routing_table.buckets[bucket_index].remove_peer(to_replace)
return await self._add_peer(peer) return await self._add_peer(peer)
def add_peer(self, peer: 'KademliaPeer') -> bool: def add_peer(self, peer: 'KademliaPeer'):
if peer.node_id == self.node_id: if peer.node_id == self.node_id:
return False return False
self._to_add.add(peer) self._to_add.add(peer)
self._wakeup_routing_task.set() self._wakeup_routing_task.set()
def remove_peer(self, peer: 'KademliaPeer'):
self._to_remove.add(peer)
self._wakeup_routing_task.set()
async def routing_table_task(self): async def routing_table_task(self):
while True: while True:
while self._to_remove: while self._to_remove:
@ -558,8 +562,7 @@ class KademliaProtocol(DatagramProtocol):
except (asyncio.TimeoutError, RemoteException): except (asyncio.TimeoutError, RemoteException):
self.peer_manager.report_failure(peer.address, peer.udp_port) self.peer_manager.report_failure(peer.address, peer.udp_port)
if self.peer_manager.peer_is_good(peer) is False: if self.peer_manager.peer_is_good(peer) is False:
self._to_remove.add(peer) self.remove_peer(peer)
self._wakeup_routing_task.set()
raise raise
def send_response(self, peer: 'KademliaPeer', response: ResponseDatagram): def send_response(self, peer: 'KademliaPeer', response: ResponseDatagram):

View file

@ -109,6 +109,6 @@ class DHTIntegrationTest(AsyncioTestCase):
self.assertFalse(node1.protocol.peer_manager.peer_is_good(peer)) self.assertFalse(node1.protocol.peer_manager.peer_is_good(peer))
# now a search happens, which removes bad peers while contacting them # now a search happens, which removes bad peers while contacting them
self.assertTrue(node1.protocol.routing_table.get_peers()) self.assertNotIn(peer, node1.protocol._to_remove)
await node1.peer_search(node2.protocol.node_id) await node1.peer_search(node2.protocol.node_id)
self.assertFalse(node1.protocol.routing_table.get_peers()) self.assertIn(peer, node1.protocol._to_remove)