aboutsummaryrefslogtreecommitdiffstats
path: root/src/transport/libp2p/ignore.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/libp2p/ignore.rs')
-rw-r--r--src/transport/libp2p/ignore.rs26
1 files changed, 25 insertions, 1 deletions
diff --git a/src/transport/libp2p/ignore.rs b/src/transport/libp2p/ignore.rs
index ab59a3e..2fcbd6f 100644
--- a/src/transport/libp2p/ignore.rs
+++ b/src/transport/libp2p/ignore.rs
@@ -2,11 +2,13 @@
//! (`Ignoring`, a behaviour that denies connections there), nor told peers by identify
//! (`Identifying`).
+use std::fmt;
+
use super::*;
/// An address range (`10.244.0.0/16`, `42::/16`; a bare address is a range of one), for
/// `Libp2pConfig::ignore`.
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub(crate) struct IpRange {
pub(super) network: std::net::IpAddr,
pub(super) prefix: u8,
@@ -36,7 +38,29 @@ impl FromStr for IpRange {
}
}
+impl fmt::Display for IpRange {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "{}/{}", self.network, self.prefix)
+ }
+}
+
impl IpRange {
+ /// The range of the `prefix` bits of `ip` (the rest zero).
+ pub(super) fn masked(ip: std::net::IpAddr, prefix: u8) -> Self {
+ use std::net::IpAddr;
+ let network = match ip {
+ IpAddr::V4(ip) => {
+ let mask = u32::MAX.checked_shl(32 - u32::from(prefix)).unwrap_or(0);
+ IpAddr::V4((u32::from(ip) & mask).into())
+ }
+ IpAddr::V6(ip) => {
+ let mask = u128::MAX.checked_shl(128 - u32::from(prefix)).unwrap_or(0);
+ IpAddr::V6((u128::from(ip) & mask).into())
+ }
+ };
+ Self { network, prefix }
+ }
+
/// Whether every address of `other` is in this range too.
pub(super) fn covers(&self, other: &IpRange) -> bool {
self.network.is_ipv4() == other.network.is_ipv4()