diff --git a/internal/discover/discover.go b/internal/discover/discover.go index 0485446a..54baa382 100644 --- a/internal/discover/discover.go +++ b/internal/discover/discover.go @@ -27,14 +27,17 @@ type Discoverer struct { localBcastIntv time.Duration localBcastStart time.Time cacheLifetime time.Duration + negCacheCutoff time.Duration broadcastBeacon beacon.Interface multicastBeacon beacon.Interface - registry map[protocol.DeviceID][]CacheEntry - registryLock sync.RWMutex extPort uint16 localBcastTick <-chan time.Time forcedBcastTick chan time.Time + registryLock sync.RWMutex + registry map[protocol.DeviceID][]CacheEntry + lastLookup map[protocol.DeviceID]time.Time + clients []Client mut sync.RWMutex } @@ -54,7 +57,9 @@ func NewDiscoverer(id protocol.DeviceID, addresses []string) *Discoverer { listenAddrs: addresses, localBcastIntv: 30 * time.Second, cacheLifetime: 5 * time.Minute, + negCacheCutoff: 3 * time.Minute, registry: make(map[protocol.DeviceID][]CacheEntry), + lastLookup: make(map[protocol.DeviceID]time.Time), } } @@ -155,18 +160,28 @@ func (d *Discoverer) ExtAnnounceOK() map[string]bool { func (d *Discoverer) Lookup(device protocol.DeviceID) []string { d.registryLock.RLock() cached := d.filterCached(d.registry[device]) + lastLookup := d.lastLookup[device] d.registryLock.RUnlock() d.mut.RLock() defer d.mut.RUnlock() - var addrs []string if len(cached) > 0 { - addrs = make([]string, len(cached)) + // There are cached address entries. + addrs := make([]string, len(cached)) for i := range cached { addrs[i] = cached[i].Address } - } else if len(d.clients) != 0 && time.Since(d.localBcastStart) > d.localBcastIntv { + return addrs + } + + if time.Since(lastLookup) < d.negCacheCutoff { + // We have recently tried to lookup this address and failed. Lets + // chill for a while. + return nil + } + + if len(d.clients) != 0 && time.Since(d.localBcastStart) > d.localBcastIntv { // Only perform external lookups if we have at least one external // server client and one local announcement interval has passed. This is // to avoid finding local peers on their remote address at startup. @@ -187,6 +202,7 @@ func (d *Discoverer) Lookup(device protocol.DeviceID) []string { seen := make(map[string]struct{}) now := time.Now() + var addrs []string for result := range results { for _, addr := range result { _, ok := seen[addr] @@ -203,9 +219,13 @@ func (d *Discoverer) Lookup(device protocol.DeviceID) []string { d.registryLock.Lock() d.registry[device] = cached + d.lastLookup[device] = time.Now() d.registryLock.Unlock() + + return addrs } - return addrs + + return nil } func (d *Discoverer) Hint(device string, addrs []string) {