Merge pull request #663 from strukturag/improve-dnsmonitor

Minor improvements to DNS monitor
This commit is contained in:
Joachim Bauch 2024-02-22 15:01:44 +01:00 committed by GitHub
commit ae37a56e34
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 27 additions and 11 deletions

View file

@ -43,8 +43,7 @@ const (
type DnsMonitorCallback = func(entry *DnsMonitorEntry, all []net.IP, add []net.IP, keep []net.IP, remove []net.IP) type DnsMonitorCallback = func(entry *DnsMonitorEntry, all []net.IP, add []net.IP, keep []net.IP, remove []net.IP)
type DnsMonitorEntry struct { type DnsMonitorEntry struct {
removing atomic.Bool entry atomic.Pointer[dnsMonitorEntry]
entry *dnsMonitorEntry
url string url string
callback DnsMonitorCallback callback DnsMonitorCallback
} }
@ -145,6 +144,7 @@ type DnsMonitor struct {
stopCtx context.Context stopCtx context.Context
stopFunc func() stopFunc func()
stopped chan struct{}
mu sync.RWMutex mu sync.RWMutex
cond *sync.Cond cond *sync.Cond
@ -167,6 +167,7 @@ func NewDnsMonitor(interval time.Duration) (*DnsMonitor, error) {
stopCtx: stopCtx, stopCtx: stopCtx,
stopFunc: stopFunc, stopFunc: stopFunc,
stopped: make(chan struct{}),
hostnames: make(map[string]*dnsMonitorEntry), hostnames: make(map[string]*dnsMonitorEntry),
} }
@ -183,6 +184,7 @@ func (m *DnsMonitor) Start() error {
func (m *DnsMonitor) Stop() { func (m *DnsMonitor) Stop() {
m.stopFunc() m.stopFunc()
m.cond.Signal() m.cond.Signal()
<-m.stopped
} }
func (m *DnsMonitor) Add(target string, callback DnsMonitorCallback) (*DnsMonitorEntry, error) { func (m *DnsMonitor) Add(target string, callback DnsMonitorCallback) (*DnsMonitorEntry, error) {
@ -219,14 +221,15 @@ func (m *DnsMonitor) Add(target string, callback DnsMonitorCallback) (*DnsMonito
} }
m.hostnames[hostname] = entry m.hostnames[hostname] = entry
} }
e.entry = entry e.entry.Store(entry)
entry.addEntry(e) entry.addEntry(e)
m.cond.Signal() m.cond.Signal()
return e, nil return e, nil
} }
func (m *DnsMonitor) Remove(entry *DnsMonitorEntry) { func (m *DnsMonitor) Remove(entry *DnsMonitorEntry) {
if !entry.removing.CompareAndSwap(false, true) { oldEntry := entry.entry.Swap(nil)
if oldEntry == nil {
// Already removed. // Already removed.
return return
} }
@ -244,16 +247,11 @@ func (m *DnsMonitor) Remove(entry *DnsMonitorEntry) {
} }
defer m.mu.Unlock() defer m.mu.Unlock()
if entry.entry == nil { e, found := m.hostnames[oldEntry.hostname]
return
}
e, found := m.hostnames[entry.entry.hostname]
if !found { if !found {
return return
} }
entry.entry = nil
if e.removeEntry(entry) { if e.removeEntry(entry) {
delete(m.hostnames, e.hostname) delete(m.hostnames, e.hostname)
} }
@ -270,7 +268,7 @@ func (m *DnsMonitor) clearRemoved() {
for hostname, entry := range m.hostnames { for hostname, entry := range m.hostnames {
deleted := false deleted := false
for e := range entry.entries { for e := range entry.entries {
if e.removing.Load() { if e.entry.Load() == nil {
delete(entry.entries, e) delete(entry.entries, e)
deleted = true deleted = true
} }
@ -296,6 +294,7 @@ func (m *DnsMonitor) waitForEntries() (waited bool) {
func (m *DnsMonitor) run() { func (m *DnsMonitor) run() {
ticker := time.NewTicker(m.interval) ticker := time.NewTicker(m.interval)
defer ticker.Stop() defer ticker.Stop()
defer close(m.stopped)
for { for {
if m.waitForEntries() { if m.waitForEntries() {

View file

@ -151,6 +151,10 @@ func (p *proxyConfigStatic) Start() error {
if p.dnsDiscovery { if p.dnsDiscovery {
for u, ips := range p.connectionsMap { for u, ips := range p.connectionsMap {
if ips.entry != nil {
continue
}
entry, err := p.dnsMonitor.Add(u, p.onLookup) entry, err := p.dnsMonitor.Add(u, p.onLookup)
if err != nil { if err != nil {
return err return err
@ -170,6 +174,19 @@ func (p *proxyConfigStatic) Start() error {
} }
func (p *proxyConfigStatic) Stop() { func (p *proxyConfigStatic) Stop() {
p.mu.Lock()
defer p.mu.Unlock()
if p.dnsDiscovery {
for _, ips := range p.connectionsMap {
if ips.entry == nil {
continue
}
p.dnsMonitor.Remove(ips.entry)
ips.entry = nil
}
}
} }
func (p *proxyConfigStatic) Reload(config *goconf.ConfigFile) error { func (p *proxyConfigStatic) Reload(config *goconf.ConfigFile) error {