[client] Warm the stdnet interface cache at construction

Moving discovery to first use regressed the privileged suites on the three
platforms that always build an ICE bind: Darwin, FreeBSD and Windows time out
in TestWGIface_UpdateAddr, TestRecreation, TestEngine_SSH and
TestEngine_MultiplePeers, while Linux stays green because a host with the
WireGuard kernel module takes the kernel-device branch and never drives the
mux that asks for interfaces.

interfaceFilter probes with wgctrl every interface the disallow list does not
already exclude. Discovering at construction ran that probe before the caller
had an overlay interface of its own; discovering at first use runs it after,
so on a userspace WireGuard platform the probe reaches the UAPI socket of the
same process. The tests reach it because they construct with a nil disallow
list, where the client passes DefaultInterfaceBlacklist and its own interface
is excluded by prefix.

Restore the original timing with an explicit warm-up. The constructors stay
infallible and the error is still reported by the accessor that needs the
interfaces, so the contract this branch is about is unchanged.
This commit is contained in:
riccardom
2026-10-02 12:53:13 +02:00
parent 8204e15393
commit 947e25288f
+14 -1
View File
@@ -60,6 +60,7 @@ func NewNetWithDiscover(ctx context.Context, iFaceDiscover ExternalIFaceDiscover
} else {
n.iFaceDiscover = newMobileIFaceDiscover(iFaceDiscover)
}
n.warmCache()
return n
}
@@ -68,11 +69,23 @@ func NewNet(ctx context.Context, disallowList []string) *Net {
if ctx == nil {
ctx = context.Background()
}
return &Net{
n := &Net{
iFaceDiscover: pionDiscover{},
interfaceFilter: InterfaceFilter(disallowList),
ctx: ctx,
}
n.warmCache()
return n
}
// warmCache performs the first discovery while the caller is still setting up,
// before an overlay interface of its own exists. interfaceFilter probes every
// interface it is not told to skip with wgctrl, and on a userspace WireGuard
// platform that probe reaches the UAPI socket of this same process, so running
// it later means asking our own device about itself. The result is discarded:
// a failure here is reported by the accessor that needs the interfaces.
func (n *Net) warmCache() {
_, _ = n.Interfaces()
}
// resolveAddr performs DNS resolution with context support and timeout.