| 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/chromium/quic_chromium_client_session.h" | 5 #include "net/quic/chromium/quic_chromium_client_session.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/callback_helpers.h" | 9 #include "base/callback_helpers.h" |
| 10 #include "base/location.h" | 10 #include "base/location.h" |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 const GURL& GetURL() const override { return request_url_; } | 180 const GURL& GetURL() const override { return request_url_; } |
| 181 | 181 |
| 182 private: | 182 private: |
| 183 base::WeakPtr<QuicChromiumClientSession> session_; | 183 base::WeakPtr<QuicChromiumClientSession> session_; |
| 184 const GURL request_url_; | 184 const GURL request_url_; |
| 185 }; | 185 }; |
| 186 | 186 |
| 187 } // namespace | 187 } // namespace |
| 188 | 188 |
| 189 QuicChromiumClientSession::StreamRequest::StreamRequest( | 189 QuicChromiumClientSession::StreamRequest::StreamRequest( |
| 190 const base::WeakPtr<QuicChromiumClientSession>& session) | 190 const base::WeakPtr<QuicChromiumClientSession>& session, |
| 191 : session_(session), stream_(nullptr) {} | 191 bool requires_confirmation) |
| 192 : session_(session), |
| 193 requires_confirmation_(requires_confirmation), |
| 194 stream_(nullptr), |
| 195 next_state_(STATE_NONE), |
| 196 weak_factory_(this) {} |
| 192 | 197 |
| 193 QuicChromiumClientSession::StreamRequest::~StreamRequest() { | 198 QuicChromiumClientSession::StreamRequest::~StreamRequest() { |
| 194 if (stream_) | 199 if (stream_) |
| 195 stream_->Reset(QUIC_STREAM_CANCELLED); | 200 stream_->Reset(QUIC_STREAM_CANCELLED); |
| 196 | 201 |
| 197 if (session_) | 202 if (session_) |
| 198 session_->CancelRequest(this); | 203 session_->CancelRequest(this); |
| 199 } | 204 } |
| 200 | 205 |
| 201 int QuicChromiumClientSession::StreamRequest::StartRequest( | 206 int QuicChromiumClientSession::StreamRequest::StartRequest( |
| 202 const CompletionCallback& callback) { | 207 const CompletionCallback& callback) { |
| 203 DCHECK(session_); | 208 DCHECK(session_); |
| 204 int rv = session_->TryCreateStream(this); | 209 |
| 205 if (rv == ERR_IO_PENDING) { | 210 next_state_ = STATE_WAIT_FOR_CONFIRMATION; |
| 211 int rv = DoLoop(OK); |
| 212 if (rv == ERR_IO_PENDING) |
| 206 callback_ = callback; | 213 callback_ = callback; |
| 207 } else { | |
| 208 session_.reset(); | |
| 209 } | |
| 210 | 214 |
| 211 return rv; | 215 return rv; |
| 212 } | 216 } |
| 213 | 217 |
| 214 QuicChromiumClientStream* | 218 QuicChromiumClientStream* |
| 215 QuicChromiumClientSession::StreamRequest::ReleaseStream() { | 219 QuicChromiumClientSession::StreamRequest::ReleaseStream() { |
| 216 DCHECK(stream_); | 220 DCHECK(stream_); |
| 217 QuicChromiumClientStream* stream = stream_; | 221 QuicChromiumClientStream* stream = stream_; |
| 218 stream_ = nullptr; | 222 stream_ = nullptr; |
| 219 return stream; | 223 return stream; |
| 220 } | 224 } |
| 221 | 225 |
| 222 void QuicChromiumClientSession::StreamRequest::OnRequestCompleteSuccess( | 226 void QuicChromiumClientSession::StreamRequest::OnRequestCompleteSuccess( |
| 223 QuicChromiumClientStream* stream) { | 227 QuicChromiumClientStream* stream) { |
| 228 DCHECK_EQ(STATE_REQUEST_STREAM_COMPLETE, next_state_); |
| 224 session_.reset(); | 229 session_.reset(); |
| 225 stream_ = stream; | 230 stream_ = stream; |
| 226 base::ResetAndReturn(&callback_).Run(OK); | 231 // This method is called even when the request completes synchronously. |
| 232 if (callback_) |
| 233 DoCallback(OK); |
| 227 } | 234 } |
| 228 | 235 |
| 229 void QuicChromiumClientSession::StreamRequest::OnRequestCompleteFailure( | 236 void QuicChromiumClientSession::StreamRequest::OnRequestCompleteFailure( |
| 230 int rv) { | 237 int rv) { |
| 238 DCHECK_EQ(STATE_REQUEST_STREAM_COMPLETE, next_state_); |
| 231 session_.reset(); | 239 session_.reset(); |
| 240 // This method is called even when the request completes synchronously. |
| 241 if (callback_) |
| 242 DoCallback(rv); |
| 243 } |
| 244 |
| 245 void QuicChromiumClientSession::StreamRequest::OnIOComplete(int rv) { |
| 246 rv = DoLoop(rv); |
| 247 |
| 248 if (rv != ERR_IO_PENDING && !callback_.is_null()) { |
| 249 DoCallback(rv); |
| 250 } |
| 251 } |
| 252 |
| 253 void QuicChromiumClientSession::StreamRequest::DoCallback(int rv) { |
| 254 CHECK_NE(rv, ERR_IO_PENDING); |
| 255 CHECK(!callback_.is_null()); |
| 256 |
| 257 // The client callback can do anything, including destroying this class, |
| 258 // so any pending callback must be issued after everything else is done. |
| 232 base::ResetAndReturn(&callback_).Run(rv); | 259 base::ResetAndReturn(&callback_).Run(rv); |
| 233 } | 260 } |
| 234 | 261 |
| 262 int QuicChromiumClientSession::StreamRequest::DoLoop(int rv) { |
| 263 do { |
| 264 State state = next_state_; |
| 265 next_state_ = STATE_NONE; |
| 266 switch (state) { |
| 267 case STATE_WAIT_FOR_CONFIRMATION: |
| 268 CHECK_EQ(OK, rv); |
| 269 rv = DoWaitForConfirmation(); |
| 270 break; |
| 271 case STATE_WAIT_FOR_CONFIRMATION_COMPLETE: |
| 272 rv = DoWaitForConfirmationComplete(rv); |
| 273 break; |
| 274 case STATE_REQUEST_STREAM: |
| 275 CHECK_EQ(OK, rv); |
| 276 rv = DoRequestStream(); |
| 277 break; |
| 278 case STATE_REQUEST_STREAM_COMPLETE: |
| 279 rv = DoRequestStreamComplete(rv); |
| 280 break; |
| 281 default: |
| 282 NOTREACHED() << "next_state_: " << next_state_; |
| 283 break; |
| 284 } |
| 285 } while (next_state_ != STATE_NONE && next_state_ && rv != ERR_IO_PENDING); |
| 286 |
| 287 return rv; |
| 288 } |
| 289 |
| 290 int QuicChromiumClientSession::StreamRequest::DoWaitForConfirmation() { |
| 291 next_state_ = STATE_WAIT_FOR_CONFIRMATION_COMPLETE; |
| 292 if (requires_confirmation_) { |
| 293 return session_->WaitForHandshakeConfirmation( |
| 294 base::Bind(&QuicChromiumClientSession::StreamRequest::OnIOComplete, |
| 295 weak_factory_.GetWeakPtr())); |
| 296 } |
| 297 |
| 298 return OK; |
| 299 } |
| 300 |
| 301 int QuicChromiumClientSession::StreamRequest::DoWaitForConfirmationComplete( |
| 302 int rv) { |
| 303 DCHECK_NE(ERR_IO_PENDING, rv); |
| 304 if (rv < 0) |
| 305 return rv; |
| 306 |
| 307 next_state_ = STATE_REQUEST_STREAM; |
| 308 return OK; |
| 309 } |
| 310 |
| 311 int QuicChromiumClientSession::StreamRequest::DoRequestStream() { |
| 312 next_state_ = STATE_REQUEST_STREAM_COMPLETE; |
| 313 |
| 314 return session_->TryCreateStream(this); |
| 315 } |
| 316 |
| 317 int QuicChromiumClientSession::StreamRequest::DoRequestStreamComplete(int rv) { |
| 318 DCHECK(rv == OK || !stream_); |
| 319 session_.reset(); |
| 320 |
| 321 return rv; |
| 322 } |
| 323 |
| 235 QuicChromiumClientSession::QuicChromiumClientSession( | 324 QuicChromiumClientSession::QuicChromiumClientSession( |
| 236 QuicConnection* connection, | 325 QuicConnection* connection, |
| 237 std::unique_ptr<DatagramClientSocket> socket, | 326 std::unique_ptr<DatagramClientSocket> socket, |
| 238 QuicStreamFactory* stream_factory, | 327 QuicStreamFactory* stream_factory, |
| 239 QuicCryptoClientStreamFactory* crypto_client_stream_factory, | 328 QuicCryptoClientStreamFactory* crypto_client_stream_factory, |
| 240 QuicClock* clock, | 329 QuicClock* clock, |
| 241 TransportSecurityState* transport_security_state, | 330 TransportSecurityState* transport_security_state, |
| 242 std::unique_ptr<QuicServerInfo> server_info, | 331 std::unique_ptr<QuicServerInfo> server_info, |
| 243 const QuicServerId& server_id, | 332 const QuicServerId& server_id, |
| 244 bool require_confirmation, | 333 bool require_confirmation, |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 300 kAdditionalOverheadForIPv6); | 389 kAdditionalOverheadForIPv6); |
| 301 } | 390 } |
| 302 connect_timing_.dns_start = dns_resolution_start_time; | 391 connect_timing_.dns_start = dns_resolution_start_time; |
| 303 connect_timing_.dns_end = dns_resolution_end_time; | 392 connect_timing_.dns_end = dns_resolution_end_time; |
| 304 } | 393 } |
| 305 | 394 |
| 306 QuicChromiumClientSession::~QuicChromiumClientSession() { | 395 QuicChromiumClientSession::~QuicChromiumClientSession() { |
| 307 DCHECK(callback_.is_null()); | 396 DCHECK(callback_.is_null()); |
| 308 | 397 |
| 309 net_log_.EndEvent(NetLogEventType::QUIC_SESSION); | 398 net_log_.EndEvent(NetLogEventType::QUIC_SESSION); |
| 399 DCHECK(waiting_for_confirmation_callbacks_.empty()); |
| 310 if (!dynamic_streams().empty()) | 400 if (!dynamic_streams().empty()) |
| 311 RecordUnexpectedOpenStreams(DESTRUCTOR); | 401 RecordUnexpectedOpenStreams(DESTRUCTOR); |
| 312 if (!observers_.empty()) | 402 if (!observers_.empty()) |
| 313 RecordUnexpectedObservers(DESTRUCTOR); | 403 RecordUnexpectedObservers(DESTRUCTOR); |
| 314 if (!going_away_) | 404 if (!going_away_) |
| 315 RecordUnexpectedNotGoingAway(DESTRUCTOR); | 405 RecordUnexpectedNotGoingAway(DESTRUCTOR); |
| 316 | 406 |
| 317 while (!dynamic_streams().empty() || !observers_.empty() || | 407 while (!dynamic_streams().empty() || !observers_.empty() || |
| 318 !stream_requests_.empty()) { | 408 !stream_requests_.empty()) { |
| 319 // The session must be closed before it is destroyed. | 409 // The session must be closed before it is destroyed. |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 448 DCHECK(!base::ContainsKey(observers_, observer)); | 538 DCHECK(!base::ContainsKey(observers_, observer)); |
| 449 observers_.insert(observer); | 539 observers_.insert(observer); |
| 450 } | 540 } |
| 451 | 541 |
| 452 void QuicChromiumClientSession::RemoveObserver(Observer* observer) { | 542 void QuicChromiumClientSession::RemoveObserver(Observer* observer) { |
| 453 DCHECK(base::ContainsKey(observers_, observer)); | 543 DCHECK(base::ContainsKey(observers_, observer)); |
| 454 observers_.erase(observer); | 544 observers_.erase(observer); |
| 455 } | 545 } |
| 456 | 546 |
| 457 std::unique_ptr<QuicChromiumClientSession::StreamRequest> | 547 std::unique_ptr<QuicChromiumClientSession::StreamRequest> |
| 458 QuicChromiumClientSession::CreateStreamRequest() { | 548 QuicChromiumClientSession::CreateStreamRequest(bool requires_confirmation) { |
| 459 // base::MakeUnique does not work because the StreamRequest constructor | 549 // base::MakeUnique does not work because the StreamRequest constructor |
| 460 // is private. | 550 // is private. |
| 461 return std::unique_ptr<StreamRequest>( | 551 return std::unique_ptr<StreamRequest>( |
| 462 new StreamRequest(weak_factory_.GetWeakPtr())); | 552 new StreamRequest(weak_factory_.GetWeakPtr(), requires_confirmation)); |
| 553 } |
| 554 |
| 555 int QuicChromiumClientSession::WaitForHandshakeConfirmation( |
| 556 const CompletionCallback& callback) { |
| 557 if (!connection()->connected()) |
| 558 return ERR_CONNECTION_CLOSED; |
| 559 |
| 560 if (IsCryptoHandshakeConfirmed()) |
| 561 return OK; |
| 562 |
| 563 waiting_for_confirmation_callbacks_.push_back(callback); |
| 564 return ERR_IO_PENDING; |
| 463 } | 565 } |
| 464 | 566 |
| 465 int QuicChromiumClientSession::TryCreateStream(StreamRequest* request) { | 567 int QuicChromiumClientSession::TryCreateStream(StreamRequest* request) { |
| 466 if (goaway_received()) { | 568 if (goaway_received()) { |
| 467 DVLOG(1) << "Going away."; | 569 DVLOG(1) << "Going away."; |
| 468 return ERR_CONNECTION_CLOSED; | 570 return ERR_CONNECTION_CLOSED; |
| 469 } | 571 } |
| 470 | 572 |
| 471 if (!connection()->connected()) { | 573 if (!connection()->connected()) { |
| 472 DVLOG(1) << "Already closed."; | 574 DVLOG(1) << "Already closed."; |
| (...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 857 "Net.QuicSession.HostResolution.HandshakeConfirmedTime", | 959 "Net.QuicSession.HostResolution.HandshakeConfirmedTime", |
| 858 base::TimeTicks::Now() - connect_timing_.dns_end); | 960 base::TimeTicks::Now() - connect_timing_.dns_end); |
| 859 } | 961 } |
| 860 | 962 |
| 861 ObserverSet::iterator it = observers_.begin(); | 963 ObserverSet::iterator it = observers_.begin(); |
| 862 while (it != observers_.end()) { | 964 while (it != observers_.end()) { |
| 863 Observer* observer = *it; | 965 Observer* observer = *it; |
| 864 ++it; | 966 ++it; |
| 865 observer->OnCryptoHandshakeConfirmed(); | 967 observer->OnCryptoHandshakeConfirmed(); |
| 866 } | 968 } |
| 969 |
| 970 NotifyRequestsOfConfirmation(OK); |
| 867 } | 971 } |
| 868 QuicSpdySession::OnCryptoHandshakeEvent(event); | 972 QuicSpdySession::OnCryptoHandshakeEvent(event); |
| 869 } | 973 } |
| 870 | 974 |
| 871 void QuicChromiumClientSession::OnCryptoHandshakeMessageSent( | 975 void QuicChromiumClientSession::OnCryptoHandshakeMessageSent( |
| 872 const CryptoHandshakeMessage& message) { | 976 const CryptoHandshakeMessage& message) { |
| 873 logger_->OnCryptoHandshakeMessageSent(message); | 977 logger_->OnCryptoHandshakeMessageSent(message); |
| 874 } | 978 } |
| 875 | 979 |
| 876 void QuicChromiumClientSession::OnCryptoHandshakeMessageReceived( | 980 void QuicChromiumClientSession::OnCryptoHandshakeMessageReceived( |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 999 base::ResetAndReturn(&callback_).Run(ERR_QUIC_PROTOCOL_ERROR); | 1103 base::ResetAndReturn(&callback_).Run(ERR_QUIC_PROTOCOL_ERROR); |
| 1000 } | 1104 } |
| 1001 | 1105 |
| 1002 for (auto& socket : sockets_) { | 1106 for (auto& socket : sockets_) { |
| 1003 socket->Close(); | 1107 socket->Close(); |
| 1004 } | 1108 } |
| 1005 DCHECK(dynamic_streams().empty()); | 1109 DCHECK(dynamic_streams().empty()); |
| 1006 CloseAllStreams(ERR_UNEXPECTED); | 1110 CloseAllStreams(ERR_UNEXPECTED); |
| 1007 CloseAllObservers(ERR_UNEXPECTED); | 1111 CloseAllObservers(ERR_UNEXPECTED); |
| 1008 CancelAllRequests(ERR_CONNECTION_CLOSED); | 1112 CancelAllRequests(ERR_CONNECTION_CLOSED); |
| 1113 NotifyRequestsOfConfirmation(ERR_CONNECTION_CLOSED); |
| 1009 NotifyFactoryOfSessionClosedLater(); | 1114 NotifyFactoryOfSessionClosedLater(); |
| 1010 } | 1115 } |
| 1011 | 1116 |
| 1012 void QuicChromiumClientSession::OnSuccessfulVersionNegotiation( | 1117 void QuicChromiumClientSession::OnSuccessfulVersionNegotiation( |
| 1013 const QuicVersion& version) { | 1118 const QuicVersion& version) { |
| 1014 logger_->OnSuccessfulVersionNegotiation(version); | 1119 logger_->OnSuccessfulVersionNegotiation(version); |
| 1015 QuicSpdySession::OnSuccessfulVersionNegotiation(version); | 1120 QuicSpdySession::OnSuccessfulVersionNegotiation(version); |
| 1016 | 1121 |
| 1017 ObserverSet::iterator it = observers_.begin(); | 1122 ObserverSet::iterator it = observers_.begin(); |
| 1018 while (it != observers_.end()) { | 1123 while (it != observers_.end()) { |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1258 UMA_HISTOGRAM_COUNTS_1000("Net.QuicSession.AbortedPendingStreamRequests", | 1363 UMA_HISTOGRAM_COUNTS_1000("Net.QuicSession.AbortedPendingStreamRequests", |
| 1259 stream_requests_.size()); | 1364 stream_requests_.size()); |
| 1260 | 1365 |
| 1261 while (!stream_requests_.empty()) { | 1366 while (!stream_requests_.empty()) { |
| 1262 StreamRequest* request = stream_requests_.front(); | 1367 StreamRequest* request = stream_requests_.front(); |
| 1263 stream_requests_.pop_front(); | 1368 stream_requests_.pop_front(); |
| 1264 request->OnRequestCompleteFailure(net_error); | 1369 request->OnRequestCompleteFailure(net_error); |
| 1265 } | 1370 } |
| 1266 } | 1371 } |
| 1267 | 1372 |
| 1373 void QuicChromiumClientSession::NotifyRequestsOfConfirmation(int net_error) { |
| 1374 // Post tasks to avoid reentrancy. |
| 1375 for (auto callback : waiting_for_confirmation_callbacks_) |
| 1376 task_runner_->PostTask(FROM_HERE, base::Bind(callback, net_error)); |
| 1377 |
| 1378 waiting_for_confirmation_callbacks_.clear(); |
| 1379 } |
| 1380 |
| 1268 std::unique_ptr<base::Value> QuicChromiumClientSession::GetInfoAsValue( | 1381 std::unique_ptr<base::Value> QuicChromiumClientSession::GetInfoAsValue( |
| 1269 const std::set<HostPortPair>& aliases) { | 1382 const std::set<HostPortPair>& aliases) { |
| 1270 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | 1383 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); |
| 1271 dict->SetString("version", QuicVersionToString(connection()->version())); | 1384 dict->SetString("version", QuicVersionToString(connection()->version())); |
| 1272 dict->SetInteger("open_streams", GetNumOpenOutgoingStreams()); | 1385 dict->SetInteger("open_streams", GetNumOpenOutgoingStreams()); |
| 1273 std::unique_ptr<base::ListValue> stream_list(new base::ListValue()); | 1386 std::unique_ptr<base::ListValue> stream_list(new base::ListValue()); |
| 1274 for (DynamicStreamMap::const_iterator it = dynamic_streams().begin(); | 1387 for (DynamicStreamMap::const_iterator it = dynamic_streams().begin(); |
| 1275 it != dynamic_streams().end(); ++it) { | 1388 it != dynamic_streams().end(); ++it) { |
| 1276 stream_list->AppendString(base::UintToString(it->second->id())); | 1389 stream_list->AppendString(base::UintToString(it->second->id())); |
| 1277 } | 1390 } |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1488 } | 1601 } |
| 1489 | 1602 |
| 1490 size_t QuicChromiumClientSession::EstimateMemoryUsage() const { | 1603 size_t QuicChromiumClientSession::EstimateMemoryUsage() const { |
| 1491 // TODO(xunjieli): Estimate |crypto_stream_|, QuicSpdySession's | 1604 // TODO(xunjieli): Estimate |crypto_stream_|, QuicSpdySession's |
| 1492 // QuicHeaderList, QuicSession's QuiCWriteBlockedList, open streams and | 1605 // QuicHeaderList, QuicSession's QuiCWriteBlockedList, open streams and |
| 1493 // unacked packet map. | 1606 // unacked packet map. |
| 1494 return base::trace_event::EstimateMemoryUsage(packet_readers_); | 1607 return base::trace_event::EstimateMemoryUsage(packet_readers_); |
| 1495 } | 1608 } |
| 1496 | 1609 |
| 1497 } // namespace net | 1610 } // namespace net |
| OLD | NEW |