summaryrefslogtreecommitdiff
path: root/internal/resolver/resolver_test.go
diff options
context:
space:
mode:
authorradhitya <alif@radhitya.org>2026-06-18 12:42:29 +0700
committerradhitya <alif@radhitya.org>2026-06-18 12:42:29 +0700
commitf5753c6a8cac5a57a042b0388f38abeff5d1f37d (patch)
tree96e1241126b23051725edb68a79c8e4603d7e23a /internal/resolver/resolver_test.go
parente05835493f821055e517a3988c6f9256abbc5c24 (diff)
migration to new dns library
Diffstat (limited to 'internal/resolver/resolver_test.go')
-rw-r--r--internal/resolver/resolver_test.go150
1 files changed, 103 insertions, 47 deletions
diff --git a/internal/resolver/resolver_test.go b/internal/resolver/resolver_test.go
index 0bd0402..54f727e 100644
--- a/internal/resolver/resolver_test.go
+++ b/internal/resolver/resolver_test.go
@@ -2,54 +2,53 @@ package resolver
import (
"context"
- "net"
+ "io"
+ "net/netip"
"testing"
"time"
- "github.com/miekg/dns"
+ "codeberg.org/miekg/dns"
+ "codeberg.org/miekg/dns/dnsutil"
+ "codeberg.org/miekg/dns/rdata"
)
func startTestServer(t *testing.T, addr string, handler dns.Handler) *dns.Server {
t.Helper()
+ ready := make(chan struct{})
srv := &dns.Server{
Addr: addr,
Net: "udp",
Handler: handler,
UDPSize: 4096,
+ NotifyStartedFunc: func(ctx context.Context) {
+ close(ready)
+ },
}
go func() {
- if err := srv.ListenAndServe(); err != nil {
- }
+ _ = srv.ListenAndServe()
}()
+ <-ready
return srv
}
func TestLookupDirectAnswer(t *testing.T) {
- mux := dns.NewServeMux()
- mux.HandleFunc(".", func(w dns.ResponseWriter, req *dns.Msg) {
- resp := new(dns.Msg)
- resp.SetReply(req)
- resp.Authoritative = true
- if req.Question[0].Name == "example.com." &&
- req.Question[0].Qtype == dns.TypeA {
+ srv := startTestServer(t, "127.0.0.1:15353",
+ dns.HandlerFunc(func(ctx context.Context, w dns.ResponseWriter, req *dns.Msg) {
+ resp := new(dns.Msg)
+ dnsutil.SetReply(resp, req)
+ resp.Authoritative = true
resp.Answer = append(resp.Answer, &dns.A{
- Hdr: dns.RR_Header{
- Name: "example.com.",
- Rrtype: dns.TypeA,
- Class: dns.ClassINET,
- Ttl: 60,
+ Hdr: dns.Header{
+ Name: "example.com.",
+ Class: dns.ClassINET,
+ TTL: 60,
},
- A: net.IPv4(127, 0, 0, 1),
+ A: rdata.A{Addr: netip.AddrFrom4([4]byte{127, 0, 0, 1})},
})
- } else {
- resp.Rcode = dns.RcodeNameError
- }
- w.WriteMsg(resp)
- })
-
- srv := startTestServer(t, "127.0.0.1:15353", mux)
- defer srv.Shutdown()
- time.Sleep(50 * time.Millisecond)
+ io.Copy(w, resp)
+ }))
+ defer srv.Shutdown(context.Background())
+ time.Sleep(100 * time.Millisecond)
r := New(
WithRootAddresses([]string{"127.0.0.1:15353"}),
@@ -73,23 +72,21 @@ func TestLookupDirectAnswer(t *testing.T) {
if !ok {
t.Fatal("expected A record")
}
- if !a.A.Equal(net.IPv4(127, 0, 0, 1)) {
- t.Fatalf("expected 127.0.0.1, got %s", a.A)
+ if a.A.Addr != netip.AddrFrom4([4]byte{127, 0, 0, 1}) {
+ t.Fatalf("expected 127.0.0.1, got %s", a.A.Addr)
}
}
func TestLookupNXDOMAIN(t *testing.T) {
- mux := dns.NewServeMux()
- mux.HandleFunc(".", func(w dns.ResponseWriter, req *dns.Msg) {
- resp := new(dns.Msg)
- resp.SetReply(req)
- resp.Rcode = dns.RcodeNameError
- w.WriteMsg(resp)
- })
-
- srv := startTestServer(t, "127.0.0.1:15354", mux)
- defer srv.Shutdown()
- time.Sleep(50 * time.Millisecond)
+ srv := startTestServer(t, "127.0.0.1:15354",
+ dns.HandlerFunc(func(ctx context.Context, w dns.ResponseWriter, req *dns.Msg) {
+ resp := new(dns.Msg)
+ dnsutil.SetReply(resp, req)
+ resp.Rcode = dns.RcodeNameError
+ io.Copy(w, resp)
+ }))
+ defer srv.Shutdown(context.Background())
+ time.Sleep(100 * time.Millisecond)
r := New(
WithRootAddresses([]string{"127.0.0.1:15354"}),
@@ -111,16 +108,16 @@ func TestNextServersWithGlue(t *testing.T) {
msg := new(dns.Msg)
msg.Authoritative = false
msg.Ns = append(msg.Ns, &dns.NS{
- Hdr: dns.RR_Header{Name: "example.com.", Rrtype: dns.TypeNS, Ttl: 300},
- Ns: "ns1.example.com.",
+ Hdr: dns.Header{Name: "example.com.", Class: dns.ClassINET, TTL: 300},
+ NS: rdata.NS{Ns: "ns1.example.com."},
})
msg.Extra = append(msg.Extra, &dns.A{
- Hdr: dns.RR_Header{Name: "ns1.example.com.", Rrtype: dns.TypeA, Ttl: 300},
- A: net.ParseIP("192.0.2.1").To4(),
+ Hdr: dns.Header{Name: "ns1.example.com.", Class: dns.ClassINET, TTL: 300},
+ A: rdata.A{Addr: netip.MustParseAddr("192.0.2.1")},
})
msg.Extra = append(msg.Extra, &dns.AAAA{
- Hdr: dns.RR_Header{Name: "ns1.example.com.", Rrtype: dns.TypeAAAA, Ttl: 300},
- AAAA: net.ParseIP("2001:db8::1"),
+ Hdr: dns.Header{Name: "ns1.example.com.", Class: dns.ClassINET, TTL: 300},
+ AAAA: rdata.AAAA{Addr: netip.MustParseAddr("2001:db8::1")},
})
r := &Resolver{}
@@ -137,8 +134,8 @@ func TestNextServersNoGlue(t *testing.T) {
msg := new(dns.Msg)
msg.Authoritative = false
msg.Ns = append(msg.Ns, &dns.NS{
- Hdr: dns.RR_Header{Name: "example.com.", Rrtype: dns.TypeNS, Ttl: 300},
- Ns: "ns1.example.com.",
+ Hdr: dns.Header{Name: "example.com.", Class: dns.ClassINET, TTL: 300},
+ NS: rdata.NS{Ns: "ns1.example.com."},
})
r := &Resolver{maxDelegations: 30, timeout: time.Second, retries: 1}
@@ -147,3 +144,62 @@ func TestNextServersNoGlue(t *testing.T) {
t.Fatal("expected error when no glue and no roots")
}
}
+
+func TestLookupCNAME(t *testing.T) {
+ callCount := 0
+ srv := startTestServer(t, "127.0.0.1:15355",
+ dns.HandlerFunc(func(ctx context.Context, w dns.ResponseWriter, req *dns.Msg) {
+ callCount++
+ resp := new(dns.Msg)
+ dnsutil.SetReply(resp, req)
+ resp.Authoritative = true
+ resp.Answer = append(resp.Answer,
+ &dns.CNAME{
+ Hdr: dns.Header{Name: "alias.example.com.", Class: dns.ClassINET, TTL: 60},
+ CNAME: rdata.CNAME{Target: "real.example.com."},
+ },
+ )
+ if callCount > 1 {
+ resp.Answer = append(resp.Answer,
+ &dns.A{
+ Hdr: dns.Header{Name: "real.example.com.", Class: dns.ClassINET, TTL: 60},
+ A: rdata.A{Addr: netip.AddrFrom4([4]byte{127, 0, 0, 1})},
+ },
+ )
+ }
+ io.Copy(w, resp)
+ }))
+ defer srv.Shutdown(context.Background())
+ time.Sleep(100 * time.Millisecond)
+
+ r := New(
+ WithRootAddresses([]string{"127.0.0.1:15355"}),
+ WithTimeout(time.Second),
+ )
+ ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
+ defer cancel()
+
+ resp, err := r.Lookup(ctx, "alias.example.com.", dns.TypeA)
+ if err != nil {
+ t.Fatalf("CNAME lookup failed: %v", err)
+ }
+ if resp.Rcode != dns.RcodeSuccess {
+ t.Fatalf("expected NOERROR, got %d", resp.Rcode)
+ }
+ hasCNAME := false
+ hasA := false
+ for _, rr := range resp.Answer {
+ if _, ok := rr.(*dns.CNAME); ok {
+ hasCNAME = true
+ }
+ if _, ok := rr.(*dns.A); ok {
+ hasA = true
+ }
+ }
+ if !hasCNAME {
+ t.Fatal("expected CNAME record in answer")
+ }
+ if !hasA {
+ t.Fatal("expected A record (CNAME target) in answer")
+ }
+}