OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/dnsrr_resolver.h" | 5 #include "net/base/dnsrr_resolver.h" |
6 | 6 |
7 #if defined(OS_POSIX) | 7 #if defined(OS_POSIX) |
8 #include <resolv.h> | 8 #include <resolv.h> |
9 #endif | 9 #endif |
10 | 10 |
| 11 #if defined(OS_WIN) |
| 12 #include <windns.h> |
| 13 #endif |
| 14 |
11 #include "base/lock.h" | 15 #include "base/lock.h" |
12 #include "base/message_loop.h" | 16 #include "base/message_loop.h" |
13 #include "base/scoped_ptr.h" | 17 #include "base/scoped_ptr.h" |
14 #include "base/singleton.h" | 18 #include "base/singleton.h" |
15 #include "base/stl_util-inl.h" | 19 #include "base/stl_util-inl.h" |
16 #include "base/string_piece.h" | 20 #include "base/string_piece.h" |
17 #include "base/task.h" | 21 #include "base/task.h" |
18 #include "base/threading/worker_pool.h" | 22 #include "base/threading/worker_pool.h" |
19 #include "net/base/dns_reload_timer.h" | 23 #include "net/base/dns_reload_timer.h" |
20 #include "net/base/dns_util.h" | 24 #include "net/base/dns_util.h" |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
63 // Resolve() | 67 // Resolve() |
64 // |---->------------------------<creates> | 68 // |---->------------------------<creates> |
65 // | | 69 // | |
66 // | | 70 // | |
67 // PostTask | 71 // PostTask |
68 // | 72 // |
69 // (MessageLoop cycles) | 73 // (MessageLoop cycles) |
70 // | 74 // |
71 // Post | 75 // Post |
72 | 76 |
| 77 namespace net { |
73 | 78 |
74 | 79 #if defined(OS_WIN) |
75 namespace net { | 80 // DnsRRIsParsedByWindows returns true if Windows knows how to parse the given |
| 81 // RR type. RR data is returned in a DNS_RECORD structure which may be raw (if |
| 82 // Windows doesn't parse it) or may be a parse result. It's unclear how this |
| 83 // API is intended to evolve in the future. If Windows adds support for new RR |
| 84 // types in a future version a client which expected raw data will break. |
| 85 // See http://msdn.microsoft.com/en-us/library/ms682082(v=vs.85).aspx |
| 86 static bool DnsRRIsParsedByWindows(uint16 rrtype) { |
| 87 // We only cover the types which are defined in dns_util.h |
| 88 switch (rrtype) { |
| 89 case kDNS_CNAME: |
| 90 case kDNS_TXT: |
| 91 case kDNS_DS: |
| 92 case kDNS_RRSIG: |
| 93 case kDNS_DNSKEY: |
| 94 return true; |
| 95 default: |
| 96 return false; |
| 97 } |
| 98 } |
| 99 #endif |
76 | 100 |
77 static const uint16 kClassIN = 1; | 101 static const uint16 kClassIN = 1; |
78 // kMaxCacheEntries is the number of RRResponse objects that we'll cache. | 102 // kMaxCacheEntries is the number of RRResponse objects that we'll cache. |
79 static const unsigned kMaxCacheEntries = 32; | 103 static const unsigned kMaxCacheEntries = 32; |
80 // kNegativeTTLSecs is the number of seconds for which we'll cache a negative | 104 // kNegativeTTLSecs is the number of seconds for which we'll cache a negative |
81 // cache entry. | 105 // cache entry. |
82 static const unsigned kNegativeTTLSecs = 60; | 106 static const unsigned kNegativeTTLSecs = 60; |
83 | 107 |
84 RRResponse::RRResponse() | 108 RRResponse::RRResponse() |
85 : ttl(0), dnssec(false), negative(false) { | 109 : ttl(0), dnssec(false), negative(false) { |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 } | 250 } |
227 | 251 |
228 #else // OS_WIN | 252 #else // OS_WIN |
229 | 253 |
230 void Run() { | 254 void Run() { |
231 if (HandleTestCases()) { | 255 if (HandleTestCases()) { |
232 Finish(); | 256 Finish(); |
233 return; | 257 return; |
234 } | 258 } |
235 | 259 |
| 260 // See http://msdn.microsoft.com/en-us/library/ms682016(v=vs.85).aspx |
| 261 PDNS_RECORD record = NULL; |
| 262 DNS_STATUS status = |
| 263 DnsQuery_A(name_.c_str(), rrtype_, DNS_QUERY_STANDARD, |
| 264 NULL /* pExtra (reserved) */, &record, NULL /* pReserved */); |
236 response_.fetch_time = base::Time::Now(); | 265 response_.fetch_time = base::Time::Now(); |
237 response_.negative = true; | 266 response_.name = name_; |
238 result_ = ERR_NAME_NOT_RESOLVED; | 267 response_.dnssec = false; |
| 268 response_.ttl = 0; |
| 269 |
| 270 if (status != 0) { |
| 271 response_.negative = true; |
| 272 result_ = ERR_NAME_NOT_RESOLVED; |
| 273 } else { |
| 274 response_.negative = false; |
| 275 result_ = OK; |
| 276 for (DNS_RECORD* cur = record; cur; cur = cur->pNext) { |
| 277 if (cur->wType == rrtype_) { |
| 278 response_.ttl = record->dwTtl; |
| 279 // Windows will parse some types of resource records. If we want one |
| 280 // of these types then we have to reserialise the record. |
| 281 switch (rrtype_) { |
| 282 case kDNS_TXT: { |
| 283 // http://msdn.microsoft.com/en-us/library/ms682109(v=vs.85).aspx |
| 284 const DNS_TXT_DATA* txt = &cur->Data.TXT; |
| 285 std::string rrdata; |
| 286 |
| 287 for (DWORD i = 0; i < txt->dwStringCount; i++) { |
| 288 // Although the string is typed as a PWSTR, it's actually just |
| 289 // an ASCII byte-string. Also, the string must be < 256 |
| 290 // elements because the length in the DNS packet is a single |
| 291 // byte. |
| 292 const char* s = reinterpret_cast<char*>(txt->pStringArray[i]); |
| 293 size_t len = strlen(s); |
| 294 DCHECK_LT(len, 256u); |
| 295 char len8 = static_cast<char>(len); |
| 296 rrdata.push_back(len8); |
| 297 rrdata += s; |
| 298 } |
| 299 response_.rrdatas.push_back(rrdata); |
| 300 break; |
| 301 } |
| 302 default: |
| 303 if (DnsRRIsParsedByWindows(rrtype_)) { |
| 304 // Windows parses this type, but we don't have code to unparse |
| 305 // it. |
| 306 NOTREACHED() << "you need to add code for the RR type here"; |
| 307 response_.negative = true; |
| 308 result_ = ERR_INVALID_ARGUMENT; |
| 309 } else { |
| 310 // This type is given to us raw. |
| 311 response_.rrdatas.push_back( |
| 312 std::string(reinterpret_cast<char*>(&cur->Data), |
| 313 cur->wDataLength)); |
| 314 } |
| 315 } |
| 316 } |
| 317 } |
| 318 } |
| 319 |
| 320 DnsRecordListFree(record, DnsFreeRecordList); |
239 Finish(); | 321 Finish(); |
240 } | 322 } |
241 | 323 |
242 #endif // OS_WIN | 324 #endif // OS_WIN |
243 | 325 |
244 // HandleTestCases stuffs in magic test values in the event that the query is | 326 // HandleTestCases stuffs in magic test values in the event that the query is |
245 // from a unittest. | 327 // from a unittest. |
246 bool HandleTestCases() { | 328 bool HandleTestCases() { |
247 if (rrtype_ == kDNS_TESTING) { | 329 if (rrtype_ == kDNS_TESTING) { |
248 response_.fetch_time = base::Time::Now(); | 330 response_.fetch_time = base::Time::Now(); |
(...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
727 inflight_.erase(j); | 809 inflight_.erase(j); |
728 | 810 |
729 job->HandleResult(result, response); | 811 job->HandleResult(result, response); |
730 delete job; | 812 delete job; |
731 } | 813 } |
732 | 814 |
733 } // namespace net | 815 } // namespace net |
734 | 816 |
735 DISABLE_RUNNABLE_METHOD_REFCOUNT(net::RRResolverHandle); | 817 DISABLE_RUNNABLE_METHOD_REFCOUNT(net::RRResolverHandle); |
736 DISABLE_RUNNABLE_METHOD_REFCOUNT(net::RRResolverWorker); | 818 DISABLE_RUNNABLE_METHOD_REFCOUNT(net::RRResolverWorker); |
OLD | NEW |