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/quic/quic_stream_factory.h" | 5 #include "net/quic/quic_stream_factory.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 | 8 |
9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
10 #include "base/message_loop/message_loop_proxy.h" | 10 #include "base/message_loop/message_loop_proxy.h" |
(...skipping 20 matching lines...) Expand all Loading... |
31 #include "net/quic/quic_default_packet_writer.h" | 31 #include "net/quic/quic_default_packet_writer.h" |
32 #include "net/quic/quic_http_stream.h" | 32 #include "net/quic/quic_http_stream.h" |
33 #include "net/quic/quic_protocol.h" | 33 #include "net/quic/quic_protocol.h" |
34 #include "net/socket/client_socket_factory.h" | 34 #include "net/socket/client_socket_factory.h" |
35 | 35 |
36 using std::string; | 36 using std::string; |
37 using std::vector; | 37 using std::vector; |
38 | 38 |
39 namespace net { | 39 namespace net { |
40 | 40 |
| 41 QuicStreamFactory::SessionKey::SessionKey() {} |
| 42 |
| 43 QuicStreamFactory::SessionKey::SessionKey( |
| 44 HostPortProxyPair host_port_proxy_pair, |
| 45 bool is_https) |
| 46 : host_port_proxy_pair(host_port_proxy_pair), |
| 47 is_https(is_https) {} |
| 48 |
| 49 QuicStreamFactory::SessionKey::~SessionKey() {} |
| 50 |
| 51 bool QuicStreamFactory::SessionKey::operator<( |
| 52 const QuicStreamFactory::SessionKey &other) const { |
| 53 if (!host_port_proxy_pair.first.Equals(other.host_port_proxy_pair.first)) { |
| 54 return host_port_proxy_pair.first < other.host_port_proxy_pair.first; |
| 55 } |
| 56 if (!(host_port_proxy_pair.second == other.host_port_proxy_pair.second)) { |
| 57 return host_port_proxy_pair.second < other.host_port_proxy_pair.second; |
| 58 } |
| 59 return is_https < other.is_https; |
| 60 } |
| 61 |
| 62 bool QuicStreamFactory::SessionKey::operator==( |
| 63 const QuicStreamFactory::SessionKey& other) const { |
| 64 return is_https == other.is_https && |
| 65 host_port_proxy_pair.second == other.host_port_proxy_pair.second && |
| 66 host_port_proxy_pair.first.Equals(other.host_port_proxy_pair.first); |
| 67 }; |
| 68 |
| 69 QuicStreamFactory::IpAliasKey::IpAliasKey() {} |
| 70 |
| 71 QuicStreamFactory::IpAliasKey::IpAliasKey(IPEndPoint ip_endpoint, |
| 72 bool is_https) |
| 73 : ip_endpoint(ip_endpoint), |
| 74 is_https(is_https) {} |
| 75 |
| 76 QuicStreamFactory::IpAliasKey::~IpAliasKey() {} |
| 77 |
| 78 bool QuicStreamFactory::IpAliasKey::operator<( |
| 79 const QuicStreamFactory::IpAliasKey& other) const { |
| 80 if (!(ip_endpoint == other.ip_endpoint)) { |
| 81 return ip_endpoint < other.ip_endpoint; |
| 82 } |
| 83 return is_https < other.is_https; |
| 84 } |
| 85 |
| 86 bool QuicStreamFactory::IpAliasKey::operator==( |
| 87 const QuicStreamFactory::IpAliasKey& other) const { |
| 88 return is_https == other.is_https && |
| 89 ip_endpoint == other.ip_endpoint; |
| 90 }; |
| 91 |
41 // Responsible for creating a new QUIC session to the specified server, and | 92 // Responsible for creating a new QUIC session to the specified server, and |
42 // for notifying any associated requests when complete. | 93 // for notifying any associated requests when complete. |
43 class QuicStreamFactory::Job { | 94 class QuicStreamFactory::Job { |
44 public: | 95 public: |
45 Job(QuicStreamFactory* factory, | 96 Job(QuicStreamFactory* factory, |
46 HostResolver* host_resolver, | 97 HostResolver* host_resolver, |
47 const HostPortProxyPair& host_port_proxy_pair, | 98 const HostPortProxyPair& host_port_proxy_pair, |
48 bool is_https, | 99 bool is_https, |
49 base::StringPiece method, | 100 base::StringPiece method, |
50 CertVerifier* cert_verifier, | 101 CertVerifier* cert_verifier, |
51 const BoundNetLog& net_log); | 102 const BoundNetLog& net_log); |
52 | 103 |
53 ~Job(); | 104 ~Job(); |
54 | 105 |
55 int Run(const CompletionCallback& callback); | 106 int Run(const CompletionCallback& callback); |
56 | 107 |
57 int DoLoop(int rv); | 108 int DoLoop(int rv); |
58 int DoResolveHost(); | 109 int DoResolveHost(); |
59 int DoResolveHostComplete(int rv); | 110 int DoResolveHostComplete(int rv); |
60 int DoConnect(); | 111 int DoConnect(); |
61 int DoConnectComplete(int rv); | 112 int DoConnectComplete(int rv); |
62 | 113 |
63 void OnIOComplete(int rv); | 114 void OnIOComplete(int rv); |
64 | 115 |
65 CompletionCallback callback() { | 116 CompletionCallback callback() { |
66 return callback_; | 117 return callback_; |
67 } | 118 } |
68 | 119 |
69 const HostPortProxyPair& host_port_proxy_pair() const { | 120 const SessionKey session_key() const { |
70 return host_port_proxy_pair_; | 121 return session_key_; |
71 } | 122 } |
72 | 123 |
73 private: | 124 private: |
74 enum IoState { | 125 enum IoState { |
75 STATE_NONE, | 126 STATE_NONE, |
76 STATE_RESOLVE_HOST, | 127 STATE_RESOLVE_HOST, |
77 STATE_RESOLVE_HOST_COMPLETE, | 128 STATE_RESOLVE_HOST_COMPLETE, |
78 STATE_CONNECT, | 129 STATE_CONNECT, |
79 STATE_CONNECT_COMPLETE, | 130 STATE_CONNECT_COMPLETE, |
80 }; | 131 }; |
81 IoState io_state_; | 132 IoState io_state_; |
82 | 133 |
83 QuicStreamFactory* factory_; | 134 QuicStreamFactory* factory_; |
84 SingleRequestHostResolver host_resolver_; | 135 SingleRequestHostResolver host_resolver_; |
85 const HostPortProxyPair host_port_proxy_pair_; | |
86 bool is_https_; | 136 bool is_https_; |
| 137 SessionKey session_key_; |
87 bool is_post_; | 138 bool is_post_; |
88 CertVerifier* cert_verifier_; | 139 CertVerifier* cert_verifier_; |
89 const BoundNetLog net_log_; | 140 const BoundNetLog net_log_; |
90 QuicClientSession* session_; | 141 QuicClientSession* session_; |
91 CompletionCallback callback_; | 142 CompletionCallback callback_; |
92 AddressList address_list_; | 143 AddressList address_list_; |
93 DISALLOW_COPY_AND_ASSIGN(Job); | 144 DISALLOW_COPY_AND_ASSIGN(Job); |
94 }; | 145 }; |
95 | 146 |
96 QuicStreamFactory::Job::Job(QuicStreamFactory* factory, | 147 QuicStreamFactory::Job::Job(QuicStreamFactory* factory, |
97 HostResolver* host_resolver, | 148 HostResolver* host_resolver, |
98 const HostPortProxyPair& host_port_proxy_pair, | 149 const HostPortProxyPair& host_port_proxy_pair, |
99 bool is_https, | 150 bool is_https, |
100 base::StringPiece method, | 151 base::StringPiece method, |
101 CertVerifier* cert_verifier, | 152 CertVerifier* cert_verifier, |
102 const BoundNetLog& net_log) | 153 const BoundNetLog& net_log) |
103 : factory_(factory), | 154 : factory_(factory), |
104 host_resolver_(host_resolver), | 155 host_resolver_(host_resolver), |
105 host_port_proxy_pair_(host_port_proxy_pair), | |
106 is_https_(is_https), | 156 is_https_(is_https), |
| 157 session_key_(host_port_proxy_pair, is_https), |
107 is_post_(method == "POST"), | 158 is_post_(method == "POST"), |
108 cert_verifier_(cert_verifier), | 159 cert_verifier_(cert_verifier), |
109 net_log_(net_log), | 160 net_log_(net_log), |
110 session_(NULL) {} | 161 session_(NULL) {} |
111 | 162 |
112 QuicStreamFactory::Job::~Job() { | 163 QuicStreamFactory::Job::~Job() { |
113 } | 164 } |
114 | 165 |
115 int QuicStreamFactory::Job::Run(const CompletionCallback& callback) { | 166 int QuicStreamFactory::Job::Run(const CompletionCallback& callback) { |
116 io_state_ = STATE_RESOLVE_HOST; | 167 io_state_ = STATE_RESOLVE_HOST; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 rv = DoLoop(rv); | 203 rv = DoLoop(rv); |
153 | 204 |
154 if (rv != ERR_IO_PENDING && !callback_.is_null()) { | 205 if (rv != ERR_IO_PENDING && !callback_.is_null()) { |
155 callback_.Run(rv); | 206 callback_.Run(rv); |
156 } | 207 } |
157 } | 208 } |
158 | 209 |
159 int QuicStreamFactory::Job::DoResolveHost() { | 210 int QuicStreamFactory::Job::DoResolveHost() { |
160 io_state_ = STATE_RESOLVE_HOST_COMPLETE; | 211 io_state_ = STATE_RESOLVE_HOST_COMPLETE; |
161 return host_resolver_.Resolve( | 212 return host_resolver_.Resolve( |
162 HostResolver::RequestInfo(host_port_proxy_pair_.first), | 213 HostResolver::RequestInfo(session_key_.host_port_proxy_pair.first), |
163 DEFAULT_PRIORITY, | 214 DEFAULT_PRIORITY, |
164 &address_list_, | 215 &address_list_, |
165 base::Bind(&QuicStreamFactory::Job::OnIOComplete, base::Unretained(this)), | 216 base::Bind(&QuicStreamFactory::Job::OnIOComplete, base::Unretained(this)), |
166 net_log_); | 217 net_log_); |
167 } | 218 } |
168 | 219 |
169 int QuicStreamFactory::Job::DoResolveHostComplete(int rv) { | 220 int QuicStreamFactory::Job::DoResolveHostComplete(int rv) { |
170 if (rv != OK) | 221 if (rv != OK) |
171 return rv; | 222 return rv; |
172 | 223 |
173 DCHECK(!factory_->HasActiveSession(host_port_proxy_pair_)); | 224 DCHECK(!factory_->HasActiveSession(session_key_)); |
174 | 225 |
175 // Inform the factory of this resolution, which will set up | 226 // Inform the factory of this resolution, which will set up |
176 // a session alias, if possible. | 227 // a session alias, if possible. |
177 if (factory_->OnResolution(host_port_proxy_pair_, address_list_)) { | 228 if (factory_->OnResolution(session_key_, address_list_)) { |
178 return OK; | 229 return OK; |
179 } | 230 } |
180 | 231 |
181 io_state_ = STATE_CONNECT; | 232 io_state_ = STATE_CONNECT; |
182 return OK; | 233 return OK; |
183 } | 234 } |
184 | 235 |
185 QuicStreamRequest::QuicStreamRequest(QuicStreamFactory* factory) | 236 QuicStreamRequest::QuicStreamRequest(QuicStreamFactory* factory) |
186 : factory_(factory) {} | 237 : factory_(factory) {} |
187 | 238 |
188 QuicStreamRequest::~QuicStreamRequest() { | 239 QuicStreamRequest::~QuicStreamRequest() { |
189 if (factory_ && !callback_.is_null()) | 240 if (factory_ && !callback_.is_null()) |
190 factory_->CancelRequest(this); | 241 factory_->CancelRequest(this); |
191 } | 242 } |
192 | 243 |
193 int QuicStreamRequest::Request(const HostPortProxyPair& host_port_proxy_pair, | 244 int QuicStreamRequest::Request(const HostPortProxyPair& host_port_proxy_pair, |
194 bool is_https, | 245 bool is_https, |
195 base::StringPiece method, | 246 base::StringPiece method, |
196 CertVerifier* cert_verifier, | 247 CertVerifier* cert_verifier, |
197 const BoundNetLog& net_log, | 248 const BoundNetLog& net_log, |
198 const CompletionCallback& callback) { | 249 const CompletionCallback& callback) { |
199 DCHECK(!stream_); | 250 DCHECK(!stream_); |
200 DCHECK(callback_.is_null()); | 251 DCHECK(callback_.is_null()); |
201 DCHECK(factory_); | 252 DCHECK(factory_); |
202 int rv = factory_->Create( | 253 int rv = factory_->Create(host_port_proxy_pair, is_https, |
203 host_port_proxy_pair, is_https, method, cert_verifier, net_log, this); | 254 method, cert_verifier, net_log, this); |
204 if (rv == ERR_IO_PENDING) { | 255 if (rv == ERR_IO_PENDING) { |
205 host_port_proxy_pair_ = host_port_proxy_pair; | 256 host_port_proxy_pair_ = host_port_proxy_pair; |
206 is_https_ = is_https; | 257 is_https_ = is_https; |
207 cert_verifier_ = cert_verifier; | 258 cert_verifier_ = cert_verifier; |
208 net_log_ = net_log; | 259 net_log_ = net_log; |
209 callback_ = callback; | 260 callback_ = callback; |
210 } else { | 261 } else { |
211 factory_ = NULL; | 262 factory_ = NULL; |
212 } | 263 } |
213 if (rv == OK) | 264 if (rv == OK) |
(...skipping 12 matching lines...) Expand all Loading... |
226 } | 277 } |
227 | 278 |
228 scoped_ptr<QuicHttpStream> QuicStreamRequest::ReleaseStream() { | 279 scoped_ptr<QuicHttpStream> QuicStreamRequest::ReleaseStream() { |
229 DCHECK(stream_); | 280 DCHECK(stream_); |
230 return stream_.Pass(); | 281 return stream_.Pass(); |
231 } | 282 } |
232 | 283 |
233 int QuicStreamFactory::Job::DoConnect() { | 284 int QuicStreamFactory::Job::DoConnect() { |
234 io_state_ = STATE_CONNECT_COMPLETE; | 285 io_state_ = STATE_CONNECT_COMPLETE; |
235 | 286 |
236 int rv = factory_->CreateSession(host_port_proxy_pair_, is_https_, | 287 int rv = factory_->CreateSession(session_key_.host_port_proxy_pair, is_https_, |
237 cert_verifier_, address_list_, net_log_, &session_); | 288 cert_verifier_, address_list_, net_log_, &session_); |
238 if (rv != OK) { | 289 if (rv != OK) { |
239 DCHECK(rv != ERR_IO_PENDING); | 290 DCHECK(rv != ERR_IO_PENDING); |
240 DCHECK(!session_); | 291 DCHECK(!session_); |
241 return rv; | 292 return rv; |
242 } | 293 } |
243 | 294 |
244 session_->StartReading(); | 295 session_->StartReading(); |
245 if (!session_->connection()->connected()) { | 296 if (!session_->connection()->connected()) { |
246 return ERR_QUIC_PROTOCOL_ERROR; | 297 return ERR_QUIC_PROTOCOL_ERROR; |
247 } | 298 } |
248 rv = session_->CryptoConnect( | 299 rv = session_->CryptoConnect( |
249 factory_->require_confirmation() || is_https_, | 300 factory_->require_confirmation() || is_https_, |
250 base::Bind(&QuicStreamFactory::Job::OnIOComplete, | 301 base::Bind(&QuicStreamFactory::Job::OnIOComplete, |
251 base::Unretained(this))); | 302 base::Unretained(this))); |
252 return rv; | 303 return rv; |
253 } | 304 } |
254 | 305 |
255 int QuicStreamFactory::Job::DoConnectComplete(int rv) { | 306 int QuicStreamFactory::Job::DoConnectComplete(int rv) { |
256 if (rv != OK) | 307 if (rv != OK) |
257 return rv; | 308 return rv; |
258 | 309 |
259 DCHECK(!factory_->HasActiveSession(host_port_proxy_pair_)); | 310 DCHECK(!factory_->HasActiveSession(session_key_)); |
260 // There may well now be an active session for this IP. If so, use the | 311 // There may well now be an active session for this IP. If so, use the |
261 // existing session instead. | 312 // existing session instead. |
262 AddressList address(session_->connection()->peer_address()); | 313 AddressList address(session_->connection()->peer_address()); |
263 if (factory_->OnResolution(host_port_proxy_pair_, address)) { | 314 if (factory_->OnResolution(session_key_, address)) { |
| 315 |
264 session_->connection()->SendConnectionClose(QUIC_NO_ERROR); | 316 session_->connection()->SendConnectionClose(QUIC_NO_ERROR); |
265 session_ = NULL; | 317 session_ = NULL; |
266 return OK; | 318 return OK; |
267 } | 319 } |
268 | 320 |
269 factory_->ActivateSession(host_port_proxy_pair_, session_); | 321 factory_->ActivateSession(session_key_, session_); |
270 | 322 |
271 return OK; | 323 return OK; |
272 } | 324 } |
273 | 325 |
274 QuicStreamFactory::QuicStreamFactory( | 326 QuicStreamFactory::QuicStreamFactory( |
275 HostResolver* host_resolver, | 327 HostResolver* host_resolver, |
276 ClientSocketFactory* client_socket_factory, | 328 ClientSocketFactory* client_socket_factory, |
277 base::WeakPtr<HttpServerProperties> http_server_properties, | 329 base::WeakPtr<HttpServerProperties> http_server_properties, |
278 QuicCryptoClientStreamFactory* quic_crypto_client_stream_factory, | 330 QuicCryptoClientStreamFactory* quic_crypto_client_stream_factory, |
279 QuicRandom* random_generator, | 331 QuicRandom* random_generator, |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
312 STLDeleteValues(&active_jobs_); | 364 STLDeleteValues(&active_jobs_); |
313 STLDeleteValues(&all_crypto_configs_); | 365 STLDeleteValues(&all_crypto_configs_); |
314 } | 366 } |
315 | 367 |
316 int QuicStreamFactory::Create(const HostPortProxyPair& host_port_proxy_pair, | 368 int QuicStreamFactory::Create(const HostPortProxyPair& host_port_proxy_pair, |
317 bool is_https, | 369 bool is_https, |
318 base::StringPiece method, | 370 base::StringPiece method, |
319 CertVerifier* cert_verifier, | 371 CertVerifier* cert_verifier, |
320 const BoundNetLog& net_log, | 372 const BoundNetLog& net_log, |
321 QuicStreamRequest* request) { | 373 QuicStreamRequest* request) { |
322 if (HasActiveSession(host_port_proxy_pair)) { | 374 SessionKey key(host_port_proxy_pair, is_https); |
323 request->set_stream(CreateIfSessionExists(host_port_proxy_pair, net_log)); | 375 if (HasActiveSession(key)) { |
| 376 request->set_stream(CreateIfSessionExists(key, net_log)); |
324 return OK; | 377 return OK; |
325 } | 378 } |
326 | 379 |
327 if (HasActiveJob(host_port_proxy_pair)) { | 380 if (HasActiveJob(key)) { |
328 Job* job = active_jobs_[host_port_proxy_pair]; | 381 Job* job = active_jobs_[key]; |
329 active_requests_[request] = job; | 382 active_requests_[request] = job; |
330 job_requests_map_[job].insert(request); | 383 job_requests_map_[job].insert(request); |
331 return ERR_IO_PENDING; | 384 return ERR_IO_PENDING; |
332 } | 385 } |
333 | 386 |
334 // Create crypto config and start the process of loading QUIC server | 387 // Create crypto config and start the process of loading QUIC server |
335 // information from disk cache. | 388 // information from disk cache. |
336 QuicCryptoClientConfig* crypto_config = | 389 QuicCryptoClientConfig* crypto_config = |
337 GetOrCreateCryptoConfig(host_port_proxy_pair); | 390 GetOrCreateCryptoConfig(host_port_proxy_pair); |
338 DCHECK(crypto_config); | 391 DCHECK(crypto_config); |
339 | 392 |
340 scoped_ptr<Job> job(new Job(this, host_resolver_, host_port_proxy_pair, | 393 scoped_ptr<Job> job(new Job(this, host_resolver_, host_port_proxy_pair, |
341 is_https, method, cert_verifier, net_log)); | 394 is_https, method, cert_verifier, net_log)); |
342 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, | 395 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, |
343 base::Unretained(this), job.get())); | 396 base::Unretained(this), job.get())); |
344 | 397 |
345 if (rv == ERR_IO_PENDING) { | 398 if (rv == ERR_IO_PENDING) { |
346 active_requests_[request] = job.get(); | 399 active_requests_[request] = job.get(); |
347 job_requests_map_[job.get()].insert(request); | 400 job_requests_map_[job.get()].insert(request); |
348 active_jobs_[host_port_proxy_pair] = job.release(); | 401 active_jobs_[key] = job.release(); |
349 } | 402 } |
350 if (rv == OK) { | 403 if (rv == OK) { |
351 DCHECK(HasActiveSession(host_port_proxy_pair)); | 404 DCHECK(HasActiveSession(key)); |
352 request->set_stream(CreateIfSessionExists(host_port_proxy_pair, net_log)); | 405 request->set_stream(CreateIfSessionExists(key, net_log)); |
353 } | 406 } |
354 return rv; | 407 return rv; |
355 } | 408 } |
356 | 409 |
357 bool QuicStreamFactory::OnResolution( | 410 bool QuicStreamFactory::OnResolution( |
358 const HostPortProxyPair& host_port_proxy_pair, | 411 const SessionKey& session_key, |
359 const AddressList& address_list) { | 412 const AddressList& address_list) { |
360 DCHECK(!HasActiveSession(host_port_proxy_pair)); | 413 DCHECK(!HasActiveSession(session_key)); |
361 for (size_t i = 0; i < address_list.size(); ++i) { | 414 for (size_t i = 0; i < address_list.size(); ++i) { |
362 const IPEndPoint& address = address_list[i]; | 415 const IPEndPoint& address = address_list[i]; |
363 if (!ContainsKey(ip_aliases_, address)) | 416 const IpAliasKey ip_alias_key(address, session_key.is_https); |
| 417 if (!ContainsKey(ip_aliases_, ip_alias_key)) |
364 continue; | 418 continue; |
365 | 419 |
366 const SessionSet& sessions = ip_aliases_[address]; | 420 const SessionSet& sessions = ip_aliases_[ip_alias_key]; |
367 for (SessionSet::const_iterator i = sessions.begin(); | 421 for (SessionSet::const_iterator i = sessions.begin(); |
368 i != sessions.end(); ++i) { | 422 i != sessions.end(); ++i) { |
369 QuicClientSession* session = *i; | 423 QuicClientSession* session = *i; |
370 if (!session->CanPool(host_port_proxy_pair.first.host())) | 424 if (!session->CanPool(session_key.host_port_proxy_pair.first.host())) |
371 continue; | 425 continue; |
372 active_sessions_[host_port_proxy_pair] = session; | 426 active_sessions_[session_key] = session; |
373 session_aliases_[session].insert(host_port_proxy_pair); | 427 session_aliases_[session].insert(session_key); |
374 return true; | 428 return true; |
375 } | 429 } |
376 } | 430 } |
377 return false; | 431 return false; |
378 } | 432 } |
379 | 433 |
380 void QuicStreamFactory::OnJobComplete(Job* job, int rv) { | 434 void QuicStreamFactory::OnJobComplete(Job* job, int rv) { |
381 if (rv == OK) { | 435 if (rv == OK) { |
382 require_confirmation_ = false; | 436 require_confirmation_ = false; |
383 | 437 |
384 // Create all the streams, but do not notify them yet. | 438 // Create all the streams, but do not notify them yet. |
385 for (RequestSet::iterator it = job_requests_map_[job].begin(); | 439 for (RequestSet::iterator it = job_requests_map_[job].begin(); |
386 it != job_requests_map_[job].end() ; ++it) { | 440 it != job_requests_map_[job].end() ; ++it) { |
387 DCHECK(HasActiveSession(job->host_port_proxy_pair())); | 441 DCHECK(HasActiveSession(job->session_key())); |
388 (*it)->set_stream(CreateIfSessionExists(job->host_port_proxy_pair(), | 442 (*it)->set_stream(CreateIfSessionExists(job->session_key(), |
389 (*it)->net_log())); | 443 (*it)->net_log())); |
390 } | 444 } |
391 } | 445 } |
392 while (!job_requests_map_[job].empty()) { | 446 while (!job_requests_map_[job].empty()) { |
393 RequestSet::iterator it = job_requests_map_[job].begin(); | 447 RequestSet::iterator it = job_requests_map_[job].begin(); |
394 QuicStreamRequest* request = *it; | 448 QuicStreamRequest* request = *it; |
395 job_requests_map_[job].erase(it); | 449 job_requests_map_[job].erase(it); |
396 active_requests_.erase(request); | 450 active_requests_.erase(request); |
397 // Even though we're invoking callbacks here, we don't need to worry | 451 // Even though we're invoking callbacks here, we don't need to worry |
398 // about |this| being deleted, because the factory is owned by the | 452 // about |this| being deleted, because the factory is owned by the |
399 // profile which can not be deleted via callbacks. | 453 // profile which can not be deleted via callbacks. |
400 request->OnRequestComplete(rv); | 454 request->OnRequestComplete(rv); |
401 } | 455 } |
402 active_jobs_.erase(job->host_port_proxy_pair()); | 456 active_jobs_.erase(job->session_key()); |
403 job_requests_map_.erase(job); | 457 job_requests_map_.erase(job); |
404 delete job; | 458 delete job; |
405 return; | 459 return; |
406 } | 460 } |
407 | 461 |
408 // Returns a newly created QuicHttpStream owned by the caller, if a | 462 // Returns a newly created QuicHttpStream owned by the caller, if a |
409 // matching session already exists. Returns NULL otherwise. | 463 // matching session already exists. Returns NULL otherwise. |
410 scoped_ptr<QuicHttpStream> QuicStreamFactory::CreateIfSessionExists( | 464 scoped_ptr<QuicHttpStream> QuicStreamFactory::CreateIfSessionExists( |
411 const HostPortProxyPair& host_port_proxy_pair, | 465 const SessionKey& session_key, |
412 const BoundNetLog& net_log) { | 466 const BoundNetLog& net_log) { |
413 if (!HasActiveSession(host_port_proxy_pair)) { | 467 if (!HasActiveSession(session_key)) { |
414 DVLOG(1) << "No active session"; | 468 DVLOG(1) << "No active session"; |
415 return scoped_ptr<QuicHttpStream>(); | 469 return scoped_ptr<QuicHttpStream>(); |
416 } | 470 } |
417 | 471 |
418 QuicClientSession* session = active_sessions_[host_port_proxy_pair]; | 472 QuicClientSession* session = active_sessions_[session_key]; |
419 DCHECK(session); | 473 DCHECK(session); |
420 return scoped_ptr<QuicHttpStream>( | 474 return scoped_ptr<QuicHttpStream>( |
421 new QuicHttpStream(session->GetWeakPtr())); | 475 new QuicHttpStream(session->GetWeakPtr())); |
422 } | 476 } |
423 | 477 |
424 void QuicStreamFactory::OnIdleSession(QuicClientSession* session) { | 478 void QuicStreamFactory::OnIdleSession(QuicClientSession* session) { |
425 } | 479 } |
426 | 480 |
427 void QuicStreamFactory::OnSessionGoingAway(QuicClientSession* session) { | 481 void QuicStreamFactory::OnSessionGoingAway(QuicClientSession* session) { |
428 const AliasSet& aliases = session_aliases_[session]; | 482 const AliasSet& aliases = session_aliases_[session]; |
429 for (AliasSet::const_iterator it = aliases.begin(); it != aliases.end(); | 483 for (AliasSet::const_iterator it = aliases.begin(); it != aliases.end(); |
430 ++it) { | 484 ++it) { |
431 DCHECK(active_sessions_.count(*it)); | 485 DCHECK(active_sessions_.count(*it)); |
432 DCHECK_EQ(session, active_sessions_[*it]); | 486 DCHECK_EQ(session, active_sessions_[*it]); |
433 // Track sessions which have recently gone away so that we can disable | 487 // Track sessions which have recently gone away so that we can disable |
434 // port suggestions. | 488 // port suggestions. |
435 if (session->goaway_received()) { | 489 if (session->goaway_received()) { |
436 gone_away_aliases_.insert(*it); | 490 gone_away_aliases_.insert(*it); |
437 } | 491 } |
438 | 492 |
439 active_sessions_.erase(*it); | 493 active_sessions_.erase(*it); |
440 if (!http_server_properties_) | 494 if (!http_server_properties_) |
441 continue; | 495 continue; |
442 | 496 |
443 if (!session->IsCryptoHandshakeConfirmed()) { | 497 if (!session->IsCryptoHandshakeConfirmed()) { |
444 // TODO(rch): In the special case where the session has received no | 498 // TODO(rch): In the special case where the session has received no |
445 // packets from the peer, we should consider blacklisting this | 499 // packets from the peer, we should consider blacklisting this |
446 // differently so that we still race TCP but we don't consider the | 500 // differently so that we still race TCP but we don't consider the |
447 // session connected until the handshake has been confirmed. | 501 // session connected until the handshake has been confirmed. |
448 http_server_properties_->SetBrokenAlternateProtocol(it->first); | 502 http_server_properties_->SetBrokenAlternateProtocol( |
| 503 it->host_port_proxy_pair.first); |
449 } else { | 504 } else { |
450 QuicConnectionStats stats = session->connection()->GetStats(); | 505 QuicConnectionStats stats = session->connection()->GetStats(); |
451 HttpServerProperties::NetworkStats network_stats; | 506 HttpServerProperties::NetworkStats network_stats; |
452 network_stats.rtt = base::TimeDelta::FromMicroseconds(stats.rtt); | 507 network_stats.rtt = base::TimeDelta::FromMicroseconds(stats.rtt); |
453 network_stats.bandwidth_estimate = stats.estimated_bandwidth; | 508 network_stats.bandwidth_estimate = stats.estimated_bandwidth; |
454 http_server_properties_->SetServerNetworkStats( | 509 http_server_properties_->SetServerNetworkStats( |
455 it->first, network_stats); | 510 it->host_port_proxy_pair.first, network_stats); |
456 } | 511 } |
457 } | 512 } |
458 IPEndPoint peer_address = session->connection()->peer_address(); | 513 if (!aliases.empty()) { |
459 ip_aliases_[peer_address].erase(session); | 514 const IpAliasKey ip_alias_key(session->connection()->peer_address(), |
460 if (ip_aliases_[peer_address].empty()) { | 515 aliases.begin()->is_https); |
461 ip_aliases_.erase(peer_address); | 516 ip_aliases_[ip_alias_key].erase(session); |
| 517 if (ip_aliases_[ip_alias_key].empty()) { |
| 518 ip_aliases_.erase(ip_alias_key); |
| 519 } |
462 } | 520 } |
463 session_aliases_.erase(session); | 521 session_aliases_.erase(session); |
464 } | 522 } |
465 | 523 |
466 void QuicStreamFactory::OnSessionClosed(QuicClientSession* session) { | 524 void QuicStreamFactory::OnSessionClosed(QuicClientSession* session) { |
467 DCHECK_EQ(0u, session->GetNumOpenStreams()); | 525 DCHECK_EQ(0u, session->GetNumOpenStreams()); |
468 OnSessionGoingAway(session); | 526 OnSessionGoingAway(session); |
469 all_sessions_.erase(session); | 527 all_sessions_.erase(session); |
470 delete session; | 528 delete session; |
471 } | 529 } |
(...skipping 17 matching lines...) Expand all Loading... |
489 DCHECK_NE(initial_size, all_sessions_.size()); | 547 DCHECK_NE(initial_size, all_sessions_.size()); |
490 } | 548 } |
491 DCHECK(all_sessions_.empty()); | 549 DCHECK(all_sessions_.empty()); |
492 } | 550 } |
493 | 551 |
494 base::Value* QuicStreamFactory::QuicStreamFactoryInfoToValue() const { | 552 base::Value* QuicStreamFactory::QuicStreamFactoryInfoToValue() const { |
495 base::ListValue* list = new base::ListValue(); | 553 base::ListValue* list = new base::ListValue(); |
496 | 554 |
497 for (SessionMap::const_iterator it = active_sessions_.begin(); | 555 for (SessionMap::const_iterator it = active_sessions_.begin(); |
498 it != active_sessions_.end(); ++it) { | 556 it != active_sessions_.end(); ++it) { |
499 const HostPortProxyPair& pair = it->first; | 557 const SessionKey& session_key = it->first; |
500 QuicClientSession* session = it->second; | 558 QuicClientSession* session = it->second; |
501 const AliasSet& aliases = session_aliases_.find(session)->second; | 559 const AliasSet& aliases = session_aliases_.find(session)->second; |
502 if (pair.first.Equals(aliases.begin()->first) && | 560 // Only add a session to the list once. |
503 pair.second == aliases.begin()->second) { | 561 if (session_key == *aliases.begin()) { |
504 list->Append(session->GetInfoAsValue(aliases)); | 562 std::set<HostPortProxyPair> hosts; |
| 563 for (AliasSet::const_iterator alias_it = aliases.begin(); |
| 564 alias_it != aliases.end(); ++alias_it) { |
| 565 hosts.insert(alias_it->host_port_proxy_pair); |
| 566 } |
| 567 list->Append(session->GetInfoAsValue(hosts)); |
505 } | 568 } |
506 } | 569 } |
507 return list; | 570 return list; |
508 } | 571 } |
509 | 572 |
510 void QuicStreamFactory::OnIPAddressChanged() { | 573 void QuicStreamFactory::OnIPAddressChanged() { |
511 CloseAllSessions(ERR_NETWORK_CHANGED); | 574 CloseAllSessions(ERR_NETWORK_CHANGED); |
512 require_confirmation_ = true; | 575 require_confirmation_ = true; |
513 } | 576 } |
514 | 577 |
515 void QuicStreamFactory::OnCertAdded(const X509Certificate* cert) { | 578 void QuicStreamFactory::OnCertAdded(const X509Certificate* cert) { |
516 CloseAllSessions(ERR_CERT_DATABASE_CHANGED); | 579 CloseAllSessions(ERR_CERT_DATABASE_CHANGED); |
517 } | 580 } |
518 | 581 |
519 void QuicStreamFactory::OnCACertChanged(const X509Certificate* cert) { | 582 void QuicStreamFactory::OnCACertChanged(const X509Certificate* cert) { |
520 // We should flush the sessions if we removed trust from a | 583 // We should flush the sessions if we removed trust from a |
521 // cert, because a previously trusted server may have become | 584 // cert, because a previously trusted server may have become |
522 // untrusted. | 585 // untrusted. |
523 // | 586 // |
524 // We should not flush the sessions if we added trust to a cert. | 587 // We should not flush the sessions if we added trust to a cert. |
525 // | 588 // |
526 // Since the OnCACertChanged method doesn't tell us what | 589 // Since the OnCACertChanged method doesn't tell us what |
527 // kind of change it is, we have to flush the socket | 590 // kind of change it is, we have to flush the socket |
528 // pools to be safe. | 591 // pools to be safe. |
529 CloseAllSessions(ERR_CERT_DATABASE_CHANGED); | 592 CloseAllSessions(ERR_CERT_DATABASE_CHANGED); |
530 } | 593 } |
531 | 594 |
532 bool QuicStreamFactory::HasActiveSession( | 595 bool QuicStreamFactory::HasActiveSession(const SessionKey& session_key) const { |
533 const HostPortProxyPair& host_port_proxy_pair) { | 596 return ContainsKey(active_sessions_, session_key); |
534 return ContainsKey(active_sessions_, host_port_proxy_pair); | |
535 } | 597 } |
536 | 598 |
537 int QuicStreamFactory::CreateSession( | 599 int QuicStreamFactory::CreateSession( |
538 const HostPortProxyPair& host_port_proxy_pair, | 600 const HostPortProxyPair& host_port_proxy_pair, |
539 bool is_https, | 601 bool is_https, |
540 CertVerifier* cert_verifier, | 602 CertVerifier* cert_verifier, |
541 const AddressList& address_list, | 603 const AddressList& address_list, |
542 const BoundNetLog& net_log, | 604 const BoundNetLog& net_log, |
543 QuicClientSession** session) { | 605 QuicClientSession** session) { |
544 bool enable_port_selection = enable_port_selection_; | 606 bool enable_port_selection = enable_port_selection_; |
| 607 SessionKey session_key(host_port_proxy_pair, is_https); |
545 if (enable_port_selection && | 608 if (enable_port_selection && |
546 ContainsKey(gone_away_aliases_, host_port_proxy_pair)) { | 609 ContainsKey(gone_away_aliases_, session_key)) { |
547 // Disable port selection when the server is going away. | 610 // Disable port selection when the server is going away. |
548 // There is no point in trying to return to the same server, if | 611 // There is no point in trying to return to the same server, if |
549 // that server is no longer handling requests. | 612 // that server is no longer handling requests. |
550 enable_port_selection = false; | 613 enable_port_selection = false; |
551 gone_away_aliases_.erase(host_port_proxy_pair); | 614 gone_away_aliases_.erase(session_key); |
552 } | 615 } |
553 | 616 |
554 QuicConnectionId connection_id = random_generator_->RandUint64(); | 617 QuicConnectionId connection_id = random_generator_->RandUint64(); |
555 IPEndPoint addr = *address_list.begin(); | 618 IPEndPoint addr = *address_list.begin(); |
556 scoped_refptr<PortSuggester> port_suggester = | 619 scoped_refptr<PortSuggester> port_suggester = |
557 new PortSuggester(host_port_proxy_pair.first, port_seed_); | 620 new PortSuggester(host_port_proxy_pair.first, port_seed_); |
558 DatagramSocket::BindType bind_type = enable_port_selection ? | 621 DatagramSocket::BindType bind_type = enable_port_selection ? |
559 DatagramSocket::RANDOM_BIND : // Use our callback. | 622 DatagramSocket::RANDOM_BIND : // Use our callback. |
560 DatagramSocket::DEFAULT_BIND; // Use OS to randomize. | 623 DatagramSocket::DEFAULT_BIND; // Use OS to randomize. |
561 scoped_ptr<DatagramClientSocket> socket( | 624 scoped_ptr<DatagramClientSocket> socket( |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
621 quic_crypto_client_stream_factory_, host_port_proxy_pair.first.host(), | 684 quic_crypto_client_stream_factory_, host_port_proxy_pair.first.host(), |
622 config, crypto_config, net_log.net_log()); | 685 config, crypto_config, net_log.net_log()); |
623 all_sessions_.insert(*session); // owning pointer | 686 all_sessions_.insert(*session); // owning pointer |
624 if (is_https) { | 687 if (is_https) { |
625 crypto_config->SetProofVerifier( | 688 crypto_config->SetProofVerifier( |
626 new ProofVerifierChromium(cert_verifier, net_log)); | 689 new ProofVerifierChromium(cert_verifier, net_log)); |
627 } | 690 } |
628 return OK; | 691 return OK; |
629 } | 692 } |
630 | 693 |
631 bool QuicStreamFactory::HasActiveJob( | 694 bool QuicStreamFactory::HasActiveJob(const SessionKey& key) const { |
632 const HostPortProxyPair& host_port_proxy_pair) { | 695 return ContainsKey(active_jobs_, key); |
633 return ContainsKey(active_jobs_, host_port_proxy_pair); | |
634 } | 696 } |
635 | 697 |
636 void QuicStreamFactory::ActivateSession( | 698 void QuicStreamFactory::ActivateSession( |
637 const HostPortProxyPair& host_port_proxy_pair, | 699 const SessionKey& session_key, |
638 QuicClientSession* session) { | 700 QuicClientSession* session) { |
639 DCHECK(!HasActiveSession(host_port_proxy_pair)); | 701 DCHECK(!HasActiveSession(session_key)); |
640 active_sessions_[host_port_proxy_pair] = session; | 702 active_sessions_[session_key] = session; |
641 session_aliases_[session].insert(host_port_proxy_pair); | 703 session_aliases_[session].insert(session_key); |
642 DCHECK(!ContainsKey(ip_aliases_[session->connection()->peer_address()], | 704 const IpAliasKey ip_alias_key(session->connection()->peer_address(), |
643 session)); | 705 session_key.is_https); |
644 ip_aliases_[session->connection()->peer_address()].insert(session); | 706 DCHECK(!ContainsKey(ip_aliases_[ip_alias_key], session)); |
| 707 ip_aliases_[ip_alias_key].insert(session); |
645 } | 708 } |
646 | 709 |
647 QuicCryptoClientConfig* QuicStreamFactory::GetOrCreateCryptoConfig( | 710 QuicCryptoClientConfig* QuicStreamFactory::GetOrCreateCryptoConfig( |
648 const HostPortProxyPair& host_port_proxy_pair) { | 711 const HostPortProxyPair& host_port_proxy_pair) { |
649 QuicCryptoClientConfig* crypto_config; | 712 QuicCryptoClientConfig* crypto_config; |
650 | 713 |
651 if (ContainsKey(all_crypto_configs_, host_port_proxy_pair)) { | 714 if (ContainsKey(all_crypto_configs_, host_port_proxy_pair)) { |
652 crypto_config = all_crypto_configs_[host_port_proxy_pair]; | 715 crypto_config = all_crypto_configs_[host_port_proxy_pair]; |
653 DCHECK(crypto_config); | 716 DCHECK(crypto_config); |
654 } else { | 717 } else { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
701 // Copy the CachedState for the canonical server from canonical_crypto_config | 764 // Copy the CachedState for the canonical server from canonical_crypto_config |
702 // as the initial CachedState for the server_hostname in crypto_config. | 765 // as the initial CachedState for the server_hostname in crypto_config. |
703 crypto_config->InitializeFrom(server_hostname, | 766 crypto_config->InitializeFrom(server_hostname, |
704 canonical_host_port_proxy_pair.first.host(), | 767 canonical_host_port_proxy_pair.first.host(), |
705 canonical_crypto_config); | 768 canonical_crypto_config); |
706 // Update canonical version to point at the "most recent" crypto_config. | 769 // Update canonical version to point at the "most recent" crypto_config. |
707 canonical_hostname_to_origin_map_[canonical_host_port] = host_port_proxy_pair; | 770 canonical_hostname_to_origin_map_[canonical_host_port] = host_port_proxy_pair; |
708 } | 771 } |
709 | 772 |
710 } // namespace net | 773 } // namespace net |
OLD | NEW |