client, wgctrl: fix various linux userspace issues

Fixes #75
pull/74/head
Jake McGinty 2021-05-20 03:16:19 +09:00
parent e95d79db66
commit 5b744d1f78
4 changed files with 47 additions and 14 deletions

View File

@ -253,6 +253,7 @@ fn install(
let iface = iface.parse()?; let iface = iface.parse()?;
redeem_invite(&iface, config, target_conf, network).map_err(|e| { redeem_invite(&iface, config, target_conf, network).map_err(|e| {
println!("{} failed to start the interface: {}.", "[!]".red(), e);
println!("{} bringing down the interface.", "[*]".dimmed()); println!("{} bringing down the interface.", "[*]".dimmed());
if let Err(e) = wg::down(&iface, network.backend) { if let Err(e) = wg::down(&iface, network.backend) {
println!("{} failed to bring down interface: {}.", "[*]".yellow(), e.to_string()); println!("{} failed to bring down interface: {}.", "[*]".yellow(), e.to_string());
@ -263,10 +264,11 @@ fn install(
let mut fetch_success = false; let mut fetch_success = false;
for _ in 0..3 { 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; fetch_success = true;
break; break;
} }
thread::sleep(Duration::from_secs(1));
} }
if !fetch_success { if !fetch_success {
println!( println!(

View File

@ -380,8 +380,11 @@ fn spawn_expired_invite_sweeper(db: Db) {
loop { loop {
interval.tick().await; interval.tick().await;
match DatabasePeer::delete_expired_invites(&db.lock()) { 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), Err(e) => log::error!("Failed to delete expired peer invitations: {}", e),
_ => {},
} }
} }
}); });
@ -439,6 +442,7 @@ async fn serve(
let context = context.clone(); let context = context.clone();
async move { async move {
Ok::<_, http::Error>(hyper::service::service_fn(move |req: Request<Body>| { Ok::<_, http::Error>(hyper::service::service_fn(move |req: Request<Body>| {
log::debug!("{} - {} {}", &remote_addr, req.method(), req.uri());
hyper_service(req, context.clone(), remote_addr) hyper_service(req, context.clone(), remote_addr)
})) }))
} }

View File

@ -8,6 +8,16 @@ use wgctrl::{Backend, Device, DeviceUpdate, InterfaceName, PeerConfigBuilder};
fn cmd(bin: &str, args: &[&str]) -> Result<process::Output, Error> { fn cmd(bin: &str, args: &[&str]) -> Result<process::Output, Error> {
let output = Command::new(bin).args(args).output()?; 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() { if output.status.success() {
Ok(output) Ok(output)
} else { } else {
@ -87,6 +97,7 @@ pub fn up(
if !network.no_routing { if !network.no_routing {
add_route(interface, address)?; add_route(interface, address)?;
} }
cmd("ip", &["link"])?;
Ok(()) Ok(())
} }
@ -107,7 +118,10 @@ pub fn set_listen_port(
} }
pub fn down(interface: &InterfaceName, backend: Backend) -> Result<(), Error> { 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. /// 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<bool, Err
&[ &[
"route", "route",
"add", "add",
&cidr.to_string(), &IpNetwork::new(cidr.network(), cidr.prefix())?.to_string(),
"dev", "dev",
&interface.to_string(), &interface.to_string(),
], ],

View File

@ -33,8 +33,12 @@ fn get_namefile(name: &InterfaceName) -> io::Result<PathBuf> {
} }
fn get_socketfile(name: &InterfaceName) -> io::Result<PathBuf> { fn get_socketfile(name: &InterfaceName) -> io::Result<PathBuf> {
if cfg!(target_os = "linux") {
Ok(get_base_folder()?.join(&format!("{}.sock", name)))
} else {
Ok(get_base_folder()?.join(&format!("{}.sock", resolve_tun(name)?))) Ok(get_base_folder()?.join(&format!("{}.sock", resolve_tun(name)?)))
} }
}
fn open_socket(name: &InterfaceName) -> io::Result<UnixStream> { fn open_socket(name: &InterfaceName) -> io::Result<UnixStream> {
UnixStream::connect(get_socketfile(name)?) UnixStream::connect(get_socketfile(name)?)
@ -42,7 +46,10 @@ fn open_socket(name: &InterfaceName) -> io::Result<UnixStream> {
pub fn resolve_tun(name: &InterfaceName) -> io::Result<String> { pub fn resolve_tun(name: &InterfaceName) -> io::Result<String> {
let namefile = get_namefile(name)?; 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<()> { 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) { let mut sock = match open_socket(iface) {
Err(_) => { Err(_) => {
fs::create_dir_all(VAR_RUN_PATH)?; fs::create_dir_all(VAR_RUN_PATH)?;
let output = Command::new(&get_userspace_implementation()) let mut command = Command::new(&get_userspace_implementation());
let output = if cfg!(target_os = "linux") {
command.args(&[iface.to_string()]).output()?
} else {
command
.env( .env(
"WG_TUN_NAME_FILE", "WG_TUN_NAME_FILE",
&format!("{}/{}.name", VAR_RUN_PATH, iface), &format!("{}/{}.name", VAR_RUN_PATH, iface),
) )
.args(&["utun"]) .args(&["utun"])
.output()?; .output()?
};
if !output.status.success() { if !output.status.success() {
return Err(io::ErrorKind::AddrNotAvailable.into()); return Err(io::ErrorKind::AddrNotAvailable.into());
} }
std::thread::sleep(Duration::from_millis(100)); 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, Ok(sock) => sock,
}; };