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/host_resolver_impl.h" | 5 #include "net/dns/host_resolver_impl.h" |
6 | 6 |
7 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
8 #include <Winsock2.h> | 8 #include <Winsock2.h> |
9 #elif defined(OS_POSIX) | 9 #elif defined(OS_POSIX) |
10 #include <netdb.h> | 10 #include <netdb.h> |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 | 135 |
136 enum DnsResolveStatus { | 136 enum DnsResolveStatus { |
137 RESOLVE_STATUS_DNS_SUCCESS = 0, | 137 RESOLVE_STATUS_DNS_SUCCESS = 0, |
138 RESOLVE_STATUS_PROC_SUCCESS, | 138 RESOLVE_STATUS_PROC_SUCCESS, |
139 RESOLVE_STATUS_FAIL, | 139 RESOLVE_STATUS_FAIL, |
140 RESOLVE_STATUS_SUSPECT_NETBIOS, | 140 RESOLVE_STATUS_SUSPECT_NETBIOS, |
141 RESOLVE_STATUS_MAX | 141 RESOLVE_STATUS_MAX |
142 }; | 142 }; |
143 | 143 |
144 void UmaAsyncDnsResolveStatus(DnsResolveStatus result) { | 144 void UmaAsyncDnsResolveStatus(DnsResolveStatus result) { |
145 UMA_HISTOGRAM_ENUMERATION("AsyncDNS.ResolveStatus", | 145 UMA_HISTOGRAM_ENUMERATION( |
146 result, | 146 "AsyncDNS.ResolveStatus", result, RESOLVE_STATUS_MAX); |
147 RESOLVE_STATUS_MAX); | |
148 } | 147 } |
149 | 148 |
150 bool ResemblesNetBIOSName(const std::string& hostname) { | 149 bool ResemblesNetBIOSName(const std::string& hostname) { |
151 return (hostname.size() < 16) && (hostname.find('.') == std::string::npos); | 150 return (hostname.size() < 16) && (hostname.find('.') == std::string::npos); |
152 } | 151 } |
153 | 152 |
154 // True if |hostname| ends with either ".local" or ".local.". | 153 // True if |hostname| ends with either ".local" or ".local.". |
155 bool ResemblesMulticastDNSName(const std::string& hostname) { | 154 bool ResemblesMulticastDNSName(const std::string& hostname) { |
156 DCHECK(!hostname.empty()); | 155 DCHECK(!hostname.empty()); |
157 const char kSuffix[] = ".local."; | 156 const char kSuffix[] = ".local."; |
158 const size_t kSuffixLen = sizeof(kSuffix) - 1; | 157 const size_t kSuffixLen = sizeof(kSuffix) - 1; |
159 const size_t kSuffixLenTrimmed = kSuffixLen - 1; | 158 const size_t kSuffixLenTrimmed = kSuffixLen - 1; |
160 if (hostname[hostname.size() - 1] == '.') { | 159 if (hostname[hostname.size() - 1] == '.') { |
161 return hostname.size() > kSuffixLen && | 160 return hostname.size() > kSuffixLen && |
162 !hostname.compare(hostname.size() - kSuffixLen, kSuffixLen, kSuffix); | 161 !hostname.compare(hostname.size() - kSuffixLen, kSuffixLen, kSuffix); |
163 } | 162 } |
164 return hostname.size() > kSuffixLenTrimmed && | 163 return hostname.size() > kSuffixLenTrimmed && |
165 !hostname.compare(hostname.size() - kSuffixLenTrimmed, kSuffixLenTrimmed, | 164 !hostname.compare(hostname.size() - kSuffixLenTrimmed, |
166 kSuffix, kSuffixLenTrimmed); | 165 kSuffixLenTrimmed, |
| 166 kSuffix, |
| 167 kSuffixLenTrimmed); |
167 } | 168 } |
168 | 169 |
169 // Attempts to connect a UDP socket to |dest|:53. | 170 // Attempts to connect a UDP socket to |dest|:53. |
170 bool IsGloballyReachable(const IPAddressNumber& dest, | 171 bool IsGloballyReachable(const IPAddressNumber& dest, |
171 const BoundNetLog& net_log) { | 172 const BoundNetLog& net_log) { |
172 scoped_ptr<DatagramClientSocket> socket( | 173 scoped_ptr<DatagramClientSocket> socket( |
173 ClientSocketFactory::GetDefaultFactory()->CreateDatagramClientSocket( | 174 ClientSocketFactory::GetDefaultFactory()->CreateDatagramClientSocket( |
174 DatagramSocket::DEFAULT_BIND, | 175 DatagramSocket::DEFAULT_BIND, |
175 RandIntCallback(), | 176 RandIntCallback(), |
176 net_log.net_log(), | 177 net_log.net_log(), |
177 net_log.source())); | 178 net_log.source())); |
178 int rv = socket->Connect(IPEndPoint(dest, 53)); | 179 int rv = socket->Connect(IPEndPoint(dest, 53)); |
179 if (rv != OK) | 180 if (rv != OK) |
180 return false; | 181 return false; |
181 IPEndPoint endpoint; | 182 IPEndPoint endpoint; |
182 rv = socket->GetLocalAddress(&endpoint); | 183 rv = socket->GetLocalAddress(&endpoint); |
183 if (rv != OK) | 184 if (rv != OK) |
184 return false; | 185 return false; |
185 DCHECK(endpoint.GetFamily() == ADDRESS_FAMILY_IPV6); | 186 DCHECK(endpoint.GetFamily() == ADDRESS_FAMILY_IPV6); |
186 const IPAddressNumber& address = endpoint.address(); | 187 const IPAddressNumber& address = endpoint.address(); |
187 bool is_link_local = (address[0] == 0xFE) && ((address[1] & 0xC0) == 0x80); | 188 bool is_link_local = (address[0] == 0xFE) && ((address[1] & 0xC0) == 0x80); |
188 if (is_link_local) | 189 if (is_link_local) |
189 return false; | 190 return false; |
190 const uint8 kTeredoPrefix[] = { 0x20, 0x01, 0, 0 }; | 191 const uint8 kTeredoPrefix[] = {0x20, 0x01, 0, 0}; |
191 bool is_teredo = std::equal(kTeredoPrefix, | 192 bool is_teredo = std::equal( |
192 kTeredoPrefix + arraysize(kTeredoPrefix), | 193 kTeredoPrefix, kTeredoPrefix + arraysize(kTeredoPrefix), address.begin()); |
193 address.begin()); | |
194 if (is_teredo) | 194 if (is_teredo) |
195 return false; | 195 return false; |
196 return true; | 196 return true; |
197 } | 197 } |
198 | 198 |
199 // Provide a common macro to simplify code and readability. We must use a | 199 // Provide a common macro to simplify code and readability. We must use a |
200 // macro as the underlying HISTOGRAM macro creates static variables. | 200 // macro as the underlying HISTOGRAM macro creates static variables. |
201 #define DNS_HISTOGRAM(name, time) UMA_HISTOGRAM_CUSTOM_TIMES(name, time, \ | 201 #define DNS_HISTOGRAM(name, time) \ |
202 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromHours(1), 100) | 202 UMA_HISTOGRAM_CUSTOM_TIMES(name, \ |
| 203 time, \ |
| 204 base::TimeDelta::FromMilliseconds(1), \ |
| 205 base::TimeDelta::FromHours(1), \ |
| 206 100) |
203 | 207 |
204 // A macro to simplify code and readability. | 208 // A macro to simplify code and readability. |
205 #define DNS_HISTOGRAM_BY_PRIORITY(basename, priority, time) \ | 209 #define DNS_HISTOGRAM_BY_PRIORITY(basename, priority, time) \ |
206 do { \ | 210 do { \ |
207 switch (priority) { \ | 211 switch (priority) { \ |
208 case HIGHEST: DNS_HISTOGRAM(basename "_HIGHEST", time); break; \ | 212 case HIGHEST: \ |
209 case MEDIUM: DNS_HISTOGRAM(basename "_MEDIUM", time); break; \ | 213 DNS_HISTOGRAM(basename "_HIGHEST", time); \ |
210 case LOW: DNS_HISTOGRAM(basename "_LOW", time); break; \ | 214 break; \ |
211 case LOWEST: DNS_HISTOGRAM(basename "_LOWEST", time); break; \ | 215 case MEDIUM: \ |
212 case IDLE: DNS_HISTOGRAM(basename "_IDLE", time); break; \ | 216 DNS_HISTOGRAM(basename "_MEDIUM", time); \ |
213 default: NOTREACHED(); break; \ | 217 break; \ |
214 } \ | 218 case LOW: \ |
215 DNS_HISTOGRAM(basename, time); \ | 219 DNS_HISTOGRAM(basename "_LOW", time); \ |
| 220 break; \ |
| 221 case LOWEST: \ |
| 222 DNS_HISTOGRAM(basename "_LOWEST", time); \ |
| 223 break; \ |
| 224 case IDLE: \ |
| 225 DNS_HISTOGRAM(basename "_IDLE", time); \ |
| 226 break; \ |
| 227 default: \ |
| 228 NOTREACHED(); \ |
| 229 break; \ |
| 230 } \ |
| 231 DNS_HISTOGRAM(basename, time); \ |
216 } while (0) | 232 } while (0) |
217 | 233 |
218 // Record time from Request creation until a valid DNS response. | 234 // Record time from Request creation until a valid DNS response. |
219 void RecordTotalTime(bool had_dns_config, | 235 void RecordTotalTime(bool had_dns_config, |
220 bool speculative, | 236 bool speculative, |
221 base::TimeDelta duration) { | 237 base::TimeDelta duration) { |
222 if (had_dns_config) { | 238 if (had_dns_config) { |
223 if (speculative) { | 239 if (speculative) { |
224 DNS_HISTOGRAM("AsyncDNS.TotalTime_speculative", duration); | 240 DNS_HISTOGRAM("AsyncDNS.TotalTime_speculative", duration); |
225 } else { | 241 } else { |
226 DNS_HISTOGRAM("AsyncDNS.TotalTime", duration); | 242 DNS_HISTOGRAM("AsyncDNS.TotalTime", duration); |
227 } | 243 } |
228 } else { | 244 } else { |
229 if (speculative) { | 245 if (speculative) { |
230 DNS_HISTOGRAM("DNS.TotalTime_speculative", duration); | 246 DNS_HISTOGRAM("DNS.TotalTime_speculative", duration); |
231 } else { | 247 } else { |
232 DNS_HISTOGRAM("DNS.TotalTime", duration); | 248 DNS_HISTOGRAM("DNS.TotalTime", duration); |
233 } | 249 } |
234 } | 250 } |
235 } | 251 } |
236 | 252 |
237 void RecordTTL(base::TimeDelta ttl) { | 253 void RecordTTL(base::TimeDelta ttl) { |
238 UMA_HISTOGRAM_CUSTOM_TIMES("AsyncDNS.TTL", ttl, | 254 UMA_HISTOGRAM_CUSTOM_TIMES("AsyncDNS.TTL", |
| 255 ttl, |
239 base::TimeDelta::FromSeconds(1), | 256 base::TimeDelta::FromSeconds(1), |
240 base::TimeDelta::FromDays(1), 100); | 257 base::TimeDelta::FromDays(1), |
| 258 100); |
241 } | 259 } |
242 | 260 |
243 bool ConfigureAsyncDnsNoFallbackFieldTrial() { | 261 bool ConfigureAsyncDnsNoFallbackFieldTrial() { |
244 const bool kDefault = false; | 262 const bool kDefault = false; |
245 | 263 |
246 // Configure the AsyncDns field trial as follows: | 264 // Configure the AsyncDns field trial as follows: |
247 // groups AsyncDnsNoFallbackA and AsyncDnsNoFallbackB: return true, | 265 // groups AsyncDnsNoFallbackA and AsyncDnsNoFallbackB: return true, |
248 // groups AsyncDnsA and AsyncDnsB: return false, | 266 // groups AsyncDnsA and AsyncDnsB: return false, |
249 // groups SystemDnsA and SystemDnsB: return false, | 267 // groups SystemDnsA and SystemDnsB: return false, |
250 // otherwise (trial absent): return default. | 268 // otherwise (trial absent): return default. |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 | 310 |
293 dict->SetInteger("net_error", net_error); | 311 dict->SetInteger("net_error", net_error); |
294 | 312 |
295 if (os_error) { | 313 if (os_error) { |
296 dict->SetInteger("os_error", os_error); | 314 dict->SetInteger("os_error", os_error); |
297 #if defined(OS_POSIX) | 315 #if defined(OS_POSIX) |
298 dict->SetString("os_error_string", gai_strerror(os_error)); | 316 dict->SetString("os_error_string", gai_strerror(os_error)); |
299 #elif defined(OS_WIN) | 317 #elif defined(OS_WIN) |
300 // Map the error code to a human-readable string. | 318 // Map the error code to a human-readable string. |
301 LPWSTR error_string = NULL; | 319 LPWSTR error_string = NULL; |
302 int size = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | | 320 int size = FormatMessage( |
303 FORMAT_MESSAGE_FROM_SYSTEM, | 321 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, |
304 0, // Use the internal message table. | 322 0, // Use the internal message table. |
305 os_error, | 323 os_error, |
306 0, // Use default language. | 324 0, // Use default language. |
307 (LPWSTR)&error_string, | 325 (LPWSTR) & error_string, |
308 0, // Buffer size. | 326 0, // Buffer size. |
309 0); // Arguments (unused). | 327 0); // Arguments (unused). |
310 dict->SetString("os_error_string", base::WideToUTF8(error_string)); | 328 dict->SetString("os_error_string", base::WideToUTF8(error_string)); |
311 LocalFree(error_string); | 329 LocalFree(error_string); |
312 #endif | 330 #endif |
313 } | 331 } |
314 | 332 |
315 return dict; | 333 return dict; |
316 } | 334 } |
317 | 335 |
318 // Creates NetLog parameters when the DnsTask failed. | 336 // Creates NetLog parameters when the DnsTask failed. |
319 base::Value* NetLogDnsTaskFailedCallback(int net_error, | 337 base::Value* NetLogDnsTaskFailedCallback(int net_error, |
320 int dns_error, | 338 int dns_error, |
321 NetLog::LogLevel /* log_level */) { | 339 NetLog::LogLevel /* log_level */) { |
322 base::DictionaryValue* dict = new base::DictionaryValue(); | 340 base::DictionaryValue* dict = new base::DictionaryValue(); |
323 dict->SetInteger("net_error", net_error); | 341 dict->SetInteger("net_error", net_error); |
324 if (dns_error) | 342 if (dns_error) |
325 dict->SetInteger("dns_error", dns_error); | 343 dict->SetInteger("dns_error", dns_error); |
326 return dict; | 344 return dict; |
327 }; | 345 }; |
328 | 346 |
329 // Creates NetLog parameters containing the information in a RequestInfo object, | 347 // Creates NetLog parameters containing the information in a RequestInfo object, |
330 // along with the associated NetLog::Source. | 348 // along with the associated NetLog::Source. |
331 base::Value* NetLogRequestInfoCallback(const NetLog::Source& source, | 349 base::Value* NetLogRequestInfoCallback(const NetLog::Source& source, |
332 const HostResolver::RequestInfo* info, | 350 const HostResolver::RequestInfo* info, |
333 NetLog::LogLevel /* log_level */) { | 351 NetLog::LogLevel /* log_level */) { |
334 base::DictionaryValue* dict = new base::DictionaryValue(); | 352 base::DictionaryValue* dict = new base::DictionaryValue(); |
335 source.AddToEventParameters(dict); | 353 source.AddToEventParameters(dict); |
336 | 354 |
337 dict->SetString("host", info->host_port_pair().ToString()); | 355 dict->SetString("host", info->host_port_pair().ToString()); |
338 dict->SetInteger("address_family", | 356 dict->SetInteger("address_family", static_cast<int>(info->address_family())); |
339 static_cast<int>(info->address_family())); | |
340 dict->SetBoolean("allow_cached_response", info->allow_cached_response()); | 357 dict->SetBoolean("allow_cached_response", info->allow_cached_response()); |
341 dict->SetBoolean("is_speculative", info->is_speculative()); | 358 dict->SetBoolean("is_speculative", info->is_speculative()); |
342 return dict; | 359 return dict; |
343 } | 360 } |
344 | 361 |
345 // Creates NetLog parameters for the creation of a HostResolverImpl::Job. | 362 // Creates NetLog parameters for the creation of a HostResolverImpl::Job. |
346 base::Value* NetLogJobCreationCallback(const NetLog::Source& source, | 363 base::Value* NetLogJobCreationCallback(const NetLog::Source& source, |
347 const std::string* host, | 364 const std::string* host, |
348 NetLog::LogLevel /* log_level */) { | 365 NetLog::LogLevel /* log_level */) { |
349 base::DictionaryValue* dict = new base::DictionaryValue(); | 366 base::DictionaryValue* dict = new base::DictionaryValue(); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
406 //----------------------------------------------------------------------------- | 423 //----------------------------------------------------------------------------- |
407 | 424 |
408 // Keeps track of the highest priority. | 425 // Keeps track of the highest priority. |
409 class PriorityTracker { | 426 class PriorityTracker { |
410 public: | 427 public: |
411 explicit PriorityTracker(RequestPriority initial_priority) | 428 explicit PriorityTracker(RequestPriority initial_priority) |
412 : highest_priority_(initial_priority), total_count_(0) { | 429 : highest_priority_(initial_priority), total_count_(0) { |
413 memset(counts_, 0, sizeof(counts_)); | 430 memset(counts_, 0, sizeof(counts_)); |
414 } | 431 } |
415 | 432 |
416 RequestPriority highest_priority() const { | 433 RequestPriority highest_priority() const { return highest_priority_; } |
417 return highest_priority_; | |
418 } | |
419 | 434 |
420 size_t total_count() const { | 435 size_t total_count() const { return total_count_; } |
421 return total_count_; | |
422 } | |
423 | 436 |
424 void Add(RequestPriority req_priority) { | 437 void Add(RequestPriority req_priority) { |
425 ++total_count_; | 438 ++total_count_; |
426 ++counts_[req_priority]; | 439 ++counts_[req_priority]; |
427 if (highest_priority_ < req_priority) | 440 if (highest_priority_ < req_priority) |
428 highest_priority_ = req_priority; | 441 highest_priority_ = req_priority; |
429 } | 442 } |
430 | 443 |
431 void Remove(RequestPriority req_priority) { | 444 void Remove(RequestPriority req_priority) { |
432 DCHECK_GT(total_count_, 0u); | 445 DCHECK_GT(total_count_, 0u); |
433 DCHECK_GT(counts_[req_priority], 0u); | 446 DCHECK_GT(counts_[req_priority], 0u); |
434 --total_count_; | 447 --total_count_; |
435 --counts_[req_priority]; | 448 --counts_[req_priority]; |
436 size_t i; | 449 size_t i; |
437 for (i = highest_priority_; i > MINIMUM_PRIORITY && !counts_[i]; --i); | 450 for (i = highest_priority_; i > MINIMUM_PRIORITY && !counts_[i]; --i) |
| 451 ; |
438 highest_priority_ = static_cast<RequestPriority>(i); | 452 highest_priority_ = static_cast<RequestPriority>(i); |
439 | 453 |
440 // In absence of requests, default to MINIMUM_PRIORITY. | 454 // In absence of requests, default to MINIMUM_PRIORITY. |
441 if (total_count_ == 0) | 455 if (total_count_ == 0) |
442 DCHECK_EQ(MINIMUM_PRIORITY, highest_priority_); | 456 DCHECK_EQ(MINIMUM_PRIORITY, highest_priority_); |
443 } | 457 } |
444 | 458 |
445 private: | 459 private: |
446 RequestPriority highest_priority_; | 460 RequestPriority highest_priority_; |
447 size_t total_count_; | 461 size_t total_count_; |
(...skipping 26 matching lines...) Expand all Loading... |
474 addresses_(addresses), | 488 addresses_(addresses), |
475 request_time_(base::TimeTicks::Now()) {} | 489 request_time_(base::TimeTicks::Now()) {} |
476 | 490 |
477 // Mark the request as canceled. | 491 // Mark the request as canceled. |
478 void MarkAsCanceled() { | 492 void MarkAsCanceled() { |
479 job_ = NULL; | 493 job_ = NULL; |
480 addresses_ = NULL; | 494 addresses_ = NULL; |
481 callback_.Reset(); | 495 callback_.Reset(); |
482 } | 496 } |
483 | 497 |
484 bool was_canceled() const { | 498 bool was_canceled() const { return callback_.is_null(); } |
485 return callback_.is_null(); | |
486 } | |
487 | 499 |
488 void set_job(Job* job) { | 500 void set_job(Job* job) { |
489 DCHECK(job); | 501 DCHECK(job); |
490 // Identify which job the request is waiting on. | 502 // Identify which job the request is waiting on. |
491 job_ = job; | 503 job_ = job; |
492 } | 504 } |
493 | 505 |
494 // Prepare final AddressList and call completion callback. | 506 // Prepare final AddressList and call completion callback. |
495 void OnComplete(int error, const AddressList& addr_list) { | 507 void OnComplete(int error, const AddressList& addr_list) { |
496 DCHECK(!was_canceled()); | 508 DCHECK(!was_canceled()); |
497 if (error == OK) | 509 if (error == OK) |
498 *addresses_ = EnsurePortOnAddressList(addr_list, info_.port()); | 510 *addresses_ = EnsurePortOnAddressList(addr_list, info_.port()); |
499 CompletionCallback callback = callback_; | 511 CompletionCallback callback = callback_; |
500 MarkAsCanceled(); | 512 MarkAsCanceled(); |
501 callback.Run(error); | 513 callback.Run(error); |
502 } | 514 } |
503 | 515 |
504 Job* job() const { | 516 Job* job() const { return job_; } |
505 return job_; | |
506 } | |
507 | 517 |
508 // NetLog for the source, passed in HostResolver::Resolve. | 518 // NetLog for the source, passed in HostResolver::Resolve. |
509 const BoundNetLog& source_net_log() { | 519 const BoundNetLog& source_net_log() { return source_net_log_; } |
510 return source_net_log_; | |
511 } | |
512 | 520 |
513 // NetLog for this request. | 521 // NetLog for this request. |
514 const BoundNetLog& request_net_log() { | 522 const BoundNetLog& request_net_log() { return request_net_log_; } |
515 return request_net_log_; | |
516 } | |
517 | 523 |
518 const RequestInfo& info() const { | 524 const RequestInfo& info() const { return info_; } |
519 return info_; | |
520 } | |
521 | 525 |
522 RequestPriority priority() const { return priority_; } | 526 RequestPriority priority() const { return priority_; } |
523 | 527 |
524 base::TimeTicks request_time() const { return request_time_; } | 528 base::TimeTicks request_time() const { return request_time_; } |
525 | 529 |
526 private: | 530 private: |
527 BoundNetLog source_net_log_; | 531 BoundNetLog source_net_log_; |
528 BoundNetLog request_net_log_; | 532 BoundNetLog request_net_log_; |
529 | 533 |
530 // The request info that started the request. | 534 // The request info that started the request. |
(...skipping 24 matching lines...) Expand all Loading... |
555 // resolution (OnLookupComplete) is completed or not. If the original attempt | 559 // resolution (OnLookupComplete) is completed or not. If the original attempt |
556 // hasn't completed, then we start another attempt for host resolution. We take | 560 // hasn't completed, then we start another attempt for host resolution. We take |
557 // the results from the first attempt that finishes and ignore the results from | 561 // the results from the first attempt that finishes and ignore the results from |
558 // all other attempts. | 562 // all other attempts. |
559 // | 563 // |
560 // TODO(szym): Move to separate source file for testing and mocking. | 564 // TODO(szym): Move to separate source file for testing and mocking. |
561 // | 565 // |
562 class HostResolverImpl::ProcTask | 566 class HostResolverImpl::ProcTask |
563 : public base::RefCountedThreadSafe<HostResolverImpl::ProcTask> { | 567 : public base::RefCountedThreadSafe<HostResolverImpl::ProcTask> { |
564 public: | 568 public: |
565 typedef base::Callback<void(int net_error, | 569 typedef base::Callback<void(int net_error, const AddressList& addr_list)> |
566 const AddressList& addr_list)> Callback; | 570 Callback; |
567 | 571 |
568 ProcTask(const Key& key, | 572 ProcTask(const Key& key, |
569 const ProcTaskParams& params, | 573 const ProcTaskParams& params, |
570 const Callback& callback, | 574 const Callback& callback, |
571 const BoundNetLog& job_net_log) | 575 const BoundNetLog& job_net_log) |
572 : key_(key), | 576 : key_(key), |
573 params_(params), | 577 params_(params), |
574 callback_(callback), | 578 callback_(callback), |
575 origin_loop_(base::MessageLoopProxy::current()), | 579 origin_loop_(base::MessageLoopProxy::current()), |
576 attempt_number_(0), | 580 attempt_number_(0), |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
630 // Dispatch the lookup attempt to a worker thread. | 634 // Dispatch the lookup attempt to a worker thread. |
631 if (!base::WorkerPool::PostTask( | 635 if (!base::WorkerPool::PostTask( |
632 FROM_HERE, | 636 FROM_HERE, |
633 base::Bind(&ProcTask::DoLookup, this, start_time, attempt_number_), | 637 base::Bind(&ProcTask::DoLookup, this, start_time, attempt_number_), |
634 true)) { | 638 true)) { |
635 NOTREACHED(); | 639 NOTREACHED(); |
636 | 640 |
637 // Since we could be running within Resolve() right now, we can't just | 641 // Since we could be running within Resolve() right now, we can't just |
638 // call OnLookupComplete(). Instead we must wait until Resolve() has | 642 // call OnLookupComplete(). Instead we must wait until Resolve() has |
639 // returned (IO_PENDING). | 643 // returned (IO_PENDING). |
640 origin_loop_->PostTask( | 644 origin_loop_->PostTask(FROM_HERE, |
641 FROM_HERE, | 645 base::Bind(&ProcTask::OnLookupComplete, |
642 base::Bind(&ProcTask::OnLookupComplete, this, AddressList(), | 646 this, |
643 start_time, attempt_number_, ERR_UNEXPECTED, 0)); | 647 AddressList(), |
| 648 start_time, |
| 649 attempt_number_, |
| 650 ERR_UNEXPECTED, |
| 651 0)); |
644 return; | 652 return; |
645 } | 653 } |
646 | 654 |
647 net_log_.AddEvent( | 655 net_log_.AddEvent( |
648 NetLog::TYPE_HOST_RESOLVER_IMPL_ATTEMPT_STARTED, | 656 NetLog::TYPE_HOST_RESOLVER_IMPL_ATTEMPT_STARTED, |
649 NetLog::IntegerCallback("attempt_number", attempt_number_)); | 657 NetLog::IntegerCallback("attempt_number", attempt_number_)); |
650 | 658 |
651 // If we don't get the results within a given time, RetryIfNotComplete | 659 // If we don't get the results within a given time, RetryIfNotComplete |
652 // will start a new attempt on a different worker thread if none of our | 660 // will start a new attempt on a different worker thread if none of our |
653 // outstanding attempts have completed yet. | 661 // outstanding attempts have completed yet. |
(...skipping 14 matching lines...) Expand all Loading... |
668 const uint32 attempt_number) { | 676 const uint32 attempt_number) { |
669 AddressList results; | 677 AddressList results; |
670 int os_error = 0; | 678 int os_error = 0; |
671 // Running on the worker thread | 679 // Running on the worker thread |
672 int error = params_.resolver_proc->Resolve(key_.hostname, | 680 int error = params_.resolver_proc->Resolve(key_.hostname, |
673 key_.address_family, | 681 key_.address_family, |
674 key_.host_resolver_flags, | 682 key_.host_resolver_flags, |
675 &results, | 683 &results, |
676 &os_error); | 684 &os_error); |
677 | 685 |
678 origin_loop_->PostTask( | 686 origin_loop_->PostTask(FROM_HERE, |
679 FROM_HERE, | 687 base::Bind(&ProcTask::OnLookupComplete, |
680 base::Bind(&ProcTask::OnLookupComplete, this, results, start_time, | 688 this, |
681 attempt_number, error, os_error)); | 689 results, |
| 690 start_time, |
| 691 attempt_number, |
| 692 error, |
| 693 os_error)); |
682 } | 694 } |
683 | 695 |
684 // Makes next attempt if DoLookup() has not finished (runs on origin thread). | 696 // Makes next attempt if DoLookup() has not finished (runs on origin thread). |
685 void RetryIfNotComplete() { | 697 void RetryIfNotComplete() { |
686 DCHECK(origin_loop_->BelongsToCurrentThread()); | 698 DCHECK(origin_loop_->BelongsToCurrentThread()); |
687 | 699 |
688 if (was_completed() || was_canceled()) | 700 if (was_completed() || was_canceled()) |
689 return; | 701 return; |
690 | 702 |
691 params_.unresponsive_delay *= params_.retry_factor; | 703 params_.unresponsive_delay *= params_.retry_factor; |
(...skipping 26 matching lines...) Expand all Loading... |
718 if (!was_retry_attempt) | 730 if (!was_retry_attempt) |
719 RecordPerformanceHistograms(start_time, error, os_error); | 731 RecordPerformanceHistograms(start_time, error, os_error); |
720 | 732 |
721 RecordAttemptHistograms(start_time, attempt_number, error, os_error); | 733 RecordAttemptHistograms(start_time, attempt_number, error, os_error); |
722 | 734 |
723 if (was_canceled()) | 735 if (was_canceled()) |
724 return; | 736 return; |
725 | 737 |
726 NetLog::ParametersCallback net_log_callback; | 738 NetLog::ParametersCallback net_log_callback; |
727 if (error != OK) { | 739 if (error != OK) { |
728 net_log_callback = base::Bind(&NetLogProcTaskFailedCallback, | 740 net_log_callback = base::Bind( |
729 attempt_number, | 741 &NetLogProcTaskFailedCallback, attempt_number, error, os_error); |
730 error, | |
731 os_error); | |
732 } else { | 742 } else { |
733 net_log_callback = NetLog::IntegerCallback("attempt_number", | 743 net_log_callback = |
734 attempt_number); | 744 NetLog::IntegerCallback("attempt_number", attempt_number); |
735 } | 745 } |
736 net_log_.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_ATTEMPT_FINISHED, | 746 net_log_.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_ATTEMPT_FINISHED, |
737 net_log_callback); | 747 net_log_callback); |
738 | 748 |
739 if (was_completed()) | 749 if (was_completed()) |
740 return; | 750 return; |
741 | 751 |
742 // Copy the results from the first worker thread that resolves the host. | 752 // Copy the results from the first worker thread that resolves the host. |
743 results_ = results; | 753 results_ = results; |
744 completed_attempt_number_ = attempt_number; | 754 completed_attempt_number_ = attempt_number; |
745 completed_attempt_error_ = error; | 755 completed_attempt_error_ = error; |
746 | 756 |
747 if (was_retry_attempt) { | 757 if (was_retry_attempt) { |
748 // If retry attempt finishes before 1st attempt, then get stats on how | 758 // If retry attempt finishes before 1st attempt, then get stats on how |
749 // much time is saved by having spawned an extra attempt. | 759 // much time is saved by having spawned an extra attempt. |
750 retry_attempt_finished_time_ = base::TimeTicks::Now(); | 760 retry_attempt_finished_time_ = base::TimeTicks::Now(); |
751 } | 761 } |
752 | 762 |
753 if (error != OK) { | 763 if (error != OK) { |
754 net_log_callback = base::Bind(&NetLogProcTaskFailedCallback, | 764 net_log_callback = |
755 0, error, os_error); | 765 base::Bind(&NetLogProcTaskFailedCallback, 0, error, os_error); |
756 } else { | 766 } else { |
757 net_log_callback = results_.CreateNetLogCallback(); | 767 net_log_callback = results_.CreateNetLogCallback(); |
758 } | 768 } |
759 net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_PROC_TASK, | 769 net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_PROC_TASK, |
760 net_log_callback); | 770 net_log_callback); |
761 | 771 |
762 callback_.Run(error, results_); | 772 callback_.Run(error, results_); |
763 } | 773 } |
764 | 774 |
765 void RecordPerformanceHistograms(const base::TimeTicks& start_time, | 775 void RecordPerformanceHistograms(const base::TimeTicks& start_time, |
(...skipping 14 matching lines...) Expand all Loading... |
780 if (had_non_speculative_request_) { | 790 if (had_non_speculative_request_) { |
781 category = RESOLVE_SUCCESS; | 791 category = RESOLVE_SUCCESS; |
782 DNS_HISTOGRAM("DNS.ResolveSuccess", duration); | 792 DNS_HISTOGRAM("DNS.ResolveSuccess", duration); |
783 } else { | 793 } else { |
784 category = RESOLVE_SPECULATIVE_SUCCESS; | 794 category = RESOLVE_SPECULATIVE_SUCCESS; |
785 DNS_HISTOGRAM("DNS.ResolveSpeculativeSuccess", duration); | 795 DNS_HISTOGRAM("DNS.ResolveSpeculativeSuccess", duration); |
786 } | 796 } |
787 | 797 |
788 // Log DNS lookups based on |address_family|. This will help us determine | 798 // Log DNS lookups based on |address_family|. This will help us determine |
789 // if IPv4 or IPv4/6 lookups are faster or slower. | 799 // if IPv4 or IPv4/6 lookups are faster or slower. |
790 switch(key_.address_family) { | 800 switch (key_.address_family) { |
791 case ADDRESS_FAMILY_IPV4: | 801 case ADDRESS_FAMILY_IPV4: |
792 DNS_HISTOGRAM("DNS.ResolveSuccess_FAMILY_IPV4", duration); | 802 DNS_HISTOGRAM("DNS.ResolveSuccess_FAMILY_IPV4", duration); |
793 break; | 803 break; |
794 case ADDRESS_FAMILY_IPV6: | 804 case ADDRESS_FAMILY_IPV6: |
795 DNS_HISTOGRAM("DNS.ResolveSuccess_FAMILY_IPV6", duration); | 805 DNS_HISTOGRAM("DNS.ResolveSuccess_FAMILY_IPV6", duration); |
796 break; | 806 break; |
797 case ADDRESS_FAMILY_UNSPECIFIED: | 807 case ADDRESS_FAMILY_UNSPECIFIED: |
798 DNS_HISTOGRAM("DNS.ResolveSuccess_FAMILY_UNSPEC", duration); | 808 DNS_HISTOGRAM("DNS.ResolveSuccess_FAMILY_UNSPEC", duration); |
799 break; | 809 break; |
800 } | 810 } |
801 } else { | 811 } else { |
802 if (had_non_speculative_request_) { | 812 if (had_non_speculative_request_) { |
803 category = RESOLVE_FAIL; | 813 category = RESOLVE_FAIL; |
804 DNS_HISTOGRAM("DNS.ResolveFail", duration); | 814 DNS_HISTOGRAM("DNS.ResolveFail", duration); |
805 } else { | 815 } else { |
806 category = RESOLVE_SPECULATIVE_FAIL; | 816 category = RESOLVE_SPECULATIVE_FAIL; |
807 DNS_HISTOGRAM("DNS.ResolveSpeculativeFail", duration); | 817 DNS_HISTOGRAM("DNS.ResolveSpeculativeFail", duration); |
808 } | 818 } |
809 // Log DNS lookups based on |address_family|. This will help us determine | 819 // Log DNS lookups based on |address_family|. This will help us determine |
810 // if IPv4 or IPv4/6 lookups are faster or slower. | 820 // if IPv4 or IPv4/6 lookups are faster or slower. |
811 switch(key_.address_family) { | 821 switch (key_.address_family) { |
812 case ADDRESS_FAMILY_IPV4: | 822 case ADDRESS_FAMILY_IPV4: |
813 DNS_HISTOGRAM("DNS.ResolveFail_FAMILY_IPV4", duration); | 823 DNS_HISTOGRAM("DNS.ResolveFail_FAMILY_IPV4", duration); |
814 break; | 824 break; |
815 case ADDRESS_FAMILY_IPV6: | 825 case ADDRESS_FAMILY_IPV6: |
816 DNS_HISTOGRAM("DNS.ResolveFail_FAMILY_IPV6", duration); | 826 DNS_HISTOGRAM("DNS.ResolveFail_FAMILY_IPV6", duration); |
817 break; | 827 break; |
818 case ADDRESS_FAMILY_UNSPECIFIED: | 828 case ADDRESS_FAMILY_UNSPECIFIED: |
819 DNS_HISTOGRAM("DNS.ResolveFail_FAMILY_UNSPEC", duration); | 829 DNS_HISTOGRAM("DNS.ResolveFail_FAMILY_UNSPEC", duration); |
820 break; | 830 break; |
821 } | 831 } |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
922 DISALLOW_COPY_AND_ASSIGN(ProcTask); | 932 DISALLOW_COPY_AND_ASSIGN(ProcTask); |
923 }; | 933 }; |
924 | 934 |
925 //----------------------------------------------------------------------------- | 935 //----------------------------------------------------------------------------- |
926 | 936 |
927 // Wraps a call to HaveOnlyLoopbackAddresses to be executed on the WorkerPool as | 937 // Wraps a call to HaveOnlyLoopbackAddresses to be executed on the WorkerPool as |
928 // it takes 40-100ms and should not block initialization. | 938 // it takes 40-100ms and should not block initialization. |
929 class HostResolverImpl::LoopbackProbeJob { | 939 class HostResolverImpl::LoopbackProbeJob { |
930 public: | 940 public: |
931 explicit LoopbackProbeJob(const base::WeakPtr<HostResolverImpl>& resolver) | 941 explicit LoopbackProbeJob(const base::WeakPtr<HostResolverImpl>& resolver) |
932 : resolver_(resolver), | 942 : resolver_(resolver), result_(false) { |
933 result_(false) { | |
934 DCHECK(resolver.get()); | 943 DCHECK(resolver.get()); |
935 const bool kIsSlow = true; | 944 const bool kIsSlow = true; |
936 base::WorkerPool::PostTaskAndReply( | 945 base::WorkerPool::PostTaskAndReply( |
937 FROM_HERE, | 946 FROM_HERE, |
938 base::Bind(&LoopbackProbeJob::DoProbe, base::Unretained(this)), | 947 base::Bind(&LoopbackProbeJob::DoProbe, base::Unretained(this)), |
939 base::Bind(&LoopbackProbeJob::OnProbeComplete, base::Owned(this)), | 948 base::Bind(&LoopbackProbeJob::OnProbeComplete, base::Owned(this)), |
940 kIsSlow); | 949 kIsSlow); |
941 } | 950 } |
942 | 951 |
943 virtual ~LoopbackProbeJob() {} | 952 virtual ~LoopbackProbeJob() {} |
944 | 953 |
945 private: | 954 private: |
946 // Runs on worker thread. | 955 // Runs on worker thread. |
947 void DoProbe() { | 956 void DoProbe() { result_ = HaveOnlyLoopbackAddresses(); } |
948 result_ = HaveOnlyLoopbackAddresses(); | |
949 } | |
950 | 957 |
951 void OnProbeComplete() { | 958 void OnProbeComplete() { |
952 if (!resolver_.get()) | 959 if (!resolver_.get()) |
953 return; | 960 return; |
954 resolver_->SetHaveOnlyLoopbackAddresses(result_); | 961 resolver_->SetHaveOnlyLoopbackAddresses(result_); |
955 } | 962 } |
956 | 963 |
957 // Used/set only on origin thread. | 964 // Used/set only on origin thread. |
958 base::WeakPtr<HostResolverImpl> resolver_; | 965 base::WeakPtr<HostResolverImpl> resolver_; |
959 | 966 |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1034 DCHECK(!transaction_aaaa_); | 1041 DCHECK(!transaction_aaaa_); |
1035 DCHECK_NE(ADDRESS_FAMILY_IPV4, key_.address_family); | 1042 DCHECK_NE(ADDRESS_FAMILY_IPV4, key_.address_family); |
1036 transaction_aaaa_ = CreateTransaction(ADDRESS_FAMILY_IPV6); | 1043 transaction_aaaa_ = CreateTransaction(ADDRESS_FAMILY_IPV6); |
1037 transaction_aaaa_->Start(); | 1044 transaction_aaaa_->Start(); |
1038 } | 1045 } |
1039 | 1046 |
1040 scoped_ptr<DnsTransaction> CreateTransaction(AddressFamily family) { | 1047 scoped_ptr<DnsTransaction> CreateTransaction(AddressFamily family) { |
1041 DCHECK_NE(ADDRESS_FAMILY_UNSPECIFIED, family); | 1048 DCHECK_NE(ADDRESS_FAMILY_UNSPECIFIED, family); |
1042 return client_->GetTransactionFactory()->CreateTransaction( | 1049 return client_->GetTransactionFactory()->CreateTransaction( |
1043 key_.hostname, | 1050 key_.hostname, |
1044 family == ADDRESS_FAMILY_IPV6 ? dns_protocol::kTypeAAAA : | 1051 family == ADDRESS_FAMILY_IPV6 ? dns_protocol::kTypeAAAA |
1045 dns_protocol::kTypeA, | 1052 : dns_protocol::kTypeA, |
1046 base::Bind(&DnsTask::OnTransactionComplete, base::Unretained(this), | 1053 base::Bind(&DnsTask::OnTransactionComplete, |
| 1054 base::Unretained(this), |
1047 base::TimeTicks::Now()), | 1055 base::TimeTicks::Now()), |
1048 net_log_); | 1056 net_log_); |
1049 } | 1057 } |
1050 | 1058 |
1051 void OnTransactionComplete(const base::TimeTicks& start_time, | 1059 void OnTransactionComplete(const base::TimeTicks& start_time, |
1052 DnsTransaction* transaction, | 1060 DnsTransaction* transaction, |
1053 int net_error, | 1061 int net_error, |
1054 const DnsResponse* response) { | 1062 const DnsResponse* response) { |
1055 DCHECK(transaction); | 1063 DCHECK(transaction); |
1056 base::TimeDelta duration = base::TimeTicks::Now() - start_time; | 1064 base::TimeDelta duration = base::TimeTicks::Now() - start_time; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1113 } | 1121 } |
1114 | 1122 |
1115 // If there are multiple addresses, and at least one is IPv6, need to sort | 1123 // If there are multiple addresses, and at least one is IPv6, need to sort |
1116 // them. Note that IPv6 addresses are always put before IPv4 ones, so it's | 1124 // them. Note that IPv6 addresses are always put before IPv4 ones, so it's |
1117 // sufficient to just check the family of the first address. | 1125 // sufficient to just check the family of the first address. |
1118 if (addr_list_.size() > 1 && | 1126 if (addr_list_.size() > 1 && |
1119 addr_list_[0].GetFamily() == ADDRESS_FAMILY_IPV6) { | 1127 addr_list_[0].GetFamily() == ADDRESS_FAMILY_IPV6) { |
1120 // Sort addresses if needed. Sort could complete synchronously. | 1128 // Sort addresses if needed. Sort could complete synchronously. |
1121 client_->GetAddressSorter()->Sort( | 1129 client_->GetAddressSorter()->Sort( |
1122 addr_list_, | 1130 addr_list_, |
1123 base::Bind(&DnsTask::OnSortComplete, | 1131 base::Bind( |
1124 AsWeakPtr(), | 1132 &DnsTask::OnSortComplete, AsWeakPtr(), base::TimeTicks::Now())); |
1125 base::TimeTicks::Now())); | |
1126 } else { | 1133 } else { |
1127 OnSuccess(addr_list_); | 1134 OnSuccess(addr_list_); |
1128 } | 1135 } |
1129 } | 1136 } |
1130 | 1137 |
1131 void OnSortComplete(base::TimeTicks start_time, | 1138 void OnSortComplete(base::TimeTicks start_time, |
1132 bool success, | 1139 bool success, |
1133 const AddressList& addr_list) { | 1140 const AddressList& addr_list) { |
1134 if (!success) { | 1141 if (!success) { |
1135 DNS_HISTOGRAM("AsyncDNS.SortFailure", | 1142 DNS_HISTOGRAM("AsyncDNS.SortFailure", |
1136 base::TimeTicks::Now() - start_time); | 1143 base::TimeTicks::Now() - start_time); |
1137 OnFailure(ERR_DNS_SORT_ERROR, DnsResponse::DNS_PARSE_OK); | 1144 OnFailure(ERR_DNS_SORT_ERROR, DnsResponse::DNS_PARSE_OK); |
1138 return; | 1145 return; |
1139 } | 1146 } |
1140 | 1147 |
1141 DNS_HISTOGRAM("AsyncDNS.SortSuccess", | 1148 DNS_HISTOGRAM("AsyncDNS.SortSuccess", base::TimeTicks::Now() - start_time); |
1142 base::TimeTicks::Now() - start_time); | |
1143 | 1149 |
1144 // AddressSorter prunes unusable destinations. | 1150 // AddressSorter prunes unusable destinations. |
1145 if (addr_list.empty()) { | 1151 if (addr_list.empty()) { |
1146 LOG(WARNING) << "Address list empty after RFC3484 sort"; | 1152 LOG(WARNING) << "Address list empty after RFC3484 sort"; |
1147 OnFailure(ERR_NAME_NOT_RESOLVED, DnsResponse::DNS_PARSE_OK); | 1153 OnFailure(ERR_NAME_NOT_RESOLVED, DnsResponse::DNS_PARSE_OK); |
1148 return; | 1154 return; |
1149 } | 1155 } |
1150 | 1156 |
1151 OnSuccess(addr_list); | 1157 OnSuccess(addr_list); |
1152 } | 1158 } |
1153 | 1159 |
1154 void OnFailure(int net_error, DnsResponse::Result result) { | 1160 void OnFailure(int net_error, DnsResponse::Result result) { |
1155 DCHECK_NE(OK, net_error); | 1161 DCHECK_NE(OK, net_error); |
1156 net_log_.EndEvent( | 1162 net_log_.EndEvent( |
1157 NetLog::TYPE_HOST_RESOLVER_IMPL_DNS_TASK, | 1163 NetLog::TYPE_HOST_RESOLVER_IMPL_DNS_TASK, |
1158 base::Bind(&NetLogDnsTaskFailedCallback, net_error, result)); | 1164 base::Bind(&NetLogDnsTaskFailedCallback, net_error, result)); |
1159 delegate_->OnDnsTaskComplete(task_start_time_, net_error, AddressList(), | 1165 delegate_->OnDnsTaskComplete( |
1160 base::TimeDelta()); | 1166 task_start_time_, net_error, AddressList(), base::TimeDelta()); |
1161 } | 1167 } |
1162 | 1168 |
1163 void OnSuccess(const AddressList& addr_list) { | 1169 void OnSuccess(const AddressList& addr_list) { |
1164 net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_DNS_TASK, | 1170 net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_DNS_TASK, |
1165 addr_list.CreateNetLogCallback()); | 1171 addr_list.CreateNetLogCallback()); |
1166 delegate_->OnDnsTaskComplete(task_start_time_, OK, addr_list, ttl_); | 1172 delegate_->OnDnsTaskComplete(task_start_time_, OK, addr_list, ttl_); |
1167 } | 1173 } |
1168 | 1174 |
1169 DnsClient* client_; | 1175 DnsClient* client_; |
1170 Key key_; | 1176 Key key_; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1206 had_non_speculative_request_(false), | 1212 had_non_speculative_request_(false), |
1207 had_dns_config_(false), | 1213 had_dns_config_(false), |
1208 num_occupied_job_slots_(0), | 1214 num_occupied_job_slots_(0), |
1209 dns_task_error_(OK), | 1215 dns_task_error_(OK), |
1210 creation_time_(base::TimeTicks::Now()), | 1216 creation_time_(base::TimeTicks::Now()), |
1211 priority_change_time_(creation_time_), | 1217 priority_change_time_(creation_time_), |
1212 net_log_(BoundNetLog::Make(request_net_log.net_log(), | 1218 net_log_(BoundNetLog::Make(request_net_log.net_log(), |
1213 NetLog::SOURCE_HOST_RESOLVER_IMPL_JOB)) { | 1219 NetLog::SOURCE_HOST_RESOLVER_IMPL_JOB)) { |
1214 request_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CREATE_JOB); | 1220 request_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CREATE_JOB); |
1215 | 1221 |
1216 net_log_.BeginEvent( | 1222 net_log_.BeginEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, |
1217 NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, | 1223 base::Bind(&NetLogJobCreationCallback, |
1218 base::Bind(&NetLogJobCreationCallback, | 1224 request_net_log.source(), |
1219 request_net_log.source(), | 1225 &key_.hostname)); |
1220 &key_.hostname)); | |
1221 } | 1226 } |
1222 | 1227 |
1223 virtual ~Job() { | 1228 virtual ~Job() { |
1224 if (is_running()) { | 1229 if (is_running()) { |
1225 // |resolver_| was destroyed with this Job still in flight. | 1230 // |resolver_| was destroyed with this Job still in flight. |
1226 // Clean-up, record in the log, but don't run any callbacks. | 1231 // Clean-up, record in the log, but don't run any callbacks. |
1227 if (is_proc_running()) { | 1232 if (is_proc_running()) { |
1228 proc_task_->Cancel(); | 1233 proc_task_->Cancel(); |
1229 proc_task_ = NULL; | 1234 proc_task_ = NULL; |
1230 } | 1235 } |
1231 // Clean up now for nice NetLog. | 1236 // Clean up now for nice NetLog. |
1232 KillDnsTask(); | 1237 KillDnsTask(); |
1233 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, | 1238 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, |
1234 ERR_ABORTED); | 1239 ERR_ABORTED); |
1235 } else if (is_queued()) { | 1240 } else if (is_queued()) { |
1236 // |resolver_| was destroyed without running this Job. | 1241 // |resolver_| was destroyed without running this Job. |
1237 // TODO(szym): is there any benefit in having this distinction? | 1242 // TODO(szym): is there any benefit in having this distinction? |
1238 net_log_.AddEvent(NetLog::TYPE_CANCELLED); | 1243 net_log_.AddEvent(NetLog::TYPE_CANCELLED); |
1239 net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB); | 1244 net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB); |
1240 } | 1245 } |
1241 // else CompleteRequests logged EndEvent. | 1246 // else CompleteRequests logged EndEvent. |
1242 | 1247 |
1243 // Log any remaining Requests as cancelled. | 1248 // Log any remaining Requests as cancelled. |
1244 for (RequestsList::const_iterator it = requests_.begin(); | 1249 for (RequestsList::const_iterator it = requests_.begin(); |
1245 it != requests_.end(); ++it) { | 1250 it != requests_.end(); |
| 1251 ++it) { |
1246 Request* req = *it; | 1252 Request* req = *it; |
1247 if (req->was_canceled()) | 1253 if (req->was_canceled()) |
1248 continue; | 1254 continue; |
1249 DCHECK_EQ(this, req->job()); | 1255 DCHECK_EQ(this, req->job()); |
1250 LogCancelRequest(req->source_net_log(), req->request_net_log(), | 1256 LogCancelRequest( |
1251 req->info()); | 1257 req->source_net_log(), req->request_net_log(), req->info()); |
1252 } | 1258 } |
1253 } | 1259 } |
1254 | 1260 |
1255 // Add this job to the dispatcher. If "at_head" is true, adds at the front | 1261 // Add this job to the dispatcher. If "at_head" is true, adds at the front |
1256 // of the queue. | 1262 // of the queue. |
1257 void Schedule(bool at_head) { | 1263 void Schedule(bool at_head) { |
1258 DCHECK(!is_queued()); | 1264 DCHECK(!is_queued()); |
1259 PrioritizedDispatcher::Handle handle; | 1265 PrioritizedDispatcher::Handle handle; |
1260 if (!at_head) { | 1266 if (!at_head) { |
1261 handle = resolver_->dispatcher_.Add(this, priority()); | 1267 handle = resolver_->dispatcher_.Add(this, priority()); |
(...skipping 12 matching lines...) Expand all Loading... |
1274 void AddRequest(scoped_ptr<Request> req) { | 1280 void AddRequest(scoped_ptr<Request> req) { |
1275 DCHECK_EQ(key_.hostname, req->info().hostname()); | 1281 DCHECK_EQ(key_.hostname, req->info().hostname()); |
1276 | 1282 |
1277 req->set_job(this); | 1283 req->set_job(this); |
1278 priority_tracker_.Add(req->priority()); | 1284 priority_tracker_.Add(req->priority()); |
1279 | 1285 |
1280 req->request_net_log().AddEvent( | 1286 req->request_net_log().AddEvent( |
1281 NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_ATTACH, | 1287 NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_ATTACH, |
1282 net_log_.source().ToEventParametersCallback()); | 1288 net_log_.source().ToEventParametersCallback()); |
1283 | 1289 |
1284 net_log_.AddEvent( | 1290 net_log_.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_REQUEST_ATTACH, |
1285 NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_REQUEST_ATTACH, | 1291 base::Bind(&NetLogJobAttachCallback, |
1286 base::Bind(&NetLogJobAttachCallback, | 1292 req->request_net_log().source(), |
1287 req->request_net_log().source(), | 1293 priority())); |
1288 priority())); | |
1289 | 1294 |
1290 // TODO(szym): Check if this is still needed. | 1295 // TODO(szym): Check if this is still needed. |
1291 if (!req->info().is_speculative()) { | 1296 if (!req->info().is_speculative()) { |
1292 had_non_speculative_request_ = true; | 1297 had_non_speculative_request_ = true; |
1293 if (proc_task_.get()) | 1298 if (proc_task_.get()) |
1294 proc_task_->set_had_non_speculative_request(); | 1299 proc_task_->set_had_non_speculative_request(); |
1295 } | 1300 } |
1296 | 1301 |
1297 requests_.push_back(req.release()); | 1302 requests_.push_back(req.release()); |
1298 | 1303 |
1299 UpdatePriority(); | 1304 UpdatePriority(); |
1300 } | 1305 } |
1301 | 1306 |
1302 // Marks |req| as cancelled. If it was the last active Request, also finishes | 1307 // Marks |req| as cancelled. If it was the last active Request, also finishes |
1303 // this Job, marking it as cancelled, and deletes it. | 1308 // this Job, marking it as cancelled, and deletes it. |
1304 void CancelRequest(Request* req) { | 1309 void CancelRequest(Request* req) { |
1305 DCHECK_EQ(key_.hostname, req->info().hostname()); | 1310 DCHECK_EQ(key_.hostname, req->info().hostname()); |
1306 DCHECK(!req->was_canceled()); | 1311 DCHECK(!req->was_canceled()); |
1307 | 1312 |
1308 // Don't remove it from |requests_| just mark it canceled. | 1313 // Don't remove it from |requests_| just mark it canceled. |
1309 req->MarkAsCanceled(); | 1314 req->MarkAsCanceled(); |
1310 LogCancelRequest(req->source_net_log(), req->request_net_log(), | 1315 LogCancelRequest( |
1311 req->info()); | 1316 req->source_net_log(), req->request_net_log(), req->info()); |
1312 | 1317 |
1313 priority_tracker_.Remove(req->priority()); | 1318 priority_tracker_.Remove(req->priority()); |
1314 net_log_.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_REQUEST_DETACH, | 1319 net_log_.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_REQUEST_DETACH, |
1315 base::Bind(&NetLogJobAttachCallback, | 1320 base::Bind(&NetLogJobAttachCallback, |
1316 req->request_net_log().source(), | 1321 req->request_net_log().source(), |
1317 priority())); | 1322 priority())); |
1318 | 1323 |
1319 if (num_active_requests() > 0) { | 1324 if (num_active_requests() > 0) { |
1320 UpdatePriority(); | 1325 UpdatePriority(); |
1321 } else { | 1326 } else { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1353 | 1358 |
1354 // This signals to CompleteRequests that this job never ran. | 1359 // This signals to CompleteRequests that this job never ran. |
1355 CompleteRequestsWithError(ERR_HOST_RESOLVER_QUEUE_TOO_LARGE); | 1360 CompleteRequestsWithError(ERR_HOST_RESOLVER_QUEUE_TOO_LARGE); |
1356 } | 1361 } |
1357 | 1362 |
1358 // Attempts to serve the job from HOSTS. Returns true if succeeded and | 1363 // Attempts to serve the job from HOSTS. Returns true if succeeded and |
1359 // this Job was destroyed. | 1364 // this Job was destroyed. |
1360 bool ServeFromHosts() { | 1365 bool ServeFromHosts() { |
1361 DCHECK_GT(num_active_requests(), 0u); | 1366 DCHECK_GT(num_active_requests(), 0u); |
1362 AddressList addr_list; | 1367 AddressList addr_list; |
1363 if (resolver_->ServeFromHosts(key(), | 1368 if (resolver_->ServeFromHosts( |
1364 requests_.front()->info(), | 1369 key(), requests_.front()->info(), &addr_list)) { |
1365 &addr_list)) { | |
1366 // This will destroy the Job. | 1370 // This will destroy the Job. |
1367 CompleteRequests( | 1371 CompleteRequests( |
1368 HostCache::Entry(OK, MakeAddressListForRequest(addr_list)), | 1372 HostCache::Entry(OK, MakeAddressListForRequest(addr_list)), |
1369 base::TimeDelta()); | 1373 base::TimeDelta()); |
1370 return true; | 1374 return true; |
1371 } | 1375 } |
1372 return false; | 1376 return false; |
1373 } | 1377 } |
1374 | 1378 |
1375 const Key key() const { | 1379 const Key key() const { return key_; } |
1376 return key_; | |
1377 } | |
1378 | 1380 |
1379 bool is_queued() const { | 1381 bool is_queued() const { return !handle_.is_null(); } |
1380 return !handle_.is_null(); | |
1381 } | |
1382 | 1382 |
1383 bool is_running() const { | 1383 bool is_running() const { return is_dns_running() || is_proc_running(); } |
1384 return is_dns_running() || is_proc_running(); | |
1385 } | |
1386 | 1384 |
1387 private: | 1385 private: |
1388 void KillDnsTask() { | 1386 void KillDnsTask() { |
1389 if (dns_task_) { | 1387 if (dns_task_) { |
1390 ReduceToOneJobSlot(); | 1388 ReduceToOneJobSlot(); |
1391 dns_task_.reset(); | 1389 dns_task_.reset(); |
1392 } | 1390 } |
1393 } | 1391 } |
1394 | 1392 |
1395 // Reduce the number of job slots occupied and queued in the dispatcher | 1393 // Reduce the number of job slots occupied and queued in the dispatcher |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1438 | 1436 |
1439 net_log_.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_STARTED); | 1437 net_log_.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_STARTED); |
1440 | 1438 |
1441 had_dns_config_ = resolver_->HaveDnsConfig(); | 1439 had_dns_config_ = resolver_->HaveDnsConfig(); |
1442 | 1440 |
1443 base::TimeTicks now = base::TimeTicks::Now(); | 1441 base::TimeTicks now = base::TimeTicks::Now(); |
1444 base::TimeDelta queue_time = now - creation_time_; | 1442 base::TimeDelta queue_time = now - creation_time_; |
1445 base::TimeDelta queue_time_after_change = now - priority_change_time_; | 1443 base::TimeDelta queue_time_after_change = now - priority_change_time_; |
1446 | 1444 |
1447 if (had_dns_config_) { | 1445 if (had_dns_config_) { |
1448 DNS_HISTOGRAM_BY_PRIORITY("AsyncDNS.JobQueueTime", priority(), | 1446 DNS_HISTOGRAM_BY_PRIORITY( |
1449 queue_time); | 1447 "AsyncDNS.JobQueueTime", priority(), queue_time); |
1450 DNS_HISTOGRAM_BY_PRIORITY("AsyncDNS.JobQueueTimeAfterChange", priority(), | 1448 DNS_HISTOGRAM_BY_PRIORITY("AsyncDNS.JobQueueTimeAfterChange", |
| 1449 priority(), |
1451 queue_time_after_change); | 1450 queue_time_after_change); |
1452 } else { | 1451 } else { |
1453 DNS_HISTOGRAM_BY_PRIORITY("DNS.JobQueueTime", priority(), queue_time); | 1452 DNS_HISTOGRAM_BY_PRIORITY("DNS.JobQueueTime", priority(), queue_time); |
1454 DNS_HISTOGRAM_BY_PRIORITY("DNS.JobQueueTimeAfterChange", priority(), | 1453 DNS_HISTOGRAM_BY_PRIORITY( |
1455 queue_time_after_change); | 1454 "DNS.JobQueueTimeAfterChange", priority(), queue_time_after_change); |
1456 } | 1455 } |
1457 | 1456 |
1458 bool system_only = | 1457 bool system_only = |
1459 (key_.host_resolver_flags & HOST_RESOLVER_SYSTEM_ONLY) != 0; | 1458 (key_.host_resolver_flags & HOST_RESOLVER_SYSTEM_ONLY) != 0; |
1460 | 1459 |
1461 // Caution: Job::Start must not complete synchronously. | 1460 // Caution: Job::Start must not complete synchronously. |
1462 if (!system_only && had_dns_config_ && | 1461 if (!system_only && had_dns_config_ && |
1463 !ResemblesMulticastDNSName(key_.hostname)) { | 1462 !ResemblesMulticastDNSName(key_.hostname)) { |
1464 StartDnsTask(); | 1463 StartDnsTask(); |
1465 } else { | 1464 } else { |
1466 StartProcTask(); | 1465 StartProcTask(); |
1467 } | 1466 } |
1468 } | 1467 } |
1469 | 1468 |
1470 // TODO(szym): Since DnsTransaction does not consume threads, we can increase | 1469 // TODO(szym): Since DnsTransaction does not consume threads, we can increase |
1471 // the limits on |dispatcher_|. But in order to keep the number of WorkerPool | 1470 // the limits on |dispatcher_|. But in order to keep the number of WorkerPool |
1472 // threads low, we will need to use an "inner" PrioritizedDispatcher with | 1471 // threads low, we will need to use an "inner" PrioritizedDispatcher with |
1473 // tighter limits. | 1472 // tighter limits. |
1474 void StartProcTask() { | 1473 void StartProcTask() { |
1475 DCHECK(!is_dns_running()); | 1474 DCHECK(!is_dns_running()); |
1476 proc_task_ = new ProcTask( | 1475 proc_task_ = new ProcTask(key_, |
1477 key_, | 1476 resolver_->proc_params_, |
1478 resolver_->proc_params_, | 1477 base::Bind(&Job::OnProcTaskComplete, |
1479 base::Bind(&Job::OnProcTaskComplete, base::Unretained(this), | 1478 base::Unretained(this), |
1480 base::TimeTicks::Now()), | 1479 base::TimeTicks::Now()), |
1481 net_log_); | 1480 net_log_); |
1482 | 1481 |
1483 if (had_non_speculative_request_) | 1482 if (had_non_speculative_request_) |
1484 proc_task_->set_had_non_speculative_request(); | 1483 proc_task_->set_had_non_speculative_request(); |
1485 // Start() could be called from within Resolve(), hence it must NOT directly | 1484 // Start() could be called from within Resolve(), hence it must NOT directly |
1486 // call OnProcTaskComplete, for example, on synchronous failure. | 1485 // call OnProcTaskComplete, for example, on synchronous failure. |
1487 proc_task_->Start(); | 1486 proc_task_->Start(); |
1488 } | 1487 } |
1489 | 1488 |
1490 // Called by ProcTask when it completes. | 1489 // Called by ProcTask when it completes. |
1491 void OnProcTaskComplete(base::TimeTicks start_time, | 1490 void OnProcTaskComplete(base::TimeTicks start_time, |
1492 int net_error, | 1491 int net_error, |
1493 const AddressList& addr_list) { | 1492 const AddressList& addr_list) { |
1494 DCHECK(is_proc_running()); | 1493 DCHECK(is_proc_running()); |
1495 | 1494 |
1496 if (!resolver_->resolved_known_ipv6_hostname_ && | 1495 if (!resolver_->resolved_known_ipv6_hostname_ && net_error == OK && |
1497 net_error == OK && | |
1498 key_.address_family == ADDRESS_FAMILY_UNSPECIFIED) { | 1496 key_.address_family == ADDRESS_FAMILY_UNSPECIFIED) { |
1499 if (key_.hostname == "www.google.com") { | 1497 if (key_.hostname == "www.google.com") { |
1500 resolver_->resolved_known_ipv6_hostname_ = true; | 1498 resolver_->resolved_known_ipv6_hostname_ = true; |
1501 bool got_ipv6_address = false; | 1499 bool got_ipv6_address = false; |
1502 for (size_t i = 0; i < addr_list.size(); ++i) { | 1500 for (size_t i = 0; i < addr_list.size(); ++i) { |
1503 if (addr_list[i].GetFamily() == ADDRESS_FAMILY_IPV6) { | 1501 if (addr_list[i].GetFamily() == ADDRESS_FAMILY_IPV6) { |
1504 got_ipv6_address = true; | 1502 got_ipv6_address = true; |
1505 break; | 1503 break; |
1506 } | 1504 } |
1507 } | 1505 } |
(...skipping 21 matching lines...) Expand all Loading... |
1529 } | 1527 } |
1530 } | 1528 } |
1531 | 1529 |
1532 base::TimeDelta ttl = | 1530 base::TimeDelta ttl = |
1533 base::TimeDelta::FromSeconds(kNegativeCacheEntryTTLSeconds); | 1531 base::TimeDelta::FromSeconds(kNegativeCacheEntryTTLSeconds); |
1534 if (net_error == OK) | 1532 if (net_error == OK) |
1535 ttl = base::TimeDelta::FromSeconds(kCacheEntryTTLSeconds); | 1533 ttl = base::TimeDelta::FromSeconds(kCacheEntryTTLSeconds); |
1536 | 1534 |
1537 // Don't store the |ttl| in cache since it's not obtained from the server. | 1535 // Don't store the |ttl| in cache since it's not obtained from the server. |
1538 CompleteRequests( | 1536 CompleteRequests( |
1539 HostCache::Entry(net_error, MakeAddressListForRequest(addr_list)), | 1537 HostCache::Entry(net_error, MakeAddressListForRequest(addr_list)), ttl); |
1540 ttl); | |
1541 } | 1538 } |
1542 | 1539 |
1543 void StartDnsTask() { | 1540 void StartDnsTask() { |
1544 DCHECK(resolver_->HaveDnsConfig()); | 1541 DCHECK(resolver_->HaveDnsConfig()); |
1545 dns_task_.reset(new DnsTask(resolver_->dns_client_.get(), key_, this, | 1542 dns_task_.reset( |
1546 net_log_)); | 1543 new DnsTask(resolver_->dns_client_.get(), key_, this, net_log_)); |
1547 | 1544 |
1548 dns_task_->StartFirstTransaction(); | 1545 dns_task_->StartFirstTransaction(); |
1549 // Schedule a second transaction, if needed. | 1546 // Schedule a second transaction, if needed. |
1550 if (dns_task_->needs_two_transactions()) | 1547 if (dns_task_->needs_two_transactions()) |
1551 Schedule(true); | 1548 Schedule(true); |
1552 } | 1549 } |
1553 | 1550 |
1554 void StartSecondDnsTransaction() { | 1551 void StartSecondDnsTransaction() { |
1555 DCHECK(dns_task_->needs_two_transactions()); | 1552 DCHECK(dns_task_->needs_two_transactions()); |
1556 dns_task_->StartSecondTransaction(); | 1553 dns_task_->StartSecondTransaction(); |
(...skipping 19 matching lines...) Expand all Loading... |
1576 // ProcTask in that case is a waste of time. | 1573 // ProcTask in that case is a waste of time. |
1577 if (resolver_->fallback_to_proctask_) { | 1574 if (resolver_->fallback_to_proctask_) { |
1578 KillDnsTask(); | 1575 KillDnsTask(); |
1579 StartProcTask(); | 1576 StartProcTask(); |
1580 } else { | 1577 } else { |
1581 UmaAsyncDnsResolveStatus(RESOLVE_STATUS_FAIL); | 1578 UmaAsyncDnsResolveStatus(RESOLVE_STATUS_FAIL); |
1582 CompleteRequestsWithError(net_error); | 1579 CompleteRequestsWithError(net_error); |
1583 } | 1580 } |
1584 } | 1581 } |
1585 | 1582 |
1586 | |
1587 // HostResolverImpl::DnsTask::Delegate implementation: | 1583 // HostResolverImpl::DnsTask::Delegate implementation: |
1588 | 1584 |
1589 virtual void OnDnsTaskComplete(base::TimeTicks start_time, | 1585 virtual void OnDnsTaskComplete(base::TimeTicks start_time, |
1590 int net_error, | 1586 int net_error, |
1591 const AddressList& addr_list, | 1587 const AddressList& addr_list, |
1592 base::TimeDelta ttl) OVERRIDE { | 1588 base::TimeDelta ttl) OVERRIDE { |
1593 DCHECK(is_dns_running()); | 1589 DCHECK(is_dns_running()); |
1594 | 1590 |
1595 base::TimeDelta duration = base::TimeTicks::Now() - start_time; | 1591 base::TimeDelta duration = base::TimeTicks::Now() - start_time; |
1596 if (net_error != OK) { | 1592 if (net_error != OK) { |
1597 OnDnsTaskFailure(dns_task_->AsWeakPtr(), duration, net_error); | 1593 OnDnsTaskFailure(dns_task_->AsWeakPtr(), duration, net_error); |
1598 return; | 1594 return; |
1599 } | 1595 } |
1600 DNS_HISTOGRAM("AsyncDNS.ResolveSuccess", duration); | 1596 DNS_HISTOGRAM("AsyncDNS.ResolveSuccess", duration); |
1601 // Log DNS lookups based on |address_family|. | 1597 // Log DNS lookups based on |address_family|. |
1602 switch(key_.address_family) { | 1598 switch (key_.address_family) { |
1603 case ADDRESS_FAMILY_IPV4: | 1599 case ADDRESS_FAMILY_IPV4: |
1604 DNS_HISTOGRAM("AsyncDNS.ResolveSuccess_FAMILY_IPV4", duration); | 1600 DNS_HISTOGRAM("AsyncDNS.ResolveSuccess_FAMILY_IPV4", duration); |
1605 break; | 1601 break; |
1606 case ADDRESS_FAMILY_IPV6: | 1602 case ADDRESS_FAMILY_IPV6: |
1607 DNS_HISTOGRAM("AsyncDNS.ResolveSuccess_FAMILY_IPV6", duration); | 1603 DNS_HISTOGRAM("AsyncDNS.ResolveSuccess_FAMILY_IPV6", duration); |
1608 break; | 1604 break; |
1609 case ADDRESS_FAMILY_UNSPECIFIED: | 1605 case ADDRESS_FAMILY_UNSPECIFIED: |
1610 DNS_HISTOGRAM("AsyncDNS.ResolveSuccess_FAMILY_UNSPEC", duration); | 1606 DNS_HISTOGRAM("AsyncDNS.ResolveSuccess_FAMILY_UNSPEC", duration); |
1611 break; | 1607 break; |
1612 } | 1608 } |
(...skipping 18 matching lines...) Expand all Loading... |
1631 ReduceToOneJobSlot(); | 1627 ReduceToOneJobSlot(); |
1632 | 1628 |
1633 // We already have a job slot at the dispatcher, so if the second | 1629 // We already have a job slot at the dispatcher, so if the second |
1634 // transaction hasn't started, reuse it now instead of waiting in the queue | 1630 // transaction hasn't started, reuse it now instead of waiting in the queue |
1635 // for the second slot. | 1631 // for the second slot. |
1636 if (dns_task_->needs_another_transaction()) | 1632 if (dns_task_->needs_another_transaction()) |
1637 dns_task_->StartSecondTransaction(); | 1633 dns_task_->StartSecondTransaction(); |
1638 } | 1634 } |
1639 | 1635 |
1640 // Performs Job's last rites. Completes all Requests. Deletes this. | 1636 // Performs Job's last rites. Completes all Requests. Deletes this. |
1641 void CompleteRequests(const HostCache::Entry& entry, | 1637 void CompleteRequests(const HostCache::Entry& entry, base::TimeDelta ttl) { |
1642 base::TimeDelta ttl) { | |
1643 CHECK(resolver_.get()); | 1638 CHECK(resolver_.get()); |
1644 | 1639 |
1645 // This job must be removed from resolver's |jobs_| now to make room for a | 1640 // This job must be removed from resolver's |jobs_| now to make room for a |
1646 // new job with the same key in case one of the OnComplete callbacks decides | 1641 // new job with the same key in case one of the OnComplete callbacks decides |
1647 // to spawn one. Consequently, the job deletes itself when CompleteRequests | 1642 // to spawn one. Consequently, the job deletes itself when CompleteRequests |
1648 // is done. | 1643 // is done. |
1649 scoped_ptr<Job> self_deleter(this); | 1644 scoped_ptr<Job> self_deleter(this); |
1650 | 1645 |
1651 resolver_->RemoveJob(this); | 1646 resolver_->RemoveJob(this); |
1652 | 1647 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1684 resolver_->received_dns_config_); | 1679 resolver_->received_dns_config_); |
1685 } | 1680 } |
1686 | 1681 |
1687 bool did_complete = (entry.error != ERR_NETWORK_CHANGED) && | 1682 bool did_complete = (entry.error != ERR_NETWORK_CHANGED) && |
1688 (entry.error != ERR_HOST_RESOLVER_QUEUE_TOO_LARGE); | 1683 (entry.error != ERR_HOST_RESOLVER_QUEUE_TOO_LARGE); |
1689 if (did_complete) | 1684 if (did_complete) |
1690 resolver_->CacheResult(key_, entry, ttl); | 1685 resolver_->CacheResult(key_, entry, ttl); |
1691 | 1686 |
1692 // Complete all of the requests that were attached to the job. | 1687 // Complete all of the requests that were attached to the job. |
1693 for (RequestsList::const_iterator it = requests_.begin(); | 1688 for (RequestsList::const_iterator it = requests_.begin(); |
1694 it != requests_.end(); ++it) { | 1689 it != requests_.end(); |
| 1690 ++it) { |
1695 Request* req = *it; | 1691 Request* req = *it; |
1696 | 1692 |
1697 if (req->was_canceled()) | 1693 if (req->was_canceled()) |
1698 continue; | 1694 continue; |
1699 | 1695 |
1700 DCHECK_EQ(this, req->job()); | 1696 DCHECK_EQ(this, req->job()); |
1701 // Update the net log and notify registered observers. | 1697 // Update the net log and notify registered observers. |
1702 LogFinishRequest(req->source_net_log(), req->request_net_log(), | 1698 LogFinishRequest(req->source_net_log(), |
1703 req->info(), entry.error); | 1699 req->request_net_log(), |
| 1700 req->info(), |
| 1701 entry.error); |
1704 if (did_complete) { | 1702 if (did_complete) { |
1705 // Record effective total time from creation to completion. | 1703 // Record effective total time from creation to completion. |
1706 RecordTotalTime(had_dns_config_, req->info().is_speculative(), | 1704 RecordTotalTime(had_dns_config_, |
| 1705 req->info().is_speculative(), |
1707 base::TimeTicks::Now() - req->request_time()); | 1706 base::TimeTicks::Now() - req->request_time()); |
1708 } | 1707 } |
1709 req->OnComplete(entry.error, entry.addrlist); | 1708 req->OnComplete(entry.error, entry.addrlist); |
1710 | 1709 |
1711 // Check if the resolver was destroyed as a result of running the | 1710 // Check if the resolver was destroyed as a result of running the |
1712 // callback. If it was, we could continue, but we choose to bail. | 1711 // callback. If it was, we could continue, but we choose to bail. |
1713 if (!resolver_.get()) | 1712 if (!resolver_.get()) |
1714 return; | 1713 return; |
1715 } | 1714 } |
1716 } | 1715 } |
1717 | 1716 |
1718 // Convenience wrapper for CompleteRequests in case of failure. | 1717 // Convenience wrapper for CompleteRequests in case of failure. |
1719 void CompleteRequestsWithError(int net_error) { | 1718 void CompleteRequestsWithError(int net_error) { |
1720 CompleteRequests(HostCache::Entry(net_error, AddressList()), | 1719 CompleteRequests(HostCache::Entry(net_error, AddressList()), |
1721 base::TimeDelta()); | 1720 base::TimeDelta()); |
1722 } | 1721 } |
1723 | 1722 |
1724 RequestPriority priority() const { | 1723 RequestPriority priority() const { |
1725 return priority_tracker_.highest_priority(); | 1724 return priority_tracker_.highest_priority(); |
1726 } | 1725 } |
1727 | 1726 |
1728 // Number of non-canceled requests in |requests_|. | 1727 // Number of non-canceled requests in |requests_|. |
1729 size_t num_active_requests() const { | 1728 size_t num_active_requests() const { return priority_tracker_.total_count(); } |
1730 return priority_tracker_.total_count(); | |
1731 } | |
1732 | 1729 |
1733 bool is_dns_running() const { | 1730 bool is_dns_running() const { return dns_task_.get() != NULL; } |
1734 return dns_task_.get() != NULL; | |
1735 } | |
1736 | 1731 |
1737 bool is_proc_running() const { | 1732 bool is_proc_running() const { return proc_task_.get() != NULL; } |
1738 return proc_task_.get() != NULL; | |
1739 } | |
1740 | 1733 |
1741 base::WeakPtr<HostResolverImpl> resolver_; | 1734 base::WeakPtr<HostResolverImpl> resolver_; |
1742 | 1735 |
1743 Key key_; | 1736 Key key_; |
1744 | 1737 |
1745 // Tracks the highest priority across |requests_|. | 1738 // Tracks the highest priority across |requests_|. |
1746 PriorityTracker priority_tracker_; | 1739 PriorityTracker priority_tracker_; |
1747 | 1740 |
1748 bool had_non_speculative_request_; | 1741 bool had_non_speculative_request_; |
1749 | 1742 |
(...skipping 28 matching lines...) Expand all Loading... |
1778 | 1771 |
1779 HostResolverImpl::ProcTaskParams::ProcTaskParams( | 1772 HostResolverImpl::ProcTaskParams::ProcTaskParams( |
1780 HostResolverProc* resolver_proc, | 1773 HostResolverProc* resolver_proc, |
1781 size_t max_retry_attempts) | 1774 size_t max_retry_attempts) |
1782 : resolver_proc(resolver_proc), | 1775 : resolver_proc(resolver_proc), |
1783 max_retry_attempts(max_retry_attempts), | 1776 max_retry_attempts(max_retry_attempts), |
1784 unresponsive_delay(base::TimeDelta::FromMilliseconds(6000)), | 1777 unresponsive_delay(base::TimeDelta::FromMilliseconds(6000)), |
1785 retry_factor(2) { | 1778 retry_factor(2) { |
1786 } | 1779 } |
1787 | 1780 |
1788 HostResolverImpl::ProcTaskParams::~ProcTaskParams() {} | 1781 HostResolverImpl::ProcTaskParams::~ProcTaskParams() { |
| 1782 } |
1789 | 1783 |
1790 HostResolverImpl::HostResolverImpl( | 1784 HostResolverImpl::HostResolverImpl( |
1791 scoped_ptr<HostCache> cache, | 1785 scoped_ptr<HostCache> cache, |
1792 const PrioritizedDispatcher::Limits& job_limits, | 1786 const PrioritizedDispatcher::Limits& job_limits, |
1793 const ProcTaskParams& proc_params, | 1787 const ProcTaskParams& proc_params, |
1794 NetLog* net_log) | 1788 NetLog* net_log) |
1795 : cache_(cache.Pass()), | 1789 : cache_(cache.Pass()), |
1796 dispatcher_(job_limits), | 1790 dispatcher_(job_limits), |
1797 max_queued_jobs_(job_limits.total_jobs * 100u), | 1791 max_queued_jobs_(job_limits.total_jobs * 100u), |
1798 proc_params_(proc_params), | 1792 proc_params_(proc_params), |
1799 net_log_(net_log), | 1793 net_log_(net_log), |
1800 default_address_family_(ADDRESS_FAMILY_UNSPECIFIED), | 1794 default_address_family_(ADDRESS_FAMILY_UNSPECIFIED), |
1801 weak_ptr_factory_(this), | 1795 weak_ptr_factory_(this), |
1802 probe_weak_ptr_factory_(this), | 1796 probe_weak_ptr_factory_(this), |
1803 received_dns_config_(false), | 1797 received_dns_config_(false), |
1804 num_dns_failures_(0), | 1798 num_dns_failures_(0), |
1805 probe_ipv6_support_(true), | 1799 probe_ipv6_support_(true), |
1806 use_local_ipv6_(false), | 1800 use_local_ipv6_(false), |
1807 resolved_known_ipv6_hostname_(false), | 1801 resolved_known_ipv6_hostname_(false), |
1808 additional_resolver_flags_(0), | 1802 additional_resolver_flags_(0), |
1809 fallback_to_proctask_(true) { | 1803 fallback_to_proctask_(true) { |
1810 | |
1811 DCHECK_GE(dispatcher_.num_priorities(), static_cast<size_t>(NUM_PRIORITIES)); | 1804 DCHECK_GE(dispatcher_.num_priorities(), static_cast<size_t>(NUM_PRIORITIES)); |
1812 | 1805 |
1813 // Maximum of 4 retry attempts for host resolution. | 1806 // Maximum of 4 retry attempts for host resolution. |
1814 static const size_t kDefaultMaxRetryAttempts = 4u; | 1807 static const size_t kDefaultMaxRetryAttempts = 4u; |
1815 | 1808 |
1816 if (proc_params_.max_retry_attempts == HostResolver::kDefaultRetryAttempts) | 1809 if (proc_params_.max_retry_attempts == HostResolver::kDefaultRetryAttempts) |
1817 proc_params_.max_retry_attempts = kDefaultMaxRetryAttempts; | 1810 proc_params_.max_retry_attempts = kDefaultMaxRetryAttempts; |
1818 | 1811 |
1819 #if defined(OS_WIN) | 1812 #if defined(OS_WIN) |
1820 EnsureWinsockInit(); | 1813 EnsureWinsockInit(); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1866 DCHECK(addresses); | 1859 DCHECK(addresses); |
1867 DCHECK(CalledOnValidThread()); | 1860 DCHECK(CalledOnValidThread()); |
1868 DCHECK_EQ(false, callback.is_null()); | 1861 DCHECK_EQ(false, callback.is_null()); |
1869 | 1862 |
1870 // Check that the caller supplied a valid hostname to resolve. | 1863 // Check that the caller supplied a valid hostname to resolve. |
1871 std::string labeled_hostname; | 1864 std::string labeled_hostname; |
1872 if (!DNSDomainFromDot(info.hostname(), &labeled_hostname)) | 1865 if (!DNSDomainFromDot(info.hostname(), &labeled_hostname)) |
1873 return ERR_NAME_NOT_RESOLVED; | 1866 return ERR_NAME_NOT_RESOLVED; |
1874 | 1867 |
1875 // Make a log item for the request. | 1868 // Make a log item for the request. |
1876 BoundNetLog request_net_log = BoundNetLog::Make(net_log_, | 1869 BoundNetLog request_net_log = |
1877 NetLog::SOURCE_HOST_RESOLVER_IMPL_REQUEST); | 1870 BoundNetLog::Make(net_log_, NetLog::SOURCE_HOST_RESOLVER_IMPL_REQUEST); |
1878 | 1871 |
1879 LogStartRequest(source_net_log, request_net_log, info); | 1872 LogStartRequest(source_net_log, request_net_log, info); |
1880 | 1873 |
1881 // Build a key that identifies the request in the cache and in the | 1874 // Build a key that identifies the request in the cache and in the |
1882 // outstanding jobs map. | 1875 // outstanding jobs map. |
1883 Key key = GetEffectiveKeyForRequest(info, request_net_log); | 1876 Key key = GetEffectiveKeyForRequest(info, request_net_log); |
1884 | 1877 |
1885 int rv = ResolveHelper(key, info, addresses, request_net_log); | 1878 int rv = ResolveHelper(key, info, addresses, request_net_log); |
1886 if (rv != ERR_DNS_CACHE_MISS) { | 1879 if (rv != ERR_DNS_CACHE_MISS) { |
1887 LogFinishRequest(source_net_log, request_net_log, info, rv); | 1880 LogFinishRequest(source_net_log, request_net_log, info, rv); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1952 return ERR_DNS_CACHE_MISS; | 1945 return ERR_DNS_CACHE_MISS; |
1953 } | 1946 } |
1954 | 1947 |
1955 int HostResolverImpl::ResolveFromCache(const RequestInfo& info, | 1948 int HostResolverImpl::ResolveFromCache(const RequestInfo& info, |
1956 AddressList* addresses, | 1949 AddressList* addresses, |
1957 const BoundNetLog& source_net_log) { | 1950 const BoundNetLog& source_net_log) { |
1958 DCHECK(CalledOnValidThread()); | 1951 DCHECK(CalledOnValidThread()); |
1959 DCHECK(addresses); | 1952 DCHECK(addresses); |
1960 | 1953 |
1961 // Make a log item for the request. | 1954 // Make a log item for the request. |
1962 BoundNetLog request_net_log = BoundNetLog::Make(net_log_, | 1955 BoundNetLog request_net_log = |
1963 NetLog::SOURCE_HOST_RESOLVER_IMPL_REQUEST); | 1956 BoundNetLog::Make(net_log_, NetLog::SOURCE_HOST_RESOLVER_IMPL_REQUEST); |
1964 | 1957 |
1965 // Update the net log and notify registered observers. | 1958 // Update the net log and notify registered observers. |
1966 LogStartRequest(source_net_log, request_net_log, info); | 1959 LogStartRequest(source_net_log, request_net_log, info); |
1967 | 1960 |
1968 Key key = GetEffectiveKeyForRequest(info, request_net_log); | 1961 Key key = GetEffectiveKeyForRequest(info, request_net_log); |
1969 | 1962 |
1970 int rv = ResolveHelper(key, info, addresses, request_net_log); | 1963 int rv = ResolveHelper(key, info, addresses, request_net_log); |
1971 LogFinishRequest(source_net_log, request_net_log, info, rv); | 1964 LogFinishRequest(source_net_log, request_net_log, info, rv); |
1972 return rv; | 1965 return rv; |
1973 } | 1966 } |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2024 const RequestInfo& info, | 2017 const RequestInfo& info, |
2025 int* net_error, | 2018 int* net_error, |
2026 AddressList* addresses) { | 2019 AddressList* addresses) { |
2027 DCHECK(addresses); | 2020 DCHECK(addresses); |
2028 DCHECK(net_error); | 2021 DCHECK(net_error); |
2029 IPAddressNumber ip_number; | 2022 IPAddressNumber ip_number; |
2030 if (!ParseIPLiteralToNumber(key.hostname, &ip_number)) | 2023 if (!ParseIPLiteralToNumber(key.hostname, &ip_number)) |
2031 return false; | 2024 return false; |
2032 | 2025 |
2033 DCHECK_EQ(key.host_resolver_flags & | 2026 DCHECK_EQ(key.host_resolver_flags & |
2034 ~(HOST_RESOLVER_CANONNAME | HOST_RESOLVER_LOOPBACK_ONLY | | 2027 ~(HOST_RESOLVER_CANONNAME | HOST_RESOLVER_LOOPBACK_ONLY | |
2035 HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6), | 2028 HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6), |
2036 0) << " Unhandled flag"; | 2029 0) |
2037 bool ipv6_disabled = (default_address_family_ == ADDRESS_FAMILY_IPV4) && | 2030 << " Unhandled flag"; |
2038 !probe_ipv6_support_; | 2031 bool ipv6_disabled = |
| 2032 (default_address_family_ == ADDRESS_FAMILY_IPV4) && !probe_ipv6_support_; |
2039 *net_error = OK; | 2033 *net_error = OK; |
2040 if ((ip_number.size() == kIPv6AddressSize) && ipv6_disabled) { | 2034 if ((ip_number.size() == kIPv6AddressSize) && ipv6_disabled) { |
2041 *net_error = ERR_NAME_NOT_RESOLVED; | 2035 *net_error = ERR_NAME_NOT_RESOLVED; |
2042 } else { | 2036 } else { |
2043 *addresses = AddressList::CreateFromIPAddress(ip_number, info.port()); | 2037 *addresses = AddressList::CreateFromIPAddress(ip_number, info.port()); |
2044 if (key.host_resolver_flags & HOST_RESOLVER_CANONNAME) | 2038 if (key.host_resolver_flags & HOST_RESOLVER_CANONNAME) |
2045 addresses->SetDefaultCanonicalName(); | 2039 addresses->SetDefaultCanonicalName(); |
2046 } | 2040 } |
2047 return true; | 2041 return true; |
2048 } | 2042 } |
2049 | 2043 |
2050 bool HostResolverImpl::ServeFromCache(const Key& key, | 2044 bool HostResolverImpl::ServeFromCache(const Key& key, |
2051 const RequestInfo& info, | 2045 const RequestInfo& info, |
2052 int* net_error, | 2046 int* net_error, |
2053 AddressList* addresses) { | 2047 AddressList* addresses) { |
2054 DCHECK(addresses); | 2048 DCHECK(addresses); |
2055 DCHECK(net_error); | 2049 DCHECK(net_error); |
2056 if (!info.allow_cached_response() || !cache_.get()) | 2050 if (!info.allow_cached_response() || !cache_.get()) |
2057 return false; | 2051 return false; |
2058 | 2052 |
2059 const HostCache::Entry* cache_entry = cache_->Lookup( | 2053 const HostCache::Entry* cache_entry = |
2060 key, base::TimeTicks::Now()); | 2054 cache_->Lookup(key, base::TimeTicks::Now()); |
2061 if (!cache_entry) | 2055 if (!cache_entry) |
2062 return false; | 2056 return false; |
2063 | 2057 |
2064 *net_error = cache_entry->error; | 2058 *net_error = cache_entry->error; |
2065 if (*net_error == OK) { | 2059 if (*net_error == OK) { |
2066 if (cache_entry->has_ttl()) | 2060 if (cache_entry->has_ttl()) |
2067 RecordTTL(cache_entry->ttl); | 2061 RecordTTL(cache_entry->ttl); |
2068 *addresses = EnsurePortOnAddressList(cache_entry->addrlist, info.port()); | 2062 *addresses = EnsurePortOnAddressList(cache_entry->addrlist, info.port()); |
2069 } | 2063 } |
2070 return true; | 2064 return true; |
(...skipping 12 matching lines...) Expand all Loading... |
2083 | 2077 |
2084 const DnsHosts& hosts = dns_client_->GetConfig()->hosts; | 2078 const DnsHosts& hosts = dns_client_->GetConfig()->hosts; |
2085 | 2079 |
2086 // If |address_family| is ADDRESS_FAMILY_UNSPECIFIED other implementations | 2080 // If |address_family| is ADDRESS_FAMILY_UNSPECIFIED other implementations |
2087 // (glibc and c-ares) return the first matching line. We have more | 2081 // (glibc and c-ares) return the first matching line. We have more |
2088 // flexibility, but lose implicit ordering. | 2082 // flexibility, but lose implicit ordering. |
2089 // We prefer IPv6 because "happy eyeballs" will fall back to IPv4 if | 2083 // We prefer IPv6 because "happy eyeballs" will fall back to IPv4 if |
2090 // necessary. | 2084 // necessary. |
2091 if (key.address_family == ADDRESS_FAMILY_IPV6 || | 2085 if (key.address_family == ADDRESS_FAMILY_IPV6 || |
2092 key.address_family == ADDRESS_FAMILY_UNSPECIFIED) { | 2086 key.address_family == ADDRESS_FAMILY_UNSPECIFIED) { |
2093 DnsHosts::const_iterator it = hosts.find( | 2087 DnsHosts::const_iterator it = |
2094 DnsHostsKey(hostname, ADDRESS_FAMILY_IPV6)); | 2088 hosts.find(DnsHostsKey(hostname, ADDRESS_FAMILY_IPV6)); |
2095 if (it != hosts.end()) | 2089 if (it != hosts.end()) |
2096 addresses->push_back(IPEndPoint(it->second, info.port())); | 2090 addresses->push_back(IPEndPoint(it->second, info.port())); |
2097 } | 2091 } |
2098 | 2092 |
2099 if (key.address_family == ADDRESS_FAMILY_IPV4 || | 2093 if (key.address_family == ADDRESS_FAMILY_IPV4 || |
2100 key.address_family == ADDRESS_FAMILY_UNSPECIFIED) { | 2094 key.address_family == ADDRESS_FAMILY_UNSPECIFIED) { |
2101 DnsHosts::const_iterator it = hosts.find( | 2095 DnsHosts::const_iterator it = |
2102 DnsHostsKey(hostname, ADDRESS_FAMILY_IPV4)); | 2096 hosts.find(DnsHostsKey(hostname, ADDRESS_FAMILY_IPV4)); |
2103 if (it != hosts.end()) | 2097 if (it != hosts.end()) |
2104 addresses->push_back(IPEndPoint(it->second, info.port())); | 2098 addresses->push_back(IPEndPoint(it->second, info.port())); |
2105 } | 2099 } |
2106 | 2100 |
2107 // If got only loopback addresses and the family was restricted, resolve | 2101 // If got only loopback addresses and the family was restricted, resolve |
2108 // again, without restrictions. See SystemHostResolverCall for rationale. | 2102 // again, without restrictions. See SystemHostResolverCall for rationale. |
2109 if ((key.host_resolver_flags & | 2103 if ((key.host_resolver_flags & |
2110 HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6) && | 2104 HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6) && |
2111 IsAllIPv4Loopback(*addresses)) { | 2105 IsAllIPv4Loopback(*addresses)) { |
2112 Key new_key(key); | 2106 Key new_key(key); |
2113 new_key.address_family = ADDRESS_FAMILY_UNSPECIFIED; | 2107 new_key.address_family = ADDRESS_FAMILY_UNSPECIFIED; |
2114 new_key.host_resolver_flags &= | 2108 new_key.host_resolver_flags &= |
2115 ~HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6; | 2109 ~HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6; |
2116 return ServeFromHosts(new_key, info, addresses); | 2110 return ServeFromHosts(new_key, info, addresses); |
2117 } | 2111 } |
2118 return !addresses->empty(); | 2112 return !addresses->empty(); |
2119 } | 2113 } |
2120 | 2114 |
(...skipping 13 matching lines...) Expand all Loading... |
2134 | 2128 |
2135 void HostResolverImpl::SetHaveOnlyLoopbackAddresses(bool result) { | 2129 void HostResolverImpl::SetHaveOnlyLoopbackAddresses(bool result) { |
2136 if (result) { | 2130 if (result) { |
2137 additional_resolver_flags_ |= HOST_RESOLVER_LOOPBACK_ONLY; | 2131 additional_resolver_flags_ |= HOST_RESOLVER_LOOPBACK_ONLY; |
2138 } else { | 2132 } else { |
2139 additional_resolver_flags_ &= ~HOST_RESOLVER_LOOPBACK_ONLY; | 2133 additional_resolver_flags_ &= ~HOST_RESOLVER_LOOPBACK_ONLY; |
2140 } | 2134 } |
2141 } | 2135 } |
2142 | 2136 |
2143 HostResolverImpl::Key HostResolverImpl::GetEffectiveKeyForRequest( | 2137 HostResolverImpl::Key HostResolverImpl::GetEffectiveKeyForRequest( |
2144 const RequestInfo& info, const BoundNetLog& net_log) const { | 2138 const RequestInfo& info, |
| 2139 const BoundNetLog& net_log) const { |
2145 HostResolverFlags effective_flags = | 2140 HostResolverFlags effective_flags = |
2146 info.host_resolver_flags() | additional_resolver_flags_; | 2141 info.host_resolver_flags() | additional_resolver_flags_; |
2147 AddressFamily effective_address_family = info.address_family(); | 2142 AddressFamily effective_address_family = info.address_family(); |
2148 | 2143 |
2149 if (info.address_family() == ADDRESS_FAMILY_UNSPECIFIED) { | 2144 if (info.address_family() == ADDRESS_FAMILY_UNSPECIFIED) { |
2150 if (probe_ipv6_support_ && !use_local_ipv6_) { | 2145 if (probe_ipv6_support_ && !use_local_ipv6_) { |
2151 base::TimeTicks start_time = base::TimeTicks::Now(); | 2146 base::TimeTicks start_time = base::TimeTicks::Now(); |
2152 // Google DNS address. | 2147 // Google DNS address. |
2153 const uint8 kIPv6Address[] = | 2148 const uint8 kIPv6Address[] = {0x20, 0x01, 0x48, 0x60, 0x48, 0x60, |
2154 { 0x20, 0x01, 0x48, 0x60, 0x48, 0x60, 0x00, 0x00, | 2149 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
2155 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88 }; | 2150 0x00, 0x00, 0x88, 0x88}; |
2156 IPAddressNumber address(kIPv6Address, | 2151 IPAddressNumber address(kIPv6Address, |
2157 kIPv6Address + arraysize(kIPv6Address)); | 2152 kIPv6Address + arraysize(kIPv6Address)); |
2158 BoundNetLog probe_net_log = BoundNetLog::Make( | 2153 BoundNetLog probe_net_log = BoundNetLog::Make( |
2159 net_log.net_log(), NetLog::SOURCE_IPV6_REACHABILITY_CHECK); | 2154 net_log.net_log(), NetLog::SOURCE_IPV6_REACHABILITY_CHECK); |
2160 probe_net_log.BeginEvent(NetLog::TYPE_IPV6_REACHABILITY_CHECK, | 2155 probe_net_log.BeginEvent(NetLog::TYPE_IPV6_REACHABILITY_CHECK, |
2161 net_log.source().ToEventParametersCallback()); | 2156 net_log.source().ToEventParametersCallback()); |
2162 bool rv6 = IsGloballyReachable(address, probe_net_log); | 2157 bool rv6 = IsGloballyReachable(address, probe_net_log); |
2163 probe_net_log.EndEvent(NetLog::TYPE_IPV6_REACHABILITY_CHECK); | 2158 probe_net_log.EndEvent(NetLog::TYPE_IPV6_REACHABILITY_CHECK); |
2164 if (rv6) | 2159 if (rv6) |
2165 net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_IPV6_SUPPORTED); | 2160 net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_IPV6_SUPPORTED); |
2166 | 2161 |
2167 UMA_HISTOGRAM_TIMES("Net.IPv6ConnectDuration", | 2162 UMA_HISTOGRAM_TIMES("Net.IPv6ConnectDuration", |
2168 base::TimeTicks::Now() - start_time); | 2163 base::TimeTicks::Now() - start_time); |
2169 if (rv6) { | 2164 if (rv6) { |
2170 UMA_HISTOGRAM_BOOLEAN("Net.IPv6ConnectSuccessMatch", | 2165 UMA_HISTOGRAM_BOOLEAN( |
| 2166 "Net.IPv6ConnectSuccessMatch", |
2171 default_address_family_ == ADDRESS_FAMILY_UNSPECIFIED); | 2167 default_address_family_ == ADDRESS_FAMILY_UNSPECIFIED); |
2172 } else { | 2168 } else { |
2173 UMA_HISTOGRAM_BOOLEAN("Net.IPv6ConnectFailureMatch", | 2169 UMA_HISTOGRAM_BOOLEAN( |
| 2170 "Net.IPv6ConnectFailureMatch", |
2174 default_address_family_ != ADDRESS_FAMILY_UNSPECIFIED); | 2171 default_address_family_ != ADDRESS_FAMILY_UNSPECIFIED); |
2175 | 2172 |
2176 effective_address_family = ADDRESS_FAMILY_IPV4; | 2173 effective_address_family = ADDRESS_FAMILY_IPV4; |
2177 effective_flags |= HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6; | 2174 effective_flags |= HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6; |
2178 } | 2175 } |
2179 } else { | 2176 } else { |
2180 effective_address_family = default_address_family_; | 2177 effective_address_family = default_address_family_; |
2181 } | 2178 } |
2182 } | 2179 } |
2183 | 2180 |
2184 return Key(info.hostname(), effective_address_family, effective_flags); | 2181 return Key(info.hostname(), effective_address_family, effective_flags); |
2185 } | 2182 } |
2186 | 2183 |
2187 void HostResolverImpl::AbortAllInProgressJobs() { | 2184 void HostResolverImpl::AbortAllInProgressJobs() { |
2188 // In Abort, a Request callback could spawn new Jobs with matching keys, so | 2185 // In Abort, a Request callback could spawn new Jobs with matching keys, so |
2189 // first collect and remove all running jobs from |jobs_|. | 2186 // first collect and remove all running jobs from |jobs_|. |
2190 ScopedVector<Job> jobs_to_abort; | 2187 ScopedVector<Job> jobs_to_abort; |
2191 for (JobMap::iterator it = jobs_.begin(); it != jobs_.end(); ) { | 2188 for (JobMap::iterator it = jobs_.begin(); it != jobs_.end();) { |
2192 Job* job = it->second; | 2189 Job* job = it->second; |
2193 if (job->is_running()) { | 2190 if (job->is_running()) { |
2194 jobs_to_abort.push_back(job); | 2191 jobs_to_abort.push_back(job); |
2195 jobs_.erase(it++); | 2192 jobs_.erase(it++); |
2196 } else { | 2193 } else { |
2197 DCHECK(job->is_queued()); | 2194 DCHECK(job->is_queued()); |
2198 ++it; | 2195 ++it; |
2199 } | 2196 } |
2200 } | 2197 } |
2201 | 2198 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2262 #endif | 2259 #endif |
2263 AbortAllInProgressJobs(); | 2260 AbortAllInProgressJobs(); |
2264 // |this| may be deleted inside AbortAllInProgressJobs(). | 2261 // |this| may be deleted inside AbortAllInProgressJobs(). |
2265 } | 2262 } |
2266 | 2263 |
2267 void HostResolverImpl::OnDNSChanged() { | 2264 void HostResolverImpl::OnDNSChanged() { |
2268 DnsConfig dns_config; | 2265 DnsConfig dns_config; |
2269 NetworkChangeNotifier::GetDnsConfig(&dns_config); | 2266 NetworkChangeNotifier::GetDnsConfig(&dns_config); |
2270 | 2267 |
2271 if (net_log_) { | 2268 if (net_log_) { |
2272 net_log_->AddGlobalEntry( | 2269 net_log_->AddGlobalEntry(NetLog::TYPE_DNS_CONFIG_CHANGED, |
2273 NetLog::TYPE_DNS_CONFIG_CHANGED, | 2270 base::Bind(&NetLogDnsConfigCallback, &dns_config)); |
2274 base::Bind(&NetLogDnsConfigCallback, &dns_config)); | |
2275 } | 2271 } |
2276 | 2272 |
2277 // TODO(szym): Remove once http://crbug.com/137914 is resolved. | 2273 // TODO(szym): Remove once http://crbug.com/137914 is resolved. |
2278 received_dns_config_ = dns_config.IsValid(); | 2274 received_dns_config_ = dns_config.IsValid(); |
2279 // Conservatively assume local IPv6 is needed when DnsConfig is not valid. | 2275 // Conservatively assume local IPv6 is needed when DnsConfig is not valid. |
2280 use_local_ipv6_ = !dns_config.IsValid() || dns_config.use_local_ipv6; | 2276 use_local_ipv6_ = !dns_config.IsValid() || dns_config.use_local_ipv6; |
2281 | 2277 |
2282 num_dns_failures_ = 0; | 2278 num_dns_failures_ = 0; |
2283 | 2279 |
2284 // We want a new DnsSession in place, before we Abort running Jobs, so that | 2280 // We want a new DnsSession in place, before we Abort running Jobs, so that |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2352 dns_client_->SetConfig(dns_config); | 2348 dns_client_->SetConfig(dns_config); |
2353 num_dns_failures_ = 0; | 2349 num_dns_failures_ = 0; |
2354 if (dns_client_->GetConfig()) | 2350 if (dns_client_->GetConfig()) |
2355 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.DnsClientEnabled", true); | 2351 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.DnsClientEnabled", true); |
2356 } | 2352 } |
2357 | 2353 |
2358 AbortDnsTasks(); | 2354 AbortDnsTasks(); |
2359 } | 2355 } |
2360 | 2356 |
2361 } // namespace net | 2357 } // namespace net |
OLD | NEW |