Skip to content

Commit

Permalink
Split network layer
Browse files Browse the repository at this point in the history
  • Loading branch information
keesverruijt committed Feb 1, 2025
1 parent 73f1c81 commit 1351c23
Show file tree
Hide file tree
Showing 5 changed files with 249 additions and 10 deletions.
138 changes: 133 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ system-configuration = "0.6.1"
netlink-sys = { version = "0.8.4", features = ["tokio", "tokio_socket"] }
rtnetlink = "0.14.1"

[target.'cfg(target_os = "windows")'.dependencies]
windows = { version = "0.59.0", features = ["Win32_NetworkManagement_IpHelper", "Win32_NetworkManagement_WiFi", "Win32_Networking_WinSock", "Win32_System", "Win32_System_Threading", "Win32_Security", "Win32_System_Diagnostics", "Win32_System_Diagnostics_Debug", "Win32_System_IO"] }

[build-dependencies]
protobuf-codegen = "3.5.1"
openssl = { version = "0.10", features = ["vendored"] }
Expand Down
3 changes: 3 additions & 0 deletions src/network/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@
pub(crate) mod linux;
#[cfg(target_os = "macos")]
pub(crate) mod macos;

#[cfg(target_os = "windows")]
pub(crate) mod windows;
59 changes: 59 additions & 0 deletions src/network/windows/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
use std::ptr::null_mut;
use tokio::sync::watch;
use tokio_util::sync::CancellationToken;
use windows::Win32::Foundation::CloseHandle;
use windows::Win32::NetworkManagement::IpHelper::NotifyAddrChange;
use windows::Win32::System::Threading::{CreateEventW, WaitForSingleObject, INFINITE};
use windows::Win32::System::IO::OVERLAPPED;

use crate::radar::RadarError;

pub async fn wait_for_ip_addr_change(cancel_token: CancellationToken) -> Result<(), RadarError> {
let (tx, mut rx) = watch::channel(false);

let handle = unsafe {
// Create a manual-reset event
let event = CreateEventW(None, true, false, None)
.map_err(|_| RadarError::Io(std::io::Error::last_os_error()))?;
if event.is_invalid() {
return Err(RadarError::Io(std::io::Error::last_os_error()));
}

// Prepare an OVERLAPPED structure with the event handle
let mut overlapped = OVERLAPPED {
hEvent: event,
..Default::default()
};

// Register for address change notifications
let notify_result = NotifyAddrChange(null_mut(), &mut overlapped);
if notify_result != 0 {
CloseHandle(event);
return Err(RadarError::Io(std::io::Error::last_os_error()));
}

// Spawn a blocking task to wait for the event
let handle = tokio::task::spawn_blocking(move || {
let result = WaitForSingleObject(event, INFINITE);
let _ = tx.send(result.0 == 0);
CloseHandle(event);
});
handle
};

// Wait asynchronously for a change or cancellation
tokio::select! {
_ = cancel_token.cancelled() => {
// Cancel the operation
handle.abort();
return Err(RadarError::Shutdown);
}
change_result = rx.changed() => {
if change_result.is_ok() && *rx.borrow() {
return Ok(());
} else {
return Err(RadarError::EnumerationFailed);
}
}
}
}
Loading

0 comments on commit 1351c23

Please sign in to comment.