| 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)) { |
| 264 session_->connection()->SendConnectionClose(QUIC_NO_ERROR); | 315 session_->connection()->SendConnectionClose(QUIC_NO_ERROR); |
| 265 session_ = NULL; | 316 session_ = NULL; |
| 266 return OK; | 317 return OK; |
| 267 } | 318 } |
| 268 | 319 |
| 269 factory_->ActivateSession(host_port_proxy_pair_, session_); | 320 factory_->ActivateSession(session_key_, session_); |
| 270 | 321 |
| 271 return OK; | 322 return OK; |
| 272 } | 323 } |
| 273 | 324 |
| 274 QuicStreamFactory::QuicStreamFactory( | 325 QuicStreamFactory::QuicStreamFactory( |
| 275 HostResolver* host_resolver, | 326 HostResolver* host_resolver, |
| 276 ClientSocketFactory* client_socket_factory, | 327 ClientSocketFactory* client_socket_factory, |
| 277 base::WeakPtr<HttpServerProperties> http_server_properties, | 328 base::WeakPtr<HttpServerProperties> http_server_properties, |
| 278 QuicCryptoClientStreamFactory* quic_crypto_client_stream_factory, | 329 QuicCryptoClientStreamFactory* quic_crypto_client_stream_factory, |
| 279 QuicRandom* random_generator, | 330 QuicRandom* random_generator, |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 312 STLDeleteValues(&active_jobs_); | 363 STLDeleteValues(&active_jobs_); |
| 313 STLDeleteValues(&all_crypto_configs_); | 364 STLDeleteValues(&all_crypto_configs_); |
| 314 } | 365 } |
| 315 | 366 |
| 316 int QuicStreamFactory::Create(const HostPortProxyPair& host_port_proxy_pair, | 367 int QuicStreamFactory::Create(const HostPortProxyPair& host_port_proxy_pair, |
| 317 bool is_https, | 368 bool is_https, |
| 318 base::StringPiece method, | 369 base::StringPiece method, |
| 319 CertVerifier* cert_verifier, | 370 CertVerifier* cert_verifier, |
| 320 const BoundNetLog& net_log, | 371 const BoundNetLog& net_log, |
| 321 QuicStreamRequest* request) { | 372 QuicStreamRequest* request) { |
| 322 if (HasActiveSession(host_port_proxy_pair)) { | 373 SessionKey session_key(host_port_proxy_pair, is_https); |
| 323 request->set_stream(CreateIfSessionExists(host_port_proxy_pair, net_log)); | 374 if (HasActiveSession(session_key)) { |
| 375 request->set_stream(CreateIfSessionExists(session_key, net_log)); |
| 324 return OK; | 376 return OK; |
| 325 } | 377 } |
| 326 | 378 |
| 327 if (HasActiveJob(host_port_proxy_pair)) { | 379 if (HasActiveJob(session_key)) { |
| 328 Job* job = active_jobs_[host_port_proxy_pair]; | 380 Job* job = active_jobs_[session_key]; |
| 329 active_requests_[request] = job; | 381 active_requests_[request] = job; |
| 330 job_requests_map_[job].insert(request); | 382 job_requests_map_[job].insert(request); |
| 331 return ERR_IO_PENDING; | 383 return ERR_IO_PENDING; |
| 332 } | 384 } |
| 333 | 385 |
| 334 // Create crypto config and start the process of loading QUIC server | 386 // Create crypto config and start the process of loading QUIC server |
| 335 // information from disk cache. | 387 // information from disk cache. |
| 336 QuicCryptoClientConfig* crypto_config = | 388 QuicCryptoClientConfig* crypto_config = GetOrCreateCryptoConfig(session_key); |
| 337 GetOrCreateCryptoConfig(host_port_proxy_pair); | |
| 338 DCHECK(crypto_config); | 389 DCHECK(crypto_config); |
| 339 | 390 |
| 340 scoped_ptr<Job> job(new Job(this, host_resolver_, host_port_proxy_pair, | 391 scoped_ptr<Job> job(new Job(this, host_resolver_, host_port_proxy_pair, |
| 341 is_https, method, cert_verifier, net_log)); | 392 is_https, method, cert_verifier, net_log)); |
| 342 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, | 393 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, |
| 343 base::Unretained(this), job.get())); | 394 base::Unretained(this), job.get())); |
| 344 | 395 |
| 345 if (rv == ERR_IO_PENDING) { | 396 if (rv == ERR_IO_PENDING) { |
| 346 active_requests_[request] = job.get(); | 397 active_requests_[request] = job.get(); |
| 347 job_requests_map_[job.get()].insert(request); | 398 job_requests_map_[job.get()].insert(request); |
| 348 active_jobs_[host_port_proxy_pair] = job.release(); | 399 active_jobs_[session_key] = job.release(); |
| 349 } | 400 } |
| 350 if (rv == OK) { | 401 if (rv == OK) { |
| 351 DCHECK(HasActiveSession(host_port_proxy_pair)); | 402 DCHECK(HasActiveSession(session_key)); |
| 352 request->set_stream(CreateIfSessionExists(host_port_proxy_pair, net_log)); | 403 request->set_stream(CreateIfSessionExists(session_key, net_log)); |
| 353 } | 404 } |
| 354 return rv; | 405 return rv; |
| 355 } | 406 } |
| 356 | 407 |
| 357 bool QuicStreamFactory::OnResolution( | 408 bool QuicStreamFactory::OnResolution( |
| 358 const HostPortProxyPair& host_port_proxy_pair, | 409 const SessionKey& session_key, |
| 359 const AddressList& address_list) { | 410 const AddressList& address_list) { |
| 360 DCHECK(!HasActiveSession(host_port_proxy_pair)); | 411 DCHECK(!HasActiveSession(session_key)); |
| 361 for (size_t i = 0; i < address_list.size(); ++i) { | 412 for (size_t i = 0; i < address_list.size(); ++i) { |
| 362 const IPEndPoint& address = address_list[i]; | 413 const IPEndPoint& address = address_list[i]; |
| 363 if (!ContainsKey(ip_aliases_, address)) | 414 const IpAliasKey ip_alias_key(address, session_key.is_https); |
| 415 if (!ContainsKey(ip_aliases_, ip_alias_key)) |
| 364 continue; | 416 continue; |
| 365 | 417 |
| 366 const SessionSet& sessions = ip_aliases_[address]; | 418 const SessionSet& sessions = ip_aliases_[ip_alias_key]; |
| 367 for (SessionSet::const_iterator i = sessions.begin(); | 419 for (SessionSet::const_iterator i = sessions.begin(); |
| 368 i != sessions.end(); ++i) { | 420 i != sessions.end(); ++i) { |
| 369 QuicClientSession* session = *i; | 421 QuicClientSession* session = *i; |
| 370 if (!session->CanPool(host_port_proxy_pair.first.host())) | 422 if (!session->CanPool(session_key.host_port_proxy_pair.first.host())) |
| 371 continue; | 423 continue; |
| 372 active_sessions_[host_port_proxy_pair] = session; | 424 active_sessions_[session_key] = session; |
| 373 session_aliases_[session].insert(host_port_proxy_pair); | 425 session_aliases_[session].insert(session_key); |
| 374 return true; | 426 return true; |
| 375 } | 427 } |
| 376 } | 428 } |
| 377 return false; | 429 return false; |
| 378 } | 430 } |
| 379 | 431 |
| 380 void QuicStreamFactory::OnJobComplete(Job* job, int rv) { | 432 void QuicStreamFactory::OnJobComplete(Job* job, int rv) { |
| 381 if (rv == OK) { | 433 if (rv == OK) { |
| 382 require_confirmation_ = false; | 434 require_confirmation_ = false; |
| 383 | 435 |
| 384 // Create all the streams, but do not notify them yet. | 436 // Create all the streams, but do not notify them yet. |
| 385 for (RequestSet::iterator it = job_requests_map_[job].begin(); | 437 for (RequestSet::iterator it = job_requests_map_[job].begin(); |
| 386 it != job_requests_map_[job].end() ; ++it) { | 438 it != job_requests_map_[job].end() ; ++it) { |
| 387 DCHECK(HasActiveSession(job->host_port_proxy_pair())); | 439 DCHECK(HasActiveSession(job->session_key())); |
| 388 (*it)->set_stream(CreateIfSessionExists(job->host_port_proxy_pair(), | 440 (*it)->set_stream(CreateIfSessionExists(job->session_key(), |
| 389 (*it)->net_log())); | 441 (*it)->net_log())); |
| 390 } | 442 } |
| 391 } | 443 } |
| 392 while (!job_requests_map_[job].empty()) { | 444 while (!job_requests_map_[job].empty()) { |
| 393 RequestSet::iterator it = job_requests_map_[job].begin(); | 445 RequestSet::iterator it = job_requests_map_[job].begin(); |
| 394 QuicStreamRequest* request = *it; | 446 QuicStreamRequest* request = *it; |
| 395 job_requests_map_[job].erase(it); | 447 job_requests_map_[job].erase(it); |
| 396 active_requests_.erase(request); | 448 active_requests_.erase(request); |
| 397 // Even though we're invoking callbacks here, we don't need to worry | 449 // 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 | 450 // about |this| being deleted, because the factory is owned by the |
| 399 // profile which can not be deleted via callbacks. | 451 // profile which can not be deleted via callbacks. |
| 400 request->OnRequestComplete(rv); | 452 request->OnRequestComplete(rv); |
| 401 } | 453 } |
| 402 active_jobs_.erase(job->host_port_proxy_pair()); | 454 active_jobs_.erase(job->session_key()); |
| 403 job_requests_map_.erase(job); | 455 job_requests_map_.erase(job); |
| 404 delete job; | 456 delete job; |
| 405 return; | 457 return; |
| 406 } | 458 } |
| 407 | 459 |
| 408 // Returns a newly created QuicHttpStream owned by the caller, if a | 460 // Returns a newly created QuicHttpStream owned by the caller, if a |
| 409 // matching session already exists. Returns NULL otherwise. | 461 // matching session already exists. Returns NULL otherwise. |
| 410 scoped_ptr<QuicHttpStream> QuicStreamFactory::CreateIfSessionExists( | 462 scoped_ptr<QuicHttpStream> QuicStreamFactory::CreateIfSessionExists( |
| 411 const HostPortProxyPair& host_port_proxy_pair, | 463 const SessionKey& session_key, |
| 412 const BoundNetLog& net_log) { | 464 const BoundNetLog& net_log) { |
| 413 if (!HasActiveSession(host_port_proxy_pair)) { | 465 if (!HasActiveSession(session_key)) { |
| 414 DVLOG(1) << "No active session"; | 466 DVLOG(1) << "No active session"; |
| 415 return scoped_ptr<QuicHttpStream>(); | 467 return scoped_ptr<QuicHttpStream>(); |
| 416 } | 468 } |
| 417 | 469 |
| 418 QuicClientSession* session = active_sessions_[host_port_proxy_pair]; | 470 QuicClientSession* session = active_sessions_[session_key]; |
| 419 DCHECK(session); | 471 DCHECK(session); |
| 420 return scoped_ptr<QuicHttpStream>( | 472 return scoped_ptr<QuicHttpStream>( |
| 421 new QuicHttpStream(session->GetWeakPtr())); | 473 new QuicHttpStream(session->GetWeakPtr())); |
| 422 } | 474 } |
| 423 | 475 |
| 424 void QuicStreamFactory::OnIdleSession(QuicClientSession* session) { | 476 void QuicStreamFactory::OnIdleSession(QuicClientSession* session) { |
| 425 } | 477 } |
| 426 | 478 |
| 427 void QuicStreamFactory::OnSessionGoingAway(QuicClientSession* session) { | 479 void QuicStreamFactory::OnSessionGoingAway(QuicClientSession* session) { |
| 428 const QuicConnectionStats& stats = session->connection()->GetStats(); | 480 const QuicConnectionStats& stats = session->connection()->GetStats(); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 439 | 491 |
| 440 active_sessions_.erase(*it); | 492 active_sessions_.erase(*it); |
| 441 if (!http_server_properties_) | 493 if (!http_server_properties_) |
| 442 continue; | 494 continue; |
| 443 | 495 |
| 444 if (!session->IsCryptoHandshakeConfirmed()) { | 496 if (!session->IsCryptoHandshakeConfirmed()) { |
| 445 // TODO(rch): In the special case where the session has received no | 497 // TODO(rch): In the special case where the session has received no |
| 446 // packets from the peer, we should consider blacklisting this | 498 // packets from the peer, we should consider blacklisting this |
| 447 // differently so that we still race TCP but we don't consider the | 499 // differently so that we still race TCP but we don't consider the |
| 448 // session connected until the handshake has been confirmed. | 500 // session connected until the handshake has been confirmed. |
| 449 http_server_properties_->SetBrokenAlternateProtocol(it->first); | 501 http_server_properties_->SetBrokenAlternateProtocol( |
| 502 it->host_port_proxy_pair.first); |
| 450 UMA_HISTOGRAM_COUNTS("Net.QuicHandshakeNotConfirmedNumPacketsReceived", | 503 UMA_HISTOGRAM_COUNTS("Net.QuicHandshakeNotConfirmedNumPacketsReceived", |
| 451 stats.packets_received); | 504 stats.packets_received); |
| 452 continue; | 505 continue; |
| 453 } | 506 } |
| 454 | 507 |
| 455 HttpServerProperties::NetworkStats network_stats; | 508 HttpServerProperties::NetworkStats network_stats; |
| 456 network_stats.rtt = base::TimeDelta::FromMicroseconds(stats.rtt); | 509 network_stats.rtt = base::TimeDelta::FromMicroseconds(stats.rtt); |
| 457 network_stats.bandwidth_estimate = stats.estimated_bandwidth; | 510 network_stats.bandwidth_estimate = stats.estimated_bandwidth; |
| 458 http_server_properties_->SetServerNetworkStats( | 511 http_server_properties_->SetServerNetworkStats( |
| 459 it->first, network_stats); | 512 it->host_port_proxy_pair.first, network_stats); |
| 460 } | 513 } |
| 461 IPEndPoint peer_address = session->connection()->peer_address(); | 514 if (!aliases.empty()) { |
| 462 ip_aliases_[peer_address].erase(session); | 515 const IpAliasKey ip_alias_key(session->connection()->peer_address(), |
| 463 if (ip_aliases_[peer_address].empty()) { | 516 aliases.begin()->is_https); |
| 464 ip_aliases_.erase(peer_address); | 517 ip_aliases_[ip_alias_key].erase(session); |
| 518 if (ip_aliases_[ip_alias_key].empty()) { |
| 519 ip_aliases_.erase(ip_alias_key); |
| 520 } |
| 465 } | 521 } |
| 466 session_aliases_.erase(session); | 522 session_aliases_.erase(session); |
| 467 } | 523 } |
| 468 | 524 |
| 469 void QuicStreamFactory::OnSessionClosed(QuicClientSession* session) { | 525 void QuicStreamFactory::OnSessionClosed(QuicClientSession* session) { |
| 470 DCHECK_EQ(0u, session->GetNumOpenStreams()); | 526 DCHECK_EQ(0u, session->GetNumOpenStreams()); |
| 471 OnSessionGoingAway(session); | 527 OnSessionGoingAway(session); |
| 472 all_sessions_.erase(session); | 528 all_sessions_.erase(session); |
| 473 delete session; | 529 delete session; |
| 474 } | 530 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 492 DCHECK_NE(initial_size, all_sessions_.size()); | 548 DCHECK_NE(initial_size, all_sessions_.size()); |
| 493 } | 549 } |
| 494 DCHECK(all_sessions_.empty()); | 550 DCHECK(all_sessions_.empty()); |
| 495 } | 551 } |
| 496 | 552 |
| 497 base::Value* QuicStreamFactory::QuicStreamFactoryInfoToValue() const { | 553 base::Value* QuicStreamFactory::QuicStreamFactoryInfoToValue() const { |
| 498 base::ListValue* list = new base::ListValue(); | 554 base::ListValue* list = new base::ListValue(); |
| 499 | 555 |
| 500 for (SessionMap::const_iterator it = active_sessions_.begin(); | 556 for (SessionMap::const_iterator it = active_sessions_.begin(); |
| 501 it != active_sessions_.end(); ++it) { | 557 it != active_sessions_.end(); ++it) { |
| 502 const HostPortProxyPair& pair = it->first; | 558 const SessionKey& session_key = it->first; |
| 503 QuicClientSession* session = it->second; | 559 QuicClientSession* session = it->second; |
| 504 const AliasSet& aliases = session_aliases_.find(session)->second; | 560 const AliasSet& aliases = session_aliases_.find(session)->second; |
| 505 if (pair.first.Equals(aliases.begin()->first) && | 561 // Only add a session to the list once. |
| 506 pair.second == aliases.begin()->second) { | 562 if (session_key == *aliases.begin()) { |
| 507 list->Append(session->GetInfoAsValue(aliases)); | 563 std::set<HostPortProxyPair> hosts; |
| 564 for (AliasSet::const_iterator alias_it = aliases.begin(); |
| 565 alias_it != aliases.end(); ++alias_it) { |
| 566 hosts.insert(alias_it->host_port_proxy_pair); |
| 567 } |
| 568 list->Append(session->GetInfoAsValue(hosts)); |
| 508 } | 569 } |
| 509 } | 570 } |
| 510 return list; | 571 return list; |
| 511 } | 572 } |
| 512 | 573 |
| 513 void QuicStreamFactory::OnIPAddressChanged() { | 574 void QuicStreamFactory::OnIPAddressChanged() { |
| 514 CloseAllSessions(ERR_NETWORK_CHANGED); | 575 CloseAllSessions(ERR_NETWORK_CHANGED); |
| 515 require_confirmation_ = true; | 576 require_confirmation_ = true; |
| 516 } | 577 } |
| 517 | 578 |
| 518 void QuicStreamFactory::OnCertAdded(const X509Certificate* cert) { | 579 void QuicStreamFactory::OnCertAdded(const X509Certificate* cert) { |
| 519 CloseAllSessions(ERR_CERT_DATABASE_CHANGED); | 580 CloseAllSessions(ERR_CERT_DATABASE_CHANGED); |
| 520 } | 581 } |
| 521 | 582 |
| 522 void QuicStreamFactory::OnCACertChanged(const X509Certificate* cert) { | 583 void QuicStreamFactory::OnCACertChanged(const X509Certificate* cert) { |
| 523 // We should flush the sessions if we removed trust from a | 584 // We should flush the sessions if we removed trust from a |
| 524 // cert, because a previously trusted server may have become | 585 // cert, because a previously trusted server may have become |
| 525 // untrusted. | 586 // untrusted. |
| 526 // | 587 // |
| 527 // We should not flush the sessions if we added trust to a cert. | 588 // We should not flush the sessions if we added trust to a cert. |
| 528 // | 589 // |
| 529 // Since the OnCACertChanged method doesn't tell us what | 590 // Since the OnCACertChanged method doesn't tell us what |
| 530 // kind of change it is, we have to flush the socket | 591 // kind of change it is, we have to flush the socket |
| 531 // pools to be safe. | 592 // pools to be safe. |
| 532 CloseAllSessions(ERR_CERT_DATABASE_CHANGED); | 593 CloseAllSessions(ERR_CERT_DATABASE_CHANGED); |
| 533 } | 594 } |
| 534 | 595 |
| 535 bool QuicStreamFactory::HasActiveSession( | 596 bool QuicStreamFactory::HasActiveSession(const SessionKey& session_key) const { |
| 536 const HostPortProxyPair& host_port_proxy_pair) { | 597 return ContainsKey(active_sessions_, session_key); |
| 537 return ContainsKey(active_sessions_, host_port_proxy_pair); | |
| 538 } | 598 } |
| 539 | 599 |
| 540 int QuicStreamFactory::CreateSession( | 600 int QuicStreamFactory::CreateSession( |
| 541 const HostPortProxyPair& host_port_proxy_pair, | 601 const HostPortProxyPair& host_port_proxy_pair, |
| 542 bool is_https, | 602 bool is_https, |
| 543 CertVerifier* cert_verifier, | 603 CertVerifier* cert_verifier, |
| 544 const AddressList& address_list, | 604 const AddressList& address_list, |
| 545 const BoundNetLog& net_log, | 605 const BoundNetLog& net_log, |
| 546 QuicClientSession** session) { | 606 QuicClientSession** session) { |
| 547 bool enable_port_selection = enable_port_selection_; | 607 bool enable_port_selection = enable_port_selection_; |
| 608 SessionKey session_key(host_port_proxy_pair, is_https); |
| 548 if (enable_port_selection && | 609 if (enable_port_selection && |
| 549 ContainsKey(gone_away_aliases_, host_port_proxy_pair)) { | 610 ContainsKey(gone_away_aliases_, session_key)) { |
| 550 // Disable port selection when the server is going away. | 611 // Disable port selection when the server is going away. |
| 551 // There is no point in trying to return to the same server, if | 612 // There is no point in trying to return to the same server, if |
| 552 // that server is no longer handling requests. | 613 // that server is no longer handling requests. |
| 553 enable_port_selection = false; | 614 enable_port_selection = false; |
| 554 gone_away_aliases_.erase(host_port_proxy_pair); | 615 gone_away_aliases_.erase(session_key); |
| 555 } | 616 } |
| 556 | 617 |
| 557 QuicConnectionId connection_id = random_generator_->RandUint64(); | 618 QuicConnectionId connection_id = random_generator_->RandUint64(); |
| 558 IPEndPoint addr = *address_list.begin(); | 619 IPEndPoint addr = *address_list.begin(); |
| 559 scoped_refptr<PortSuggester> port_suggester = | 620 scoped_refptr<PortSuggester> port_suggester = |
| 560 new PortSuggester(host_port_proxy_pair.first, port_seed_); | 621 new PortSuggester(host_port_proxy_pair.first, port_seed_); |
| 561 DatagramSocket::BindType bind_type = enable_port_selection ? | 622 DatagramSocket::BindType bind_type = enable_port_selection ? |
| 562 DatagramSocket::RANDOM_BIND : // Use our callback. | 623 DatagramSocket::RANDOM_BIND : // Use our callback. |
| 563 DatagramSocket::DEFAULT_BIND; // Use OS to randomize. | 624 DatagramSocket::DEFAULT_BIND; // Use OS to randomize. |
| 564 scoped_ptr<DatagramClientSocket> socket( | 625 scoped_ptr<DatagramClientSocket> socket( |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 597 clock_.get(), random_generator_)); | 658 clock_.get(), random_generator_)); |
| 598 } | 659 } |
| 599 | 660 |
| 600 QuicConnection* connection = new QuicConnection(connection_id, addr, | 661 QuicConnection* connection = new QuicConnection(connection_id, addr, |
| 601 helper_.get(), | 662 helper_.get(), |
| 602 writer.get(), false, | 663 writer.get(), false, |
| 603 supported_versions_); | 664 supported_versions_); |
| 604 writer->SetConnection(connection); | 665 writer->SetConnection(connection); |
| 605 connection->options()->max_packet_length = max_packet_length_; | 666 connection->options()->max_packet_length = max_packet_length_; |
| 606 | 667 |
| 607 QuicCryptoClientConfig* crypto_config = | 668 QuicCryptoClientConfig* crypto_config = GetOrCreateCryptoConfig(session_key); |
| 608 GetOrCreateCryptoConfig(host_port_proxy_pair); | 669 |
| 609 DCHECK(crypto_config); | 670 DCHECK(crypto_config); |
| 610 | 671 |
| 611 QuicConfig config = config_; | 672 QuicConfig config = config_; |
| 612 if (http_server_properties_) { | 673 if (http_server_properties_) { |
| 613 const HttpServerProperties::NetworkStats* stats = | 674 const HttpServerProperties::NetworkStats* stats = |
| 614 http_server_properties_->GetServerNetworkStats( | 675 http_server_properties_->GetServerNetworkStats( |
| 615 host_port_proxy_pair.first); | 676 host_port_proxy_pair.first); |
| 616 if (stats != NULL) { | 677 if (stats != NULL) { |
| 617 config.set_initial_round_trip_time_us(stats->rtt.InMicroseconds(), | 678 config.set_initial_round_trip_time_us(stats->rtt.InMicroseconds(), |
| 618 stats->rtt.InMicroseconds()); | 679 stats->rtt.InMicroseconds()); |
| 619 } | 680 } |
| 620 } | 681 } |
| 621 | 682 |
| 622 *session = new QuicClientSession( | 683 *session = new QuicClientSession( |
| 623 connection, socket.Pass(), writer.Pass(), this, | 684 connection, socket.Pass(), writer.Pass(), this, |
| 624 quic_crypto_client_stream_factory_, host_port_proxy_pair.first.host(), | 685 quic_crypto_client_stream_factory_, host_port_proxy_pair.first.host(), |
| 625 config, crypto_config, net_log.net_log()); | 686 config, crypto_config, net_log.net_log()); |
| 626 all_sessions_.insert(*session); // owning pointer | 687 all_sessions_.insert(*session); // owning pointer |
| 627 if (is_https) { | 688 if (is_https) { |
| 628 crypto_config->SetProofVerifier( | 689 crypto_config->SetProofVerifier( |
| 629 new ProofVerifierChromium(cert_verifier, net_log)); | 690 new ProofVerifierChromium(cert_verifier, net_log)); |
| 630 } | 691 } |
| 631 return OK; | 692 return OK; |
| 632 } | 693 } |
| 633 | 694 |
| 634 bool QuicStreamFactory::HasActiveJob( | 695 bool QuicStreamFactory::HasActiveJob(const SessionKey& key) const { |
| 635 const HostPortProxyPair& host_port_proxy_pair) { | 696 return ContainsKey(active_jobs_, key); |
| 636 return ContainsKey(active_jobs_, host_port_proxy_pair); | |
| 637 } | 697 } |
| 638 | 698 |
| 639 void QuicStreamFactory::ActivateSession( | 699 void QuicStreamFactory::ActivateSession( |
| 640 const HostPortProxyPair& host_port_proxy_pair, | 700 const SessionKey& session_key, |
| 641 QuicClientSession* session) { | 701 QuicClientSession* session) { |
| 642 DCHECK(!HasActiveSession(host_port_proxy_pair)); | 702 DCHECK(!HasActiveSession(session_key)); |
| 643 active_sessions_[host_port_proxy_pair] = session; | 703 active_sessions_[session_key] = session; |
| 644 session_aliases_[session].insert(host_port_proxy_pair); | 704 session_aliases_[session].insert(session_key); |
| 645 DCHECK(!ContainsKey(ip_aliases_[session->connection()->peer_address()], | 705 const IpAliasKey ip_alias_key(session->connection()->peer_address(), |
| 646 session)); | 706 session_key.is_https); |
| 647 ip_aliases_[session->connection()->peer_address()].insert(session); | 707 DCHECK(!ContainsKey(ip_aliases_[ip_alias_key], session)); |
| 708 ip_aliases_[ip_alias_key].insert(session); |
| 648 } | 709 } |
| 649 | 710 |
| 650 QuicCryptoClientConfig* QuicStreamFactory::GetOrCreateCryptoConfig( | 711 QuicCryptoClientConfig* QuicStreamFactory::GetOrCreateCryptoConfig( |
| 651 const HostPortProxyPair& host_port_proxy_pair) { | 712 const SessionKey& session_key) { |
| 652 QuicCryptoClientConfig* crypto_config; | 713 QuicCryptoClientConfig* crypto_config; |
| 653 | 714 |
| 654 if (ContainsKey(all_crypto_configs_, host_port_proxy_pair)) { | 715 if (ContainsKey(all_crypto_configs_, session_key)) { |
| 655 crypto_config = all_crypto_configs_[host_port_proxy_pair]; | 716 crypto_config = all_crypto_configs_[session_key]; |
| 656 DCHECK(crypto_config); | 717 DCHECK(crypto_config); |
| 657 } else { | 718 } else { |
| 658 // TODO(rtenneti): if two quic_sessions for the same host_port_proxy_pair | 719 // TODO(rtenneti): if two quic_sessions for the same host_port_proxy_pair |
| 659 // share the same crypto_config, will it cause issues? | 720 // share the same crypto_config, will it cause issues? |
| 660 crypto_config = new QuicCryptoClientConfig(); | 721 crypto_config = new QuicCryptoClientConfig(); |
| 661 if (quic_server_info_factory_) { | 722 if (quic_server_info_factory_) { |
| 662 QuicCryptoClientConfig::CachedState* cached = | 723 QuicCryptoClientConfig::CachedState* cached = |
| 663 crypto_config->Create(host_port_proxy_pair.first.host(), | 724 crypto_config->Create(session_key.host_port_proxy_pair.first.host(), |
| 664 quic_server_info_factory_); | 725 quic_server_info_factory_); |
| 665 DCHECK(cached); | 726 DCHECK(cached); |
| 666 } | 727 } |
| 667 crypto_config->SetDefaults(); | 728 crypto_config->SetDefaults(); |
| 668 all_crypto_configs_[host_port_proxy_pair] = crypto_config; | 729 all_crypto_configs_[session_key] = crypto_config; |
| 669 PopulateFromCanonicalConfig(host_port_proxy_pair, crypto_config); | 730 PopulateFromCanonicalConfig(session_key, crypto_config); |
| 670 } | 731 } |
| 671 return crypto_config; | 732 return crypto_config; |
| 672 } | 733 } |
| 673 | 734 |
| 674 void QuicStreamFactory::PopulateFromCanonicalConfig( | 735 void QuicStreamFactory::PopulateFromCanonicalConfig( |
| 675 const HostPortProxyPair& host_port_proxy_pair, | 736 const SessionKey& session_key, |
| 676 QuicCryptoClientConfig* crypto_config) { | 737 QuicCryptoClientConfig* crypto_config) { |
| 677 const string server_hostname = host_port_proxy_pair.first.host(); | 738 const string server_hostname = session_key.host_port_proxy_pair.first.host(); |
| 678 | 739 const uint16 server_port = session_key.host_port_proxy_pair.first.port(); |
| 679 unsigned i = 0; | 740 unsigned i = 0; |
| 680 for (; i < canoncial_suffixes_.size(); ++i) { | 741 for (; i < canoncial_suffixes_.size(); ++i) { |
| 681 if (EndsWith(server_hostname, canoncial_suffixes_[i], false)) { | 742 if (EndsWith(server_hostname, canoncial_suffixes_[i], false)) { |
| 682 break; | 743 break; |
| 683 } | 744 } |
| 684 } | 745 } |
| 685 if (i == canoncial_suffixes_.size()) | 746 if (i == canoncial_suffixes_.size()) |
| 686 return; | 747 return; |
| 687 | 748 |
| 688 HostPortPair canonical_host_port(canoncial_suffixes_[i], | 749 HostPortPair suffix_host_port(canoncial_suffixes_[i], server_port); |
| 689 host_port_proxy_pair.first.port()); | 750 HostPortProxyPair suffix_host_port_proxy_pair( |
| 690 if (!ContainsKey(canonical_hostname_to_origin_map_, canonical_host_port)) { | 751 suffix_host_port, session_key.host_port_proxy_pair.second); |
| 752 SessionKey suffix_session_key(suffix_host_port_proxy_pair, |
| 753 session_key.is_https); |
| 754 if (!ContainsKey(canonical_hostname_to_origin_map_, suffix_session_key)) { |
| 691 // This is the first host we've seen which matches the suffix, so make it | 755 // This is the first host we've seen which matches the suffix, so make it |
| 692 // canonical. | 756 // canonical. |
| 693 canonical_hostname_to_origin_map_[canonical_host_port] = | 757 canonical_hostname_to_origin_map_[suffix_session_key] = session_key; |
| 694 host_port_proxy_pair; | |
| 695 return; | 758 return; |
| 696 } | 759 } |
| 697 | 760 |
| 761 const SessionKey& canonical_session_key = |
| 762 canonical_hostname_to_origin_map_[suffix_session_key]; |
| 763 QuicCryptoClientConfig* canonical_crypto_config = |
| 764 all_crypto_configs_[canonical_session_key]; |
| 765 DCHECK(canonical_crypto_config); |
| 698 const HostPortProxyPair& canonical_host_port_proxy_pair = | 766 const HostPortProxyPair& canonical_host_port_proxy_pair = |
| 699 canonical_hostname_to_origin_map_[canonical_host_port]; | 767 canonical_session_key.host_port_proxy_pair; |
| 700 QuicCryptoClientConfig* canonical_crypto_config = | |
| 701 all_crypto_configs_[canonical_host_port_proxy_pair]; | |
| 702 DCHECK(canonical_crypto_config); | |
| 703 | 768 |
| 704 // Copy the CachedState for the canonical server from canonical_crypto_config | 769 // Copy the CachedState for the canonical server from canonical_crypto_config |
| 705 // as the initial CachedState for the server_hostname in crypto_config. | 770 // as the initial CachedState for the server_hostname in crypto_config. |
| 706 crypto_config->InitializeFrom(server_hostname, | 771 crypto_config->InitializeFrom(server_hostname, |
| 707 canonical_host_port_proxy_pair.first.host(), | 772 canonical_host_port_proxy_pair.first.host(), |
| 708 canonical_crypto_config); | 773 canonical_crypto_config); |
| 709 // Update canonical version to point at the "most recent" crypto_config. | 774 // Update canonical version to point at the "most recent" crypto_config. |
| 710 canonical_hostname_to_origin_map_[canonical_host_port] = host_port_proxy_pair; | 775 canonical_hostname_to_origin_map_[suffix_session_key] = |
| 776 canonical_session_key; |
| 711 } | 777 } |
| 712 | 778 |
| 713 } // namespace net | 779 } // namespace net |
| OLD | NEW |