"context"
"fmt"
"math/rand"
+ "net"
"sync"
"time"
lru "github.com/hashicorp/golang-lru"
"github.com/miekg/dns"
+
+ "go.fuhry.dev/runtime/utils/log"
)
var dnsCache *lru.Cache
if msg, ok = entry.(*dns.Msg); !ok {
return "", "", fmt.Errorf("lru cache is corrupt: expected entry to be *dns.Msg, got %T", entry)
}
+ log.V(3).Debugf("cache hit for hostname %q: %+v", hostname, entry)
} else {
msg, err = doDualStackQuery(hostname)
if err != nil {
return nil, err
}
+ log.V(3).Debugf("cache miss, attempting dualstack dns query for hostname: %q", hostname)
+ log.V(3).Debugf("will resolve using DNS servers: %+v", cc.Servers)
for _, qtype := range []uint16{dns.TypeA, dns.TypeAAAA} {
query := &dns.Msg{
MsgHdr: dns.MsgHdr{
Id: dns.Id(),
+ Opcode: dns.OpcodeQuery,
+ Response: false,
RecursionDesired: true,
AuthenticatedData: true,
},
defer cancel()
for _, server := range cc.Servers {
- go (func() {
- m, _, err := client.Exchange(query, server+":53")
+ go (func(server string) {
+ start := time.Now()
+ m, _, err := client.Exchange(query, net.JoinHostPort(server, "53"))
if m != nil && err == nil {
mu.Lock()
defer mu.Unlock()
if !done {
+ log.V(2).Infof("resolved name %q to %v via DNS server %s in %s", hostname, m.Answer, server, time.Since(start))
resultChan <- m
}
}
- })()
+ })(server)
}
select {
Hdr: dns.RR_Header{
Name: ".",
Rrtype: dns.TypeOPT,
+ Class: 1232,
},
Option: []dns.EDNS0{
&dns.EDNS0_COOKIE{
return nil, fmt.Errorf("cannot dial happy eyeballs connection: at least one address family must be enabled")
}
+ if len(addrs) < 1 {
+ return nil, fmt.Errorf("error dialing: no address associated with hostname")
+ }
+
logger.V(2).Debugf("ipv4: %t / ipv6: %t", ipv4Enable, ipv6Enable)
dialer := &net.Dialer{}