| 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 |