| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/base/dnsrr_resolver.h" | 5 #include "net/base/dnsrr_resolver.h" |
| 6 | 6 |
| 7 #if defined(OS_POSIX) | 7 #if defined(OS_POSIX) |
| 8 #include <resolv.h> | 8 #include <resolv.h> |
| 9 #endif | 9 #endif |
| 10 | 10 |
| (...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 393 | 393 |
| 394 base::Lock lock_; | 394 base::Lock lock_; |
| 395 bool canceled_; | 395 bool canceled_; |
| 396 | 396 |
| 397 int result_; | 397 int result_; |
| 398 RRResponse response_; | 398 RRResponse response_; |
| 399 | 399 |
| 400 DISALLOW_COPY_AND_ASSIGN(RRResolverWorker); | 400 DISALLOW_COPY_AND_ASSIGN(RRResolverWorker); |
| 401 }; | 401 }; |
| 402 | 402 |
| 403 | |
| 404 // A Buffer is used for walking over a DNS packet. | |
| 405 class Buffer { | |
| 406 public: | |
| 407 Buffer(const uint8* p, unsigned len) | |
| 408 : p_(p), | |
| 409 packet_(p), | |
| 410 len_(len), | |
| 411 packet_len_(len) { | |
| 412 } | |
| 413 | |
| 414 bool U8(uint8* v) { | |
| 415 if (len_ < 1) | |
| 416 return false; | |
| 417 *v = *p_; | |
| 418 p_++; | |
| 419 len_--; | |
| 420 return true; | |
| 421 } | |
| 422 | |
| 423 bool U16(uint16* v) { | |
| 424 if (len_ < 2) | |
| 425 return false; | |
| 426 *v = static_cast<uint16>(p_[0]) << 8 | | |
| 427 static_cast<uint16>(p_[1]); | |
| 428 p_ += 2; | |
| 429 len_ -= 2; | |
| 430 return true; | |
| 431 } | |
| 432 | |
| 433 bool U32(uint32* v) { | |
| 434 if (len_ < 4) | |
| 435 return false; | |
| 436 *v = static_cast<uint32>(p_[0]) << 24 | | |
| 437 static_cast<uint32>(p_[1]) << 16 | | |
| 438 static_cast<uint32>(p_[2]) << 8 | | |
| 439 static_cast<uint32>(p_[3]); | |
| 440 p_ += 4; | |
| 441 len_ -= 4; | |
| 442 return true; | |
| 443 } | |
| 444 | |
| 445 bool Skip(unsigned n) { | |
| 446 if (len_ < n) | |
| 447 return false; | |
| 448 p_ += n; | |
| 449 len_ -= n; | |
| 450 return true; | |
| 451 } | |
| 452 | |
| 453 bool Block(base::StringPiece* out, unsigned len) { | |
| 454 if (len_ < len) | |
| 455 return false; | |
| 456 *out = base::StringPiece(reinterpret_cast<const char*>(p_), len); | |
| 457 p_ += len; | |
| 458 len_ -= len; | |
| 459 return true; | |
| 460 } | |
| 461 | |
| 462 // DNSName parses a (possibly compressed) DNS name from the packet. If |name| | |
| 463 // is not NULL, then the name is written into it. See RFC 1035 section 4.1.4. | |
| 464 bool DNSName(std::string* name) { | |
| 465 unsigned jumps = 0; | |
| 466 const uint8* p = p_; | |
| 467 unsigned len = len_; | |
| 468 | |
| 469 if (name) | |
| 470 name->clear(); | |
| 471 | |
| 472 for (;;) { | |
| 473 if (len < 1) | |
| 474 return false; | |
| 475 uint8 d = *p; | |
| 476 p++; | |
| 477 len--; | |
| 478 | |
| 479 // The two couple of bits of the length give the type of the length. It's | |
| 480 // either a direct length or a pointer to the remainder of the name. | |
| 481 if ((d & 0xc0) == 0xc0) { | |
| 482 // This limit matches the depth limit in djbdns. | |
| 483 if (jumps > 100) | |
| 484 return false; | |
| 485 if (len < 1) | |
| 486 return false; | |
| 487 uint16 offset = static_cast<uint16>(d) << 8 | | |
| 488 static_cast<uint16>(p[0]); | |
| 489 offset &= 0x3ff; | |
| 490 p++; | |
| 491 len--; | |
| 492 | |
| 493 if (jumps == 0) { | |
| 494 p_ = p; | |
| 495 len_ = len; | |
| 496 } | |
| 497 jumps++; | |
| 498 | |
| 499 if (offset >= packet_len_) | |
| 500 return false; | |
| 501 p = &packet_[offset]; | |
| 502 len = packet_len_ - offset; | |
| 503 } else if ((d & 0xc0) == 0) { | |
| 504 uint8 label_len = d; | |
| 505 if (len < label_len) | |
| 506 return false; | |
| 507 if (name && label_len) { | |
| 508 if (!name->empty()) | |
| 509 name->append("."); | |
| 510 name->append(reinterpret_cast<const char*>(p), label_len); | |
| 511 } | |
| 512 p += label_len; | |
| 513 len -= label_len; | |
| 514 | |
| 515 if (jumps == 0) { | |
| 516 p_ = p; | |
| 517 len_ = len; | |
| 518 } | |
| 519 | |
| 520 if (label_len == 0) | |
| 521 break; | |
| 522 } else { | |
| 523 return false; | |
| 524 } | |
| 525 } | |
| 526 | |
| 527 return true; | |
| 528 } | |
| 529 | |
| 530 private: | |
| 531 const uint8* p_; | |
| 532 const uint8* const packet_; | |
| 533 unsigned len_; | |
| 534 const unsigned packet_len_; | |
| 535 | |
| 536 DISALLOW_COPY_AND_ASSIGN(Buffer); | |
| 537 }; | |
| 538 | |
| 539 bool RRResponse::HasExpired(const base::Time current_time) const { | 403 bool RRResponse::HasExpired(const base::Time current_time) const { |
| 540 const base::TimeDelta delta(base::TimeDelta::FromSeconds(ttl)); | 404 const base::TimeDelta delta(base::TimeDelta::FromSeconds(ttl)); |
| 541 const base::Time expiry = fetch_time + delta; | 405 const base::Time expiry = fetch_time + delta; |
| 542 return current_time >= expiry; | 406 return current_time >= expiry; |
| 543 } | 407 } |
| 544 | 408 |
| 545 bool RRResponse::ParseFromResponse(const uint8* p, unsigned len, | 409 bool RRResponse::ParseFromResponse(const uint8* p, unsigned len, |
| 546 uint16 rrtype_requested) { | 410 uint16 rrtype_requested) { |
| 547 #if defined(OS_POSIX) | 411 #if defined(OS_POSIX) |
| 548 name.clear(); | 412 name.clear(); |
| 549 ttl = 0; | 413 ttl = 0; |
| 550 dnssec = false; | 414 dnssec = false; |
| 551 negative = false; | 415 negative = false; |
| 552 rrdatas.clear(); | 416 rrdatas.clear(); |
| 553 signatures.clear(); | 417 signatures.clear(); |
| 554 | 418 |
| 555 // RFC 1035 section 4.4.1 | 419 // RFC 1035 section 4.4.1 |
| 556 uint8 flags2; | 420 uint8 flags2; |
| 557 Buffer buf(p, len); | 421 DnsResponseBuffer buf(p, len); |
| 558 if (!buf.Skip(2) || // skip id | 422 if (!buf.Skip(2) || // skip id |
| 559 !buf.Skip(1) || // skip first flags byte | 423 !buf.Skip(1) || // skip first flags byte |
| 560 !buf.U8(&flags2)) { | 424 !buf.U8(&flags2)) { |
| 561 return false; | 425 return false; |
| 562 } | 426 } |
| 563 | 427 |
| 564 // Bit 5 is the Authenticated Data (AD) bit. See | 428 // Bit 5 is the Authenticated Data (AD) bit. See |
| 565 // http://tools.ietf.org/html/rfc2535#section-6.1 | 429 // http://tools.ietf.org/html/rfc2535#section-6.1 |
| 566 if (flags2 & 32) { | 430 if (flags2 & 32) { |
| 567 // AD flag is set. We'll trust it if it came from a local nameserver. | 431 // AD flag is set. We'll trust it if it came from a local nameserver. |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 810 inflight_.erase(j); | 674 inflight_.erase(j); |
| 811 | 675 |
| 812 job->HandleResult(result, response); | 676 job->HandleResult(result, response); |
| 813 delete job; | 677 delete job; |
| 814 } | 678 } |
| 815 | 679 |
| 816 } // namespace net | 680 } // namespace net |
| 817 | 681 |
| 818 DISABLE_RUNNABLE_METHOD_REFCOUNT(net::RRResolverHandle); | 682 DISABLE_RUNNABLE_METHOD_REFCOUNT(net::RRResolverHandle); |
| 819 DISABLE_RUNNABLE_METHOD_REFCOUNT(net::RRResolverWorker); | 683 DISABLE_RUNNABLE_METHOD_REFCOUNT(net::RRResolverWorker); |
| OLD | NEW |