Skip to content

Commit

Permalink
Network discovery: store the remote address of the peer after finishi…
Browse files Browse the repository at this point in the history
…ng a successful handshake.

This remote address can later by used for various tasks, like banning.

Network connection pool: only look at a part of a Multiaddr to determine if an address is banned.
  • Loading branch information
Eligioo authored and jsdanielh committed Oct 3, 2024
1 parent bd8cb3d commit c7f80f6
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 10 deletions.
19 changes: 10 additions & 9 deletions network-libp2p/src/connection_pool/behaviour.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use rand::{seq::IteratorRandom, thread_rng};
use void::Void;

use super::Error;
use crate::discovery::peer_contacts::PeerContactBook;
use crate::discovery::{handler, peer_contacts::PeerContactBook};

/// Current state of connections and peers for connection limits
#[derive(Clone, Debug)]
Expand Down Expand Up @@ -625,12 +625,11 @@ impl Behaviour {
self.peer_ids.mark_banned(peer_id);
debug!(%peer_id, "Banned peer");

// Mark its addresses as banned if we have them
// Mark its outer protocol address as banned if we have it
if let Some(contact) = self.contacts.read().get(&peer_id) {
let addresses = contact.addresses();
for address in addresses {
self.addresses.mark_banned(address.clone());
debug!(%address, "Banned address");
if let Some(outer_protocol_address) = contact.get_outer_protocol_address() {
debug!(address = %outer_protocol_address, "Banned address");
self.addresses.mark_banned(outer_protocol_address);
}
}
}
Expand Down Expand Up @@ -893,9 +892,11 @@ impl NetworkBehaviour for Behaviour {
_local_addr: &Multiaddr,
remote_addr: &Multiaddr,
) -> Result<(), ConnectionDenied> {
if self.addresses.is_banned(remote_addr.clone()) {
debug!(%remote_addr, "Address is banned");
return Err(ConnectionDenied::new(Error::BannedIp));
if let Some(outer_protocol_address) = handler::outer_protocol_address(remote_addr) {
if self.addresses.is_banned(outer_protocol_address) {
debug!(%remote_addr, "Address is banned");
return Err(ConnectionDenied::new(Error::BannedIp));
}
}

// Get IP from multiaddress if it exists.
Expand Down
24 changes: 24 additions & 0 deletions network-libp2p/src/discovery/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use futures_timer::Delay;
use instant::Instant;
use libp2p::{
identity::Keypair,
multiaddr::Protocol,
swarm::{
handler::{
ConnectionEvent, DialUpgradeError, FullyNegotiatedInbound, FullyNegotiatedOutbound,
Expand Down Expand Up @@ -173,6 +174,12 @@ impl Handler {
peer_contact_book: Arc<RwLock<PeerContactBook>>,
peer_address: Multiaddr,
) -> Self {
if let Some(peer_contact) = peer_contact_book.write().get(&peer_id) {
if let Some(outer_protocol_address) = outer_protocol_address(&peer_address) {
peer_contact.set_outer_protocol_address(outer_protocol_address);
}
}

Self {
peer_id,
config,
Expand Down Expand Up @@ -244,6 +251,23 @@ impl Handler {
}
}

/// Extract the `/ip4/`,`/ip6/`, `/dns4/` or `/dns6/` protocol part from a `Multiaddr`
pub(crate) fn outer_protocol_address(addr: &Multiaddr) -> Option<Multiaddr> {
addr.iter()
.find(|p| {
matches!(
p,
Protocol::Dns(_)
| Protocol::Dns4(_)
| Protocol::Dns6(_)
| Protocol::Ip4(_)
| Protocol::Ip6(_)
)
})
.map(|p| Some(p.into()))
.unwrap_or(None)
}

impl ConnectionHandler for Handler {
type FromBehaviour = ();
type ToBehaviour = HandlerOutEvent;
Expand Down
22 changes: 21 additions & 1 deletion network-libp2p/src/discovery/peer_contacts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ impl SignedPeerContact {
/// Meta information attached to peer contact info objects. This is meant to be mutable and change over time.
#[derive(Clone, Debug, Serialize, Deserialize)]
struct PeerContactMeta {
outer_protocol_address: Option<Multiaddr>,
score: f64,
}

Expand All @@ -209,7 +210,10 @@ impl From<SignedPeerContact> for PeerContactInfo {
Self {
peer_id,
contact,
meta: RwLock::new(PeerContactMeta { score: 0. }),
meta: RwLock::new(PeerContactMeta {
score: 0.,
outer_protocol_address: None,
}),
}
}
}
Expand Down Expand Up @@ -273,6 +277,22 @@ impl PeerContactInfo {
pub fn set_score(&self, score: f64) {
self.meta.write().score = score;
}

/// Gets the outer protocol address of the peer. For example `/ip4/x.x.x.x` or `/dns4/foo.bar`
pub fn get_outer_protocol_address(&self) -> Option<Multiaddr> {
self.meta.read().outer_protocol_address.clone()
}

/// Sets the outer protocol address of the peer once
pub fn set_outer_protocol_address(&self, addr: Multiaddr) {
self.meta
.write()
.outer_protocol_address
.get_or_insert_with(|| {
trace!(peer_id = %self.peer_id, %addr, "Set outer protocol address for peer");
addr
});
}
}

/// Main structure that holds the peer information that has been obtained or
Expand Down

0 comments on commit c7f80f6

Please sign in to comment.