Index: net/quic/quic_client_session.cc |
diff --git a/net/quic/quic_client_session.cc b/net/quic/quic_client_session.cc |
index 00b1411ec9abb1da2d7d590667a13302c2b5bbe9..a24b9b2cca4ed4abce436918d6b651fc6be4d933 100644 |
--- a/net/quic/quic_client_session.cc |
+++ b/net/quic/quic_client_session.cc |
@@ -138,6 +138,7 @@ QuicClientSession::QuicClientSession( |
const QuicConfig& config, |
uint32 max_flow_control_receive_window_bytes, |
QuicCryptoClientConfig* crypto_config, |
+ base::TaskRunner* task_runner, |
NetLog* net_log) |
: QuicClientSessionBase(connection, |
max_flow_control_receive_window_bytes, |
@@ -150,6 +151,7 @@ QuicClientSession::QuicClientSession( |
server_info_(server_info.Pass()), |
read_pending_(false), |
num_total_streams_(0), |
+ task_runner_(task_runner), |
net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_QUIC_SESSION)), |
logger_(net_log_), |
num_packets_read_(0), |
@@ -436,16 +438,39 @@ int QuicClientSession::CryptoConnect(bool require_confirmation, |
return ERR_CONNECTION_FAILED; |
} |
- bool can_notify = require_confirmation_ ? |
- IsCryptoHandshakeConfirmed() : IsEncryptionEstablished(); |
- if (can_notify) { |
+ if (IsCryptoHandshakeConfirmed()) |
+ return OK; |
+ |
+ // Unless we require handshake confirmation, activate the session if |
+ // we have established initial encryption. |
+ if (!require_confirmation_ && IsEncryptionEstablished()) { |
+ // To mitigate the effects of hanging 0-RTT connections, set up a timer to |
+ // cancel any requests, if the handshake takes too long. |
+ task_runner_->PostDelayedTask( |
+ FROM_HERE, |
+ base::Bind(&QuicClientSession::OnConnectTimeout, |
+ weak_factory_.GetWeakPtr()), |
+ base::TimeDelta::FromMilliseconds(300)); |
ramant (doing other things)
2014/06/05 22:27:18
overly nit: wondering if 300ms is long enough for
ramant (doing other things)
2014/06/05 22:33:47
I like this change. Should we do a similar change
Ryan Hamilton
2014/06/05 22:47:51
Possibly. Of course, we're reading the configs fro
Ryan Hamilton
2014/06/05 22:47:51
It's a good question! :> The short answer is that
|
return OK; |
+ |
} |
callback_ = callback; |
return ERR_IO_PENDING; |
} |
+int QuicClientSession::ResumeCryptoConnect(const CompletionCallback& callback) { |
+ |
+ if (IsCryptoHandshakeConfirmed()) |
+ return OK; |
+ |
+ if (!connection()->connected()) |
+ return ERR_QUIC_HANDSHAKE_FAILED; |
+ |
+ callback_ = callback; |
+ return ERR_IO_PENDING; |
+} |
+ |
int QuicClientSession::GetNumSentClientHellos() const { |
return crypto_stream_->num_sent_client_hellos(); |
} |
@@ -800,4 +825,16 @@ void QuicClientSession::NotifyFactoryOfSessionClosed() { |
stream_factory_->OnSessionClosed(this); |
} |
+void QuicClientSession::OnConnectTimeout() { |
+ DCHECK(callback_.is_null()); |
+ DCHECK(IsEncryptionEstablished()); |
+ |
+ if (IsCryptoHandshakeConfirmed()) |
+ return; |
+ |
+ if (stream_factory_) |
+ stream_factory_->OnSessionConnectTimeout(this); |
+ CloseAllStreams(ERR_QUIC_HANDSHAKE_FAILED); |
+} |
+ |
} // namespace net |