feat(client): resolve Windows interface identity by GUID
Add a small route-crate API that resolves a Windows network adapter GUID into its interface LUID and index. The TAP adapter discovery already gives us the NetCfgInstanceId GUID, and the route/metric work needs the corresponding IP interface identity before it can safely inspect or adjust TAP metrics. The implementation keeps GUID parsing local and dependency-free, then delegates the actual identity lookup to Windows IP Helper calls. Non-Windows builds expose the same API shape with a clear unsupported-platform error. Test Plan: - cargo fmt --check - cargo test --workspace - cargo clippy --workspace --all-targets -- -D warnings - cargo check -p lanparty-client-route --target x86_64-pc-windows-msvc - cargo clippy -p lanparty-client-route --target x86_64-pc-windows-msvc --all-targets -- -D warnings - git diff --check Refs: PLAN.md
This commit is contained in:
@@ -21,6 +21,29 @@ pub struct RouteSnapshot {
|
||||
metric: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct NetworkInterfaceIdentity {
|
||||
index: u32,
|
||||
luid: u64,
|
||||
}
|
||||
|
||||
impl NetworkInterfaceIdentity {
|
||||
#[cfg_attr(not(windows), allow(dead_code))]
|
||||
const fn new(index: u32, luid: u64) -> Self {
|
||||
Self { index, luid }
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn index(self) -> u32 {
|
||||
self.index
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn luid(self) -> u64 {
|
||||
self.luid
|
||||
}
|
||||
}
|
||||
|
||||
impl RouteSnapshot {
|
||||
#[cfg_attr(not(windows), allow(dead_code))]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
@@ -91,7 +114,7 @@ impl RouteSnapshot {
|
||||
mod windows;
|
||||
|
||||
#[cfg(windows)]
|
||||
pub use windows::{PinnedRelayRoute, best_route_to, pin_relay_route};
|
||||
pub use windows::{PinnedRelayRoute, best_route_to, interface_identity_from_guid, pin_relay_route};
|
||||
|
||||
#[cfg(not(windows))]
|
||||
pub fn best_route_to(_destination: IpAddr) -> Result<RouteSnapshot> {
|
||||
@@ -109,6 +132,11 @@ pub fn pin_relay_route(_route: &RouteSnapshot) -> Result<PinnedRelayRoute> {
|
||||
bail!("Windows route pinning is only available on Windows");
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
pub fn interface_identity_from_guid(_interface_guid: &str) -> Result<NetworkInterfaceIdentity> {
|
||||
bail!("Windows interface identity lookup is only available on Windows");
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@@ -136,6 +164,14 @@ mod tests {
|
||||
assert_eq!(snapshot.metric(), 25);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn exposes_network_interface_identity_fields() {
|
||||
let identity = NetworkInterfaceIdentity::new(12, 34);
|
||||
|
||||
assert_eq!(identity.index(), 12);
|
||||
assert_eq!(identity.luid(), 34);
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
#[test]
|
||||
fn rejects_route_inspection_on_non_windows() {
|
||||
@@ -159,6 +195,12 @@ mod tests {
|
||||
assert!(pin_relay_route(&snapshot).is_err());
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
#[test]
|
||||
fn rejects_interface_lookup_on_non_windows() {
|
||||
assert!(interface_identity_from_guid("{00112233-4455-6677-8899-AABBCCDDEEFF}").is_err());
|
||||
}
|
||||
|
||||
fn ip(value: &str) -> IpAddr {
|
||||
value.parse().unwrap()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user