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 |