mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-23 14:51:34 +00:00
feat(swarm): replace address scoring with explicit candidates
Previously, a `NetworkBehaviour` could report an `AddressScore` for an external address. This score was a `u32` and addresses would be ranked amongst those. In reality, an address is either confirmed to be publicly reachable (via a protocol such as AutoNAT) or merely represents a candidate that might be an external address. In a way, addresses are guilty (private) until proven innocent (publicly reachable). When a `NetworkBehaviour` reports an address candidate, we perform address translation on it to potentially correct for ephemeral ports of TCP. These candidates are then injected back into the `NetworkBehaviour`. Protocols such as AutoNAT can use these addresses as a source for probing their NAT status. Once confirmed, they can emit a `ToSwarm::ExternalAddrConfirmed` event which again will be passed to all `NetworkBehaviour`s. This simplified approach will allow us implement Kademlia's client-mode (https://github.com/libp2p/rust-libp2p/issues/2032) without additional configuration options: As soon as an address is reported as publicly reachable, we can activate server-mode for that connection. Related: https://github.com/libp2p/rust-libp2p/pull/3877. Related: https://github.com/libp2p/rust-libp2p/issues/3953. Related: https://github.com/libp2p/rust-libp2p/issues/2032. Related: https://github.com/libp2p/go-libp2p/issues/2229. Co-authored-by: Max Inden <mail@max-inden.de> Pull-Request: #3954.
This commit is contained in:
@ -29,8 +29,8 @@ pub use listen_addresses::ListenAddresses;
|
||||
use crate::connection::ConnectionId;
|
||||
use crate::dial_opts::DialOpts;
|
||||
use crate::{
|
||||
AddressRecord, AddressScore, ConnectionDenied, ConnectionHandler, DialError, ListenError,
|
||||
THandler, THandlerInEvent, THandlerOutEvent,
|
||||
ConnectionDenied, ConnectionHandler, DialError, ListenError, THandler, THandlerInEvent,
|
||||
THandlerOutEvent,
|
||||
};
|
||||
use libp2p_core::{transport::ListenerId, ConnectedPoint, Endpoint, Multiaddr};
|
||||
use libp2p_identity::PeerId;
|
||||
@ -221,8 +221,6 @@ pub trait PollParameters {
|
||||
type SupportedProtocolsIter: ExactSizeIterator<Item = Vec<u8>>;
|
||||
/// Iterator returned by [`listened_addresses`](PollParameters::listened_addresses).
|
||||
type ListenedAddressesIter: ExactSizeIterator<Item = Multiaddr>;
|
||||
/// Iterator returned by [`external_addresses`](PollParameters::external_addresses).
|
||||
type ExternalAddressesIter: ExactSizeIterator<Item = AddressRecord>;
|
||||
|
||||
/// Returns the list of protocol the behaviour supports when a remote negotiates a protocol on
|
||||
/// an inbound substream.
|
||||
@ -242,13 +240,6 @@ pub trait PollParameters {
|
||||
)]
|
||||
fn listened_addresses(&self) -> Self::ListenedAddressesIter;
|
||||
|
||||
/// Returns the list of the addresses nodes can use to reach us.
|
||||
#[deprecated(
|
||||
since = "0.42.0",
|
||||
note = "Use `libp2p_swarm::ExternalAddresses` instead."
|
||||
)]
|
||||
fn external_addresses(&self) -> Self::ExternalAddressesIter;
|
||||
|
||||
/// Returns the peer id of the local node.
|
||||
#[deprecated(
|
||||
since = "0.42.0",
|
||||
@ -299,21 +290,28 @@ pub enum ToSwarm<TOutEvent, TInEvent> {
|
||||
event: TInEvent,
|
||||
},
|
||||
|
||||
/// Informs the `Swarm` about an address observed by a remote for
|
||||
/// the local node by which the local node is supposedly publicly
|
||||
/// reachable.
|
||||
/// Reports a new candidate for an external address to the [`Swarm`](crate::Swarm).
|
||||
///
|
||||
/// It is advisable to issue `ReportObservedAddr` actions at a fixed frequency
|
||||
/// per node. This way address information will be more accurate over time
|
||||
/// and individual outliers carry less weight.
|
||||
ReportObservedAddr {
|
||||
/// The observed address of the local node.
|
||||
address: Multiaddr,
|
||||
/// The score to associate with this observation, i.e.
|
||||
/// an indicator for the trusworthiness of this address
|
||||
/// relative to other observed addresses.
|
||||
score: AddressScore,
|
||||
},
|
||||
/// This address will be shared with all [`NetworkBehaviour`]s via [`FromSwarm::NewExternalAddrCandidate`].
|
||||
///
|
||||
/// This address could come from a variety of sources:
|
||||
/// - A protocol such as identify obtained it from a remote.
|
||||
/// - The user provided it based on configuration.
|
||||
/// - We made an educated guess based on one of our listen addresses.
|
||||
/// - We established a new relay connection.
|
||||
NewExternalAddrCandidate(Multiaddr),
|
||||
|
||||
/// Indicates to the [`Swarm`](crate::Swarm) that the provided address is confirmed to be externally reachable.
|
||||
///
|
||||
/// This is intended to be issued in response to a [`FromSwarm::NewExternalAddrCandidate`] if we are indeed externally reachable on this address.
|
||||
/// This address will be shared with all [`NetworkBehaviour`]s via [`FromSwarm::ExternalAddrConfirmed`].
|
||||
ExternalAddrConfirmed(Multiaddr),
|
||||
|
||||
/// Indicates to the [`Swarm`](crate::Swarm) that we are no longer externally reachable under the provided address.
|
||||
///
|
||||
/// This expires an address that was earlier confirmed via [`ToSwarm::ExternalAddrConfirmed`].
|
||||
/// This address will be shared with all [`NetworkBehaviour`]s via [`FromSwarm::ExternalAddrExpired`].
|
||||
ExternalAddrExpired(Multiaddr),
|
||||
|
||||
/// Instructs the `Swarm` to initiate a graceful close of one or all connections
|
||||
/// with the given peer.
|
||||
@ -351,9 +349,6 @@ impl<TOutEvent, TInEventOld> ToSwarm<TOutEvent, TInEventOld> {
|
||||
handler,
|
||||
event: f(event),
|
||||
},
|
||||
ToSwarm::ReportObservedAddr { address, score } => {
|
||||
ToSwarm::ReportObservedAddr { address, score }
|
||||
}
|
||||
ToSwarm::CloseConnection {
|
||||
peer_id,
|
||||
connection,
|
||||
@ -361,6 +356,9 @@ impl<TOutEvent, TInEventOld> ToSwarm<TOutEvent, TInEventOld> {
|
||||
peer_id,
|
||||
connection,
|
||||
},
|
||||
ToSwarm::NewExternalAddrCandidate(addr) => ToSwarm::NewExternalAddrCandidate(addr),
|
||||
ToSwarm::ExternalAddrConfirmed(addr) => ToSwarm::ExternalAddrConfirmed(addr),
|
||||
ToSwarm::ExternalAddrExpired(addr) => ToSwarm::ExternalAddrExpired(addr),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -380,9 +378,9 @@ impl<TOutEvent, THandlerIn> ToSwarm<TOutEvent, THandlerIn> {
|
||||
handler,
|
||||
event,
|
||||
},
|
||||
ToSwarm::ReportObservedAddr { address, score } => {
|
||||
ToSwarm::ReportObservedAddr { address, score }
|
||||
}
|
||||
ToSwarm::NewExternalAddrCandidate(addr) => ToSwarm::NewExternalAddrCandidate(addr),
|
||||
ToSwarm::ExternalAddrConfirmed(addr) => ToSwarm::ExternalAddrConfirmed(addr),
|
||||
ToSwarm::ExternalAddrExpired(addr) => ToSwarm::ExternalAddrExpired(addr),
|
||||
ToSwarm::CloseConnection {
|
||||
peer_id,
|
||||
connection,
|
||||
@ -449,10 +447,12 @@ pub enum FromSwarm<'a, Handler> {
|
||||
ListenerError(ListenerError<'a>),
|
||||
/// Informs the behaviour that a listener closed.
|
||||
ListenerClosed(ListenerClosed<'a>),
|
||||
/// Informs the behaviour that we have discovered a new external address for us.
|
||||
NewExternalAddr(NewExternalAddr<'a>),
|
||||
/// Informs the behaviour that an external address was removed.
|
||||
ExpiredExternalAddr(ExpiredExternalAddr<'a>),
|
||||
/// Informs the behaviour that we have discovered a new candidate for an external address for us.
|
||||
NewExternalAddrCandidate(NewExternalAddrCandidate<'a>),
|
||||
/// Informs the behaviour that an external address of the local node was removed.
|
||||
ExternalAddrConfirmed(ExternalAddrConfirmed<'a>),
|
||||
/// Informs the behaviour that an external address of the local node expired, i.e. is no-longer confirmed.
|
||||
ExternalAddrExpired(ExternalAddrExpired<'a>),
|
||||
}
|
||||
|
||||
/// [`FromSwarm`] variant that informs the behaviour about a newly established connection to a peer.
|
||||
@ -549,15 +549,21 @@ pub struct ListenerClosed<'a> {
|
||||
}
|
||||
|
||||
/// [`FromSwarm`] variant that informs the behaviour
|
||||
/// that we have discovered a new external address for us.
|
||||
/// that we have discovered a new candidate for an external address for us.
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct NewExternalAddr<'a> {
|
||||
pub struct NewExternalAddrCandidate<'a> {
|
||||
pub addr: &'a Multiaddr,
|
||||
}
|
||||
|
||||
/// [`FromSwarm`] variant that informs the behaviour that an external address was removed.
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct ExpiredExternalAddr<'a> {
|
||||
pub struct ExternalAddrConfirmed<'a> {
|
||||
pub addr: &'a Multiaddr,
|
||||
}
|
||||
|
||||
/// [`FromSwarm`] variant that informs the behaviour that an external address was removed.
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct ExternalAddrExpired<'a> {
|
||||
pub addr: &'a Multiaddr,
|
||||
}
|
||||
|
||||
@ -657,12 +663,9 @@ impl<'a, Handler> FromSwarm<'a, Handler> {
|
||||
listener_id,
|
||||
reason,
|
||||
})),
|
||||
FromSwarm::NewExternalAddr(NewExternalAddr { addr }) => {
|
||||
Some(FromSwarm::NewExternalAddr(NewExternalAddr { addr }))
|
||||
}
|
||||
FromSwarm::ExpiredExternalAddr(ExpiredExternalAddr { addr }) => {
|
||||
Some(FromSwarm::ExpiredExternalAddr(ExpiredExternalAddr { addr }))
|
||||
}
|
||||
FromSwarm::NewExternalAddrCandidate(e) => Some(FromSwarm::NewExternalAddrCandidate(e)),
|
||||
FromSwarm::ExternalAddrExpired(e) => Some(FromSwarm::ExternalAddrExpired(e)),
|
||||
FromSwarm::ExternalAddrConfirmed(e) => Some(FromSwarm::ExternalAddrConfirmed(e)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user