From: Dan Fuhry Date: Thu, 25 Apr 2024 04:05:07 +0000 (-0400) Subject: dns cache: fix message headers, populate edns udp size X-Git-Url: https://go.fuhry.dev/?a=commitdiff_plain;h=39feda1cdedf49196e605d11ea374f2e9bbd1844;p=runtime.git dns cache: fix message headers, populate edns udp size --- diff --git a/net/dns/dns_cache.go b/net/dns/dns_cache.go index 4a3a6fa..2cd3237 100644 --- a/net/dns/dns_cache.go +++ b/net/dns/dns_cache.go @@ -4,11 +4,14 @@ import ( "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 @@ -32,6 +35,7 @@ func ResolveDualStack(hostname string) (string, string, error) { 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 { @@ -66,10 +70,14 @@ func doDualStackQuery(hostname string) (*dns.Msg, error) { 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, }, @@ -101,16 +109,18 @@ func doDualStackQuery(hostname string) (*dns.Msg, error) { 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 { @@ -134,6 +144,7 @@ func newEDNSCookie() dns.RR { Hdr: dns.RR_Header{ Name: ".", Rrtype: dns.TypeOPT, + Class: 1232, }, Option: []dns.EDNS0{ &dns.EDNS0_COOKIE{ diff --git a/sase/happy_eyeballs.go b/sase/happy_eyeballs.go index 5ebd07e..4e87c2e 100644 --- a/sase/happy_eyeballs.go +++ b/sase/happy_eyeballs.go @@ -63,6 +63,10 @@ func dialHappyEyeballs(ctx context.Context, addrs []net.Addr, port uint16) (net. 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{}