1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
13 func TestStructPackUnpack(t
*testing
.T
) {
19 buf
:= make([]byte, 50)
20 n
, ok
:= packStruct(&want
, buf
, 0)
22 t
.Fatal("packing failed")
26 n
, ok
= unpackStruct(&got
, buf
, 0)
28 t
.Fatal("unpacking failed")
31 t
.Errorf("unpacked different amount than packed: got n = %d, want = %d", n
, len(buf
))
33 if !reflect
.DeepEqual(got
, want
) {
34 t
.Errorf("got = %+v, want = %+v", got
, want
)
38 func TestDomainNamePackUnpack(t
*testing
.T
) {
46 {"google..com", "", false},
47 {"google.com", "google.com.", true},
48 {"google..com.", "", false},
49 {"google.com.", "google.com.", true},
50 {".google.com.", "", false},
51 {"www..google.com.", "", false},
52 {"www.google.com.", "www.google.com.", true},
55 for _
, test
:= range tests
{
56 buf
:= make([]byte, 30)
57 n
, ok
:= packDomainName(test
.in
, buf
, 0)
59 t
.Errorf("packing of %s: got ok = %t, want = %t", test
.in
, ok
, test
.ok
)
66 got
, n
, ok
:= unpackDomainName(buf
, 0)
68 t
.Errorf("unpacking for %s failed", test
.in
)
73 "unpacked different amount than packed for %s: got n = %d, want = %d",
80 t
.Errorf("unpacking packing of %s: got = %s, want = %s", test
.in
, got
, test
.want
)
85 func TestDNSPackUnpack(t
*testing
.T
) {
87 question
: []dnsQuestion
{{
98 t
.Fatal("packing failed")
103 t
.Fatal("unpacking failed")
105 if !reflect
.DeepEqual(got
, want
) {
106 t
.Errorf("got = %+v, want = %+v", got
, want
)
110 func TestDNSParseSRVReply(t
*testing
.T
) {
111 data
, err
:= hex
.DecodeString(dnsSRVReply
)
116 ok
:= msg
.Unpack(data
)
118 t
.Fatal("unpacking packet failed")
120 _
= msg
.String() // exercise this code path
121 if g
, e
:= len(msg
.answer
), 5; g
!= e
{
122 t
.Errorf("len(msg.answer) = %d; want %d", g
, e
)
124 for idx
, rr
:= range msg
.answer
{
125 if g
, e
:= rr
.Header().Rrtype
, uint16(dnsTypeSRV
); g
!= e
{
126 t
.Errorf("rr[%d].Header().Rrtype = %d; want %d", idx
, g
, e
)
128 if _
, ok
:= rr
.(*dnsRR_SRV
); !ok
{
129 t
.Errorf("answer[%d] = %T; want *dnsRR_SRV", idx
, rr
)
132 for _
, name
:= range [...]string{
133 "_xmpp-server._tcp.google.com.",
134 "_XMPP-Server._TCP.Google.COM.",
135 "_XMPP-SERVER._TCP.GOOGLE.COM.",
137 _
, addrs
, err
:= answer(name
, "foo:53", msg
, uint16(dnsTypeSRV
))
141 if g
, e
:= len(addrs
), 5; g
!= e
{
142 t
.Errorf("len(addrs) = %d; want %d", g
, e
)
143 t
.Logf("addrs = %#v", addrs
)
146 // repack and unpack.
147 data2
, ok
:= msg
.Pack()
152 t
.Error("failed to repack message")
153 case !reflect
.DeepEqual(msg
, msg2
):
154 t
.Error("repacked message differs from original")
158 func TestDNSParseCorruptSRVReply(t
*testing
.T
) {
159 data
, err
:= hex
.DecodeString(dnsSRVCorruptReply
)
164 ok
:= msg
.Unpack(data
)
166 t
.Fatal("unpacking packet failed")
168 _
= msg
.String() // exercise this code path
169 if g
, e
:= len(msg
.answer
), 5; g
!= e
{
170 t
.Errorf("len(msg.answer) = %d; want %d", g
, e
)
172 for idx
, rr
:= range msg
.answer
{
173 if g
, e
:= rr
.Header().Rrtype
, uint16(dnsTypeSRV
); g
!= e
{
174 t
.Errorf("rr[%d].Header().Rrtype = %d; want %d", idx
, g
, e
)
177 if _
, ok
:= rr
.(*dnsRR_Header
); !ok
{
178 t
.Errorf("answer[%d] = %T; want *dnsRR_Header", idx
, rr
)
181 if _
, ok
:= rr
.(*dnsRR_SRV
); !ok
{
182 t
.Errorf("answer[%d] = %T; want *dnsRR_SRV", idx
, rr
)
186 _
, addrs
, err
:= answer("_xmpp-server._tcp.google.com.", "foo:53", msg
, uint16(dnsTypeSRV
))
188 t
.Fatalf("answer: %v", err
)
190 if g
, e
:= len(addrs
), 4; g
!= e
{
191 t
.Errorf("len(addrs) = %d; want %d", g
, e
)
192 t
.Logf("addrs = %#v", addrs
)
196 func TestDNSParseTXTReply(t
*testing
.T
) {
197 expectedTxt1
:= "v=spf1 redirect=_spf.google.com"
198 expectedTxt2
:= "v=spf1 ip4:69.63.179.25 ip4:69.63.178.128/25 ip4:69.63.184.0/25 " +
199 "ip4:66.220.144.128/25 ip4:66.220.155.0/24 " +
200 "ip4:69.171.232.0/25 ip4:66.220.157.0/25 " +
201 "ip4:69.171.244.0/24 mx -all"
203 replies
:= []string{dnsTXTReply1
, dnsTXTReply2
}
204 expectedTxts
:= []string{expectedTxt1
, expectedTxt2
}
206 for i
:= range replies
{
207 data
, err
:= hex
.DecodeString(replies
[i
])
213 ok
:= msg
.Unpack(data
)
215 t
.Errorf("test %d: unpacking packet failed", i
)
219 if len(msg
.answer
) != 1 {
220 t
.Errorf("test %d: len(rr.answer) = %d; want 1", i
, len(msg
.answer
))
225 rrTXT
, ok
:= rr
.(*dnsRR_TXT
)
227 t
.Errorf("test %d: answer[0] = %T; want *dnsRR_TXT", i
, rr
)
231 if rrTXT
.Txt
!= expectedTxts
[i
] {
232 t
.Errorf("test %d: Txt = %s; want %s", i
, rrTXT
.Txt
, expectedTxts
[i
])
237 func TestDNSParseTXTCorruptDataLengthReply(t
*testing
.T
) {
238 replies
:= []string{dnsTXTCorruptDataLengthReply1
, dnsTXTCorruptDataLengthReply2
}
240 for i
:= range replies
{
241 data
, err
:= hex
.DecodeString(replies
[i
])
247 ok
:= msg
.Unpack(data
)
249 t
.Errorf("test %d: expected to fail on unpacking corrupt packet", i
)
254 func TestDNSParseTXTCorruptTXTLengthReply(t
*testing
.T
) {
255 replies
:= []string{dnsTXTCorruptTXTLengthReply1
, dnsTXTCorruptTXTLengthReply2
}
257 for i
:= range replies
{
258 data
, err
:= hex
.DecodeString(replies
[i
])
264 ok
:= msg
.Unpack(data
)
265 // Unpacking should succeed, but we should just get the header.
267 t
.Errorf("test %d: unpacking packet failed", i
)
271 if len(msg
.answer
) != 1 {
272 t
.Errorf("test %d: len(rr.answer) = %d; want 1", i
, len(msg
.answer
))
277 if _
, justHeader
:= rr
.(*dnsRR_Header
); !justHeader
{
278 t
.Errorf("test %d: rr = %T; expected *dnsRR_Header", i
, rr
)
283 func TestIsResponseTo(t
*testing
.T
) {
286 dnsMsgHdr
: dnsMsgHdr
{
289 question
: []dnsQuestion
{
291 Name
: "www.example.com.",
293 Qclass
: dnsClassINET
,
300 if !resp
.IsResponseTo(&query
) {
301 t
.Error("got false, want true")
304 badResponses
:= []dnsMsg
{
307 dnsMsgHdr
: dnsMsgHdr
{
311 question
: []dnsQuestion
{
313 Name
: "www.example.com.",
315 Qclass
: dnsClassINET
,
320 // Different query name.
322 dnsMsgHdr
: dnsMsgHdr
{
326 question
: []dnsQuestion
{
328 Name
: "www.google.com.",
330 Qclass
: dnsClassINET
,
335 // Different query type.
337 dnsMsgHdr
: dnsMsgHdr
{
341 question
: []dnsQuestion
{
343 Name
: "www.example.com.",
345 Qclass
: dnsClassINET
,
350 // Different query class.
352 dnsMsgHdr
: dnsMsgHdr
{
356 question
: []dnsQuestion
{
358 Name
: "www.example.com.",
360 Qclass
: dnsClassCSNET
,
367 dnsMsgHdr
: dnsMsgHdr
{
375 dnsMsgHdr
: dnsMsgHdr
{
379 question
: []dnsQuestion
{
381 Name
: "www.example.com.",
383 Qclass
: dnsClassINET
,
386 Name
: "www.golang.org.",
388 Qclass
: dnsClassINET
,
394 for i
:= range badResponses
{
395 if badResponses
[i
].IsResponseTo(&query
) {
396 t
.Errorf("%v: got true, want false", i
)
401 // Valid DNS SRV reply
402 const dnsSRVReply
= "0901818000010005000000000c5f786d70702d736572766572045f74637006676f6f67" +
403 "6c6503636f6d0000210001c00c002100010000012c00210014000014950c786d70702d" +
404 "73657276657234016c06676f6f676c6503636f6d00c00c002100010000012c00210014" +
405 "000014950c786d70702d73657276657232016c06676f6f676c6503636f6d00c00c0021" +
406 "00010000012c00210014000014950c786d70702d73657276657233016c06676f6f676c" +
407 "6503636f6d00c00c002100010000012c00200005000014950b786d70702d7365727665" +
408 "72016c06676f6f676c6503636f6d00c00c002100010000012c00210014000014950c78" +
409 "6d70702d73657276657231016c06676f6f676c6503636f6d00"
411 // Corrupt DNS SRV reply, with its final RR having a bogus length
412 // (perhaps it was truncated, or it's malicious) The mutation is the
413 // capital "FF" below, instead of the proper "21".
414 const dnsSRVCorruptReply
= "0901818000010005000000000c5f786d70702d736572766572045f74637006676f6f67" +
415 "6c6503636f6d0000210001c00c002100010000012c00210014000014950c786d70702d" +
416 "73657276657234016c06676f6f676c6503636f6d00c00c002100010000012c00210014" +
417 "000014950c786d70702d73657276657232016c06676f6f676c6503636f6d00c00c0021" +
418 "00010000012c00210014000014950c786d70702d73657276657233016c06676f6f676c" +
419 "6503636f6d00c00c002100010000012c00200005000014950b786d70702d7365727665" +
420 "72016c06676f6f676c6503636f6d00c00c002100010000012c00FF0014000014950c78" +
421 "6d70702d73657276657231016c06676f6f676c6503636f6d00"
423 // TXT reply with one <character-string>
424 const dnsTXTReply1
= "b3458180000100010004000505676d61696c03636f6d0000100001c00c001000010000012c00" +
425 "201f763d737066312072656469726563743d5f7370662e676f6f676c652e636f6dc00" +
426 "c0002000100025d4c000d036e733406676f6f676c65c012c00c0002000100025d4c00" +
427 "06036e7331c057c00c0002000100025d4c0006036e7333c057c00c0002000100025d4" +
428 "c0006036e7332c057c06c00010001000248b50004d8ef200ac09000010001000248b5" +
429 "0004d8ef220ac07e00010001000248b50004d8ef240ac05300010001000248b50004d" +
430 "8ef260a0000291000000000000000"
432 // TXT reply with more than one <character-string>.
433 // See https://tools.ietf.org/html/rfc1035#section-3.3.14
434 const dnsTXTReply2
= "a0a381800001000100020002045f7370660866616365626f6f6b03636f6d0000100001c00c0010000" +
435 "100000e1000af7f763d73706631206970343a36392e36332e3137392e3235206970343a36392e" +
436 "36332e3137382e3132382f3235206970343a36392e36332e3138342e302f3235206970343a363" +
437 "62e3232302e3134342e3132382f3235206970343a36362e3232302e3135352e302f3234206970" +
438 "343a36392e3137312e3233322e302f323520692e70343a36362e3232302e3135372e302f32352" +
439 "06970343a36392e3137312e3234342e302f3234206d78202d616c6cc0110002000100025d1500" +
440 "070161026e73c011c0110002000100025d1500040162c0ecc0ea0001000100025d15000445abe" +
441 "f0cc0fd0001000100025d15000445abff0c"
443 // DataLength field should be sum of all TXT fields. In this case it's less.
444 const dnsTXTCorruptDataLengthReply1
= "a0a381800001000100020002045f7370660866616365626f6f6b03636f6d0000100001c00c0010000" +
445 "100000e1000967f763d73706631206970343a36392e36332e3137392e3235206970343a36392e" +
446 "36332e3137382e3132382f3235206970343a36392e36332e3138342e302f3235206970343a363" +
447 "62e3232302e3134342e3132382f3235206970343a36362e3232302e3135352e302f3234206970" +
448 "343a36392e3137312e3233322e302f323520692e70343a36362e3232302e3135372e302f32352" +
449 "06970343a36392e3137312e3234342e302f3234206d78202d616c6cc0110002000100025d1500" +
450 "070161026e73c011c0110002000100025d1500040162c0ecc0ea0001000100025d15000445abe" +
451 "f0cc0fd0001000100025d15000445abff0c"
453 // Same as above but DataLength is more than sum of TXT fields.
454 const dnsTXTCorruptDataLengthReply2
= "a0a381800001000100020002045f7370660866616365626f6f6b03636f6d0000100001c00c0010000" +
455 "100000e1001227f763d73706631206970343a36392e36332e3137392e3235206970343a36392e" +
456 "36332e3137382e3132382f3235206970343a36392e36332e3138342e302f3235206970343a363" +
457 "62e3232302e3134342e3132382f3235206970343a36362e3232302e3135352e302f3234206970" +
458 "343a36392e3137312e3233322e302f323520692e70343a36362e3232302e3135372e302f32352" +
459 "06970343a36392e3137312e3234342e302f3234206d78202d616c6cc0110002000100025d1500" +
460 "070161026e73c011c0110002000100025d1500040162c0ecc0ea0001000100025d15000445abe" +
461 "f0cc0fd0001000100025d15000445abff0c"
463 // TXT Length field is less than actual length.
464 const dnsTXTCorruptTXTLengthReply1
= "a0a381800001000100020002045f7370660866616365626f6f6b03636f6d0000100001c00c0010000" +
465 "100000e1000af7f763d73706631206970343a36392e36332e3137392e3235206970343a36392e" +
466 "36332e3137382e3132382f3235206970343a36392e36332e3138342e302f3235206970343a363" +
467 "62e3232302e3134342e3132382f3235206970343a36362e3232302e3135352e302f3234206970" +
468 "343a36392e3137312e3233322e302f323520691470343a36362e3232302e3135372e302f32352" +
469 "06970343a36392e3137312e3234342e302f3234206d78202d616c6cc0110002000100025d1500" +
470 "070161026e73c011c0110002000100025d1500040162c0ecc0ea0001000100025d15000445abe" +
471 "f0cc0fd0001000100025d15000445abff0c"
473 // TXT Length field is more than actual length.
474 const dnsTXTCorruptTXTLengthReply2
= "a0a381800001000100020002045f7370660866616365626f6f6b03636f6d0000100001c00c0010000" +
475 "100000e1000af7f763d73706631206970343a36392e36332e3137392e3235206970343a36392e" +
476 "36332e3137382e3132382f3235206970343a36392e36332e3138342e302f3235206970343a363" +
477 "62e3232302e3134342e3132382f3235206970343a36362e3232302e3135352e302f3234206970" +
478 "343a36392e3137312e3233322e302f323520693370343a36362e3232302e3135372e302f32352" +
479 "06970343a36392e3137312e3234342e302f3234206d78202d616c6cc0110002000100025d1500" +
480 "070161026e73c011c0110002000100025d1500040162c0ecc0ea0001000100025d15000445abe" +
481 "f0cc0fd0001000100025d15000445abff0c"