From 5b744d1f78b5b275d058088dddbdb7f07c1b4269 Mon Sep 17 00:00:00 2001 From: Jake McGinty Date: Thu, 20 May 2021 03:16:19 +0900 Subject: [PATCH] client, wgctrl: fix various linux userspace issues Fixes #75 --- client/src/main.rs | 4 +++- server/src/main.rs | 6 +++++- shared/src/wg.rs | 18 ++++++++++++++-- wgctrl-rs/src/backends/userspace.rs | 33 ++++++++++++++++++++--------- 4 files changed, 47 insertions(+), 14 deletions(-) diff --git a/client/src/main.rs b/client/src/main.rs index c212d84..c039b80 100644 --- a/client/src/main.rs +++ b/client/src/main.rs @@ -253,6 +253,7 @@ fn install( let iface = iface.parse()?; redeem_invite(&iface, config, target_conf, network).map_err(|e| { + println!("{} failed to start the interface: {}.", "[!]".red(), e); println!("{} bringing down the interface.", "[*]".dimmed()); if let Err(e) = wg::down(&iface, network.backend) { println!("{} failed to bring down interface: {}.", "[*]".yellow(), e.to_string()); @@ -263,10 +264,11 @@ fn install( let mut fetch_success = false; for _ in 0..3 { - if fetch(&iface, false, hosts_file.clone(), network).is_ok() { + if fetch(&iface, true, hosts_file.clone(), network).is_ok() { fetch_success = true; break; } + thread::sleep(Duration::from_secs(1)); } if !fetch_success { println!( diff --git a/server/src/main.rs b/server/src/main.rs index 8d5267a..5b56dcf 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -380,8 +380,11 @@ fn spawn_expired_invite_sweeper(db: Db) { loop { interval.tick().await; match DatabasePeer::delete_expired_invites(&db.lock()) { - Ok(deleted) => log::info!("Deleted {} expired peer invitations.", deleted), + Ok(deleted) if deleted > 0 => { + log::info!("Deleted {} expired peer invitations.", deleted) + }, Err(e) => log::error!("Failed to delete expired peer invitations: {}", e), + _ => {}, } } }); @@ -439,6 +442,7 @@ async fn serve( let context = context.clone(); async move { Ok::<_, http::Error>(hyper::service::service_fn(move |req: Request| { + log::debug!("{} - {} {}", &remote_addr, req.method(), req.uri()); hyper_service(req, context.clone(), remote_addr) })) } diff --git a/shared/src/wg.rs b/shared/src/wg.rs index fb8eca3..383ac79 100644 --- a/shared/src/wg.rs +++ b/shared/src/wg.rs @@ -8,6 +8,16 @@ use wgctrl::{Backend, Device, DeviceUpdate, InterfaceName, PeerConfigBuilder}; fn cmd(bin: &str, args: &[&str]) -> Result { let output = Command::new(bin).args(args).output()?; + log::debug!("{} {}", bin, args.join(" ")); + log::debug!("status code {:?}", output.status.code()); + log::trace!( + "stdout: {}", + String::from_utf8_lossy(&output.stdout) + ); + log::trace!( + "stderr: {}", + String::from_utf8_lossy(&output.stderr) + ); if output.status.success() { Ok(output) } else { @@ -87,6 +97,7 @@ pub fn up( if !network.no_routing { add_route(interface, address)?; } + cmd("ip", &["link"])?; Ok(()) } @@ -107,7 +118,10 @@ pub fn set_listen_port( } pub fn down(interface: &InterfaceName, backend: Backend) -> Result<(), Error> { - Ok(Device::get(interface, backend)?.delete()?) + Ok(Device::get(interface, backend) + .with_str(interface.as_str_lossy())? + .delete() + .with_str(interface.as_str_lossy())?) } /// Add a route in the OS's routing table to get traffic flowing through this interface. @@ -145,7 +159,7 @@ pub fn add_route(interface: &InterfaceName, cidr: IpNetwork) -> Result io::Result { } fn get_socketfile(name: &InterfaceName) -> io::Result { - Ok(get_base_folder()?.join(&format!("{}.sock", resolve_tun(name)?))) + if cfg!(target_os = "linux") { + Ok(get_base_folder()?.join(&format!("{}.sock", name))) + } else { + Ok(get_base_folder()?.join(&format!("{}.sock", resolve_tun(name)?))) + } } fn open_socket(name: &InterfaceName) -> io::Result { @@ -42,7 +46,10 @@ fn open_socket(name: &InterfaceName) -> io::Result { pub fn resolve_tun(name: &InterfaceName) -> io::Result { let namefile = get_namefile(name)?; - Ok(fs::read_to_string(namefile)?.trim().to_string()) + Ok(fs::read_to_string(namefile) + .map_err(|_| io::Error::new(io::ErrorKind::NotFound, "WireGuard name file can't be read"))? + .trim() + .to_string()) } pub fn delete_interface(name: &InterfaceName) -> io::Result<()> { @@ -269,18 +276,24 @@ pub fn apply(builder: &DeviceUpdate, iface: &InterfaceName) -> io::Result<()> { let mut sock = match open_socket(iface) { Err(_) => { fs::create_dir_all(VAR_RUN_PATH)?; - let output = Command::new(&get_userspace_implementation()) - .env( - "WG_TUN_NAME_FILE", - &format!("{}/{}.name", VAR_RUN_PATH, iface), - ) - .args(&["utun"]) - .output()?; + let mut command = Command::new(&get_userspace_implementation()); + let output = if cfg!(target_os = "linux") { + command.args(&[iface.to_string()]).output()? + } else { + command + .env( + "WG_TUN_NAME_FILE", + &format!("{}/{}.name", VAR_RUN_PATH, iface), + ) + .args(&["utun"]) + .output()? + }; if !output.status.success() { return Err(io::ErrorKind::AddrNotAvailable.into()); } std::thread::sleep(Duration::from_millis(100)); - open_socket(iface)? + open_socket(iface) + .map_err(|e| io::Error::new(e.kind(), format!("failed to open socket ({})", e)))? }, Ok(sock) => sock, };