Chromium Code Reviews| 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[1] = v & 0xff; | |
| 21 buf[0] = v >> 8; | |
| 22 } | |
| 23 | |
| 24 } | |
| 25 | |
| 26 // DNS query consists of a 12-byte header followed by a question section, | |
| 27 // for details, see RFC 1035 section 4.1.1. This header template sets RD | |
| 28 // bit, which directs the name server to pursue query recursively, and sets | |
| 29 // the QDCOUNT to 1, meaning the question section has a single entry. The | |
| 30 // first two bytes of the header form a 16-bit query ID to be copied in the | |
| 31 // corresponding reply by the name server; it's set to 0 here and is | |
| 32 // randomized every time the underlying buffer is fetched. | |
| 33 static const char kHeader[] = {0x00, 0x00, 0x01, 0x00, 0x00, 0x01, | |
| 34 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; | |
| 35 static const int kHeaderLen = arraysize(kHeader); | |
| 36 | |
| 37 DnsQuery::DnsQuery(const std::string& hostname, | |
| 38 AddressFamily address_family, | |
| 39 int port) | |
| 40 : port_(port), | |
| 41 id_(0), | |
| 42 qtype_(kDNS_A), | |
|
cbentzel
2011/05/26 17:32:40
I'd add a function such as QtypeFromAddressFamily(
agayev
2011/05/26 22:55:55
Done.
| |
| 43 qclass_(kClassIN) { | |
| 44 if (address_family == ADDRESS_FAMILY_IPV6) | |
| 45 qtype_ = kDNS_AAAA; | |
| 46 else if (address_family != ADDRESS_FAMILY_IPV4) | |
| 47 NOTREACHED(); | |
| 48 | |
| 49 if (!net::DNSDomainFromDot(hostname, &qname_)) | |
| 50 return; | |
| 51 | |
| 52 size_t query_size = kHeaderLen + qname_.size() + | |
| 53 sizeof(qtype_) + sizeof(qclass_); | |
| 54 std::vector<char> query(query_size); | |
|
cbentzel
2011/05/26 17:32:40
Why don't you do this directly into the IOBuffer?
agayev
2011/05/26 22:55:55
Done.
| |
| 55 | |
| 56 size_t iterator = 0; | |
| 57 memcpy(&query[iterator], kHeader, kHeaderLen); | |
| 58 iterator += kHeaderLen; | |
| 59 memcpy(&query[iterator], &qname_[0], qname_.size()); | |
| 60 iterator += qname_.size(); | |
| 61 PackUint16BE(&query[iterator], qtype_); | |
| 62 iterator += sizeof(qtype_); | |
| 63 PackUint16BE(&query[iterator], qclass_); | |
| 64 | |
| 65 io_buffer_ = new IOBufferWithSize(query.size()); | |
| 66 memcpy(io_buffer_->data(), &query[0], query.size()); | |
| 67 | |
| 68 RandomizeId(); | |
| 69 // RFC2181 section 11: A full domain name is limited to 255 octets | |
| 70 // (including the separators). | |
| 71 static const int kMaxQuerySize = kHeaderLen + 255 + | |
| 72 sizeof(qtype_) + sizeof(qclass_); | |
| 73 DCHECK(io_buffer_->size() > kHeaderLen && | |
| 74 io_buffer_->size() <= kMaxQuerySize); | |
| 75 } | |
| 76 | |
| 77 void DnsQuery::RandomizeId() { | |
| 78 DCHECK(IsValid()); | |
| 79 id_ = base::RandUint64() & 0xffff; | |
|
cbentzel
2011/05/26 17:32:40
Is this random enough? I haven't looked.
agayev
2011/05/26 22:55:55
This is the primitive used by all other randomness
| |
| 80 PackUint16BE(io_buffer_->data(), id_); | |
|
cbentzel
2011/05/26 17:32:40
You should probably use htons here.
agayev
2011/05/26 22:55:55
No, since I'm doing it big-endian anyway.
| |
| 81 } | |
| 82 | |
| 83 int DnsQuery::port() const { | |
| 84 DCHECK(IsValid()); | |
| 85 return port_; | |
| 86 } | |
| 87 | |
| 88 uint16 DnsQuery::id() const { | |
| 89 DCHECK(IsValid()); | |
| 90 return id_; | |
| 91 } | |
| 92 | |
| 93 uint16 DnsQuery::qtype() const { | |
| 94 DCHECK(IsValid()); | |
| 95 return qtype_; | |
| 96 } | |
| 97 | |
| 98 uint16 DnsQuery::qclass() const { | |
| 99 DCHECK(IsValid()); | |
| 100 return qclass_; | |
| 101 } | |
| 102 | |
| 103 const std::string& DnsQuery::qname() const { | |
| 104 DCHECK(IsValid()); | |
| 105 return qname_; | |
| 106 } | |
| 107 | |
| 108 size_t DnsQuery::size() const { | |
| 109 DCHECK(IsValid()); | |
| 110 return io_buffer_->size(); | |
| 111 } | |
| 112 | |
| 113 IOBuffer* DnsQuery::io_buffer() { | |
| 114 DCHECK(IsValid()); | |
| 115 RandomizeId(); | |
| 116 return io_buffer_.get(); | |
| 117 } | |
| 118 | |
| 119 char* DnsQuery::data() const { | |
| 120 DCHECK(IsValid()); | |
| 121 return io_buffer_->data(); | |
| 122 } | |
| 123 | |
| 124 } // namespace net | |
| OLD | NEW |