summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/base/dns_util.cc118
-rw-r--r--net/base/dns_util.h32
-rw-r--r--net/base/dnsrr_resolver.cc138
3 files changed, 150 insertions, 138 deletions
diff --git a/net/base/dns_util.cc b/net/base/dns_util.cc
index d97d3d2..8051ca1 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
diff --git a/net/base/dns_util.h b/net/base/dns_util.h
index bf4c330..781c104 100644
--- a/net/base/dns_util.h
+++ b/net/base/dns_util.h
@@ -9,6 +9,7 @@
#include <string>
#include "base/basictypes.h"
+#include "base/string_piece.h"
#include "net/base/net_api.h"
namespace net {
@@ -54,6 +55,37 @@ static const uint8 kDNSSEC_RSA_SHA256 = 8;
static const uint8 kDNSSEC_SHA1 = 1;
static const uint8 kDNSSEC_SHA256 = 2;
+// A Buffer is used for walking over a DNS response packet.
+class DnsResponseBuffer {
+ public:
+ DnsResponseBuffer(const uint8* p, unsigned len)
+ : p_(p),
+ packet_(p),
+ len_(len),
+ packet_len_(len) {
+ }
+
+ bool U8(uint8* v);
+ bool U16(uint16* v);
+ bool U32(uint32* v);
+ bool Skip(unsigned n);
+
+ bool Block(base::StringPiece* out, unsigned len);
+
+ // 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 DNSName(std::string* name);
+
+ private:
+ const uint8* p_;
+ const uint8* const packet_;
+ unsigned len_;
+ const unsigned packet_len_;
+
+ DISALLOW_COPY_AND_ASSIGN(DnsResponseBuffer);
+};
+
+
} // namespace net
#endif // NET_BASE_DNS_UTIL_H_
diff --git a/net/base/dnsrr_resolver.cc b/net/base/dnsrr_resolver.cc
index b07df69..454a9fe 100644
--- a/net/base/dnsrr_resolver.cc
+++ b/net/base/dnsrr_resolver.cc
@@ -400,142 +400,6 @@ class RRResolverWorker {
DISALLOW_COPY_AND_ASSIGN(RRResolverWorker);
};
-
-// A Buffer is used for walking over a DNS packet.
-class Buffer {
- public:
- Buffer(const uint8* p, unsigned len)
- : p_(p),
- packet_(p),
- len_(len),
- packet_len_(len) {
- }
-
- bool U8(uint8* v) {
- if (len_ < 1)
- return false;
- *v = *p_;
- p_++;
- len_--;
- return true;
- }
-
- bool 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 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 Skip(unsigned n) {
- if (len_ < n)
- return false;
- p_ += n;
- len_ -= n;
- return true;
- }
-
- bool 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 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;
- }
-
- private:
- const uint8* p_;
- const uint8* const packet_;
- unsigned len_;
- const unsigned packet_len_;
-
- DISALLOW_COPY_AND_ASSIGN(Buffer);
-};
-
bool RRResponse::HasExpired(const base::Time current_time) const {
const base::TimeDelta delta(base::TimeDelta::FromSeconds(ttl));
const base::Time expiry = fetch_time + delta;
@@ -554,7 +418,7 @@ bool RRResponse::ParseFromResponse(const uint8* p, unsigned len,
// RFC 1035 section 4.4.1
uint8 flags2;
- Buffer buf(p, len);
+ DnsResponseBuffer buf(p, len);
if (!buf.Skip(2) || // skip id
!buf.Skip(1) || // skip first flags byte
!buf.U8(&flags2)) {