dns

DNS client and server implementations using the Go project's dnsmessage package
Log | Files | Refs | README | LICENSE

recursor_test.go (3671B)


      1 package main
      2 
      3 import (
      4 	"fmt"
      5 	"golang.org/x/net/dns/dnsmessage"
      6 	"os"
      7 	"testing"
      8 
      9 	"olowe.co/dns"
     10 )
     11 
     12 var tquery dnsmessage.Message = dnsmessage.Message{
     13 	Header: dnsmessage.Header{
     14 		ID:               69,
     15 		RecursionDesired: true,
     16 	},
     17 	Questions: []dnsmessage.Question{
     18 		dnsmessage.Question{
     19 			Name:  dnsmessage.MustNewName("www.example.com."),
     20 			Type:  dnsmessage.TypeAAAA,
     21 			Class: dnsmessage.ClassINET,
     22 		},
     23 	},
     24 }
     25 
     26 const testAddr string = "127.0.0.1:5359"
     27 const quad9 string = "9.9.9.9:domain"
     28 
     29 func compareMsg(want, got dnsmessage.Message) error {
     30 	if want.Header != got.Header {
     31 		fmt.Errorf("mismatched headers")
     32 	}
     33 	if len(want.Answers) != len(got.Answers) {
     34 		return fmt.Errorf("mismatched answer count")
     35 	}
     36 	if len(want.Answers) == 0 || len(got.Answers) == 0 {
     37 		return fmt.Errorf("unsupported comparison of empty answer messages")
     38 	}
     39 	wantaddr, ok := want.Answers[0].Body.(*dnsmessage.AAAAResource)
     40 	if !ok {
     41 		return fmt.Errorf("unexpected resource type from external resolver")
     42 	}
     43 	gotaddr, ok := got.Answers[0].Body.(*dnsmessage.AAAAResource)
     44 	if !ok {
     45 		return fmt.Errorf("unexpected resource type from our resolver")
     46 	}
     47 	if wantaddr.AAAA != gotaddr.AAAA {
     48 		return fmt.Errorf("wanted %s got %s", wantaddr.AAAA, gotaddr.AAAA)
     49 	}
     50 	return nil
     51 }
     52 
     53 func TestMain(m *testing.M) {
     54 	go func() {
     55 		if err := dns.ListenAndServe("udp", testAddr, handler); err != nil {
     56 			fmt.Println(err)
     57 			os.Exit(1)
     58 		}
     59 	}()
     60 	os.Exit(m.Run())
     61 }
     62 
     63 func TestRecursor(t *testing.T) {
     64 	wanted, err := dns.Exchange(tquery, quad9)
     65 	if err != nil {
     66 		fmt.Fprintf(os.Stderr, "skipping %s: %v\n", t.Name(), err)
     67 		t.Skip("query internet DNS:", err)
     68 	}
     69 	got, err := dns.Exchange(tquery, testAddr)
     70 	if err != nil {
     71 		t.Fatal(err)
     72 	}
     73 	t.Logf("wanted: %+v got %+v", wanted, got)
     74 	if err := compareMsg(wanted, got); err != nil {
     75 		t.Error(err)
     76 	}
     77 	// answer should come from cache
     78 	for i := 0; i <= 1; i++ {
     79 		got, err = dns.Exchange(tquery, testAddr)
     80 		if err = compareMsg(wanted, got); err != nil {
     81 			t.Error("resolve from cache:", err)
     82 		}
     83 	}
     84 	q := tquery
     85 	q.Questions[0].Name = dnsmessage.MustNewName("www.example.net.")
     86 	for i := 0; i <= 1; i++ {
     87 		if _, err = dns.Exchange(q, testAddr); err != nil {
     88 			t.Error("resolve from cache:", err)
     89 		}
     90 	}
     91 	t.Logf("wanted: %+v got %+v", wanted, got)
     92 }
     93 
     94 func TestNXDomain(t *testing.T) {
     95 	var wanted, got dnsmessage.Message
     96 	var err error
     97 	wanted, err = dns.Exchange(tquery, quad9)
     98 	if err != nil {
     99 		fmt.Fprintf(os.Stderr, "skipping %s: %v\n", t.Name(), err)
    100 		t.Skip("query internet DNS:", err)
    101 	}
    102 	q := tquery
    103 	q.Questions[0].Name = dnsmessage.MustNewName("nxdomain.example.com.")
    104 	wanted, err = dns.Exchange(q, quad9)
    105 	if err != nil {
    106 		t.Fatal(err)
    107 	}
    108 	// try twice: first for fresh response, second for cached response
    109 	for i := 0; i <= 1; i++ {
    110 		got, err = dns.Exchange(q, testAddr)
    111 		if err != nil {
    112 			t.Fatal(err)
    113 		}
    114 		if wanted.Header != got.Header {
    115 			t.Error("mismatched headers")
    116 		}
    117 	}
    118 	t.Logf("wanted: %+v got %+v", wanted, got)
    119 }
    120 
    121 func TestRefused(t *testing.T) {
    122 	var wanted, got dnsmessage.Message
    123 	var err error
    124 	wanted, err = dns.Exchange(tquery, quad9)
    125 	if err != nil {
    126 		fmt.Fprintf(os.Stderr, "skipping %s: %v\n", t.Name(), err)
    127 		t.Skip("query internet DNS:", err)
    128 	}
    129 	q := tquery
    130 	q.Questions[0].Name = dnsmessage.MustNewName("kjyq.com.")
    131 	wanted, err = dns.Exchange(q, "8.8.4.4:domain")
    132 	if err != nil {
    133 		t.Fatal(err)
    134 	}
    135 	// try twice: first for fresh response, second for cached response
    136 	for i := 0; i <= 1; i++ {
    137 		got, err = dns.Exchange(q, testAddr)
    138 		if err != nil {
    139 			t.Fatal(err)
    140 		}
    141 		if wanted.Header != got.Header {
    142 			t.Error("mismatched headers")
    143 		}
    144 	}
    145 	t.Logf("wanted: %+v got %+v", wanted, got)
    146 }