Add uTLS to TODO.
[dnstt.git] / dns / dns_test.go
blob4603e634158b41d36d111e7037dd2cf31dd9a90d
1 package dns
3 import (
4 "bytes"
5 "io"
6 "strings"
7 "testing"
10 func namesEqual(a, b Name) bool {
11 if len(a) != len(b) {
12 return false
14 for i := 0; i < len(a); i++ {
15 if !bytes.Equal(a[i], b[i]) {
16 return false
19 return true
22 func anyLabelContainsDot(labels [][]byte) bool {
23 for _, label := range labels {
24 if bytes.Contains(label, []byte(".")) {
25 return true
28 return false
31 func TestName(t *testing.T) {
32 for _, test := range []struct {
33 labels [][]byte
34 err error
35 s string
37 {[][]byte{}, nil, "."},
38 {[][]byte{[]byte("test")}, nil, "test"},
39 {[][]byte{[]byte("a"), []byte("b"), []byte("c")}, nil, "a.b.c"},
41 {[][]byte{{}}, ErrZeroLengthLabel, ""},
42 {[][]byte{[]byte("a"), {}, []byte("c")}, ErrZeroLengthLabel, ""},
44 // 63 octets.
45 {[][]byte{[]byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE")}, nil,
46 "0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE"},
47 // 64 octets.
48 {[][]byte{[]byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDEF")}, ErrLabelTooLong, ""},
50 // 64+64+64+62 octets.
51 {[][]byte{
52 []byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE"),
53 []byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE"),
54 []byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE"),
55 []byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABC"),
56 }, nil,
57 "0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE.0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE.0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE.0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABC"},
58 // 64+64+64+63 octets.
59 {[][]byte{
60 []byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE"),
61 []byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE"),
62 []byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE"),
63 []byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCD"),
64 }, ErrNameTooLong, ""},
65 // 127 one-octet labels.
66 {[][]byte{
67 {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'a'}, {'b'}, {'c'}, {'d'}, {'e'}, {'f'},
68 {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'A'}, {'B'}, {'C'}, {'D'}, {'E'}, {'F'},
69 {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'a'}, {'b'}, {'c'}, {'d'}, {'e'}, {'f'},
70 {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'A'}, {'B'}, {'C'}, {'D'}, {'E'}, {'F'},
71 {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'a'}, {'b'}, {'c'}, {'d'}, {'e'}, {'f'},
72 {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'A'}, {'B'}, {'C'}, {'D'}, {'E'}, {'F'},
73 {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'a'}, {'b'}, {'c'}, {'d'}, {'e'}, {'f'},
74 {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'A'}, {'B'}, {'C'}, {'D'}, {'E'},
75 }, nil,
76 "0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E"},
77 // 128 one-octet labels.
78 {[][]byte{
79 {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'a'}, {'b'}, {'c'}, {'d'}, {'e'}, {'f'},
80 {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'A'}, {'B'}, {'C'}, {'D'}, {'E'}, {'F'},
81 {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'a'}, {'b'}, {'c'}, {'d'}, {'e'}, {'f'},
82 {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'A'}, {'B'}, {'C'}, {'D'}, {'E'}, {'F'},
83 {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'a'}, {'b'}, {'c'}, {'d'}, {'e'}, {'f'},
84 {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'A'}, {'B'}, {'C'}, {'D'}, {'E'}, {'F'},
85 {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'a'}, {'b'}, {'c'}, {'d'}, {'e'}, {'f'},
86 {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'A'}, {'B'}, {'C'}, {'D'}, {'E'}, {'F'},
87 }, ErrNameTooLong, ""},
89 // Labels may contain any octets, though ones containing dots
90 // cannot be losslessly roundtripped through a string.
91 {[][]byte{[]byte("\x00"), []byte("a.b")}, nil, "\x00.a.b"},
92 } {
93 // Test that NewName returns proper error codes, and otherwise
94 // returns an equal slice of labels.
95 name, err := NewName(test.labels)
96 if err != test.err || (err == nil && !namesEqual(name, test.labels)) {
97 t.Errorf("%+q returned (%+q, %v), expected (%+q, %v)",
98 test.labels, name, err, test.labels, test.err)
99 continue
101 if test.err != nil {
102 continue
105 // Test that the string version of the name comes out as
106 // expected.
107 s := name.String()
108 if s != test.s {
109 t.Errorf("%+q became string %+q, expected %+q", test.labels, s, test.s)
110 continue
113 // Test that parsing from a string back to a Name results in the
114 // original slice of labels.
115 if !anyLabelContainsDot(test.labels) {
116 name, err := ParseName(s)
117 if err != nil || !namesEqual(name, test.labels) {
118 t.Errorf("%+q parsing %+q returned (%+q, %v), expected (%+q, %v)",
119 test.labels, s, name, err, test.labels, nil)
120 continue
122 // A trailing dot should be ignored.
123 if !strings.HasSuffix(s, ".") {
124 dotName, dotErr := ParseName(s + ".")
125 if dotErr != err || !namesEqual(dotName, name) {
126 t.Errorf("%+q parsing %+q returned (%+q, %v), expected (%+q, %v)",
127 test.labels, s+".", dotName, dotErr, name, err)
128 continue
135 func TestParseName(t *testing.T) {
136 for _, test := range []struct {
137 s string
138 name Name
139 err error
141 // This case can't be tested by TestName above because String
142 // will never produce "" (it produces "." instead).
143 {"", [][]byte{}, nil},
145 name, err := ParseName(test.s)
146 if err != test.err || (err == nil && !namesEqual(name, test.name)) {
147 t.Errorf("%+q returned (%+q, %v), expected (%+q, %v)",
148 test.s, name, err, test.name, test.err)
149 continue
154 func TestNameTrimSuffix(t *testing.T) {
155 for _, test := range []struct {
156 name, suffix string
157 trimmed string
158 ok bool
160 {"", "", ".", true},
161 {".", ".", ".", true},
162 {"abc", "", "abc", true},
163 {"abc", ".", "abc", true},
164 {"", "abc", ".", false},
165 {".", "abc", ".", false},
166 {"example.com", "com", "example", true},
167 {"example.com", "net", ".", false},
168 {"example.com", "example.com", ".", true},
169 {"example.com", "test.com", ".", false},
170 {"example.com", "xample.com", ".", false},
171 {"example.com", "example", ".", false},
172 {"example.com", "COM", "example", true},
173 {"EXAMPLE.COM", "com", "EXAMPLE", true},
175 tmp, ok := mustParseName(test.name).TrimSuffix(mustParseName(test.suffix))
176 trimmed := tmp.String()
177 if ok != test.ok || trimmed != test.trimmed {
178 t.Errorf("TrimSuffix %+q %+q returned (%+q, %v), expected (%+q, %v)",
179 test.name, test.suffix, trimmed, ok, test.trimmed, test.ok)
180 continue
185 func TestReadName(t *testing.T) {
186 // Good tests.
187 for _, test := range []struct {
188 start int64
189 end int64
190 input string
191 s string
193 // Empty name.
194 {0, 1, "\x00abcd", "."},
195 // No pointers.
196 {12, 25, "AAAABBBBCCCC\x07example\x03com\x00", "example.com"},
197 // Backward pointer.
198 {25, 31, "AAAABBBBCCCC\x07example\x03com\x00\x03sub\xc0\x0c", "sub.example.com"},
199 // Forward pointer.
200 {0, 4, "\x01a\xc0\x04\x03bcd\x00", "a.bcd"},
201 // Two backwards pointers.
202 {31, 38, "AAAABBBBCCCC\x07example\x03com\x00\x03sub\xc0\x0c\x04sub2\xc0\x19", "sub2.sub.example.com"},
203 // Forward then backward pointer.
204 {25, 31, "AAAABBBBCCCC\x07example\x03com\x00\x03sub\xc0\x1f\x04sub2\xc0\x0c", "sub.sub2.example.com"},
205 // Overlapping codons.
206 {0, 4, "\x01a\xc0\x03bcd\x00", "a.bcd"},
207 // Pointer to empty label.
208 {0, 10, "\x07example\xc0\x0a\x00", "example"},
209 {1, 11, "\x00\x07example\xc0\x00", "example"},
210 // Pointer to pointer to empty label.
211 {0, 10, "\x07example\xc0\x0a\xc0\x0c\x00", "example"},
212 {1, 11, "\x00\x07example\xc0\x0c\xc0\x00", "example"},
214 r := bytes.NewReader([]byte(test.input))
215 _, err := r.Seek(test.start, io.SeekStart)
216 if err != nil {
217 panic(err)
219 name, err := readName(r)
220 if err != nil {
221 t.Errorf("%+q returned error %s", test.input, err)
222 continue
224 s := name.String()
225 if s != test.s {
226 t.Errorf("%+q returned %+q, expected %+q", test.input, s, test.s)
227 continue
229 cur, _ := r.Seek(0, io.SeekCurrent)
230 if cur != test.end {
231 t.Errorf("%+q left offset %d, expected %d", test.input, cur, test.end)
232 continue
236 // Bad tests.
237 for _, test := range []struct {
238 start int64
239 input string
240 err error
242 {0, "", io.ErrUnexpectedEOF},
243 // Reserved label type.
244 {0, "\x80example", ErrReservedLabelType},
245 // Reserved label type.
246 {0, "\x40example", ErrReservedLabelType},
247 // No Terminating empty label.
248 {0, "\x07example\x03com", io.ErrUnexpectedEOF},
249 // Pointer past end of buffer.
250 {0, "\x07example\xc0\xff", io.ErrUnexpectedEOF},
251 // Pointer to self.
252 {0, "\x07example\x03com\xc0\x0c", ErrTooManyPointers},
253 // Pointer to self with intermediate label.
254 {0, "\x07example\x03com\xc0\x08", ErrTooManyPointers},
255 // Two pointers that point to each other.
256 {0, "\xc0\x02\xc0\x00", ErrTooManyPointers},
257 // Two pointers that point to each other, with intermediate labels.
258 {0, "\x01a\xc0\x04\x01b\xc0\x00", ErrTooManyPointers},
259 // EOF while reading label.
260 {0, "\x0aexample", io.ErrUnexpectedEOF},
261 // EOF before second byte of pointer.
262 {0, "\xc0", io.ErrUnexpectedEOF},
263 {0, "\x07example\xc0", io.ErrUnexpectedEOF},
265 r := bytes.NewReader([]byte(test.input))
266 _, err := r.Seek(test.start, io.SeekStart)
267 if err != nil {
268 panic(err)
270 name, err := readName(r)
271 if err == io.EOF {
272 err = io.ErrUnexpectedEOF
274 if err != test.err {
275 t.Errorf("%+q returned (%+q, %v), expected %v", test.input, name, err, test.err)
276 continue
281 func mustParseName(s string) Name {
282 name, err := ParseName(s)
283 if err != nil {
284 panic(err)
286 return name
289 func questionsEqual(a, b *Question) bool {
290 if !namesEqual(a.Name, b.Name) {
291 return false
293 if a.Type != b.Type || a.Class != b.Class {
294 return false
296 return true
299 func rrsEqual(a, b *RR) bool {
300 if !namesEqual(a.Name, b.Name) {
301 return false
303 if a.Type != b.Type || a.Class != b.Class || a.TTL != b.TTL {
304 return false
306 if !bytes.Equal(a.Data, b.Data) {
307 return false
309 return true
312 func messagesEqual(a, b *Message) bool {
313 if a.ID != b.ID || a.Flags != b.Flags {
314 return false
316 if len(a.Question) != len(b.Question) {
317 return false
319 for i := 0; i < len(a.Question); i++ {
320 if !questionsEqual(&a.Question[i], &b.Question[i]) {
321 return false
324 for _, rec := range []struct{ rrA, rrB []RR }{
325 {a.Answer, b.Answer},
326 {a.Authority, b.Authority},
327 {a.Additional, b.Additional},
329 if len(rec.rrA) != len(rec.rrB) {
330 return false
332 for i := 0; i < len(rec.rrA); i++ {
333 if !rrsEqual(&rec.rrA[i], &rec.rrB[i]) {
334 return false
338 return true
341 func TestMessageFromWireFormat(t *testing.T) {
342 for _, test := range []struct {
343 buf string
344 expected Message
345 err error
348 "\x12\x34",
349 Message{},
350 io.ErrUnexpectedEOF,
353 "\x12\x34\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x03www\x07example\x03com\x00\x00\x01\x00\x01",
354 Message{
355 ID: 0x1234,
356 Flags: 0x0100,
357 Question: []Question{
359 Name: mustParseName("www.example.com"),
360 Type: 1,
361 Class: 1,
364 Answer: []RR{},
365 Authority: []RR{},
366 Additional: []RR{},
368 nil,
371 "\x12\x34\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x03www\x07example\x03com\x00\x00\x01\x00\x01X",
372 Message{},
373 ErrTrailingBytes,
376 "\x12\x34\x81\x80\x00\x01\x00\x01\x00\x00\x00\x00\x03www\x07example\x03com\x00\x00\x01\x00\x01\x03www\x07example\x03com\x00\x00\x01\x00\x01\x00\x00\x00\x80\x00\x04\xc0\x00\x02\x01",
377 Message{
378 ID: 0x1234,
379 Flags: 0x8180,
380 Question: []Question{
382 Name: mustParseName("www.example.com"),
383 Type: 1,
384 Class: 1,
387 Answer: []RR{
389 Name: mustParseName("www.example.com"),
390 Type: 1,
391 Class: 1,
392 TTL: 128,
393 Data: []byte{192, 0, 2, 1},
396 Authority: []RR{},
397 Additional: []RR{},
399 nil,
402 message, err := MessageFromWireFormat([]byte(test.buf))
403 if err != test.err || (err == nil && !messagesEqual(&message, &test.expected)) {
404 t.Errorf("%+q\nreturned (%+v, %v)\nexpected (%+v, %v)",
405 test.buf, message, err, test.expected, test.err)
406 continue
411 func TestMessageWireFormatRoundTrip(t *testing.T) {
412 for _, message := range []Message{
414 ID: 0x1234,
415 Flags: 0x0100,
416 Question: []Question{
418 Name: mustParseName("www.example.com"),
419 Type: 1,
420 Class: 1,
423 Name: mustParseName("www2.example.com"),
424 Type: 2,
425 Class: 2,
428 Answer: []RR{
430 Name: mustParseName("abc"),
431 Type: 2,
432 Class: 3,
433 TTL: 0xffffffff,
434 Data: []byte{1},
437 Name: mustParseName("xyz"),
438 Type: 2,
439 Class: 3,
440 TTL: 255,
441 Data: []byte{},
444 Authority: []RR{
446 Name: mustParseName("."),
447 Type: 65535,
448 Class: 65535,
449 TTL: 0,
450 Data: []byte("XXXXXXXXXXXXXXXXXXX"),
453 Additional: []RR{},
456 buf, err := message.WireFormat()
457 if err != nil {
458 t.Errorf("%+v cannot make wire format: %v", message, err)
459 continue
461 message2, err := MessageFromWireFormat(buf)
462 if err != nil {
463 t.Errorf("%+q cannot parse wire format: %v", buf, err)
464 continue
466 if !messagesEqual(&message, &message2) {
467 t.Errorf("messages unequal\nbefore: %+v\n after: %+v", message, message2)
468 continue
473 func TestDecodeRDataTXT(t *testing.T) {
474 for _, test := range []struct {
475 p []byte
476 decoded []byte
477 err error
479 {[]byte{}, nil, io.ErrUnexpectedEOF},
480 {[]byte("\x00"), []byte{}, nil},
481 {[]byte("\x01"), nil, io.ErrUnexpectedEOF},
483 decoded, err := DecodeRDataTXT(test.p)
484 if err != test.err || (err == nil && !bytes.Equal(decoded, test.decoded)) {
485 t.Errorf("%+q\nreturned (%+q, %v)\nexpected (%+q, %v)",
486 test.p, decoded, err, test.decoded, test.err)
487 continue
492 func TestEncodeRDataTXT(t *testing.T) {
493 // Encoding 0 bytes needs to return at least a single length octet of
494 // zero, not an empty slice.
495 p := make([]byte, 0)
496 encoded := EncodeRDataTXT(p)
497 if len(encoded) < 0 {
498 t.Errorf("EncodeRDataTXT(%v) returned %v", p, encoded)
501 // 255 bytes should be able to be encoded into 256 bytes.
502 p = make([]byte, 255)
503 encoded = EncodeRDataTXT(p)
504 if len(encoded) > 256 {
505 t.Errorf("EncodeRDataTXT(%d bytes) returned %d bytes", len(p), len(encoded))
509 func TestRDataTXTRoundTrip(t *testing.T) {
510 for _, p := range [][]byte{
512 []byte("\x00"),
514 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
515 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
516 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
517 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
518 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
519 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
520 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
521 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
522 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
523 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
524 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
525 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
526 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
527 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
528 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
529 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
532 rdata := EncodeRDataTXT(p)
533 decoded, err := DecodeRDataTXT(rdata)
534 if err != nil || !bytes.Equal(decoded, p) {
535 t.Errorf("%+q returned (%+q, %v)", p, decoded, err)
536 continue