Neptune-Crypto / neptune-core

anonymous peer-to-peer cash
Apache License 2.0
27 stars 8 forks source link

Redefine or remove all references to listen address #9

Closed Sword-Smith closed 1 year ago

Sword-Smith commented 1 year ago

It doesn't represent what I thought it did, at least not in its current form. It is the listen address of the internal network interface, not the public socket address.

Sword-Smith commented 1 year ago

An example where listen_address is used in incorrectly can be found in the peer discovery method

        // 0) Ask all peers for their peer lists
        // 1) Get peer candidate from these responses
        // 2) Connect to one of those peers, A.
        // 3) Ask this newly connected peer, A, for its peers.
        // 4) Connect to one of those peers
        // 5) Disconnect from A. (not yet implemented)

        // 0)
        self.main_to_peer_broadcast_tx
            .send(MainToPeerThread::MakePeerDiscoveryRequest)?;

        // 1)
        let (peer_candidate, candidate_distance) =
            match main_loop_state.potential_peers.get_distant_candidate(
                &connected_peers,
                self.global_state.cli.get_own_listen_address(),
                self.global_state.net.instance_id,
            ) {
                Some(candidate) => candidate,
                None => return Ok(()),
            };

and the callee looks like this

/// Return a random peer from the potential peer list that we aren't connected to
    /// and that isn't our own address. Returns (socket address, peer distance)
    fn get_distant_candidate(
        &self,
        connected_clients: &[PeerInfo],
        own_listen_socket: Option<SocketAddr>,
        own_instance_id: u128,
    ) -> Option<(SocketAddr, u8)> {
        let peers_instance_ids: Vec<u128> =
            connected_clients.iter().map(|x| x.instance_id).collect();

        // Only pick those peers that report a listening port
        let peers_listen_addresses: Vec<SocketAddr> = connected_clients
            .iter()
            .filter_map(|x| x.address_for_incoming_connections)
            .collect();

        // Find the appropriate candidates
        let not_connected_peers = self
            .potential_peers
            .iter()
            // Prevent connecting to self
            .filter(|pp| pp.1.instance_id != own_instance_id)
            .filter(|pp| own_listen_socket.is_some() && *pp.0 != own_listen_socket.unwrap())
            // Prevent connecting to peer we already are connected to
            .filter(|potential_peer| !peers_instance_ids.contains(&potential_peer.1.instance_id))
            .filter(|potential_peer| !peers_listen_addresses.contains(potential_peer.0))
            .collect::<Vec<_>>();

        // Get the candidate list with the highest distance
        let max_distance_candidates = not_connected_peers.iter().max_by_key(|pp| pp.1.distance);

        // Pick a random candidate from the appropriate candidates
        let mut rng = rand::thread_rng();
        max_distance_candidates
            .iter()
            .choose(&mut rng)
            .map(|x| (x.0.to_owned(), x.1.distance))
    }

The problem is that listen_address is a NATted address, and defaults to 0.0.0.0 which is how to tell the OS to listen on all network interfaces. It does not represent the public IP address as the above code assumes.