mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-05-29 10:41:21 +00:00
[libp2p-swarm] Ignore a node's own addresses on dialing. (#1646)
* Ignore a node's own addresses on dialing. Dialing attempts of a local node to one of its own addresses for what appears to be a different peer ID are futile and bound to fail with an `InvalidPeerId` error. To avoid such futile dialing attempts, filter out the node's own addresses from the addresses reported by the `NetworkBehaviour` for any peer. There can be a few reasons why a `NetworkBehaviour` may think an address belongs to a different peer, e.g.: 1. In the context of e.g. `libp2p-kad`, the local node may have changed its network identity (e.g. key rotation) and "discovers" its former identity in the DHT, with the same address(es). 2. Another peer may erroneously or intentionally, possibly even maliciously, report one of the local node's addresses as its own, making the node try to connect to itself. Relates to https://github.com/paritytech/stakingops-issues/issues/18. * Remove filtering of external addresses. Since these are obtained from other peers, it would constitute an attack vector. It is furthermore usually not possible for a peer behind a NAT to dial its own external address so these are unlikely to cause `InvalidPeerId` errors as a result of a peer dialing itself under the expectation of one of its former peer IDs.
This commit is contained in:
parent
c4a5497d2d
commit
6ad05b0ff1
@ -2,6 +2,13 @@
|
||||
|
||||
- Documentation updates.
|
||||
|
||||
- Ignore addresses returned by `NetworkBehaviour::addresses_of_peer`
|
||||
that the `Swarm` considers to be listening addresses of the local node. This
|
||||
avoids futile dialing attempts of a node to itself, which can otherwise
|
||||
even happen in genuine situations, e.g. after the local node changed
|
||||
its network identity and a behaviour makes a dialing attempt to a
|
||||
former identity using the same addresses.
|
||||
|
||||
# 0.20.0 [2020-07-01]
|
||||
|
||||
- Updated the `libp2p-core` dependency.
|
||||
|
@ -382,13 +382,16 @@ where TBehaviour: NetworkBehaviour<ProtocolsHandler = THandler>,
|
||||
/// dialing attempt or `addresses_of_peer` reports no addresses, `Ok(false)`
|
||||
/// is returned.
|
||||
pub fn dial(me: &mut Self, peer_id: &PeerId) -> Result<(), DialError> {
|
||||
let mut addrs = me.behaviour.addresses_of_peer(peer_id).into_iter();
|
||||
let peer = me.network.peer(peer_id.clone());
|
||||
let self_listening = &me.listened_addrs;
|
||||
let mut addrs = me.behaviour.addresses_of_peer(peer_id)
|
||||
.into_iter()
|
||||
.filter(|a| !self_listening.contains(a));
|
||||
|
||||
let result =
|
||||
if let Some(first) = addrs.next() {
|
||||
let handler = me.behaviour.new_handler().into_node_handler_builder();
|
||||
peer.dial(first, addrs, handler)
|
||||
me.network.peer(peer_id.clone())
|
||||
.dial(first, addrs, handler)
|
||||
.map(|_| ())
|
||||
.map_err(DialError::ConnectionLimit)
|
||||
} else {
|
||||
@ -696,11 +699,14 @@ where TBehaviour: NetworkBehaviour<ProtocolsHandler = THandler>,
|
||||
// ongoing dialing attempt, if there is one.
|
||||
log::trace!("Condition for new dialing attempt to {:?} not met: {:?}",
|
||||
peer_id, condition);
|
||||
let self_listening = &this.listened_addrs;
|
||||
if let Some(mut peer) = this.network.peer(peer_id.clone()).into_dialing() {
|
||||
let addrs = this.behaviour.addresses_of_peer(peer.id());
|
||||
let mut attempt = peer.some_attempt();
|
||||
for addr in addrs {
|
||||
attempt.add_address(addr);
|
||||
for a in addrs {
|
||||
if !self_listening.contains(&a) {
|
||||
attempt.add_address(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user