Go: net: add Resolver.Dial hook to allow specifying source address, etc

Created on 11 Oct 2016  路  12Comments  路  Source: golang/go

If use custome LocalAddr in Dialer, the localaddr changed,but the remoteaddr according to dns resolve is not changed.
For example: two different ip IpA and IpB belongs to different isp in my computer. DomainC is what i want to send request to. So i use custome Dialer to choose which ip i want to use as my localaddr. Linux dig tool can resolve different ip use -b option sets the source IP address to IpA or IpB of the query. But in golang the ip resolved is the same. I use httptrace to find localaddr changed but remote ip is the same.

FrozenDueToAge NeedsInvestigation help wanted

Most helpful comment

This seems like a reasonable request. Or something in the new Resolver type.

All 12 comments

I'm afraid this is not how any resolver library actually works. dig is very special in that it is a debugging tool that sends DNS requests itself.

You'll need to explicitly send DNS requests yourself if you want to have this behavior. Perhaps using a library like https://godoc.org/github.com/miekg/dns

This is a reasonable request,i use ip of ispA, why the resolver resolve ip belongs to ispB ?

        // LocalAddr is the local address to use when dialing an
        // address. The address must be of a compatible type for the
        // network being dialed.
        // If nil, a local address is automatically chosen.
        LocalAddr Addr

Perharps it should do every net request using LocalAddr, including dns query.

This seems like a reasonable request. Or something in the new Resolver type.

/cc @mikioh

I think it's reasonable to support this feature because unlike conventional DNS APIs we can provide both DNS RR exchange control and DNS transport control through the combination of Dialer and Resolver structs. If there is a reason to hesitate to do this it must be overkill, but nowadays we see the complicated circumstances; multiple IP links/interfaces, two IP address spaces. Probably just following the existing APIs/behaviors wouldn't be much help for the circumstances.

I'm working on this - specifically I'm working on a way to configure the Dialer that a Resolver will use for to make its connections. Note that this can only work when the go (not cgo) resolver is used, and that's not available on some platforms.

CL https://golang.org/cl/37260 mentions this issue.

@Tevic, can you clarify your situation? What platform are you on, and what does your DNS configuration look like (/etc/resolv.conf)? When you look up domainC on ispA (using dig), do you get an IP address back? What about on ispB? If both lookups succeed, do you get the same or different IP addresses?

A domain set two A Records : ispA->ipA, ispB->ipB
A Server with 2 IPs: ip1(belongs ispA), ip2(belongs ispB). Default route is ip1.
Golang Behavior: Set LocalAddr: ip1,RemoteAddr get ipA. Set LocalAddr: ip2,RemoteAddr still get ipA.
Expected Behavior: Set LocalAddr: ip1,RemoteAddr get ipA. Set LocalAddr: ip2,RemoteAddr still get ipB.
Using dig's -b option get the expected behavior.

@Tevic, please understand that what you are asking for is very unusual behavior. DNS is not designed to work the way you are requesting. We are working on a way to allow you to get that behavior, but I don't think we can make it the default. You would need to create a Dialer, set a custom Resolver in that Dialer, and use that Dialer to make your connection. As long as you own the code doing the dialing, that should work out OK.

Yes,you're right. Thanks for your working on custom resolver. Previous golang has no resolver option.

Was this page helpful?
0 / 5 - 0 ratings