-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Description
I mentioned in #12476 that I would like to detect the time it took for DNS resolution phase of the Dial process in Dialer.Dial
. The solution posted there was very hacky and adds unnecessarily to the API.
@bradfitz suggested
Perhaps
net.Dialer
could have an optionalResolver
, akin to howhttp.Client
has an optionalTransport
, orhttp.Server
has an optionalErrorLog
, etc.
This seems like an excellent idea. Here is how I propose we go about it by adding minimal complexity and preserving code compatibility.
I propose net package adds a new Resolver
interface.
type Resolver interface {
Resolve(host string, deadline time.Time) (addrs []IPAddr, err error)
}
The signature of Resolver.Resolve
is same as lookupIPDeadline
which Dial
eventually uses. Dialer
gets an optional field CustomResolver
of type Resolver
.
The Resolver
object (or nil
) gets passed around thru the resolution process.
Dialer.Dial
-> resolveAddrList
-> internetAddrList
.
internetAddrList
currently always uses lookupIPDeadline
, it would need to be changed such that if the passed custom resolver is not nil then use it, otherwise use lookupIPDeadline
.
Other functions calling resolveAddrList
or internetAddrList
would need to be modified to add an extra nil
argument . This does not break code compatibility because they are unexported functions.
Benefits of allowing a custom Resolver
- Allowing me to collect timing information as mentioned in net: I would like Dialer.Dial to provide the time it took to do DNS lookups and TCP Connect #12476
- Allowing users to implement their own DNS logic. Failovers, etc.
- Mocking for tests.
- Client side caching, pre-fetching, etc.
- In time, other packages ( like the superb github.com/miekg/dns ) could provide their own
Resolver
implementations. - Great for people like me who rely on Go to write network debugging tools.