Index: net/quic/quic_crypto_client_stream.cc |
diff --git a/net/quic/quic_crypto_client_stream.cc b/net/quic/quic_crypto_client_stream.cc |
index 3e5f84059fc0ec4567c39d1da66a18f7c3f5299c..dfff7451372fed77753e86553002afdc6927e04b 100644 |
--- a/net/quic/quic_crypto_client_stream.cc |
+++ b/net/quic/quic_crypto_client_stream.cc |
@@ -11,6 +11,7 @@ |
#include "net/quic/crypto/null_encrypter.h" |
#include "net/quic/crypto/proof_verifier.h" |
#include "net/quic/crypto/proof_verifier_chromium.h" |
+#include "net/quic/crypto/quic_server_info.h" |
#include "net/quic/quic_protocol.h" |
#include "net/quic/quic_session.h" |
#include "net/ssl/ssl_connection_status_flags.h" |
@@ -91,7 +92,7 @@ void QuicCryptoClientStream::OnHandshakeMessage( |
} |
bool QuicCryptoClientStream::CryptoConnect() { |
- next_state_ = STATE_SEND_CHLO; |
+ next_state_ = STATE_LOAD_QUIC_SERVER_INFO; |
DoHandshakeLoop(NULL); |
return true; |
} |
@@ -159,6 +160,16 @@ void QuicCryptoClientStream::DoHandshakeLoop( |
const State state = next_state_; |
next_state_ = STATE_IDLE; |
switch (state) { |
+ case STATE_LOAD_QUIC_SERVER_INFO: { |
+ if (DoLoadQuicServerInfo(cached) == ERR_IO_PENDING) { |
+ return; |
+ } |
+ break; |
+ } |
+ case STATE_LOAD_QUIC_SERVER_INFO_COMPLETE: { |
+ DoLoadQuicServerInfoComplete(cached); |
+ break; |
+ } |
case STATE_SEND_CHLO: { |
// Send the client hello in plaintext. |
session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_NONE); |
@@ -394,4 +405,88 @@ void QuicCryptoClientStream::DoHandshakeLoop( |
} |
} |
+void QuicCryptoClientStream::OnIOComplete(int result) { |
+ DCHECK_EQ(STATE_LOAD_QUIC_SERVER_INFO_COMPLETE, next_state_); |
+ DCHECK_NE(ERR_IO_PENDING, result); |
+ quic_server_info_data_ready_result_ = result; |
+ DoHandshakeLoop(NULL); |
+} |
+ |
+int QuicCryptoClientStream::DoLoadQuicServerInfo( |
+ QuicCryptoClientConfig::CachedState* cached) { |
+ next_state_ = STATE_SEND_CHLO; |
+ QuicServerInfo* quic_server_info = cached->quic_server_info(); |
+ if (!quic_server_info) { |
+ return OK; |
+ } |
+ |
+ quic_server_info_data_ready_result_ = OK; |
+ generation_counter_ = cached->generation_counter(); |
wtc
2014/02/13 23:48:43
I think we should set next_state_ to STATE_LOAD_QU
ramant (doing other things)
2014/02/15 00:36:12
Done.
|
+ |
+ // We read the QuicServeInfo's data from disk cache only once. |
+ if (cached->quic_server_info()->IsDataReady()) { |
+ next_state_ = STATE_LOAD_QUIC_SERVER_INFO_COMPLETE; |
+ return OK; |
+ } |
+ |
+ // TODO(rtenneti): If multiple tabs load the same URL, all requests except for |
+ // the first request send InchoateClientHello. Fix the code to handle multiple |
+ // requests. A possible solution is to wait for the first request to finish |
+ // and use the data from the disk cache for all requests. |
+ int rv = quic_server_info->WaitForDataReady( |
+ base::Bind(&QuicCryptoClientStream::OnIOComplete, |
+ base::Unretained(this))); |
+ |
+ if (rv != OK) { |
+ if (rv == ERR_IO_PENDING) { |
+ next_state_ = STATE_LOAD_QUIC_SERVER_INFO_COMPLETE; |
+ return rv; |
+ } |
+ // It is ok to proceed to STATE_SEND_CHLO when we cannot load QuicServerInfo |
+ // from the disk cache. |
+ DVLOG(1) << "QuicServerInfo's WaitForDataReady failed"; |
+ } |
+ return OK; |
wtc
2014/02/13 23:48:43
I think lines 440-449 can be replaced by:
if (r
ramant (doing other things)
2014/02/15 00:36:12
Done.
|
+} |
+ |
+void QuicCryptoClientStream::DoLoadQuicServerInfoComplete( |
wtc
2014/02/13 23:48:43
The logic of this method probably should be (omitt
wtc
2014/02/14 01:46:13
void QuicCryptoClientStream::DoLoadQuicServerInfoC
ramant (doing other things)
2014/02/15 00:36:12
Done.
ramant (doing other things)
2014/02/15 00:36:12
As we had talked implemented the second comment.
|
+ QuicCryptoClientConfig::CachedState* cached) { |
+ next_state_ = STATE_SEND_CHLO; |
+ |
+ if (quic_server_info_data_ready_result_ != OK) { |
+ DVLOG(1) << "WaitForDataReady failed result: " |
+ << quic_server_info_data_ready_result_; |
+ return; |
+ } |
+ |
+ // Check if generation_counter has changed between STATE_LOAD_QUIC_SERVER_INFO |
+ // and STATE_LOAD_QUIC_SERVER_INFO_COMPLETE state changes. |
+ if (generation_counter_ != cached->generation_counter()) { |
+ DVLOG(1) << "generation_counter_ has changed: " << generation_counter_ |
+ << " cached's generation_counter_" << cached->generation_counter(); |
+ return; |
+ } |
+ |
+ if (!cached->quic_server_info()->IsDataReady()) { |
+ // It is ok to proceed to STATE_SEND_CHLO when we cannot load QuicServerInfo |
+ // from the disk cache. |
+ DVLOG(1) << "Loading of QuicServerInfo failed"; |
+ return; |
+ } |
+ |
+ cached->LoadQuicServerInfo(); |
+ |
+ if (cached->proof_valid()) { |
+ return; |
+ } |
+ |
+ ProofVerifier* verifier = crypto_config_->proof_verifier(); |
+ if (!verifier) { |
+ // If no verifier is set then we don't check the certificates. |
+ cached->SetProofValid(); |
+ } else if (!cached->signature().empty()) { |
+ next_state_ = STATE_VERIFY_PROOF; |
+ } |
+} |
+ |
} // namespace net |