aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJake McGinty <me@jake.su>2018-02-26 03:03:15 +0000
committerJake McGinty <me@jake.su>2018-02-26 03:03:15 +0000
commita67009a677900c12f1ba564715c7c55f288259e3 (patch)
tree104400cea175565426b6ec4dbeda732c3fad90db
parentadd cross-platform fs notify library (diff)
downloadwireguard-rs-a67009a677900c12f1ba564715c7c55f288259e3.tar.xz
wireguard-rs-a67009a677900c12f1ba564715c7c55f288259e3.zip
die on SIG{INT,TERM} and config UDS deletion, per spec
-rw-r--r--Cargo.lock16
-rw-r--r--Cargo.toml1
-rw-r--r--src/interface/config.rs5
-rw-r--r--src/interface/grim_reaper.rs70
-rw-r--r--src/interface/mod.rs28
-rw-r--r--src/lib.rs2
6 files changed, 112 insertions, 10 deletions
diff --git a/Cargo.lock b/Cargo.lock
index b113e4d..5ed5504 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1136,6 +1136,20 @@ dependencies = [
]
[[package]]
+name = "tokio-signal"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio-uds 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-io 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "tokio-timer"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1262,6 +1276,7 @@ dependencies = [
"subtle 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-signal 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-uds 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-utun 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1452,6 +1467,7 @@ dependencies = [
"checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098"
"checksum tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "52b4e32d8edbf29501aabb3570f027c6ceb00ccef6538f4bddba0200503e74e8"
"checksum tokio-io 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b9532748772222bf70297ec0e2ad0f17213b4a7dd0e6afb68e0a0768f69f4e4f"
+"checksum tokio-signal 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c4ef9836ecceb2583e0ddf25b7ca448fac74c1115461436f85e088a8e39e7904"
"checksum tokio-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6131e780037787ff1b3f8aad9da83bca02438b72277850dd6ad0d455e0e20efc"
"checksum tokio-uds 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "65ae5d255ce739e8537221ed2942e0445f4b3b813daebac1c0050ddaaa3587f9"
"checksum tokio-utun 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "5352f613ebd4d3a9ec72c087da0a34480dd942529af6897788ff7fe2689936af"
diff --git a/Cargo.toml b/Cargo.toml
index ce22b1a..e7e1d08 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -52,6 +52,7 @@ tokio-core = "^0.1"
tokio-uds = "^0.1"
tokio-utun = "^0.1"
tokio-timer = "^0.1"
+tokio-signal = "^0.1"
treebitmap = "^0.2"
x25519-dalek = "^0.1"
diff --git a/src/interface/config.rs b/src/interface/config.rs
index b2e25d8..71ca155 100644
--- a/src/interface/config.rs
+++ b/src/interface/config.rs
@@ -136,10 +136,7 @@ impl ConfigurationServiceManager {
}
}
- /// Creates a new `WireGuard` instance
pub fn get_path(&self) -> Result<PathBuf, Error> {
- // let _tun = Tun::create(Some("hey"));
- // Create the socket directory if not existing
let mut socket_path = Self::get_run_path().join("wireguard");
if !socket_path.exists() {
@@ -162,7 +159,6 @@ impl ConfigurationServiceManager {
}
#[cfg(unix)]
- /// Sets the permissions to a given `Path`
fn chmod(path: &Path, perms: u32) -> Result<(), Error> {
use std::os::unix::prelude::PermissionsExt;
use std::fs::{set_permissions, Permissions};
@@ -171,7 +167,6 @@ impl ConfigurationServiceManager {
}
#[cfg(windows)]
- /// Sets the permissions to a given `Path`
fn chmod(_path: &Path, _perms: u32) -> Result<(), Error> {
Ok(())
}
diff --git a/src/interface/grim_reaper.rs b/src/interface/grim_reaper.rs
new file mode 100644
index 0000000..0bbe7b6
--- /dev/null
+++ b/src/interface/grim_reaper.rs
@@ -0,0 +1,70 @@
+use failure::Error;
+use futures::{self, Future, Async, Poll, Stream};
+use notify::{self, Watcher, RecursiveMode, RawEvent, raw_watcher};
+use std::{self, thread, time::Duration, path::Path};
+use tokio_core::reactor::Handle;
+use tokio_signal::{self, unix::{Signal, SIGTERM}};
+
+pub struct GrimReaper {
+ rx: futures::sync::oneshot::Receiver<()>,
+ signal: Box<Stream<Item = (), Error = std::io::Error>>,
+}
+
+impl GrimReaper {
+ pub fn spawn(handle: &Handle, socket_path: &Path) -> Result<Self, Error> {
+ let (std_tx, std_rx) = std::sync::mpsc::channel::<RawEvent>();
+ let (tx, rx ) = futures::sync::oneshot::channel::<()>();
+
+ let path = socket_path.to_owned();
+ debug!("grim reaper spawning for {}.", socket_path.to_string_lossy());
+
+ thread::Builder::new()
+ .name("grim reaper".into())
+ .spawn(move || {
+ thread::sleep(Duration::from_millis(500));
+ let mut watcher = raw_watcher(std_tx).unwrap();
+ watcher.watch(path, RecursiveMode::Recursive).unwrap();
+
+ loop {
+ debug!("listening");
+ let event = std_rx.recv().unwrap();
+ debug!("FS EVENT: {:?}", event);
+ if event.op.unwrap() == notify::op::REMOVE {
+ tx.send(()).unwrap();
+ panic!("configuration socket removed, sounding death cry.")
+ }
+ }
+ })?;
+
+ let sigint = tokio_signal::ctrl_c(&handle).flatten_stream();
+ let sigterm = Signal::new(SIGTERM, &handle).flatten_stream().map(|_| ());
+ let signal = Box::new(sigint.select(sigterm));
+
+ Ok(Self { rx, signal })
+ }
+}
+
+impl Future for GrimReaper {
+ type Item = ();
+ type Error = ();
+
+ fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
+ match self.rx.poll() {
+ Ok(Async::NotReady) => {},
+ _ => {
+ info!("configuration socket removed, bubbling up to reactor core.");
+ return Err(())
+ },
+ }
+
+ match self.signal.poll() {
+ Ok(Async::NotReady) => {},
+ _ => {
+ info!("SIGINT received, bubbling up to reactor core.");
+ return Err(())
+ },
+ }
+
+ Ok(Async::NotReady)
+ }
+}
diff --git a/src/interface/mod.rs b/src/interface/mod.rs
index 532fb40..e969954 100644
--- a/src/interface/mod.rs
+++ b/src/interface/mod.rs
@@ -1,7 +1,9 @@
mod config;
+mod grim_reaper;
mod peer_server;
use self::config::{ConfigurationServiceManager, UpdateEvent, Command, ConfigurationCodec};
+use self::grim_reaper::GrimReaper;
use self::peer_server::PeerServer;
use router::Router;
@@ -13,6 +15,7 @@ use std::io;
use std::rc::Rc;
use std::cell::RefCell;
use std::collections::HashMap;
+use std::fs::remove_file;
use types::{InterfaceInfo};
use x25519_dalek as x25519;
@@ -115,11 +118,14 @@ impl Interface {
.map_err(|e| { warn!("utun write error: {:?}", e); () });
let utun_fut = utun_write_fut.join(utun_read_fut);
- let config_manager = ConfigurationServiceManager::new(&self.name);
- let handle = core.handle();
- let listener = UnixListener::bind(config_manager.get_path().unwrap(), &handle).unwrap();
+ let config_manager = ConfigurationServiceManager::new(&self.name);
+ let handle = core.handle();
+ let config_path = config_manager.get_path().unwrap();
+ let listener = UnixListener::bind(config_path.clone(), &handle).unwrap();
+ let reaper = GrimReaper::spawn(&handle, config_path.parent().unwrap()).unwrap();
let (config_tx, config_rx) = sync::mpsc::channel::<UpdateEvent>(1024);
- let h = handle.clone();
+ let h = handle.clone();
+
let config_server = listener.incoming().for_each({
let config_tx = config_tx.clone();
let state = self.state.clone();
@@ -231,6 +237,18 @@ impl Interface {
let config_fut = peer_server.config_tx().sink_map_err(|_|()).send_all(config_fut).map_err(|e| { warn!("error {:?}", e); () });
- core.run(peer_server.join(utun_fut.join(config_fut.join(config_server)))).unwrap();
+ core.run(reaper.join(peer_server.join(utun_fut.join(config_fut.join(config_server))))).unwrap();
}
}
+
+impl Drop for Interface {
+ fn drop(&mut self) {
+ let mut socket_path = ConfigurationServiceManager::get_run_path().join("wireguard");
+ socket_path.push(&self.name);
+ socket_path.set_extension("sock");
+ if socket_path.exists() {
+ info!("Removing socket on drop: {}", socket_path.display());
+ let _ = remove_file(&socket_path);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/lib.rs b/src/lib.rs
index 9cd3dd6..376a34d 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -19,6 +19,7 @@ extern crate env_logger;
extern crate futures;
extern crate hex;
extern crate nix;
+extern crate notify;
extern crate pnet_packet;
extern crate rand;
extern crate snow;
@@ -30,6 +31,7 @@ extern crate tokio_io;
extern crate tokio_uds;
extern crate tokio_utun;
extern crate tokio_timer;
+extern crate tokio_signal;
extern crate treebitmap;
extern crate x25519_dalek;