aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/transport/libp2p/config.rs37
-rw-r--r--src/transport/libp2p/ignore.rs7
-rw-r--r--src/transport/libp2p/tests.rs34
3 files changed, 76 insertions, 2 deletions
diff --git a/src/transport/libp2p/config.rs b/src/transport/libp2p/config.rs
index 8b172ba..4db8444 100644
--- a/src/transport/libp2p/config.rs
+++ b/src/transport/libp2p/config.rs
@@ -59,8 +59,14 @@ pub(crate) fn check(settings: &crate::config::Settings) -> Result<()> {
parse_addresses("libp2p-listen", &settings.libp2p_listen)?;
parse_addresses("libp2p-announce", &settings.libp2p_announce)?;
parse_addresses("libp2p-relays", &settings.libp2p_relays)?;
- parse_ranges("libp2p-ignore", &settings.libp2p_ignore)?;
- parse_ranges("libp2p-prefer", &settings.libp2p_prefer)?;
+ let ignore = parse_ranges("libp2p-ignore", &settings.libp2p_ignore)?;
+ let prefer = parse_ranges("libp2p-prefer", &settings.libp2p_prefer)?;
+ check_preferred(
+ &ignore,
+ &prefer,
+ &settings.libp2p_ignore,
+ &settings.libp2p_prefer,
+ )?;
if settings.relay_only {
if settings.libp2p_listen.is_empty() {
bail!("relay-only needs libp2p-listen: where nodes reach the relay");
@@ -74,6 +80,33 @@ pub(crate) fn check(settings: &crate::config::Settings) -> Result<()> {
Ok(())
}
+/// A range both ignored and preferred: refused where all of the preferred one is
+/// ignored (it would name nothing usable), a warning where only part of it is (the
+/// ignored part stays left out). `ignore_given` and `prefer_given`: as written, for
+/// the messages. Ranges nest or are apart, so there's nothing in between.
+pub(super) fn check_preferred(
+ ignore: &[IpRange],
+ prefer: &[IpRange],
+ ignore_given: &[String],
+ prefer_given: &[String],
+) -> Result<()> {
+ for (preferred, preferred_given) in prefer.iter().zip(prefer_given) {
+ for (ignored, ignored_given) in ignore.iter().zip(ignore_given) {
+ if ignored.covers(preferred) {
+ bail!(
+ "libp2p-prefer {preferred_given:?} is all in libp2p-ignore {ignored_given:?}: nothing there is used"
+ );
+ }
+ if preferred.covers(ignored) {
+ warn!(
+ "libp2p-prefer {preferred_given:?} has libp2p-ignore {ignored_given:?} in it: addresses there stay left out"
+ );
+ }
+ }
+ }
+ Ok(())
+}
+
impl Libp2pConfig {
/// The configuration `settings` give; `relay_only`: a relay that is no node
/// (`--relay-only`).
diff --git a/src/transport/libp2p/ignore.rs b/src/transport/libp2p/ignore.rs
index 659ec91..51e1f45 100644
--- a/src/transport/libp2p/ignore.rs
+++ b/src/transport/libp2p/ignore.rs
@@ -37,6 +37,13 @@ impl FromStr for IpRange {
}
impl IpRange {
+ /// 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()
+ && self.prefix <= other.prefix
+ && self.contains(other.network)
+ }
+
pub(super) fn contains(&self, ip: std::net::IpAddr) -> bool {
use std::net::IpAddr;
match (self.network, ip) {
diff --git a/src/transport/libp2p/tests.rs b/src/transport/libp2p/tests.rs
index 9eb2808..f3c9374 100644
--- a/src/transport/libp2p/tests.rs
+++ b/src/transport/libp2p/tests.rs
@@ -220,6 +220,40 @@ fn address_ranges() {
for wrong in ["10.244.0.0/33", "42::/129", "nowhere", "10.0.0.0/x"] {
assert!(wrong.parse::<IpRange>().is_err(), "{wrong}");
}
+ // Mycelium's range: a prefix that isn't a multiple of 8.
+ let mycelium = [range("400::/7")];
+ assert!(ignored(
+ &mycelium,
+ &address("/ip6/45f:fa21:4bdd:1::1/tcp/9661")
+ ));
+ assert!(ignored(&mycelium, &address("/ip6/5ff::1/tcp/9661")));
+ assert!(!ignored(&mycelium, &address("/ip6/600::1/tcp/9661")));
+}
+
+/// A preferred range all ignored is refused; one with an ignored range in it is fine
+/// (with a warning).
+#[test]
+fn preferred_and_ignored_ranges() {
+ let check = |ignore: &[&str], prefer: &[&str]| {
+ let given = |ranges: &[&str]| {
+ ranges
+ .iter()
+ .map(|range| range.to_string())
+ .collect::<Vec<_>>()
+ };
+ let (ignore, prefer) = (given(ignore), given(prefer));
+ super::config::check_preferred(
+ &super::config::parse_ranges("libp2p-ignore", &ignore).unwrap(),
+ &super::config::parse_ranges("libp2p-prefer", &prefer).unwrap(),
+ &ignore,
+ &prefer,
+ )
+ };
+ assert!(check(&["10.244.0.0/16"], &["10.23.0.0/16"]).is_ok());
+ assert!(check(&["10.0.0.0/8"], &["10.23.0.0/16"]).is_err());
+ assert!(check(&["10.23.0.0/16"], &["10.23.0.0/16"]).is_err());
+ assert!(check(&["10.23.5.0/24"], &["10.23.0.0/16"]).is_ok());
+ assert!(check(&["42::/16"], &["10.0.0.0/8"]).is_ok());
}
/// Ranges left out aren't published; announced addresses are, whatever they are.