Skip to content

Commit 342a3eb

Browse files
committed
autonatv2: add Unknown addrs to event
Providing unknown addresses to the user, helps them infer whether autonatv2 has any more addresses it might confirm. There's no upside to not sending this information
1 parent b82a39c commit 342a3eb

File tree

6 files changed

+94
-42
lines changed

6 files changed

+94
-42
lines changed

core/event/reachability.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@ type EvtLocalReachabilityChanged struct {
1414
}
1515

1616
// EvtHostReachableAddrsChanged is sent when host's reachable or unreachable addresses change
17-
// Reachable and Unreachable both contain only Public IP or DNS addresses
17+
// Reachable, Unreachable, and Unknown only contain Public IP or DNS addresses
1818
//
1919
// Experimental: This API is unstable. Any changes to this event will be done without a deprecation notice.
2020
type EvtHostReachableAddrsChanged struct {
2121
Reachable []ma.Multiaddr
2222
Unreachable []ma.Multiaddr
23+
Unknown []ma.Multiaddr
2324
}

p2p/host/basic/addrs_manager.go

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ type hostAddrs struct {
3434
localAddrs []ma.Multiaddr
3535
reachableAddrs []ma.Multiaddr
3636
unreachableAddrs []ma.Multiaddr
37+
unknownAddrs []ma.Multiaddr
3738
relayAddrs []ma.Multiaddr
3839
}
3940

@@ -250,9 +251,9 @@ func (a *addrsManager) updateAddrs(updateRelayAddrs bool, relayAddrs []ma.Multia
250251
defer a.addrsMx.Unlock()
251252

252253
localAddrs := a.getLocalAddrs()
253-
var currReachableAddrs, currUnreachableAddrs []ma.Multiaddr
254+
var currReachableAddrs, currUnreachableAddrs, currUnknownAddrs []ma.Multiaddr
254255
if a.addrsReachabilityTracker != nil {
255-
currReachableAddrs, currUnreachableAddrs = a.getConfirmedAddrs(localAddrs)
256+
currReachableAddrs, currUnreachableAddrs, currUnknownAddrs = a.getConfirmedAddrs(localAddrs)
256257
}
257258
if !updateRelayAddrs {
258259
relayAddrs = a.currentAddrs.relayAddrs
@@ -267,6 +268,7 @@ func (a *addrsManager) updateAddrs(updateRelayAddrs bool, relayAddrs []ma.Multia
267268
localAddrs: append(a.currentAddrs.localAddrs[:0], localAddrs...),
268269
reachableAddrs: append(a.currentAddrs.reachableAddrs[:0], currReachableAddrs...),
269270
unreachableAddrs: append(a.currentAddrs.unreachableAddrs[:0], currUnreachableAddrs...),
271+
unknownAddrs: append(a.currentAddrs.unknownAddrs[:0], currUnknownAddrs...),
270272
relayAddrs: append(a.currentAddrs.relayAddrs[:0], relayAddrs...),
271273
}
272274

@@ -275,6 +277,7 @@ func (a *addrsManager) updateAddrs(updateRelayAddrs bool, relayAddrs []ma.Multia
275277
addrs: currAddrs,
276278
reachableAddrs: currReachableAddrs,
277279
unreachableAddrs: currUnreachableAddrs,
280+
unknownAddrs: currUnknownAddrs,
278281
relayAddrs: relayAddrs,
279282
}
280283
}
@@ -303,11 +306,13 @@ func (a *addrsManager) notifyAddrsChanged(emitter event.Emitter, previous, curre
303306
// We must send these events in the same order. It'll be confusing for consumers
304307
// if the reachable event is received after the addr removed event.
305308
if areAddrsDifferent(previous.reachableAddrs, current.reachableAddrs) ||
306-
areAddrsDifferent(previous.unreachableAddrs, current.unreachableAddrs) {
309+
areAddrsDifferent(previous.unreachableAddrs, current.unreachableAddrs) ||
310+
areAddrsDifferent(previous.unknownAddrs, current.unknownAddrs) {
307311
log.Debugf("host reachable addrs updated: %s", current.localAddrs)
308312
if err := emitter.Emit(event.EvtHostReachableAddrsChanged{
309313
Reachable: slices.Clone(current.reachableAddrs),
310314
Unreachable: slices.Clone(current.unreachableAddrs),
315+
Unknown: slices.Clone(current.unknownAddrs),
311316
}); err != nil {
312317
log.Errorf("error sending host reachable addrs changed event: %s", err)
313318
}
@@ -365,16 +370,16 @@ func (a *addrsManager) DirectAddrs() []ma.Multiaddr {
365370
return slices.Clone(a.currentAddrs.localAddrs)
366371
}
367372

368-
// ReachableAddrs returns all addresses of the host that are reachable from the internet
369-
func (a *addrsManager) ReachableAddrs() []ma.Multiaddr {
373+
// ConfirmedAddrs returns all addresses of the host that are reachable from the internet
374+
func (a *addrsManager) ConfirmedAddrs() (reachable []ma.Multiaddr, unreachable []ma.Multiaddr, unknown []ma.Multiaddr) {
370375
a.addrsMx.RLock()
371376
defer a.addrsMx.RUnlock()
372-
return slices.Clone(a.currentAddrs.reachableAddrs)
377+
return slices.Clone(a.currentAddrs.reachableAddrs), slices.Clone(a.currentAddrs.unreachableAddrs), slices.Clone(a.currentAddrs.unknownAddrs)
373378
}
374379

375-
func (a *addrsManager) getConfirmedAddrs(localAddrs []ma.Multiaddr) (reachableAddrs, unreachableAddrs []ma.Multiaddr) {
376-
reachableAddrs, unreachableAddrs = a.addrsReachabilityTracker.ConfirmedAddrs()
377-
return removeNotInSource(reachableAddrs, localAddrs), removeNotInSource(unreachableAddrs, localAddrs)
380+
func (a *addrsManager) getConfirmedAddrs(localAddrs []ma.Multiaddr) (reachableAddrs, unreachableAddrs, unknownAddrs []ma.Multiaddr) {
381+
reachableAddrs, unreachableAddrs, unknownAddrs = a.addrsReachabilityTracker.ConfirmedAddrs()
382+
return removeNotInSource(reachableAddrs, localAddrs), removeNotInSource(unreachableAddrs, localAddrs), removeNotInSource(unknownAddrs, localAddrs)
378383
}
379384

380385
var p2pCircuitAddr = ma.StringCast("/p2p-circuit")

p2p/host/basic/addrs_manager_test.go

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -462,16 +462,34 @@ func TestAddrsManagerReachabilityEvent(t *testing.T) {
462462
},
463463
})
464464

465+
initialUnknownAddrs := []ma.Multiaddr{publicQUIC, publicTCP, publicQUIC2}
466+
467+
// First event: all addresses are initially unknown
468+
select {
469+
case e := <-sub.Out():
470+
evt := e.(event.EvtHostReachableAddrsChanged)
471+
require.Empty(t, evt.Reachable)
472+
require.Empty(t, evt.Unreachable)
473+
require.ElementsMatch(t, initialUnknownAddrs, evt.Unknown)
474+
case <-time.After(5 * time.Second):
475+
t.Fatal("expected initial event for reachability change")
476+
}
477+
478+
// Wait for probes to complete and addresses to be classified
465479
reachableAddrs := []ma.Multiaddr{publicQUIC}
466480
unreachableAddrs := []ma.Multiaddr{publicTCP, publicQUIC2}
467481
select {
468482
case e := <-sub.Out():
469483
evt := e.(event.EvtHostReachableAddrsChanged)
470484
require.ElementsMatch(t, reachableAddrs, evt.Reachable)
471485
require.ElementsMatch(t, unreachableAddrs, evt.Unreachable)
472-
require.ElementsMatch(t, reachableAddrs, am.ReachableAddrs())
486+
require.Empty(t, evt.Unknown)
487+
reachable, unreachable, unknown := am.ConfirmedAddrs()
488+
require.ElementsMatch(t, reachable, reachableAddrs)
489+
require.ElementsMatch(t, unreachable, unreachableAddrs)
490+
require.Empty(t, unknown)
473491
case <-time.After(5 * time.Second):
474-
t.Fatal("expected event for reachability change")
492+
t.Fatal("expected final event for reachability change after probing")
475493
}
476494
}
477495

p2p/host/basic/addrs_reachability_tracker.go

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ type addrsReachabilityTracker struct {
5454
mx sync.Mutex
5555
reachableAddrs []ma.Multiaddr
5656
unreachableAddrs []ma.Multiaddr
57+
unknownAddrs []ma.Multiaddr
5758
}
5859

5960
// newAddrsReachabilityTracker returns a new addrsReachabilityTracker.
@@ -83,10 +84,10 @@ func (r *addrsReachabilityTracker) UpdateAddrs(addrs []ma.Multiaddr) {
8384
}
8485
}
8586

86-
func (r *addrsReachabilityTracker) ConfirmedAddrs() (reachableAddrs, unreachableAddrs []ma.Multiaddr) {
87+
func (r *addrsReachabilityTracker) ConfirmedAddrs() (reachableAddrs, unreachableAddrs, unknownAddrs []ma.Multiaddr) {
8788
r.mx.Lock()
8889
defer r.mx.Unlock()
89-
return slices.Clone(r.reachableAddrs), slices.Clone(r.unreachableAddrs)
90+
return slices.Clone(r.reachableAddrs), slices.Clone(r.unreachableAddrs), slices.Clone(r.unknownAddrs)
9091
}
9192

9293
func (r *addrsReachabilityTracker) Start() error {
@@ -129,7 +130,7 @@ func (r *addrsReachabilityTracker) background() {
129130

130131
var task reachabilityTask
131132
var backoffInterval time.Duration
132-
var currReachable, currUnreachable, prevReachable, prevUnreachable []ma.Multiaddr
133+
var currReachable, currUnreachable, currUnknown, prevReachable, prevUnreachable, prevUnknown []ma.Multiaddr
133134
for {
134135
select {
135136
case <-probeTicker.C:
@@ -173,12 +174,13 @@ func (r *addrsReachabilityTracker) background() {
173174
return
174175
}
175176

176-
currReachable, currUnreachable = r.appendConfirmedAddrs(currReachable[:0], currUnreachable[:0])
177-
if areAddrsDifferent(prevReachable, currReachable) || areAddrsDifferent(prevUnreachable, currUnreachable) {
177+
currReachable, currUnreachable, currUnknown = r.appendConfirmedAddrs(currReachable[:0], currUnreachable[:0], currUnknown[:0])
178+
if areAddrsDifferent(prevReachable, currReachable) || areAddrsDifferent(prevUnreachable, currUnreachable) || areAddrsDifferent(prevUnknown, currUnknown) {
178179
r.notify()
179180
}
180181
prevReachable = append(prevReachable[:0], currReachable...)
181182
prevUnreachable = append(prevUnreachable[:0], currUnreachable...)
183+
prevUnknown = append(prevUnknown[:0], currUnknown...)
182184
if !nextProbeTime.IsZero() {
183185
probeTimer.Reset(nextProbeTime.Sub(r.clock.Now()))
184186
}
@@ -196,13 +198,14 @@ func newBackoffInterval(current time.Duration) time.Duration {
196198
return current
197199
}
198200

199-
func (r *addrsReachabilityTracker) appendConfirmedAddrs(reachable, unreachable []ma.Multiaddr) (reachableAddrs, unreachableAddrs []ma.Multiaddr) {
200-
reachable, unreachable = r.probeManager.AppendConfirmedAddrs(reachable, unreachable)
201+
func (r *addrsReachabilityTracker) appendConfirmedAddrs(reachable, unreachable, unknown []ma.Multiaddr) (reachableAddrs, unreachableAddrs, unknownAddrs []ma.Multiaddr) {
202+
reachable, unreachable, unknown = r.probeManager.AppendConfirmedAddrs(reachable, unreachable, unknown)
201203
r.mx.Lock()
202204
r.reachableAddrs = append(r.reachableAddrs[:0], reachable...)
203205
r.unreachableAddrs = append(r.unreachableAddrs[:0], unreachable...)
206+
r.unknownAddrs = append(r.unknownAddrs[:0], unknown...)
204207
r.mx.Unlock()
205-
return reachable, unreachable
208+
return reachable, unreachable, unknown
206209
}
207210

208211
func (r *addrsReachabilityTracker) notify() {
@@ -381,7 +384,7 @@ func newProbeManager(now func() time.Time) *probeManager {
381384
}
382385

383386
// AppendConfirmedAddrs appends the current confirmed reachable and unreachable addresses.
384-
func (m *probeManager) AppendConfirmedAddrs(reachable, unreachable []ma.Multiaddr) (reachableAddrs, unreachableAddrs []ma.Multiaddr) {
387+
func (m *probeManager) AppendConfirmedAddrs(reachable, unreachable, unknown []ma.Multiaddr) (reachableAddrs, unreachableAddrs, unknownAddrs []ma.Multiaddr) {
385388
m.mx.Lock()
386389
defer m.mx.Unlock()
387390

@@ -393,9 +396,11 @@ func (m *probeManager) AppendConfirmedAddrs(reachable, unreachable []ma.Multiadd
393396
reachable = append(reachable, a)
394397
case network.ReachabilityPrivate:
395398
unreachable = append(unreachable, a)
399+
case network.ReachabilityUnknown:
400+
unknown = append(unknown, a)
396401
}
397402
}
398-
return reachable, unreachable
403+
return reachable, unreachable, unknown
399404
}
400405

401406
// UpdateAddrs updates the tracked addrs

0 commit comments

Comments
 (0)