diff options
Diffstat (limited to 'src/daemon_network.rs')
-rw-r--r-- | src/daemon_network.rs | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/src/daemon_network.rs b/src/daemon_network.rs new file mode 100644 index 0000000..895e409 --- /dev/null +++ b/src/daemon_network.rs @@ -0,0 +1,102 @@ +use atomic_write_file::AtomicWriteFile; +use defguard_wireguard_rs::{ + host::Peer, key::Key, net::IpAddrMask, InterfaceConfiguration, WGApi, WireguardInterfaceApi, +}; +use log::{debug, error, info, warn}; +use std::{ + collections::{BTreeSet, HashMap}, + io::Write, + net::ToSocketAddrs, + sync::Arc, +}; +use tokio::{ + net::TcpListener, + sync::{broadcast, RwLock}, +}; + +use crate::daemon::*; + +pub async fn add_network( + hostfile: &mut Option<(String, BTreeSet<String>)>, + name: String, + privkey: String, + address: String, + port: u16, + peers: &HashMap<Key, PeerConfig>, +) -> Result<WGApi, DaemonError> { + let wg = WGApi::new(name.clone(), false)?; + let defguard_peers = peers + .iter() + .map(|(peer_key, p)| Peer { + public_key: peer_key.clone(), + preshared_key: p.psk.clone(), + protocol_version: None, + endpoint: p + .endpoint + .clone() + .map(|e| match e { + Endpoint::Ip(ep) => Some(ep), + Endpoint::Domain(s, p) => (s, p) + .to_socket_addrs() + .ok() + .map(|mut it| it.next()) + .flatten(), + }) + .flatten(), + last_handshake: None, + tx_bytes: 0, + rx_bytes: 0, + persistent_keepalive_interval: None, + allowed_ips: p.ips.iter().map(|(ip_mask, _)| ip_mask.clone()).collect(), + }) + .collect(); + wg.create_interface()?; + wg.configure_interface(&InterfaceConfiguration { + name: name.clone(), + prvkey: privkey, + address: address, + port: port as u32, + peers: defguard_peers, + })?; + + if let Some((hosts_str, hosts)) = hostfile { + peers + .values() + .map(|peer| { + if peer.use_hostnames { + peer.ips + .iter() + .map(|(mask, may_dom)| { + if let Some(dom) = may_dom + && hosts.insert(dom.clone()) + { + hosts_str.push_str(&format!("{}", mask.ip)); + hosts_str.push('\t'); + hosts_str.push_str(&dom); + hosts_str.push('\n'); + } + }) + .count(); + } + }) + .count(); + } + + if let Some((hosts_str, _)) = hostfile { + debug!("writing hosts file: {hosts_str}"); + + let mut f = AtomicWriteFile::open("/etc/hosts")?; + f.write(hosts_str.as_bytes())?; + f.commit()?; + } + + Ok(wg) +} + +pub async fn run_network( + state: Arc<RwLock<State>>, + sock: TcpListener, + nw_name: String, +) -> Result<(), DaemonError> { + Ok(()) +} |