| 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
|
|
|