diff --git a/pkg/services/dns/dns.go b/pkg/services/dns/dns.go index e50bbc52..c6c9e8d7 100644 --- a/pkg/services/dns/dns.go +++ b/pkg/services/dns/dns.go @@ -16,34 +16,32 @@ import ( ) type dnsHandler struct { - zones []types.Zone - zonesLock sync.RWMutex - udpClient *dns.Client - tcpClient *dns.Client - hostsFile *HostsFile - nameservers []string + zones []types.Zone + zonesLock sync.RWMutex + udpClient *dns.Client + tcpClient *dns.Client + hostsFile *HostsFile + resolver *dnsConfig } func newDNSHandler(zones []types.Zone) (*dnsHandler, error) { - - nameservers, err := getDNSHostAndPort() + hostsFile, err := NewHostsFile("") if err != nil { return nil, err } - hostsFile, err := NewHostsFile("") + resolver, err := newDNSConfig() if err != nil { return nil, err } return &dnsHandler{ - zones: zones, - tcpClient: &dns.Client{Net: "tcp"}, - udpClient: &dns.Client{Net: "udp"}, - nameservers: nameservers, - hostsFile: hostsFile, + zones: zones, + tcpClient: &dns.Client{Net: "tcp"}, + udpClient: &dns.Client{Net: "udp"}, + resolver: resolver, + hostsFile: hostsFile, }, nil - } func (h *dnsHandler) handle(w dns.ResponseWriter, dnsClient *dns.Client, r *dns.Msg, responseMessageSize int) { @@ -145,7 +143,7 @@ func (h *dnsHandler) addAnswers(dnsClient *dns.Client, r *dns.Msg) *dns.Msg { return m } } - for _, nameserver := range h.nameservers { + for _, nameserver := range h.resolver.Nameservers() { msg := r.Copy() r, _, err := dnsClient.Exchange(msg, nameserver) // return first good answer diff --git a/pkg/services/dns/dns_config.go b/pkg/services/dns/dns_config.go new file mode 100644 index 00000000..1abdfe0c --- /dev/null +++ b/pkg/services/dns/dns_config.go @@ -0,0 +1,24 @@ +package dns + +import "sync" + +type dnsConfig struct { + mu sync.RWMutex + nameservers []string +} + +func newDNSConfig() (*dnsConfig, error) { + r := &dnsConfig{nameservers: []string{}} + if err := r.init(); err != nil { + return nil, err + } + + return r, nil +} + +func (r *dnsConfig) Nameservers() []string { + r.mu.RLock() + defer r.mu.RUnlock() + + return r.nameservers +} diff --git a/pkg/services/dns/dns_config_unix.go b/pkg/services/dns/dns_config_unix.go index ef66be39..09fbe51c 100644 --- a/pkg/services/dns/dns_config_unix.go +++ b/pkg/services/dns/dns_config_unix.go @@ -7,18 +7,50 @@ import ( "net" "net/netip" + "github.com/containers/gvisor-tap-vsock/pkg/utils" "github.com/miekg/dns" log "github.com/sirupsen/logrus" ) +func (r *dnsConfig) init() error { + if err := r.refreshNameservers(); err != nil { + return err + } + + w, err := utils.NewFileWatcher(etcResolvConfPath) + if err != nil { + return err + } + + if err := w.Start(func() { _ = r.refreshNameservers() }); err != nil { + return err + } + + return nil +} + +func (r *dnsConfig) refreshNameservers() error { + nsList, err := getDNSHostAndPort(etcResolvConfPath) + if err != nil { + return err + } + + r.mu.Lock() + r.nameservers = nsList + r.mu.Unlock() + return nil +} + +const etcResolvConfPath = "/etc/resolv.conf" + var errEmptyResolvConf = errors.New("no DNS servers configured in /etc/resolv.conf") -func getDNSHostAndPort() ([]string, error) { - conf, err := dns.ClientConfigFromFile("/etc/resolv.conf") +func getDNSHostAndPort(path string) ([]string, error) { + conf, err := dns.ClientConfigFromFile(path) if err != nil { return []string{}, err } - var hosts = make([]string, len(conf.Servers)) + hosts := make([]string, len(conf.Servers)) for _, server := range conf.Servers { dnsIP, err := netip.ParseAddr(server) if err != nil { diff --git a/pkg/services/dns/dns_config_windows.go b/pkg/services/dns/dns_config_windows.go index 5f1166d1..431727df 100644 --- a/pkg/services/dns/dns_config_windows.go +++ b/pkg/services/dns/dns_config_windows.go @@ -9,6 +9,16 @@ import ( qdmDns "github.com/qdm12/dns/v2/pkg/nameserver" ) +func (r *dnsConfig) init() error { + nsList, err := getDNSHostAndPort() + if err != nil { + return err + } + + r.nameservers = nsList + return nil +} + func getDNSHostAndPort() ([]string, error) { nameservers := qdmDns.GetDNSServers() @@ -21,5 +31,4 @@ func getDNSHostAndPort() ([]string, error) { } return dnsServers, nil - }