| Index: net/base/dns_util.cc
|
| diff --git a/net/base/dns_util.cc b/net/base/dns_util.cc
|
| index d97d3d2c9eca4dedd07059df19b0e73bef217431..8051ca1ede10ea7dd1fc72dc55f81baca18c843d 100644
|
| --- a/net/base/dns_util.cc
|
| +++ b/net/base/dns_util.cc
|
| @@ -1,4 +1,4 @@
|
| -// Copyright (c) 2009 The Chromium Authors. All rights reserved.
|
| +// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| @@ -96,4 +96,120 @@ std::string TrimEndingDot(const std::string& host) {
|
| return host_trimmed;
|
| }
|
|
|
| +bool DnsResponseBuffer::U8(uint8* v) {
|
| + if (len_ < 1)
|
| + return false;
|
| + *v = *p_;
|
| + p_++;
|
| + len_--;
|
| + return true;
|
| +}
|
| +
|
| +bool DnsResponseBuffer::U16(uint16* v) {
|
| + if (len_ < 2)
|
| + return false;
|
| + *v = static_cast<uint16>(p_[0]) << 8 |
|
| + static_cast<uint16>(p_[1]);
|
| + p_ += 2;
|
| + len_ -= 2;
|
| + return true;
|
| +}
|
| +
|
| +bool DnsResponseBuffer::U32(uint32* v) {
|
| + if (len_ < 4)
|
| + return false;
|
| + *v = static_cast<uint32>(p_[0]) << 24 |
|
| + static_cast<uint32>(p_[1]) << 16 |
|
| + static_cast<uint32>(p_[2]) << 8 |
|
| + static_cast<uint32>(p_[3]);
|
| + p_ += 4;
|
| + len_ -= 4;
|
| + return true;
|
| +}
|
| +
|
| +bool DnsResponseBuffer::Skip(unsigned n) {
|
| + if (len_ < n)
|
| + return false;
|
| + p_ += n;
|
| + len_ -= n;
|
| + return true;
|
| +}
|
| +
|
| +bool DnsResponseBuffer::Block(base::StringPiece* out, unsigned len) {
|
| + if (len_ < len)
|
| + return false;
|
| + *out = base::StringPiece(reinterpret_cast<const char*>(p_), len);
|
| + p_ += len;
|
| + len_ -= len;
|
| + return true;
|
| +}
|
| +
|
| +// DNSName parses a (possibly compressed) DNS name from the packet. If |name|
|
| +// is not NULL, then the name is written into it. See RFC 1035 section 4.1.4.
|
| +bool DnsResponseBuffer::DNSName(std::string* name) {
|
| + unsigned jumps = 0;
|
| + const uint8* p = p_;
|
| + unsigned len = len_;
|
| +
|
| + if (name)
|
| + name->clear();
|
| +
|
| + for (;;) {
|
| + if (len < 1)
|
| + return false;
|
| + uint8 d = *p;
|
| + p++;
|
| + len--;
|
| +
|
| + // The two couple of bits of the length give the type of the length. It's
|
| + // either a direct length or a pointer to the remainder of the name.
|
| + if ((d & 0xc0) == 0xc0) {
|
| + // This limit matches the depth limit in djbdns.
|
| + if (jumps > 100)
|
| + return false;
|
| + if (len < 1)
|
| + return false;
|
| + uint16 offset = static_cast<uint16>(d) << 8 |
|
| + static_cast<uint16>(p[0]);
|
| + offset &= 0x3ff;
|
| + p++;
|
| + len--;
|
| +
|
| + if (jumps == 0) {
|
| + p_ = p;
|
| + len_ = len;
|
| + }
|
| + jumps++;
|
| +
|
| + if (offset >= packet_len_)
|
| + return false;
|
| + p = &packet_[offset];
|
| + len = packet_len_ - offset;
|
| + } else if ((d & 0xc0) == 0) {
|
| + uint8 label_len = d;
|
| + if (len < label_len)
|
| + return false;
|
| + if (name && label_len) {
|
| + if (!name->empty())
|
| + name->append(".");
|
| + name->append(reinterpret_cast<const char*>(p), label_len);
|
| + }
|
| + p += label_len;
|
| + len -= label_len;
|
| +
|
| + if (jumps == 0) {
|
| + p_ = p;
|
| + len_ = len;
|
| + }
|
| +
|
| + if (label_len == 0)
|
| + break;
|
| + } else {
|
| + return false;
|
| + }
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| } // namespace net
|
|
|