Skip to content

delegatingresolver: avoid proxy for resolved addresses in NO_PROXY env #8329

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
May 23, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 32 additions & 17 deletions internal/resolver/delegatingresolver/delegatingresolver.go
Original file line number Diff line number Diff line change
@@ -186,30 +186,45 @@ func (r *delegatingResolver) Close() {
r.proxyResolver = nil
}

func networkTypeFromAddr(addr resolver.Address) string {
networkType, ok := networktype.Get(addr)
if !ok {
networkType, _ = transport.ParseDialTarget(addr.Addr)
}
return networkType
}

func isTCPAddressPresent(state *resolver.State) bool {
func needsProxyResolver(state *resolver.State) bool {
for _, addr := range state.Addresses {
if networkType := networkTypeFromAddr(addr); networkType == "tcp" {
if !skipProxy(addr) {
return true
}
}
for _, endpoint := range state.Endpoints {
for _, addr := range endpoint.Addresses {
if networktype := networkTypeFromAddr(addr); networktype == "tcp" {
if !skipProxy(addr) {
return true
}
}
}
return false
}

func skipProxy(address resolver.Address) bool {
// Avoid proxy when network is not tcp.
networkType, ok := networktype.Get(address)
if !ok {
networkType, _ = transport.ParseDialTarget(address.Addr)
}
if networkType != "tcp" {
return true
}

req := &http.Request{URL: &url.URL{
Scheme: "https",
Host: address.Addr,
}}
// Avoid proxy when address included in `NO_PROXY` environment variable or
// fails to get the proxy address.
url, err := HTTPSProxyFromEnvironment(req)
if err != nil || url == nil {
return true
}
return false
}

// updateClientConnStateLocked constructs a combined list of addresses by
// pairing each proxy address with every target address of type TCP. For each
// pair, it creates a new [resolver.Address] using the proxy address and
@@ -240,8 +255,7 @@ func (r *delegatingResolver) updateClientConnStateLocked() error {
}
var addresses []resolver.Address
for _, targetAddr := range (*r.targetResolverState).Addresses {
// Avoid proxy when network is not tcp.
if networkType := networkTypeFromAddr(targetAddr); networkType != "tcp" {
if skipProxy(targetAddr) {
addresses = append(addresses, targetAddr)
continue
}
@@ -259,7 +273,7 @@ func (r *delegatingResolver) updateClientConnStateLocked() error {
var addrs []resolver.Address
for _, targetAddr := range endpt.Addresses {
// Avoid proxy when network is not tcp.
if networkType := networkTypeFromAddr(targetAddr); networkType != "tcp" {
if skipProxy(targetAddr) {
addrs = append(addrs, targetAddr)
continue
}
@@ -340,9 +354,10 @@ func (r *delegatingResolver) updateTargetResolverState(state resolver.State) err
logger.Infof("Addresses received from target resolver: %v", state.Addresses)
}
r.targetResolverState = &state
// If no addresses returned by resolver have network type as tcp , do not
// wait for proxy update.
if !isTCPAddressPresent(r.targetResolverState) {
// If all addresses returned by the target resolver have a non-TCP network
// type, or are listed in the `NO_PROXY` environment variable, do not wait
// for proxy update.
if !needsProxyResolver(r.targetResolverState) {
return r.cc.UpdateState(*r.targetResolverState)
}

Loading
Oops, something went wrong.