diff options
Diffstat (limited to 'net/dns/dns_query.cc')
-rw-r--r-- | net/dns/dns_query.cc | 111 |
1 files changed, 49 insertions, 62 deletions
diff --git a/net/dns/dns_query.cc b/net/dns/dns_query.cc index 788d653..3cfb5cd 100644 --- a/net/dns/dns_query.cc +++ b/net/dns/dns_query.cc @@ -6,91 +6,78 @@ #include <limits> +#include "net/base/big_endian.h" #include "net/base/dns_util.h" #include "net/base/io_buffer.h" +#include "net/base/sys_byteorder.h" +#include "net/dns/dns_protocol.h" namespace net { -namespace { - -void PackUint16BE(char buf[2], uint16 v) { - buf[0] = v >> 8; - buf[1] = v & 0xff; -} - -uint16 UnpackUint16BE(char buf[2]) { - return static_cast<uint8>(buf[0]) << 8 | static_cast<uint8>(buf[1]); -} - -} // namespace - // DNS query consists of a 12-byte header followed by a question section. // For details, see RFC 1035 section 4.1.1. This header template sets RD // bit, which directs the name server to pursue query recursively, and sets -// the QDCOUNT to 1, meaning the question section has a single entry. The -// first two bytes of the header form a 16-bit random query ID to be copied -// in the corresponding reply by the name server -- randomized during -// DnsQuery construction. -static const char kHeader[] = {0x00, 0x00, 0x01, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; -static const size_t kHeaderSize = arraysize(kHeader); - -DnsQuery::DnsQuery(const std::string& qname, - uint16 qtype, - const RandIntCallback& rand_int_cb) - : qname_size_(qname.size()), - rand_int_cb_(rand_int_cb) { - DCHECK(DnsResponseBuffer(reinterpret_cast<const uint8*>(qname.c_str()), - qname.size()).DNSName(NULL)); - DCHECK(qtype == kDNS_A || qtype == kDNS_AAAA); - - io_buffer_ = new IOBufferWithSize(kHeaderSize + question_size()); - - int byte_offset = 0; - char* buffer_head = io_buffer_->data(); - memcpy(&buffer_head[byte_offset], kHeader, kHeaderSize); - byte_offset += kHeaderSize; - memcpy(&buffer_head[byte_offset], &qname[0], qname_size_); - byte_offset += qname_size_; - PackUint16BE(&buffer_head[byte_offset], qtype); - byte_offset += sizeof(qtype); - PackUint16BE(&buffer_head[byte_offset], kClassIN); - RandomizeId(); +// the QDCOUNT to 1, meaning the question section has a single entry. +DnsQuery::DnsQuery(uint16 id, const base::StringPiece& qname, uint16 qtype) + : qname_size_(qname.size()) { + DCHECK(!DNSDomainToString(qname).empty()); + // QNAME + QTYPE + QCLASS + size_t question_size = qname_size_ + sizeof(uint16) + sizeof(uint16); + io_buffer_ = new IOBufferWithSize(sizeof(dns_protocol::Header) + + question_size); + dns_protocol::Header* header = + reinterpret_cast<dns_protocol::Header*>(io_buffer_->data()); + memset(header, 0, sizeof(dns_protocol::Header)); + header->id = htons(id); + header->flags[0] = 0x1; // RD bit + header->qdcount = htons(1); + + // Write question section after the header. + BigEndianWriter writer(reinterpret_cast<char*>(header + 1), question_size); + writer.WriteBytes(qname.data(), qname.size()); + writer.WriteU16(qtype); + writer.WriteU16(dns_protocol::kClassIN); } DnsQuery::~DnsQuery() { } -uint16 DnsQuery::id() const { - return UnpackUint16BE(&io_buffer_->data()[0]); +DnsQuery* DnsQuery::CloneWithNewId(uint16 id) const { + return new DnsQuery(*this, id); } -uint16 DnsQuery::qtype() const { - return UnpackUint16BE(&io_buffer_->data()[kHeaderSize + qname_size_]); -} - -DnsQuery* DnsQuery::CloneWithNewId() const { - return new DnsQuery(qname(), qtype(), rand_int_cb_); +uint16 DnsQuery::id() const { + const dns_protocol::Header* header = + reinterpret_cast<const dns_protocol::Header*>(io_buffer_->data()); + return ntohs(header->id); } -size_t DnsQuery::question_size() const { - return qname_size_ // QNAME - + sizeof(uint16) // QTYPE - + sizeof(uint16); // QCLASS +base::StringPiece DnsQuery::qname() const { + return base::StringPiece(io_buffer_->data() + sizeof(dns_protocol::Header), + qname_size_); } -const char* DnsQuery::question_data() const { - return &io_buffer_->data()[kHeaderSize]; +uint16 DnsQuery::qtype() const { + uint16 type; + ReadBigEndian<uint16>(io_buffer_->data() + + sizeof(dns_protocol::Header) + + qname_size_, &type); + return type; } -const std::string DnsQuery::qname() const { - return std::string(question_data(), qname_size_); +base::StringPiece DnsQuery::question() const { + return base::StringPiece(io_buffer_->data() + sizeof(dns_protocol::Header), + qname_size_ + sizeof(uint16) + sizeof(uint16)); } -void DnsQuery::RandomizeId() { - PackUint16BE(&io_buffer_->data()[0], rand_int_cb_.Run( - std::numeric_limits<uint16>::min(), - std::numeric_limits<uint16>::max())); +DnsQuery::DnsQuery(const DnsQuery& orig, uint16 id) { + qname_size_ = orig.qname_size_; + io_buffer_ = new IOBufferWithSize(orig.io_buffer()->size()); + memcpy(io_buffer_.get()->data(), orig.io_buffer()->data(), + io_buffer_.get()->size()); + dns_protocol::Header* header = + reinterpret_cast<dns_protocol::Header*>(io_buffer_->data()); + header->id = htons(id); } } // namespace net |