OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/dns/dns_response.h" | 5 #include "net/dns/dns_response.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "base/big_endian.h" | 9 #include "base/big_endian.h" |
10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
11 #include "base/sys_byteorder.h" | 11 #include "base/sys_byteorder.h" |
12 #include "net/base/address_list.h" | 12 #include "net/base/address_list.h" |
13 #include "net/base/io_buffer.h" | 13 #include "net/base/io_buffer.h" |
14 #include "net/base/ip_address.h" | 14 #include "net/base/ip_address.h" |
15 #include "net/base/net_errors.h" | 15 #include "net/base/net_errors.h" |
16 #include "net/dns/dns_protocol.h" | 16 #include "net/dns/dns_protocol.h" |
17 #include "net/dns/dns_query.h" | 17 #include "net/dns/dns_query.h" |
18 #include "net/dns/dns_util.h" | 18 #include "net/dns/dns_util.h" |
19 | 19 |
20 namespace net { | 20 namespace net { |
21 | 21 |
22 namespace { | 22 namespace { |
23 | 23 |
| 24 const size_t kHeaderSize = sizeof(dns_protocol::Header); |
| 25 |
24 const uint8_t kRcodeMask = 0xf; | 26 const uint8_t kRcodeMask = 0xf; |
25 | 27 |
26 } // namespace | 28 } // namespace |
27 | 29 |
28 DnsResourceRecord::DnsResourceRecord() { | 30 DnsResourceRecord::DnsResourceRecord() { |
29 } | 31 } |
30 | 32 |
31 DnsResourceRecord::~DnsResourceRecord() { | 33 DnsResourceRecord::~DnsResourceRecord() { |
32 } | 34 } |
33 | 35 |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
178 | 180 |
179 // Match the query id. | 181 // Match the query id. |
180 if (base::NetToHost16(header()->id) != query.id()) | 182 if (base::NetToHost16(header()->id) != query.id()) |
181 return false; | 183 return false; |
182 | 184 |
183 // Match question count. | 185 // Match question count. |
184 if (base::NetToHost16(header()->qdcount) != 1) | 186 if (base::NetToHost16(header()->qdcount) != 1) |
185 return false; | 187 return false; |
186 | 188 |
187 // Match the question section. | 189 // Match the question section. |
188 const size_t hdr_size = sizeof(dns_protocol::Header); | |
189 const base::StringPiece question = query.question(); | 190 const base::StringPiece question = query.question(); |
190 if (question != base::StringPiece(io_buffer_->data() + hdr_size, | 191 if (question != |
191 question.size())) { | 192 base::StringPiece(io_buffer_->data() + kHeaderSize, question.size())) { |
192 return false; | 193 return false; |
193 } | 194 } |
194 | 195 |
195 // Construct the parser. | 196 // Construct the parser. |
196 parser_ = DnsRecordParser(io_buffer_->data(), | 197 parser_ = DnsRecordParser(io_buffer_->data(), nbytes, |
197 nbytes, | 198 kHeaderSize + question.size()); |
198 hdr_size + question.size()); | |
199 return true; | 199 return true; |
200 } | 200 } |
201 | 201 |
202 bool DnsResponse::InitParseWithoutQuery(int nbytes) { | 202 bool DnsResponse::InitParseWithoutQuery(int nbytes) { |
203 DCHECK_GE(nbytes, 0); | 203 DCHECK_GE(nbytes, 0); |
204 | 204 |
205 size_t hdr_size = sizeof(dns_protocol::Header); | 205 if (nbytes < static_cast<int>(kHeaderSize) || nbytes >= io_buffer_->size()) |
206 | |
207 if (nbytes < static_cast<int>(hdr_size) || nbytes >= io_buffer_->size()) | |
208 return false; | 206 return false; |
209 | 207 |
210 parser_ = DnsRecordParser( | 208 parser_ = DnsRecordParser(io_buffer_->data(), nbytes, kHeaderSize); |
211 io_buffer_->data(), nbytes, hdr_size); | |
212 | 209 |
213 unsigned qdcount = base::NetToHost16(header()->qdcount); | 210 unsigned qdcount = base::NetToHost16(header()->qdcount); |
214 for (unsigned i = 0; i < qdcount; ++i) { | 211 for (unsigned i = 0; i < qdcount; ++i) { |
215 if (!parser_.SkipQuestion()) { | 212 if (!parser_.SkipQuestion()) { |
216 parser_ = DnsRecordParser(); // Make parser invalid again. | 213 parser_ = DnsRecordParser(); // Make parser invalid again. |
217 return false; | 214 return false; |
218 } | 215 } |
219 } | 216 } |
220 | 217 |
221 return true; | 218 return true; |
(...skipping 21 matching lines...) Expand all Loading... |
243 unsigned DnsResponse::additional_answer_count() const { | 240 unsigned DnsResponse::additional_answer_count() const { |
244 DCHECK(parser_.IsValid()); | 241 DCHECK(parser_.IsValid()); |
245 return base::NetToHost16(header()->arcount); | 242 return base::NetToHost16(header()->arcount); |
246 } | 243 } |
247 | 244 |
248 base::StringPiece DnsResponse::qname() const { | 245 base::StringPiece DnsResponse::qname() const { |
249 DCHECK(parser_.IsValid()); | 246 DCHECK(parser_.IsValid()); |
250 // The response is HEADER QNAME QTYPE QCLASS ANSWER. | 247 // The response is HEADER QNAME QTYPE QCLASS ANSWER. |
251 // |parser_| is positioned at the beginning of ANSWER, so the end of QNAME is | 248 // |parser_| is positioned at the beginning of ANSWER, so the end of QNAME is |
252 // two uint16_ts before it. | 249 // two uint16_ts before it. |
253 const size_t hdr_size = sizeof(dns_protocol::Header); | |
254 const size_t qname_size = | 250 const size_t qname_size = |
255 parser_.GetOffset() - 2 * sizeof(uint16_t) - hdr_size; | 251 parser_.GetOffset() - 2 * sizeof(uint16_t) - kHeaderSize; |
256 return base::StringPiece(io_buffer_->data() + hdr_size, qname_size); | 252 return base::StringPiece(io_buffer_->data() + kHeaderSize, qname_size); |
257 } | 253 } |
258 | 254 |
259 uint16_t DnsResponse::qtype() const { | 255 uint16_t DnsResponse::qtype() const { |
260 DCHECK(parser_.IsValid()); | 256 DCHECK(parser_.IsValid()); |
261 // QTYPE starts where QNAME ends. | 257 // QTYPE starts where QNAME ends. |
262 const size_t type_offset = parser_.GetOffset() - 2 * sizeof(uint16_t); | 258 const size_t type_offset = parser_.GetOffset() - 2 * sizeof(uint16_t); |
263 uint16_t type; | 259 uint16_t type; |
264 base::ReadBigEndian<uint16_t>(io_buffer_->data() + type_offset, &type); | 260 base::ReadBigEndian<uint16_t>(io_buffer_->data() + type_offset, &type); |
265 return type; | 261 return type; |
266 } | 262 } |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
340 | 336 |
341 // getcanonname in eglibc returns the first owner name of an A or AAAA RR. | 337 // getcanonname in eglibc returns the first owner name of an A or AAAA RR. |
342 // If the response passed all the checks so far, then |expected_name| is it. | 338 // If the response passed all the checks so far, then |expected_name| is it. |
343 *addr_list = AddressList::CreateFromIPAddressList(ip_addresses, | 339 *addr_list = AddressList::CreateFromIPAddressList(ip_addresses, |
344 expected_name); | 340 expected_name); |
345 *ttl = base::TimeDelta::FromSeconds(ttl_sec); | 341 *ttl = base::TimeDelta::FromSeconds(ttl_sec); |
346 return DNS_PARSE_OK; | 342 return DNS_PARSE_OK; |
347 } | 343 } |
348 | 344 |
349 } // namespace net | 345 } // namespace net |
OLD | NEW |