diff --git a/go.mod b/go.mod index 92f2952..3a60f50 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,8 @@ go 1.22 require github.com/miekg/dns v1.1.62 +require github.com/patrickmn/go-cache v2.1.0+incompatible + require ( golang.org/x/mod v0.18.0 // indirect golang.org/x/net v0.27.0 // indirect diff --git a/go.sum b/go.sum index 95e8194..26556ce 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ= github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ= +github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= +github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= diff --git a/service.go b/service.go index bfaf8bb..1ea0320 100644 --- a/service.go +++ b/service.go @@ -10,6 +10,8 @@ import ( "strings" "sync" "time" + + cache "github.com/patrickmn/go-cache" ) const defaultTreeRootCheckInterval = 15 * time.Second @@ -43,7 +45,7 @@ type ReverseLookupResult struct { type Service struct { mu sync.RWMutex records map[string]NameRecords - reverseIndex map[string][]string + reverseIndex *cache.Cache treeRoot string zoneApex string hsdClient *HSDClient @@ -99,7 +101,7 @@ func NewService(options ServiceOptions) *Service { treeRoot := computeTreeRoot(cached) return &Service{ records: cached, - reverseIndex: buildReverseIndex(cached), + reverseIndex: buildReverseIndexCache(cached), treeRoot: treeRoot, zoneApex: computeZoneApex(cached), hsdClient: options.HSDClient, @@ -361,7 +363,7 @@ func (service *Service) replaceRecords(discovered map[string]NameRecords) { service.mu.Lock() defer service.mu.Unlock() service.records = cached - service.reverseIndex = buildReverseIndex(service.records) + service.reverseIndex = buildReverseIndexCache(service.records) service.treeRoot = computeTreeRoot(service.records) service.zoneApex = computeZoneApex(service.records) } @@ -373,7 +375,7 @@ func (service *Service) SetRecord(name string, record NameRecords) { service.mu.Lock() defer service.mu.Unlock() service.records[normalizeName(name)] = record - service.reverseIndex = buildReverseIndex(service.records) + service.reverseIndex = buildReverseIndexCache(service.records) service.treeRoot = computeTreeRoot(service.records) service.zoneApex = computeZoneApex(service.records) } @@ -385,7 +387,7 @@ func (service *Service) RemoveRecord(name string) { service.mu.Lock() defer service.mu.Unlock() delete(service.records, normalizeName(name)) - service.reverseIndex = buildReverseIndex(service.records) + service.reverseIndex = buildReverseIndexCache(service.records) service.treeRoot = computeTreeRoot(service.records) service.zoneApex = computeZoneApex(service.records) } @@ -472,16 +474,26 @@ func (service *Service) ResolveAddress(name string) (ResolveAddressResult, bool) // // names, ok := service.ResolveReverse("10.10.10.10") func (service *Service) ResolveReverse(ip string) ([]string, bool) { - service.mu.RLock() - defer service.mu.RUnlock() - normalizedIP := normalizeIP(ip) if normalizedIP == "" { return nil, false } - names, ok := service.reverseIndex[normalizedIP] - if !ok { + service.mu.RLock() + reverseIndex := service.reverseIndex + service.mu.RUnlock() + + if reverseIndex == nil { + return nil, false + } + + rawNames, found := reverseIndex.Get(normalizedIP) + if !found { + return nil, false + } + + names, ok := rawNames.([]string) + if !ok || len(names) == 0 { return nil, false } return append([]string(nil), names...), true @@ -568,7 +580,7 @@ func resolveResult(record NameRecords) ResolveAllResult { } } -func buildReverseIndex(records map[string]NameRecords) map[string][]string { +func buildReverseIndexCache(records map[string]NameRecords) *cache.Cache { raw := map[string]map[string]struct{}{} for name, record := range records { for _, ip := range record.A { @@ -606,7 +618,11 @@ func buildReverseIndex(records map[string]NameRecords) map[string][]string { slices.Sort(unique) reverseIndex[ip] = unique } - return reverseIndex + reverseIndexCache := cache.New(cache.NoExpiration, cache.NoExpiration) + for ip, names := range reverseIndex { + reverseIndexCache.Set(ip, names, cache.NoExpiration) + } + return reverseIndexCache } func normalizeIP(ip string) string {