Compare commits

..

No commits in common. "a1a95f2865076cd9147e3634e43e88e4546b1c67" and "fb83d6e04f0cc78b3b8f76c0ede6e19d342ca331" have entirely different histories.

3 changed files with 25 additions and 90 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 = 4
version = 3
[[package]]
name = "addr2line"
@ -452,15 +452,6 @@ 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 = "ipnetwork"
version = "0.20.0"
@ -1010,7 +1001,6 @@ dependencies = [
"bincode",
"blake3",
"futures",
"ipnet",
"log",
"pnet",
"pretty_env_logger",

View file

@ -20,4 +20,3 @@ pnet = "0.35.0"
rupnp = "2.0.0"
tokio = { version = "1.41.1", features = ["rt", "rt-multi-thread", "macros"] }
futures = "0.3.31"
ipnet = { version = "2.10.1", features = ["serde"] }

View file

@ -29,8 +29,6 @@ const PERSIST_INTERVAL: Duration = Duration::from_secs(600);
const LAN_BROADCAST_INTERVAL: Duration = Duration::from_secs(60);
const IGD_INTERVAL: Duration = Duration::from_secs(60);
const IGD_LEASE_DURATION: Duration = Duration::from_secs(300);
type Pubkey = String;
#[derive(Deserialize)]
@ -58,9 +56,6 @@ struct Config {
/// Settings for the Wireguard interfaces (currently only necessary if you want to use igd features)
#[serde(default)]
interfaces: Vec<InterfaceSetting>,
#[serde(default)]
forbidden_nets: Vec<ipnet::IpNet>,
}
#[derive(Deserialize)]
@ -173,11 +168,7 @@ fn wg_dump(interface: &str) -> Result<IfInfo> {
})
.collect::<Vec<_>>();
Ok(IfInfo {
our_pubkey,
listen_port,
peers,
})
Ok(IfInfo { our_pubkey, listen_port, peers })
}
// ============ DAEMON CODE =================
@ -219,39 +210,26 @@ impl Daemon {
fn new(config: Config) -> Result<Self> {
let gossip_key = kdf(config.gossip_secret.as_deref().unwrap_or_default());
let interface_names = config
.peers
.iter()
.map(|peer| peer.interface.clone())
.collect::<HashSet<_>>();
let interfaces = interface_names
.into_iter()
.map(|interface_name| wg_dump(&interface_name).map(|ifinfo| (interface_name, ifinfo)))
.collect::<Result<HashMap<_, _>>>()?;
let interface_names = config.peers.iter().map(|peer| peer.interface.clone()).collect::<HashSet<_>>();
let interfaces = interface_names.into_iter().map(|interface_name| wg_dump(&interface_name).map(|ifinfo| (interface_name, ifinfo))).collect::<Result<HashMap<_, _>>>()?;
let socket = UdpSocket::bind(SocketAddr::new("::".parse()?, config.gossip_port))?;
socket.set_broadcast(true)?;
//socket.set_ttl(1)?;
socket.set_ttl(1)?;
let our_pubkey = interfaces.iter().next().unwrap().1.our_pubkey.clone();
let peers = config
.peers
.iter()
.map(|peer_cfg| {
let peers = config.peers.iter().map(|peer_cfg| {
(
peer_cfg.pubkey.clone(),
PeerInfo {
gossip_ip: peer_cfg.address,
gossip_prio: fasthash(
format!("{}-{}", our_pubkey, peer_cfg.pubkey).as_bytes(),
),
gossip_prio: fasthash(format!("{}-{}", our_pubkey, peer_cfg.pubkey).as_bytes()),
endpoint: None, // Is resolved as DNS name later
last_seen: u64::MAX,
lan_endpoint: None,
},
}
)
})
.collect();
}).collect();
Ok(Daemon {
config,
@ -379,7 +357,9 @@ impl Daemon {
self.socket.send_to(&packet, from)?;
}
}
Gossip::LanBroadcast { pubkey } => {
Gossip::LanBroadcast {
pubkey,
} => {
if self.config.lan_discovery {
if let Some(peer) = state.peers.get_mut(&pubkey) {
peer.lan_endpoint = Some((from.ip(), time()));
@ -548,20 +528,7 @@ impl State {
let mut peer_vec = self
.peers
.iter()
.filter(|(_, info)| {
let seen = info.last_seen != u64::MAX && 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
})
.filter(|(_, info)| info.last_seen != u64::MAX && now < info.last_seen + TIMEOUT.as_secs() && info.endpoint.is_some())
.map(|(_, info)| (info.gossip_ip, info.gossip_prio))
.collect::<Vec<_>>();
peer_vec.sort_by_key(|(_, prio)| *prio);
@ -622,6 +589,7 @@ impl State {
}
fn read_wg_peers(&mut self) -> Result<()> {
// Clear old known endpoints if any
for (_, peer) in self.peers.iter_mut() {
peer.endpoint = None;
@ -662,22 +630,10 @@ 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 && peer.last_seen != u64::MAX && !forbidden_endpoint && now < peer.last_seen + TIMEOUT.as_secs()
{
if !bad_endpoint && peer.last_seen != u64::MAX && now < peer.last_seen + TIMEOUT.as_secs() {
Command::new("wg")
.args([
"set",
@ -717,16 +673,6 @@ impl State {
}
}
endpoints.sort();
endpoints = endpoints
.into_iter()
.filter(|(ep, _)| {
!daemon
.config
.forbidden_nets
.iter()
.any(|net| net.contains(ep))
})
.collect();
endpoints
}
};
@ -756,7 +702,7 @@ impl State {
"persistent-keepalive",
"10",
"allowed-ips",
"::/0,0.0.0.0/0",
"::/0,0.0.0.0/0"
])
.output()?;
let packet = daemon.make_packet(&Gossip::Ping)?;
@ -774,7 +720,7 @@ impl State {
"peer",
&peer_cfg.pubkey,
"allowed-ips",
"::/0,0.0.0.0/0",
"::/0,0.0.0.0/0"
])
.output()?;
}