OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "net/base/dns_query.h" |
| 6 |
| 7 #include <string> |
| 8 |
| 9 #include "base/rand_util.h" |
| 10 #include "net/base/address_family.h" |
| 11 #include "net/base/dns_util.h" |
| 12 |
| 13 #include <iostream> |
| 14 |
| 15 namespace net { |
| 16 |
| 17 namespace { |
| 18 |
| 19 void PackUint16BE(char buf[2], uint16 v) { |
| 20 buf[0] = v >> 8; |
| 21 buf[1] = v & 0xff; |
| 22 } |
| 23 |
| 24 uint16 QTypeFromAddressFamily(AddressFamily address_family) { |
| 25 switch (address_family) { |
| 26 case ADDRESS_FAMILY_IPV4: |
| 27 return kDNS_A; |
| 28 case ADDRESS_FAMILY_IPV6: |
| 29 return kDNS_AAAA; |
| 30 default: |
| 31 NOTREACHED() << "Bad address family"; |
| 32 return kDNS_A; |
| 33 } |
| 34 } |
| 35 |
| 36 } // namespace |
| 37 |
| 38 // DNS query consists of a 12-byte header followed by a question section. |
| 39 // For details, see RFC 1035 section 4.1.1. This header template sets RD |
| 40 // bit, which directs the name server to pursue query recursively, and sets |
| 41 // the QDCOUNT to 1, meaning the question section has a single entry. The |
| 42 // first two bytes of the header form a 16-bit random query ID to be copied |
| 43 // in the corresponding reply by the name server -- randomized during |
| 44 // DnsQuery construction. |
| 45 static const char kHeader[] = {0x00, 0x00, 0x01, 0x00, 0x00, 0x01, |
| 46 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; |
| 47 static const size_t kHeaderLen = arraysize(kHeader); |
| 48 |
| 49 DnsQuery::DnsQuery(const std::string& hostname, |
| 50 AddressFamily address_family, |
| 51 int port) |
| 52 : port_(port), |
| 53 id_(0), |
| 54 qtype_(QTypeFromAddressFamily(address_family)), |
| 55 hostname_(hostname) { |
| 56 std::string qname; |
| 57 if (!net::DNSDomainFromDot(hostname, &qname)) |
| 58 return; |
| 59 |
| 60 size_t query_size = kHeaderLen + qname.size() + |
| 61 sizeof(qtype_) + sizeof(kClassIN); |
| 62 |
| 63 io_buffer_ = new IOBufferWithSize(query_size); |
| 64 |
| 65 int byte_offset = 0; |
| 66 char* buffer_head = io_buffer_->data(); |
| 67 memcpy(&buffer_head[byte_offset], kHeader, kHeaderLen); |
| 68 byte_offset += kHeaderLen; |
| 69 memcpy(&buffer_head[byte_offset], &qname[0], qname.size()); |
| 70 byte_offset += qname.size(); |
| 71 PackUint16BE(&buffer_head[byte_offset], qtype_); |
| 72 byte_offset += sizeof(qtype_); |
| 73 PackUint16BE(&buffer_head[byte_offset], kClassIN); |
| 74 |
| 75 // Randomize ID. |
| 76 id_ = base::RandUint64() & 0xffff; |
| 77 PackUint16BE(io_buffer_->data(), id_); |
| 78 } |
| 79 |
| 80 int DnsQuery::port() const { |
| 81 DCHECK(IsValid()); |
| 82 return port_; |
| 83 } |
| 84 |
| 85 uint16 DnsQuery::id() const { |
| 86 DCHECK(IsValid()); |
| 87 return id_; |
| 88 } |
| 89 |
| 90 uint16 DnsQuery::qtype() const { |
| 91 DCHECK(IsValid()); |
| 92 return qtype_; |
| 93 } |
| 94 |
| 95 AddressFamily DnsQuery::address_family() const { |
| 96 DCHECK(IsValid()); |
| 97 return address_family_; |
| 98 } |
| 99 |
| 100 const std::string& DnsQuery::hostname() const { |
| 101 DCHECK(IsValid()); |
| 102 return hostname_; |
| 103 } |
| 104 |
| 105 IOBufferWithSize* DnsQuery::io_buffer() { |
| 106 DCHECK(IsValid()); |
| 107 return io_buffer_.get(); |
| 108 } |
| 109 |
| 110 } // namespace net |
OLD | NEW |