]> go.fuhry.dev Git - runtime.git/commitdiff
machines/coredns_plugin: use RWMutex to guard registryStore reads
authorDan Fuhry <dan@fuhry.com>
Thu, 15 May 2025 21:43:19 +0000 (17:43 -0400)
committerDan Fuhry <dan@fuhry.com>
Thu, 15 May 2025 21:43:19 +0000 (17:43 -0400)
machines/coredns_plugin/registry.go
machines/coredns_plugin/registry_store.go

index 0769e3b1847f779bd7d7f2585b6061cd78c8a4ae..b4da6632f5cad7617c45090f0a068d684ad306fb 100644 (file)
@@ -138,6 +138,9 @@ func (r *registry) Shutdown() error {
 }
 
 func (r *registry) defaultDomain() *machines.Domain {
+       r.store.mu.RLock()
+       defer r.store.mu.RUnlock()
+
        if r.defDomain != "" {
                if d, ok := r.store.Domains[r.defDomain]; ok && d != nil {
                        return d
@@ -202,6 +205,9 @@ func (r *registry) defaultDomain() *machines.Domain {
 }
 
 func (r *registry) domainFromQuestion(ques dns.Question) *machines.Domain {
+       r.store.mu.RLock()
+       defer r.store.mu.RUnlock()
+
        qname := strings.ToLower(strings.TrimSuffix(ques.Name, "."))
        for _, domain := range r.store.Domains {
                if qname == domain.Name || strings.HasSuffix(qname, "."+domain.Name) {
@@ -266,10 +272,15 @@ func (r *registry) LookupRecord(ques dns.Question) (int, []dns.RR) {
 
        if defDomain := r.defaultDomain(); defDomain != nil {
                if qname == defDomain.ReverseDNSZoneIPv4 || qname == defDomain.ReverseDNSZoneIPv6 {
-                       return r.lookupApex(ques, defDomain)
+                       code, rrs := r.lookupApex(ques, defDomain)
+                       r.log.V(1).Infof("lookupApex(%s): %+v", qname, rrs)
+                       return code, rrs
                }
        }
 
+       r.store.mu.RLock()
+       defer r.store.mu.RUnlock()
+
        for _, domain := range r.store.Domains {
                myfqdn := fmt.Sprintf("%s.%s", myHostname, domain.Name)
 
@@ -342,6 +353,9 @@ func (r *registry) LookupHost(qname string) (*Result, error) {
                return r.lookupReverseIPv6(fqdn)
        }
 
+       r.store.mu.RLock()
+       defer r.store.mu.RUnlock()
+
        var basename, domainName string
 
        var domain *machines.Domain
@@ -372,6 +386,9 @@ func (r *registry) LookupHost(qname string) (*Result, error) {
 }
 
 func (r *registry) lookupHostLastSeenIface(basename string) (*Result, error) {
+       r.store.mu.RLock()
+       defer r.store.mu.RUnlock()
+
        hostID, ok := r.store.HostNames[basename]
        if !ok {
                // host not found
@@ -404,6 +421,9 @@ func (r *registry) lookupHostLastSeenIface(basename string) (*Result, error) {
                return nil, nil
        }
 
+       r.log.V(1).Infof("lookupHostLastSeenIface(%s) result: domain %s, host %s, iface %s",
+               basename, domain.Name, host.Name, iface.Name)
+
        return &Result{
                domain: domain,
                host:   host,
@@ -412,6 +432,9 @@ func (r *registry) lookupHostLastSeenIface(basename string) (*Result, error) {
 }
 
 func (r *registry) lookupHostWithIface(basename string) (*Result, error) {
+       r.store.mu.RLock()
+       defer r.store.mu.RUnlock()
+
        ifaceID, ok := r.store.HostInterfaceNames[basename]
        if !ok {
                // host not found
@@ -447,6 +470,9 @@ func (r *registry) lookupHostWithIface(basename string) (*Result, error) {
                return nil, nil
        }
 
+       r.log.V(1).Infof("lookupHostWithIface(%s) result: domain %s, host %s, iface %s",
+               basename, domain.Name, host.Name, iface.Name)
+
        return &Result{
                domain: domain,
                host:   host,
@@ -469,6 +495,9 @@ func (r *registry) lookupReverseIPv4(ptrName string) (*Result, error) {
                return nil, fmt.Errorf("failed to parse IP")
        }
 
+       r.store.mu.RLock()
+       defer r.store.mu.RUnlock()
+
        var domain *machines.Domain
        for _, d := range r.store.Domains {
                if !ip.Mask(d.IPv4PrefixLength.IPMask()).Equal(d.IPv4Address.AsIP()) {
@@ -514,6 +543,8 @@ func (r *registry) lookupReverseIPv4(ptrName string) (*Result, error) {
        }
 
        if domain != nil && host != nil && iface != nil {
+               r.log.V(1).Infof("lookupReverseIPv4(%s) result: domain %s, host %s, iface %s",
+                       ptrName, domain.Name, host.Name, iface.Name)
                return &Result{
                        domain: domain,
                        host:   host,
@@ -540,7 +571,10 @@ func (r *registry) lookupReverseIPv6(ptrName string) (*Result, error) {
                return nil, fmt.Errorf("failed to parse IP")
        }
 
-       r.log.V(1).Debugf("processing PTR lookup for IP %s", ip.String())
+       r.log.V(3).Debugf("processing PTR lookup for IP %s", ip.String())
+
+       r.store.mu.RLock()
+       defer r.store.mu.RUnlock()
 
        var domain *machines.Domain
        for _, d := range r.store.Domains {
@@ -556,7 +590,7 @@ func (r *registry) lookupReverseIPv6(ptrName string) (*Result, error) {
        }
 
        routerAddress := r.store.Addrs.IPv6[domain.IPv6Address.String()].Address
-       r.log.Debugf("routerAddress = %s", routerAddress)
+       r.log.V(3).Debugf("routerAddress = %s", routerAddress)
        if ip.Equal(routerAddress.AsIP()) {
                return &Result{
                        domain: domain,
@@ -588,6 +622,8 @@ func (r *registry) lookupReverseIPv6(ptrName string) (*Result, error) {
        }
 
        if domain != nil && host != nil && iface != nil {
+               r.log.V(1).Infof("lookupReverseIPv6(%s) result: domain %s, host %s, iface %s",
+                       ptrName, domain.Name, host.Name, iface.Name)
                return &Result{
                        domain: domain,
                        host:   host,
@@ -603,8 +639,6 @@ func (r *registry) lookupApex(ques dns.Question, domain *machines.Domain) (int,
        qname := strings.TrimSuffix(ques.Name, ".")
        defDomain := r.defaultDomain()
 
-       r.log.V(2).Debugf("lookupApex(%s)", ques.Name)
-
        switch ques.Qtype {
        case dns.TypeSOA:
                return dns.RcodeSuccess, []dns.RR{
index 8958365eb5fb991d3962f68eb3e25270702a25ad..37df43d68b1fd38234732fcd39b632b8f186b60e 100644 (file)
@@ -16,7 +16,7 @@ import (
 )
 
 type registryStore struct {
-       mu  sync.Mutex `json:"-"`
+       mu  sync.RWMutex `json:"-"`
        log log.Logger
 
        lastRefresh        time.Time
@@ -54,8 +54,8 @@ func init() {
 }
 
 func (rs *registryStore) initialized() bool {
-       rs.mu.Lock()
-       defer rs.mu.Unlock()
+       rs.mu.RLock()
+       defer rs.mu.RUnlock()
 
        return rs.Sites != nil && rs.Domains != nil && rs.Hosts != nil && rs.Ifaces != nil && rs.Records != nil
 }
@@ -70,8 +70,8 @@ func (rs *registryStore) saveState() error {
        }
 
        // wait to acquire lock until after initialization check to avoid deadlock
-       rs.mu.Lock()
-       defer rs.mu.Unlock()
+       rs.mu.RLock()
+       defer rs.mu.RUnlock()
 
        contents, err := json.Marshal(rs)
        if err != nil {
@@ -279,6 +279,9 @@ func (rs *registryStore) patchIface(iface *machines.Iface) {
 }
 
 func (rs *registryStore) DomainForFqdn(qname string) *machines.Domain {
+       rs.mu.RLock()
+       defer rs.mu.RUnlock()
+
        for _, domain := range rs.Domains {
                if strings.HasSuffix(qname, "."+domain.Name) {
                        return domain
@@ -289,6 +292,9 @@ func (rs *registryStore) DomainForFqdn(qname string) *machines.Domain {
 }
 
 func (rs *registryStore) DomainForAddress(addr net.Addr) *machines.Domain {
+       rs.mu.RLock()
+       defer rs.mu.RUnlock()
+
        udpAddr, ok := addr.(*net.UDPAddr)
        if !ok {
                return nil