From 92863c1d5c8fa58d0b3882cc54ead727af029757 Mon Sep 17 00:00:00 2001 From: Egbert Bouman Date: Mon, 1 Apr 2024 11:44:24 +0200 Subject: [PATCH] Fixed relaying to exits --- ipv8/messaging/anonymization/community.py | 30 ++++++++++++----------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/ipv8/messaging/anonymization/community.py b/ipv8/messaging/anonymization/community.py index 0f23be838..66202a19b 100644 --- a/ipv8/messaging/anonymization/community.py +++ b/ipv8/messaging/anonymization/community.py @@ -576,6 +576,7 @@ def _ours_on_created_extended(self, circuit_id: int, payload: CreatedPayload | E circuit.unverified_hop = None circuit.add_hop(hop) self.circuits.get(circuit_id) # Needed for notifying the RustEndpoint + self.logger.info("Added hop %d (%s) to circuit %d", len(circuit.hops), hop.peer, circuit.circuit_id) if circuit.state == CIRCUIT_STATE_EXTENDING: candidates_enc = payload.candidates_enc @@ -592,10 +593,6 @@ def send_extend(self, circuit: Circuit, candidates: list[bytes], max_tries: int) """ Extend a circuit by choosing one of the given candidates. """ - ignore_candidates = [hop.public_key_bin for hop in circuit.hops] + [self.my_peer.public_key.key_to_bin()] - if circuit.required_exit: - ignore_candidates.append(circuit.required_exit.public_key.key_to_bin()) - become_exit = circuit.goal_hops - 1 == len(circuit.hops) if become_exit and circuit.required_exit: # Set the required exit according to the circuit setting (e.g. for linking e2e circuits) @@ -603,19 +600,24 @@ def send_extend(self, circuit: Circuit, candidates: list[bytes], max_tries: int) extend_hop_addr = circuit.required_exit.address else: - # The next candidate is chosen from the returned list of possible candidates - for ignore_candidate in ignore_candidates: - if ignore_candidate in candidates: - candidates.remove(ignore_candidate) - - for i in range(len(candidates) - 1, -1, -1): - public_key = self.crypto.key_from_public_bin(candidates[i]) - if not self.crypto.is_key_compatible(public_key): - candidates.pop(i) - + # Chose the next candidate. Ensure we didn't use this candidate already, and its key is compatible. + exclude = [hop.public_key_bin for hop in circuit.hops] + [self.my_peer.public_key.key_to_bin()] + if circuit.required_exit: + exclude.append(circuit.required_exit.public_key.key_to_bin()) + candidates = [c for c in candidates if c not in exclude and self.crypto.key_from_public_bin(c)] extend_hop_public_bin = next(iter(candidates), b'') extend_hop_addr = ('0.0.0.0', 0) + # By default, nodes will give a number of relays to which we can extend the circuit (i.e., peers + # that have already been punctured). However, it could be that there simply aren't enough relays + # available. When this happens, we try to extend to exit nodes (which we assume are connectable). + exits = self.get_candidates(PEER_FLAG_EXIT_BT, PEER_FLAG_RELAY) + if not extend_hop_public_bin and exits: + peer = random.choice([peer for peer in exits if peer.public_key.key_to_bin() not in exclude]) + extend_hop_public_bin = peer.public_key.key_to_bin() + extend_hop_addr = peer.address + self.logger.info('No candidates to extend to, trying exit node %s instead', peer) + if extend_hop_public_bin: if self.request_cache.has(RetryRequestCache, circuit.circuit_id): self.request_cache.pop(RetryRequestCache, circuit.circuit_id)