Skip to content
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

internal/delegatingresolver: avoid proxy if networktype of target address is not tcp #8215

Open
wants to merge 10 commits into
base: master
Choose a base branch
from

Conversation

eshitachandwani
Copy link
Member

@eshitachandwani eshitachandwani commented Apr 2, 2025

Fixes: #8207

RELEASE NOTES:

  • Proxy connections are no longer attempted for targets with non-TCP network types.

@eshitachandwani eshitachandwani added this to the 1.72 Release milestone Apr 2, 2025
@eshitachandwani eshitachandwani added the Area: Resolvers/Balancers Includes LB policy & NR APIs, resolver/balancer/picker wrappers, LB policy impls and utilities. label Apr 2, 2025
Copy link

codecov bot commented Apr 2, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 82.17%. Comparing base (5edab9e) to head (607ec91).
Report is 6 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #8215      +/-   ##
==========================================
- Coverage   82.17%   82.17%   -0.01%     
==========================================
  Files         410      410              
  Lines       40236    40405     +169     
==========================================
+ Hits        33065    33203     +138     
- Misses       5822     5842      +20     
- Partials     1349     1360      +11     
Files with missing lines Coverage Δ
.../resolver/delegatingresolver/delegatingresolver.go 83.67% <100.00%> (+1.45%) ⬆️

... and 35 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment on lines 208 to 212
if len(curState.Endpoints) != 0 {
networkType, ok = networktype.Get(curState.Endpoints[0].Addresses[0])
} else {
networkType, ok = networktype.Get(curState.Addresses[0])
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we're making an assumption that the network type of the first address of the endpoint is the same the address type of all remaining addresses. This may be true for most real-world usecases, but it isn't a requirement specified in the resolver API. It should not be too difficult to avoid proxying on a per-address basis. There are two places below where we do the following, one for resolver.State.Addresses and once for resolver.State.Endpoints:

proxyattributes.Set(proxyAddr, proxyattributes.Options{
	User:        r.proxyURL.User,
	ConnectAddr: targetAddr.Addr,
})

We can refactor this into a method that takes in the target address and proxy address and returns the combined address.

fn (r *delegatingResolver) combineAddresses(targetAddr, proxyAddr resolver.Address) resolver.Address {
    if  networktype.Get(targetAddr) != "tcp" {
        return targetAddr
    }
    return proxyattributes.Set(proxyAddr, proxyattributes.Options{
	User:        r.proxyURL.User,
	ConnectAddr: targetAddr.Addr,
    })
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The above comment end up adding duplicate addresses in the loop on targetResolverState.Endpoints. We will probably need to invert the loop on r.proxyAddrs and endpt.Addresses and break early:

for _, endpt := range (*r.targetResolverState).Endpoints {
	var addrs []resolver.Address
	for _, targetAddr := range endpt.Addresses {
                 if  networktype.Get(targetAddr) != "tcp" {
                          addrs = append(addrs, targetAddr)
                          continue
                  }
                  for _, proxyAddr := range r.proxyAddrs { 
			addrs = append(addrs, proxyattributes.Set(proxyAddr, proxyattributes.Options{
				User:        r.proxyURL.User,
				ConnectAddr: targetAddr.Addr,
			}))
		}
	}
	endpoints = append(endpoints, resolver.Endpoint{Addresses: addrs})
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, done ! Also added a check in beginning , if there is not address with network type TCP , we do not wait for proxy update and just update the cc state.

@arjan-bal
Copy link
Contributor

Please also fix the format of the release notes.

Comment on lines +208 to +211
if networkType, ok := networktype.Get(addr); !ok || networkType == "tcp" {
isTCP = true
break
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out here we're assuming !ok to be the same of tcp. However, the old code in the dialer used to parse the address string when !ok to determine the network type, we should probably maintain the same behaviour.

if !ok {
networkType, address = parseDialTarget(address)
}
if networkType == "tcp" && useProxy {
return proxyDial(ctx, address, grpcUA)
}

Comment on lines +216 to +219
if networkType, ok := networktype.Get(addr); !ok || networkType == "tcp" || isTCP {
isTCP = true
break
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the code will be simpler if we refactor finding a TCP address in a helper function. The helper function can return early instead of keeping track of a isTCP boolean and breaking out of nested loops.

Comment on lines +252 to +257
} else {
addresses = append(addresses, proxyattributes.Set(proxyAddr, proxyattributes.Options{
User: r.proxyURL.User,
ConnectAddr: targetAddr.Addr,
}))
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: You can use continue in the if block to avoid indenting the else block.

Comment on lines +274 to 281
} else {
for _, proxyAddr := range r.proxyAddrs {
addrs = append(addrs, proxyattributes.Set(proxyAddr, proxyattributes.Options{
User: r.proxyURL.User,
ConnectAddr: targetAddr.Addr,
}))
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: You can use continue in the if block to avoid indenting the else block.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: Resolvers/Balancers Includes LB policy & NR APIs, resolver/balancer/picker wrappers, LB policy impls and utilities. Type: Bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

grpc.Dial fails to connect to unix domain socket when https_proxy is set
2 participants