feat(client): add scoped default-route suppression
The Windows route helper now supports a scoped DisableDefaultRoutes override for an IP interface family. The guard snapshots the existing interface row, sets the requested default-route disabled state, and restores the previous state when dropped. This is the route-crate half of neutralizing TAP default-route takeover from PLAN.md. It intentionally does not wire the client yet, so the public API can be reviewed independently from the client startup behavior. The implementation keeps metric restoration and default-route restoration separate even though both read the same IP interface row. That avoids one guard accidentally reverting the other guard's setting when the Windows client holds both at the same time. Test Plan: - cargo fmt --check - cargo test -p lanparty-client-route - cargo clippy -p lanparty-client-route --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:
@@ -78,6 +78,24 @@ pub fn set_scoped_interface_metric(
|
||||
})
|
||||
}
|
||||
|
||||
pub fn set_scoped_default_routes_disabled(
|
||||
identity: NetworkInterfaceIdentity,
|
||||
family: IpInterfaceFamily,
|
||||
disabled: bool,
|
||||
) -> Result<ScopedDefaultRoutes> {
|
||||
let previous = interface_metric(identity, family)?;
|
||||
let mut row = get_interface_row(identity, family)?;
|
||||
row.DisableDefaultRoutes = disabled;
|
||||
set_interface_row(&mut row).with_context(|| {
|
||||
format!("failed to set {family:?} default-route disabled state to {disabled}")
|
||||
})?;
|
||||
|
||||
Ok(ScopedDefaultRoutes {
|
||||
previous,
|
||||
active: true,
|
||||
})
|
||||
}
|
||||
|
||||
pub struct ScopedInterfaceMetric {
|
||||
previous: InterfaceMetricSnapshot,
|
||||
active: bool,
|
||||
@@ -109,6 +127,37 @@ impl Drop for ScopedInterfaceMetric {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ScopedDefaultRoutes {
|
||||
previous: InterfaceMetricSnapshot,
|
||||
active: bool,
|
||||
}
|
||||
|
||||
impl ScopedDefaultRoutes {
|
||||
#[must_use]
|
||||
pub const fn previous(&self) -> InterfaceMetricSnapshot {
|
||||
self.previous
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for ScopedDefaultRoutes {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("ScopedDefaultRoutes")
|
||||
.field("previous", &self.previous)
|
||||
.field("active", &self.active)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for ScopedDefaultRoutes {
|
||||
fn drop(&mut self) {
|
||||
if !self.active {
|
||||
return;
|
||||
}
|
||||
|
||||
let _ = restore_default_routes(self.previous);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn best_route_to(destination: IpAddr) -> Result<RouteSnapshot> {
|
||||
let destination_sockaddr = sockaddr_from_ip(destination);
|
||||
let mut route = MIB_IPFORWARD_ROW2::default();
|
||||
@@ -183,6 +232,12 @@ fn restore_interface_metric(snapshot: InterfaceMetricSnapshot) -> Result<()> {
|
||||
set_interface_row(&mut row)
|
||||
}
|
||||
|
||||
fn restore_default_routes(snapshot: InterfaceMetricSnapshot) -> Result<()> {
|
||||
let mut row = get_interface_row(snapshot.identity(), snapshot.family())?;
|
||||
row.DisableDefaultRoutes = snapshot.disable_default_routes();
|
||||
set_interface_row(&mut row)
|
||||
}
|
||||
|
||||
fn interface_row_key(
|
||||
identity: NetworkInterfaceIdentity,
|
||||
family: IpInterfaceFamily,
|
||||
|
||||
Reference in New Issue
Block a user