OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 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/base/dns_response.h" | 5 #include "net/base/dns_response.h" |
6 | 6 |
7 #include "net/base/address_list.h" | |
8 #include "net/base/dns_util.h" | 7 #include "net/base/dns_util.h" |
9 #include "net/base/net_errors.h" | 8 #include "net/base/net_errors.h" |
10 | 9 |
11 namespace net { | 10 namespace net { |
12 | 11 |
13 // RFC 1035, section 4.2.1: Messages carried by UDP are restricted to 512 | 12 // RFC 1035, section 4.2.1: Messages carried by UDP are restricted to 512 |
14 // bytes (not counting the IP nor UDP headers). | 13 // bytes (not counting the IP nor UDP headers). |
15 static const int kMaxResponseSize = 512; | 14 static const int kMaxResponseSize = 512; |
16 | 15 |
17 DnsResponse::DnsResponse(DnsQuery* query) | 16 DnsResponse::DnsResponse(DnsQuery* query) |
18 : query_(query), | 17 : query_(query), |
19 io_buffer_(new IOBufferWithSize(kMaxResponseSize + 1)) { | 18 io_buffer_(new IOBufferWithSize(kMaxResponseSize + 1)) { |
20 DCHECK(query_); | 19 DCHECK(query_); |
21 DCHECK(query_->IsValid()); | |
22 } | 20 } |
23 | 21 |
24 DnsResponse::~DnsResponse() { | 22 DnsResponse::~DnsResponse() { |
25 } | 23 } |
26 | 24 |
27 int DnsResponse::Parse(int nbytes, AddressList* results) { | 25 int DnsResponse::Parse(int nbytes, std::vector<IPAddressNumber>* ip_addresses) { |
28 DCHECK(query_->IsValid()); | |
29 | |
30 // Response includes query, it should be at least that size. | 26 // Response includes query, it should be at least that size. |
31 if (nbytes < query_->io_buffer()->size() || nbytes > kMaxResponseSize) | 27 if (nbytes < query_->io_buffer()->size() || nbytes > kMaxResponseSize) |
32 return ERR_DNS_MALFORMED_RESPONSE; | 28 return ERR_DNS_MALFORMED_RESPONSE; |
33 | 29 |
34 DnsResponseBuffer response(reinterpret_cast<uint8*>(io_buffer_->data()), | 30 DnsResponseBuffer response(reinterpret_cast<uint8*>(io_buffer_->data()), |
35 io_buffer_->size()); | 31 io_buffer_->size()); |
36 uint16 id; | 32 uint16 id; |
37 if (!response.U16(&id) || id != query_->id()) // Make sure IDs match. | 33 if (!response.U16(&id) || id != query_->id()) // Make sure IDs match. |
38 return ERR_DNS_MALFORMED_RESPONSE; | 34 return ERR_DNS_MALFORMED_RESPONSE; |
39 | 35 |
(...skipping 12 matching lines...) Expand all Loading... |
52 if (!response.U16(&query_count) || | 48 if (!response.U16(&query_count) || |
53 !response.U16(&answer_count) || | 49 !response.U16(&answer_count) || |
54 !response.U16(&authority_count) || | 50 !response.U16(&authority_count) || |
55 !response.U16(&additional_count)) { | 51 !response.U16(&additional_count)) { |
56 return ERR_DNS_MALFORMED_RESPONSE; | 52 return ERR_DNS_MALFORMED_RESPONSE; |
57 } | 53 } |
58 | 54 |
59 if (query_count != 1) // Sent a single question, shouldn't have changed. | 55 if (query_count != 1) // Sent a single question, shouldn't have changed. |
60 return ERR_DNS_MALFORMED_RESPONSE; | 56 return ERR_DNS_MALFORMED_RESPONSE; |
61 | 57 |
62 std::string hostname; | 58 base::StringPiece question; // Make sure question section is echoed back. |
63 uint16 qtype, qclass; | 59 if (!response.Block(&question, query_->question_size()) || |
64 if (!response.DNSName(&hostname) || | 60 memcmp(question.data(), query_->question_data(), |
65 !response.U16(&qtype) || | 61 query_->question_size())) { |
66 !response.U16(&qclass) || | |
67 hostname != query_->hostname() || // Make sure Question section | |
68 qtype != query_->qtype() || // echoed back. | |
69 qclass != kClassIN) { | |
70 return ERR_DNS_MALFORMED_RESPONSE; | 62 return ERR_DNS_MALFORMED_RESPONSE; |
71 } | 63 } |
72 | 64 |
73 if (answer_count < 1) | 65 if (answer_count < 1) |
74 return ERR_NAME_NOT_RESOLVED; | 66 return ERR_NAME_NOT_RESOLVED; |
75 | 67 |
76 std::vector<IPAddressNumber> rdatas; | 68 std::vector<IPAddressNumber> rdatas; |
77 while (answer_count--) { | 69 while (answer_count--) { |
78 uint32 ttl; | 70 uint32 ttl; |
79 uint16 rdlength; | 71 uint16 rdlength, qtype, qclass; |
80 if (!response.DNSName(NULL) || | 72 if (!response.DNSName(NULL) || |
81 !response.U16(&qtype) || | 73 !response.U16(&qtype) || |
82 !response.U16(&qclass) || | 74 !response.U16(&qclass) || |
83 !response.U32(&ttl) || | 75 !response.U32(&ttl) || |
84 !response.U16(&rdlength)) { | 76 !response.U16(&rdlength)) { |
85 return ERR_DNS_MALFORMED_RESPONSE; | 77 return ERR_DNS_MALFORMED_RESPONSE; |
86 } | 78 } |
87 | |
88 if (qtype == query_->qtype() && | 79 if (qtype == query_->qtype() && |
89 qclass == kClassIN && | 80 qclass == kClassIN && |
90 (rdlength == kIPv4AddressSize || rdlength == kIPv6AddressSize)) { | 81 (rdlength == kIPv4AddressSize || rdlength == kIPv6AddressSize)) { |
91 base::StringPiece rdata; | 82 base::StringPiece rdata; |
92 if (!response.Block(&rdata, rdlength)) | 83 if (!response.Block(&rdata, rdlength)) |
93 return ERR_DNS_MALFORMED_RESPONSE; | 84 return ERR_DNS_MALFORMED_RESPONSE; |
94 rdatas.push_back(IPAddressNumber(rdata.begin(), rdata.end())); | 85 rdatas.push_back(IPAddressNumber(rdata.begin(), rdata.end())); |
95 } else if (!response.Skip(rdlength)) | 86 } else if (!response.Skip(rdlength)) |
96 return ERR_DNS_MALFORMED_RESPONSE; | 87 return ERR_DNS_MALFORMED_RESPONSE; |
97 } | 88 } |
98 | 89 |
99 if (rdatas.empty()) | 90 if (rdatas.empty()) |
100 return ERR_NAME_NOT_RESOLVED; | 91 return ERR_NAME_NOT_RESOLVED; |
101 | 92 |
102 *results = AddressList::CreateFromIPAddressList(rdatas, query_->port()); | 93 if (ip_addresses) |
| 94 ip_addresses->swap(rdatas); |
103 return OK; | 95 return OK; |
104 } | 96 } |
105 | 97 |
106 } // namespace net | 98 } // namespace net |
OLD | NEW |