mirror of
https://github.com/fosrl/olm.git
synced 2026-04-28 11:27:51 -05:00
Compare commits
6 Commits
1.4.3
...
dependabot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2edacbbd4b | ||
|
|
df6a84648b | ||
|
|
703fe4fe5d | ||
|
|
42ef1f5ee3 | ||
|
|
f250702177 | ||
|
|
8549dc8746 |
@@ -1,5 +1,5 @@
|
||||
# FROM golang:1.25-alpine AS builder
|
||||
FROM public.ecr.aws/docker/library/golang:1.25-alpine AS builder
|
||||
FROM public.ecr.aws/docker/library/golang:1.26-alpine AS builder
|
||||
|
||||
# Install git and ca-certificates
|
||||
RUN apk --no-cache add ca-certificates git tzdata
|
||||
|
||||
@@ -13,4 +13,10 @@ func SetupDNSOverride(interfaceName string, proxyIp netip.Addr) error {
|
||||
// RestoreDNSOverride is a no-op on Android
|
||||
func RestoreDNSOverride() error {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// CleanupStaleState is a no-op on Android as DNS configuration is handled by the VpnService API
|
||||
func CleanupStaleState(interfaceName string) error {
|
||||
_ = interfaceName
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -61,3 +61,20 @@ func RestoreDNSOverride() error {
|
||||
logger.Info("DNS configuration restored successfully")
|
||||
return nil
|
||||
}
|
||||
|
||||
// CleanupStaleState removes any stale DNS configuration left over from a previous
|
||||
// unclean shutdown (e.g., system crash, power loss while tunnel was active).
|
||||
// This function should be called early during startup, before any network operations,
|
||||
// to ensure DNS is working properly.
|
||||
//
|
||||
// On macOS, this cleans up any scutil DNS keys that were created but not removed.
|
||||
func CleanupStaleState(interfaceName string) error {
|
||||
_ = interfaceName
|
||||
if err := platform.CleanupStaleDarwinDNS(); err != nil {
|
||||
logger.Warn("Failed to cleanup stale Darwin DNS config: %v", err)
|
||||
return fmt.Errorf("Darwin DNS cleanup: %w", err)
|
||||
}
|
||||
|
||||
logger.Info("Stale DNS state cleanup completed successfully")
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -12,4 +12,10 @@ func SetupDNSOverride(interfaceName string, proxyIp netip.Addr) error {
|
||||
// RestoreDNSOverride is a no-op on iOS as DNS configuration is handled by the system
|
||||
func RestoreDNSOverride() error {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// CleanupStaleState is a no-op on iOS as DNS configuration is handled by the system
|
||||
func CleanupStaleState(interfaceName string) error {
|
||||
_ = interfaceName
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -98,3 +98,49 @@ func RestoreDNSOverride() error {
|
||||
logger.Info("DNS configuration restored successfully")
|
||||
return nil
|
||||
}
|
||||
|
||||
// CleanupStaleState removes any stale DNS configuration left over from a previous
|
||||
// unclean shutdown (e.g., system crash, power loss while tunnel was active).
|
||||
// This function should be called early during startup, before any network operations,
|
||||
// to ensure DNS is working properly.
|
||||
//
|
||||
// It checks and cleans up stale state from all supported DNS managers:
|
||||
// - NetworkManager: removes /etc/NetworkManager/conf.d/olm-dns.conf
|
||||
// - resolvconf: removes entry for the provided interface
|
||||
// - File-based: restores /etc/resolv.conf from backup if it exists
|
||||
//
|
||||
// This is safe to call even if no stale state exists.
|
||||
func CleanupStaleState(interfaceName string) error {
|
||||
var errs []error
|
||||
|
||||
// Clean up NetworkManager stale config
|
||||
if err := platform.CleanupStaleNetworkManagerDNS(); err != nil {
|
||||
logger.Warn("Failed to cleanup stale NetworkManager DNS config: %v", err)
|
||||
errs = append(errs, fmt.Errorf("NetworkManager cleanup: %w", err))
|
||||
} else {
|
||||
logger.Debug("NetworkManager DNS cleanup completed")
|
||||
}
|
||||
|
||||
// Clean up resolvconf stale entries for the provided interface
|
||||
if err := platform.CleanupStaleResolvconfDNS(interfaceName); err != nil {
|
||||
logger.Warn("Failed to cleanup stale resolvconf DNS config: %v", err)
|
||||
errs = append(errs, fmt.Errorf("resolvconf cleanup: %w", err))
|
||||
} else {
|
||||
logger.Debug("resolvconf DNS cleanup completed")
|
||||
}
|
||||
|
||||
// Clean up file-based stale backup
|
||||
if err := platform.CleanupStaleFileDNS(); err != nil {
|
||||
logger.Warn("Failed to cleanup stale file-based DNS config: %v", err)
|
||||
errs = append(errs, fmt.Errorf("file DNS cleanup: %w", err))
|
||||
} else {
|
||||
logger.Debug("File-based DNS cleanup completed")
|
||||
}
|
||||
|
||||
if len(errs) > 0 {
|
||||
return fmt.Errorf("some DNS cleanup operations failed: %v", errs)
|
||||
}
|
||||
|
||||
logger.Info("Stale DNS state cleanup completed successfully")
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -61,3 +61,19 @@ func RestoreDNSOverride() error {
|
||||
logger.Info("DNS configuration restored successfully")
|
||||
return nil
|
||||
}
|
||||
|
||||
// CleanupStaleState removes any stale DNS configuration left over from a previous
|
||||
// unclean shutdown (e.g., system crash, power loss while tunnel was active).
|
||||
// This function should be called early during startup, before any network operations,
|
||||
// to ensure DNS is working properly.
|
||||
//
|
||||
// On Windows, DNS configuration is tied to the interface GUID. When the WireGuard
|
||||
// interface is recreated, it gets a new GUID, so there's no stale state to clean up.
|
||||
func CleanupStaleState(interfaceName string) error {
|
||||
// Windows DNS configuration via registry is interface-specific.
|
||||
// When the WireGuard interface is recreated, it gets a new GUID,
|
||||
// so there's no leftover state to clean up from previous sessions.
|
||||
_ = interfaceName
|
||||
logger.Debug("Windows DNS cleanup: no stale state to clean (interface-specific)")
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -417,3 +417,59 @@ func (d *DarwinDNSConfigurator) clearState() error {
|
||||
logger.Debug("Cleared DNS state file")
|
||||
return nil
|
||||
}
|
||||
|
||||
// CleanupStaleDarwinDNS removes any stale DNS configuration left by the Darwin
|
||||
// configurator from a previous unclean shutdown. This is a static function that can be
|
||||
// called without creating a configurator instance, useful for cleanup before network operations.
|
||||
func CleanupStaleDarwinDNS() error {
|
||||
stateFilePath := getDNSStateFilePath()
|
||||
|
||||
// Check if state file exists
|
||||
data, err := os.ReadFile(stateFilePath)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
// No state file, nothing to clean up
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("read state file: %w", err)
|
||||
}
|
||||
|
||||
var state DNSPersistentState
|
||||
if err := json.Unmarshal(data, &state); err != nil {
|
||||
// Invalid state file, remove it
|
||||
os.Remove(stateFilePath)
|
||||
return nil
|
||||
}
|
||||
|
||||
if len(state.CreatedKeys) == 0 {
|
||||
// No keys to clean up
|
||||
return nil
|
||||
}
|
||||
|
||||
logger.Info("Found DNS state from previous session, cleaning up %d keys", len(state.CreatedKeys))
|
||||
|
||||
// Remove all keys from previous session using scutil directly
|
||||
for _, key := range state.CreatedKeys {
|
||||
logger.Debug("Removing leftover DNS key: %s", key)
|
||||
cmd := fmt.Sprintf("open\nremove %s\nquit\n", key)
|
||||
scutilCmd := exec.Command(scutilPath)
|
||||
scutilCmd.Stdin = strings.NewReader(cmd)
|
||||
if err := scutilCmd.Run(); err != nil {
|
||||
logger.Warn("Failed to remove DNS key %s: %v", key, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Clear state file
|
||||
if err := os.Remove(stateFilePath); err != nil && !os.IsNotExist(err) {
|
||||
logger.Warn("Failed to clear DNS state file: %v", err)
|
||||
}
|
||||
|
||||
// Flush DNS cache after cleanup
|
||||
cacheCmd := exec.Command(dscacheutilPath, "-flushcache")
|
||||
_ = cacheCmd.Run()
|
||||
|
||||
killCmd := exec.Command("killall", "-HUP", "mDNSResponder")
|
||||
_ = killCmd.Run()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -218,3 +218,27 @@ func copyFile(src, dst string) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CleanupStaleFileDNS removes any stale DNS configuration left by the file-based
|
||||
// configurator from a previous unclean shutdown. This is a static function that can be
|
||||
// called without creating a configurator instance, useful for cleanup before network operations.
|
||||
func CleanupStaleFileDNS() error {
|
||||
// Check if backup file exists from a previous session
|
||||
if _, err := os.Stat(resolvConfBackupPath); os.IsNotExist(err) {
|
||||
// No backup file, nothing to clean up
|
||||
return nil
|
||||
}
|
||||
|
||||
// A backup exists, which means we crashed while DNS was configured
|
||||
// Restore the original resolv.conf
|
||||
if err := copyFile(resolvConfBackupPath, resolvConfPath); err != nil {
|
||||
return fmt.Errorf("restore from backup during cleanup: %w", err)
|
||||
}
|
||||
|
||||
// Remove backup file
|
||||
if err := os.Remove(resolvConfBackupPath); err != nil {
|
||||
return fmt.Errorf("remove backup file during cleanup: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -323,3 +323,41 @@ func GetNetworkManagerVersion() (string, error) {
|
||||
|
||||
return version, nil
|
||||
}
|
||||
|
||||
// CleanupStaleNetworkManagerDNS removes any stale DNS configuration left by NetworkManager
|
||||
// configurator from a previous unclean shutdown. This is a static function that can be called
|
||||
// without creating a configurator instance, useful for cleanup before network operations.
|
||||
func CleanupStaleNetworkManagerDNS() error {
|
||||
confPath := networkManagerConfDir + "/" + networkManagerDNSConfFile
|
||||
|
||||
// Check if our config file exists from a previous session
|
||||
if _, err := os.Stat(confPath); os.IsNotExist(err) {
|
||||
// No config file, nothing to clean up
|
||||
return nil
|
||||
}
|
||||
|
||||
// Remove the stale configuration file
|
||||
if err := os.Remove(confPath); err != nil && !os.IsNotExist(err) {
|
||||
return fmt.Errorf("remove stale DNS config file: %w", err)
|
||||
}
|
||||
|
||||
// Try to reload NetworkManager if it's available
|
||||
if IsNetworkManagerAvailable() {
|
||||
conn, err := dbus.SystemBus()
|
||||
if err != nil {
|
||||
return fmt.Errorf("connect to system bus for reload: %w", err)
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
obj := conn.Object(networkManagerDest, networkManagerDbusObjectNode)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
|
||||
if err := obj.CallWithContext(ctx, networkManagerDest+".Reload", 0, uint32(0)).Store(); err != nil {
|
||||
return fmt.Errorf("reload NetworkManager after cleanup: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -219,3 +219,37 @@ func IsResolvconfAvailable() bool {
|
||||
cmd := exec.Command(resolvconfCommand, "--version")
|
||||
return cmd.Run() == nil
|
||||
}
|
||||
|
||||
// CleanupStaleResolvconfDNS removes any stale DNS configuration left by the resolvconf
|
||||
// configurator from a previous unclean shutdown. This is a static function that can be
|
||||
// called without creating a configurator instance, useful for cleanup before network operations.
|
||||
// The interfaceName parameter specifies which interface entry to clean up (typically "olm").
|
||||
func CleanupStaleResolvconfDNS(interfaceName string) error {
|
||||
if !IsResolvconfAvailable() {
|
||||
// resolvconf not available, nothing to clean up
|
||||
return nil
|
||||
}
|
||||
|
||||
// Detect resolvconf implementation type
|
||||
implType, err := detectResolvconfType()
|
||||
if err != nil {
|
||||
// Can't detect type, try default
|
||||
implType = "resolvconf"
|
||||
}
|
||||
|
||||
// Try to delete any existing entry for this interface
|
||||
// This is idempotent - if no entry exists, resolvconf will just return success
|
||||
var cmd *exec.Cmd
|
||||
|
||||
switch implType {
|
||||
case "openresolv":
|
||||
cmd = exec.Command(resolvconfCommand, "-f", "-d", interfaceName)
|
||||
default:
|
||||
cmd = exec.Command(resolvconfCommand, "-d", interfaceName)
|
||||
}
|
||||
|
||||
// Ignore errors - the entry may not exist, which is fine
|
||||
_ = cmd.Run()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
15
olm/peer.go
15
olm/peer.go
@@ -20,6 +20,11 @@ func (o *Olm) handleWgPeerAdd(msg websocket.WSMessage) {
|
||||
return
|
||||
}
|
||||
|
||||
if o.peerManager == nil {
|
||||
logger.Debug("Ignoring add-peer message: peerManager is nil (shutdown in progress)")
|
||||
return
|
||||
}
|
||||
|
||||
jsonData, err := json.Marshal(msg.Data)
|
||||
if err != nil {
|
||||
logger.Error("Error marshaling data: %v", err)
|
||||
@@ -76,6 +81,11 @@ func (o *Olm) handleWgPeerRemove(msg websocket.WSMessage) {
|
||||
return
|
||||
}
|
||||
|
||||
if o.peerManager == nil {
|
||||
logger.Debug("Ignoring remove-peer message: peerManager is nil (shutdown in progress)")
|
||||
return
|
||||
}
|
||||
|
||||
jsonData, err := json.Marshal(msg.Data)
|
||||
if err != nil {
|
||||
logger.Error("Error marshaling data: %v", err)
|
||||
@@ -113,6 +123,11 @@ func (o *Olm) handleWgPeerUpdate(msg websocket.WSMessage) {
|
||||
return
|
||||
}
|
||||
|
||||
if o.peerManager == nil {
|
||||
logger.Debug("Ignoring update-peer message: peerManager is nil (shutdown in progress)")
|
||||
return
|
||||
}
|
||||
|
||||
jsonData, err := json.Marshal(msg.Data)
|
||||
if err != nil {
|
||||
logger.Error("Error marshaling data: %v", err)
|
||||
|
||||
Reference in New Issue
Block a user