OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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/dns/dns_query.h" | |
6 | |
7 #include <limits> | |
8 | |
9 #include "base/big_endian.h" | |
10 #include "base/sys_byteorder.h" | |
11 #include "net/base/dns_util.h" | |
12 #include "net/base/io_buffer.h" | |
13 #include "net/dns/dns_protocol.h" | |
14 | |
15 namespace net { | |
16 | |
17 // DNS query consists of a 12-byte header followed by a question section. | |
18 // For details, see RFC 1035 section 4.1.1. This header template sets RD | |
19 // bit, which directs the name server to pursue query recursively, and sets | |
20 // the QDCOUNT to 1, meaning the question section has a single entry. | |
21 DnsQuery::DnsQuery(uint16 id, const base::StringPiece& qname, uint16 qtype) | |
22 : qname_size_(qname.size()) { | |
23 DCHECK(!DNSDomainToString(qname).empty()); | |
24 // QNAME + QTYPE + QCLASS | |
25 size_t question_size = qname_size_ + sizeof(uint16) + sizeof(uint16); | |
26 io_buffer_ = new IOBufferWithSize(sizeof(dns_protocol::Header) + | |
27 question_size); | |
28 dns_protocol::Header* header = | |
29 reinterpret_cast<dns_protocol::Header*>(io_buffer_->data()); | |
30 memset(header, 0, sizeof(dns_protocol::Header)); | |
31 header->id = base::HostToNet16(id); | |
32 header->flags = base::HostToNet16(dns_protocol::kFlagRD); | |
33 header->qdcount = base::HostToNet16(1); | |
34 | |
35 // Write question section after the header. | |
36 base::BigEndianWriter writer(reinterpret_cast<char*>(header + 1), | |
37 question_size); | |
38 writer.WriteBytes(qname.data(), qname.size()); | |
39 writer.WriteU16(qtype); | |
40 writer.WriteU16(dns_protocol::kClassIN); | |
41 } | |
42 | |
43 DnsQuery::~DnsQuery() { | |
44 } | |
45 | |
46 DnsQuery* DnsQuery::CloneWithNewId(uint16 id) const { | |
47 return new DnsQuery(*this, id); | |
48 } | |
49 | |
50 uint16 DnsQuery::id() const { | |
51 const dns_protocol::Header* header = | |
52 reinterpret_cast<const dns_protocol::Header*>(io_buffer_->data()); | |
53 return base::NetToHost16(header->id); | |
54 } | |
55 | |
56 base::StringPiece DnsQuery::qname() const { | |
57 return base::StringPiece(io_buffer_->data() + sizeof(dns_protocol::Header), | |
58 qname_size_); | |
59 } | |
60 | |
61 uint16 DnsQuery::qtype() const { | |
62 uint16 type; | |
63 base::ReadBigEndian<uint16>( | |
64 io_buffer_->data() + sizeof(dns_protocol::Header) + qname_size_, &type); | |
65 return type; | |
66 } | |
67 | |
68 base::StringPiece DnsQuery::question() const { | |
69 return base::StringPiece(io_buffer_->data() + sizeof(dns_protocol::Header), | |
70 qname_size_ + sizeof(uint16) + sizeof(uint16)); | |
71 } | |
72 | |
73 DnsQuery::DnsQuery(const DnsQuery& orig, uint16 id) { | |
74 qname_size_ = orig.qname_size_; | |
75 io_buffer_ = new IOBufferWithSize(orig.io_buffer()->size()); | |
76 memcpy(io_buffer_.get()->data(), orig.io_buffer()->data(), | |
77 io_buffer_.get()->size()); | |
78 dns_protocol::Header* header = | |
79 reinterpret_cast<dns_protocol::Header*>(io_buffer_->data()); | |
80 header->id = base::HostToNet16(id); | |
81 } | |
82 | |
83 void DnsQuery::set_flags(uint16 flags) { | |
84 dns_protocol::Header* header = | |
85 reinterpret_cast<dns_protocol::Header*>(io_buffer_->data()); | |
86 header->flags = flags; | |
87 } | |
88 | |
89 } // namespace net | |
OLD | NEW |