12 func namesEqual(a
, b Name
) bool {
16 for i
:= 0; i
< len(a
); i
++ {
17 if !bytes
.Equal(a
[i
], b
[i
]) {
24 func TestName(t
*testing
.T
) {
25 for _
, test
:= range []struct {
30 {[][]byte{}, nil, "."},
31 {[][]byte{[]byte("test")}, nil, "test"},
32 {[][]byte{[]byte("a"), []byte("b"), []byte("c")}, nil, "a.b.c"},
34 {[][]byte{{}}, ErrZeroLengthLabel
, ""},
35 {[][]byte{[]byte("a"), {}, []byte("c")}, ErrZeroLengthLabel
, ""},
38 {[][]byte{[]byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE")}, nil,
39 "0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE"},
41 {[][]byte{[]byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDEF")}, ErrLabelTooLong
, ""},
43 // 64+64+64+62 octets.
45 []byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE"),
46 []byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE"),
47 []byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE"),
48 []byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABC"),
50 "0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE.0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE.0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE.0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABC"},
51 // 64+64+64+63 octets.
53 []byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE"),
54 []byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE"),
55 []byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE"),
56 []byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCD"),
57 }, ErrNameTooLong
, ""},
58 // 127 one-octet labels.
60 {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'a'}, {'b'}, {'c'}, {'d'}, {'e'}, {'f'},
61 {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'A'}, {'B'}, {'C'}, {'D'}, {'E'}, {'F'},
62 {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'a'}, {'b'}, {'c'}, {'d'}, {'e'}, {'f'},
63 {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'A'}, {'B'}, {'C'}, {'D'}, {'E'}, {'F'},
64 {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'a'}, {'b'}, {'c'}, {'d'}, {'e'}, {'f'},
65 {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'A'}, {'B'}, {'C'}, {'D'}, {'E'}, {'F'},
66 {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'a'}, {'b'}, {'c'}, {'d'}, {'e'}, {'f'},
67 {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'A'}, {'B'}, {'C'}, {'D'}, {'E'},
69 "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"},
70 // 128 one-octet labels.
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'}, {'f'},
75 {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'A'}, {'B'}, {'C'}, {'D'}, {'E'}, {'F'},
76 {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'a'}, {'b'}, {'c'}, {'d'}, {'e'}, {'f'},
77 {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'A'}, {'B'}, {'C'}, {'D'}, {'E'}, {'F'},
78 {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'a'}, {'b'}, {'c'}, {'d'}, {'e'}, {'f'},
79 {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'A'}, {'B'}, {'C'}, {'D'}, {'E'}, {'F'},
80 }, ErrNameTooLong
, ""},
82 // Test that NewName returns proper error codes, and otherwise
83 // returns an equal slice of labels.
84 name
, err
:= NewName(test
.labels
)
85 if err
!= test
.err ||
(err
== nil && !namesEqual(name
, test
.labels
)) {
86 t
.Errorf("%+q returned (%+q, %v), expected (%+q, %v)",
87 test
.labels
, name
, err
, test
.labels
, test
.err
)
94 // Test that the string version of the name comes out as
98 t
.Errorf("%+q became string %+q, expected %+q", test
.labels
, s
, test
.s
)
102 // Test that parsing from a string back to a Name results in the
103 // original slice of labels.
104 name
, err
= ParseName(s
)
105 if err
!= nil ||
!namesEqual(name
, test
.labels
) {
106 t
.Errorf("%+q parsing %+q returned (%+q, %v), expected (%+q, %v)",
107 test
.labels
, s
, name
, err
, test
.labels
, nil)
110 // A trailing dot should be ignored.
111 if !strings
.HasSuffix(s
, ".") {
112 dotName
, dotErr
:= ParseName(s
+ ".")
113 if dotErr
!= err ||
!namesEqual(dotName
, name
) {
114 t
.Errorf("%+q parsing %+q returned (%+q, %v), expected (%+q, %v)",
115 test
.labels
, s
+".", dotName
, dotErr
, name
, err
)
122 func TestParseName(t
*testing
.T
) {
123 for _
, test
:= range []struct {
128 // This case can't be tested by TestName above because String
129 // will never produce "" (it produces "." instead).
130 {"", [][]byte{}, nil},
132 name
, err
:= ParseName(test
.s
)
133 if err
!= test
.err ||
(err
== nil && !namesEqual(name
, test
.name
)) {
134 t
.Errorf("%+q returned (%+q, %v), expected (%+q, %v)",
135 test
.s
, name
, err
, test
.name
, test
.err
)
141 func unescapeString(s
string) ([][]byte, error
) {
143 return [][]byte{}, nil
147 for _
, label
:= range strings
.Split(s
, ".") {
153 if i
+3 >= len(label
) {
154 return nil, fmt
.Errorf("truncated escape sequence at index %v", i
)
156 if label
[i
+1] != 'x' {
157 return nil, fmt
.Errorf("malformed escape sequence at index %v", i
)
159 b
, err
:= strconv
.ParseInt(string(label
[i
+2:i
+4]), 16, 8)
161 return nil, fmt
.Errorf("malformed hex sequence at index %v", i
+2)
163 buf
.WriteByte(byte(b
))
166 buf
.WriteByte(label
[i
])
170 result
= append(result
, buf
.Bytes())
175 func TestNameString(t
*testing
.T
) {
176 for _
, test
:= range []struct {
181 {[][]byte{[]byte("\x00"), []byte("a.b"), []byte("c\nd\\")}, "\\x00.a\\x2eb.c\\x0ad\\x5c"},
183 s
:= test
.name
.String()
185 t
.Errorf("%+q escaped to %+q, expected %+q", test
.name
, s
, test
.s
)
188 unescaped
, err
:= unescapeString(s
)
190 t
.Errorf("%+q unescaping %+q resulted in error %v", test
.name
, s
, err
)
193 if !namesEqual(Name(unescaped
), test
.name
) {
194 t
.Errorf("%+q roundtripped through %+q to %+q", test
.name
, s
, unescaped
)
200 func TestNameTrimSuffix(t
*testing
.T
) {
201 for _
, test
:= range []struct {
207 {".", ".", ".", true},
208 {"abc", "", "abc", true},
209 {"abc", ".", "abc", true},
210 {"", "abc", ".", false},
211 {".", "abc", ".", false},
212 {"example.com", "com", "example", true},
213 {"example.com", "net", ".", false},
214 {"example.com", "example.com", ".", true},
215 {"example.com", "test.com", ".", false},
216 {"example.com", "xample.com", ".", false},
217 {"example.com", "example", ".", false},
218 {"example.com", "COM", "example", true},
219 {"EXAMPLE.COM", "com", "EXAMPLE", true},
221 tmp
, ok
:= mustParseName(test
.name
).TrimSuffix(mustParseName(test
.suffix
))
222 trimmed
:= tmp
.String()
223 if ok
!= test
.ok || trimmed
!= test
.trimmed
{
224 t
.Errorf("TrimSuffix %+q %+q returned (%+q, %v), expected (%+q, %v)",
225 test
.name
, test
.suffix
, trimmed
, ok
, test
.trimmed
, test
.ok
)
231 func TestReadName(t
*testing
.T
) {
233 for _
, test
:= range []struct {
240 {0, 1, "\x00abcd", "."},
242 {12, 25, "AAAABBBBCCCC\x07example\x03com\x00", "example.com"},
244 {25, 31, "AAAABBBBCCCC\x07example\x03com\x00\x03sub\xc0\x0c", "sub.example.com"},
246 {0, 4, "\x01a\xc0\x04\x03bcd\x00", "a.bcd"},
247 // Two backwards pointers.
248 {31, 38, "AAAABBBBCCCC\x07example\x03com\x00\x03sub\xc0\x0c\x04sub2\xc0\x19", "sub2.sub.example.com"},
249 // Forward then backward pointer.
250 {25, 31, "AAAABBBBCCCC\x07example\x03com\x00\x03sub\xc0\x1f\x04sub2\xc0\x0c", "sub.sub2.example.com"},
251 // Overlapping codons.
252 {0, 4, "\x01a\xc0\x03bcd\x00", "a.bcd"},
253 // Pointer to empty label.
254 {0, 10, "\x07example\xc0\x0a\x00", "example"},
255 {1, 11, "\x00\x07example\xc0\x00", "example"},
256 // Pointer to pointer to empty label.
257 {0, 10, "\x07example\xc0\x0a\xc0\x0c\x00", "example"},
258 {1, 11, "\x00\x07example\xc0\x0c\xc0\x00", "example"},
260 r
:= bytes
.NewReader([]byte(test
.input
))
261 _
, err
:= r
.Seek(test
.start
, io
.SeekStart
)
265 name
, err
:= readName(r
)
267 t
.Errorf("%+q returned error %s", test
.input
, err
)
272 t
.Errorf("%+q returned %+q, expected %+q", test
.input
, s
, test
.s
)
275 cur
, _
:= r
.Seek(0, io
.SeekCurrent
)
277 t
.Errorf("%+q left offset %d, expected %d", test
.input
, cur
, test
.end
)
283 for _
, test
:= range []struct {
288 {0, "", io
.ErrUnexpectedEOF
},
289 // Reserved label type.
290 {0, "\x80example", ErrReservedLabelType
},
291 // Reserved label type.
292 {0, "\x40example", ErrReservedLabelType
},
293 // No Terminating empty label.
294 {0, "\x07example\x03com", io
.ErrUnexpectedEOF
},
295 // Pointer past end of buffer.
296 {0, "\x07example\xc0\xff", io
.ErrUnexpectedEOF
},
298 {0, "\x07example\x03com\xc0\x0c", ErrTooManyPointers
},
299 // Pointer to self with intermediate label.
300 {0, "\x07example\x03com\xc0\x08", ErrTooManyPointers
},
301 // Two pointers that point to each other.
302 {0, "\xc0\x02\xc0\x00", ErrTooManyPointers
},
303 // Two pointers that point to each other, with intermediate labels.
304 {0, "\x01a\xc0\x04\x01b\xc0\x00", ErrTooManyPointers
},
305 // EOF while reading label.
306 {0, "\x0aexample", io
.ErrUnexpectedEOF
},
307 // EOF before second byte of pointer.
308 {0, "\xc0", io
.ErrUnexpectedEOF
},
309 {0, "\x07example\xc0", io
.ErrUnexpectedEOF
},
311 r
:= bytes
.NewReader([]byte(test
.input
))
312 _
, err
:= r
.Seek(test
.start
, io
.SeekStart
)
316 name
, err
:= readName(r
)
318 err
= io
.ErrUnexpectedEOF
321 t
.Errorf("%+q returned (%+q, %v), expected %v", test
.input
, name
, err
, test
.err
)
327 func mustParseName(s
string) Name
{
328 name
, err
:= ParseName(s
)
335 func questionsEqual(a
, b
*Question
) bool {
336 if !namesEqual(a
.Name
, b
.Name
) {
339 if a
.Type
!= b
.Type || a
.Class
!= b
.Class
{
345 func rrsEqual(a
, b
*RR
) bool {
346 if !namesEqual(a
.Name
, b
.Name
) {
349 if a
.Type
!= b
.Type || a
.Class
!= b
.Class || a
.TTL
!= b
.TTL
{
352 if !bytes
.Equal(a
.Data
, b
.Data
) {
358 func messagesEqual(a
, b
*Message
) bool {
359 if a
.ID
!= b
.ID || a
.Flags
!= b
.Flags
{
362 if len(a
.Question
) != len(b
.Question
) {
365 for i
:= 0; i
< len(a
.Question
); i
++ {
366 if !questionsEqual(&a
.Question
[i
], &b
.Question
[i
]) {
370 for _
, rec
:= range []struct{ rrA
, rrB
[]RR
}{
371 {a
.Answer
, b
.Answer
},
372 {a
.Authority
, b
.Authority
},
373 {a
.Additional
, b
.Additional
},
375 if len(rec
.rrA
) != len(rec
.rrB
) {
378 for i
:= 0; i
< len(rec
.rrA
); i
++ {
379 if !rrsEqual(&rec
.rrA
[i
], &rec
.rrB
[i
]) {
387 func TestMessageFromWireFormat(t
*testing
.T
) {
388 for _
, test
:= range []struct {
399 "\x12\x34\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x03www\x07example\x03com\x00\x00\x01\x00\x01",
403 Question
: []Question
{
405 Name
: mustParseName("www.example.com"),
417 "\x12\x34\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x03www\x07example\x03com\x00\x00\x01\x00\x01X",
422 "\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",
426 Question
: []Question
{
428 Name
: mustParseName("www.example.com"),
435 Name
: mustParseName("www.example.com"),
439 Data
: []byte{192, 0, 2, 1},
448 message
, err
:= MessageFromWireFormat([]byte(test
.buf
))
449 if err
!= test
.err ||
(err
== nil && !messagesEqual(&message
, &test
.expected
)) {
450 t
.Errorf("%+q\nreturned (%+v, %v)\nexpected (%+v, %v)",
451 test
.buf
, message
, err
, test
.expected
, test
.err
)
457 func TestMessageWireFormatRoundTrip(t
*testing
.T
) {
458 for _
, message
:= range []Message
{
462 Question
: []Question
{
464 Name
: mustParseName("www.example.com"),
469 Name
: mustParseName("www2.example.com"),
476 Name
: mustParseName("abc"),
483 Name
: mustParseName("xyz"),
492 Name
: mustParseName("."),
496 Data
: []byte("XXXXXXXXXXXXXXXXXXX"),
502 buf
, err
:= message
.WireFormat()
504 t
.Errorf("%+v cannot make wire format: %v", message
, err
)
507 message2
, err
:= MessageFromWireFormat(buf
)
509 t
.Errorf("%+q cannot parse wire format: %v", buf
, err
)
512 if !messagesEqual(&message
, &message2
) {
513 t
.Errorf("messages unequal\nbefore: %+v\n after: %+v", message
, message2
)
519 func TestDecodeRDataTXT(t
*testing
.T
) {
520 for _
, test
:= range []struct {
525 {[]byte{}, nil, io
.ErrUnexpectedEOF
},
526 {[]byte("\x00"), []byte{}, nil},
527 {[]byte("\x01"), nil, io
.ErrUnexpectedEOF
},
529 decoded
, err
:= DecodeRDataTXT(test
.p
)
530 if err
!= test
.err ||
(err
== nil && !bytes
.Equal(decoded
, test
.decoded
)) {
531 t
.Errorf("%+q\nreturned (%+q, %v)\nexpected (%+q, %v)",
532 test
.p
, decoded
, err
, test
.decoded
, test
.err
)
538 func TestEncodeRDataTXT(t
*testing
.T
) {
539 // Encoding 0 bytes needs to return at least a single length octet of
540 // zero, not an empty slice.
542 encoded
:= EncodeRDataTXT(p
)
543 if len(encoded
) < 0 {
544 t
.Errorf("EncodeRDataTXT(%v) returned %v", p
, encoded
)
547 // 255 bytes should be able to be encoded into 256 bytes.
548 p
= make([]byte, 255)
549 encoded
= EncodeRDataTXT(p
)
550 if len(encoded
) > 256 {
551 t
.Errorf("EncodeRDataTXT(%d bytes) returned %d bytes", len(p
), len(encoded
))
555 func TestRDataTXTRoundTrip(t
*testing
.T
) {
556 for _
, p
:= range [][]byte{
560 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
561 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
562 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
563 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
564 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
565 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
566 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
567 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
568 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
569 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
570 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
571 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
572 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
573 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
574 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
575 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
578 rdata
:= EncodeRDataTXT(p
)
579 decoded
, err
:= DecodeRDataTXT(rdata
)
580 if err
!= nil ||
!bytes
.Equal(decoded
, p
) {
581 t
.Errorf("%+q returned (%+q, %v)", p
, decoded
, err
)