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 |