From 80a88811cd2afc1580b922b94a32b7ef21632cf2 Mon Sep 17 00:00:00 2001 From: Cuong Manh Le Date: Thu, 7 Sep 2023 11:13:36 +0000 Subject: [PATCH] cmd/cli: restart systemd-resolved after setting DNS So the current selected DNS server will be reset, and the new one will be used by systemd-resolved after first query made. --- cmd/cli/os_linux.go | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/cmd/cli/os_linux.go b/cmd/cli/os_linux.go index 004e863..7fb692c 100644 --- a/cmd/cli/os_linux.go +++ b/cmd/cli/os_linux.go @@ -9,7 +9,6 @@ import ( "net" "net/netip" "os/exec" - "reflect" "strings" "syscall" "time" @@ -85,8 +84,13 @@ func setDNS(iface *net.Interface, nameservers []string) error { } return err } + if useSystemdResolved { + if out, err := exec.Command("systemctl", "restart", "systemd-resolved").CombinedOutput(); err != nil { + mainLog.Load().Warn().Err(err).Msgf("could not restart systemd-resolved: %s", string(out)) + } + } currentNS := currentDNS(iface) - if reflect.DeepEqual(currentNS, nameservers) { + if isSubSet(nameservers, currentNS) { return nil } } @@ -104,7 +108,7 @@ func setDNS(iface *net.Interface, nameservers []string) error { return fmt.Errorf("%s: %w", string(out), err) } currentNS := currentDNS(iface) - if reflect.DeepEqual(currentNS, nameservers) { + if isSubSet(nameservers, currentNS) { return nil } time.Sleep(time.Second) @@ -265,3 +269,33 @@ func ignoringEINTR(fn func() error) error { } } } + +// isSubSet reports whether s2 contains all elements of s1. +func isSubSet(s1, s2 []string) bool { + ok := true + for _, ns := range s1 { + // TODO(cuonglm): use slices.Contains once upgrading to go1.21 + if sliceContains(s2, ns) { + continue + } + ok = false + break + } + return ok +} + +// sliceContains reports whether v is present in s. +func sliceContains[S ~[]E, E comparable](s S, v E) bool { + return sliceIndex(s, v) >= 0 +} + +// sliceIndex returns the index of the first occurrence of v in s, +// or -1 if not present. +func sliceIndex[S ~[]E, E comparable](s S, v E) int { + for i := range s { + if v == s[i] { + return i + } + } + return -1 +}