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, |
| 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 |
| 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 |