| Index: net/base/dns_query.cc
|
| diff --git a/net/base/dns_query.cc b/net/base/dns_query.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..f316fb3a1b14b457f8a6bafd10bfe799eb16ac99
|
| --- /dev/null
|
| +++ b/net/base/dns_query.cc
|
| @@ -0,0 +1,110 @@
|
| +// 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.
|
| +
|
| +#include "net/base/dns_query.h"
|
| +
|
| +#include <string>
|
| +
|
| +#include "base/rand_util.h"
|
| +#include "net/base/address_family.h"
|
| +#include "net/base/dns_util.h"
|
| +
|
| +#include <iostream>
|
| +
|
| +namespace net {
|
| +
|
| +namespace {
|
| +
|
| +void PackUint16BE(char buf[2], uint16 v) {
|
| + buf[0] = v >> 8;
|
| + buf[1] = v & 0xff;
|
| +}
|
| +
|
| +uint16 QTypeFromAddressFamily(AddressFamily address_family) {
|
| + switch (address_family) {
|
| + case ADDRESS_FAMILY_IPV4:
|
| + return kDNS_A;
|
| + case ADDRESS_FAMILY_IPV6:
|
| + return kDNS_AAAA;
|
| + default:
|
| + NOTREACHED() << "Bad address family";
|
| + return kDNS_A;
|
| + }
|
| +}
|
| +
|
| +} // 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 kHeaderLen = arraysize(kHeader);
|
| +
|
| +DnsQuery::DnsQuery(const std::string& hostname,
|
| + AddressFamily address_family,
|
| + int port)
|
| + : port_(port),
|
| + id_(0),
|
| + qtype_(QTypeFromAddressFamily(address_family)),
|
| + hostname_(hostname) {
|
| + std::string qname;
|
| + if (!net::DNSDomainFromDot(hostname, &qname))
|
| + return;
|
| +
|
| + size_t query_size = kHeaderLen + qname.size() +
|
| + sizeof(qtype_) + sizeof(kClassIN);
|
| +
|
| + io_buffer_ = new IOBufferWithSize(query_size);
|
| +
|
| + int byte_offset = 0;
|
| + char* buffer_head = io_buffer_->data();
|
| + memcpy(&buffer_head[byte_offset], kHeader, kHeaderLen);
|
| + byte_offset += kHeaderLen;
|
| + 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);
|
| +
|
| + // Randomize ID.
|
| + id_ = base::RandUint64() & 0xffff;
|
| + PackUint16BE(io_buffer_->data(), id_);
|
| +}
|
| +
|
| +int DnsQuery::port() const {
|
| + DCHECK(IsValid());
|
| + return port_;
|
| +}
|
| +
|
| +uint16 DnsQuery::id() const {
|
| + DCHECK(IsValid());
|
| + return id_;
|
| +}
|
| +
|
| +uint16 DnsQuery::qtype() const {
|
| + DCHECK(IsValid());
|
| + return qtype_;
|
| +}
|
| +
|
| +AddressFamily DnsQuery::address_family() const {
|
| + DCHECK(IsValid());
|
| + return address_family_;
|
| +}
|
| +
|
| +const std::string& DnsQuery::hostname() const {
|
| + DCHECK(IsValid());
|
| + return hostname_;
|
| +}
|
| +
|
| +IOBufferWithSize* DnsQuery::io_buffer() {
|
| + DCHECK(IsValid());
|
| + return io_buffer_.get();
|
| +}
|
| +
|
| +} // namespace net
|
|
|