| 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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 // the destruction of AsyncHostResolver, which would destruct pending or | 78 // the destruction of AsyncHostResolver, which would destruct pending or |
| 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 const HostResolver::RequestInfo& info, | 87 const HostResolver::RequestInfo& info, |
| 88 OldCompletionCallback* callback, | 88 const CompletionCallback& callback, |
| 89 AddressList* addresses) | 89 AddressList* addresses) |
| 90 : resolver_(resolver), | 90 : resolver_(resolver), |
| 91 source_net_log_(source_net_log), | 91 source_net_log_(source_net_log), |
| 92 request_net_log_(request_net_log), | 92 request_net_log_(request_net_log), |
| 93 info_(info), | 93 info_(info), |
| 94 callback_(callback), | 94 callback_(callback), |
| 95 addresses_(addresses), | 95 addresses_(addresses), |
| 96 result_(ERR_UNEXPECTED) { | 96 result_(ERR_UNEXPECTED) { |
| 97 DCHECK(addresses_); | 97 DCHECK(addresses_); |
| 98 DCHECK(resolver_); | 98 DCHECK(resolver_); |
| 99 resolver_->OnStart(this); | 99 resolver_->OnStart(this); |
| 100 std::string dns_name; | 100 std::string dns_name; |
| 101 if (DNSDomainFromDot(info.hostname(), &dns_name)) | 101 if (DNSDomainFromDot(info.hostname(), &dns_name)) |
| 102 key_ = Key(dns_name, QueryTypeFromAddressFamily(info.address_family())); | 102 key_ = Key(dns_name, QueryTypeFromAddressFamily(info.address_family())); |
| 103 } | 103 } |
| 104 | 104 |
| 105 ~Request() { | 105 ~Request() { |
| 106 if (callback_) | 106 if (!callback_.is_null()) |
| 107 resolver_->OnCancel(this); | 107 resolver_->OnCancel(this); |
| 108 } | 108 } |
| 109 | 109 |
| 110 int result() const { return result_; } | 110 int result() const { return result_; } |
| 111 const Key& key() const { | 111 const Key& key() const { |
| 112 DCHECK(IsValid()); | 112 DCHECK(IsValid()); |
| 113 return key_; | 113 return key_; |
| 114 } | 114 } |
| 115 const HostResolver::RequestInfo& info() const { return info_; } | 115 const HostResolver::RequestInfo& info() const { return info_; } |
| 116 RequestPriority priority() const { return info_.priority(); } | 116 RequestPriority priority() const { return info_.priority(); } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 154 } | 154 } |
| 155 return false; | 155 return false; |
| 156 } | 156 } |
| 157 | 157 |
| 158 // Called when a request completes synchronously; we do not have an | 158 // Called when a request completes synchronously; we do not have an |
| 159 // AddressList argument, since in case of a successful synchronous | 159 // AddressList argument, since in case of a successful synchronous |
| 160 // completion, either ResolveAsIp or ServerFromCache would set the | 160 // completion, either ResolveAsIp or ServerFromCache would set the |
| 161 // |addresses_| and in case of an unsuccessful synchronous completion, we | 161 // |addresses_| and in case of an unsuccessful synchronous completion, we |
| 162 // do not touch |addresses_|. | 162 // do not touch |addresses_|. |
| 163 void OnSyncComplete(int result) { | 163 void OnSyncComplete(int result) { |
| 164 callback_ = NULL; | 164 callback_.Reset(); |
| 165 resolver_->OnFinish(this, result); | 165 resolver_->OnFinish(this, result); |
| 166 } | 166 } |
| 167 | 167 |
| 168 // Called when a request completes asynchronously. | 168 // Called when a request completes asynchronously. |
| 169 void OnAsyncComplete(int result, const AddressList& addresses) { | 169 void OnAsyncComplete(int result, const AddressList& addresses) { |
| 170 if (result == OK) | 170 if (result == OK) |
| 171 *addresses_ = CreateAddressListUsingPort(addresses, info_.port()); | 171 *addresses_ = CreateAddressListUsingPort(addresses, info_.port()); |
| 172 DCHECK(callback_); | 172 DCHECK_EQ(false, callback_.is_null()); |
| 173 OldCompletionCallback* callback = callback_; | 173 CompletionCallback callback = callback_; |
| 174 callback_ = NULL; | 174 callback_.Reset(); |
| 175 resolver_->OnFinish(this, result); | 175 resolver_->OnFinish(this, result); |
| 176 callback->Run(result); | 176 callback.Run(result); |
| 177 } | 177 } |
| 178 | 178 |
| 179 // Returns true if request has a validly formed hostname. | 179 // Returns true if request has a validly formed hostname. |
| 180 bool IsValid() const { | 180 bool IsValid() const { |
| 181 return !info_.hostname().empty() && !key_.first.empty(); | 181 return !info_.hostname().empty() && !key_.first.empty(); |
| 182 } | 182 } |
| 183 | 183 |
| 184 private: | 184 private: |
| 185 AsyncHostResolver* resolver_; | 185 AsyncHostResolver* resolver_; |
| 186 BoundNetLog source_net_log_; | 186 BoundNetLog source_net_log_; |
| 187 BoundNetLog request_net_log_; | 187 BoundNetLog request_net_log_; |
| 188 const HostResolver::RequestInfo info_; | 188 const HostResolver::RequestInfo info_; |
| 189 Key key_; | 189 Key key_; |
| 190 OldCompletionCallback* callback_; | 190 CompletionCallback callback_; |
| 191 AddressList* addresses_; | 191 AddressList* addresses_; |
| 192 int result_; | 192 int result_; |
| 193 }; | 193 }; |
| 194 | 194 |
| 195 //----------------------------------------------------------------------------- | 195 //----------------------------------------------------------------------------- |
| 196 AsyncHostResolver::AsyncHostResolver(const IPEndPoint& dns_server, | 196 AsyncHostResolver::AsyncHostResolver(const IPEndPoint& dns_server, |
| 197 size_t max_transactions, | 197 size_t max_transactions, |
| 198 size_t max_pending_requests, | 198 size_t max_pending_requests, |
| 199 const RandIntCallback& rand_int_cb, | 199 const RandIntCallback& rand_int_cb, |
| 200 HostCache* cache, | 200 HostCache* cache, |
| (...skipping 17 matching lines...) Expand all Loading... |
| 218 // Destroy transactions. | 218 // Destroy transactions. |
| 219 STLDeleteElements(&transactions_); | 219 STLDeleteElements(&transactions_); |
| 220 | 220 |
| 221 // Destroy pending requests. | 221 // Destroy pending requests. |
| 222 for (size_t i = 0; i < arraysize(pending_requests_); ++i) | 222 for (size_t i = 0; i < arraysize(pending_requests_); ++i) |
| 223 STLDeleteElements(&pending_requests_[i]); | 223 STLDeleteElements(&pending_requests_[i]); |
| 224 } | 224 } |
| 225 | 225 |
| 226 int AsyncHostResolver::Resolve(const RequestInfo& info, | 226 int AsyncHostResolver::Resolve(const RequestInfo& info, |
| 227 AddressList* addresses, | 227 AddressList* addresses, |
| 228 OldCompletionCallback* callback, | 228 const CompletionCallback& callback, |
| 229 RequestHandle* out_req, | 229 RequestHandle* out_req, |
| 230 const BoundNetLog& source_net_log) { | 230 const BoundNetLog& source_net_log) { |
| 231 DCHECK(addresses); | 231 DCHECK(addresses); |
| 232 DCHECK(callback); | 232 DCHECK_EQ(false, callback.is_null()); |
| 233 scoped_ptr<Request> request( | 233 scoped_ptr<Request> request( |
| 234 CreateNewRequest(info, callback, addresses, source_net_log)); | 234 CreateNewRequest(info, callback, addresses, source_net_log)); |
| 235 | 235 |
| 236 int rv = ERR_UNEXPECTED; | 236 int rv = ERR_UNEXPECTED; |
| 237 if (!request->IsValid()) | 237 if (!request->IsValid()) |
| 238 rv = ERR_NAME_NOT_RESOLVED; | 238 rv = ERR_NAME_NOT_RESOLVED; |
| 239 else if (request->ResolveAsIp() || request->ServeFromCache()) | 239 else if (request->ResolveAsIp() || request->ServeFromCache()) |
| 240 rv = request->result(); | 240 rv = request->result(); |
| 241 else if (AttachToRequestList(request.get())) | 241 else if (AttachToRequestList(request.get())) |
| 242 rv = ERR_IO_PENDING; | 242 rv = ERR_IO_PENDING; |
| 243 else if (transactions_.size() < max_transactions_) | 243 else if (transactions_.size() < max_transactions_) |
| 244 rv = StartNewTransactionFor(request.get()); | 244 rv = StartNewTransactionFor(request.get()); |
| 245 else | 245 else |
| 246 rv = Enqueue(request.get()); | 246 rv = Enqueue(request.get()); |
| 247 | 247 |
| 248 if (rv != ERR_IO_PENDING) { | 248 if (rv != ERR_IO_PENDING) { |
| 249 request->OnSyncComplete(rv); | 249 request->OnSyncComplete(rv); |
| 250 } else { | 250 } else { |
| 251 Request* req = request.release(); | 251 Request* req = request.release(); |
| 252 if (out_req) | 252 if (out_req) |
| 253 *out_req = reinterpret_cast<RequestHandle>(req); | 253 *out_req = reinterpret_cast<RequestHandle>(req); |
| 254 } | 254 } |
| 255 return rv; | 255 return rv; |
| 256 } | 256 } |
| 257 | 257 |
| 258 int AsyncHostResolver::ResolveFromCache(const RequestInfo& info, | 258 int AsyncHostResolver::ResolveFromCache(const RequestInfo& info, |
| 259 AddressList* addresses, | 259 AddressList* addresses, |
| 260 const BoundNetLog& source_net_log) { | 260 const BoundNetLog& source_net_log) { |
| 261 scoped_ptr<Request> request( | 261 scoped_ptr<Request> request( |
| 262 CreateNewRequest(info, NULL, addresses, source_net_log)); | 262 CreateNewRequest(info, CompletionCallback(), addresses, source_net_log)); |
| 263 int rv = ERR_UNEXPECTED; | 263 int rv = ERR_UNEXPECTED; |
| 264 if (!request->IsValid()) | 264 if (!request->IsValid()) |
| 265 rv = ERR_NAME_NOT_RESOLVED; | 265 rv = ERR_NAME_NOT_RESOLVED; |
| 266 else if (request->ResolveAsIp() || request->ServeFromCache()) | 266 else if (request->ResolveAsIp() || request->ServeFromCache()) |
| 267 rv = request->result(); | 267 rv = request->result(); |
| 268 else | 268 else |
| 269 rv = ERR_DNS_CACHE_MISS; | 269 rv = ERR_DNS_CACHE_MISS; |
| 270 request->OnSyncComplete(rv); | 270 request->OnSyncComplete(rv); |
| 271 return rv; | 271 return rv; |
| 272 } | 272 } |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 375 requestlist_map_.erase(transaction->key()); | 375 requestlist_map_.erase(transaction->key()); |
| 376 | 376 |
| 377 // Cleanup transaction and start a new one if there are pending requests. | 377 // Cleanup transaction and start a new one if there are pending requests. |
| 378 delete transaction; | 378 delete transaction; |
| 379 transactions_.remove(transaction); | 379 transactions_.remove(transaction); |
| 380 ProcessPending(); | 380 ProcessPending(); |
| 381 } | 381 } |
| 382 | 382 |
| 383 AsyncHostResolver::Request* AsyncHostResolver::CreateNewRequest( | 383 AsyncHostResolver::Request* AsyncHostResolver::CreateNewRequest( |
| 384 const RequestInfo& info, | 384 const RequestInfo& info, |
| 385 OldCompletionCallback* callback, | 385 const CompletionCallback& callback, |
| 386 AddressList* addresses, | 386 AddressList* addresses, |
| 387 const BoundNetLog& source_net_log) { | 387 const BoundNetLog& source_net_log) { |
| 388 BoundNetLog request_net_log = BoundNetLog::Make(net_log_, | 388 BoundNetLog request_net_log = BoundNetLog::Make(net_log_, |
| 389 NetLog::SOURCE_ASYNC_HOST_RESOLVER_REQUEST); | 389 NetLog::SOURCE_ASYNC_HOST_RESOLVER_REQUEST); |
| 390 return new Request( | 390 return new Request( |
| 391 this, source_net_log, request_net_log, info, callback, addresses); | 391 this, source_net_log, request_net_log, info, callback, addresses); |
| 392 } | 392 } |
| 393 | 393 |
| 394 bool AsyncHostResolver::AttachToRequestList(Request* request) { | 394 bool AsyncHostResolver::AttachToRequestList(Request* request) { |
| 395 KeyRequestListMap::iterator it = requestlist_map_.find(request->key()); | 395 KeyRequestListMap::iterator it = requestlist_map_.find(request->key()); |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 487 it = requests.erase(it); | 487 it = requests.erase(it); |
| 488 } else { | 488 } else { |
| 489 ++it; | 489 ++it; |
| 490 } | 490 } |
| 491 } | 491 } |
| 492 } | 492 } |
| 493 StartNewTransactionFor(request); | 493 StartNewTransactionFor(request); |
| 494 } | 494 } |
| 495 | 495 |
| 496 } // namespace net | 496 } // namespace net |
| OLD | NEW |