net: fixes to dnsReadConfig in dnsconfig_windows.go

- Only search DNS servers for network interfaces with at least one gateway
- Clarify comment on deprecated site local anycast fec0/10 DNS IPv6 addresses
- Minor maintenance: skip not "up" interfaces earlier in outer loop

Change-Id: I98ca7b81d3d51e6aa6bfa4a10dcd651305a843df
GitHub-Last-Rev: 3b358c7e3f89971d069286f997dc19e092ec8f08
GitHub-Pull-Request: golang/go#64441
Reviewed-on: https://go-review.googlesource.com/c/go/+/545775
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
This commit is contained in:
Quentin McGaw 2023-11-29 21:44:34 +00:00 committed by Quim Muntal
parent c9ed561db4
commit d98b444839
3 changed files with 60 additions and 33 deletions

View File

@ -42,7 +42,10 @@ const (
ERROR_NO_UNICODE_TRANSLATION syscall.Errno = 1113
)
const GAA_FLAG_INCLUDE_PREFIX = 0x00000010
const (
GAA_FLAG_INCLUDE_PREFIX = 0x00000010
GAA_FLAG_INCLUDE_GATEWAYS = 0x0080
)
const (
IF_TYPE_OTHER = 1
@ -104,27 +107,45 @@ type IpAdapterPrefix struct {
PrefixLength uint32
}
type IpAdapterWinsServerAddress struct {
Length uint32
Reserved uint32
Next *IpAdapterWinsServerAddress
Address SocketAddress
}
type IpAdapterGatewayAddress struct {
Length uint32
Reserved uint32
Next *IpAdapterGatewayAddress
Address SocketAddress
}
type IpAdapterAddresses struct {
Length uint32
IfIndex uint32
Next *IpAdapterAddresses
AdapterName *byte
FirstUnicastAddress *IpAdapterUnicastAddress
FirstAnycastAddress *IpAdapterAnycastAddress
FirstMulticastAddress *IpAdapterMulticastAddress
FirstDnsServerAddress *IpAdapterDnsServerAdapter
DnsSuffix *uint16
Description *uint16
FriendlyName *uint16
PhysicalAddress [syscall.MAX_ADAPTER_ADDRESS_LENGTH]byte
PhysicalAddressLength uint32
Flags uint32
Mtu uint32
IfType uint32
OperStatus uint32
Ipv6IfIndex uint32
ZoneIndices [16]uint32
FirstPrefix *IpAdapterPrefix
Length uint32
IfIndex uint32
Next *IpAdapterAddresses
AdapterName *byte
FirstUnicastAddress *IpAdapterUnicastAddress
FirstAnycastAddress *IpAdapterAnycastAddress
FirstMulticastAddress *IpAdapterMulticastAddress
FirstDnsServerAddress *IpAdapterDnsServerAdapter
DnsSuffix *uint16
Description *uint16
FriendlyName *uint16
PhysicalAddress [syscall.MAX_ADAPTER_ADDRESS_LENGTH]byte
PhysicalAddressLength uint32
Flags uint32
Mtu uint32
IfType uint32
OperStatus uint32
Ipv6IfIndex uint32
ZoneIndices [16]uint32
FirstPrefix *IpAdapterPrefix
TransmitLinkSpeed uint64
ReceiveLinkSpeed uint64
FirstWinsServerAddress *IpAdapterWinsServerAddress
FirstGatewayAddress *IpAdapterGatewayAddress
/* more fields might be present here. */
}

View File

@ -25,16 +25,19 @@ func dnsReadConfig(ignoredFilename string) (conf *dnsConfig) {
if err != nil {
return
}
// TODO(bradfitz): this just collects all the DNS servers on all
// the interfaces in some random order. It should order it by
// default route, or only use the default route(s) instead.
// In practice, however, it mostly works.
for _, aa := range aas {
// Only take interfaces whose OperStatus is IfOperStatusUp(0x01) into DNS configs.
if aa.OperStatus != windows.IfOperStatusUp {
continue
}
// Only take interfaces which have at least one gateway
if aa.FirstGatewayAddress == nil {
continue
}
for dns := aa.FirstDnsServerAddress; dns != nil; dns = dns.Next {
// Only take interfaces whose OperStatus is IfOperStatusUp(0x01) into DNS configs.
if aa.OperStatus != windows.IfOperStatusUp {
continue
}
sa, err := dns.Address.Sockaddr.Sockaddr()
if err != nil {
continue
@ -47,9 +50,11 @@ func dnsReadConfig(ignoredFilename string) (conf *dnsConfig) {
ip = make(IP, IPv6len)
copy(ip, sa.Addr[:])
if ip[0] == 0xfe && ip[1] == 0xc0 {
// Ignore these fec0/10 ones. Windows seems to
// populate them as defaults on its misc rando
// interfaces.
// fec0/10 IPv6 addresses are site local anycast DNS
// addresses Microsoft sets by default if no other
// IPv6 DNS address is set. Site local anycast is
// deprecated since 2004, see
// https://datatracker.ietf.org/doc/html/rfc3879
continue
}
default:

View File

@ -20,7 +20,8 @@ func adapterAddresses() ([]*windows.IpAdapterAddresses, error) {
l := uint32(15000) // recommended initial size
for {
b = make([]byte, l)
err := windows.GetAdaptersAddresses(syscall.AF_UNSPEC, windows.GAA_FLAG_INCLUDE_PREFIX, 0, (*windows.IpAdapterAddresses)(unsafe.Pointer(&b[0])), &l)
const flags = windows.GAA_FLAG_INCLUDE_PREFIX | windows.GAA_FLAG_INCLUDE_GATEWAYS
err := windows.GetAdaptersAddresses(syscall.AF_UNSPEC, flags, 0, (*windows.IpAdapterAddresses)(unsafe.Pointer(&b[0])), &l)
if err == nil {
if l == 0 {
return nil, nil