Chromium Code Reviews| 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..5d03b32201121db6ae4a37a09b28a21d97f74fc1 |
| --- /dev/null |
| +++ b/net/base/dns_query.cc |
| @@ -0,0 +1,131 @@ |
| +// 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[1] = v & 0xff; |
|
agl
2011/05/30 18:35:30
please flip these two lines.
agayev
2011/05/31 15:19:06
Will do.
|
| + buf[0] = v >> 8; |
| +} |
| + |
| +uint16 QTypeFromAddressFamily(AddressFamily address_family) { |
| + uint16 qtype = kDNS_A; |
|
agl
2011/05/30 18:35:30
switch (address_family) {
case ADDRESS_FAMILY_IP
agayev
2011/05/31 15:19:06
Will do.
|
| + if (address_family == ADDRESS_FAMILY_IPV6) |
| + qtype = kDNS_AAAA; |
| + else if (address_family != ADDRESS_FAMILY_IPV4) |
| + NOTREACHED() << "Bad address family"; |
| + return qtype; |
| +} |
| + |
| +} |
| + |
| +// DNS query consists of a 12-byte header followed by a question section, |
|
agl
2011/05/30 18:35:30
s/section,/section./ (and s/for/For/ on the next l
agayev
2011/05/31 15:19:06
Will do.
|
| +// 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 query ID to be copied in the |
| +// corresponding reply by the name server; it's set to 0 here and is |
| +// randomized every time the underlying buffer is fetched. |
| +static const char kHeader[] = {0x00, 0x00, 0x01, 0x00, 0x00, 0x01, |
| + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; |
| +static const int kHeaderLen = arraysize(kHeader); |
|
agl
2011/05/30 18:35:30
s/int/size_t/
agayev
2011/05/31 15:19:06
Same argument as previous one regarding int vs siz
|
| + |
| +DnsQuery::DnsQuery(const std::string& hostname, |
| + AddressFamily address_family, |
| + int port) |
| + : port_(port), |
| + id_(0), |
| + qtype_(QTypeFromAddressFamily(address_family)), |
| + qclass_(kClassIN), |
| + hostname_(hostname) { |
| + std::string qname; |
| + if (!net::DNSDomainFromDot(hostname, &qname)) |
| + return; |
| + |
| + size_t query_size = kHeaderLen + qname.size() + |
| + sizeof(qtype_) + sizeof(qclass_); |
| + |
| + io_buffer_ = new IOBufferWithSize(query_size); |
| + |
| + int iterator = 0; |
| + memcpy(&io_buffer_->data()[iterator], kHeader, kHeaderLen); |
| + iterator += kHeaderLen; |
| + memcpy(&io_buffer_->data()[iterator], &qname[0], qname.size()); |
| + iterator += qname.size(); |
| + PackUint16BE(&io_buffer_->data()[iterator], qtype_); |
| + iterator += sizeof(qtype_); |
| + PackUint16BE(&io_buffer_->data()[iterator], qclass_); |
| + iterator += sizeof(qclass_); |
| + |
| + // RFC2181 section 11: A full domain name is limited to 255 octets |
| + // (including the separators). |
| + static const int kMaxQuerySize = kHeaderLen + 255 + |
|
agl
2011/05/30 18:35:30
DNSDomainFromDot should fail if the name is too lo
agayev
2011/05/31 15:19:06
Will do.
|
| + sizeof(qtype_) + sizeof(qclass_); |
| + |
| + DCHECK(iterator <= kMaxQuerySize); |
|
cbentzel
2011/05/27 15:15:54
This shouldn't be a DCHECK - unless there are chec
agayev
2011/05/31 15:19:06
Will do.
|
| + DCHECK(io_buffer_->size() > kHeaderLen && io_buffer_->size() <= kMaxQuerySize); |
| + |
| + RandomizeId(); |
| +} |
| + |
| +void DnsQuery::RandomizeId() { |
| + DCHECK(IsValid()); |
| + 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_; |
| +} |
| + |
| +uint16 DnsQuery::qclass() const { |
| + DCHECK(IsValid()); |
| + return qclass_; |
| +} |
| + |
| +const std::string& DnsQuery::hostname() const { |
| + DCHECK(IsValid()); |
| + return hostname_; |
| +} |
| + |
| +int DnsQuery::size() const { |
| + DCHECK(IsValid()); |
| + return io_buffer_->size(); |
| +} |
| + |
| +IOBuffer* DnsQuery::io_buffer() { |
| + DCHECK(IsValid()); |
| + RandomizeId(); |
| + return io_buffer_.get(); |
| +} |
| + |
| +char* DnsQuery::data() const { |
| + DCHECK(IsValid()); |
| + return io_buffer_->data(); |
| +} |
| + |
| +} // namespace net |