]> go.fuhry.dev Git - runtime.git/commitdiff
dns cache: fix message headers, populate edns udp size
authorDan Fuhry <dan@fuhry.com>
Thu, 25 Apr 2024 04:05:07 +0000 (00:05 -0400)
committerDan Fuhry <dan@fuhry.com>
Thu, 25 Apr 2024 04:05:07 +0000 (00:05 -0400)
net/dns/dns_cache.go
sase/happy_eyeballs.go

index 4a3a6faa76909bed5c95e13b7c84daefa2db9d10..2cd32377b5712523be3570236229713847be8018 100644 (file)
@@ -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{
index 5ebd07e8c919b38697027a3e3b625622df6be355..4e87c2e7c614c357e49e408ea73df9158fbac16c 100644 (file)
@@ -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{}