summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock32
-rw-r--r--mullvad-daemon/Cargo.toml2
-rw-r--r--mullvad-daemon/src/system_service.rs63
3 files changed, 81 insertions, 16 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 1caa605063..79ed38fae9 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1186,7 +1186,7 @@ dependencies = [
"tokio-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "windows-service 0.1.0 (git+https://github.com/mullvad/windows-service-rs.git?rev=aab5b26beae364253802b6e5554c9ecdc6285454)",
+ "windows-service 0.2.0 (git+https://github.com/mullvad/windows-service-rs.git?rev=a5eb1dcbbcee4ec2c6479256305c64b25640c799)",
"winres 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2809,6 +2809,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi"
version = "0.3.7"
+source = "git+https://github.com/mullvad/winapi-rs.git?rev=4bcf5cab87124bbeef8c1a445137494d874f8082#4bcf5cab87124bbeef8c1a445137494d874f8082"
+dependencies = [
+ "winapi-i686-pc-windows-gnu 0.4.0 (git+https://github.com/mullvad/winapi-rs.git?rev=4bcf5cab87124bbeef8c1a445137494d874f8082)",
+ "winapi-x86_64-pc-windows-gnu 0.4.0 (git+https://github.com/mullvad/winapi-rs.git?rev=4bcf5cab87124bbeef8c1a445137494d874f8082)",
+]
+
+[[package]]
+name = "winapi"
+version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2823,6 +2832,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
+source = "git+https://github.com/mullvad/winapi-rs.git?rev=4bcf5cab87124bbeef8c1a445137494d874f8082#4bcf5cab87124bbeef8c1a445137494d874f8082"
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -2836,6 +2850,11 @@ dependencies = [
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
+source = "git+https://github.com/mullvad/winapi-rs.git?rev=4bcf5cab87124bbeef8c1a445137494d874f8082#4bcf5cab87124bbeef8c1a445137494d874f8082"
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -2860,13 +2879,13 @@ dependencies = [
[[package]]
name = "windows-service"
-version = "0.1.0"
-source = "git+https://github.com/mullvad/windows-service-rs.git?rev=aab5b26beae364253802b6e5554c9ecdc6285454#aab5b26beae364253802b6e5554c9ecdc6285454"
+version = "0.2.0"
+source = "git+https://github.com/mullvad/windows-service-rs.git?rev=a5eb1dcbbcee4ec2c6479256305c64b25640c799#a5eb1dcbbcee4ec2c6479256305c64b25640c799"
dependencies = [
"bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"err-derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"widestring 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.7 (git+https://github.com/mullvad/winapi-rs.git?rev=4bcf5cab87124bbeef8c1a445137494d874f8082)",
]
[[package]]
@@ -3185,14 +3204,17 @@ dependencies = [
"checksum widestring 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a212922ea58fbf5044f83663aa4fc6281ff890f1fd7546c0c3f52f5290831781"
"checksum widestring 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "effc0e4ff8085673ea7b9b2e3c73f6bd4d118810c9009ed8f1e16bd96c331db6"
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
+"checksum winapi 0.3.7 (git+https://github.com/mullvad/winapi-rs.git?rev=4bcf5cab87124bbeef8c1a445137494d874f8082)" = "<none>"
"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770"
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
+"checksum winapi-i686-pc-windows-gnu 0.4.0 (git+https://github.com/mullvad/winapi-rs.git?rev=4bcf5cab87124bbeef8c1a445137494d874f8082)" = "<none>"
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
"checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9"
+"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (git+https://github.com/mullvad/winapi-rs.git?rev=4bcf5cab87124bbeef8c1a445137494d874f8082)" = "<none>"
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
"checksum wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "561ed901ae465d6185fa7864d63fbd5720d0ef718366c9a4dc83cf6170d7e9ba"
"checksum winconsole 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ef84b96d10db72dd980056666d7f1e7663ce93d82fa33b63e71c966f4cf5032"
-"checksum windows-service 0.1.0 (git+https://github.com/mullvad/windows-service-rs.git?rev=aab5b26beae364253802b6e5554c9ecdc6285454)" = "<none>"
+"checksum windows-service 0.2.0 (git+https://github.com/mullvad/windows-service-rs.git?rev=a5eb1dcbbcee4ec2c6479256305c64b25640c799)" = "<none>"
"checksum winreg 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "daf67b95d0b1bf421c4f11048d63110ca3719977169eec86396b614c8942b6e0"
"checksum winres 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "ff4fb510bbfe5b8992ff15f77a2e6fe6cf062878f0eda00c0f44963a807ca5dc"
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
diff --git a/mullvad-daemon/Cargo.toml b/mullvad-daemon/Cargo.toml
index bbd1de43b2..511e52b060 100644
--- a/mullvad-daemon/Cargo.toml
+++ b/mullvad-daemon/Cargo.toml
@@ -52,7 +52,7 @@ simple-signal = "1.1"
[target.'cfg(windows)'.dependencies]
ctrlc = "3.0"
-windows-service = { git = "https://github.com/mullvad/windows-service-rs.git", rev = "aab5b26beae364253802b6e5554c9ecdc6285454" }
+windows-service = { git = "https://github.com/mullvad/windows-service-rs.git", rev = "a5eb1dcbbcee4ec2c6479256305c64b25640c799" }
winapi = "0.3"
[target.'cfg(windows)'.build-dependencies]
diff --git a/mullvad-daemon/src/system_service.rs b/mullvad-daemon/src/system_service.rs
index 62c997022a..c7007ae666 100644
--- a/mullvad-daemon/src/system_service.rs
+++ b/mullvad-daemon/src/system_service.rs
@@ -4,7 +4,7 @@ use std::{
env,
ffi::OsString,
sync::{
- atomic::{AtomicUsize, Ordering},
+ atomic::{AtomicBool, AtomicUsize, Ordering},
mpsc, Arc,
},
thread,
@@ -13,9 +13,10 @@ use std::{
use talpid_types::ErrorExt;
use windows_service::{
service::{
- ServiceAccess, ServiceControl, ServiceControlAccept, ServiceDependency,
- ServiceErrorControl, ServiceExitCode, ServiceInfo, ServiceStartType, ServiceState,
- ServiceStatus, ServiceType,
+ ServiceAccess, ServiceAction, ServiceActionType, ServiceControl, ServiceControlAccept,
+ ServiceDependency, ServiceErrorControl, ServiceExitCode, ServiceFailureActions,
+ ServiceFailureResetPeriod, ServiceInfo, ServiceStartType, ServiceState, ServiceStatus,
+ ServiceType,
},
service_control_handler::{self, ServiceControlHandlerResult, ServiceStatusHandle},
service_dispatcher,
@@ -69,26 +70,42 @@ fn run_service() -> Result<(), String> {
.set_pending_start(Duration::from_secs(1))
.unwrap();
+ let clean_shutdown = Arc::new(AtomicBool::new(false));
+
let log_dir = crate::get_log_dir(cli::get_config()).expect("Log dir should be available here");
let result = crate::create_daemon(log_dir).and_then(|daemon| {
let shutdown_handle = daemon.shutdown_handle();
// Register monitor that translates `ServiceControl` to Daemon events
- start_event_monitor(persistent_service_status.clone(), shutdown_handle, event_rx);
+ start_event_monitor(
+ persistent_service_status.clone(),
+ shutdown_handle,
+ event_rx,
+ clean_shutdown.clone(),
+ );
persistent_service_status.set_running().unwrap();
daemon.run().map_err(|e| e.display_chain())
});
+
let exit_code = match result {
- Ok(()) => ServiceExitCode::default(),
+ Ok(()) => {
+ // check if shutdown signal was sent from the system
+ if clean_shutdown.load(Ordering::Acquire) {
+ ServiceExitCode::default()
+ } else {
+ // otherwise return a non-zero code so that the daemon gets restarted
+ ServiceExitCode::ServiceSpecific(1)
+ }
+ }
Err(_) => ServiceExitCode::ServiceSpecific(1),
};
persistent_service_status.set_stopped(exit_code).unwrap();
- result
+ result.map(|_| ())
}
/// Start event monitor thread that polls for `ServiceControl` and translates them into calls to
@@ -97,6 +114,7 @@ fn start_event_monitor(
mut persistent_service_status: PersistentServiceStatus,
shutdown_handle: DaemonShutdownHandle,
event_rx: mpsc::Receiver<ServiceControl>,
+ clean_shutdown: Arc<AtomicBool>,
) -> thread::JoinHandle<()> {
thread::spawn(move || {
for event in event_rx {
@@ -106,6 +124,7 @@ fn start_event_monitor(
.set_pending_stop(Duration::from_secs(10))
.unwrap();
+ clean_shutdown.store(true, Ordering::Release);
shutdown_handle.shutdown();
}
_ => (),
@@ -227,9 +246,33 @@ pub fn install_service() -> Result<(), InstallError> {
let manager_access = ServiceManagerAccess::CONNECT | ServiceManagerAccess::CREATE_SERVICE;
let service_manager = ServiceManager::local_computer(None::<&str>, manager_access)
.map_err(InstallError::ConnectServiceManager)?;
- service_manager
- .create_service(get_service_info(), ServiceAccess::empty())
- .map(|_| ())
+ let service_access = ServiceAccess::QUERY_CONFIG
+ | ServiceAccess::CHANGE_CONFIG
+ | ServiceAccess::START
+ | ServiceAccess::DELETE;
+
+ let service = service_manager
+ .create_service(get_service_info(), service_access)
+ .or(service_manager.open_service(SERVICE_NAME, service_access))
+ .map_err(InstallError::CreateService)?;
+
+ let recovery_actions = vec![ServiceAction {
+ action_type: ServiceActionType::Restart,
+ delay: Duration::from_secs(3),
+ }];
+
+ let failure_actions = ServiceFailureActions {
+ reset_period: ServiceFailureResetPeriod::After(Duration::from_secs(2)),
+ reboot_msg: None,
+ command: None,
+ actions: Some(recovery_actions),
+ };
+
+ service
+ .update_failure_actions(failure_actions)
+ .map_err(InstallError::CreateService)?;
+ service
+ .set_failure_actions_on_non_crash_failures(true)
.map_err(InstallError::CreateService)
}