Skip to content

Commit 9d9a6fa

Browse files
committed
dnsx/alg: invalidate caches when transport stopped
1 parent 8478aee commit 9d9a6fa

File tree

2 files changed

+47
-0
lines changed

2 files changed

+47
-0
lines changed

intra/dnsx/alg.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ type Gateway interface {
8282
translate(yes bool)
8383
// Query using t1 as primary transport and t2 as secondary and preset as pre-determined ip answers
8484
q(t1, t2 Transport, preset []netip.Addr, network string, q *dns.Msg, s *x.DNSSummary) (*dns.Msg, error)
85+
// onStopped is called when a transport tid is stopped. Gateway invalidates its local caches, if any.
86+
onStopped(tid string)
8587
// clear obj state
8688
stop()
8789
}
@@ -116,6 +118,7 @@ func (a expaddr) alive() []netip.Addr {
116118
return a.get(true /*live*/)
117119
}
118120

121+
// fresh returns false if a has expired or if a is zero-value.
119122
func (a expaddr) fresh() bool {
120123
return !a.ttl.IsZero() && time.Now().Before(a.ttl)
121124
}
@@ -250,6 +253,20 @@ func (p *xips) sec() []netip.Addr {
250253
return p.aux
251254
}
252255

256+
func (p *xips) rmv(tid string) (done bool) {
257+
if p == nil {
258+
return
259+
}
260+
p.pmu.Lock()
261+
defer p.pmu.Unlock()
262+
if xaddr := p.pri[tid]; xaddr.fresh() {
263+
done = true
264+
xaddr.ttl = time.Now() // mark as expired
265+
p.pri[tid] = xaddr
266+
}
267+
return
268+
}
269+
253270
// block returns true if any secondary ip is unspecified
254271
func anyUnspecified(ips []netip.Addr) bool {
255272
// unspecified ips expected to be in aux
@@ -399,6 +416,33 @@ func (t *dnsgateway) translate(yes bool) {
399416
log.I("alg: translate? prev(%t) > now(%t)", prev, yes)
400417
}
401418

419+
func (t *dnsgateway) onStopped(tid string) {
420+
if len(tid) <= 0 {
421+
return
422+
}
423+
424+
ach := make(chan *xips, len(t.alg))
425+
defer close(ach)
426+
427+
go func() {
428+
n := 0
429+
for x := range ach {
430+
if x.rmv(tid) {
431+
n++
432+
}
433+
}
434+
log.I("alg: onStopped(%s): removed %d alg<>realip translations", tid, n)
435+
}()
436+
437+
t.RLock()
438+
defer t.RUnlock()
439+
for _, algans := range t.alg {
440+
if algans != nil {
441+
ach <- algans.ips
442+
}
443+
}
444+
}
445+
402446
// Implements Gateway
403447
func (t *dnsgateway) stop() {
404448
t.Lock()

intra/dnsx/transport.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,9 @@ func (r *resolver) Translate(b bool) {
249249
func (r *resolver) stopIfExistsLocked(id string) {
250250
if t, ok := r.transports[id]; ok && t != nil {
251251
err := t.Stop() // todo: async?
252+
core.Go("r.gateway.stopTid", func() {
253+
r.gateway.onStopped(id)
254+
})
252255
log.VV("dns: stop: %s; err? %v", id, err)
253256
delete(r.transports, id)
254257
}

0 commit comments

Comments
 (0)