chore: sync konduit-platform v0.1.0-beta.3
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
use super::DnsState;
|
||||
use anyhow::Result;
|
||||
use std::net::IpAddr;
|
||||
use std::os::windows::process::CommandExt;
|
||||
use tracing::info;
|
||||
|
||||
const CREATE_NO_WINDOW: u32 = 0x0800_0000;
|
||||
|
||||
pub async fn set_dns(
|
||||
interface: &str,
|
||||
@@ -8,92 +12,57 @@ pub async fn set_dns(
|
||||
dns_servers: &[IpAddr],
|
||||
state: &mut DnsState,
|
||||
) -> Result<()> {
|
||||
// Windows implementation using windows-rs crate
|
||||
// Note: This logic runs within unsafe blocks as it calls Win32 APIs
|
||||
if dns_servers.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
use std::ffi::c_void;
|
||||
use windows::Win32::Foundation::NO_ERROR;
|
||||
use windows::Win32::NetworkManagement::IpHelper::{
|
||||
SetInterfaceDnsSettings, DNS_INTERFACE_SETTINGS, DNS_INTERFACE_SETTINGS_FLAGS,
|
||||
DNS_INTERFACE_SETTINGS_VERSION1, DNS_SETTING_NAMESERVER,
|
||||
let addrs: Vec<String> = dns_servers.iter().map(|ip| ip.to_string()).collect();
|
||||
let addrs_str = addrs.join(",");
|
||||
|
||||
let iface_arg = if let Some(idx) = if_index {
|
||||
format!("-InterfaceIndex {}", idx)
|
||||
} else {
|
||||
format!("-InterfaceAlias '{}'", interface)
|
||||
};
|
||||
|
||||
// We need the Interface LUID (Locally Unique Identifier) or Index/GUID.
|
||||
// The user provided `interface` string might be a GUID or friendly name.
|
||||
// If if_index is provided, that's easier for some APIs.
|
||||
info!("Setting DNS on {} to {}", interface, addrs_str);
|
||||
|
||||
// Convert IP addresses to wide string (UTF-16) comma-separated
|
||||
let mut dns_str = String::new();
|
||||
for (i, ip) in dns_servers.iter().enumerate() {
|
||||
if i > 0 {
|
||||
dns_str.push(',');
|
||||
}
|
||||
dns_str.push_str(&ip.to_string());
|
||||
}
|
||||
let dns_wide: Vec<u16> = dns_str.encode_utf16().chain(std::iter::once(0)).collect();
|
||||
|
||||
if let Some(idx) = if_index {
|
||||
// Find existing settings to backup?
|
||||
// Windows doesn't make it easy to "get current and restore later" without some work.
|
||||
// For simplicity, we assume we can just clear settings on restore.
|
||||
}
|
||||
|
||||
/*
|
||||
Implementation note:
|
||||
Since we cannot easily compile this on Linux to verify, we outline the logic.
|
||||
Real implementation would need `GetInterfaceDnsSettings` to backup state.
|
||||
*/
|
||||
|
||||
tracing::info!(
|
||||
"Setting DNS on Windows for interface {}: {:?}",
|
||||
interface,
|
||||
dns_servers
|
||||
let script = format!(
|
||||
"Set-DnsClientServerAddress {} -ServerAddresses {}",
|
||||
iface_arg, addrs_str
|
||||
);
|
||||
let status = std::process::Command::new("powershell")
|
||||
.args(["-NoProfile", "-NonInteractive", "-Command", &script])
|
||||
.creation_flags(CREATE_NO_WINDOW)
|
||||
.status()?;
|
||||
|
||||
/*
|
||||
unsafe {
|
||||
let mut settings = DNS_INTERFACE_SETTINGS {
|
||||
Version: DNS_INTERFACE_SETTINGS_VERSION1,
|
||||
Flags: DNS_SETTING_NAMESERVER,
|
||||
NameServer: windows::core::PCWSTR(dns_wide.as_ptr()),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let guid = windows::core::GUID::from(interface)?; // Assuming interface is a GUID string
|
||||
|
||||
let result = SetInterfaceDnsSettings(guid, &mut settings);
|
||||
if result != NO_ERROR {
|
||||
anyhow::bail!("Failed to set DNS: {:?}", result);
|
||||
}
|
||||
if !status.success() {
|
||||
anyhow::bail!("PowerShell failed to set DNS on {}", interface);
|
||||
}
|
||||
*/
|
||||
|
||||
// For now, since we can't test, we log a limitation
|
||||
tracing::warn!("Windows DNS setting logic placeholder");
|
||||
|
||||
state.configured = true;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn restore(
|
||||
_interface: &str,
|
||||
_if_index: Option<u32>,
|
||||
_state: &mut DnsState,
|
||||
interface: &str,
|
||||
if_index: Option<u32>,
|
||||
state: &mut DnsState,
|
||||
) -> Result<()> {
|
||||
tracing::info!("Restoring DNS on Windows...");
|
||||
info!("Restoring DNS on {} to automatic", interface);
|
||||
|
||||
// Clear custom DNS settings (return to DHCP?)
|
||||
/*
|
||||
unsafe {
|
||||
let mut settings = DNS_INTERFACE_SETTINGS {
|
||||
Version: DNS_INTERFACE_SETTINGS_VERSION1,
|
||||
Flags: DNS_SETTING_NAMESERVER,
|
||||
NameServer: windows::core::PCWSTR::null(),
|
||||
..Default::default()
|
||||
};
|
||||
// Call SetInterfaceDnsSettings with empty NameServer or appropriate flags
|
||||
}
|
||||
*/
|
||||
let iface_arg = if let Some(idx) = if_index {
|
||||
format!("-InterfaceIndex {}", idx)
|
||||
} else {
|
||||
format!("-InterfaceAlias '{}'", interface)
|
||||
};
|
||||
|
||||
let script = format!("Set-DnsClientServerAddress {} -ResetServerAddresses", iface_arg);
|
||||
let _ = std::process::Command::new("powershell")
|
||||
.args(["-NoProfile", "-NonInteractive", "-Command", &script])
|
||||
.creation_flags(CREATE_NO_WINDOW)
|
||||
.status();
|
||||
|
||||
state.configured = false;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user