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