Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(436)

Side by Side Diff: net/quic/quic_stream_factory.cc

Issue 190063008: Include the scheme in the key for QUIC the session map. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/quic/quic_stream_factory.h ('k') | net/quic/quic_stream_factory_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « net/quic/quic_stream_factory.h ('k') | net/quic/quic_stream_factory_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698