Remove duplicates in answers
This commit is contained in:
1 parent
174b47d1db
commit
db0ef5cf5c
1 file changed
+52
-11
+52
-11
@@ -6,18 +6,52 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type uniqZoneRecordKey struct {
|
||||
name string
|
||||
ipv4 IPv4
|
||||
}
|
||||
|
||||
// A group of ZoneRecords where there are no duplicates (according to the name & IPv4)
|
||||
type uniqZoneRecords map[uniqZoneRecordKey]ZoneRecord
|
||||
|
||||
func newUniqZoneRecords() uniqZoneRecords {
|
||||
return make(uniqZoneRecords, 0)
|
||||
}
|
||||
|
||||
// Add a new ZoneRecord to the group
|
||||
func (uzr *uniqZoneRecords) add(zr ZoneRecord) {
|
||||
key := uniqZoneRecordKey{zr.Name(), ipToIPv4(zr.IP())}
|
||||
(*uzr)[key] = zr
|
||||
}
|
||||
|
||||
// Return the group as an slice
|
||||
func (uzr *uniqZoneRecords) toSlice() []ZoneRecord {
|
||||
res := make([]ZoneRecord, len(*uzr))
|
||||
i := 0
|
||||
for _, r := range *uzr {
|
||||
res[i] = r
|
||||
i++
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Lookup in the database for locally-introduced information
|
||||
func (zone *zoneDb) lookup(target string, lfun func(ns *namesSet) []*recordEntry) (res []ZoneRecord, err error) {
|
||||
uniq := newUniqZoneRecords()
|
||||
for identName, nameset := range zone.idents {
|
||||
if identName != defaultRemoteIdent {
|
||||
for _, ze := range lfun(nameset) {
|
||||
res = append(res, ze)
|
||||
uniq.add(ze)
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(res) == 0 {
|
||||
err = LookupError(target)
|
||||
if len(uniq) == 0 {
|
||||
return nil, LookupError(target)
|
||||
} else {
|
||||
return uniq.toSlice(), nil
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Perform a lookup for a name in the zone
|
||||
@@ -63,16 +97,19 @@ func (zone *zoneDb) domainLookup(target string, lfun ZoneLookupFunc) (res []Zone
|
||||
res = make([]ZoneRecord, len(lanswers))
|
||||
zone.mx.Lock()
|
||||
now := zone.clock.Now()
|
||||
for i, answer := range lanswers {
|
||||
res[i], err = zone.getNamesSet(defaultRemoteIdent).addIPToName(answer, now)
|
||||
uniq := newUniqZoneRecords()
|
||||
for _, answer := range lanswers {
|
||||
r, err := zone.getNamesSet(defaultRemoteIdent).addIPToName(answer, now)
|
||||
if err != nil {
|
||||
zone.mx.Unlock()
|
||||
Warning.Printf("[zonedb] '%s' insertion for %s failed: %s", answer, target, err)
|
||||
return nil, err
|
||||
}
|
||||
uniq.add(r)
|
||||
}
|
||||
zone.mx.Unlock()
|
||||
return
|
||||
|
||||
return uniq.toSlice(), nil
|
||||
}
|
||||
|
||||
// Perform a lookup for a name in the zone
|
||||
@@ -83,6 +120,7 @@ func (zone *zoneDb) DomainLookupName(name string) (res []ZoneRecord, err error)
|
||||
|
||||
zone.mx.RLock()
|
||||
now := zone.clock.Now()
|
||||
uniq := newUniqZoneRecords()
|
||||
for identName, nameset := range zone.idents {
|
||||
for _, ze := range nameset.getEntriesForName(name) {
|
||||
// filter the entries with expired TTL
|
||||
@@ -91,7 +129,7 @@ func (zone *zoneDb) DomainLookupName(name string) (res []ZoneRecord, err error)
|
||||
Debug.Printf("[zonedb] '%s': expired entry '%s' ignored: removing", name, ze)
|
||||
nameset.deleteName(name)
|
||||
} else {
|
||||
res = append(res, ze)
|
||||
uniq.add(ze)
|
||||
}
|
||||
}
|
||||
if identName != defaultRemoteIdent {
|
||||
@@ -100,8 +138,9 @@ func (zone *zoneDb) DomainLookupName(name string) (res []ZoneRecord, err error)
|
||||
}
|
||||
zone.mx.RUnlock()
|
||||
|
||||
if len(res) > 0 {
|
||||
if len(uniq) > 0 {
|
||||
Debug.Printf("[zonedb] '%s' resolved in local database", name)
|
||||
res = uniq.toSlice()
|
||||
} else {
|
||||
res, err = zone.domainLookup(name, zone.mdnsCli.LookupName)
|
||||
}
|
||||
@@ -126,6 +165,7 @@ func (zone *zoneDb) DomainLookupInaddr(inaddr string) (res []ZoneRecord, err err
|
||||
|
||||
zone.mx.RLock()
|
||||
now := zone.clock.Now()
|
||||
uniq := newUniqZoneRecords()
|
||||
for identName, nameset := range zone.idents {
|
||||
for _, ze := range nameset.getEntriesForIP(revIPv4) {
|
||||
// filter the entries with expired TTL
|
||||
@@ -134,7 +174,7 @@ func (zone *zoneDb) DomainLookupInaddr(inaddr string) (res []ZoneRecord, err err
|
||||
Debug.Printf("[zonedb] '%s': expired entry '%s' ignored: removing", revIPv4, ze)
|
||||
nameset.deleteIP(revIPv4)
|
||||
} else {
|
||||
res = append(res, ZoneRecord(ze))
|
||||
uniq.add(ze)
|
||||
if identName != defaultRemoteIdent {
|
||||
nameset.touchName(ze.Name(), now)
|
||||
}
|
||||
@@ -143,8 +183,9 @@ func (zone *zoneDb) DomainLookupInaddr(inaddr string) (res []ZoneRecord, err err
|
||||
}
|
||||
zone.mx.RUnlock()
|
||||
|
||||
if len(res) > 0 {
|
||||
if len(uniq) > 0 {
|
||||
Debug.Printf("[zonedb] '%s' resolved in local database", inaddr)
|
||||
res = uniq.toSlice()
|
||||
} else {
|
||||
res, err = zone.domainLookup(inaddr, zone.mdnsCli.LookupInaddr)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user