| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/dns/async_host_resolver.h" | 5 #include "net/dns/async_host_resolver.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 // in-progress requests, causing them to be cancelled. Synchronous | 79 // in-progress requests, causing them to be cancelled. Synchronous |
| 80 // resolution sets |callback_| to NULL, thus, if in the destructor we still | 80 // resolution sets |callback_| to NULL, thus, if in the destructor we still |
| 81 // have a non-NULL |callback_|, we are being cancelled. | 81 // have a non-NULL |callback_|, we are being cancelled. |
| 82 class AsyncHostResolver::Request { | 82 class AsyncHostResolver::Request { |
| 83 public: | 83 public: |
| 84 Request(AsyncHostResolver* resolver, | 84 Request(AsyncHostResolver* resolver, |
| 85 const BoundNetLog& source_net_log, | 85 const BoundNetLog& source_net_log, |
| 86 const BoundNetLog& request_net_log, | 86 const BoundNetLog& request_net_log, |
| 87 int id, | 87 int id, |
| 88 const HostResolver::RequestInfo& info, | 88 const HostResolver::RequestInfo& info, |
| 89 OldCompletionCallback* callback, | 89 const CompletionCallback& callback, |
| 90 AddressList* addresses) | 90 AddressList* addresses) |
| 91 : resolver_(resolver), | 91 : resolver_(resolver), |
| 92 source_net_log_(source_net_log), | 92 source_net_log_(source_net_log), |
| 93 request_net_log_(request_net_log), | 93 request_net_log_(request_net_log), |
| 94 id_(id), | 94 id_(id), |
| 95 info_(info), | 95 info_(info), |
| 96 callback_(callback), | 96 callback_(callback), |
| 97 addresses_(addresses), | 97 addresses_(addresses), |
| 98 result_(ERR_UNEXPECTED) { | 98 result_(ERR_UNEXPECTED) { |
| 99 DCHECK(addresses_); | 99 DCHECK(addresses_); |
| 100 DCHECK(resolver_); | 100 DCHECK(resolver_); |
| 101 resolver_->OnStart(this); | 101 resolver_->OnStart(this); |
| 102 std::string dns_name; | 102 std::string dns_name; |
| 103 if (DNSDomainFromDot(info.hostname(), &dns_name)) | 103 if (DNSDomainFromDot(info.hostname(), &dns_name)) |
| 104 key_ = Key(dns_name, QueryTypeFromAddressFamily(info.address_family())); | 104 key_ = Key(dns_name, QueryTypeFromAddressFamily(info.address_family())); |
| 105 } | 105 } |
| 106 | 106 |
| 107 ~Request() { | 107 ~Request() { |
| 108 if (callback_) | 108 if (!callback_.is_null()) |
| 109 resolver_->OnCancel(this); | 109 resolver_->OnCancel(this); |
| 110 } | 110 } |
| 111 | 111 |
| 112 int id() const { return id_; } | 112 int id() const { return id_; } |
| 113 int result() const { return result_; } | 113 int result() const { return result_; } |
| 114 const Key& key() const { | 114 const Key& key() const { |
| 115 DCHECK(IsValid()); | 115 DCHECK(IsValid()); |
| 116 return key_; | 116 return key_; |
| 117 } | 117 } |
| 118 const HostResolver::RequestInfo& info() const { return info_; } | 118 const HostResolver::RequestInfo& info() const { return info_; } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 157 } | 157 } |
| 158 return false; | 158 return false; |
| 159 } | 159 } |
| 160 | 160 |
| 161 // Called when a request completes synchronously; we do not have an | 161 // Called when a request completes synchronously; we do not have an |
| 162 // AddressList argument, since in case of a successful synchronous | 162 // AddressList argument, since in case of a successful synchronous |
| 163 // completion, either ResolveAsIp or ServerFromCache would set the | 163 // completion, either ResolveAsIp or ServerFromCache would set the |
| 164 // |addresses_| and in case of an unsuccessful synchronous completion, we | 164 // |addresses_| and in case of an unsuccessful synchronous completion, we |
| 165 // do not touch |addresses_|. | 165 // do not touch |addresses_|. |
| 166 void OnSyncComplete(int result) { | 166 void OnSyncComplete(int result) { |
| 167 callback_ = NULL; | 167 callback_.Reset(); |
| 168 resolver_->OnFinish(this, result); | 168 resolver_->OnFinish(this, result); |
| 169 } | 169 } |
| 170 | 170 |
| 171 // Called when a request completes asynchronously. | 171 // Called when a request completes asynchronously. |
| 172 void OnAsyncComplete(int result, const AddressList& addresses) { | 172 void OnAsyncComplete(int result, const AddressList& addresses) { |
| 173 if (result == OK) | 173 if (result == OK) |
| 174 *addresses_ = CreateAddressListUsingPort(addresses, info_.port()); | 174 *addresses_ = CreateAddressListUsingPort(addresses, info_.port()); |
| 175 DCHECK(callback_); | 175 DCHECK_EQ(false, callback_.is_null()); |
| 176 OldCompletionCallback* callback = callback_; | 176 CompletionCallback callback = callback_; |
| 177 callback_ = NULL; | 177 callback_.Reset(); |
| 178 resolver_->OnFinish(this, result); | 178 resolver_->OnFinish(this, result); |
| 179 callback->Run(result); | 179 callback.Run(result); |
| 180 } | 180 } |
| 181 | 181 |
| 182 // Returns true if request has a validly formed hostname. | 182 // Returns true if request has a validly formed hostname. |
| 183 bool IsValid() const { | 183 bool IsValid() const { |
| 184 return !info_.hostname().empty() && !key_.first.empty(); | 184 return !info_.hostname().empty() && !key_.first.empty(); |
| 185 } | 185 } |
| 186 | 186 |
| 187 private: | 187 private: |
| 188 AsyncHostResolver* resolver_; | 188 AsyncHostResolver* resolver_; |
| 189 BoundNetLog source_net_log_; | 189 BoundNetLog source_net_log_; |
| 190 BoundNetLog request_net_log_; | 190 BoundNetLog request_net_log_; |
| 191 const int id_; | 191 const int id_; |
| 192 const HostResolver::RequestInfo info_; | 192 const HostResolver::RequestInfo info_; |
| 193 Key key_; | 193 Key key_; |
| 194 OldCompletionCallback* callback_; | 194 CompletionCallback callback_; |
| 195 AddressList* addresses_; | 195 AddressList* addresses_; |
| 196 int result_; | 196 int result_; |
| 197 }; | 197 }; |
| 198 | 198 |
| 199 //----------------------------------------------------------------------------- | 199 //----------------------------------------------------------------------------- |
| 200 AsyncHostResolver::AsyncHostResolver(const IPEndPoint& dns_server, | 200 AsyncHostResolver::AsyncHostResolver(const IPEndPoint& dns_server, |
| 201 size_t max_transactions, | 201 size_t max_transactions, |
| 202 size_t max_pending_requests, | 202 size_t max_pending_requests, |
| 203 const RandIntCallback& rand_int_cb, | 203 const RandIntCallback& rand_int_cb, |
| 204 HostCache* cache, | 204 HostCache* cache, |
| (...skipping 18 matching lines...) Expand all Loading... |
| 223 // Destroy transactions. | 223 // Destroy transactions. |
| 224 STLDeleteElements(&transactions_); | 224 STLDeleteElements(&transactions_); |
| 225 | 225 |
| 226 // Destroy pending requests. | 226 // Destroy pending requests. |
| 227 for (size_t i = 0; i < arraysize(pending_requests_); ++i) | 227 for (size_t i = 0; i < arraysize(pending_requests_); ++i) |
| 228 STLDeleteElements(&pending_requests_[i]); | 228 STLDeleteElements(&pending_requests_[i]); |
| 229 } | 229 } |
| 230 | 230 |
| 231 int AsyncHostResolver::Resolve(const RequestInfo& info, | 231 int AsyncHostResolver::Resolve(const RequestInfo& info, |
| 232 AddressList* addresses, | 232 AddressList* addresses, |
| 233 OldCompletionCallback* callback, | 233 const CompletionCallback& callback, |
| 234 RequestHandle* out_req, | 234 RequestHandle* out_req, |
| 235 const BoundNetLog& source_net_log) { | 235 const BoundNetLog& source_net_log) { |
| 236 DCHECK(addresses); | 236 DCHECK(addresses); |
| 237 DCHECK(callback); | 237 DCHECK_EQ(false, callback.is_null()); |
| 238 scoped_ptr<Request> request( | 238 scoped_ptr<Request> request( |
| 239 CreateNewRequest(info, callback, addresses, source_net_log)); | 239 CreateNewRequest(info, callback, addresses, source_net_log)); |
| 240 | 240 |
| 241 int rv = ERR_UNEXPECTED; | 241 int rv = ERR_UNEXPECTED; |
| 242 if (!request->IsValid()) | 242 if (!request->IsValid()) |
| 243 rv = ERR_NAME_NOT_RESOLVED; | 243 rv = ERR_NAME_NOT_RESOLVED; |
| 244 else if (request->ResolveAsIp() || request->ServeFromCache()) | 244 else if (request->ResolveAsIp() || request->ServeFromCache()) |
| 245 rv = request->result(); | 245 rv = request->result(); |
| 246 else if (AttachToRequestList(request.get())) | 246 else if (AttachToRequestList(request.get())) |
| 247 rv = ERR_IO_PENDING; | 247 rv = ERR_IO_PENDING; |
| 248 else if (transactions_.size() < max_transactions_) | 248 else if (transactions_.size() < max_transactions_) |
| 249 rv = StartNewTransactionFor(request.get()); | 249 rv = StartNewTransactionFor(request.get()); |
| 250 else | 250 else |
| 251 rv = Enqueue(request.get()); | 251 rv = Enqueue(request.get()); |
| 252 | 252 |
| 253 if (rv != ERR_IO_PENDING) { | 253 if (rv != ERR_IO_PENDING) { |
| 254 request->OnSyncComplete(rv); | 254 request->OnSyncComplete(rv); |
| 255 } else { | 255 } else { |
| 256 Request* req = request.release(); | 256 Request* req = request.release(); |
| 257 if (out_req) | 257 if (out_req) |
| 258 *out_req = reinterpret_cast<RequestHandle>(req); | 258 *out_req = reinterpret_cast<RequestHandle>(req); |
| 259 } | 259 } |
| 260 return rv; | 260 return rv; |
| 261 } | 261 } |
| 262 | 262 |
| 263 int AsyncHostResolver::ResolveFromCache(const RequestInfo& info, | 263 int AsyncHostResolver::ResolveFromCache(const RequestInfo& info, |
| 264 AddressList* addresses, | 264 AddressList* addresses, |
| 265 const BoundNetLog& source_net_log) { | 265 const BoundNetLog& source_net_log) { |
| 266 scoped_ptr<Request> request( | 266 scoped_ptr<Request> request( |
| 267 CreateNewRequest(info, NULL, addresses, source_net_log)); | 267 CreateNewRequest(info, CompletionCallback(), addresses, source_net_log)); |
| 268 int rv = ERR_UNEXPECTED; | 268 int rv = ERR_UNEXPECTED; |
| 269 if (!request->IsValid()) | 269 if (!request->IsValid()) |
| 270 rv = ERR_NAME_NOT_RESOLVED; | 270 rv = ERR_NAME_NOT_RESOLVED; |
| 271 else if (request->ResolveAsIp() || request->ServeFromCache()) | 271 else if (request->ResolveAsIp() || request->ServeFromCache()) |
| 272 rv = request->result(); | 272 rv = request->result(); |
| 273 else | 273 else |
| 274 rv = ERR_DNS_CACHE_MISS; | 274 rv = ERR_DNS_CACHE_MISS; |
| 275 request->OnSyncComplete(rv); | 275 request->OnSyncComplete(rv); |
| 276 return rv; | 276 return rv; |
| 277 } | 277 } |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 403 requestlist_map_.erase(transaction->key()); | 403 requestlist_map_.erase(transaction->key()); |
| 404 | 404 |
| 405 // Cleanup transaction and start a new one if there are pending requests. | 405 // Cleanup transaction and start a new one if there are pending requests. |
| 406 delete transaction; | 406 delete transaction; |
| 407 transactions_.remove(transaction); | 407 transactions_.remove(transaction); |
| 408 ProcessPending(); | 408 ProcessPending(); |
| 409 } | 409 } |
| 410 | 410 |
| 411 AsyncHostResolver::Request* AsyncHostResolver::CreateNewRequest( | 411 AsyncHostResolver::Request* AsyncHostResolver::CreateNewRequest( |
| 412 const RequestInfo& info, | 412 const RequestInfo& info, |
| 413 OldCompletionCallback* callback, | 413 const CompletionCallback& callback, |
| 414 AddressList* addresses, | 414 AddressList* addresses, |
| 415 const BoundNetLog& source_net_log) { | 415 const BoundNetLog& source_net_log) { |
| 416 BoundNetLog request_net_log = BoundNetLog::Make(net_log_, | 416 BoundNetLog request_net_log = BoundNetLog::Make(net_log_, |
| 417 NetLog::SOURCE_ASYNC_HOST_RESOLVER_REQUEST); | 417 NetLog::SOURCE_ASYNC_HOST_RESOLVER_REQUEST); |
| 418 int id = next_request_id_++; | 418 int id = next_request_id_++; |
| 419 return new Request( | 419 return new Request( |
| 420 this, source_net_log, request_net_log, id, info, callback, addresses); | 420 this, source_net_log, request_net_log, id, info, callback, addresses); |
| 421 } | 421 } |
| 422 | 422 |
| 423 bool AsyncHostResolver::AttachToRequestList(Request* request) { | 423 bool AsyncHostResolver::AttachToRequestList(Request* request) { |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 516 it = requests.erase(it); | 516 it = requests.erase(it); |
| 517 } else { | 517 } else { |
| 518 ++it; | 518 ++it; |
| 519 } | 519 } |
| 520 } | 520 } |
| 521 } | 521 } |
| 522 StartNewTransactionFor(request); | 522 StartNewTransactionFor(request); |
| 523 } | 523 } |
| 524 | 524 |
| 525 } // namespace net | 525 } // namespace net |
| OLD | NEW |