Basic windows is working

Former-commit-id: 2c62f9cc2a
This commit is contained in:
Owen
2025-11-24 14:41:04 -05:00
parent 34c7f89804
commit 16362f285d
6 changed files with 339 additions and 30 deletions

View File

@@ -0,0 +1,66 @@
//go:build darwin && !ios
package olm
import (
"fmt"
"net/netip"
"github.com/fosrl/newt/logger"
"github.com/fosrl/olm/dns"
platform "github.com/fosrl/olm/dns/platform"
)
// SetupDNSOverride configures the system DNS to use the DNS proxy on macOS
// Uses scutil for DNS configuration
func SetupDNSOverride(interfaceName string, dnsProxy *dns.DNSProxy) error {
if dnsProxy == nil {
return fmt.Errorf("DNS proxy is nil")
}
var err error
configurator, err = platform.NewDarwinDNSConfigurator()
if err != nil {
return fmt.Errorf("failed to create Darwin DNS configurator: %w", err)
}
logger.Info("Using Darwin scutil DNS configurator")
// Get current DNS servers before changing
currentDNS, err := configurator.GetCurrentDNS()
if err != nil {
logger.Warn("Could not get current DNS: %v", err)
} else {
logger.Info("Current DNS servers: %v", currentDNS)
}
// Set new DNS servers to point to our proxy
newDNS := []netip.Addr{
dnsProxy.GetProxyIP(),
}
logger.Info("Setting DNS servers to: %v", newDNS)
originalDNS, err := configurator.SetDNS(newDNS)
if err != nil {
return fmt.Errorf("failed to set DNS: %w", err)
}
logger.Info("Original DNS servers backed up: %v", originalDNS)
return nil
}
// RestoreDNSOverride restores the original DNS configuration
func RestoreDNSOverride() error {
if configurator == nil {
logger.Debug("No DNS configurator to restore")
return nil
}
logger.Info("Restoring original DNS configuration")
if err := configurator.RestoreDNS(); err != nil {
return fmt.Errorf("failed to restore DNS: %w", err)
}
logger.Info("DNS configuration restored successfully")
return nil
}

102
olm/dns_override_unix.go Normal file
View File

@@ -0,0 +1,102 @@
//go:build (linux && !android) || freebsd
package olm
import (
"fmt"
"net/netip"
"github.com/fosrl/newt/logger"
"github.com/fosrl/olm/dns"
platform "github.com/fosrl/olm/dns/platform"
)
// SetupDNSOverride configures the system DNS to use the DNS proxy on Linux/FreeBSD
// Tries systemd-resolved, NetworkManager, resolvconf, or falls back to /etc/resolv.conf
func SetupDNSOverride(interfaceName string, dnsProxy *dns.DNSProxy) error {
if dnsProxy == nil {
return fmt.Errorf("DNS proxy is nil")
}
var err error
// Try systemd-resolved first (most modern)
if platform.IsSystemdResolvedAvailable() && interfaceName != "" {
configurator, err = platform.NewSystemdResolvedDNSConfigurator(interfaceName)
if err == nil {
logger.Info("Using systemd-resolved DNS configurator")
return setDNS(dnsProxy, configurator)
}
logger.Debug("systemd-resolved not available: %v", err)
}
// Try NetworkManager (common on desktops)
if platform.IsNetworkManagerAvailable() && interfaceName != "" {
configurator, err = platform.NewNetworkManagerDNSConfigurator(interfaceName)
if err == nil {
logger.Info("Using NetworkManager DNS configurator")
return setDNS(dnsProxy, configurator)
}
logger.Debug("NetworkManager not available: %v", err)
}
// Try resolvconf (common on older systems)
if platform.IsResolvconfAvailable() && interfaceName != "" {
configurator, err = platform.NewResolvconfDNSConfigurator(interfaceName)
if err == nil {
logger.Info("Using resolvconf DNS configurator")
return setDNS(dnsProxy, configurator)
}
logger.Debug("resolvconf not available: %v", err)
}
// Fall back to direct file manipulation
configurator, err = platform.NewFileDNSConfigurator()
if err != nil {
return fmt.Errorf("failed to create file DNS configurator: %w", err)
}
logger.Info("Using file-based DNS configurator")
return setDNS(dnsProxy, configurator)
}
// setDNS is a helper function to set DNS and log the results
func setDNS(dnsProxy *dns.DNSProxy, conf platform.DNSConfigurator) error {
// Get current DNS servers before changing
currentDNS, err := conf.GetCurrentDNS()
if err != nil {
logger.Warn("Could not get current DNS: %v", err)
} else {
logger.Info("Current DNS servers: %v", currentDNS)
}
// Set new DNS servers to point to our proxy
newDNS := []netip.Addr{
dnsProxy.GetProxyIP(),
}
logger.Info("Setting DNS servers to: %v", newDNS)
originalDNS, err := conf.SetDNS(newDNS)
if err != nil {
return fmt.Errorf("failed to set DNS: %w", err)
}
logger.Info("Original DNS servers backed up: %v", originalDNS)
return nil
}
// RestoreDNSOverride restores the original DNS configuration
func RestoreDNSOverride() error {
if configurator == nil {
logger.Debug("No DNS configurator to restore")
return nil
}
logger.Info("Restoring original DNS configuration")
if err := configurator.RestoreDNS(); err != nil {
return fmt.Errorf("failed to restore DNS: %w", err)
}
logger.Info("DNS configuration restored successfully")
return nil
}

View File

@@ -0,0 +1,78 @@
//go:build windows
package olm
import (
"fmt"
"net/netip"
"github.com/fosrl/newt/logger"
"github.com/fosrl/olm/dns"
platform "github.com/fosrl/olm/dns/platform"
)
// SetupDNSOverride configures the system DNS to use the DNS proxy on Windows
// Uses registry-based configuration (requires interface GUID)
func SetupDNSOverride(interfaceName string, dnsProxy *dns.DNSProxy) error {
if dnsProxy == nil {
return fmt.Errorf("DNS proxy is nil")
}
// On Windows, we need to get the interface GUID from the TUN device
// The interfaceName parameter is ignored on Windows
if tdev == nil {
return fmt.Errorf("TUN device is not available")
}
guid, err := GetInterfaceGUIDString(tdev)
if err != nil {
return fmt.Errorf("failed to get interface GUID: %w", err)
}
logger.Info("Retrieved interface GUID: %s for interface name: %s", guid, interfaceName)
configurator, err = platform.NewWindowsDNSConfigurator(guid)
if err != nil {
return fmt.Errorf("failed to create Windows DNS configurator: %w", err)
}
logger.Info("Using Windows registry DNS configurator for GUID: %s", guid)
// Get current DNS servers before changing
currentDNS, err := configurator.GetCurrentDNS()
if err != nil {
logger.Warn("Could not get current DNS: %v", err)
} else {
logger.Info("Current DNS servers: %v", currentDNS)
}
// Set new DNS servers to point to our proxy
newDNS := []netip.Addr{
dnsProxy.GetProxyIP(),
}
logger.Info("Setting DNS servers to: %v", newDNS)
originalDNS, err := configurator.SetDNS(newDNS)
if err != nil {
return fmt.Errorf("failed to set DNS: %w", err)
}
logger.Info("Original DNS servers backed up: %v", originalDNS)
return nil
}
// RestoreDNSOverride restores the original DNS configuration
func RestoreDNSOverride() error {
if configurator == nil {
logger.Debug("No DNS configurator to restore")
return nil
}
logger.Info("Restoring original DNS configuration")
if err := configurator.RestoreDNS(); err != nil {
return fmt.Errorf("failed to restore DNS: %w", err)
}
logger.Info("DNS configuration restored successfully")
return nil
}

View File

@@ -0,0 +1,15 @@
//go:build !windows
package olm
import (
"fmt"
"golang.zx2c4.com/wireguard/tun"
)
// GetInterfaceGUIDString is only implemented for Windows
// This stub is provided for compilation on other platforms
func GetInterfaceGUIDString(tunDevice tun.Device) (string, error) {
return "", fmt.Errorf("GetInterfaceGUIDString is only supported on Windows")
}

View File

@@ -0,0 +1,69 @@
//go:build windows
package olm
import (
"fmt"
"unsafe"
"golang.org/x/sys/windows"
"golang.zx2c4.com/wireguard/tun"
)
// GetInterfaceGUIDString retrieves the GUID string for a Windows TUN interface
// This is required for registry-based DNS configuration on Windows
func GetInterfaceGUIDString(tunDevice tun.Device) (string, error) {
if tunDevice == nil {
return "", fmt.Errorf("TUN device is nil")
}
// The wireguard-go Windows TUN device has a LUID() method
// We need to use type assertion to access it
type nativeTun interface {
LUID() uint64
}
nativeDev, ok := tunDevice.(nativeTun)
if !ok {
return "", fmt.Errorf("TUN device does not support LUID retrieval (not a native Windows TUN device)")
}
luid := nativeDev.LUID()
// Convert LUID to GUID using Windows API
guid, err := luidToGUID(luid)
if err != nil {
return "", fmt.Errorf("failed to convert LUID to GUID: %w", err)
}
return guid, nil
}
// luidToGUID converts a Windows LUID (Locally Unique Identifier) to a GUID string
// using the Windows ConvertInterface* APIs
func luidToGUID(luid uint64) (string, error) {
var guid windows.GUID
// Load the iphlpapi.dll and get the ConvertInterfaceLuidToGuid function
iphlpapi := windows.NewLazySystemDLL("iphlpapi.dll")
convertLuidToGuid := iphlpapi.NewProc("ConvertInterfaceLuidToGuid")
// Call the Windows API
// NET_LUID is a 64-bit value on Windows
ret, _, err := convertLuidToGuid.Call(
uintptr(unsafe.Pointer(&luid)),
uintptr(unsafe.Pointer(&guid)),
)
if ret != 0 {
return "", fmt.Errorf("ConvertInterfaceLuidToGuid failed with code %d: %w", ret, err)
}
// Format the GUID as a string with curly braces
guidStr := fmt.Sprintf("{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
guid.Data1, guid.Data2, guid.Data3,
guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7])
return guidStr, nil
}

View File

@@ -6,7 +6,6 @@ import (
"fmt"
"log"
"net"
"net/netip"
"runtime"
"strings"
"time"
@@ -577,35 +576,10 @@ func StartTunnel(config TunnelConfig) {
peerMonitor.Start()
configurator, err = platform.DetectBestConfigurator(interfaceName)
if err != nil {
log.Fatalf("Failed to detect DNS configurator: %v", err)
}
fmt.Printf("Using DNS configurator: %s\n", configurator.Name())
// Get current DNS servers before changing
currentDNS, err := configurator.GetCurrentDNS()
if err != nil {
log.Printf("Warning: Could not get current DNS: %v", err)
} else {
fmt.Printf("Current DNS servers: %v\n", currentDNS)
}
// Set new DNS servers
newDNS := []netip.Addr{
dnsProxy.GetProxyIP(),
// netip.MustParseAddr("8.8.8.8"), // Google
}
fmt.Printf("Setting DNS servers to: %v\n", newDNS)
originalDNS, err := configurator.SetDNS(newDNS)
if err != nil {
log.Fatalf("Failed to set DNS: %v", err)
}
for _, addr := range originalDNS {
fmt.Printf("Original DNS server: %v\n", addr)
// Set up DNS override to use our DNS proxy
if err := SetupDNSOverride(interfaceName, dnsProxy); err != nil {
logger.Error("Failed to setup DNS override: %v", err)
return
}
if err := dnsProxy.Start(); err != nil {
@@ -1202,6 +1176,11 @@ func StopTunnel() {
Close()
// Restore original DNS configuration
if err := RestoreDNSOverride(); err != nil {
logger.Error("Failed to restore DNS: %v", err)
}
// Reset the connected state
connected = false
tunnelRunning = false