add forbidden_nets config option

This commit is contained in:
Yureka 2025-01-15 10:44:39 +01:00
parent 4c08a63811
commit c811f2d0a1
3 changed files with 52 additions and 3 deletions

12
Cargo.lock generated
View file

@ -1,6 +1,6 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
version = 4
[[package]]
name = "aead"
@ -288,6 +288,15 @@ dependencies = [
"generic-array",
]
[[package]]
name = "ipnet"
version = "2.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708"
dependencies = [
"serde",
]
[[package]]
name = "is-terminal"
version = "0.4.12"
@ -621,6 +630,7 @@ dependencies = [
"blake3",
"get_if_addrs",
"igd",
"ipnet",
"log",
"pretty_env_logger",
"serde",

View file

@ -19,3 +19,4 @@ blake3 = "1.5"
igd = { version = "0.12", default-features = false }
get_if_addrs = "0.5"
ipnet = { version = "2.10.1", features = ["serde"] }

View file

@ -50,6 +50,9 @@ struct Config {
/// The list of peers we try to connect to
#[serde(default)]
peers: Vec<Peer>,
#[serde(default)]
forbidden_nets: Vec<ipnet::IpNet>,
}
#[derive(Deserialize)]
@ -527,7 +530,20 @@ impl State {
let mut peer_vec = self
.peers
.iter()
.filter(|(_, info)| now < info.last_seen + TIMEOUT.as_secs() && info.endpoint.is_some())
.filter(|(_, info)| {
let seen = now < info.last_seen + TIMEOUT.as_secs();
let endpoint_valid = info
.endpoint
.map(|ep| {
!daemon
.config
.forbidden_nets
.iter()
.any(|net| net.contains(&ep))
})
.unwrap_or(false);
seen && endpoint_valid
})
.map(|(_, info)| (info.gossip_ip, info.gossip_prio))
.collect::<Vec<_>>();
peer_vec.sort_by_key(|(_, prio)| *prio);
@ -628,10 +644,22 @@ impl State {
(Some((addr1, _)), Some(addr2)) => addr1 != addr2,
_ => false,
};
// If the current endpoint is in a forbidden net, reconfigure the peer even if it has a connection
let forbidden_endpoint = peer
.endpoint
.map(|ep| {
daemon
.config
.forbidden_nets
.iter()
.any(|net| net.contains(&ep))
})
.unwrap_or(false);
// if peer is connected and endpoint is the correct one,
// set higher keepalive and then skip reconfiguring it
if !bad_endpoint && now < peer.last_seen + TIMEOUT.as_secs() {
if !bad_endpoint && !forbidden_endpoint && now < peer.last_seen + TIMEOUT.as_secs()
{
Command::new("wg")
.args([
"set",
@ -671,6 +699,16 @@ impl State {
}
}
endpoints.sort();
endpoints = endpoints
.into_iter()
.filter(|(ep, _)| {
!daemon
.config
.forbidden_nets
.iter()
.any(|net| net.contains(ep))
})
.collect();
endpoints
}
};