OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/dns/dns_response.h" | 5 #include "net/dns/dns_response.h" |
6 | 6 |
7 #include "base/time.h" | 7 #include "base/time.h" |
8 #include "net/base/address_list.h" | 8 #include "net/base/address_list.h" |
9 #include "net/base/io_buffer.h" | 9 #include "net/base/io_buffer.h" |
10 #include "net/base/net_util.h" | 10 #include "net/base/net_util.h" |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
238 | 238 |
239 DnsResourceRecord record; | 239 DnsResourceRecord record; |
240 DnsRecordParser parser = resp.Parser(); | 240 DnsRecordParser parser = resp.Parser(); |
241 EXPECT_TRUE(parser.ReadRecord(&record)); | 241 EXPECT_TRUE(parser.ReadRecord(&record)); |
242 EXPECT_FALSE(parser.AtEnd()); | 242 EXPECT_FALSE(parser.AtEnd()); |
243 EXPECT_TRUE(parser.ReadRecord(&record)); | 243 EXPECT_TRUE(parser.ReadRecord(&record)); |
244 EXPECT_TRUE(parser.AtEnd()); | 244 EXPECT_TRUE(parser.AtEnd()); |
245 EXPECT_FALSE(parser.ReadRecord(&record)); | 245 EXPECT_FALSE(parser.ReadRecord(&record)); |
246 } | 246 } |
247 | 247 |
248 // TODO(noamsml): Simplify this test | |
249 TEST(DnsResponseTest, GetResponseOffset) { | |
250 // Easiest way to comput size of QNAME data | |
251 const char qname_data[] = "\x0A""codereview""\x08""chromium""\x03""org"; | |
252 const base::StringPiece qname(qname_data, sizeof(qname_data)); | |
253 const size_t qsec_length = qname.size() + 4; | |
254 | |
255 const uint8 response_data[] = { | |
256 // Header | |
257 0xca, 0xfe, // ID | |
258 0x81, 0x80, // Standard query response, RA, no error | |
259 0x00, 0x01, // 1 question | |
260 0x00, 0x02, // 2 RRs (answers) | |
261 0x00, 0x00, // 0 authority RRs | |
262 0x00, 0x00, // 0 additional RRs | |
263 | |
264 // Question | |
265 // This part is echoed back from the respective query. | |
266 0x0a, 'c', 'o', 'd', 'e', 'r', 'e', 'v', 'i', 'e', 'w', | |
267 0x08, 'c', 'h', 'r', 'o', 'm', 'i', 'u', 'm', | |
268 0x03, 'o', 'r', 'g', | |
269 0x00, | |
270 0x00, 0x01, // TYPE is A. | |
271 0x00, 0x01, // CLASS is IN. | |
272 | |
273 // Answer 1 | |
274 0xc0, 0x0c, // NAME is a pointer to name in Question section. | |
275 0x00, 0x05, // TYPE is CNAME. | |
276 0x00, 0x01, // CLASS is IN. | |
277 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds. | |
278 0x24, 0x74, | |
279 0x00, 0x12, // RDLENGTH is 18 bytes. | |
280 // ghs.l.google.com in DNS format. | |
281 0x03, 'g', 'h', 's', | |
282 0x01, 'l', | |
283 0x06, 'g', 'o', 'o', 'g', 'l', 'e', | |
284 0x03, 'c', 'o', 'm', | |
285 0x00, | |
286 | |
287 // Answer 2 | |
288 0xc0, 0x35, // NAME is a pointer to name in Answer 1. | |
289 0x00, 0x01, // TYPE is A. | |
290 0x00, 0x01, // CLASS is IN. | |
291 0x00, 0x00, // TTL (4 bytes) is 53 seconds. | |
292 0x00, 0x35, | |
293 0x00, 0x04, // RDLENGTH is 4 bytes. | |
294 0x4a, 0x7d, // RDATA is the IP: 74.125.95.121 | |
295 0x5f, 0x79, | |
296 }; | |
297 | |
298 DnsResponse resp; | |
299 memcpy(resp.io_buffer()->data(), response_data, sizeof(response_data)); | |
300 | |
301 EXPECT_EQ(sizeof(dns_protocol::Header) + qsec_length, | |
302 resp.GetResponseOffset()); | |
303 } | |
304 | |
305 // TODO(noamsml): Simplify this test | |
306 TEST(DnsResponseTest, GetQuestionSectionSizeNoQuestion) { | |
307 const uint8 response_data[] = { | |
308 // Header | |
309 0xca, 0xfe, // ID | |
310 0x81, 0x80, // Standard query response, RA, no error | |
311 0x00, 0x00, // 1 question | |
312 0x00, 0x02, // 2 RRs (answers) | |
313 0x00, 0x00, // 0 authority RRs | |
314 0x00, 0x00, // 0 additional RRs | |
315 | |
316 // Answer 1 | |
317 0xc0, 0x0c, // NAME is a pointer to name in Question section. | |
318 0x00, 0x05, // TYPE is CNAME. | |
319 0x00, 0x01, // CLASS is IN. | |
320 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds. | |
321 0x24, 0x74, | |
322 0x00, 0x12, // RDLENGTH is 18 bytes. | |
323 // ghs.l.google.com in DNS format. | |
324 0x03, 'g', 'h', 's', | |
325 0x01, 'l', | |
326 0x06, 'g', 'o', 'o', 'g', 'l', 'e', | |
327 0x03, 'c', 'o', 'm', | |
328 0x00, | |
329 | |
330 // Answer 2 | |
331 0xc0, 0x35, // NAME is a pointer to name in Answer 1. | |
332 0x00, 0x01, // TYPE is A. | |
333 0x00, 0x01, // CLASS is IN. | |
334 0x00, 0x00, // TTL (4 bytes) is 53 seconds. | |
335 0x00, 0x35, | |
336 0x00, 0x04, // RDLENGTH is 4 bytes. | |
337 0x4a, 0x7d, // RDATA is the IP: 74.125.95.121 | |
338 0x5f, 0x79, | |
339 }; | |
340 | |
341 DnsResponse resp; | |
342 memcpy(resp.io_buffer()->data(), response_data, sizeof(response_data)); | |
343 | |
344 EXPECT_EQ(sizeof(dns_protocol::Header), resp.GetResponseOffset()); | |
345 } | |
346 | |
347 // TODO(noamsml): Simplify this test | |
348 TEST(DnsResponseTest, GetQuestionSectionSizeTwoQuestions) { | |
349 // Easiest way to compute size of QNAME data | |
350 const char qname_data[] = "\x0A""codereview""\x08""chromium""\x03""org"; | |
351 const base::StringPiece qname(qname_data, sizeof(qname_data)); | |
352 const char qname2_data[] = "\x0B""codereview2""\xc0\x18"; | |
353 const base::StringPiece qname2(qname2_data, sizeof(qname2_data)); | |
354 const size_t qsec_length = qname.size() + qname2.size() + 8; | |
355 | |
356 const uint8 response_data[] = { | |
357 // Header | |
358 0xca, 0xfe, // ID | |
359 0x81, 0x80, // Standard query response, RA, no error | |
360 0x00, 0x02, // 1 question | |
361 0x00, 0x02, // 2 RRs (answers) | |
362 0x00, 0x00, // 0 authority RRs | |
363 0x00, 0x00, // 0 additional RRs | |
364 | |
365 // Question 1 | |
366 0x0a, 'c', 'o', 'd', 'e', 'r', 'e', 'v', 'i', 'e', 'w', | |
367 0x08, 'c', 'h', 'r', 'o', 'm', 'i', 'u', 'm', | |
368 0x03, 'o', 'r', 'g', | |
369 0x00, | |
370 0x00, 0x01, // TYPE is A. | |
371 0x00, 0x01, // CLASS is IN. | |
372 | |
373 // Question 2 | |
374 0x0b, 'c', 'o', 'd', 'e', 'r', 'e', 'v', 'i', 'e', 'w', '2', | |
375 0xc0, 0x18, // pointer to "chromium.org" | |
376 0x00, | |
szym
2013/04/17 22:11:12
This is not a valid DNS response. The pointer is t
Noam Samuel
2013/04/18 19:03:17
Done.
| |
377 0x00, 0x01, // TYPE is A. | |
378 0x00, 0x01, // CLASS is IN. | |
379 | |
380 // Answer 1 | |
381 0xc0, 0x0c, // NAME is a pointer to name in Question section. | |
382 0x00, 0x05, // TYPE is CNAME. | |
383 0x00, 0x01, // CLASS is IN. | |
384 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds. | |
385 0x24, 0x74, | |
386 0x00, 0x12, // RDLENGTH is 18 bytes. | |
387 // ghs.l.google.com in DNS format. | |
388 0x03, 'g', 'h', 's', | |
389 0x01, 'l', | |
390 0x06, 'g', 'o', 'o', 'g', 'l', 'e', | |
391 0x03, 'c', 'o', 'm', | |
392 0x00, | |
393 | |
394 // Answer 2 | |
395 0xc0, 0x35, // NAME is a pointer to name in Answer 1. | |
396 0x00, 0x01, // TYPE is A. | |
397 0x00, 0x01, // CLASS is IN. | |
398 0x00, 0x00, // TTL (4 bytes) is 53 seconds. | |
399 0x00, 0x35, | |
400 0x00, 0x04, // RDLENGTH is 4 bytes. | |
401 0x4a, 0x7d, // RDATA is the IP: 74.125.95.121 | |
402 0x5f, 0x79, | |
403 }; | |
404 | |
405 DnsResponse resp; | |
406 memcpy(resp.io_buffer()->data(), response_data, sizeof(response_data)); | |
407 | |
408 EXPECT_EQ(sizeof(dns_protocol::Header) + qsec_length, | |
409 resp.GetResponseOffset()); | |
410 } | |
411 | |
412 // TODO(noamsml): simplify test | |
szym
2013/04/17 22:11:12
I suggest you reuse the response packets in dns_te
Noam Samuel
2013/04/18 19:03:17
Done.
| |
413 TEST(DnsResponseTest, InitParseNoQuery) { | |
414 // This includes \0 at the end. | |
415 const char qname_data[] = "\x0A""codereview""\x08""chromium""\x03""org"; | |
416 const base::StringPiece qname(qname_data, sizeof(qname_data)); | |
417 // Compilers want to copy when binding temporary to const &, so must use heap. | |
418 scoped_ptr<DnsQuery> query(new DnsQuery(0xcafe, qname, dns_protocol::kTypeA)); | |
419 | |
420 const uint8 response_data[] = { | |
421 // Header | |
422 0xca, 0xfe, // ID | |
423 0x81, 0x80, // Standard query response, RA, no error | |
424 0x00, 0x01, // 1 question | |
425 0x00, 0x02, // 2 RRs (answers) | |
426 0x00, 0x00, // 0 authority RRs | |
427 0x00, 0x00, // 0 additional RRs | |
428 | |
429 // Question | |
430 // This part is echoed back from the respective query. | |
431 0x0a, 'c', 'o', 'd', 'e', 'r', 'e', 'v', 'i', 'e', 'w', | |
432 0x08, 'c', 'h', 'r', 'o', 'm', 'i', 'u', 'm', | |
433 0x03, 'o', 'r', 'g', | |
434 0x00, | |
435 0x00, 0x01, // TYPE is A. | |
436 0x00, 0x01, // CLASS is IN. | |
437 | |
438 // Answer 1 | |
439 0xc0, 0x0c, // NAME is a pointer to name in Question section. | |
440 0x00, 0x05, // TYPE is CNAME. | |
441 0x00, 0x01, // CLASS is IN. | |
442 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds. | |
443 0x24, 0x74, | |
444 0x00, 0x12, // RDLENGTH is 18 bytes. | |
445 // ghs.l.google.com in DNS format. | |
446 0x03, 'g', 'h', 's', | |
447 0x01, 'l', | |
448 0x06, 'g', 'o', 'o', 'g', 'l', 'e', | |
449 0x03, 'c', 'o', 'm', | |
450 0x00, | |
451 | |
452 // Answer 2 | |
453 0xc0, 0x35, // NAME is a pointer to name in Answer 1. | |
454 0x00, 0x01, // TYPE is A. | |
455 0x00, 0x01, // CLASS is IN. | |
456 0x00, 0x00, // TTL (4 bytes) is 53 seconds. | |
457 0x00, 0x35, | |
458 0x00, 0x04, // RDLENGTH is 4 bytes. | |
459 0x4a, 0x7d, // RDATA is the IP: 74.125.95.121 | |
460 0x5f, 0x79, | |
461 }; | |
462 | |
463 DnsResponse resp; | |
464 memcpy(resp.io_buffer()->data(), response_data, sizeof(response_data)); | |
465 | |
466 // Accept matching question. | |
467 EXPECT_TRUE(resp.InitParse(sizeof(response_data))); | |
468 EXPECT_TRUE(resp.IsValid()); | |
469 | |
470 // Check header access. | |
471 EXPECT_EQ(0x8180, resp.flags()); | |
472 EXPECT_EQ(0x0, resp.rcode()); | |
473 EXPECT_EQ(2u, resp.answer_count()); | |
474 | |
475 // Check question access. | |
476 EXPECT_EQ(query->qname(), resp.qname()); | |
477 EXPECT_EQ(query->qtype(), resp.qtype()); | |
478 EXPECT_EQ("codereview.chromium.org", resp.GetDottedName()); | |
479 | |
480 DnsResourceRecord record; | |
481 DnsRecordParser parser = resp.Parser(); | |
482 EXPECT_TRUE(parser.ReadRecord(&record)); | |
483 EXPECT_FALSE(parser.AtEnd()); | |
484 EXPECT_TRUE(parser.ReadRecord(&record)); | |
485 EXPECT_TRUE(parser.AtEnd()); | |
486 EXPECT_FALSE(parser.ReadRecord(&record)); | |
487 } | |
488 | |
489 | |
248 void VerifyAddressList(const std::vector<const char*>& ip_addresses, | 490 void VerifyAddressList(const std::vector<const char*>& ip_addresses, |
249 const AddressList& addrlist) { | 491 const AddressList& addrlist) { |
250 ASSERT_EQ(ip_addresses.size(), addrlist.size()); | 492 ASSERT_EQ(ip_addresses.size(), addrlist.size()); |
251 | 493 |
252 for (size_t i = 0; i < addrlist.size(); ++i) { | 494 for (size_t i = 0; i < addrlist.size(); ++i) { |
253 EXPECT_EQ(ip_addresses[i], addrlist[i].ToStringWithoutPort()); | 495 EXPECT_EQ(ip_addresses[i], addrlist[i].ToStringWithoutPort()); |
254 } | 496 } |
255 } | 497 } |
256 | 498 |
257 TEST(DnsResponseTest, ParseToAddressList) { | 499 TEST(DnsResponseTest, ParseToAddressList) { |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
425 AddressList addr_list; | 667 AddressList addr_list; |
426 base::TimeDelta ttl; | 668 base::TimeDelta ttl; |
427 EXPECT_EQ(t.expected_result, | 669 EXPECT_EQ(t.expected_result, |
428 response.ParseToAddressList(&addr_list, &ttl)); | 670 response.ParseToAddressList(&addr_list, &ttl)); |
429 } | 671 } |
430 } | 672 } |
431 | 673 |
432 } // namespace | 674 } // namespace |
433 | 675 |
434 } // namespace net | 676 } // namespace net |
OLD | NEW |