chore: sync konduit-platform v0.1.0-beta.3

This commit is contained in:
E. Kaparulin
2026-06-19 10:41:56 +03:00
parent b1afe43ef0
commit 9eb9b39f77
5 changed files with 503 additions and 99 deletions

View File

@@ -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(())
}