Index: net/quic/quic_crypto_client_stream.cc |
=================================================================== |
--- net/quic/quic_crypto_client_stream.cc (revision 173961) |
+++ net/quic/quic_crypto_client_stream.cc (working copy) |
@@ -5,8 +5,13 @@ |
#include "net/quic/quic_crypto_client_stream.h" |
#include "net/quic/crypto/crypto_protocol.h" |
+#include "net/quic/crypto/quic_random.h" |
+#include "net/quic/quic_clock.h" |
#include "net/quic/quic_protocol.h" |
+#include "net/quic/quic_session.h" |
+using base::StringPiece; |
+ |
namespace net { |
QuicCryptoClientStream::QuicCryptoClientStream(QuicSession* session) |
@@ -32,4 +37,86 @@ |
return; |
} |
+bool QuicCryptoClientStream::CryptoConnect() { |
+ CryptoHandshakeMessage message; |
+ if (!FillClientHelloMessage(&message)) { |
+ return false; |
+ } |
+ SendHandshakeMessage(message); |
+ return true; |
+} |
+ |
+// Generates the connection nonce. |
+void QuicCryptoClientStream::GenerateNonce() { |
+ // a 4-byte timestamp + 28 random bytes. |
+ nonce_.reserve(kNonceSize); |
+ nonce_.resize(kNonceSize); |
+ QuicTime::Delta now = |
+ session()->connection()->clock()->NowAsDeltaSinceUnixEpoch(); |
+ uint32 gmt_unix_time = now.ToSeconds(); |
+ const size_t time_size = sizeof(gmt_unix_time); |
+ memcpy(&nonce_[0], &gmt_unix_time, time_size); |
+ QuicRandom::GetInstance()->RandBytes(&nonce_[time_size], |
+ kNonceSize - time_size); |
+} |
+ |
+bool QuicCryptoClientStream::FillClientHelloMessage( |
+ CryptoHandshakeMessage* message) { |
+ message->tag = kCHLO; |
+ |
+ StringPiece value; |
+ |
+ // Version must be 0. |
+ version_ = 0; |
+ value.set(&version_, sizeof(version_)); |
+ message->tag_value_map[kVERS] = value.as_string(); |
+ |
+ // Key exchange methods. |
+ key_exchange_.resize(2); |
+ key_exchange_[0] = kC255; |
+ key_exchange_[1] = kP256; |
+ value.set(&key_exchange_[0], |
+ key_exchange_.size() * sizeof(key_exchange_[0])); |
+ message->tag_value_map[kKEXS] = value.as_string(); |
+ |
+ // Authenticated encryption algorithms. |
+ aead_.resize(2); |
+ aead_[0] = kAESG; |
+ aead_[1] = kAESH; |
+ value.set(&aead_[0], aead_.size() * sizeof(aead_[0])); |
+ message->tag_value_map[kAEAD] = value.as_string(); |
+ |
+ // Congestion control feedback types. |
+ congestion_control_.resize(2); |
+ congestion_control_[0] = kQBIC; |
+ congestion_control_[1] = kINAR; |
+ value.set(&congestion_control_[0], |
+ congestion_control_.size() * sizeof(congestion_control_[0])); |
+ message->tag_value_map[kCGST] = value.as_string(); |
+ |
+ // Idle connection state lifetime. |
+ idle_connection_state_lifetime_ = 300; // 300 seconds. |
+ value.set(&idle_connection_state_lifetime_, |
+ sizeof(idle_connection_state_lifetime_)); |
+ message->tag_value_map[kICSL] = value.as_string(); |
+ |
+ // Keepalive timeout. |
+ keepalive_timeout_ = 0; // Don't send keepalive probes. |
+ value.set(&keepalive_timeout_, sizeof(keepalive_timeout_)); |
+ message->tag_value_map[kKATO] = value.as_string(); |
+ |
+ // Connection nonce. |
+ GenerateNonce(); |
+ if (nonce_.empty()) { |
+ return false; |
+ } |
+ message->tag_value_map[kNONC] = nonce_; |
+ |
+ // Server name indication. |
+ // TODO(wtc): if server_hostname_ is a DNS name, store it in |
+ // message->tag_value_map[kSNI]. |
+ |
+ return true; |
+} |
+ |
} // namespace net |