10 func namesEqual(a
, b Name
) bool {
14 for i
:= 0; i
< len(a
); i
++ {
15 if !bytes
.Equal(a
[i
], b
[i
]) {
22 func anyLabelContainsDot(labels
[][]byte) bool {
23 for _
, label
:= range labels
{
24 if bytes
.Contains(label
, []byte(".")) {
31 func TestName(t
*testing
.T
) {
32 for _
, test
:= range []struct {
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
, ""},
45 {[][]byte{[]byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE")}, nil,
46 "0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE"},
48 {[][]byte{[]byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDEF")}, ErrLabelTooLong
, ""},
50 // 64+64+64+62 octets.
52 []byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE"),
53 []byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE"),
54 []byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE"),
55 []byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABC"),
57 "0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE.0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE.0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE.0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABC"},
58 // 64+64+64+63 octets.
60 []byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE"),
61 []byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE"),
62 []byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE"),
63 []byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCD"),
64 }, ErrNameTooLong
, ""},
65 // 127 one-octet labels.
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'},
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.
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"},
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
)
105 // Test that the string version of the name comes out as
109 t
.Errorf("%+q became string %+q, expected %+q", test
.labels
, s
, test
.s
)
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)
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
)
135 func TestParseName(t
*testing
.T
) {
136 for _
, test
:= range []struct {
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
)
154 func TestNameTrimSuffix(t
*testing
.T
) {
155 for _
, test
:= range []struct {
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
)
185 func TestReadName(t
*testing
.T
) {
187 for _
, test
:= range []struct {
194 {0, 1, "\x00abcd", "."},
196 {12, 25, "AAAABBBBCCCC\x07example\x03com\x00", "example.com"},
198 {25, 31, "AAAABBBBCCCC\x07example\x03com\x00\x03sub\xc0\x0c", "sub.example.com"},
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
)
219 name
, err
:= readName(r
)
221 t
.Errorf("%+q returned error %s", test
.input
, err
)
226 t
.Errorf("%+q returned %+q, expected %+q", test
.input
, s
, test
.s
)
229 cur
, _
:= r
.Seek(0, io
.SeekCurrent
)
231 t
.Errorf("%+q left offset %d, expected %d", test
.input
, cur
, test
.end
)
237 for _
, test
:= range []struct {
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
},
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
)
270 name
, err
:= readName(r
)
272 err
= io
.ErrUnexpectedEOF
275 t
.Errorf("%+q returned (%+q, %v), expected %v", test
.input
, name
, err
, test
.err
)
281 func mustParseName(s
string) Name
{
282 name
, err
:= ParseName(s
)
289 func questionsEqual(a
, b
*Question
) bool {
290 if !namesEqual(a
.Name
, b
.Name
) {
293 if a
.Type
!= b
.Type || a
.Class
!= b
.Class
{
299 func rrsEqual(a
, b
*RR
) bool {
300 if !namesEqual(a
.Name
, b
.Name
) {
303 if a
.Type
!= b
.Type || a
.Class
!= b
.Class || a
.TTL
!= b
.TTL
{
306 if !bytes
.Equal(a
.Data
, b
.Data
) {
312 func messagesEqual(a
, b
*Message
) bool {
313 if a
.ID
!= b
.ID || a
.Flags
!= b
.Flags
{
316 if len(a
.Question
) != len(b
.Question
) {
319 for i
:= 0; i
< len(a
.Question
); i
++ {
320 if !questionsEqual(&a
.Question
[i
], &b
.Question
[i
]) {
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
) {
332 for i
:= 0; i
< len(rec
.rrA
); i
++ {
333 if !rrsEqual(&rec
.rrA
[i
], &rec
.rrB
[i
]) {
341 func TestMessageFromWireFormat(t
*testing
.T
) {
342 for _
, test
:= range []struct {
353 "\x12\x34\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x03www\x07example\x03com\x00\x00\x01\x00\x01",
357 Question
: []Question
{
359 Name
: mustParseName("www.example.com"),
371 "\x12\x34\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x03www\x07example\x03com\x00\x00\x01\x00\x01X",
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",
380 Question
: []Question
{
382 Name
: mustParseName("www.example.com"),
389 Name
: mustParseName("www.example.com"),
393 Data
: []byte{192, 0, 2, 1},
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
)
411 func TestMessageWireFormatRoundTrip(t
*testing
.T
) {
412 for _
, message
:= range []Message
{
416 Question
: []Question
{
418 Name
: mustParseName("www.example.com"),
423 Name
: mustParseName("www2.example.com"),
430 Name
: mustParseName("abc"),
437 Name
: mustParseName("xyz"),
446 Name
: mustParseName("."),
450 Data
: []byte("XXXXXXXXXXXXXXXXXXX"),
456 buf
, err
:= message
.WireFormat()
458 t
.Errorf("%+v cannot make wire format: %v", message
, err
)
461 message2
, err
:= MessageFromWireFormat(buf
)
463 t
.Errorf("%+q cannot parse wire format: %v", buf
, err
)
466 if !messagesEqual(&message
, &message2
) {
467 t
.Errorf("messages unequal\nbefore: %+v\n after: %+v", message
, message2
)
473 func TestDecodeRDataTXT(t
*testing
.T
) {
474 for _
, test
:= range []struct {
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
)
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.
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{
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
)