Skip to content

Commit 585248e

Browse files
committed
net/dnscache: fix case where Resolver could return zero IP with single IPv6 address
The controlhttp dialer with a ControlDialPlan IPv6 entry was hitting a case where the dnscache Resolver was returning an netip.Addr zero value, where it should've been returning the IPv6 address. We then tried to dial "invalid IP:80", which would immediately fail, at least locally. Mostly this was causing spammy logs when debugging other stuff. Updates tailscale/corp#32534 Change-Id: If8b9a20f10c1a6aa8a662c324151d987fe9bd2f8 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com> (cherry picked from commit 1b6bc37)
1 parent a5e69bc commit 585248e

File tree

2 files changed

+61
-0
lines changed

2 files changed

+61
-0
lines changed

net/dnscache/dnscache.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,9 @@ func (r *Resolver) LookupIP(ctx context.Context, host string) (ip, v6 netip.Addr
205205
}
206206
allIPs = append(allIPs, naIP)
207207
}
208+
if !ip.IsValid() && v6.IsValid() {
209+
ip = v6
210+
}
208211
r.dlogf("returning %d static results", len(allIPs))
209212
return
210213
}

net/dnscache/dnscache_test.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"net"
1212
"net/netip"
1313
"reflect"
14+
"slices"
1415
"testing"
1516
"time"
1617

@@ -240,3 +241,60 @@ func TestShouldTryBootstrap(t *testing.T) {
240241
})
241242
}
242243
}
244+
245+
func TestSingleHostStaticResult(t *testing.T) {
246+
v4 := netip.MustParseAddr("0.0.0.1")
247+
v6 := netip.MustParseAddr("2001::a")
248+
249+
tests := []struct {
250+
name string
251+
static []netip.Addr
252+
wantIP netip.Addr
253+
wantIP6 netip.Addr
254+
wantAll []netip.Addr
255+
}{
256+
{
257+
name: "just-v6",
258+
static: []netip.Addr{v6},
259+
wantIP: v6,
260+
wantIP6: v6,
261+
wantAll: []netip.Addr{v6},
262+
},
263+
{
264+
name: "just-v4",
265+
static: []netip.Addr{v4},
266+
wantIP: v4,
267+
wantIP6: netip.Addr{},
268+
wantAll: []netip.Addr{v4},
269+
},
270+
{
271+
name: "v6-then-v4",
272+
static: []netip.Addr{v6, v4},
273+
wantIP: v4,
274+
wantIP6: v6,
275+
wantAll: []netip.Addr{v6, v4},
276+
},
277+
}
278+
279+
for _, tt := range tests {
280+
t.Run(tt.name, func(t *testing.T) {
281+
r := &Resolver{
282+
SingleHost: "example.com",
283+
SingleHostStaticResult: tt.static,
284+
}
285+
ip, ip6, all, err := r.LookupIP(context.Background(), "example.com")
286+
if err != nil {
287+
t.Fatal(err)
288+
}
289+
if ip != tt.wantIP {
290+
t.Errorf("got ip %v; want %v", ip, tt.wantIP)
291+
}
292+
if ip6 != tt.wantIP6 {
293+
t.Errorf("got ip6 %v; want %v", ip6, tt.wantIP6)
294+
}
295+
if !slices.Equal(all, tt.wantAll) {
296+
t.Errorf("got all %v; want %v", all, tt.wantAll)
297+
}
298+
})
299+
}
300+
}

0 commit comments

Comments
 (0)