SIGN IN SIGN UP

net/dns/resolver: reach netstack-only upstreams over UDP (#20786)

sendTCP dials through tsdial.Dialer and so honors UseNetstackForIP, but
sendUDP opened a host-stack socket via packetListener and never consulted
the dialer. In userspace networking mode (tsnet, or tailscaled
--tun=userspace-networking) there is no tun device, so a split-DNS query
to a tailnet resolver blackholed for the full udpRaceTimeout before the
TCP fallback answered it.

Add dialUDP, which picks between the netstack dialer and the existing
packetListener the same way tsdial.Dialer.dialOneUser does, and adapt the
connected netstack conn to nettype.PacketConn. sendUDP is otherwise
unchanged, so txid checks, SERVFAIL/REFUSED handling, TC flagging and EDNS
clamping are identical on both paths.

Unskips the UDP subtest of TestForwarderNetstackUpstream, which now
answers in ~300µs rather than 2s, and adds unit tests for the dispatch and
for truncation over the netstack path. TestSplitDNSToTailnetResolverUDP
covers the whole path end to end over real gVisor: two tsnet nodes with no
tun, one resolving a split-DNS name whose upstream is the other.

Fixes #20314

Signed-off-by: Brendan Creane <bcreane@gmail.com>
B
Brendan Creane committed
e1e5325c22a46a9df2e76d725f01f92065885138
Parent: e592a0c
Committed by GitHub <noreply@github.com> on 8/9/2026, 4:01:45 PM