dialer := &net.Dialer{
Timeout: dialTimeout,
KeepAlive: keepAliveTimeout,
}
transport := &http.Transport{
Proxy: http.ProxyFromEnvironment,
ForceAttemptHTTP2: false,
DialContext: func(ctx context.Context, network string, addr string) (net.Conn, error) {
ipv4, err := resolveIPv4(addr)
if err != nil {
return nil, err
}
return dialer.DialContext(ctx, network, ipv4)
},
}
httpClient := &http.Client{
Transport: transport,
Timeout: args.HTTPTimeout,
}
// resolveIPv4 resolves an address to IPv4 address.
func resolveIPv4(addr string) (string, error) {
url := strings.Split(addr, ":")
m := new(dns.Msg)
m.SetQuestion(dns.Fqdn(url[0]), dns.TypeA)
m.RecursionDesired = true
config, _ := dns.ClientConfigFromFile("/etc/resolv.conf")
c := new(dns.Client)
r, _, err := c.Exchange(m, net.JoinHostPort(config.Servers[0], config.Port))
if err != nil {
return "", err
}
for _, ans := range r.Answer {
if a, ok := ans.(*dns.A); ok {
url[0] = a.A.String()
}
}
return strings.Join(url, ":"), nil
}