summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorEmīls <emils@mullvad.net>2018-05-15 16:09:56 +0100
committerEmīls Piņķis <emils@mullvad.net>2018-05-22 12:49:57 +0200
commitbb8a81e15382effe2cbf56d4bfb4b703b89ccff5 (patch)
tree497e2c5aab828e07dd90e1a2e7ee0f6d46b3d37b
parent01afa29fac8b44be0ddf0ef666fc4771069bb32b (diff)
downloadmullvadvpn-bb8a81e15382effe2cbf56d4bfb4b703b89ccff5.tar.xz
mullvadvpn-bb8a81e15382effe2cbf56d4bfb4b703b89ccff5.zip
Fix shutdown behaviour on windows
-rw-r--r--talpid-core/src/process/openvpn.rs50
-rw-r--r--talpid-core/src/process/stoppable_process.rs12
-rw-r--r--talpid-core/src/tunnel/openvpn.rs3
3 files changed, 15 insertions, 50 deletions
diff --git a/talpid-core/src/process/openvpn.rs b/talpid-core/src/process/openvpn.rs
index 4884b593c9..805d97c0a6 100644
--- a/talpid-core/src/process/openvpn.rs
+++ b/talpid-core/src/process/openvpn.rs
@@ -1,17 +1,17 @@
use duct;
-extern crate os_pipe;
extern crate libc;
+extern crate os_pipe;
+use super::stoppable_process::StoppableProcess;
use std::ffi::{OsStr, OsString};
use std::fmt;
use std::path::{Path, PathBuf};
-use super::stoppable_process::StoppableProcess;
+use std::sync::Mutex;
use self::os_pipe::{pipe, PipeWriter};
use atty;
use shell_escape;
use std::io;
-use std::sync::{Arc, Mutex};
use talpid_types::net;
static BASE_ARGUMENTS: &[&[&str]] = &[
@@ -224,19 +224,18 @@ pub struct OpenVpnProcHandle {
/// Duct handle
pub inner: duct::Handle,
/// Standard input handle
- pub stdin: PipeWriter,
+ pub stdin: Mutex<Option<PipeWriter>>,
}
/// Impl for proc handle
impl OpenVpnProcHandle {
- const KILL_BYTE: u8 = b'c';
/// Constructor for a new openvpn proc handle
pub fn new(mut cmd: duct::Expression) -> io::Result<Self> {
- if atty::is(atty::Stream::Stdout) {
+ if !atty::is(atty::Stream::Stdout) {
cmd = cmd.stdout_null();
}
- if atty::is(atty::Stream::Stderr) {
+ if !atty::is(atty::Stream::Stderr) {
cmd = cmd.stderr_null();
}
@@ -245,41 +244,18 @@ impl OpenVpnProcHandle {
Ok(Self {
inner: proc_handle,
- stdin: writer,
+ stdin: Mutex::new(Some(writer)),
})
}
-
}
impl StoppableProcess for OpenVpnProcHandle {
- #[cfg(unix)]
/// Closes STDIN to stop the openvpn process
- fn stop(&self) -> io::Result<()> {
- use std::io::Error;
- use std::os::unix::io::AsRawFd;
- let raw_fd = self.stdin.as_raw_fd();
- unsafe {
- let err = libc::close(raw_fd);
- match err {
- 0 => Ok(()),
- err => Err(Error::from_raw_os_error(err)),
- }
- }
- }
-
- #[cfg(windows)]
- fn stop(&self) -> io::Result<()> {
- use std::io::Error;
- use std::os::unix::io::AsRawHandle;
- use libc::funcs::extra::kernel32;
- let raw_handle = self.stdin.as_raw_handle();
- unsafe {
- let success = CloseHandle(raw_handle);
- match err {
- 0 => Err(Error::last_os_error()),
- _ => Ok(()),
- }
- }
+ fn stop(&self) {
+ let mut stdin = self.stdin.lock().unwrap();
+ // Dropping our stdin handle so that it is closed once. Closing the handle should
+ // gracefully stop our openvpn child process.
+ let _ = stdin.take();
}
fn kill(&self) -> io::Result<()> {
@@ -296,8 +272,6 @@ impl StoppableProcess for OpenVpnProcHandle {
}
-
-
#[cfg(test)]
mod tests {
use super::OpenVpnCommand;
diff --git a/talpid-core/src/process/stoppable_process.rs b/talpid-core/src/process/stoppable_process.rs
index c2d8304d85..bfd0ec3ac4 100644
--- a/talpid-core/src/process/stoppable_process.rs
+++ b/talpid-core/src/process/stoppable_process.rs
@@ -1,6 +1,5 @@
extern crate libc;
-use std::error::Error;
use std::io;
use std::thread;
use std::time::{Duration, Instant};
@@ -14,7 +13,7 @@ where
Self: Sized,
{
/// Gracefully stops a process.
- fn stop(&self) -> io::Result<()>;
+ fn stop(&self);
/// Kills a process unconditionally. Implementations should strive to never fail.
fn kill(&self) -> io::Result<()>;
@@ -26,14 +25,7 @@ where
/// process.
fn nice_kill(&self, timeout: Duration) -> io::Result<()> {
trace!("Trying to stop child process gracefully");
- if let Err(e) = self.stop() {
- error!(
- "Failed to stop the child process gracefully: {}",
- e.description()
- );
- return self.kill();
- };
-
+ self.stop();
if wait_timeout(self, timeout)? {
debug!("Child process terminated gracefully");
Ok(())
diff --git a/talpid-core/src/tunnel/openvpn.rs b/talpid-core/src/tunnel/openvpn.rs
index 0380f29bce..58fa15eca2 100644
--- a/talpid-core/src/tunnel/openvpn.rs
+++ b/talpid-core/src/tunnel/openvpn.rs
@@ -9,7 +9,6 @@ use std::process::ExitStatus;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{mpsc, Arc};
use std::thread;
-#[cfg(unix)]
use std::time::Duration;
use talpid_ipc;
@@ -32,7 +31,7 @@ mod errors {
pub use self::errors::*;
-static OPENVPN_DIE_TIMEOUT: Duration = Duration::from_secs(2);
+static OPENVPN_DIE_TIMEOUT: Duration = Duration::from_secs(4);
/// Struct for monitoring an OpenVPN process.
#[derive(Debug)]