mirror of
https://github.com/tailscale/tailscale.git
synced 2025-08-14 23:17:29 +00:00
net/tshttpproxy: fix WDAP/PAC proxy detection on Win10 1607 and earlier
Using WINHTTP_AUTOPROXY_ALLOW_AUTOCONFIG on Windows versions older than Windows 10 1703 (build 15063) is not supported and causes WinHttpGetProxyForUrl to fail with ERROR_INVALID_PARAMETER. This results in failures reaching the control on environments where a proxy is required. We use wingoes version detection to conditionally set the WINHTTP_AUTOPROXY_ALLOW_AUTOCONFIG flag on Windows builds greater than 15063. While there, we also update proxy detection to use WINHTTP_AUTO_DETECT_TYPE_DNS_A, as DNS-based proxy discovery might be required with Active Directory and in certain other environments. Updates tailscale/corp#29168 Fixes #879 Signed-off-by: Nick Khyl <nickk@tailscale.com>
This commit is contained in:
@@ -18,6 +18,7 @@ import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/alexbrainman/sspi/negotiate"
|
||||
"github.com/dblohm7/wingoes"
|
||||
"golang.org/x/sys/windows"
|
||||
"tailscale.com/hostinfo"
|
||||
"tailscale.com/syncs"
|
||||
@@ -97,9 +98,7 @@ func proxyFromWinHTTPOrCache(req *http.Request) (*url.URL, error) {
|
||||
}
|
||||
if err == windows.ERROR_INVALID_PARAMETER {
|
||||
metricErrInvalidParameters.Add(1)
|
||||
// Seen on Windows 8.1. (https://github.com/tailscale/tailscale/issues/879)
|
||||
// TODO(bradfitz): figure this out.
|
||||
setNoProxyUntil(time.Hour)
|
||||
setNoProxyUntil(10 * time.Second)
|
||||
proxyErrorf("tshttpproxy: winhttp: GetProxyForURL(%q): ERROR_INVALID_PARAMETER [unexpected]", urlStr)
|
||||
return nil, nil
|
||||
}
|
||||
@@ -238,17 +237,30 @@ func (pi *winHTTPProxyInfo) free() {
|
||||
}
|
||||
}
|
||||
|
||||
var proxyForURLOpts = &winHTTPAutoProxyOptions{
|
||||
DwFlags: winHTTP_AUTOPROXY_ALLOW_AUTOCONFIG | winHTTP_AUTOPROXY_AUTO_DETECT,
|
||||
DwAutoDetectFlags: winHTTP_AUTO_DETECT_TYPE_DHCP, // | winHTTP_AUTO_DETECT_TYPE_DNS_A,
|
||||
}
|
||||
var getProxyForURLOpts = sync.OnceValue(func() *winHTTPAutoProxyOptions {
|
||||
opts := &winHTTPAutoProxyOptions{
|
||||
DwFlags: winHTTP_AUTOPROXY_AUTO_DETECT,
|
||||
DwAutoDetectFlags: winHTTP_AUTO_DETECT_TYPE_DHCP | winHTTP_AUTO_DETECT_TYPE_DNS_A,
|
||||
}
|
||||
// Support for the WINHTTP_AUTOPROXY_ALLOW_AUTOCONFIG flag was added in Windows 10, version 1703.
|
||||
//
|
||||
// Using it on earlier versions causes GetProxyForURL to fail with ERROR_INVALID_PARAMETER,
|
||||
// which prevents proxy detection and can lead to failures reaching the control server
|
||||
// on environments where a proxy is required.
|
||||
//
|
||||
// https://web.archive.org/web/20250529044903/https://learn.microsoft.com/en-us/windows/win32/api/winhttp/ns-winhttp-winhttp_autoproxy_options
|
||||
if wingoes.IsWin10BuildOrGreater(wingoes.Win10Build1703) {
|
||||
opts.DwFlags |= winHTTP_AUTOPROXY_ALLOW_AUTOCONFIG
|
||||
}
|
||||
return opts
|
||||
})
|
||||
|
||||
func (hi winHTTPInternet) GetProxyForURL(urlStr string) (string, error) {
|
||||
var out winHTTPProxyInfo
|
||||
err := winHTTPGetProxyForURL(
|
||||
hi,
|
||||
windows.StringToUTF16Ptr(urlStr),
|
||||
proxyForURLOpts,
|
||||
getProxyForURLOpts(),
|
||||
&out,
|
||||
)
|
||||
if err != nil {
|
||||
|
Reference in New Issue
Block a user