net/netcheck: test for OS IPv6 support as well as connectivity.

This lets us distinguish "no IPv6 because the device's ISP doesn't
offer IPv6" from "IPv6 is unavailable/disabled in the OS".

Signed-off-by: David Anderson <danderson@tailscale.com>
This commit is contained in:
David Anderson
2022-07-18 16:56:10 -07:00
committed by Dave Anderson
parent 4c0feba38e
commit c1cb3efbba
7 changed files with 26 additions and 3 deletions

View File

@@ -76,6 +76,7 @@ type Report struct {
IPv4 bool // an IPv4 STUN round trip completed
IPv6CanSend bool // an IPv6 packet was able to be sent
IPv4CanSend bool // an IPv4 packet was able to be sent
OSHasIPv6 bool // could bind a socket to ::1
// MappingVariesByDestIP is whether STUN results depend which
// STUN server you're talking to (on IPv4).
@@ -806,6 +807,14 @@ func (c *Client) GetReport(ctx context.Context, dm *tailcfg.DERPMap) (_ *Report,
return nil, err
}
// See if IPv6 works at all, or if it's been hard disabled at the
// OS level.
v6udp, err := netns.Listener(c.logf).ListenPacket(ctx, "udp6", "[::1]:0")
if err == nil {
rs.report.OSHasIPv6 = true
v6udp.Close()
}
// Create a UDP4 socket used for sending to our discovered IPv4 address.
rs.pc4Hair, err = netns.Listener(c.logf).ListenPacket(ctx, "udp4", ":0")
if err != nil {

View File

@@ -111,6 +111,9 @@ func TestWorksWhenUDPBlocked(t *testing.T) {
// That's not relevant to this test, so just accept what we're
// given.
want.IPv4CanSend = r.IPv4CanSend
// OS IPv6 test is irrelevant here, accept whatever the current
// machine has.
want.OSHasIPv6 = r.OSHasIPv6
if !reflect.DeepEqual(r, want) {
t.Errorf("mismatch\n got: %+v\nwant: %+v\n", r, want)