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/cpu.h" | 9 #include "base/cpu.h" |
10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
113 Job(QuicStreamFactory* factory, | 113 Job(QuicStreamFactory* factory, |
114 HostResolver* host_resolver, | 114 HostResolver* host_resolver, |
115 const HostPortPair& host_port_pair, | 115 const HostPortPair& host_port_pair, |
116 bool is_https, | 116 bool is_https, |
117 bool was_alternate_protocol_recently_broken, | 117 bool was_alternate_protocol_recently_broken, |
118 PrivacyMode privacy_mode, | 118 PrivacyMode privacy_mode, |
119 base::StringPiece method, | 119 base::StringPiece method, |
120 QuicServerInfo* server_info, | 120 QuicServerInfo* server_info, |
121 const BoundNetLog& net_log); | 121 const BoundNetLog& net_log); |
122 | 122 |
| 123 // Creates a new job to handle the resumption of for connecting an |
| 124 // existing session. |
| 125 Job(QuicStreamFactory* factory, |
| 126 HostResolver* host_resolver, |
| 127 QuicClientSession* session, |
| 128 QuicServerId server_id); |
| 129 |
123 ~Job(); | 130 ~Job(); |
124 | 131 |
125 int Run(const CompletionCallback& callback); | 132 int Run(const CompletionCallback& callback); |
126 | 133 |
127 int DoLoop(int rv); | 134 int DoLoop(int rv); |
128 int DoResolveHost(); | 135 int DoResolveHost(); |
129 int DoResolveHostComplete(int rv); | 136 int DoResolveHostComplete(int rv); |
130 int DoLoadServerInfo(); | 137 int DoLoadServerInfo(); |
131 int DoLoadServerInfoComplete(int rv); | 138 int DoLoadServerInfoComplete(int rv); |
132 int DoConnect(); | 139 int DoConnect(); |
| 140 int DoResumeConnect(); |
133 int DoConnectComplete(int rv); | 141 int DoConnectComplete(int rv); |
134 | 142 |
135 void OnIOComplete(int rv); | 143 void OnIOComplete(int rv); |
136 | 144 |
137 CompletionCallback callback() { | 145 CompletionCallback callback() { |
138 return callback_; | 146 return callback_; |
139 } | 147 } |
140 | 148 |
141 const QuicServerId server_id() const { | 149 const QuicServerId server_id() const { |
142 return server_id_; | 150 return server_id_; |
143 } | 151 } |
144 | 152 |
145 private: | 153 private: |
146 enum IoState { | 154 enum IoState { |
147 STATE_NONE, | 155 STATE_NONE, |
148 STATE_RESOLVE_HOST, | 156 STATE_RESOLVE_HOST, |
149 STATE_RESOLVE_HOST_COMPLETE, | 157 STATE_RESOLVE_HOST_COMPLETE, |
150 STATE_LOAD_SERVER_INFO, | 158 STATE_LOAD_SERVER_INFO, |
151 STATE_LOAD_SERVER_INFO_COMPLETE, | 159 STATE_LOAD_SERVER_INFO_COMPLETE, |
152 STATE_CONNECT, | 160 STATE_CONNECT, |
| 161 STATE_RESUME_CONNECT, |
153 STATE_CONNECT_COMPLETE, | 162 STATE_CONNECT_COMPLETE, |
154 }; | 163 }; |
155 IoState io_state_; | 164 IoState io_state_; |
156 | 165 |
157 QuicStreamFactory* factory_; | 166 QuicStreamFactory* factory_; |
158 SingleRequestHostResolver host_resolver_; | 167 SingleRequestHostResolver host_resolver_; |
159 QuicServerId server_id_; | 168 QuicServerId server_id_; |
160 bool is_post_; | 169 bool is_post_; |
161 bool was_alternate_protocol_recently_broken_; | 170 bool was_alternate_protocol_recently_broken_; |
162 scoped_ptr<QuicServerInfo> server_info_; | 171 scoped_ptr<QuicServerInfo> server_info_; |
163 const BoundNetLog net_log_; | 172 const BoundNetLog net_log_; |
164 QuicClientSession* session_; | 173 QuicClientSession* session_; |
165 CompletionCallback callback_; | 174 CompletionCallback callback_; |
166 AddressList address_list_; | 175 AddressList address_list_; |
167 base::TimeTicks disk_cache_load_start_time_; | 176 base::TimeTicks disk_cache_load_start_time_; |
168 base::WeakPtrFactory<Job> weak_factory_; | 177 base::WeakPtrFactory<Job> weak_factory_; |
169 DISALLOW_COPY_AND_ASSIGN(Job); | 178 DISALLOW_COPY_AND_ASSIGN(Job); |
170 }; | 179 }; |
171 | 180 |
172 QuicStreamFactory::Job::Job(QuicStreamFactory* factory, | 181 QuicStreamFactory::Job::Job(QuicStreamFactory* factory, |
173 HostResolver* host_resolver, | 182 HostResolver* host_resolver, |
174 const HostPortPair& host_port_pair, | 183 const HostPortPair& host_port_pair, |
175 bool is_https, | 184 bool is_https, |
176 bool was_alternate_protocol_recently_broken, | 185 bool was_alternate_protocol_recently_broken, |
177 PrivacyMode privacy_mode, | 186 PrivacyMode privacy_mode, |
178 base::StringPiece method, | 187 base::StringPiece method, |
179 QuicServerInfo* server_info, | 188 QuicServerInfo* server_info, |
180 const BoundNetLog& net_log) | 189 const BoundNetLog& net_log) |
181 : factory_(factory), | 190 : io_state_(STATE_RESOLVE_HOST), |
| 191 factory_(factory), |
182 host_resolver_(host_resolver), | 192 host_resolver_(host_resolver), |
183 server_id_(host_port_pair, is_https, privacy_mode), | 193 server_id_(host_port_pair, is_https, privacy_mode), |
184 is_post_(method == "POST"), | 194 is_post_(method == "POST"), |
185 was_alternate_protocol_recently_broken_( | 195 was_alternate_protocol_recently_broken_( |
186 was_alternate_protocol_recently_broken), | 196 was_alternate_protocol_recently_broken), |
187 server_info_(server_info), | 197 server_info_(server_info), |
188 net_log_(net_log), | 198 net_log_(net_log), |
189 session_(NULL), | 199 session_(NULL), |
190 weak_factory_(this) {} | 200 weak_factory_(this) {} |
191 | 201 |
| 202 QuicStreamFactory::Job::Job(QuicStreamFactory* factory, |
| 203 HostResolver* host_resolver, |
| 204 QuicClientSession* session, |
| 205 QuicServerId server_id) |
| 206 : io_state_(STATE_RESUME_CONNECT), |
| 207 factory_(factory), |
| 208 host_resolver_(host_resolver), // unused |
| 209 server_id_(server_id), |
| 210 is_post_(false), // unused |
| 211 was_alternate_protocol_recently_broken_(false), // unused |
| 212 net_log_(session->net_log()), // unused |
| 213 session_(session), |
| 214 weak_factory_(this) {} |
| 215 |
192 QuicStreamFactory::Job::~Job() { | 216 QuicStreamFactory::Job::~Job() { |
193 } | 217 } |
194 | 218 |
195 int QuicStreamFactory::Job::Run(const CompletionCallback& callback) { | 219 int QuicStreamFactory::Job::Run(const CompletionCallback& callback) { |
196 io_state_ = STATE_RESOLVE_HOST; | |
197 int rv = DoLoop(OK); | 220 int rv = DoLoop(OK); |
198 if (rv == ERR_IO_PENDING) | 221 if (rv == ERR_IO_PENDING) |
199 callback_ = callback; | 222 callback_ = callback; |
200 | 223 |
201 return rv > 0 ? OK : rv; | 224 return rv > 0 ? OK : rv; |
202 } | 225 } |
203 | 226 |
204 int QuicStreamFactory::Job::DoLoop(int rv) { | 227 int QuicStreamFactory::Job::DoLoop(int rv) { |
205 do { | 228 do { |
206 IoState state = io_state_; | 229 IoState state = io_state_; |
(...skipping 10 matching lines...) Expand all Loading... |
217 CHECK_EQ(OK, rv); | 240 CHECK_EQ(OK, rv); |
218 rv = DoLoadServerInfo(); | 241 rv = DoLoadServerInfo(); |
219 break; | 242 break; |
220 case STATE_LOAD_SERVER_INFO_COMPLETE: | 243 case STATE_LOAD_SERVER_INFO_COMPLETE: |
221 rv = DoLoadServerInfoComplete(rv); | 244 rv = DoLoadServerInfoComplete(rv); |
222 break; | 245 break; |
223 case STATE_CONNECT: | 246 case STATE_CONNECT: |
224 CHECK_EQ(OK, rv); | 247 CHECK_EQ(OK, rv); |
225 rv = DoConnect(); | 248 rv = DoConnect(); |
226 break; | 249 break; |
| 250 case STATE_RESUME_CONNECT: |
| 251 CHECK_EQ(OK, rv); |
| 252 rv = DoResumeConnect(); |
| 253 break; |
227 case STATE_CONNECT_COMPLETE: | 254 case STATE_CONNECT_COMPLETE: |
228 rv = DoConnectComplete(rv); | 255 rv = DoConnectComplete(rv); |
229 break; | 256 break; |
230 default: | 257 default: |
231 NOTREACHED() << "io_state_: " << io_state_; | 258 NOTREACHED() << "io_state_: " << io_state_; |
232 break; | 259 break; |
233 } | 260 } |
234 } while (io_state_ != STATE_NONE && rv != ERR_IO_PENDING); | 261 } while (io_state_ != STATE_NONE && rv != ERR_IO_PENDING); |
235 return rv; | 262 return rv; |
236 } | 263 } |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 bool require_confirmation = | 346 bool require_confirmation = |
320 factory_->require_confirmation() || is_post_ || | 347 factory_->require_confirmation() || is_post_ || |
321 was_alternate_protocol_recently_broken_; | 348 was_alternate_protocol_recently_broken_; |
322 rv = session_->CryptoConnect( | 349 rv = session_->CryptoConnect( |
323 require_confirmation, | 350 require_confirmation, |
324 base::Bind(&QuicStreamFactory::Job::OnIOComplete, | 351 base::Bind(&QuicStreamFactory::Job::OnIOComplete, |
325 base::Unretained(this))); | 352 base::Unretained(this))); |
326 return rv; | 353 return rv; |
327 } | 354 } |
328 | 355 |
| 356 int QuicStreamFactory::Job::DoResumeConnect() { |
| 357 io_state_ = STATE_CONNECT_COMPLETE; |
| 358 |
| 359 int rv = session_->ResumeCryptoConnect( |
| 360 base::Bind(&QuicStreamFactory::Job::OnIOComplete, |
| 361 base::Unretained(this))); |
| 362 |
| 363 return rv; |
| 364 } |
| 365 |
329 int QuicStreamFactory::Job::DoConnectComplete(int rv) { | 366 int QuicStreamFactory::Job::DoConnectComplete(int rv) { |
330 if (rv != OK) | 367 if (rv != OK) |
331 return rv; | 368 return rv; |
332 | 369 |
333 DCHECK(!factory_->HasActiveSession(server_id_)); | 370 DCHECK(!factory_->HasActiveSession(server_id_)); |
334 // There may well now be an active session for this IP. If so, use the | 371 // There may well now be an active session for this IP. If so, use the |
335 // existing session instead. | 372 // existing session instead. |
336 AddressList address(session_->connection()->peer_address()); | 373 AddressList address(session_->connection()->peer_address()); |
337 if (factory_->OnResolution(server_id_, address)) { | 374 if (factory_->OnResolution(server_id_, address)) { |
338 session_->connection()->SendConnectionClose(QUIC_CONNECTION_IP_POOLED); | 375 session_->connection()->SendConnectionClose(QUIC_CONNECTION_IP_POOLED); |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
596 session_aliases_.erase(session); | 633 session_aliases_.erase(session); |
597 } | 634 } |
598 | 635 |
599 void QuicStreamFactory::OnSessionClosed(QuicClientSession* session) { | 636 void QuicStreamFactory::OnSessionClosed(QuicClientSession* session) { |
600 DCHECK_EQ(0u, session->GetNumOpenStreams()); | 637 DCHECK_EQ(0u, session->GetNumOpenStreams()); |
601 OnSessionGoingAway(session); | 638 OnSessionGoingAway(session); |
602 delete session; | 639 delete session; |
603 all_sessions_.erase(session); | 640 all_sessions_.erase(session); |
604 } | 641 } |
605 | 642 |
| 643 void QuicStreamFactory::OnSessionConnectTimeout( |
| 644 QuicClientSession* session) { |
| 645 const AliasSet& aliases = session_aliases_[session]; |
| 646 for (AliasSet::const_iterator it = aliases.begin(); it != aliases.end(); |
| 647 ++it) { |
| 648 DCHECK(active_sessions_.count(*it)); |
| 649 DCHECK_EQ(session, active_sessions_[*it]); |
| 650 active_sessions_.erase(*it); |
| 651 } |
| 652 |
| 653 if (aliases.empty()) { |
| 654 return; |
| 655 } |
| 656 |
| 657 const IpAliasKey ip_alias_key(session->connection()->peer_address(), |
| 658 aliases.begin()->is_https()); |
| 659 ip_aliases_[ip_alias_key].erase(session); |
| 660 if (ip_aliases_[ip_alias_key].empty()) { |
| 661 ip_aliases_.erase(ip_alias_key); |
| 662 } |
| 663 QuicServerId server_id = *aliases.begin(); |
| 664 session_aliases_.erase(session); |
| 665 Job* job = new Job(this, host_resolver_, session, server_id); |
| 666 active_jobs_[server_id] = job; |
| 667 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, |
| 668 base::Unretained(this), job)); |
| 669 DCHECK_EQ(ERR_IO_PENDING, rv); |
| 670 } |
| 671 |
606 void QuicStreamFactory::CancelRequest(QuicStreamRequest* request) { | 672 void QuicStreamFactory::CancelRequest(QuicStreamRequest* request) { |
607 DCHECK(ContainsKey(active_requests_, request)); | 673 DCHECK(ContainsKey(active_requests_, request)); |
608 Job* job = active_requests_[request]; | 674 Job* job = active_requests_[request]; |
609 job_requests_map_[job].erase(request); | 675 job_requests_map_[job].erase(request); |
610 active_requests_.erase(request); | 676 active_requests_.erase(request); |
611 } | 677 } |
612 | 678 |
613 void QuicStreamFactory::CloseAllSessions(int error) { | 679 void QuicStreamFactory::CloseAllSessions(int error) { |
614 while (!active_sessions_.empty()) { | 680 while (!active_sessions_.empty()) { |
615 size_t initial_size = active_sessions_.size(); | 681 size_t initial_size = active_sessions_.size(); |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
762 http_server_properties_->GetServerNetworkStats( | 828 http_server_properties_->GetServerNetworkStats( |
763 server_id.host_port_pair()); | 829 server_id.host_port_pair()); |
764 if (stats != NULL) { | 830 if (stats != NULL) { |
765 config.SetInitialRoundTripTimeUsToSend(stats->srtt.InMicroseconds()); | 831 config.SetInitialRoundTripTimeUsToSend(stats->srtt.InMicroseconds()); |
766 } | 832 } |
767 } | 833 } |
768 | 834 |
769 *session = new QuicClientSession( | 835 *session = new QuicClientSession( |
770 connection, socket.Pass(), writer.Pass(), this, | 836 connection, socket.Pass(), writer.Pass(), this, |
771 quic_crypto_client_stream_factory_, server_info.Pass(), server_id, | 837 quic_crypto_client_stream_factory_, server_info.Pass(), server_id, |
772 config, kInitialReceiveWindowSize, &crypto_config_, net_log.net_log()); | 838 config, kInitialReceiveWindowSize, &crypto_config_, |
| 839 base::MessageLoop::current()->message_loop_proxy().get(), |
| 840 net_log.net_log()); |
773 all_sessions_[*session] = server_id; // owning pointer | 841 all_sessions_[*session] = server_id; // owning pointer |
774 return OK; | 842 return OK; |
775 } | 843 } |
776 | 844 |
777 bool QuicStreamFactory::HasActiveJob(const QuicServerId& key) const { | 845 bool QuicStreamFactory::HasActiveJob(const QuicServerId& key) const { |
778 return ContainsKey(active_jobs_, key); | 846 return ContainsKey(active_jobs_, key); |
779 } | 847 } |
780 | 848 |
781 void QuicStreamFactory::ActivateSession( | 849 void QuicStreamFactory::ActivateSession( |
782 const QuicServerId& server_id, | 850 const QuicServerId& server_id, |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
864 http_server_properties_->ClearAlternateProtocol(server); | 932 http_server_properties_->ClearAlternateProtocol(server); |
865 http_server_properties_->SetAlternateProtocol( | 933 http_server_properties_->SetAlternateProtocol( |
866 server, alternate.port, alternate.protocol); | 934 server, alternate.port, alternate.protocol); |
867 DCHECK_EQ(QUIC, | 935 DCHECK_EQ(QUIC, |
868 http_server_properties_->GetAlternateProtocol(server).protocol); | 936 http_server_properties_->GetAlternateProtocol(server).protocol); |
869 DCHECK(http_server_properties_->WasAlternateProtocolRecentlyBroken( | 937 DCHECK(http_server_properties_->WasAlternateProtocolRecentlyBroken( |
870 server)); | 938 server)); |
871 } | 939 } |
872 | 940 |
873 } // namespace net | 941 } // namespace net |
OLD | NEW |