This commit is contained in:
2026-02-19 10:07:43 +00:00
parent 007438e372
commit 6e637ecf77
1763 changed files with 60820 additions and 279516 deletions

View File

@@ -7,6 +7,7 @@ package tshttpproxy
import (
"context"
"errors"
"fmt"
"log"
"net"
@@ -38,6 +39,23 @@ var (
proxyFunc func(*url.URL) (*url.URL, error)
)
// SetProxyFunc can be used by clients to set a platform-specific function for proxy resolution.
// If config is set when this function is called, an error will be returned.
// The provided function should return a proxy URL for the given request URL,
// nil if no proxy is enabled for the request URL, or an error if proxy settings cannot be resolved.
func SetProxyFunc(fn func(*url.URL) (*url.URL, error)) error {
mu.Lock()
defer mu.Unlock()
// Allow override only if config is not set
if config != nil {
return errors.New("tshttpproxy: SetProxyFunc can only be called when config is not set")
}
proxyFunc = fn
return nil
}
func getProxyFunc() func(*url.URL) (*url.URL, error) {
// Create config/proxyFunc if it's not created
mu.Lock()

View File

@@ -9,6 +9,7 @@ import (
"net/http"
"net/url"
"tailscale.com/feature/buildfeatures"
"tailscale.com/version/distro"
)
@@ -17,7 +18,7 @@ func init() {
}
func linuxSysProxyFromEnv(req *http.Request) (*url.URL, error) {
if distro.Get() == distro.Synology {
if buildfeatures.HasSynology && distro.Get() == distro.Synology {
return synologyProxyFromConfigCached(req)
}
return nil, nil

View File

@@ -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 {

View File

@@ -48,7 +48,7 @@ var (
)
func globalFree(hglobal winHGlobal) (err error) {
r1, _, e1 := syscall.Syscall(procGlobalFree.Addr(), 1, uintptr(hglobal), 0, 0)
r1, _, e1 := syscall.SyscallN(procGlobalFree.Addr(), uintptr(hglobal))
if r1 == 0 {
err = errnoErr(e1)
}
@@ -56,7 +56,7 @@ func globalFree(hglobal winHGlobal) (err error) {
}
func winHTTPCloseHandle(whi winHTTPInternet) (err error) {
r1, _, e1 := syscall.Syscall(procWinHttpCloseHandle.Addr(), 1, uintptr(whi), 0, 0)
r1, _, e1 := syscall.SyscallN(procWinHttpCloseHandle.Addr(), uintptr(whi))
if r1 == 0 {
err = errnoErr(e1)
}
@@ -64,7 +64,7 @@ func winHTTPCloseHandle(whi winHTTPInternet) (err error) {
}
func winHTTPGetProxyForURL(whi winHTTPInternet, url *uint16, options *winHTTPAutoProxyOptions, proxyInfo *winHTTPProxyInfo) (err error) {
r1, _, e1 := syscall.Syscall6(procWinHttpGetProxyForUrl.Addr(), 4, uintptr(whi), uintptr(unsafe.Pointer(url)), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(proxyInfo)), 0, 0)
r1, _, e1 := syscall.SyscallN(procWinHttpGetProxyForUrl.Addr(), uintptr(whi), uintptr(unsafe.Pointer(url)), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(proxyInfo)))
if r1 == 0 {
err = errnoErr(e1)
}
@@ -72,7 +72,7 @@ func winHTTPGetProxyForURL(whi winHTTPInternet, url *uint16, options *winHTTPAut
}
func winHTTPOpen(agent *uint16, accessType uint32, proxy *uint16, proxyBypass *uint16, flags uint32) (whi winHTTPInternet, err error) {
r0, _, e1 := syscall.Syscall6(procWinHttpOpen.Addr(), 5, uintptr(unsafe.Pointer(agent)), uintptr(accessType), uintptr(unsafe.Pointer(proxy)), uintptr(unsafe.Pointer(proxyBypass)), uintptr(flags), 0)
r0, _, e1 := syscall.SyscallN(procWinHttpOpen.Addr(), uintptr(unsafe.Pointer(agent)), uintptr(accessType), uintptr(unsafe.Pointer(proxy)), uintptr(unsafe.Pointer(proxyBypass)), uintptr(flags))
whi = winHTTPInternet(r0)
if whi == 0 {
err = errnoErr(e1)