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