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