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 }