diff options
author | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-23 15:51:34 +0000 |
---|---|---|
committer | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-23 15:51:34 +0000 |
commit | c284be3f28d9c9eea24b844c7aeb9c004ce2de9f (patch) | |
tree | 901986c10f09beb41d1a8a2454ff6a452d0a6bb6 /net/base/dns_util.cc | |
parent | deb40835d8e2f88901af6934b659f0eb89fa2177 (diff) | |
download | chromium_src-c284be3f28d9c9eea24b844c7aeb9c004ce2de9f.zip chromium_src-c284be3f28d9c9eea24b844c7aeb9c004ce2de9f.tar.gz chromium_src-c284be3f28d9c9eea24b844c7aeb9c004ce2de9f.tar.bz2 |
Revert "net: remove DnsRRResolver"
This reverts commit r114845.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@123247 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/base/dns_util.cc')
-rw-r--r-- | net/base/dns_util.cc | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/net/base/dns_util.cc b/net/base/dns_util.cc index 816095b..a49ada8 100644 --- a/net/base/dns_util.cc +++ b/net/base/dns_util.cc @@ -101,4 +101,120 @@ std::string TrimEndingDot(const base::StringPiece& host) { return host_trimmed.as_string(); } +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 |