Skip to content

Commit 7bf70e3

Browse files
committed
Cleanup Windows code
1 parent db287c9 commit 7bf70e3

File tree

3 files changed

+115
-174
lines changed

3 files changed

+115
-174
lines changed

src-tauri/src/commands.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ use crate::{
4545
};
4646

4747
#[derive(Clone, Serialize)]
48-
pub struct Payload {
48+
pub(crate) struct Payload {
4949
pub message: String,
5050
}
5151

src-tauri/src/log_watcher/service_log_watcher.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,10 @@ pub async fn spawn_log_watcher_task(
230230
"Location"
231231
};
232232
let event_topic = format!("log-update-{connection_type_str}-{location_id}");
233-
debug!("Using the following event topic for the service log watcher for communicating with the frontend: {event_topic}");
233+
debug!(
234+
"Using the following event topic for the service log watcher for communicating with the \
235+
frontend: {event_topic}"
236+
);
234237

235238
// explicitly clone before topic is moved into the closure
236239
let topic_clone = event_topic.clone();
@@ -273,8 +276,11 @@ pub async fn spawn_log_watcher_task(
273276
}
274277

275278
let name = get_tunnel_or_location_name(location_id, connection_type, &app_state).await;
276-
info!("A background task has been spawned to watch the defguard service log file for {connection_type} {name} (interface {interface_name}), \
277-
location's specific collected logs will be displayed in the {connection_type}'s detailed view.");
279+
info!(
280+
"A background task has been spawned to watch the defguard service log file for \
281+
{connection_type} {name} (interface {interface_name}), location's specific collected logs \
282+
will be displayed in the {connection_type}'s detailed view."
283+
);
278284
Ok(event_topic)
279285
}
280286

src-tauri/src/utils.rs

Lines changed: 105 additions & 170 deletions
Original file line numberDiff line numberDiff line change
@@ -829,6 +829,99 @@ pub async fn get_tunnel_or_location_name(
829829
}
830830
}
831831

832+
// Check if location/tunnel is connected and WireGuard Windows service is running.
833+
// `id`: location or tunnel Id
834+
// `name`: location or tunnel name
835+
#[cfg(target_os = "windows")]
836+
async fn check_connection(
837+
service_manager: &ServiceManager,
838+
id: Id,
839+
name: &str,
840+
connection_type: ConnectionType,
841+
app_handle: AppHandle,
842+
) -> Result<(), Error> {
843+
let appstate = app_handle.state::<AppState>();
844+
let interface_name = get_interface_name(name);
845+
let service_name = format!("WireGuardTunnel${}", name);
846+
let service = match service_manager.open_service(&service_name, ServiceAccess::QUERY_CONFIG) {
847+
Ok(service) => service,
848+
Err(windows_service::Error::Winapi(err))
849+
if err.raw_os_error() == Some(ERROR_SERVICE_DOES_NOT_EXIST as i32) =>
850+
{
851+
debug!("WireGuard tunnel {interface_name} is not installed, nothing to synchronize");
852+
return Ok(());
853+
}
854+
Err(err) => {
855+
warn!(
856+
"Failed to open service {service_name} for interface {interface_name} while \
857+
synchronizing active connections. This may cause the {connection_type} {name} \
858+
state to display incorrectly in the client. Reconnect to it manually to fix it. \
859+
Error: {err}"
860+
);
861+
return Ok(());
862+
}
863+
};
864+
match service.query_status() {
865+
Ok(status) => {
866+
// Only point where we don't return and continue with the rest of the code below.
867+
if status.current_state == ServiceState::Running {
868+
debug!("WireGuard tunnel {interface_name} is running.");
869+
} else {
870+
debug!(
871+
"WireGuard tunnel {interface_name} is not running, status code: {:?}. Refer to \
872+
Windows documentation for more information about the code.",
873+
status.current_state
874+
);
875+
return Ok(());
876+
}
877+
}
878+
Err(err) => {
879+
warn!(
880+
"Failed to query service status for interface {interface_name} while synchronizing \
881+
active connections. This may cause the {connection_type} {name} state to display \
882+
incorrectly in the client. Reconnect to it manually to fix it. Error: {err}",
883+
);
884+
return Ok(());
885+
}
886+
}
887+
888+
if appstate
889+
.find_connection(id, connection_type)
890+
.await
891+
.is_some()
892+
{
893+
debug!("{connection_type} {name} has already a connected state, skipping synchronization");
894+
return Ok(());
895+
}
896+
897+
appstate
898+
.add_connection(id, &interface_name, connection_type)
899+
.await;
900+
901+
debug!("Sending event informing the frontend that a new connection has been created.");
902+
app_handle.emit_all(
903+
CONNECTION_CHANGED,
904+
Payload {
905+
message: "Created new connection".into(),
906+
},
907+
)?;
908+
debug!("Event informing the frontend that a new connection has been created sent.");
909+
910+
debug!("Spawning service log watcher for {connection_type} {name}...");
911+
spawn_log_watcher_task(
912+
app_handle.clone(),
913+
id,
914+
interface_name,
915+
connection_type,
916+
Level::DEBUG,
917+
None,
918+
)
919+
.await?;
920+
debug!("Service log watcher for {connection_type} {name} spawned.");
921+
922+
Ok(())
923+
}
924+
832925
// TODO: Move the connection handling to a seperate, common function,
833926
// so `handle_connection_for_location` and `handle_connection_for_tunnel` are not
834927
// partially duplicated here.
@@ -837,7 +930,7 @@ pub async fn sync_connections(app_handle: &AppHandle) -> Result<(), Error> {
837930
debug!("Synchronizing active connections with the systems' state...");
838931
let appstate = app_handle.state::<AppState>();
839932
let all_locations = Location::all(&appstate.db).await?;
840-
let service_control_manager =
933+
let service_manager =
841934
ServiceManager::local_computer(None::<&str>, ServiceManagerAccess::CONNECT).map_err(
842935
|err| {
843936
error!(
@@ -852,190 +945,32 @@ pub async fn sync_connections(app_handle: &AppHandle) -> Result<(), Error> {
852945
},
853946
)?;
854947

855-
debug!("Opened service control manager, starting to synchronize active connections for locations...");
856-
// Go through all locations and check if they are connected (if the windows service is running)
948+
debug!("Opened service control manager. Synchronizing active connections for locations...");
949+
// Go through all locations and check if they are connected and Windows service is running.
857950
// If we encounter any errors, continue with the next iteration of the loop, it's not a big deal
858-
// if we skip some locations, as the user can always reconnect to them manually
951+
// if we skip some locations, as the user can always reconnect to them manually.
859952
for location in all_locations {
860-
let interface_name = get_interface_name(&location.name);
861-
let service_name = format!("WireGuardTunnel${}", location.name);
862-
let service = match service_control_manager
863-
.open_service(&service_name, ServiceAccess::QUERY_CONFIG)
864-
{
865-
Ok(service) => service,
866-
Err(windows_service::Error::Winapi(err))
867-
if err.raw_os_error() == Some(ERROR_SERVICE_DOES_NOT_EXIST as i32) =>
868-
{
869-
debug!(
870-
"WireGuard tunnel {} is not installed, nothing to synchronize",
871-
interface_name
872-
);
873-
continue;
874-
}
875-
Err(err) => {
876-
warn!(
877-
"Failed to open service {service_name} for interface {interface_name} while \
878-
synchronizing active connections. This may cause the location {} state to \
879-
display incorrectly in the client. Reconnect to it manually to fix it. \
880-
Error: {err}",
881-
location.name
882-
);
883-
continue;
884-
}
885-
};
886-
match service.query_status() {
887-
Ok(status) => {
888-
// Only point where we don't jump to the next iteration of the loop and continue with the rest of the code below the match
889-
if status.current_state == ServiceState::Running {
890-
debug!("WireGuard tunnel {} is running, ", interface_name);
891-
} else {
892-
debug!(
893-
"WireGuard tunnel {} is not running, status code: {:?}. Refer to \
894-
Windows documentation for more information about the code.",
895-
interface_name, status.current_state
896-
);
897-
continue;
898-
}
899-
}
900-
Err(err) => {
901-
warn!(
902-
"Failed to query service status for interface {} while synchronizing active \
903-
connections. This may cause the location {} state to display incorrectly in \
904-
the client. Reconnect to it manually to fix it. Error: {err}",
905-
interface_name, location.name
906-
);
907-
continue;
908-
}
909-
}
910-
911-
if appstate
912-
.find_connection(location.id, ConnectionType::Location)
913-
.await
914-
.is_some()
915-
{
916-
debug!(
917-
"Location {} has already a connected state, skipping synchronization",
918-
location.name
919-
);
920-
continue;
921-
}
922-
923-
appstate
924-
.add_connection(location.id, &interface_name, ConnectionType::Location)
925-
.await;
926-
927-
debug!("Sending event informing the frontend that a new connection has been created.");
928-
app_handle.emit_all(
929-
CONNECTION_CHANGED,
930-
Payload {
931-
message: "Created new connection".into(),
932-
},
933-
)?;
934-
debug!("Event informing the frontend that a new connection has been created sent.");
935-
936-
debug!("Spawning service log watcher for location {}...", location);
937-
spawn_log_watcher_task(
938-
app_handle.clone(),
953+
check_connection(
954+
&service_manager,
939955
location.id,
940-
interface_name,
956+
&location.name,
941957
ConnectionType::Location,
942-
Level::DEBUG,
943-
None,
958+
app_handle.clone(),
944959
)
945960
.await?;
946-
debug!("Service log watcher for location {} spawned.", location);
947961
}
948962

949963
debug!("Synchronizing active connections for tunnels...");
950964
// Do the same for tunnels
951965
for tunnel in Tunnel::all(&appstate.db).await? {
952-
let interface_name = get_interface_name(&tunnel.name);
953-
let service_name = format!("WireGuardTunnel${}", interface_name);
954-
let service = match service_control_manager
955-
.open_service(&service_name, ServiceAccess::QUERY_CONFIG)
956-
{
957-
Ok(service) => service,
958-
Err(windows_service::Error::Winapi(err))
959-
if err.raw_os_error() == Some(ERROR_SERVICE_DOES_NOT_EXIST as i32) =>
960-
{
961-
debug!(
962-
"WireGuard tunnel {} is not installed, nothing to synchronize",
963-
interface_name
964-
);
965-
continue;
966-
}
967-
Err(err) => {
968-
error!(
969-
"Failed to open service {service_name} for interface {interface_name}. \
970-
This may cause the tunnel {} state to display incorrectly in the \
971-
client. Reconnect to it manually to fix it. Error: {err}",
972-
tunnel.name
973-
);
974-
continue;
975-
}
976-
};
977-
match service.query_status() {
978-
Ok(status) => {
979-
// Only point where we don't jump to the next iteration of the loop and continue with the rest of the code below the match
980-
if status.current_state == ServiceState::Running {
981-
debug!("WireGuard tunnel {} is running", interface_name);
982-
} else {
983-
debug!(
984-
"WireGuard tunnel {} is not running, status code: {:?}. Refer to Windows \
985-
documentation for more information about the code.",
986-
interface_name, status.current_state
987-
);
988-
continue;
989-
}
990-
}
991-
Err(err) => {
992-
warn!(
993-
"Failed to query service status for interface {}. \
994-
This may cause the tunnel {} state to display incorrectly in the client. \
995-
Reconnect to it manually to fix it. Error: {err}",
996-
interface_name, tunnel.name
997-
);
998-
continue;
999-
}
1000-
}
1001-
1002-
if appstate
1003-
.find_connection(tunnel.id, ConnectionType::Tunnel)
1004-
.await
1005-
.is_some()
1006-
{
1007-
debug!(
1008-
"Tunnel {} has already a connected state, skipping synchronization",
1009-
tunnel.name
1010-
);
1011-
continue;
1012-
}
1013-
1014-
appstate
1015-
.add_connection(tunnel.id, &interface_name, ConnectionType::Tunnel)
1016-
.await;
1017-
1018-
debug!("Sending event informing the frontend that a new connection has been created.");
1019-
app_handle.emit_all(
1020-
CONNECTION_CHANGED,
1021-
Payload {
1022-
message: "Created new connection".into(),
1023-
},
1024-
)?;
1025-
debug!("Event informing the frontend that a new connection has been created sent.");
1026-
1027-
//spawn log watcher
1028-
debug!("Spawning log watcher for tunnel {}", tunnel.name);
1029-
spawn_log_watcher_task(
1030-
app_handle.clone(),
966+
check_connection(
967+
&service_manager,
1031968
tunnel.id,
1032-
interface_name,
969+
&tunnel.name,
1033970
ConnectionType::Tunnel,
1034-
Level::DEBUG,
1035-
None,
971+
app_handle.clone(),
1036972
)
1037973
.await?;
1038-
debug!("Log watcher for tunnel {} spawned", tunnel.name);
1039974
}
1040975

1041976
debug!("Active connections synchronized with the system state");

0 commit comments

Comments
 (0)