diff --git a/net/interfaces/interfaces_windows.go b/net/interfaces/interfaces_windows.go index 6a8052389..c7d0f88c6 100644 --- a/net/interfaces/interfaces_windows.go +++ b/net/interfaces/interfaces_windows.go @@ -168,16 +168,25 @@ const ( func getPACWindows() string { var res *uint16 - r, _, err := detectAutoProxyConfigURL.Call( + r, _, e := detectAutoProxyConfigURL.Call( winHTTP_AUTO_DETECT_TYPE_DHCP|winHTTP_AUTO_DETECT_TYPE_DNS_A, uintptr(unsafe.Pointer(&res)), ) - var got string - if res != nil { - got = windows.UTF16PtrToString(res) - globalFree.Call(uintptr(unsafe.Pointer(res))) - } else { - log.Printf("getPACWindows: r=%v, err=%#v", r, err) + if r == 1 { + if res == nil { + log.Printf("getPACWindows: unexpected success with nil result") + return "" + } + defer globalFree.Call(uintptr(unsafe.Pointer(res))) + return windows.UTF16PtrToString(res) } - return got + const ( + ERROR_WINHTTP_AUTODETECTION_FAILED = 12180 + ) + if e == syscall.Errno(ERROR_WINHTTP_AUTODETECTION_FAILED) { + // Common case on networks without advertised PAC. + return "" + } + log.Printf("getPACWindows: %T=%v", e, e) // syscall.Errno=0x.... + return "" } diff --git a/net/interfaces/interfaces_windows_test.go b/net/interfaces/interfaces_windows_test.go new file mode 100644 index 000000000..8eaf26bd6 --- /dev/null +++ b/net/interfaces/interfaces_windows_test.go @@ -0,0 +1,17 @@ +// Copyright (c) 2020 Tailscale Inc & AUTHORS All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package interfaces + +import "testing" + +func BenchmarkGetPACWindows(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + v := getPACWindows() + if i == 0 { + b.Logf("Got: %q", v) + } + } +}