diff options
Diffstat (limited to 'net')
82 files changed, 1960 insertions, 963 deletions
diff --git a/net/net.gyp b/net/net.gyp index 085802b..2a9d78a 100644 --- a/net/net.gyp +++ b/net/net.gyp @@ -811,14 +811,16 @@ 'quic/quic_http_stream.h', 'quic/quic_packet_creator.cc', 'quic/quic_packet_creator.h', - 'quic/quic_packet_entropy_manager.cc', - 'quic/quic_packet_entropy_manager.h', 'quic/quic_packet_generator.cc', 'quic/quic_packet_generator.h', 'quic/quic_protocol.cc', 'quic/quic_protocol.h', + 'quic/quic_received_entropy_manager.cc', + 'quic/quic_received_entropy_manager.h', 'quic/quic_reliable_client_stream.cc', 'quic/quic_reliable_client_stream.h', + 'quic/quic_sent_entropy_manager.cc', + 'quic/quic_sent_entropy_manager.h', 'quic/quic_session.cc', 'quic/quic_session.h', 'quic/quic_spdy_compressor.cc', @@ -1737,10 +1739,11 @@ 'quic/quic_http_stream_test.cc', 'quic/quic_network_transaction_unittest.cc', 'quic/quic_packet_creator_test.cc', - 'quic/quic_packet_entropy_manager_test.cc', 'quic/quic_packet_generator_test.cc', 'quic/quic_protocol_test.cc', + 'quic/quic_received_entropy_manager_test.cc', 'quic/quic_reliable_client_stream_test.cc', + 'quic/quic_sent_entropy_manager_test.cc', 'quic/quic_session_test.cc', 'quic/quic_spdy_compressor_test.cc', 'quic/quic_spdy_decompressor_test.cc', diff --git a/net/quic/congestion_control/fix_rate_sender.cc b/net/quic/congestion_control/fix_rate_sender.cc index 5398cc6..cd0923d 100644 --- a/net/quic/congestion_control/fix_rate_sender.cc +++ b/net/quic/congestion_control/fix_rate_sender.cc @@ -46,8 +46,14 @@ void FixRateSender::OnIncomingAck( QuicPacketSequenceNumber /*acked_sequence_number*/, QuicByteCount bytes_acked, QuicTime::Delta rtt) { - latest_rtt_ = rtt; + // RTT can't be negative. + DCHECK_LE(0, rtt.ToMicroseconds()); + data_in_flight_ -= bytes_acked; + if (rtt.IsInfinite()) { + return; + } + latest_rtt_ = rtt; } void FixRateSender::OnIncomingLoss(QuicTime /*ack_receive_time*/) { @@ -105,4 +111,10 @@ QuicTime::Delta FixRateSender::SmoothedRtt() { return latest_rtt_; } +QuicTime::Delta FixRateSender::RetransmissionDelay() { + // TODO(pwestin): Calculate and return retransmission delay. + // Use 2 * the latest RTT for now. + return latest_rtt_.Add(latest_rtt_); +} + } // namespace net diff --git a/net/quic/congestion_control/fix_rate_sender.h b/net/quic/congestion_control/fix_rate_sender.h index 545f2d3..251ab39 100644 --- a/net/quic/congestion_control/fix_rate_sender.h +++ b/net/quic/congestion_control/fix_rate_sender.h @@ -44,6 +44,7 @@ class NET_EXPORT_PRIVATE FixRateSender : public SendAlgorithmInterface { HasRetransmittableData has_retransmittable_data) OVERRIDE; virtual QuicBandwidth BandwidthEstimate() OVERRIDE; virtual QuicTime::Delta SmoothedRtt() OVERRIDE; + virtual QuicTime::Delta RetransmissionDelay() OVERRIDE; // End implementation of SendAlgorithmInterface. private: diff --git a/net/quic/congestion_control/inter_arrival_sender.cc b/net/quic/congestion_control/inter_arrival_sender.cc index c8d2c86..07421ae 100644 --- a/net/quic/congestion_control/inter_arrival_sender.cc +++ b/net/quic/congestion_control/inter_arrival_sender.cc @@ -14,6 +14,8 @@ const float kMaxBitrateReduction = 0.9f; const float kMinBitrateReduction = 0.05f; const uint64 kMinBitrateKbit = 10; const int kInitialRttMs = 60; // At a typical RTT 60 ms. +const float kAlpha = 0.125f; +const float kOneMinusAlpha = 1 - kAlpha; static const int kBitrateSmoothingPeriodMs = 1000; static const int kMinBitrateSmoothingPeriodMs = 500; @@ -200,18 +202,25 @@ void InterArrivalSender::OnIncomingAck( QuicPacketSequenceNumber /*acked_sequence_number*/, QuicByteCount acked_bytes, QuicTime::Delta rtt) { - DCHECK(!rtt.IsZero()); - DCHECK(!rtt.IsInfinite()); + // RTT can't be negative. + DCHECK_LE(0, rtt.ToMicroseconds()); + + if (probing_) { + probe_->OnAcknowledgedPacket(acked_bytes); + } + + if (rtt.IsInfinite()) { + return; + } + if (smoothed_rtt_.IsZero()) { smoothed_rtt_ = rtt; } else { smoothed_rtt_ = QuicTime::Delta::FromMicroseconds( - (smoothed_rtt_.ToMicroseconds() * 3 + rtt.ToMicroseconds()) / 4); - } - state_machine_->set_rtt(SmoothedRtt()); - if (probing_) { - probe_->OnAcknowledgedPacket(acked_bytes); + kOneMinusAlpha * smoothed_rtt_.ToMicroseconds() + + kAlpha * rtt.ToMicroseconds()); } + state_machine_->set_rtt(smoothed_rtt_); } void InterArrivalSender::OnIncomingLoss(QuicTime ack_receive_time) { @@ -305,6 +314,12 @@ QuicTime::Delta InterArrivalSender::SmoothedRtt() { return smoothed_rtt_; } +QuicTime::Delta InterArrivalSender::RetransmissionDelay() { + // TODO(pwestin): Calculate and return retransmission delay. + // Use 2 * the smoothed RTT for now. + return smoothed_rtt_.Add(smoothed_rtt_); +} + void InterArrivalSender::EstimateNewBandwidth(QuicTime feedback_receive_time, QuicBandwidth sent_bandwidth) { QuicBandwidth new_bandwidth = bitrate_ramp_up_->GetNewBitrate(sent_bandwidth); diff --git a/net/quic/congestion_control/inter_arrival_sender.h b/net/quic/congestion_control/inter_arrival_sender.h index 7997d0d..9889c0d 100644 --- a/net/quic/congestion_control/inter_arrival_sender.h +++ b/net/quic/congestion_control/inter_arrival_sender.h @@ -58,6 +58,7 @@ class NET_EXPORT_PRIVATE InterArrivalSender : public SendAlgorithmInterface { virtual QuicBandwidth BandwidthEstimate() OVERRIDE; virtual QuicTime::Delta SmoothedRtt() OVERRIDE; + virtual QuicTime::Delta RetransmissionDelay() OVERRIDE; // End implementation of SendAlgorithmInterface. private: diff --git a/net/quic/congestion_control/quic_congestion_manager.cc b/net/quic/congestion_control/quic_congestion_manager.cc index a6bd0a8..1773c82 100644 --- a/net/quic/congestion_control/quic_congestion_manager.cc +++ b/net/quic/congestion_control/quic_congestion_manager.cc @@ -16,6 +16,11 @@ static const int kBitrateSmoothingPeriodMs = 1000; static const int kHistoryPeriodMs = 5000; static const int kDefaultRetransmissionTimeMs = 500; +// TCP RFC calls for 1 second RTO however Linux differs from this default and +// define the minimum RTO to 200ms, we will use the same until we have data to +// support a higher or lower value. +static const int kMinRetransmissionTimeMs = 200; +static const int kMaxRetransmissionTimeMs = 10000; static const size_t kMaxRetransmissions = 10; static const size_t kTailDropWindowSize = 5; static const size_t kTailDropMaxRetransmissions = 4; @@ -152,18 +157,30 @@ const QuicTime::Delta QuicCongestionManager::DefaultRetransmissionTime() { const QuicTime::Delta QuicCongestionManager::GetRetransmissionDelay( size_t unacked_packets_count, size_t number_retransmissions) { - // TODO(pwestin): This should take the RTT into account instead of a hard - // coded kDefaultRetransmissionTimeMs. Ideally the variance of the RTT too. - if (unacked_packets_count <= kTailDropWindowSize) { - if (number_retransmissions <= kTailDropMaxRetransmissions) { - return QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs); + QuicTime::Delta retransmission_delay = send_algorithm_->RetransmissionDelay(); + if (retransmission_delay.IsZero()) { + // We are in the initial state, use default timeout values. + if (unacked_packets_count <= kTailDropWindowSize) { + if (number_retransmissions <= kTailDropMaxRetransmissions) { + return QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs); + } + number_retransmissions -= kTailDropMaxRetransmissions; } - number_retransmissions -= kTailDropMaxRetransmissions; + retransmission_delay = + QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs); } + // Calcluate exponential back off. + retransmission_delay = QuicTime::Delta::FromMilliseconds( + retransmission_delay.ToMilliseconds() * static_cast<size_t>( + (1 << min<size_t>(number_retransmissions, kMaxRetransmissions)))); - return QuicTime::Delta::FromMilliseconds( - kDefaultRetransmissionTimeMs * - (1 << min<size_t>(number_retransmissions, kMaxRetransmissions))); + if (retransmission_delay.ToMilliseconds() < kMinRetransmissionTimeMs) { + return QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs); + } + if (retransmission_delay.ToMilliseconds() > kMaxRetransmissionTimeMs) { + return QuicTime::Delta::FromMilliseconds(kMaxRetransmissionTimeMs); + } + return retransmission_delay; } const QuicTime::Delta QuicCongestionManager::SmoothedRtt() { diff --git a/net/quic/congestion_control/send_algorithm_interface.h b/net/quic/congestion_control/send_algorithm_interface.h index f2c4e7b..440201c 100644 --- a/net/quic/congestion_control/send_algorithm_interface.h +++ b/net/quic/congestion_control/send_algorithm_interface.h @@ -77,6 +77,11 @@ class NET_EXPORT_PRIVATE SendAlgorithmInterface { // TODO(satyamshekhar): Monitor MinRtt. virtual QuicTime::Delta SmoothedRtt() = 0; + + // Get the send algorithm specific retransmission delay, called RTO in TCP, + // Note 1: the caller is responsible for sanity checking this value. + // Note 2: this will return zero if we don't have enough data for an estimate. + virtual QuicTime::Delta RetransmissionDelay() = 0; }; } // namespace net diff --git a/net/quic/congestion_control/tcp_cubic_sender.cc b/net/quic/congestion_control/tcp_cubic_sender.cc index e71b8c2..73c05da 100644 --- a/net/quic/congestion_control/tcp_cubic_sender.cc +++ b/net/quic/congestion_control/tcp_cubic_sender.cc @@ -15,7 +15,11 @@ const int64 kInitialCongestionWindow = 10; const int64 kMaxCongestionWindow = 10000; const int kMaxBurstLength = 3; const int kInitialRttMs = 60; // At a typical RTT 60 ms. -}; +const float kAlpha = 0.125f; +const float kOneMinusAlpha = (1 - kAlpha); +const float kBeta = 0.25f; +const float kOneMinusBeta = (1 - kBeta); +}; // namespace TcpCubicSender::TcpCubicSender(const QuicClock* clock, bool reno) : hybrid_slow_start_(clock), @@ -29,7 +33,12 @@ TcpCubicSender::TcpCubicSender(const QuicClock* clock, bool reno) end_sequence_number_(0), congestion_window_(kInitialCongestionWindow), slowstart_threshold_(kMaxCongestionWindow), - delay_min_(QuicTime::Delta::Zero()) { + delay_min_(QuicTime::Delta::Zero()), + smoothed_rtt_(QuicTime::Delta::Zero()), + mean_deviation_(QuicTime::Delta::Zero()) { +} + +TcpCubicSender::~TcpCubicSender() { } void TcpCubicSender::OnIncomingQuicCongestionFeedbackFrame( @@ -136,11 +145,15 @@ QuicBandwidth TcpCubicSender::BandwidthEstimate() { } QuicTime::Delta TcpCubicSender::SmoothedRtt() { - // TODO(satyamshekhar): Return the smoothed averaged RTT. - if (delay_min_.IsZero()) { + if (smoothed_rtt_.IsZero()) { return QuicTime::Delta::FromMilliseconds(kInitialRttMs); } - return delay_min_; + return smoothed_rtt_; +} + +QuicTime::Delta TcpCubicSender::RetransmissionDelay() { + return QuicTime::Delta::FromMicroseconds( + smoothed_rtt_.ToMicroseconds() + 4 * mean_deviation_.ToMicroseconds()); } void TcpCubicSender::Reset() { @@ -218,6 +231,21 @@ void TcpCubicSender::AckAccounting(QuicTime::Delta rtt) { if (delay_min_.IsZero() || delay_min_ > rtt) { delay_min_ = rtt; } + // First time call. + if (smoothed_rtt_.IsZero()) { + smoothed_rtt_ = rtt; + mean_deviation_ = QuicTime::Delta::FromMicroseconds( + rtt.ToMicroseconds() / 2); + } else { + mean_deviation_ = QuicTime::Delta::FromMicroseconds( + kOneMinusBeta * mean_deviation_.ToMicroseconds() + + kBeta * abs(smoothed_rtt_.ToMicroseconds() - rtt.ToMicroseconds())); + smoothed_rtt_ = QuicTime::Delta::FromMicroseconds( + kOneMinusAlpha * smoothed_rtt_.ToMicroseconds() + + kAlpha * rtt.ToMicroseconds()); + DLOG(INFO) << "Cubic; mean_deviation_:" << mean_deviation_.ToMicroseconds(); + } + // Hybrid start triggers when cwnd is larger than some threshold. if (congestion_window_ <= slowstart_threshold_ && congestion_window_ >= kHybridStartLowWindow) { diff --git a/net/quic/congestion_control/tcp_cubic_sender.h b/net/quic/congestion_control/tcp_cubic_sender.h index 0b7e948..1774023 100644 --- a/net/quic/congestion_control/tcp_cubic_sender.h +++ b/net/quic/congestion_control/tcp_cubic_sender.h @@ -28,6 +28,7 @@ class NET_EXPORT_PRIVATE TcpCubicSender : public SendAlgorithmInterface { public: // Reno option provided for testing. TcpCubicSender(const QuicClock* clock, bool reno); + virtual ~TcpCubicSender(); // Start implementation of SendAlgorithmInterface. virtual void OnIncomingQuicCongestionFeedbackFrame( @@ -50,6 +51,7 @@ class NET_EXPORT_PRIVATE TcpCubicSender : public SendAlgorithmInterface { HasRetransmittableData has_retransmittable_data) OVERRIDE; virtual QuicBandwidth BandwidthEstimate() OVERRIDE; virtual QuicTime::Delta SmoothedRtt() OVERRIDE; + virtual QuicTime::Delta RetransmissionDelay() OVERRIDE; // End implementation of SendAlgorithmInterface. private: @@ -94,6 +96,14 @@ class NET_EXPORT_PRIVATE TcpCubicSender : public SendAlgorithmInterface { // Min RTT during this session. QuicTime::Delta delay_min_; + // Smoothed RTT during this session. + QuicTime::Delta smoothed_rtt_; + + // Mean RTT deviation during this session. + // Approximation of standard deviation, the error is roughly 1.25 times + // larger than the standard deviation, for a normally distributed signal. + QuicTime::Delta mean_deviation_; + DISALLOW_COPY_AND_ASSIGN(TcpCubicSender); }; diff --git a/net/quic/congestion_control/tcp_cubic_sender_test.cc b/net/quic/congestion_control/tcp_cubic_sender_test.cc index a9e468f..68a8d6b 100644 --- a/net/quic/congestion_control/tcp_cubic_sender_test.cc +++ b/net/quic/congestion_control/tcp_cubic_sender_test.cc @@ -17,11 +17,12 @@ const QuicByteCount kNoNBytesInFlight = 0; class TcpCubicSenderPeer : public TcpCubicSender { public: - explicit TcpCubicSenderPeer(const QuicClock* clock, bool reno) + TcpCubicSenderPeer(const QuicClock* clock, bool reno) : TcpCubicSender(clock, reno) { } using TcpCubicSender::AvailableCongestionWindow; using TcpCubicSender::CongestionWindow; + using TcpCubicSender::AckAccounting; }; class TcpCubicSenderTest : public ::testing::Test { @@ -221,5 +222,33 @@ TEST_F(TcpCubicSenderTest, SlowStartPacketLoss) { EXPECT_EQ(expected_congestion_window, sender_->CongestionWindow()); } +TEST_F(TcpCubicSenderTest, RetransmissionDelay) { + const int64 kRttMs = 10; + const int64 kDeviationMs = 3; + EXPECT_EQ(QuicTime::Delta::Zero(), sender_->RetransmissionDelay()); + + sender_->AckAccounting(QuicTime::Delta::FromMilliseconds(kRttMs)); + + // Initial value is to set the median deviation to half of the initial + // rtt, the median in then multiplied by a factor of 4 and finaly the + // smoothed rtt is added which is the inital rtt. + QuicTime::Delta expected_delay = + QuicTime::Delta::FromMilliseconds(kRttMs + kRttMs / 2 * 4); + EXPECT_EQ(expected_delay, sender_->RetransmissionDelay()); + + for (int i = 0; i < 100; ++i) { + // Run to make sure that we converge. + sender_->AckAccounting( + QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs)); + sender_->AckAccounting( + QuicTime::Delta::FromMilliseconds(kRttMs - kDeviationMs)); + } + expected_delay = QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs * 4); + + EXPECT_NEAR(kRttMs, sender_->SmoothedRtt().ToMilliseconds(), 1); + EXPECT_NEAR(expected_delay.ToMilliseconds(), + sender_->RetransmissionDelay().ToMilliseconds(), + 1); +} } // namespace test } // namespace net diff --git a/net/quic/crypto/aes_128_gcm_12_encrypter.h b/net/quic/crypto/aes_128_gcm_12_encrypter.h index ca9a2b1..451f84d 100644 --- a/net/quic/crypto/aes_128_gcm_12_encrypter.h +++ b/net/quic/crypto/aes_128_gcm_12_encrypter.h @@ -61,6 +61,8 @@ class NET_EXPORT_PRIVATE Aes128Gcm12Encrypter : public QuicEncrypter { unsigned char key_[16]; // The nonce prefix. unsigned char nonce_prefix_[4]; + // last_seq_num_ is the last sequence number observed. + QuicPacketSequenceNumber last_seq_num_; #if defined(USE_OPENSSL) ScopedEVPCipherCtx ctx_; diff --git a/net/quic/crypto/aes_128_gcm_12_encrypter_nss.cc b/net/quic/crypto/aes_128_gcm_12_encrypter_nss.cc index 4729ef8..1cd3540 100644 --- a/net/quic/crypto/aes_128_gcm_12_encrypter_nss.cc +++ b/net/quic/crypto/aes_128_gcm_12_encrypter_nss.cc @@ -250,7 +250,7 @@ SECStatus My_Encrypt(PK11SymKey* key, } // namespace -Aes128Gcm12Encrypter::Aes128Gcm12Encrypter() { +Aes128Gcm12Encrypter::Aes128Gcm12Encrypter() : last_seq_num_(0) { ignore_result(g_gcm_support_checker.Get()); } @@ -350,6 +350,12 @@ QuicData* Aes128Gcm12Encrypter::EncryptPacket( size_t ciphertext_size = GetCiphertextSize(plaintext.length()); scoped_ptr<char[]> ciphertext(new char[ciphertext_size]); + if (last_seq_num_ != 0 && sequence_number <= last_seq_num_) { + DLOG(FATAL) << "Sequence numbers regressed"; + return NULL; + } + last_seq_num_ = sequence_number; + uint8 nonce[kNoncePrefixSize + sizeof(sequence_number)]; COMPILE_ASSERT(sizeof(nonce) == kAESNonceSize, bad_sequence_number_size); memcpy(nonce, nonce_prefix_, kNoncePrefixSize); diff --git a/net/quic/crypto/aes_128_gcm_12_encrypter_openssl.cc b/net/quic/crypto/aes_128_gcm_12_encrypter_openssl.cc index c32efcf..79d0ec1 100644 --- a/net/quic/crypto/aes_128_gcm_12_encrypter_openssl.cc +++ b/net/quic/crypto/aes_128_gcm_12_encrypter_openssl.cc @@ -21,7 +21,7 @@ const size_t kAESNonceSize = 12; } // namespace -Aes128Gcm12Encrypter::Aes128Gcm12Encrypter() {} +Aes128Gcm12Encrypter::Aes128Gcm12Encrypter() : last_seq_num_(0) {} Aes128Gcm12Encrypter::~Aes128Gcm12Encrypter() {} @@ -118,6 +118,12 @@ QuicData* Aes128Gcm12Encrypter::EncryptPacket( size_t ciphertext_size = GetCiphertextSize(plaintext.length()); scoped_ptr<char[]> ciphertext(new char[ciphertext_size]); + if (last_seq_num_ != 0 && sequence_number <= last_seq_num_) { + DLOG(FATAL) << "Sequence numbers regressed"; + return NULL; + } + last_seq_num_ = sequence_number; + uint8 nonce[kNoncePrefixSize + sizeof(sequence_number)]; COMPILE_ASSERT(sizeof(nonce) == kAESNonceSize, bad_sequence_number_size); memcpy(nonce, nonce_prefix_, kNoncePrefixSize); diff --git a/net/quic/crypto/common_cert_set_0.c b/net/quic/crypto/common_cert_set_0.c index d89548a..1133733 100644 --- a/net/quic/crypto/common_cert_set_0.c +++ b/net/quic/crypto/common_cert_set_0.c @@ -9,7 +9,7 @@ #include "net/quic/crypto/common_cert_set_1_50.inc" #include "net/quic/crypto/common_cert_set_51_100.inc" -static const size_t kNumCerts = 101; +static const size_t kNumCerts = 102; static const unsigned char* const kCerts[] = { kDERCert0, kDERCert1, @@ -112,6 +112,7 @@ static const unsigned char* const kCerts[] = { kDERCert98, kDERCert99, kDERCert100, + kDERCert101, }; static const size_t kLens[] = { @@ -125,6 +126,7 @@ static const size_t kLens[] = { 985, 989, 1022, + 1032, 1049, 1055, 1071, @@ -218,4 +220,4 @@ static const size_t kLens[] = { 1770, }; -static const uint64 kHash = GG_UINT64_C(0xde8086f914a3af54); +static const uint64 kHash = GG_UINT64_C(0xc9fef74053f99f39); diff --git a/net/quic/crypto/common_cert_set_1_50.inc b/net/quic/crypto/common_cert_set_1_50.inc index c151f1e..5ee471b 100644 --- a/net/quic/crypto/common_cert_set_1_50.inc +++ b/net/quic/crypto/common_cert_set_1_50.inc @@ -1641,6 +1641,191 @@ static const unsigned char kDERCert9[] = { Certificate: Data: Version: 3 (0x2) + Serial Number: 146025 (0x23a69) + Signature Algorithm: sha1WithRSAEncryption + Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA + Validity + Not Before: Apr 5 15:15:55 2013 GMT + Not After : Apr 4 15:15:55 2015 GMT + Subject: C=US, O=Google Inc, CN=Google Internet Authority G2 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:9c:2a:04:77:5c:d8:50:91:3a:06:a3:82:e0:d8: + 50:48:bc:89:3f:f1:19:70:1a:88:46:7e:e0:8f:c5: + f1:89:ce:21:ee:5a:fe:61:0d:b7:32:44:89:a0:74: + 0b:53:4f:55:a4:ce:82:62:95:ee:eb:59:5f:c6:e1: + 05:80:12:c4:5e:94:3f:bc:5b:48:38:f4:53:f7:24: + e6:fb:91:e9:15:c4:cf:f4:53:0d:f4:4a:fc:9f:54: + de:7d:be:a0:6b:6f:87:c0:d0:50:1f:28:30:03:40: + da:08:73:51:6c:7f:ff:3a:3c:a7:37:06:8e:bd:4b: + 11:04:eb:7d:24:de:e6:f9:fc:31:71:fb:94:d5:60: + f3:2e:4a:af:42:d2:cb:ea:c4:6a:1a:b2:cc:53:dd: + 15:4b:8b:1f:c8:19:61:1f:cd:9d:a8:3e:63:2b:84: + 35:69:65:84:c8:19:c5:46:22:f8:53:95:be:e3:80: + 4a:10:c6:2a:ec:ba:97:20:11:c7:39:99:10:04:a0: + f0:61:7a:95:25:8c:4e:52:75:e2:b6:ed:08:ca:14: + fc:ce:22:6a:b3:4e:cf:46:03:97:97:03:7e:c0:b1: + de:7b:af:45:33:cf:ba:3e:71:b7:de:f4:25:25:c2: + 0d:35:89:9d:9d:fb:0e:11:79:89:1e:37:c5:af:8e: + 72:69 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Authority Key Identifier: + keyid:C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E + + X509v3 Subject Key Identifier: + 4A:DD:06:16:1B:BC:F6:68:B5:76:F5:81:B6:BB:62:1A:BA:5A:81:2F + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:0 + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl.geotrust.com/crls/gtglobal.crl + + Authority Information Access: + OCSP - URI:http://gtglobal-ocsp.geotrust.com + + X509v3 Certificate Policies: + Policy: 1.3.6.1.4.1.11129.2.5.1 + + Signature Algorithm: sha1WithRSAEncryption + 36:d7:06:80:11:27:ad:2a:14:9b:38:77:b3:23:a0:75:58:bb: + b1:7e:83:42:ba:72:da:1e:d8:8e:36:06:97:e0:f0:95:3b:37: + fd:1b:42:58:fe:22:c8:6b:bd:38:5e:d1:3b:25:6e:12:eb:5e: + 67:76:46:40:90:da:14:c8:78:0d:ed:95:66:da:8e:86:6f:80: + a1:ba:56:32:95:86:dc:dc:6a:ca:04:8c:5b:7f:f6:bf:cc:6f: + 85:03:58:c3:68:51:13:cd:fd:c8:f7:79:3d:99:35:f0:56:a3: + bd:e0:59:ed:4f:44:09:a3:9e:38:7a:f6:46:d1:1d:12:9d:4f: + be:d0:40:fc:55:fe:06:5e:3c:da:1c:56:bd:96:51:7b:6f:57: + 2a:db:a2:aa:96:dc:8c:74:c2:95:be:f0:6e:95:13:ff:17:f0: + 3c:ac:b2:10:8d:cc:73:fb:e8:8f:02:c6:f0:fb:33:b3:95:3b: + e3:c2:cb:68:58:73:db:a8:24:62:3b:06:35:9d:0d:a9:33:bd: + 78:03:90:2e:4c:78:5d:50:3a:81:d4:ee:a0:c8:70:38:dc:b2: + f9:67:fa:87:40:5d:61:c0:51:8f:6b:83:6b:cd:05:3a:ca:e1: + a7:05:78:fc:ca:da:94:d0:2c:08:3d:7e:16:79:c8:a0:50:20: + 24:54:33:71 +-----BEGIN CERTIFICATE----- +MIIEBDCCAuygAwIBAgIDAjppMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT +MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i +YWwgQ0EwHhcNMTMwNDA1MTUxNTU1WhcNMTUwNDA0MTUxNTU1WjBJMQswCQYDVQQG +EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy +bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP +VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv +h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE +ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ +EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC +DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB+zCB+DAfBgNVHSMEGDAWgBTAephojYn7 +qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wEgYD +VR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMwMTAvoC2g +K4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9ndGdsb2JhbC5jcmwwPQYI +KwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwOi8vZ3RnbG9iYWwtb2NzcC5n +ZW90cnVzdC5jb20wFwYDVR0gBBAwDjAMBgorBgEEAdZ5AgUBMA0GCSqGSIb3DQEB +BQUAA4IBAQA21waAESetKhSbOHezI6B1WLuxfoNCunLaHtiONgaX4PCVOzf9G0JY +/iLIa704XtE7JW4S615ndkZAkNoUyHgN7ZVm2o6Gb4ChulYylYbc3GrKBIxbf/a/ +zG+FA1jDaFETzf3I93k9mTXwVqO94FntT0QJo544evZG0R0SnU++0ED8Vf4GXjza +HFa9llF7b1cq26KqltyMdMKVvvBulRP/F/A8rLIQjcxz++iPAsbw+zOzlTvjwsto +WHPbqCRiOwY1nQ2pM714A5AuTHhdUDqB1O6gyHA43LL5Z/qHQF1hwFGPa4NrzQU6 +yuGnBXj8ytqU0CwIPX4WecigUCAkVDNx +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert10[] = { + 0x30, 0x82, 0x04, 0x04, 0x30, 0x82, 0x02, 0xec, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x03, 0x02, 0x3a, 0x69, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x42, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, + 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47, + 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, + 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47, + 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62, + 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x30, + 0x34, 0x30, 0x35, 0x31, 0x35, 0x31, 0x35, 0x35, 0x35, 0x5a, 0x17, 0x0d, + 0x31, 0x35, 0x30, 0x34, 0x30, 0x34, 0x31, 0x35, 0x31, 0x35, 0x35, 0x35, + 0x5a, 0x30, 0x49, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x0a, 0x13, 0x0a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x49, 0x6e, + 0x63, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1c, + 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, + 0x6e, 0x65, 0x74, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x47, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, + 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, + 0x00, 0x9c, 0x2a, 0x04, 0x77, 0x5c, 0xd8, 0x50, 0x91, 0x3a, 0x06, 0xa3, + 0x82, 0xe0, 0xd8, 0x50, 0x48, 0xbc, 0x89, 0x3f, 0xf1, 0x19, 0x70, 0x1a, + 0x88, 0x46, 0x7e, 0xe0, 0x8f, 0xc5, 0xf1, 0x89, 0xce, 0x21, 0xee, 0x5a, + 0xfe, 0x61, 0x0d, 0xb7, 0x32, 0x44, 0x89, 0xa0, 0x74, 0x0b, 0x53, 0x4f, + 0x55, 0xa4, 0xce, 0x82, 0x62, 0x95, 0xee, 0xeb, 0x59, 0x5f, 0xc6, 0xe1, + 0x05, 0x80, 0x12, 0xc4, 0x5e, 0x94, 0x3f, 0xbc, 0x5b, 0x48, 0x38, 0xf4, + 0x53, 0xf7, 0x24, 0xe6, 0xfb, 0x91, 0xe9, 0x15, 0xc4, 0xcf, 0xf4, 0x53, + 0x0d, 0xf4, 0x4a, 0xfc, 0x9f, 0x54, 0xde, 0x7d, 0xbe, 0xa0, 0x6b, 0x6f, + 0x87, 0xc0, 0xd0, 0x50, 0x1f, 0x28, 0x30, 0x03, 0x40, 0xda, 0x08, 0x73, + 0x51, 0x6c, 0x7f, 0xff, 0x3a, 0x3c, 0xa7, 0x37, 0x06, 0x8e, 0xbd, 0x4b, + 0x11, 0x04, 0xeb, 0x7d, 0x24, 0xde, 0xe6, 0xf9, 0xfc, 0x31, 0x71, 0xfb, + 0x94, 0xd5, 0x60, 0xf3, 0x2e, 0x4a, 0xaf, 0x42, 0xd2, 0xcb, 0xea, 0xc4, + 0x6a, 0x1a, 0xb2, 0xcc, 0x53, 0xdd, 0x15, 0x4b, 0x8b, 0x1f, 0xc8, 0x19, + 0x61, 0x1f, 0xcd, 0x9d, 0xa8, 0x3e, 0x63, 0x2b, 0x84, 0x35, 0x69, 0x65, + 0x84, 0xc8, 0x19, 0xc5, 0x46, 0x22, 0xf8, 0x53, 0x95, 0xbe, 0xe3, 0x80, + 0x4a, 0x10, 0xc6, 0x2a, 0xec, 0xba, 0x97, 0x20, 0x11, 0xc7, 0x39, 0x99, + 0x10, 0x04, 0xa0, 0xf0, 0x61, 0x7a, 0x95, 0x25, 0x8c, 0x4e, 0x52, 0x75, + 0xe2, 0xb6, 0xed, 0x08, 0xca, 0x14, 0xfc, 0xce, 0x22, 0x6a, 0xb3, 0x4e, + 0xcf, 0x46, 0x03, 0x97, 0x97, 0x03, 0x7e, 0xc0, 0xb1, 0xde, 0x7b, 0xaf, + 0x45, 0x33, 0xcf, 0xba, 0x3e, 0x71, 0xb7, 0xde, 0xf4, 0x25, 0x25, 0xc2, + 0x0d, 0x35, 0x89, 0x9d, 0x9d, 0xfb, 0x0e, 0x11, 0x79, 0x89, 0x1e, 0x37, + 0xc5, 0xaf, 0x8e, 0x72, 0x69, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, + 0xfb, 0x30, 0x81, 0xf8, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, + 0x18, 0x30, 0x16, 0x80, 0x14, 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb, + 0xab, 0x05, 0x64, 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc, + 0x4e, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, + 0x4a, 0xdd, 0x06, 0x16, 0x1b, 0xbc, 0xf6, 0x68, 0xb5, 0x76, 0xf5, 0x81, + 0xb6, 0xbb, 0x62, 0x1a, 0xba, 0x5a, 0x81, 0x2f, 0x30, 0x12, 0x06, 0x03, + 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, + 0xff, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, + 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x3a, 0x06, 0x03, + 0x55, 0x1d, 0x1f, 0x04, 0x33, 0x30, 0x31, 0x30, 0x2f, 0xa0, 0x2d, 0xa0, + 0x2b, 0x86, 0x29, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, + 0x6c, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73, 0x2f, 0x67, 0x74, 0x67, 0x6c, + 0x6f, 0x62, 0x61, 0x6c, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x3d, 0x06, 0x08, + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x31, 0x30, 0x2f, + 0x30, 0x2d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, + 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x74, 0x67, + 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x2d, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, + 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, + 0x17, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x10, 0x30, 0x0e, 0x30, 0x0c, + 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6, 0x79, 0x02, 0x05, 0x01, + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x36, 0xd7, 0x06, 0x80, + 0x11, 0x27, 0xad, 0x2a, 0x14, 0x9b, 0x38, 0x77, 0xb3, 0x23, 0xa0, 0x75, + 0x58, 0xbb, 0xb1, 0x7e, 0x83, 0x42, 0xba, 0x72, 0xda, 0x1e, 0xd8, 0x8e, + 0x36, 0x06, 0x97, 0xe0, 0xf0, 0x95, 0x3b, 0x37, 0xfd, 0x1b, 0x42, 0x58, + 0xfe, 0x22, 0xc8, 0x6b, 0xbd, 0x38, 0x5e, 0xd1, 0x3b, 0x25, 0x6e, 0x12, + 0xeb, 0x5e, 0x67, 0x76, 0x46, 0x40, 0x90, 0xda, 0x14, 0xc8, 0x78, 0x0d, + 0xed, 0x95, 0x66, 0xda, 0x8e, 0x86, 0x6f, 0x80, 0xa1, 0xba, 0x56, 0x32, + 0x95, 0x86, 0xdc, 0xdc, 0x6a, 0xca, 0x04, 0x8c, 0x5b, 0x7f, 0xf6, 0xbf, + 0xcc, 0x6f, 0x85, 0x03, 0x58, 0xc3, 0x68, 0x51, 0x13, 0xcd, 0xfd, 0xc8, + 0xf7, 0x79, 0x3d, 0x99, 0x35, 0xf0, 0x56, 0xa3, 0xbd, 0xe0, 0x59, 0xed, + 0x4f, 0x44, 0x09, 0xa3, 0x9e, 0x38, 0x7a, 0xf6, 0x46, 0xd1, 0x1d, 0x12, + 0x9d, 0x4f, 0xbe, 0xd0, 0x40, 0xfc, 0x55, 0xfe, 0x06, 0x5e, 0x3c, 0xda, + 0x1c, 0x56, 0xbd, 0x96, 0x51, 0x7b, 0x6f, 0x57, 0x2a, 0xdb, 0xa2, 0xaa, + 0x96, 0xdc, 0x8c, 0x74, 0xc2, 0x95, 0xbe, 0xf0, 0x6e, 0x95, 0x13, 0xff, + 0x17, 0xf0, 0x3c, 0xac, 0xb2, 0x10, 0x8d, 0xcc, 0x73, 0xfb, 0xe8, 0x8f, + 0x02, 0xc6, 0xf0, 0xfb, 0x33, 0xb3, 0x95, 0x3b, 0xe3, 0xc2, 0xcb, 0x68, + 0x58, 0x73, 0xdb, 0xa8, 0x24, 0x62, 0x3b, 0x06, 0x35, 0x9d, 0x0d, 0xa9, + 0x33, 0xbd, 0x78, 0x03, 0x90, 0x2e, 0x4c, 0x78, 0x5d, 0x50, 0x3a, 0x81, + 0xd4, 0xee, 0xa0, 0xc8, 0x70, 0x38, 0xdc, 0xb2, 0xf9, 0x67, 0xfa, 0x87, + 0x40, 0x5d, 0x61, 0xc0, 0x51, 0x8f, 0x6b, 0x83, 0x6b, 0xcd, 0x05, 0x3a, + 0xca, 0xe1, 0xa7, 0x05, 0x78, 0xfc, 0xca, 0xda, 0x94, 0xd0, 0x2c, 0x08, + 0x3d, 0x7e, 0x16, 0x79, 0xc8, 0xa0, 0x50, 0x20, 0x24, 0x54, 0x33, 0x71, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) Serial Number: 120033005 (0x7278eed) Signature Algorithm: sha1WithRSAEncryption Issuer: C=US, O=GTE Corporation, OU=GTE CyberTrust Solutions, Inc., CN=GTE CyberTrust Global Root @@ -1723,7 +1908,7 @@ rnO2ufsU/V9tuFC2xIrWQH7Xw8tz3MldW6+wQbU36+rcIJHENGr0ofOWnTeGl+Fx pN19+kSElK7XCQQidg9kUTWpJA/5C9sy2sL+wbkqXHonE8qxSDpx0EM= -----END CERTIFICATE----- #endif -static const unsigned char kDERCert10[] = { +static const unsigned char kDERCert11[] = { 0x30, 0x82, 0x04, 0x15, 0x30, 0x82, 0x03, 0x7e, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x04, 0x07, 0x27, 0x8e, 0xed, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x75, @@ -1908,7 +2093,7 @@ VQ/4FgdxBddlnNcbPDTmRBY6vdhgk4ODDIiWZTNA32qs//6UUWG7iT/3rMTks0fi /aJqMoPifm/wEo6jZnZAl/sR4fdzH9qLHDFCi58RxUmlYO1IKwWEFasviixRcsA= -----END CERTIFICATE----- #endif -static const unsigned char kDERCert11[] = { +static const unsigned char kDERCert12[] = { 0x30, 0x82, 0x04, 0x1b, 0x30, 0x82, 0x03, 0x03, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x04, 0x07, 0x27, 0x37, 0x0c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x5a, @@ -2094,7 +2279,7 @@ n85RdEhsrLXRomr6B0Te0NupjRgf8bnF6Crruj07GIzADDCzySEcM0w6SVPUqLq6 OCM9OmWCXnlxFfglK30Z -----END CERTIFICATE----- #endif -static const unsigned char kDERCert12[] = { +static const unsigned char kDERCert13[] = { 0x30, 0x82, 0x04, 0x2b, 0x30, 0x82, 0x03, 0x13, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x07, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x63, 0x31, 0x0b, 0x30, @@ -2285,7 +2470,7 @@ K2V8eROoPpEU3IgFCNdvU/YVQ+7FU1YaArWmokaNHhPkZ8JFX0BeEEJYtc1Eo5RM HFSQTZGaJoutooBQjRQU -----END CERTIFICATE----- #endif -static const unsigned char kDERCert13[] = { +static const unsigned char kDERCert14[] = { 0x30, 0x82, 0x04, 0x2b, 0x30, 0x82, 0x03, 0x13, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x12, 0x11, 0x20, 0x96, 0xf6, 0xc8, 0x03, 0x7c, 0x9e, 0x07, 0xb1, 0x38, 0xbf, 0x2e, 0x72, 0x10, 0x8a, 0xd7, 0xed, 0x30, 0x0d, 0x06, @@ -2468,7 +2653,7 @@ EcDI457j1sVP9//D7zaKaKqyUJKrWZ3qWycfFqk8RV/rpSpdVimNOhQNEnRxvtar l96Sh2EhiHtBRj38PU/QVFs= -----END CERTIFICATE----- #endif -static const unsigned char kDERCert14[] = { +static const unsigned char kDERCert15[] = { 0x30, 0x82, 0x04, 0x2d, 0x30, 0x82, 0x03, 0x96, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x04, 0x46, 0x9f, 0x18, 0x2b, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, @@ -2660,7 +2845,7 @@ OGoICNdTHC2Tr8kTe9RsxDrE+4CsuzpOVHrNTrM+7fH8EU6f9fMUvLmxMc72qi+l +MPpZqmyIJ3E+LgDYqeF0RhjWw== -----END CERTIFICATE----- #endif -static const unsigned char kDERCert15[] = { +static const unsigned char kDERCert16[] = { 0x30, 0x82, 0x04, 0x2f, 0x30, 0x82, 0x03, 0x17, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x2f, 0x4e, 0xe1, 0x37, 0x02, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, @@ -2853,7 +3038,7 @@ x05b2jZUoUl59koGCuMB6v5Icws9nLgogfC0pchimhEozRjRByPSuu4U24dk7Suq fxq9CncU1dXMMRKi7wajF8HgGKvHUw== -----END CERTIFICATE----- #endif -static const unsigned char kDERCert16[] = { +static const unsigned char kDERCert17[] = { 0x30, 0x82, 0x04, 0x32, 0x30, 0x82, 0x03, 0x1a, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x1e, 0x44, 0xa5, 0xf1, 0x71, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, @@ -3041,7 +3226,7 @@ uHRfx+zADq3Yw8+f0jAOXFEfPhniwdKpkA/mV7mvBHai8ggEJQo1u3MEMdCYRn82 wWEWo4qMmd4QBfLe7aUJZJeEj0KoeyLE -----END CERTIFICATE----- #endif -static const unsigned char kDERCert17[] = { +static const unsigned char kDERCert18[] = { 0x30, 0x82, 0x04, 0x34, 0x30, 0x82, 0x03, 0x1c, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x04, 0x07, 0x27, 0x5c, 0x26, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x5a, @@ -3229,7 +3414,7 @@ gJqXiVRA5iXFHo6vf6EQvzcTBR2K0EIY+Lv5ZKgFVgb6J3EPXHmQ/1pDoqe3bGhk ipQl7r5/eycMkkuZxTM9k+BicSmByyZ6p8g= -----END CERTIFICATE----- #endif -static const unsigned char kDERCert18[] = { +static const unsigned char kDERCert19[] = { 0x30, 0x82, 0x04, 0x36, 0x30, 0x82, 0x03, 0x1e, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x04, 0x12, 0xb9, 0xb0, 0xbc, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x50, @@ -3418,7 +3603,7 @@ D/U4Lg7WKJ3UuVrRTQg5tvRHnIJI5rRxjg0FzRVIi+euEv0k6G16z78eTn5th/Ov Vo9OEkJPtHxb/RD4eOObUj3NqZl1sMPJ/SQ= -----END CERTIFICATE----- #endif -static const unsigned char kDERCert19[] = { +static const unsigned char kDERCert20[] = { 0x30, 0x82, 0x04, 0x36, 0x30, 0x82, 0x03, 0x1e, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x04, 0x12, 0xb9, 0xb0, 0xe2, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x50, @@ -3601,7 +3786,7 @@ f3eaURBuTh8gPEecQ3R/loQQTBNDvvjgci7/v648CgNggktv+ZrFHvavkDufYTs+ 3psFGsYsPFchCA9U+ihjbOgbnA/P3TBEE7lX/g== -----END CERTIFICATE----- #endif -static const unsigned char kDERCert20[] = { +static const unsigned char kDERCert21[] = { 0x30, 0x82, 0x04, 0x38, 0x30, 0x82, 0x03, 0xa1, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x04, 0x07, 0x27, 0x6d, 0xb9, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x75, @@ -3787,7 +3972,7 @@ NREU768A/l7qX46w2ZJZuvwTlqAYAVbO2vYoC7Gv3VxPXLLzj1pxz+0YrWOIHY6V pG1FJseIVqDwavfY5/wnfmcI0L36tsNhAgFlubgvz1o= -----END CERTIFICATE----- #endif -static const unsigned char kDERCert21[] = { +static const unsigned char kDERCert22[] = { 0x30, 0x82, 0x04, 0x3c, 0x30, 0x82, 0x03, 0x24, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x48, 0x4b, 0xac, 0xf1, 0xaa, 0xc7, 0xd7, 0x13, 0x43, 0xd1, 0xa2, 0x74, 0x35, 0x49, 0x97, 0x25, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -3970,7 +4155,7 @@ ydC35nz7H+1SGZBp9F+pT9YnaNH6lKl7o8mXPOCznQYeIvGCgI4L1uv37QtBvbri B/I8h+FY/43FMjAnk9ciR1xgbARK4bUKZaPd9MdU+/TY7w== -----END CERTIFICATE----- #endif -static const unsigned char kDERCert22[] = { +static const unsigned char kDERCert23[] = { 0x30, 0x82, 0x04, 0x3e, 0x30, 0x82, 0x03, 0xa7, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x04, 0x07, 0x27, 0x13, 0xf5, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x75, @@ -4156,7 +4341,7 @@ w2pcsszZ5ESHb9uPOGL3RDadurxuB8TUjegf0Qtgo7WczmO+7Wfc+Lrebskly1u1 nXZwC99CcvhPQRFkpdLq/NWvEfQVOGecIKhLd1qRMkIy54Wz3zY= -----END CERTIFICATE----- #endif -static const unsigned char kDERCert23[] = { +static const unsigned char kDERCert24[] = { 0x30, 0x82, 0x04, 0x42, 0x30, 0x82, 0x03, 0xab, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x04, 0x42, 0x87, 0x40, 0xa5, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, @@ -4337,7 +4522,7 @@ Cajd1FYVLnp5MV9jllMbNNkV6k9tcMq+9oKp7dqFd8x2HGqBCiHYQZl/Xi6Cweiq 95OBBaqStB+3msAHF/XLxrRMDtdW3HEgdDjWdMbWj2uvi42gbCkLYeA= -----END CERTIFICATE----- #endif -static const unsigned char kDERCert24[] = { +static const unsigned char kDERCert25[] = { 0x30, 0x82, 0x04, 0x45, 0x30, 0x82, 0x03, 0xae, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x33, 0x65, 0x50, 0x08, 0x79, 0xad, 0x73, 0xe2, 0x30, 0xb9, 0xe0, 0x1d, 0x0d, 0x7f, 0xac, 0x91, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -4527,7 +4712,7 @@ VpeTpUe9Sj+MG3XInrDwJZh3IcB2p1F6JCV9GDUG/sEJxQ47majNnSmwOon16ucq 0OF5xgl41fW9sbPFf6ZLr0kRyJecT3xwaRZcLbjQ3xwyUrne88MG6IMi -----END CERTIFICATE----- #endif -static const unsigned char kDERCert25[] = { +static const unsigned char kDERCert26[] = { 0x30, 0x82, 0x04, 0x46, 0x30, 0x82, 0x03, 0x2e, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x04, 0x07, 0x27, 0x75, 0x8a, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x5a, @@ -4712,7 +4897,7 @@ r2Ru1cVfCadAfRa6SQ2i/fbfVTBs13jGuc9YKWQWTKMggUexRJKEFhtvSrwhxgo9 7TPK -----END CERTIFICATE----- #endif -static const unsigned char kDERCert26[] = { +static const unsigned char kDERCert27[] = { 0x30, 0x82, 0x04, 0x4f, 0x30, 0x82, 0x03, 0xb8, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x04, 0x07, 0x27, 0x58, 0x3d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x75, @@ -4908,7 +5093,7 @@ l9w5EdLYieuNkKO2UCXLbNmmw2/7iFS45JJwh855O/DeNr8DBAA9+e+eqWek9IY+ I5e4KnHi7f5piGe/Jlw= -----END CERTIFICATE----- #endif -static const unsigned char kDERCert27[] = { +static const unsigned char kDERCert28[] = { 0x30, 0x82, 0x04, 0x5a, 0x30, 0x82, 0x03, 0x42, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x2f, 0x4e, 0xe1, 0x41, 0x43, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, @@ -5105,7 +5290,7 @@ IXvC9b4u9gIT6a5McOkq9h/Di+Wf4I0qKOgZLLNl3ffxb5c1ntuSNWOB1yfkK2Kq +mKhcZKMCha3PbVKZVsC -----END CERTIFICATE----- #endif -static const unsigned char kDERCert28[] = { +static const unsigned char kDERCert29[] = { 0x30, 0x82, 0x04, 0x5b, 0x30, 0x82, 0x03, 0x43, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x2f, 0x4e, 0xe1, 0x5b, 0x63, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, @@ -5299,7 +5484,7 @@ xT/II3C5qGDCXkeojRmJY6egaQecJ1QiLE7HPZk8ufyTgGW9u9D46oz7ceHopgdA iQ8HV/rRV+9Nstd3yLz4ZQ+e -----END CERTIFICATE----- #endif -static const unsigned char kDERCert29[] = { +static const unsigned char kDERCert30[] = { 0x30, 0x82, 0x04, 0x5e, 0x30, 0x82, 0x03, 0x46, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x04, 0x07, 0x27, 0x42, 0xc2, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x5a, @@ -5496,7 +5681,7 @@ hag8IyrhFHvBN91i0ZJsumB9iOQct+R2UTjEqUdOqCsukNK1OFHrwZyKarXMsh3o wFZUTKiL8IkyhtyTMr5NGvo1dbU= -----END CERTIFICATE----- #endif -static const unsigned char kDERCert30[] = { +static const unsigned char kDERCert31[] = { 0x30, 0x82, 0x04, 0x60, 0x30, 0x82, 0x03, 0x48, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x2f, 0x4e, 0xe1, 0x45, 0x0c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, @@ -5694,7 +5879,7 @@ h4HIYKzEuXInCo4eqLEuzTKieFewnPiVu0OOjDGGblMNxhIFukFuqDUwCRgdAmH/ c738B0E0t6pu7qfb0ZM87ZDsMpKI2cgjbHQh -----END CERTIFICATE----- #endif -static const unsigned char kDERCert31[] = { +static const unsigned char kDERCert32[] = { 0x30, 0x82, 0x04, 0x67, 0x30, 0x82, 0x03, 0x4f, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x1e, 0x44, 0xa5, 0xf5, 0x2a, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, @@ -5889,7 +6074,7 @@ NmGrJH6f+C0/kiljvssQ2w1ANgKg1BeijX9+fJmvRVpAzaJrXL4O89OH/KEQyqoz t7pLwD2kIYwXnM/Yv+ZX/s3r+jAa1f7oJZepvjvq -----END CERTIFICATE----- #endif -static const unsigned char kDERCert32[] = { +static const unsigned char kDERCert33[] = { 0x30, 0x82, 0x04, 0x6a, 0x30, 0x82, 0x03, 0x52, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x04, 0x47, 0x86, 0x9f, 0xe5, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x48, @@ -6085,7 +6270,7 @@ EvrRI5YPv5wN8nlFUzeaVi/oVxBw9u6JDEmJmsEj9cIqzEHPIqtlbreUgm0vQF9Y huNMrUnjl1nOG5srztxl1Asoa06ERlFE9zMILViXIa4= -----END CERTIFICATE----- #endif -static const unsigned char kDERCert33[] = { +static const unsigned char kDERCert34[] = { 0x30, 0x82, 0x04, 0x6c, 0x30, 0x82, 0x03, 0x54, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x4d, 0x5f, 0x2c, 0x34, 0x08, 0xb2, 0x4c, 0x20, 0xcd, 0x6d, 0x50, 0x7e, 0x24, 0x4d, 0xc9, 0xec, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -6285,7 +6470,7 @@ PmWHxA5fbkqsiqge5/rkM4AVhFZlJZv7njCIy5EWwQXDqSTsIdLVsPy3I0annff3 xlMSeDe0E3OPN5deBJv5mYuTPiZCl5/9HrXVy4hINKJmoPqsco/dRy+CdA== -----END CERTIFICATE----- #endif -static const unsigned char kDERCert34[] = { +static const unsigned char kDERCert35[] = { 0x30, 0x82, 0x04, 0x77, 0x30, 0x82, 0x03, 0x5f, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x2f, 0x4e, 0xe1, 0x47, 0x10, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, @@ -6487,7 +6672,7 @@ N17mj5G8pV9RK667jHYxTlMReewRTjhz5RpmcPSC93sQVfi7pcMd5dP2vPootjEQ DOEtZGWRvsK5 -----END CERTIFICATE----- #endif -static const unsigned char kDERCert35[] = { +static const unsigned char kDERCert36[] = { 0x30, 0x82, 0x04, 0x85, 0x30, 0x82, 0x03, 0x6d, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x2f, 0x4e, 0xe1, 0x3f, 0x11, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, @@ -6690,7 +6875,7 @@ qmwIft/I+shWKpLLg7h5CZctXqEBzgbttJfJBNxB7+BPNk3kQHNG7BESfIhbNCYl TercGL7FG81kwA== -----END CERTIFICATE----- #endif -static const unsigned char kDERCert36[] = { +static const unsigned char kDERCert37[] = { 0x30, 0x82, 0x04, 0x86, 0x30, 0x82, 0x03, 0x6e, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x2f, 0x4e, 0xe1, 0x5d, 0xd4, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, @@ -6890,7 +7075,7 @@ vm9nu/9iVzmdDE2yKmE9HZzvmncgoC/uGnKdsJ2/eBMnBwpgEZP1Dy7J72skg/6b kLRLaIHQwvrgPw== -----END CERTIFICATE----- #endif -static const unsigned char kDERCert37[] = { +static const unsigned char kDERCert38[] = { 0x30, 0x82, 0x04, 0x86, 0x30, 0x82, 0x03, 0x6e, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x52, 0x42, 0x06, 0x4a, 0x4f, 0x37, 0xfe, 0x43, 0x69, 0x48, 0x7a, 0x96, 0x67, 0xff, 0x5d, 0x27, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -7093,7 +7278,7 @@ rjIKL/gt9KKn/zbTXmOLThL3tSiAde6UL3CgVnc5qjmXF/wA889m56JxkqsFm3Mu eufnIVkJjTChrFzKGXr4 -----END CERTIFICATE----- #endif -static const unsigned char kDERCert38[] = { +static const unsigned char kDERCert39[] = { 0x30, 0x82, 0x04, 0x8b, 0x30, 0x82, 0x03, 0x73, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x2f, 0x4e, 0xe1, 0x42, 0xf9, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, @@ -7287,7 +7472,7 @@ HUnJizNUQ8SLCSYcqQxQ49+SxWhsBS3G1yMTnr9GNhCN8SfBdKj1D8a44pE8LUz7 ndoe5KWHgKbOQ7cUfZ84 -----END CERTIFICATE----- #endif -static const unsigned char kDERCert39[] = { +static const unsigned char kDERCert40[] = { 0x30, 0x82, 0x04, 0x8b, 0x30, 0x82, 0x03, 0xf4, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x04, 0x04, 0x00, 0x03, 0xb2, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x75, @@ -7487,7 +7672,7 @@ Le6/Wjv6iJx0bK8h3ZLswxXvlHUmRtamP79mSKod790n5rdRiTh9E4QMQPzQtfHg bxQe3FL+vN8MvSk/dvsRX2hoFQ== -----END CERTIFICATE----- #endif -static const unsigned char kDERCert40[] = { +static const unsigned char kDERCert41[] = { 0x30, 0x82, 0x04, 0x8f, 0x30, 0x82, 0x03, 0x77, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x76, 0x10, 0x12, 0x8a, 0x17, 0xb6, 0x82, 0xbb, 0x3a, 0x1f, 0x9d, 0x1a, 0x9a, 0x35, 0xc0, 0x92, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -7681,7 +7866,7 @@ zjQiYRXqZnBk0vFu88oYWWpBRn6C3hmwcDFWaQ0M5h2dcVjczN5i9eF6EALYetw7 +le9yemPRiE5n1FlTI46vihBcB0= -----END CERTIFICATE----- #endif -static const unsigned char kDERCert41[] = { +static const unsigned char kDERCert42[] = { 0x30, 0x82, 0x04, 0x90, 0x30, 0x82, 0x03, 0xf9, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x1b, 0x09, 0x3b, 0x78, 0x60, 0x96, 0xda, 0x37, 0xbb, 0xa4, 0x51, 0x94, 0x46, 0xc8, 0x96, 0x78, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -7882,7 +8067,7 @@ tIGG3cXyqHE+3adKtfr4bDs0mptYfU3U01tTI2tJOBahmJ+EXquuP67Of8gX5DKr xNMvmpAxwpJTlu1yp/7E2jkpUWjtkI2Xjv5FGbc= -----END CERTIFICATE----- #endif -static const unsigned char kDERCert42[] = { +static const unsigned char kDERCert43[] = { 0x30, 0x82, 0x04, 0x99, 0x30, 0x82, 0x03, 0x81, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x3d, 0x3a, 0x05, 0x26, 0x09, 0xb6, 0x2e, 0xe5, 0x8c, 0x36, 0x29, 0x38, 0x63, 0x54, 0xe1, 0x24, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -8080,7 +8265,7 @@ jg9kSm9mA4M/TzSUNqopbYuNAiIrjM13pXCVhpHRtr9SvjNqa5n5b+ESvgTLM7/1 EhpORLpbFk0wufO0dM5u8mhWWN3Yof1UBfQjkYXJ+Q== -----END CERTIFICATE----- #endif -static const unsigned char kDERCert43[] = { +static const unsigned char kDERCert44[] = { 0x30, 0x82, 0x04, 0x9b, 0x30, 0x82, 0x04, 0x04, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x04, 0x42, 0x87, 0x2d, 0x4c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, @@ -8283,7 +8468,7 @@ S62MTw95oMwRPCXnRr960C+IyL/rlAtqdTN/cwC4EnAjXlV/RVseELECaNgnQM8k CeJldM6JRI17KJBorqzCOMhWDTOIKH9U/Dw8UAmTPTg= -----END CERTIFICATE----- #endif -static const unsigned char kDERCert44[] = { +static const unsigned char kDERCert45[] = { 0x30, 0x82, 0x04, 0x9c, 0x30, 0x82, 0x03, 0x84, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x69, 0x48, 0xa2, 0x6b, 0x20, 0x1a, 0xa4, 0x21, 0xe8, 0x98, 0xb1, 0xc4, 0x92, 0xc7, 0xc5, 0x8e, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -8481,7 +8666,7 @@ RfPB+JbFi1WkzGuDFiAy2r77r5u3n+F+hJ+ePFCnP1zCvouGuAiS7vhCKw0T43aF SApKv9ClOwqwVLht4wj5NI0LjosSzBcaM4eVyJ4K3FBTF3s= -----END CERTIFICATE----- #endif -static const unsigned char kDERCert45[] = { +static const unsigned char kDERCert46[] = { 0x30, 0x82, 0x04, 0x9f, 0x30, 0x82, 0x04, 0x08, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x04, 0x46, 0x9e, 0x91, 0x1a, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, @@ -8684,7 +8869,7 @@ m1gAv6+t+jducW0YNA7B6mr4Dd9pVFYV8iiz/qRj7MUEZGC7/irw9IehsK69quQv 8/ifBlIK3se2e4/hEfcEejX/arxbx1BJCHBvlEPNnsdw8dvQbdqP -----END CERTIFICATE----- #endif -static const unsigned char kDERCert46[] = { +static const unsigned char kDERCert47[] = { 0x30, 0x82, 0x04, 0xa3, 0x30, 0x82, 0x03, 0x8b, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x5a, 0xb6, 0x1d, 0xac, 0x1e, 0x4d, 0xa2, 0x06, 0x14, 0xc7, 0x55, 0x3d, 0x3d, 0xa9, 0xb2, 0xdc, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -8887,7 +9072,7 @@ SEQ751duggqtxYrd6FO0ca8T0gadN21TP4o1CPr+ohbmuW9cVjnWxqrvGWfOE8W4 lQX7CkTJn6lAJUsyEa8H/gjVQnHp4VOLFR/dKgeVcCRvZF7Tt5AuiyHY -----END CERTIFICATE----- #endif -static const unsigned char kDERCert47[] = { +static const unsigned char kDERCert48[] = { 0x30, 0x82, 0x04, 0xa6, 0x30, 0x82, 0x03, 0x8e, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x10, 0xe7, 0x76, 0xe8, 0xa6, 0x5a, 0x6e, 0x37, 0x7e, 0x05, 0x03, 0x06, 0xd4, 0x3c, 0x25, 0xea, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -9092,7 +9277,7 @@ YKF+MOHjiD6ku2NvLOmKaCzulmmsBGHhT04OnXJM9nk4yMdIaW+UD3S0vMjPV025 dXGWDYoGC+vd0PA8fcYumEZqOMcCtci4smV13tqQCLZ3uFMAJctHynNf -----END CERTIFICATE----- #endif -static const unsigned char kDERCert48[] = { +static const unsigned char kDERCert49[] = { 0x30, 0x82, 0x04, 0xa6, 0x30, 0x82, 0x03, 0x8e, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x46, 0xea, 0xf0, 0x96, 0x05, 0x4c, 0xc5, 0xe3, 0xfa, 0x65, 0xea, 0x6e, 0x9f, 0x42, 0xc6, 0x64, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -9297,7 +9482,7 @@ uyXAALv17BZlgQ771KMhlneaqHS8U6rCOVD/CwIJYcyVt9eIavZcxWjTFJUaR1/Z +y3kL48ThqsxE0ATrG7ttRAwixtQqc7ujMrrfLW5Fj3U+m+SbR6ivfsCSsVwvvE= -----END CERTIFICATE----- #endif -static const unsigned char kDERCert49[] = { +static const unsigned char kDERCert50[] = { 0x30, 0x82, 0x04, 0xab, 0x30, 0x82, 0x03, 0x93, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x2e, 0x79, 0x83, 0x2e, 0x90, 0x88, 0x87, 0xea, 0x8b, 0x8e, 0xf3, 0x1a, 0x6e, 0xe6, 0x7a, 0x44, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -9503,7 +9688,7 @@ kGGmSavOPN/mymTugmU5RZUWukEGAJi6DFZh5MbGhgHPZqkiKQLWPc/EKo2Z3vsJ FJ4O0dXG14HdrSSrrAcF4h1ow3BmX9M= -----END CERTIFICATE----- #endif -static const unsigned char kDERCert50[] = { +static const unsigned char kDERCert51[] = { 0x30, 0x82, 0x04, 0xc3, 0x30, 0x82, 0x03, 0xab, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x7f, 0x71, 0xc1, 0xd3, 0xa2, 0x26, 0xb0, 0xd2, 0xb1, 0x13, 0xf3, 0xe6, 0x81, 0x67, 0x64, 0x3e, 0x30, 0x0d, 0x06, 0x09, 0x2a, diff --git a/net/quic/crypto/common_cert_set_51_100.inc b/net/quic/crypto/common_cert_set_51_100.inc index 0a1b0d1a..3c79622 100644 --- a/net/quic/crypto/common_cert_set_51_100.inc +++ b/net/quic/crypto/common_cert_set_51_100.inc @@ -102,7 +102,7 @@ fjSAqLiD4gnXbSPdie0oCL1jWhFXCMSe2uJoKK/dUDzsgiHYAMJVRFBwQa2DF3m6 CPMr3u00HUSe0gST9MsFFy0JLS1j7/YmC3s= -----END CERTIFICATE----- #endif -static const unsigned char kDERCert51[] = { +static const unsigned char kDERCert52[] = { 0x30, 0x82, 0x04, 0xc6, 0x30, 0x82, 0x04, 0x2f, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x35, 0x97, 0x31, 0x87, 0xf3, 0x87, 0x3a, 0x07, 0x32, 0x7e, 0xce, 0x58, 0x0c, 0x9b, 0x7e, 0xda, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -310,7 +310,7 @@ KPNE0UN2tIFoKgchP4/0Z9MIoHnezLlTLR9E01ScowdNigg0Td0Xev6ta0uZtgDJ YnZ+mJqiSRyGvrJVlSwtJyG8GbDxPq220Rre7bbuNQ== -----END CERTIFICATE----- #endif -static const unsigned char kDERCert52[] = { +static const unsigned char kDERCert53[] = { 0x30, 0x82, 0x04, 0xcb, 0x30, 0x82, 0x03, 0xb3, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x18, 0xa2, 0x23, 0x6c, 0xd7, 0x27, 0xc7, 0x52, 0x8d, 0xf6, 0x7b, 0x4b, 0x85, 0x6e, 0xff, 0xed, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -512,7 +512,7 @@ lCDDPLq9ZVTGr0SzEK0saz6r1we2uIFjxfleLuUqZ87NMwwq14lWAyMfs77oOghZ tOxFNfeKW/9mz1Cvxm1XjRl4t7mi0VfqH5pLr7rJjhJ+xr3/ -----END CERTIFICATE----- #endif -static const unsigned char kDERCert53[] = { +static const unsigned char kDERCert54[] = { 0x30, 0x82, 0x04, 0xd0, 0x30, 0x82, 0x04, 0x39, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x25, 0x0c, 0xe8, 0xe0, 0x30, 0x61, 0x2e, 0x9f, 0x2b, 0x89, 0xf7, 0x05, 0x4d, 0x7c, 0xf8, 0xfd, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -721,7 +721,7 @@ kqCeuEYcYmOwuAjE/bC0nyQJsy2cdRR3Sm7EY8FNE4bOmHIdPbnGTnMw5MZzotH3 kOSQzOE6N9ZTAl9FLS+mT0lB6t+PL5ccdtt4QGPL5NXXUzgOERA4 -----END CERTIFICATE----- #endif -static const unsigned char kDERCert54[] = { +static const unsigned char kDERCert55[] = { 0x30, 0x82, 0x04, 0xd3, 0x30, 0x82, 0x03, 0xbb, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x48, 0xfc, 0x4b, 0x0a, 0x37, 0x06, 0xff, 0x46, 0xfe, 0xd3, 0xde, 0x5d, 0x4c, 0x1e, 0xca, 0x62, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -930,7 +930,7 @@ qDTMBqLdElrRhjZkAzVvb3du6/KFUJheqwNTrZEjYx8WnM25sgVjOuH0aBsXBTWV U+4= -----END CERTIFICATE----- #endif -static const unsigned char kDERCert55[] = { +static const unsigned char kDERCert56[] = { 0x30, 0x82, 0x04, 0xde, 0x30, 0x82, 0x03, 0xc6, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x02, 0x03, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x63, 0x31, 0x0b, @@ -1142,7 +1142,7 @@ RwHGXhnCtJWX7mEAVfEEOPyE5ni0DUO+QzPdaNMiWwD7FILoS2J5MM/TlZ+zuYQB 1N3PIxL4 -----END CERTIFICATE----- #endif -static const unsigned char kDERCert56[] = { +static const unsigned char kDERCert57[] = { 0x30, 0x82, 0x04, 0xe2, 0x30, 0x82, 0x03, 0xca, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x6e, 0xba, 0xf0, 0x8f, 0x79, 0x83, 0xfa, 0x9d, 0xe1, 0xb2, 0x6f, 0x96, 0xfc, 0x6e, 0x98, 0xbf, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -1354,7 +1354,7 @@ W1jQbCn2Nrrcy5lJdU0qnaW1M10125vV9bNno9vAhV8RMwmP4YpC96Dao7l/NdRs dI/f+P++v44= -----END CERTIFICATE----- #endif -static const unsigned char kDERCert57[] = { +static const unsigned char kDERCert58[] = { 0x30, 0x82, 0x04, 0xe4, 0x30, 0x82, 0x03, 0xcc, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x4e, 0x6c, 0x48, 0x88, 0x36, 0xbb, 0x28, 0xce, 0x2b, 0xe3, 0x5a, 0xc3, 0x79, 0x8f, 0x4a, 0x24, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -1566,7 +1566,7 @@ Z4ZElXJAVfbdo7Q9LQlgpedf/Kw77AyRn/juarqyPP2VfZoH9LBlQ6L23324IUmE BO69zlOPDyk= -----END CERTIFICATE----- #endif -static const unsigned char kDERCert58[] = { +static const unsigned char kDERCert59[] = { 0x30, 0x82, 0x04, 0xe4, 0x30, 0x82, 0x03, 0xcc, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x4f, 0xe3, 0xe2, 0x65, 0x21, 0x07, 0xab, 0x20, 0x37, 0x41, 0x6e, 0x48, 0x70, 0xce, 0xd2, 0xc2, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -1778,7 +1778,7 @@ uuGtm87fM04wO+mPZn+C+mv626PAcwDj1hKvTfIPWhRRH224hoFiB85ccsJP81cq cdnUl4XmGFO3 -----END CERTIFICATE----- #endif -static const unsigned char kDERCert59[] = { +static const unsigned char kDERCert60[] = { 0x30, 0x82, 0x04, 0xe5, 0x30, 0x82, 0x03, 0xcd, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x07, 0x6f, 0x12, 0x46, 0x81, 0x45, 0x9c, 0x28, 0xd5, 0x48, 0xd6, 0x97, 0xc4, 0x0e, 0x00, 0x1b, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -1990,7 +1990,7 @@ Gs11aYk5ZpXhModzkdCbg424x+C8Io8sJBPIwpSX+jEmIoIrte8FpqB+mgC0a+Oe WUO8dpjzPDDbHDAu -----END CERTIFICATE----- #endif -static const unsigned char kDERCert60[] = { +static const unsigned char kDERCert61[] = { 0x30, 0x82, 0x04, 0xe8, 0x30, 0x82, 0x03, 0xd0, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x74, 0x86, 0x21, 0x96, 0x95, 0x10, 0xc9, 0x29, 0x26, 0x29, 0x4b, 0xcc, 0x8b, 0xf8, 0x29, 0x2c, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -2202,7 +2202,7 @@ i+qweI4gAdIpsozxeyoIsmJqMDZdXKc7Su73BzJHLfaIYgypJOBw36KmQgx7fSgF FhvXMwUw+wCqKOtfDecUViddfLQ= -----END CERTIFICATE----- #endif -static const unsigned char kDERCert61[] = { +static const unsigned char kDERCert62[] = { 0x30, 0x82, 0x04, 0xf0, 0x30, 0x82, 0x03, 0xd8, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x7a, 0xac, 0xa2, 0x1d, 0x53, 0x9d, 0x14, 0x54, 0x11, 0x3c, 0x04, 0x5e, 0xd8, 0x35, 0xf8, 0xea, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -2415,7 +2415,7 @@ GeTBoc1M1Dq2iMjz0GVhOr8Y9K8cVqnrlzjZICkfPyopR52KD2oSgUQCIdQ7Ohor HkBDfZSgaQ78LvtS9v0uMtjLa73r -----END CERTIFICATE----- #endif -static const unsigned char kDERCert62[] = { +static const unsigned char kDERCert63[] = { 0x30, 0x82, 0x04, 0xf1, 0x30, 0x82, 0x03, 0xd9, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x4b, 0x75, 0x57, 0x82, 0x69, 0x39, 0x0c, 0x9b, 0xe3, 0x2f, 0x12, 0xec, 0x5f, 0x6d, 0x94, 0x5e, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -2628,7 +2628,7 @@ Q4hvNRevHmCDrHqMEHufyfaDbZ76iO4+3e6esL/garnQnweyCROa9aTlyFt5p0c1 M2jlVZ6qW8swC53HD79oRIGXi1FK -----END CERTIFICATE----- #endif -static const unsigned char kDERCert63[] = { +static const unsigned char kDERCert64[] = { 0x30, 0x82, 0x04, 0xf1, 0x30, 0x82, 0x03, 0xd9, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x6f, 0x25, 0xdc, 0x15, 0xaf, 0xdf, 0x5e, 0xa3, 0x08, 0x56, 0x0c, 0x3b, 0x7a, 0x4f, 0xc7, 0xf8, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -2839,7 +2839,7 @@ PFS+/i/qaZ0cHimbltjI/lGQ8SSmkAaz8Cmi/3gud1xFIdlEADHzvjJP9QoyDfz8 uhZ2VrLWSJLyi6Y+t6xcaeoLP2ZFuQ== -----END CERTIFICATE----- #endif -static const unsigned char kDERCert64[] = { +static const unsigned char kDERCert65[] = { 0x30, 0x82, 0x04, 0xf2, 0x30, 0x82, 0x03, 0xda, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x04, 0x38, 0x63, 0xe9, 0xfc, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, @@ -3050,7 +3050,7 @@ mWEn7kVuxzn/9sWL4Mt8ih7VegcxKlJcOlAZOKlE+jyoz+95nWrZ5S6hjyko1+yq wfsm5p9GJKaxB825DOgNghYAHZaS/KYIoA== -----END CERTIFICATE----- #endif -static const unsigned char kDERCert65[] = { +static const unsigned char kDERCert66[] = { 0x30, 0x82, 0x04, 0xf5, 0x30, 0x82, 0x03, 0xdd, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x04, 0x4c, 0x0e, 0x8c, 0x39, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, @@ -3264,7 +3264,7 @@ jVqP2KBBNaOGcwWu2Rl6Ossgr1GRo8xGTUdQxvvcFSxUcb/+V/uJrP/Qu49mPu/k Ia+AR/+G2zkRyOZQzUVtWZbKVXZttY6w3gloAA== -----END CERTIFICATE----- #endif -static const unsigned char kDERCert66[] = { +static const unsigned char kDERCert67[] = { 0x30, 0x82, 0x04, 0xf8, 0x30, 0x82, 0x03, 0xe0, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x40, 0x89, 0x95, 0x44, 0x7e, 0x5f, 0xb1, 0x19, 0xd8, 0x65, 0x73, 0x70, 0x2f, 0x8d, 0x64, 0xfc, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -3470,7 +3470,7 @@ WBsUs5iB0QQeyAfJg594RAoYC5jcdnplDQ1tgMQLARzLrUc+cb53S8wGd9D0Vmsf SxOaFIqII6hR8INMqzW/Rn453HWkrugp++85j09VZw== -----END CERTIFICATE----- #endif -static const unsigned char kDERCert67[] = { +static const unsigned char kDERCert68[] = { 0x30, 0x82, 0x04, 0xfb, 0x30, 0x82, 0x04, 0x64, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x02, 0x01, 0x0d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, 0xbb, 0x31, @@ -3684,7 +3684,7 @@ uSqM8XCsJt0EuUDChd4ck0DQzG7Dm6rvYGXfYCLwWqV6oi/kcHPuPNQmK2gHwSB6 6JhaPnufAotiwIWBgGA1fqUdDNKc32JFDdv8N/v1JSI= -----END CERTIFICATE----- #endif -static const unsigned char kDERCert68[] = { +static const unsigned char kDERCert69[] = { 0x30, 0x82, 0x04, 0xfc, 0x30, 0x82, 0x03, 0xe4, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x16, 0x90, 0xc3, 0x29, 0xb6, 0x78, 0x06, 0x07, 0x51, 0x1f, 0x05, 0xb0, 0x34, 0x48, 0x46, 0xcb, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -3898,7 +3898,7 @@ FMFVbcFckVfsjUPF+X20DAY0w7SnZ4e2xM8aNQiVESAhoXe/LxmKc4HChyPr05my fyeJ0o5A+j3uBkkL/vSkNEl3iD1CkZa0LJwL5tRBxN+tkA== -----END CERTIFICATE----- #endif -static const unsigned char kDERCert69[] = { +static const unsigned char kDERCert70[] = { 0x30, 0x82, 0x04, 0xfe, 0x30, 0x82, 0x03, 0xe6, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x45, 0x4f, 0xa2, 0x0d, 0x78, 0x11, 0x74, 0x59, 0xf8, 0xc6, 0xab, 0x3c, 0x7b, 0xcd, 0x03, 0x0e, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -4124,7 +4124,7 @@ baThaXwy0AR796kdlzvVWb/Lb52ktqW7QRHtyJGDFVWuWTa3n2rwuDj5fDIllcwz dZCN4dazxVD8XdX7b5Lh9H7wrq/5ObPOSwGcvU738fJvzsA22A== -----END CERTIFICATE----- #endif -static const unsigned char kDERCert70[] = { +static const unsigned char kDERCert71[] = { 0x30, 0x82, 0x05, 0x01, 0x30, 0x82, 0x03, 0xe9, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x04, 0x07, 0x27, 0x6f, 0xae, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x5a, @@ -4341,7 +4341,7 @@ dXRHKJcUCitTsOtuQmh272chYbZkdAhwbRHG53/lNhxmOv1OemOeFc7PqQTmMOoQ 0lqBJEvC8jv7NOZpe/9dmzBGWWktDfJ//PsKKeo1FNC7PKOxEEE= -----END CERTIFICATE----- #endif -static const unsigned char kDERCert71[] = { +static const unsigned char kDERCert72[] = { 0x30, 0x82, 0x05, 0x02, 0x30, 0x82, 0x03, 0xea, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x20, 0x93, 0x42, 0xda, 0xa7, 0x64, 0x7c, 0x05, 0xc5, 0xf5, 0xfd, 0x93, 0x76, 0xa4, 0x42, 0x8c, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -4558,7 +4558,7 @@ F6r7yJiIatnyfKH2cboZT7g440LX8NqxwCPf3dfxp+0Jj1agq8MLy6SSgIGSH6lv XSXaPV7Od4rhPsbXlM1wSTz/Dr0ISKvlUhQVnQ6cGodWaK2cCQBk -----END CERTIFICATE----- #endif -static const unsigned char kDERCert72[] = { +static const unsigned char kDERCert73[] = { 0x30, 0x82, 0x05, 0x03, 0x30, 0x82, 0x03, 0xeb, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x18, 0xb2, 0xcb, 0xba, 0xa3, 0x04, 0xf1, 0xa0, 0x0f, 0xc1, 0xf2, 0xf3, 0x26, 0x46, 0x2a, 0x4a, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -4772,7 +4772,7 @@ zg5G8t6P2jt9HpOs/PQyKw+rAR+lQI/jJJkfXbKqDLnioeeSDJBLU30fKO5WPa8Y Z0nf1R7CqJgrTEeDgUwuRMLvyGPui3tbMfYmYb95HLCpTqnJUHvi -----END CERTIFICATE----- #endif -static const unsigned char kDERCert73[] = { +static const unsigned char kDERCert74[] = { 0x30, 0x82, 0x05, 0x03, 0x30, 0x82, 0x03, 0xeb, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x4c, 0xcd, 0x4a, 0x9a, 0x5b, 0x45, 0x13, 0x21, 0x8c, 0xcf, 0x90, 0x2f, 0x8b, 0x2b, 0x51, 0x71, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -4987,7 +4987,7 @@ tN3t40DeDDYlV5rA0WCeXgNol64aO+pF11GZSe5EWVYLXrGPaOqKnsrSyaADfnAl 9DLJTlCDh6I0SD1PNXf82Ijq9n0ezkO21cJqfjhmY03n7jLvDyToKmf6 -----END CERTIFICATE----- #endif -static const unsigned char kDERCert74[] = { +static const unsigned char kDERCert75[] = { 0x30, 0x82, 0x05, 0x06, 0x30, 0x82, 0x03, 0xee, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x11, 0xa3, 0xb4, 0xd0, 0xec, 0x8d, 0xb7, 0x7f, 0x9d, 0xa0, 0xcd, 0x5d, 0x2d, 0x51, 0x2f, 0x42, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -5200,7 +5200,7 @@ aRN+0AqNnQ9gVHrEjBs1D3R6cLKCzx214orbKsayUWm/EheSYBeqPVsJ+IdlHaek KOUiAgOCRJo0Y577KM/ozS4OUiDtSss4fJ2ubnnXlSyokfOGASGRS7VApA== -----END CERTIFICATE----- #endif -static const unsigned char kDERCert75[] = { +static const unsigned char kDERCert76[] = { 0x30, 0x82, 0x05, 0x07, 0x30, 0x82, 0x03, 0xef, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x68, 0x31, 0x0b, @@ -5418,7 +5418,7 @@ wbIR/Vp3xB+Yny6g0Ml80zRi9S+WN0hItCH7L61TZTTCe0p8/JBJn/P3NwieQQCy YxtLufbBfVlmq9HzijAFGHpBR6vHZxQ6fGCxCE7QzsfhraZN7q4yrKzGWg== -----END CERTIFICATE----- #endif -static const unsigned char kDERCert76[] = { +static const unsigned char kDERCert77[] = { 0x30, 0x82, 0x05, 0x07, 0x30, 0x82, 0x03, 0xef, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x04, 0x4c, 0x0e, 0xa6, 0xdb, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, @@ -5634,7 +5634,7 @@ OOb58TkCnUa2ycKePoK2H5/KSqixBl8QNDv92nusM07tprdL85H1nAsRktwTasjV 8TttlmsB5CNMscHg0hIhnynUrZU9pvfnMsV1twtX2KT5wOzsMjMMTa7oCNXsqg== -----END CERTIFICATE----- #endif -static const unsigned char kDERCert77[] = { +static const unsigned char kDERCert78[] = { 0x30, 0x82, 0x05, 0x0a, 0x30, 0x82, 0x03, 0xf2, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x04, 0x45, 0x6b, 0x9a, 0xdc, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, @@ -5850,7 +5850,7 @@ RdJ+50puHU9Iu8LaGn5KWYH6HOP7FHNBA6F3+psG/HwzvUY9DAYXhXsqe+M26IPf +qrLMgx5qoZ0bERU9tgHns2Y9CMFCS+iU7XbCoHMXyPLeRHFEVuFaycBifMOuw== -----END CERTIFICATE----- #endif -static const unsigned char kDERCert78[] = { +static const unsigned char kDERCert79[] = { 0x30, 0x82, 0x05, 0x0a, 0x30, 0x82, 0x03, 0xf2, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x7b, 0x11, 0x55, 0xeb, 0x78, 0x9a, 0x90, 0x85, 0xb5, 0x8c, 0x92, 0xff, 0x42, 0xb7, 0xfe, 0x56, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -6067,7 +6067,7 @@ YZKXE16AMQy3npAghwvQqgoGBCc8hmogDZ27zn1XyVmTogM7jLNvQv2k1ZvKAaoE DA== -----END CERTIFICATE----- #endif -static const unsigned char kDERCert79[] = { +static const unsigned char kDERCert80[] = { 0x30, 0x82, 0x05, 0x0d, 0x30, 0x82, 0x03, 0xf5, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x04, 0x4c, 0x0e, 0xc9, 0x18, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, @@ -6276,7 +6276,7 @@ GkVrMgfHeMpkksK0hAzc3S1fTbvdiuo43NlmouxBulVtWmQ9twPMHOKRUJ7jCUSV FxdzPcwl -----END CERTIFICATE----- #endif -static const unsigned char kDERCert80[] = { +static const unsigned char kDERCert81[] = { 0x30, 0x82, 0x05, 0x12, 0x30, 0x82, 0x04, 0x7b, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x02, 0x01, 0x0c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, 0xbb, 0x31, @@ -6500,7 +6500,7 @@ V94kzjWraZBOKww6+bTxgPptAHmmOpaZTjpuVNCjWW6LHZVJu5XYdbjhEjOsXCe7 y1Vx1frt -----END CERTIFICATE----- #endif -static const unsigned char kDERCert81[] = { +static const unsigned char kDERCert82[] = { 0x30, 0x82, 0x05, 0x12, 0x30, 0x82, 0x04, 0x7b, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x04, 0x07, 0x27, 0x62, 0x02, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x75, @@ -6711,7 +6711,7 @@ MFNIUYWFE6hU4e52ookY05eJesb9s72UYVo6CM8Uk72T/Qmpe1bIALhEWOneW3e9 BxxsCzAwxw== -----END CERTIFICATE----- #endif -static const unsigned char kDERCert82[] = { +static const unsigned char kDERCert83[] = { 0x30, 0x82, 0x05, 0x13, 0x30, 0x82, 0x04, 0x7c, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x57, 0xbf, 0xfb, 0x03, 0xfb, 0x2c, 0x46, 0xd4, 0xe1, 0x9e, 0xce, 0xe0, 0xd7, 0x43, 0x7f, 0x13, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -6930,7 +6930,7 @@ XB+FCSBCZnFZ1S9JtaspY1TjA5mNjjgoRP+1PsPNQ3M92To7Dbz2iCE0mdmZ6FZ8 J4Su08i9t4L6dCzgM6aP -----END CERTIFICATE----- #endif -static const unsigned char kDERCert83[] = { +static const unsigned char kDERCert84[] = { 0x30, 0x82, 0x05, 0x1b, 0x30, 0x82, 0x04, 0x03, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x08, 0x0a, 0x57, 0x82, 0x2c, 0xc6, 0xf5, 0xe1, 0x4f, 0x19, 0xb7, 0x09, 0x55, 0xc8, 0x03, 0x42, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -7149,7 +7149,7 @@ nHnRkb9z8N2yAFwz7llh/a4ncvOxPXr/TEGS5IPiVqJE4wNW9jSaNntiliLzb9NO fyyysLJbsSoGDjZbYzTIO2mz71GsmmiF7S4tRP6eCdcm+A== -----END CERTIFICATE----- #endif -static const unsigned char kDERCert84[] = { +static const unsigned char kDERCert85[] = { 0x30, 0x82, 0x05, 0x2e, 0x30, 0x82, 0x04, 0x16, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x03, 0x0e, 0x95, 0x29, 0x4d, 0xae, 0xc1, 0x2c, 0x03, 0xcf, 0x31, 0xab, 0x5b, 0x02, 0x71, 0xd7, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -7361,7 +7361,7 @@ YZiaKfWdsc+43PN7gEdI0X30aIzEQcu06f3wI+Cxm3YqbShWo4zN6ewhAHHwX91Q pWlCG4MRXYQo0yeu7CqrL2BCxcR4 -----END CERTIFICATE----- #endif -static const unsigned char kDERCert85[] = { +static const unsigned char kDERCert86[] = { 0x30, 0x82, 0x05, 0x51, 0x30, 0x82, 0x04, 0xba, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x5f, 0xa6, 0xbe, 0x80, 0xb6, 0x86, 0xc6, 0x2f, 0x01, 0xed, 0x0c, 0xab, 0xb1, 0x96, 0xa1, 0x05, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -7592,7 +7592,7 @@ fip8tmNHnna6l9AW5wtsbfdDbzMLKTB3+p359U64drPNGLT5IO892+bKrZvQTtKH qQ2mRHNQ3XBb7a1+Srwi1agm5MKFIA3Z -----END CERTIFICATE----- #endif -static const unsigned char kDERCert86[] = { +static const unsigned char kDERCert87[] = { 0x30, 0x82, 0x05, 0xe4, 0x30, 0x82, 0x04, 0xcc, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x5b, 0x77, 0x59, 0xc6, 0x17, 0x84, 0xe1, 0x5e, 0xc7, 0x27, 0xc0, 0x32, 0x95, 0x29, 0x28, 0x6b, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -7835,7 +7835,7 @@ W+yzf5VK+wPIrSbb5mZ4EkrZn0L74ZjmQoObj49nJOhhGbXdzbULJgWOw27EyHW4 Rs/iGAZeqa6ogZpHFt4MKGwlJ7net4RYxh84HqTEy2Y= -----END CERTIFICATE----- #endif -static const unsigned char kDERCert87[] = { +static const unsigned char kDERCert88[] = { 0x30, 0x82, 0x05, 0xec, 0x30, 0x82, 0x04, 0xd4, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x6e, 0xcc, 0x7a, 0xa5, 0xa7, 0x03, 0x20, 0x09, 0xb8, 0xce, 0xbc, 0xf4, 0xe9, 0x52, 0xd4, 0x91, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -8076,7 +8076,7 @@ hYkukH9ZtpwG5TX///+1U9k+td2u/gZPZnHgT/f8wYW1e4VDIs9b9pSFplmyXf4p T4ycHpLODzMgGUlZVDZsxOn5ZhsgbLJvPiQ5b5H7tNiTUMDCl97pk16XIAVKCRM= -----END CERTIFICATE----- #endif -static const unsigned char kDERCert88[] = { +static const unsigned char kDERCert89[] = { 0x30, 0x82, 0x05, 0xfb, 0x30, 0x82, 0x04, 0xe3, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x71, 0x63, 0x66, 0x35, 0xeb, 0xf3, 0x82, 0x3d, 0x7e, 0x13, 0x09, 0x59, 0xa2, 0xd8, 0xe5, 0xde, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -8336,7 +8336,7 @@ DPUmsX7cmCZwWCYTXMd12xLeTKz/mgzqosIcQQSM5keXR2+JxUjeNw1q2fBoJFz/ GVnm4XA3OA3b7rDi -----END CERTIFICATE----- #endif -static const unsigned char kDERCert89[] = { +static const unsigned char kDERCert90[] = { 0x30, 0x82, 0x06, 0x08, 0x30, 0x82, 0x03, 0xf0, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0a, 0x61, 0x5d, 0xaa, 0xd2, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, @@ -8585,7 +8585,7 @@ u5aNZkU5tBIK9nDpnHYiS2DpKhs0Sfei1GfAsSatE7rZhAHBq+GObXAWO3eskZq7 Gh/aWKfkT8Fhrryi/ks= -----END CERTIFICATE----- #endif -static const unsigned char kDERCert90[] = { +static const unsigned char kDERCert91[] = { 0x30, 0x82, 0x06, 0x0a, 0x30, 0x82, 0x04, 0xf2, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x11, 0x2a, 0x00, 0x6d, 0x37, 0xe5, 0x10, 0x6f, 0xd6, 0xca, 0x7c, 0xc3, 0xef, 0xba, 0xcc, 0x18, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -8847,7 +8847,7 @@ oSj7jKGnHwEoUeVxlDec3EFbfH7pLCNnlJ1z319AeaONlTDMUxcIvFCG8/wQGYH8 pnj1Hn3eGjp4fNwqcQajLW8FVSOLkO8= -----END CERTIFICATE----- #endif -static const unsigned char kDERCert91[] = { +static const unsigned char kDERCert92[] = { 0x30, 0x82, 0x06, 0x13, 0x30, 0x82, 0x03, 0xfb, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0a, 0x61, 0x03, 0x33, 0x36, 0x00, 0x05, 0x00, 0x00, 0x00, 0x30, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, @@ -9097,7 +9097,7 @@ k1PZf+6hCKezMJZJcG6jbD3QY+8lZmPMqrcYF07qcHb2ukKmgDcJTp9miC5rM2bI wHGkQeta4/wULkuI/a5uW2XpJ+S/5LAjwbJ9W2Il1z4Q1A== -----END CERTIFICATE----- #endif -static const unsigned char kDERCert92[] = { +static const unsigned char kDERCert93[] = { 0x30, 0x82, 0x06, 0x1e, 0x30, 0x82, 0x05, 0x06, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x2c, 0x48, 0xdd, 0x93, 0x0d, 0xf5, 0x59, 0x8e, 0xf9, 0x3c, 0x99, 0x54, 0x7a, 0x60, 0xed, 0x43, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -9348,7 +9348,7 @@ Ett9LnZQ/9/XaxvMisxx+rNAVnwzeneUW/ULU/sOX7xo+68q7jA3eRaTJX9NEP9X XmnUG623kHdq2FlveasB+lXwiiFm5WVu/XzT3x7rfj8GkPsZC9MGAht4Q5mo -----END CERTIFICATE----- #endif -static const unsigned char kDERCert93[] = { +static const unsigned char kDERCert94[] = { 0x30, 0x82, 0x06, 0x29, 0x30, 0x82, 0x05, 0x11, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x64, 0x1b, 0xe8, 0x20, 0xce, 0x02, 0x08, 0x13, 0xf3, 0x2d, 0x4d, 0x2d, 0x95, 0xd6, 0x7e, 0x67, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -9592,7 +9592,7 @@ OcUgdav4bC1nHynCIdcUiGNLsJsnY5H48KMBJLb7j+M9AgtvVP7UzNvWhb98lR5e YhHB2QmcQrmy1KotmDojYMyimvFu6M+O0Ro8XhnF15s1sAIjJOUFuNWI4+D6ufRf -----END CERTIFICATE----- #endif -static const unsigned char kDERCert94[] = { +static const unsigned char kDERCert95[] = { 0x30, 0x82, 0x06, 0x2c, 0x30, 0x82, 0x05, 0x95, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x6e, 0x4f, 0xfa, 0xb3, 0xc5, 0xe6, 0x69, 0xc4, 0xd1, 0x67, 0xc9, 0x92, 0xab, 0xe8, 0x58, 0xc4, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -9855,7 +9855,7 @@ p/EiO/h94pDQehn7Skzj0n1fSoMD7SfWI55rjbRZotnvbIIp3XUZPD9MEI3vu3Un 0q6Dp6jOW6c= -----END CERTIFICATE----- #endif -static const unsigned char kDERCert95[] = { +static const unsigned char kDERCert96[] = { 0x30, 0x82, 0x06, 0x34, 0x30, 0x82, 0x04, 0x1c, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x18, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x7d, 0x31, 0x0b, 0x30, @@ -10119,7 +10119,7 @@ oUCcSyrcuNDUnv3xhHgbDlePaVRCaHvqoO91DweijHOZq1X1BwnSrzgDapADDC+P qhykguAzx/Q= -----END CERTIFICATE----- #endif -static const unsigned char kDERCert96[] = { +static const unsigned char kDERCert97[] = { 0x30, 0x82, 0x06, 0x34, 0x30, 0x82, 0x04, 0x1c, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x1a, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x7d, 0x31, 0x0b, 0x30, @@ -10370,7 +10370,7 @@ EIRYzwfu45DC9fkpx1ojcflZtGQriLCnNseaIGHr+k61rmsb5OPs4tk8QUmoIKRU 9ZKNu8BVIASm2LAXFszj0Mi0PeXZhMbT9m5teMl5Q+h6N/9cNUm/ocU= -----END CERTIFICATE----- #endif -static const unsigned char kDERCert97[] = { +static const unsigned char kDERCert98[] = { 0x30, 0x82, 0x06, 0x55, 0x30, 0x82, 0x05, 0x3d, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x08, 0x51, 0xf9, 0x59, 0x81, 0x41, 0x45, 0xca, 0xbd, 0xe0, 0x24, 0xe2, 0x12, 0xc9, 0xc2, 0x0e, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -10624,7 +10624,7 @@ JiiNeXf1L/BXunwH1OH8zVowV36GEEfdMR/X/KLCvzB8XSSq6PmuX2p0ws5rs0bY Ib4p1I5eFdZCSucyb6Sxa1GDWL4/bcf72gMhy2oWGU4K8K2Eyl2Us1p292E= -----END CERTIFICATE----- #endif -static const unsigned char kDERCert98[] = { +static const unsigned char kDERCert99[] = { 0x30, 0x82, 0x06, 0x58, 0x30, 0x82, 0x05, 0x40, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x0a, 0x5f, 0x11, 0x4d, 0x03, 0x5b, 0x17, 0x91, 0x17, 0xd2, 0xef, 0xd4, 0x03, 0x8c, 0x3f, 0x3b, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -10884,7 +10884,7 @@ ogBpIAfKgkwez6eYuAzuzRYcvhpj1MCZ9mey8I4XLVjCgKpdlsezKO3w2o62RxuP ThXxl0wLS6+B1EaUYixDpzwlSBlj8lyqFYl2hIVzkX0oPAmDgrz3 -----END CERTIFICATE----- #endif -static const unsigned char kDERCert99[] = { +static const unsigned char kDERCert100[] = { 0x30, 0x82, 0x06, 0xe3, 0x30, 0x82, 0x05, 0xcb, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x08, 0xbb, 0xb0, 0x25, 0x47, 0x13, 0x4b, 0xc9, 0xb1, 0x10, 0xd7, 0xc1, 0xa2, 0x12, 0x59, 0xc5, 0x30, 0x0d, 0x06, 0x09, 0x2a, @@ -11156,7 +11156,7 @@ BEkAui6mSnKDcp33C4ypieez12Qf1uNgywPE3IjpnSUBAHHLA7QpYCWP+UbRe3Gu zVMSW4SOwg/H7ZMZ2cn6j1g0djIvruFQFGHUqFijyDATI+/GJYw2jxyA -----END CERTIFICATE----- #endif -static const unsigned char kDERCert100[] = { +static const unsigned char kDERCert101[] = { 0x30, 0x82, 0x06, 0xe6, 0x30, 0x82, 0x05, 0xce, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x03, 0x37, 0xb9, 0x28, 0x34, 0x7c, 0x60, 0xa6, 0xae, 0xc5, 0xad, 0xb1, 0x21, 0x7f, 0x38, 0x60, 0x30, 0x0d, 0x06, 0x09, 0x2a, diff --git a/net/quic/crypto/common_cert_set_test.cc b/net/quic/crypto/common_cert_set_test.cc index 6ce020d..325d0b2 100644 --- a/net/quic/crypto/common_cert_set_test.cc +++ b/net/quic/crypto/common_cert_set_test.cc @@ -78,7 +78,7 @@ TEST(CommonCertSets, FindGIA) { const CommonCertSets* sets(CommonCertSets::GetInstanceQUIC()); - const uint64 in_hash = GG_UINT64_C(0xde8086f914a3af54); + const uint64 in_hash = GG_UINT64_C(0xc9fef74053f99f39); uint64 hash; uint32 index; ASSERT_TRUE(sets->MatchCert( @@ -96,7 +96,7 @@ TEST(CommonCertSets, FindGIA) { TEST(CommonCertSets, NonMatch) { const CommonCertSets* sets(CommonCertSets::GetInstanceQUIC()); StringPiece not_a_cert("hello"); - const uint64 in_hash = GG_UINT64_C(0xde8086f914a3af54); + const uint64 in_hash = GG_UINT64_C(0xc9fef74053f99f39); uint64 hash; uint32 index; EXPECT_FALSE(sets->MatchCert( diff --git a/net/quic/crypto/crypto_handshake.cc b/net/quic/crypto/crypto_handshake.cc index 474dd3c..ad4366d 100644 --- a/net/quic/crypto/crypto_handshake.cc +++ b/net/quic/crypto/crypto_handshake.cc @@ -573,6 +573,13 @@ void QuicCryptoClientConfig::FillInchoateClientHello( #endif } + if (proof_verifier_.get() && !cached->proof_valid()) { + // If we are expecting a certificate chain, double the size of the client + // hello so that the response from the server can be larger - hopefully + // including the whole certificate chain. + out->set_minimum_size(kClientHelloMinimumSize * 2); + } + if (common_cert_sets) { out->SetStringPiece(kCCS, common_cert_sets->GetCommonHashes()); } diff --git a/net/quic/crypto/crypto_server_config.cc b/net/quic/crypto/crypto_server_config.cc index b28207f..e0475b5 100644 --- a/net/quic/crypto/crypto_server_config.cc +++ b/net/quic/crypto/crypto_server_config.cc @@ -137,7 +137,12 @@ QuicServerConfigProtobuf* QuicCryptoServerConfig::DefaultConfig( } char orbit_bytes[kOrbitSize]; - rand->RandBytes(orbit_bytes, sizeof(orbit_bytes)); + if (options.orbit.size() == kOrbitSize) { + memcpy(orbit_bytes, options.orbit.data(), sizeof(orbit_bytes)); + } else { + DCHECK(options.orbit.empty()); + rand->RandBytes(orbit_bytes, sizeof(orbit_bytes)); + } msg.SetStringPiece(kORBT, StringPiece(orbit_bytes, sizeof(orbit_bytes))); if (options.channel_id_enabled) { @@ -674,44 +679,60 @@ void QuicCryptoServerConfig::BuildRejection( const QuicTag* their_proof_demands; size_t num_their_proof_demands; - if (proof_source_.get() != NULL && + if (proof_source_.get() == NULL || client_hello.GetTaglist(kPDMD, &their_proof_demands, - &num_their_proof_demands) == + &num_their_proof_demands) != QUIC_NO_ERROR) { - for (size_t i = 0; i < num_their_proof_demands; i++) { - if (their_proof_demands[i] != kX509) { - continue; - } + return; + } - const vector<string>* certs; - string signature; - if (!proof_source_->GetProof(info.sni.as_string(), config->serialized, - &certs, &signature)) { + bool x509_supported = false, x509_ecdsa_supported = false; + for (size_t i = 0; i < num_their_proof_demands; i++) { + switch (their_proof_demands[i]) { + case kX509: + x509_supported = true; + x509_ecdsa_supported = true; + break; + case kX59R: + x509_supported = true; break; - } - - StringPiece their_common_set_hashes; - StringPiece their_cached_cert_hashes; - client_hello.GetStringPiece(kCCS, &their_common_set_hashes); - client_hello.GetStringPiece(kCCRT, &their_cached_cert_hashes); - - const string compressed = CertCompressor::CompressChain( - *certs, their_common_set_hashes, their_cached_cert_hashes, - config->common_cert_sets); - - // kMaxUnverifiedSize is the number of bytes that the certificate chain - // and signature can consume before we will demand a valid - // source-address token. - // TODO(agl): make this configurable. - static const size_t kMaxUnverifiedSize = 400; - if (info.valid_source_address_token || - signature.size() + compressed.size() < kMaxUnverifiedSize) { - out->SetStringPiece(kCertificateTag, compressed); - out->SetStringPiece(kPROF, signature); - } - break; } } + + if (!x509_supported) { + return; + } + + const vector<string>* certs; + string signature; + if (!proof_source_->GetProof(info.sni.as_string(), config->serialized, + x509_ecdsa_supported, &certs, &signature)) { + return; + } + + StringPiece their_common_set_hashes; + StringPiece their_cached_cert_hashes; + client_hello.GetStringPiece(kCCS, &their_common_set_hashes); + client_hello.GetStringPiece(kCCRT, &their_cached_cert_hashes); + + const string compressed = CertCompressor::CompressChain( + *certs, their_common_set_hashes, their_cached_cert_hashes, + config->common_cert_sets); + + // kREJOverheadBytes is a very rough estimate of how much of a REJ + // message is taken up by things other than the certificates. + const size_t kREJOverheadBytes = 112; + // kMaxUnverifiedSize is the number of bytes that the certificate chain + // and signature can consume before we will demand a valid source-address + // token. + const size_t kMaxUnverifiedSize = client_hello.size() - kREJOverheadBytes; + COMPILE_ASSERT(kClientHelloMinimumSize >= kREJOverheadBytes, + overhead_calculation_may_underflow); + if (info.valid_source_address_token || + signature.size() + compressed.size() < kMaxUnverifiedSize) { + out->SetStringPiece(kCertificateTag, compressed); + out->SetStringPiece(kPROF, signature); + } } scoped_refptr<QuicCryptoServerConfig::Config> diff --git a/net/quic/crypto/crypto_server_config.h b/net/quic/crypto/crypto_server_config.h index f4816b6..651e928 100644 --- a/net/quic/crypto/crypto_server_config.h +++ b/net/quic/crypto/crypto_server_config.h @@ -58,6 +58,9 @@ class NET_EXPORT_PRIVATE QuicCryptoServerConfig { // id contains the server config id for the resulting config. If empty, a // random id is generated. std::string id; + // orbit contains the kOrbitSize bytes of the orbit value for the server + // config. If |orbit| is empty then a random orbit is generated. + std::string orbit; }; // |source_address_token_secret|: secret key material used for encrypting and diff --git a/net/quic/crypto/proof_source.h b/net/quic/crypto/proof_source.h index b788a79..277549f 100644 --- a/net/quic/crypto/proof_source.h +++ b/net/quic/crypto/proof_source.h @@ -44,6 +44,7 @@ class NET_EXPORT_PRIVATE ProofSource { // This function may be called concurrently. virtual bool GetProof(const std::string& hostname, const std::string& server_config, + bool ecdsa_ok, const std::vector<std::string>** out_certs, std::string* out_signature) = 0; }; diff --git a/net/quic/crypto/proof_source_chromium.cc b/net/quic/crypto/proof_source_chromium.cc index 48c2b77..7522631 100644 --- a/net/quic/crypto/proof_source_chromium.cc +++ b/net/quic/crypto/proof_source_chromium.cc @@ -14,6 +14,7 @@ ProofSourceChromium::ProofSourceChromium() { bool ProofSourceChromium::GetProof(const string& hostname, const string& server_config, + bool ecdsa_ok, const vector<string>** out_certs, string* out_signature) { return false; diff --git a/net/quic/crypto/proof_source_chromium.h b/net/quic/crypto/proof_source_chromium.h index fb0b6a6..70ab92d 100644 --- a/net/quic/crypto/proof_source_chromium.h +++ b/net/quic/crypto/proof_source_chromium.h @@ -25,6 +25,7 @@ class NET_EXPORT_PRIVATE ProofSourceChromium : public ProofSource { // ProofSource interface virtual bool GetProof(const std::string& hostname, const std::string& server_config, + bool ecdsa_ok, const std::vector<std::string>** out_certs, std::string* out_signature) OVERRIDE; diff --git a/net/quic/crypto/proof_test.cc b/net/quic/crypto/proof_test.cc index 9aeab69..8facb82 100644 --- a/net/quic/crypto/proof_test.cc +++ b/net/quic/crypto/proof_test.cc @@ -35,9 +35,10 @@ TEST(Proof, Verify) { string error_details, signature, first_signature; CertVerifyResult cert_verify_result; - ASSERT_TRUE(source->GetProof(hostname, server_config, &first_certs, - &first_signature)); - ASSERT_TRUE(source->GetProof(hostname, server_config, &certs, &signature)); + ASSERT_TRUE(source->GetProof(hostname, server_config, false /* no ECDSA */, + &first_certs, &first_signature)); + ASSERT_TRUE(source->GetProof(hostname, server_config, false /* no ECDSA */, + &certs, &signature)); // Check that the proof source is caching correctly: ASSERT_EQ(first_certs, certs); diff --git a/net/quic/quic_connection.cc b/net/quic/quic_connection.cc index f407606..fef8445 100644 --- a/net/quic/quic_connection.cc +++ b/net/quic/quic_connection.cc @@ -69,8 +69,9 @@ bool Near(QuicPacketSequenceNumber a, QuicPacketSequenceNumber b) { QuicConnection::QuicConnection(QuicGuid guid, IPEndPoint address, QuicConnectionHelperInterface* helper, - bool is_server) - : framer_(kQuicVersion1, + bool is_server, + QuicVersion version) + : framer_(version, helper->GetClock()->ApproximateNow(), is_server), helper_(helper), @@ -106,7 +107,7 @@ QuicConnection::QuicConnection(QuicGuid guid, helper_->SetConnection(this); helper_->SetTimeoutAlarm(idle_network_timeout_); framer_.set_visitor(this); - framer_.set_entropy_calculator(&entropy_manager_); + framer_.set_received_entropy_calculator(&received_entropy_manager_); outgoing_ack_.sent_info.least_unacked = 0; outgoing_ack_.sent_info.entropy_hash = 0; outgoing_ack_.received_info.largest_observed = 0; @@ -133,17 +134,20 @@ QuicConnection::~QuicConnection() { } bool QuicConnection::SelectMutualVersion( - const QuicTagVector& available_versions) { - // TODO(satyamshekhar): Make this generic. - if (std::find(available_versions.begin(), available_versions.end(), - kQuicVersion1) == available_versions.end()) { - return false; + const QuicVersionVector& available_versions) { + // Try to find the highest mutual version by iterating over supported + // versions, starting with the highest, and breaking out of the loop once we + // find a matching version in the provided available_versions vector. + for (size_t i = 0; i < arraysize(kSupportedQuicVersions); ++i) { + const QuicVersion& version = kSupportedQuicVersions[i]; + if (std::find(available_versions.begin(), available_versions.end(), + version) != available_versions.end()) { + framer_.set_version(version); + return true; + } } - // Right now we only support kQuicVersion1 so it's okay not to - // update the framer version. When we start supporting more - // versions please update. - return true; + return false; } void QuicConnection::OnError(QuicFramer* framer) { @@ -166,7 +170,7 @@ void QuicConnection::OnPublicResetPacket( CloseConnection(QUIC_PUBLIC_RESET, true); } -bool QuicConnection::OnProtocolVersionMismatch(QuicTag received_version) { +bool QuicConnection::OnProtocolVersionMismatch(QuicVersion received_version) { // TODO(satyamshekhar): Implement no server state in this mode. if (!is_server_) { LOG(DFATAL) << ENDPOINT << "Framer called OnProtocolVersionMismatch. " @@ -205,10 +209,11 @@ bool QuicConnection::OnProtocolVersionMismatch(QuicTag received_version) { DCHECK(false); } - // Right now we only support kQuicVersion1 so it's okay not to - // update the framer version. When we start supporting more - // versions please update. version_negotiation_state_ = NEGOTIATED_VERSION; + + // Store the new version. + framer_.set_version(received_version); + // TODO(satyamshekhar): Store the sequence number of this packet and close the // connection if we ever received a packet with incorrect version and whose // sequence number is greater. @@ -408,7 +413,8 @@ bool QuicConnection::ValidateAckFrame(const QuicAckFrame& incoming_ack) { DLOG(ERROR) << ENDPOINT << "Peer's largest_observed packet decreased:" << incoming_ack.received_info.largest_observed << " vs " << peer_largest_observed_packet_; - // We got an error for data we have not sent. Error out. + // A new ack has a diminished largest_observed value. Error out. + // If this was an old packet, we wouldn't even have checked. return false; } @@ -454,7 +460,7 @@ bool QuicConnection::ValidateAckFrame(const QuicAckFrame& incoming_ack) { return false; } - if (!entropy_manager_.IsValidEntropy( + if (!sent_entropy_manager_.IsValidEntropy( incoming_ack.received_info.largest_observed, incoming_ack.received_info.missing_packets, incoming_ack.received_info.entropy_hash)) { @@ -544,7 +550,7 @@ void QuicConnection::UpdatePacketInformationReceivedByPeer( *(incoming_ack.received_info.missing_packets.begin()); } - entropy_manager_.ClearSentEntropyBefore(least_packet_awaited_by_peer_ - 1); + sent_entropy_manager_.ClearEntropyBefore(least_packet_awaited_by_peer_ - 1); SequenceNumberSet acked_packets; HandleAckForSentPackets(incoming_ack, &acked_packets); @@ -579,7 +585,7 @@ void QuicConnection::UpdatePacketInformationSentByPeer( DVLOG(1) << ENDPOINT << "Updating entropy hashed since we missed packets"; // There were some missing packets that we won't ever get now. Recalculate // the received entropy hash. - entropy_manager_.RecalculateReceivedEntropyHash( + received_entropy_manager_.RecalculateEntropyHash( incoming_ack.sent_info.least_unacked, incoming_ack.sent_info.entropy_hash); } @@ -697,8 +703,10 @@ void QuicConnection::MaybeSendAckInResponseToPacket() { } void QuicConnection::SendVersionNegotiationPacket() { - QuicTagVector supported_versions; - supported_versions.push_back(kQuicVersion1); + QuicVersionVector supported_versions; + for (size_t i = 0; i < arraysize(kSupportedQuicVersions); ++i) { + supported_versions.push_back(kSupportedQuicVersions[i]); + } QuicEncryptedPacket* encrypted = packet_creator_.SerializeVersionNegotiationPacket(supported_versions); // TODO(satyamshekhar): implement zero server state negotiation. @@ -864,8 +872,8 @@ void QuicConnection::RecordPacketReceived(const QuicPacketHeader& header) { header.packet_sequence_number; time_largest_observed_ = time_of_last_received_packet_; } - entropy_manager_.RecordReceivedPacketEntropyHash(sequence_number, - header.entropy_hash); + received_entropy_manager_.RecordPacketEntropyHash( + sequence_number, header.entropy_hash); } bool QuicConnection::MaybeRetransmitPacketForRTO( @@ -1160,7 +1168,7 @@ int QuicConnection::WritePacketToWire(QuicPacketSequenceNumber sequence_number, int bytes_written = helper_->WritePacketToWire(packet, error); if (debug_visitor_) { // WritePacketToWire returned -1, then |error| will be populated with - // a NetErrorCode, which we want to pass along to the visitor. + // an error code, which we want to pass along to the visitor. debug_visitor_->OnPacketSent(sequence_number, level, packet, bytes_written == -1 ? *error : bytes_written); } @@ -1203,7 +1211,7 @@ bool QuicConnection::SendOrQueuePacket(EncryptionLevel level, QuicPacket* packet, QuicPacketEntropyHash entropy_hash, HasRetransmittableData retransmittable) { - entropy_manager_.RecordSentPacketEntropyHash(sequence_number, entropy_hash); + sent_entropy_manager_.RecordPacketEntropyHash(sequence_number, entropy_hash); if (!WritePacket(level, sequence_number, packet, retransmittable, NO_FORCE)) { queued_packets_.push_back(QueuedPacket(sequence_number, packet, level, retransmittable)); @@ -1231,10 +1239,10 @@ void QuicConnection::UpdateOutgoingAck() { outgoing_ack_.sent_info.least_unacked = packet_creator_.sequence_number() + 1; } - outgoing_ack_.sent_info.entropy_hash = entropy_manager_.SentEntropyHash( + outgoing_ack_.sent_info.entropy_hash = sent_entropy_manager_.EntropyHash( outgoing_ack_.sent_info.least_unacked - 1); outgoing_ack_.received_info.entropy_hash = - entropy_manager_.ReceivedEntropyHash( + received_entropy_manager_.EntropyHash( outgoing_ack_.received_info.largest_observed); } @@ -1446,8 +1454,8 @@ void QuicConnection::SendConnectionClosePacket(QuicErrorCode error, SerializedPacket serialized_packet = packet_creator_.SerializeConnectionClose(&frame); - // We need to update the sent entrophy hash for all sent packets. - entropy_manager_.RecordSentPacketEntropyHash( + // We need to update the sent entropy hash for all sent packets. + sent_entropy_manager_.RecordPacketEntropyHash( serialized_packet.sequence_number, serialized_packet.entropy_hash); diff --git a/net/quic/quic_connection.h b/net/quic/quic_connection.h index d869937..3fd80f0 100644 --- a/net/quic/quic_connection.h +++ b/net/quic/quic_connection.h @@ -30,9 +30,10 @@ #include "net/quic/quic_blocked_writer_interface.h" #include "net/quic/quic_framer.h" #include "net/quic/quic_packet_creator.h" -#include "net/quic/quic_packet_entropy_manager.h" #include "net/quic/quic_packet_generator.h" #include "net/quic/quic_protocol.h" +#include "net/quic/quic_received_entropy_manager.h" +#include "net/quic/quic_sent_entropy_manager.h" #include "net/quic/quic_stats.h" namespace net { @@ -101,7 +102,7 @@ class NET_EXPORT_PRIVATE QuicConnectionDebugVisitorInterface // Called when the protocol version on the received packet doensn't match // current protocol version of the connection. - virtual void OnProtocolVersionMismatch(QuicTag version) = 0; + virtual void OnProtocolVersionMismatch(QuicVersion version) = 0; // Called when the complete header of a packet has been parsed. virtual void OnPacketHeader(const QuicPacketHeader& header) = 0; @@ -220,7 +221,8 @@ class NET_EXPORT_PRIVATE QuicConnection QuicConnection(QuicGuid guid, IPEndPoint address, QuicConnectionHelperInterface* helper, - bool is_server); + bool is_server, + QuicVersion version); virtual ~QuicConnection(); static void DeleteEnclosedFrame(QuicFrame* frame); @@ -276,11 +278,11 @@ class NET_EXPORT_PRIVATE QuicConnection bool ProcessValidatedPacket(); // The version of the protocol this connection is using. - QuicTag version() const { return framer_.version(); } + QuicVersion version() const { return framer_.version(); } // From QuicFramerVisitorInterface virtual void OnError(QuicFramer* framer) OVERRIDE; - virtual bool OnProtocolVersionMismatch(QuicTag received_version) OVERRIDE; + virtual bool OnProtocolVersionMismatch(QuicVersion received_version) OVERRIDE; virtual void OnPacket() OVERRIDE; virtual void OnPublicResetPacket( const QuicPublicResetPacket& packet) OVERRIDE; @@ -448,7 +450,11 @@ class NET_EXPORT_PRIVATE QuicConnection QuicConnectionHelperInterface* helper() { return helper_.get(); } - protected: + // Selects and updates the version of the protocol being used by selecting a + // version from |available_versions| which is also supported. Returns true if + // such a version exists, false otherwise. + bool SelectMutualVersion(const QuicVersionVector& available_versions); + QuicFramer framer_; private: @@ -519,10 +525,6 @@ class NET_EXPORT_PRIVATE QuicConnection RetransmissionTimeComparator> RetransmissionTimeouts; - // Selects and updates the version of the protocol being used by selecting a - // version from |available_versions| which is also supported. Returns true if - // such a version exists, false otherwise. - bool SelectMutualVersion(const QuicTagVector& available_versions); // Sends a version negotiation packet to the peer. void SendVersionNegotiationPacket(); @@ -651,7 +653,8 @@ class NET_EXPORT_PRIVATE QuicConnection FecGroupMap group_map_; - QuicPacketEntropyManager entropy_manager_; + QuicReceivedEntropyManager received_entropy_manager_; + QuicSentEntropyManager sent_entropy_manager_; QuicConnectionVisitorInterface* visitor_; QuicConnectionDebugVisitorInterface* debug_visitor_; diff --git a/net/quic/quic_connection_helper_test.cc b/net/quic/quic_connection_helper_test.cc index c9c7ba5..21ff95b 100644 --- a/net/quic/quic_connection_helper_test.cc +++ b/net/quic/quic_connection_helper_test.cc @@ -30,7 +30,7 @@ class TestConnection : public QuicConnection { TestConnection(QuicGuid guid, IPEndPoint address, QuicConnectionHelper* helper) - : QuicConnection(guid, address, helper, false) { + : QuicConnection(guid, address, helper, false, QuicVersionMax()) { } void SendAck() { @@ -59,7 +59,7 @@ class QuicConnectionHelperTest : public ::testing::Test { QuicConnectionHelperTest() : guid_(2), - framer_(kQuicVersion1, QuicTime::Zero(), false), + framer_(QuicVersionMax(), QuicTime::Zero(), false), net_log_(BoundNetLog()), frame_(1, false, 0, kData) { Initialize(); @@ -304,6 +304,9 @@ TEST_F(QuicConnectionHelperTest, TestRetransmission) { AddWrite(SYNCHRONOUS, ConstructDataPacket(2)); Initialize(); + EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly( + testing::Return(QuicTime::Delta::Zero())); + QuicTime::Delta kDefaultRetransmissionTime = QuicTime::Delta::FromMilliseconds(500); QuicTime start = clock_.ApproximateNow(); @@ -328,6 +331,9 @@ TEST_F(QuicConnectionHelperTest, TestMultipleRetransmission) { AddWrite(SYNCHRONOUS, ConstructDataPacket(3)); Initialize(); + EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly( + testing::Return(QuicTime::Delta::Zero())); + QuicTime::Delta kDefaultRetransmissionTime = QuicTime::Delta::FromMilliseconds(500); QuicTime start = clock_.ApproximateNow(); @@ -442,6 +448,8 @@ TEST_F(QuicConnectionHelperTest, SendSchedulerDelayThenSend) { Initialize(); // Test that if we send a packet with a delay, it ends up queued. + EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly( + testing::Return(QuicTime::Delta::Zero())); EXPECT_CALL( *send_algorithm_, TimeUntilSend(_, NOT_RETRANSMISSION, _)).WillOnce( testing::Return(QuicTime::Delta::FromMicroseconds(1))); diff --git a/net/quic/quic_connection_logger.cc b/net/quic/quic_connection_logger.cc index 0ca1802..3405cd0 100644 --- a/net/quic/quic_connection_logger.cc +++ b/net/quic/quic_connection_logger.cc @@ -225,7 +225,8 @@ void QuicConnectionLogger::OnPacketReceived(const IPEndPoint& self_address, packet.length())); } -void QuicConnectionLogger::OnProtocolVersionMismatch(QuicTag received_version) { +void QuicConnectionLogger::OnProtocolVersionMismatch( + QuicVersion received_version) { // TODO(rtenneti): Add logging. } diff --git a/net/quic/quic_connection_logger.h b/net/quic/quic_connection_logger.h index 81a5441..1d2bd2d 100644 --- a/net/quic/quic_connection_logger.h +++ b/net/quic/quic_connection_logger.h @@ -32,7 +32,7 @@ class NET_EXPORT_PRIVATE QuicConnectionLogger virtual void OnPacketReceived(const IPEndPoint& self_address, const IPEndPoint& peer_address, const QuicEncryptedPacket& packet) OVERRIDE; - virtual void OnProtocolVersionMismatch(QuicTag version) OVERRIDE; + virtual void OnProtocolVersionMismatch(QuicVersion version) OVERRIDE; virtual void OnPacketHeader(const QuicPacketHeader& header) OVERRIDE; virtual void OnStreamFrame(const QuicStreamFrame& frame) OVERRIDE; virtual void OnAckFrame(const QuicAckFrame& frame) OVERRIDE; diff --git a/net/quic/quic_connection_test.cc b/net/quic/quic_connection_test.cc index b170d0d..274f868 100644 --- a/net/quic/quic_connection_test.cc +++ b/net/quic/quic_connection_test.cc @@ -13,6 +13,7 @@ #include "net/quic/crypto/quic_decrypter.h" #include "net/quic/crypto/quic_encrypter.h" #include "net/quic/crypto/quic_random.h" +#include "net/quic/quic_protocol.h" #include "net/quic/quic_utils.h" #include "net/quic/test_tools/mock_clock.h" #include "net/quic/test_tools/mock_random.h" @@ -250,7 +251,7 @@ class TestConnectionHelper : public QuicConnectionHelperInterface { sizeof(final_bytes_of_last_packet_)); } - QuicFramer framer(kQuicVersion1, QuicTime::Zero(), is_server_); + QuicFramer framer(QuicVersionMax(), QuicTime::Zero(), is_server_); if (use_tagging_decrypter_) { framer.SetDecrypter(new TaggingDecrypter); } @@ -380,7 +381,7 @@ class TestConnection : public QuicConnection { IPEndPoint address, TestConnectionHelper* helper, bool is_server) - : QuicConnection(guid, address, helper, is_server), + : QuicConnection(guid, address, helper, is_server, QuicVersionMax()), helper_(helper) { helper_->set_is_server(!is_server); } @@ -409,6 +410,10 @@ class TestConnection : public QuicConnection { return QuicConnectionPeer::IsServer(this); } + void set_version(QuicVersion version) { + framer_.set_version(version); + } + void set_is_server(bool is_server) { helper_->set_is_server(!is_server); QuicPacketCreatorPeer::SetIsServer( @@ -418,6 +423,7 @@ class TestConnection : public QuicConnection { using QuicConnection::SendOrQueuePacket; using QuicConnection::DontWaitForPacketsBefore; + using QuicConnection::SelectMutualVersion; private: TestConnectionHelper* helper_; @@ -429,7 +435,7 @@ class QuicConnectionTest : public ::testing::Test { protected: QuicConnectionTest() : guid_(42), - framer_(kQuicVersion1, QuicTime::Zero(), false), + framer_(QuicVersionMax(), QuicTime::Zero(), false), creator_(guid_, &framer_, QuicRandom::GetInstance(), false), send_algorithm_(new StrictMock<MockSendAlgorithm>), helper_(new TestConnectionHelper(&clock_, &random_generator_)), @@ -446,6 +452,8 @@ class QuicConnectionTest : public ::testing::Test { EXPECT_CALL(*receive_algorithm_, RecordIncomingPacket(_, _, _, _)).Times(AnyNumber()); EXPECT_CALL(*send_algorithm_, SentPacket(_, _, _, _)).Times(AnyNumber()); + EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly( + Return(QuicTime::Delta::Zero())); } QuicAckFrame* outgoing_ack() { @@ -823,6 +831,25 @@ TEST_F(QuicConnectionTest, TruncatedAck) { EXPECT_FALSE(QuicConnectionPeer::GetReceivedTruncatedAck(&connection_)); } +TEST_F(QuicConnectionTest, DISABLED_AckReceiptCausesAckSend) { + ProcessPacket(1); + // Delay sending, then queue up an ack. + EXPECT_CALL(*send_algorithm_, + TimeUntilSend(_, NOT_RETRANSMISSION, _)).WillOnce( + testing::Return(QuicTime::Delta::FromMicroseconds(1))); + QuicConnectionPeer::SendAck(&connection_); + + // Process an ack with a least unacked of the received ack. + // This causes an ack to be sent when TimeUntilSend returns 0. + EXPECT_CALL(*send_algorithm_, + TimeUntilSend(_, NOT_RETRANSMISSION, _)).WillRepeatedly( + testing::Return(QuicTime::Delta::Zero())); + // Skip a packet and then record an ack. + creator_.set_sequence_number(2); + QuicAckFrame frame(0, QuicTime::Zero(), 3); + ProcessAckPacket(&frame, true); +} + TEST_F(QuicConnectionTest, LeastUnackedLower) { SendStreamDataToPeer(1, "foo", 0, !kFin, NULL); SendStreamDataToPeer(1, "bar", 3, !kFin, NULL); @@ -2093,8 +2120,9 @@ TEST_F(QuicConnectionTest, CheckSentEntropyHash) { // TODO(satyamsehkhar): Add more test when we start supporting more versions. TEST_F(QuicConnectionTest, SendVersionNegotiationPacket) { - QuicTag kRandomVersion = 143; - QuicFramerPeer::SetVersion(&framer_, kRandomVersion); + // TODO(rjshade): Update this to use a real version once we have multiple + // versions in the codebase. + framer_.set_version_for_tests(QUIC_VERSION_UNSUPPORTED); QuicPacketHeader header; header.public_header.guid = guid_; @@ -2113,14 +2141,21 @@ TEST_F(QuicConnectionTest, SendVersionNegotiationPacket) { scoped_ptr<QuicEncryptedPacket> encrypted( framer_.EncryptPacket(ENCRYPTION_NONE, 12, *packet)); - QuicFramerPeer::SetVersion(&framer_, kQuicVersion1); + framer_.set_version(QuicVersionMax()); connection_.set_is_server(true); connection_.ProcessUdpPacket(IPEndPoint(), IPEndPoint(), *encrypted); EXPECT_TRUE(helper_->version_negotiation_packet() != NULL); - EXPECT_EQ(1u, + + size_t num_versions = arraysize(kSupportedQuicVersions); + EXPECT_EQ(num_versions, helper_->version_negotiation_packet()->versions.size()); - EXPECT_EQ(kQuicVersion1, - helper_->version_negotiation_packet()->versions[0]); + + // We expect all versions in kSupportedQuicVersions to be + // included in the packet. + for (size_t i = 0; i < num_versions; ++i) { + EXPECT_EQ(kSupportedQuicVersions[i], + helper_->version_negotiation_packet()->versions[i]); + } } TEST_F(QuicConnectionTest, CheckSendStats) { @@ -2251,6 +2286,27 @@ TEST_F(QuicConnectionTest, DontProcessFramesIfPacketClosedConnection) { connection_.ProcessUdpPacket(IPEndPoint(), IPEndPoint(), *encrypted); } +//// The QUIC_VERSION_X versions are deliberately set, rather than using all +//// values in kSupportedQuicVersions. +//TEST_F(QuicConnectionTest, SelectMutualVersion) { +// // Set the connection to speak QUIC_VERSION_6. +// connection_.set_version(QUIC_VERSION_6); +// EXPECT_EQ(connection_.version(), QUIC_VERSION_6); +// +// // Pass in available versions which includes a higher mutually supported +// // version. The higher mutually supported version should be selected. +// EXPECT_TRUE( +// connection_.SelectMutualVersion({QUIC_VERSION_6, QUIC_VERSION_7})); +// EXPECT_EQ(connection_.version(), QUIC_VERSION_7); +// +// // Expect that the lower version is selected. +// EXPECT_TRUE(connection_.SelectMutualVersion({QUIC_VERSION_6})); +// EXPECT_EQ(connection_.version(), QUIC_VERSION_6); +// +// // Shouldn't be able to find a mutually supported version. +// EXPECT_FALSE(connection_.SelectMutualVersion({QUIC_VERSION_UNSUPPORTED})); +//} + } // namespace } // namespace test } // namespace net diff --git a/net/quic/quic_crypto_server_stream_test.cc b/net/quic/quic_crypto_server_stream_test.cc index fb829db..5f72739 100644 --- a/net/quic/quic_crypto_server_stream_test.cc +++ b/net/quic/quic_crypto_server_stream_test.cc @@ -122,12 +122,11 @@ TEST_F(QuicCryptoServerStreamTest, ConnectedAfterCHLO) { // CompleteCryptoHandshake returns the number of client hellos sent. This // test should send: - // * One to get a source-address token. + // * One to get a source-address token and certificates. // * One to complete the handshake. // TODO(rtenneti): Until we set the crypto_config.SetProofVerifier to enable // ProofVerifier in CryptoTestUtils::HandshakeWithFakeClient, we would not // have sent the following client hello. - // * One to get the server's certificates EXPECT_EQ(2, CompleteCryptoHandshake()); EXPECT_TRUE(stream_.encryption_established()); EXPECT_TRUE(stream_.handshake_confirmed()); diff --git a/net/quic/quic_framer.cc b/net/quic/quic_framer.cc index 1df3590..e4484f6 100644 --- a/net/quic/quic_framer.cc +++ b/net/quic/quic_framer.cc @@ -53,7 +53,7 @@ QuicPacketSequenceNumber ClosestTo(QuicPacketSequenceNumber target, } // namespace -QuicFramer::QuicFramer(QuicTag version, +QuicFramer::QuicFramer(QuicVersion version, QuicTime creation_time, bool is_server) : visitor_(NULL), @@ -142,8 +142,13 @@ size_t QuicFramer::GetStreamOffsetSize(QuicStreamOffset offset) { return 8; } -bool QuicFramer::IsSupportedVersion(QuicTag version) { - return version == kQuicVersion1; +bool QuicFramer::IsSupportedVersion(const QuicVersion version) const { + for (size_t i = 0; i < arraysize(kSupportedQuicVersions); ++i) { + if (version == kSupportedQuicVersions[i]) { + return true; + } + } + return false; } size_t QuicFramer::GetVersionNegotiationPacketSize(size_t number_versions) { @@ -342,7 +347,7 @@ QuicEncryptedPacket* QuicFramer::ConstructPublicResetPacket( QuicEncryptedPacket* QuicFramer::ConstructVersionNegotiationPacket( const QuicPacketPublicHeader& header, - const QuicTagVector& supported_versions) { + const QuicVersionVector& supported_versions) { DCHECK(header.version_flag); size_t len = GetVersionNegotiationPacketSize(supported_versions.size()); QuicDataWriter writer(len); @@ -359,7 +364,7 @@ QuicEncryptedPacket* QuicFramer::ConstructVersionNegotiationPacket( } for (size_t i = 0; i < supported_versions.size(); ++i) { - if (!writer.WriteUInt32(supported_versions[i])) { + if (!writer.WriteUInt32(QuicVersionToQuicTag(supported_versions[i]))) { return NULL; } } @@ -413,7 +418,7 @@ bool QuicFramer::ProcessVersionNegotiationPacket( set_detailed_error("Unable to read supported version in negotiation."); return RaiseError(QUIC_INVALID_VERSION_NEGOTIATION_PACKET); } - public_header->versions.push_back(version); + public_header->versions.push_back(QuicTagToQuicVersion(version)); } while (!reader_->IsDoneReading()); visitor_->OnVersionNegotiationPacket(*public_header); @@ -568,7 +573,7 @@ bool QuicFramer::WritePacketHeader(const QuicPacketHeader& header, if (header.public_header.version_flag) { DCHECK(!is_server_); - writer->WriteUInt32(quic_version_); + writer->WriteUInt32(QuicVersionToQuicTag(quic_version_)); } if (!AppendPacketSequenceNumber(header.public_header.sequence_number_length, @@ -712,14 +717,19 @@ bool QuicFramer::ProcessPublicHeader( break; } + // Read the version only if the packet is from the client. + // version flag from the server means version negotiation packet. if (public_header->version_flag && is_server_) { - QuicTag version; - if (!reader_->ReadUInt32(&version)) { - // Read the version only if the packet is from the client. - // version flag from the server means version negotiation packet. + QuicTag version_tag; + if (!reader_->ReadUInt32(&version_tag)) { set_detailed_error("Unable to read protocol version."); return false; } + + // If the version from the new packet is the same as the version of this + // framer, then the public flags should be set to something we understand. + // If not, this raises an error. + QuicVersion version = QuicTagToQuicVersion(version_tag); if (version == quic_version_ && public_flags > PACKET_PUBLIC_FLAGS_MAX) { set_detailed_error("Illegal public flags value."); return false; @@ -1549,7 +1559,7 @@ bool QuicFramer::AppendAckFramePayload( CalculateLargestObserved(frame.received_info.missing_packets, --it); // Overwrite entropy hash for received packets. writer->WriteUInt8ToOffset( - entropy_calculator_->ReceivedEntropyHash(largest_observed), + entropy_calculator_->EntropyHash(largest_observed), received_entropy_offset); // Overwrite largest_observed. writer->WriteUInt48ToOffset(largest_observed & k6ByteSequenceNumberMask, diff --git a/net/quic/quic_framer.h b/net/quic/quic_framer.h index dd3eaef..b62d56f 100644 --- a/net/quic/quic_framer.h +++ b/net/quic/quic_framer.h @@ -64,7 +64,7 @@ class NET_EXPORT_PRIVATE QuicFramerVisitorInterface { // |quic_version_|. The visitor should return true after it updates the // version of the |framer_| to |received_version| or false to stop processing // this packet. - virtual bool OnProtocolVersionMismatch(QuicTag received_version) = 0; + virtual bool OnProtocolVersionMismatch(QuicVersion received_version) = 0; // Called when a new packet has been received, before it // has been validated or processed. @@ -141,7 +141,7 @@ class NET_EXPORT_PRIVATE QuicReceivedEntropyHashCalculatorInterface { // missing packets are not added and the largest observed might be lowered. // This should return the received entropy hash of the packets received up to // and including |sequence_number|. - virtual QuicPacketEntropyHash ReceivedEntropyHash( + virtual QuicPacketEntropyHash EntropyHash( QuicPacketSequenceNumber sequence_number) const = 0; }; @@ -153,14 +153,14 @@ class NET_EXPORT_PRIVATE QuicFramer { public: // Constructs a new framer that installs a kNULL QuicEncrypter and // QuicDecrypter for level ENCRYPTION_NONE. - QuicFramer(QuicTag quic_version, + QuicFramer(QuicVersion quic_version, QuicTime creation_time, bool is_server); virtual ~QuicFramer(); // Returns true if |version| is a supported protocol version. - bool IsSupportedVersion(QuicTag version); + bool IsSupportedVersion(const QuicVersion version) const; // Calculates the largest observed packet to advertise in the case an Ack // Frame was truncated. last_written in this case is the iterator for the @@ -184,20 +184,26 @@ class NET_EXPORT_PRIVATE QuicFramer { fec_builder_ = builder; } - QuicTag version() const { + QuicVersion version() const { return quic_version_; } - void set_version(QuicTag version) { + void set_version(const QuicVersion version) { DCHECK(IsSupportedVersion(version)); quic_version_ = version; } + // Does not DCHECK for supported version. Used by tests to set unsupported + // version to trigger version negotiation. + void set_version_for_tests(const QuicVersion version) { + quic_version_ = version; + } + // Set entropy calculator to be called from the framer when it needs the // entropy of a truncated ack frame. An entropy calculator must be set or else // the framer will likely crash. If this is called multiple times, only the - // last visitor will be used. - void set_entropy_calculator( + // last calculator will be used. + void set_received_entropy_calculator( QuicReceivedEntropyHashCalculatorInterface* entropy_calculator) { entropy_calculator_ = entropy_calculator; } @@ -285,7 +291,7 @@ class NET_EXPORT_PRIVATE QuicFramer { QuicEncryptedPacket* ConstructVersionNegotiationPacket( const QuicPacketPublicHeader& header, - const QuicTagVector& supported_versions); + const QuicVersionVector& supported_versions); // SetDecrypter sets the primary decrypter, replacing any that already exists, // and takes ownership. If an alternative decrypter is in place then the @@ -419,7 +425,7 @@ class NET_EXPORT_PRIVATE QuicFramer { // Buffer containing decrypted payload data during parsing. scoped_ptr<QuicData> decrypted_; // Version of the protocol being used. - QuicTag quic_version_; + QuicVersion quic_version_; // Primary decrypter used to decrypt packets during parsing. scoped_ptr<QuicDecrypter> decrypter_; // Alternative decrypter that can also be used to decrypt packets. diff --git a/net/quic/quic_framer_test.cc b/net/quic/quic_framer_test.cc index 97c0ac6..b7a4e30 100644 --- a/net/quic/quic_framer_test.cc +++ b/net/quic/quic_framer_test.cc @@ -221,7 +221,7 @@ class TestQuicVisitor : public ::net::QuicFramerVisitorInterface { revived_packets_++; } - virtual bool OnProtocolVersionMismatch(QuicTag version) OVERRIDE { + virtual bool OnProtocolVersionMismatch(QuicVersion version) OVERRIDE { DLOG(INFO) << "QuicFramer Version Mismatch, version: " << version; version_mismatch_++; return true; @@ -305,17 +305,20 @@ class TestQuicVisitor : public ::net::QuicFramerVisitorInterface { QuicGoAwayFrame goaway_frame_; }; -class QuicFramerTest : public ::testing::Test { +class QuicFramerTest : public ::testing::TestWithParam<QuicVersion> { public: QuicFramerTest() : encrypter_(new test::TestEncrypter()), decrypter_(new test::TestDecrypter()), start_(QuicTime::Zero().Add(QuicTime::Delta::FromMicroseconds(0x10))), - framer_(kQuicVersion1, start_, true) { + framer_(QuicVersionMax(), start_, true) { framer_.SetDecrypter(decrypter_); framer_.SetEncrypter(ENCRYPTION_NONE, encrypter_); framer_.set_visitor(&visitor_); - framer_.set_entropy_calculator(&entropy_calculator_); + framer_.set_received_entropy_calculator(&entropy_calculator_); + + QuicVersion version = GetParam(); + framer_.set_version(version); } bool CheckEncryption(QuicPacketSequenceNumber sequence_number, @@ -415,7 +418,12 @@ class QuicFramerTest : public ::testing::Test { test::TestEntropyCalculator entropy_calculator_; }; -TEST_F(QuicFramerTest, CalculatePacketSequenceNumberFromWireNearEpochStart) { +// Run all framer tests with QUIC version 6. +INSTANTIATE_TEST_CASE_P(QuicFramerTests, + QuicFramerTest, + ::testing::Values(QUIC_VERSION_6)); + +TEST_P(QuicFramerTest, CalculatePacketSequenceNumberFromWireNearEpochStart) { // A few quick manual sanity checks CheckCalculatePacketSequenceNumber(GG_UINT64_C(1), GG_UINT64_C(0)); CheckCalculatePacketSequenceNumber(kEpoch + 1, kMask); @@ -435,7 +443,7 @@ TEST_F(QuicFramerTest, CalculatePacketSequenceNumberFromWireNearEpochStart) { } } -TEST_F(QuicFramerTest, CalculatePacketSequenceNumberFromWireNearEpochEnd) { +TEST_P(QuicFramerTest, CalculatePacketSequenceNumberFromWireNearEpochEnd) { // Cases where the last number was close to the end of the range for (uint64 i = 0; i < 10; i++) { QuicPacketSequenceNumber last = kEpoch - i; @@ -454,7 +462,7 @@ TEST_F(QuicFramerTest, CalculatePacketSequenceNumberFromWireNearEpochEnd) { // Next check where we're in a non-zero epoch to verify we handle // reverse wrapping, too. -TEST_F(QuicFramerTest, CalculatePacketSequenceNumberFromWireNearPrevEpoch) { +TEST_P(QuicFramerTest, CalculatePacketSequenceNumberFromWireNearPrevEpoch) { const uint64 prev_epoch = 1 * kEpoch; const uint64 cur_epoch = 2 * kEpoch; // Cases where the last number was close to the start of the range @@ -473,7 +481,7 @@ TEST_F(QuicFramerTest, CalculatePacketSequenceNumberFromWireNearPrevEpoch) { } } -TEST_F(QuicFramerTest, CalculatePacketSequenceNumberFromWireNearNextEpoch) { +TEST_P(QuicFramerTest, CalculatePacketSequenceNumberFromWireNearNextEpoch) { const uint64 cur_epoch = 2 * kEpoch; const uint64 next_epoch = 3 * kEpoch; // Cases where the last number was close to the end of the range @@ -493,7 +501,7 @@ TEST_F(QuicFramerTest, CalculatePacketSequenceNumberFromWireNearNextEpoch) { } } -TEST_F(QuicFramerTest, CalculatePacketSequenceNumberFromWireNearNextMax) { +TEST_P(QuicFramerTest, CalculatePacketSequenceNumberFromWireNearNextMax) { const uint64 max_number = numeric_limits<uint64>::max(); const uint64 max_epoch = max_number & ~kMask; @@ -516,14 +524,14 @@ TEST_F(QuicFramerTest, CalculatePacketSequenceNumberFromWireNearNextMax) { } } -TEST_F(QuicFramerTest, EmptyPacket) { +TEST_P(QuicFramerTest, EmptyPacket) { char packet[] = { 0x00 }; QuicEncryptedPacket encrypted(packet, 0, false); EXPECT_FALSE(framer_.ProcessPacket(encrypted)); EXPECT_EQ(QUIC_INVALID_PACKET_HEADER, framer_.error()); } -TEST_F(QuicFramerTest, LargePacket) { +TEST_P(QuicFramerTest, LargePacket) { unsigned char packet[kMaxPacketSize + 1] = { // public flags (8 byte guid) 0x3C, @@ -555,7 +563,7 @@ TEST_F(QuicFramerTest, LargePacket) { EXPECT_EQ(QUIC_PACKET_TOO_LARGE, framer_.error()); } -TEST_F(QuicFramerTest, PacketHeader) { +TEST_P(QuicFramerTest, PacketHeader) { unsigned char packet[] = { // public flags (8 byte guid) 0x3C, @@ -606,7 +614,7 @@ TEST_F(QuicFramerTest, PacketHeader) { } } -TEST_F(QuicFramerTest, PacketHeaderWith4ByteGuid) { +TEST_P(QuicFramerTest, PacketHeaderWith4ByteGuid) { QuicFramerPeer::SetLastSerializedGuid(&framer_, GG_UINT64_C(0xFEDCBA9876543210)); @@ -661,7 +669,7 @@ TEST_F(QuicFramerTest, PacketHeaderWith4ByteGuid) { } } -TEST_F(QuicFramerTest, PacketHeader1ByteGuid) { +TEST_P(QuicFramerTest, PacketHeader1ByteGuid) { QuicFramerPeer::SetLastSerializedGuid(&framer_, GG_UINT64_C(0xFEDCBA9876543210)); @@ -715,7 +723,7 @@ TEST_F(QuicFramerTest, PacketHeader1ByteGuid) { } } -TEST_F(QuicFramerTest, PacketHeaderWith0ByteGuid) { +TEST_P(QuicFramerTest, PacketHeaderWith0ByteGuid) { QuicFramerPeer::SetLastSerializedGuid(&framer_, GG_UINT64_C(0xFEDCBA9876543210)); @@ -768,7 +776,10 @@ TEST_F(QuicFramerTest, PacketHeaderWith0ByteGuid) { } } -TEST_F(QuicFramerTest, PacketHeaderWithVersionFlag) { +TEST_P(QuicFramerTest, PacketHeaderWithVersionFlag) { + // Set a specific version. + framer_.set_version(QUIC_VERSION_6); + unsigned char packet[] = { // public flags (version) 0x3D, @@ -792,7 +803,7 @@ TEST_F(QuicFramerTest, PacketHeaderWithVersionFlag) { visitor_.header_->public_header.guid); EXPECT_FALSE(visitor_.header_->public_header.reset_flag); EXPECT_TRUE(visitor_.header_->public_header.version_flag); - EXPECT_EQ(kQuicVersion1, visitor_.header_->public_header.versions[0]); + EXPECT_EQ(QUIC_VERSION_6, visitor_.header_->public_header.versions[0]); EXPECT_FALSE(visitor_.header_->fec_flag); EXPECT_FALSE(visitor_.header_->entropy_flag); EXPECT_EQ(0, visitor_.header_->entropy_hash); @@ -824,7 +835,7 @@ TEST_F(QuicFramerTest, PacketHeaderWithVersionFlag) { } } -TEST_F(QuicFramerTest, PacketHeaderWith4ByteSequenceNumber) { +TEST_P(QuicFramerTest, PacketHeaderWith4ByteSequenceNumber) { QuicFramerPeer::SetLastSequenceNumber(&framer_, GG_UINT64_C(0x123456789ABA)); @@ -879,7 +890,7 @@ TEST_F(QuicFramerTest, PacketHeaderWith4ByteSequenceNumber) { } } -TEST_F(QuicFramerTest, PacketHeaderWith2ByteSequenceNumber) { +TEST_P(QuicFramerTest, PacketHeaderWith2ByteSequenceNumber) { QuicFramerPeer::SetLastSequenceNumber(&framer_, GG_UINT64_C(0x123456789ABA)); @@ -934,7 +945,7 @@ TEST_F(QuicFramerTest, PacketHeaderWith2ByteSequenceNumber) { } } -TEST_F(QuicFramerTest, PacketHeaderWith1ByteSequenceNumber) { +TEST_P(QuicFramerTest, PacketHeaderWith1ByteSequenceNumber) { QuicFramerPeer::SetLastSequenceNumber(&framer_, GG_UINT64_C(0x123456789ABA)); @@ -989,9 +1000,9 @@ TEST_F(QuicFramerTest, PacketHeaderWith1ByteSequenceNumber) { } } -TEST_F(QuicFramerTest, InvalidPublicFlag) { +TEST_P(QuicFramerTest, InvalidPublicFlag) { unsigned char packet[] = { - // public flags + // public flags, unknown flag at bit 6 0x40, // guid 0x10, 0x32, 0x54, 0x76, @@ -1026,7 +1037,10 @@ TEST_F(QuicFramerTest, InvalidPublicFlag) { QUIC_INVALID_PACKET_HEADER); }; -TEST_F(QuicFramerTest, InvalidPublicFlagWithMatchingVersions) { +TEST_P(QuicFramerTest, InvalidPublicFlagWithMatchingVersions) { + // Set a specific version. + framer_.set_version(QUIC_VERSION_6); + unsigned char packet[] = { // public flags (8 byte guid and version flag and an unknown flag) 0x4D, @@ -1065,7 +1079,7 @@ TEST_F(QuicFramerTest, InvalidPublicFlagWithMatchingVersions) { QUIC_INVALID_PACKET_HEADER); }; -TEST_F(QuicFramerTest, LargePublicFlagWithMismatchedVersions) { +TEST_P(QuicFramerTest, LargePublicFlagWithMismatchedVersions) { unsigned char packet[] = { // public flags (8 byte guid, version flag and an unknown flag) 0x7D, @@ -1091,7 +1105,7 @@ TEST_F(QuicFramerTest, LargePublicFlagWithMismatchedVersions) { EXPECT_EQ(1, visitor_.version_mismatch_); }; -TEST_F(QuicFramerTest, InvalidPrivateFlag) { +TEST_P(QuicFramerTest, InvalidPrivateFlag) { unsigned char packet[] = { // public flags (8 byte guid) 0x3C, @@ -1128,7 +1142,7 @@ TEST_F(QuicFramerTest, InvalidPrivateFlag) { QUIC_INVALID_PACKET_HEADER); }; -TEST_F(QuicFramerTest, PaddingFrame) { +TEST_P(QuicFramerTest, PaddingFrame) { unsigned char packet[] = { // public flags (8 byte guid) 0x3C, @@ -1171,7 +1185,7 @@ TEST_F(QuicFramerTest, PaddingFrame) { "Unable to read frame type.", QUIC_INVALID_FRAME_DATA); } -TEST_F(QuicFramerTest, StreamFrame) { +TEST_P(QuicFramerTest, StreamFrame) { unsigned char packet[] = { // public flags (8 byte guid) 0x3C, @@ -1241,7 +1255,10 @@ TEST_F(QuicFramerTest, StreamFrame) { } } -TEST_F(QuicFramerTest, StreamFrameWithVersion) { +TEST_P(QuicFramerTest, StreamFrameWithVersion) { + // Set a specific version. + framer_.set_version(QUIC_VERSION_6); + unsigned char packet[] = { // public flags (version, 8 byte guid) 0x3D, @@ -1279,7 +1296,7 @@ TEST_F(QuicFramerTest, StreamFrameWithVersion) { EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); ASSERT_TRUE(visitor_.header_.get()); EXPECT_TRUE(visitor_.header_.get()->public_header.version_flag); - EXPECT_EQ(kQuicVersion1, visitor_.header_.get()->public_header.versions[0]); + EXPECT_EQ(QUIC_VERSION_6, visitor_.header_.get()->public_header.versions[0]); EXPECT_TRUE(CheckDecryption(encrypted, kIncludeVersion)); ASSERT_EQ(1u, visitor_.stream_frames_.size()); @@ -1315,7 +1332,7 @@ TEST_F(QuicFramerTest, StreamFrameWithVersion) { } } -TEST_F(QuicFramerTest, RejectPacket) { +TEST_P(QuicFramerTest, RejectPacket) { visitor_.accept_packet_ = false; unsigned char packet[] = { @@ -1358,7 +1375,7 @@ TEST_F(QuicFramerTest, RejectPacket) { EXPECT_EQ(0u, visitor_.ack_frames_.size()); } -TEST_F(QuicFramerTest, RevivedStreamFrame) { +TEST_P(QuicFramerTest, RevivedStreamFrame) { unsigned char payload[] = { // frame type (stream frame) 0x01, @@ -1416,7 +1433,7 @@ TEST_F(QuicFramerTest, RevivedStreamFrame) { EXPECT_EQ("hello world!", visitor_.stream_frames_[0]->data); } -TEST_F(QuicFramerTest, StreamFrameInFecGroup) { +TEST_P(QuicFramerTest, StreamFrameInFecGroup) { unsigned char packet[] = { // public flags (8 byte guid) 0x3C, @@ -1472,7 +1489,7 @@ TEST_F(QuicFramerTest, StreamFrameInFecGroup) { EXPECT_EQ("hello world!", visitor_.stream_frames_[0]->data); } -TEST_F(QuicFramerTest, AckFrame) { +TEST_P(QuicFramerTest, AckFrame) { unsigned char packet[] = { // public flags (8 byte guid) 0x3C, @@ -1567,7 +1584,7 @@ TEST_F(QuicFramerTest, AckFrame) { } } -TEST_F(QuicFramerTest, CongestionFeedbackFrameTCP) { +TEST_P(QuicFramerTest, CongestionFeedbackFrameTCP) { unsigned char packet[] = { // public flags (8 byte guid) 0x3C, @@ -1626,7 +1643,7 @@ TEST_F(QuicFramerTest, CongestionFeedbackFrameTCP) { } } -TEST_F(QuicFramerTest, CongestionFeedbackFrameInterArrival) { +TEST_P(QuicFramerTest, CongestionFeedbackFrameInterArrival) { unsigned char packet[] = { // public flags (8 byte guid) 0x3C, @@ -1724,7 +1741,7 @@ TEST_F(QuicFramerTest, CongestionFeedbackFrameInterArrival) { } } -TEST_F(QuicFramerTest, CongestionFeedbackFrameFixRate) { +TEST_P(QuicFramerTest, CongestionFeedbackFrameFixRate) { unsigned char packet[] = { // public flags (8 byte guid) 0x3C, @@ -1779,7 +1796,7 @@ TEST_F(QuicFramerTest, CongestionFeedbackFrameFixRate) { } -TEST_F(QuicFramerTest, CongestionFeedbackFrameInvalidFeedback) { +TEST_P(QuicFramerTest, CongestionFeedbackFrameInvalidFeedback) { unsigned char packet[] = { // public flags (8 byte guid) 0x3C, @@ -1804,7 +1821,7 @@ TEST_F(QuicFramerTest, CongestionFeedbackFrameInvalidFeedback) { EXPECT_EQ(QUIC_INVALID_FRAME_DATA, framer_.error()); } -TEST_F(QuicFramerTest, RstStreamFrame) { +TEST_P(QuicFramerTest, RstStreamFrame) { unsigned char packet[] = { // public flags (8 byte guid) 0x3C, @@ -1863,7 +1880,7 @@ TEST_F(QuicFramerTest, RstStreamFrame) { } } -TEST_F(QuicFramerTest, ConnectionCloseFrame) { +TEST_P(QuicFramerTest, ConnectionCloseFrame) { unsigned char packet[] = { // public flags (8 byte guid) 0x3C, @@ -1950,7 +1967,7 @@ TEST_F(QuicFramerTest, ConnectionCloseFrame) { } } -TEST_F(QuicFramerTest, GoAwayFrame) { +TEST_P(QuicFramerTest, GoAwayFrame) { unsigned char packet[] = { // public flags (8 byte guid) 0x3C, @@ -2011,7 +2028,7 @@ TEST_F(QuicFramerTest, GoAwayFrame) { } } -TEST_F(QuicFramerTest, PublicResetPacket) { +TEST_P(QuicFramerTest, PublicResetPacket) { unsigned char packet[] = { // public flags (public reset, 8 byte guid) 0x3E, @@ -2063,7 +2080,10 @@ TEST_F(QuicFramerTest, PublicResetPacket) { } } -TEST_F(QuicFramerTest, VersionNegotiationPacket) { +TEST_P(QuicFramerTest, VersionNegotiationPacket) { + // Set a specific version. + framer_.set_version(QUIC_VERSION_6); + unsigned char packet[] = { // public flags (version, 8 byte guid) 0x3D, @@ -2082,7 +2102,7 @@ TEST_F(QuicFramerTest, VersionNegotiationPacket) { ASSERT_EQ(QUIC_NO_ERROR, framer_.error()); ASSERT_TRUE(visitor_.version_negotiation_packet_.get()); EXPECT_EQ(2u, visitor_.version_negotiation_packet_->versions.size()); - EXPECT_EQ(kQuicVersion1, + EXPECT_EQ(QUIC_VERSION_6, visitor_.version_negotiation_packet_->versions[0]); for (size_t i = 0; i <= kPublicFlagsSize + PACKET_8BYTE_GUID; ++i) { @@ -2100,7 +2120,7 @@ TEST_F(QuicFramerTest, VersionNegotiationPacket) { } } -TEST_F(QuicFramerTest, FecPacket) { +TEST_P(QuicFramerTest, FecPacket) { unsigned char packet[] = { // public flags (8 byte guid) 0x3C, @@ -2137,7 +2157,7 @@ TEST_F(QuicFramerTest, FecPacket) { EXPECT_EQ("abcdefghijklmnop", fec_data.redundancy); } -TEST_F(QuicFramerTest, ConstructPaddingFramePacket) { +TEST_P(QuicFramerTest, ConstructPaddingFramePacket) { QuicPacketHeader header; header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210); header.public_header.reset_flag = false; @@ -2182,7 +2202,7 @@ TEST_F(QuicFramerTest, ConstructPaddingFramePacket) { AsChars(packet), arraysize(packet)); } -TEST_F(QuicFramerTest, Construct4ByteSequenceNumberPaddingFramePacket) { +TEST_P(QuicFramerTest, Construct4ByteSequenceNumberPaddingFramePacket) { QuicPacketHeader header; header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210); header.public_header.reset_flag = false; @@ -2227,7 +2247,7 @@ TEST_F(QuicFramerTest, Construct4ByteSequenceNumberPaddingFramePacket) { AsChars(packet), arraysize(packet)); } -TEST_F(QuicFramerTest, Construct2ByteSequenceNumberPaddingFramePacket) { +TEST_P(QuicFramerTest, Construct2ByteSequenceNumberPaddingFramePacket) { QuicPacketHeader header; header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210); header.public_header.reset_flag = false; @@ -2272,7 +2292,7 @@ TEST_F(QuicFramerTest, Construct2ByteSequenceNumberPaddingFramePacket) { AsChars(packet), arraysize(packet)); } -TEST_F(QuicFramerTest, Construct1ByteSequenceNumberPaddingFramePacket) { +TEST_P(QuicFramerTest, Construct1ByteSequenceNumberPaddingFramePacket) { QuicPacketHeader header; header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210); header.public_header.reset_flag = false; @@ -2317,7 +2337,7 @@ TEST_F(QuicFramerTest, Construct1ByteSequenceNumberPaddingFramePacket) { AsChars(packet), arraysize(packet)); } -TEST_F(QuicFramerTest, ConstructStreamFramePacket) { +TEST_P(QuicFramerTest, ConstructStreamFramePacket) { QuicPacketHeader header; header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210); header.public_header.reset_flag = false; @@ -2374,7 +2394,7 @@ TEST_F(QuicFramerTest, ConstructStreamFramePacket) { AsChars(packet), arraysize(packet)); } -TEST_F(QuicFramerTest, ConstructStreamFramePacketWithVersionFlag) { +TEST_P(QuicFramerTest, ConstructStreamFramePacketWithVersionFlag) { QuicPacketHeader header; header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210); header.public_header.reset_flag = false; @@ -2393,6 +2413,8 @@ TEST_F(QuicFramerTest, ConstructStreamFramePacketWithVersionFlag) { QuicFrames frames; frames.push_back(QuicFrame(&stream_frame)); + // Set a specific version. + framer_.set_version(QUIC_VERSION_6); unsigned char packet[] = { // public flags (version, 8 byte guid) 0x3D, @@ -2434,7 +2456,7 @@ TEST_F(QuicFramerTest, ConstructStreamFramePacketWithVersionFlag) { AsChars(packet), arraysize(packet)); } -TEST_F(QuicFramerTest, ConstructVersionNegotiationPacket) { +TEST_P(QuicFramerTest, ConstructVersionNegotiationPacket) { QuicPacketPublicHeader header; header.guid = GG_UINT64_C(0xFEDCBA9876543210); header.reset_flag = false; @@ -2448,13 +2470,12 @@ TEST_F(QuicFramerTest, ConstructVersionNegotiationPacket) { 0x98, 0xBA, 0xDC, 0xFE, // version tag 'Q', '0', '0', '6', - 'Q', '2', '.', '0', + // 'Q', '0', '0', '7', }; - const int kQuicVersion2 = MakeQuicTag('Q', '2', '.', '0'); - QuicTagVector versions; - versions.push_back(kQuicVersion1); - versions.push_back(kQuicVersion2); + QuicVersionVector versions; + versions.push_back(QUIC_VERSION_6); + // versions.push_back(QUIC_VERSION_7); scoped_ptr<QuicEncryptedPacket> data( framer_.ConstructVersionNegotiationPacket(header, versions)); @@ -2463,7 +2484,7 @@ TEST_F(QuicFramerTest, ConstructVersionNegotiationPacket) { AsChars(packet), arraysize(packet)); } -TEST_F(QuicFramerTest, ConstructAckFramePacket) { +TEST_P(QuicFramerTest, ConstructAckFramePacket) { QuicPacketHeader header; header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210); header.public_header.reset_flag = false; @@ -2527,7 +2548,7 @@ TEST_F(QuicFramerTest, ConstructAckFramePacket) { AsChars(packet), arraysize(packet)); } -TEST_F(QuicFramerTest, ConstructCongestionFeedbackFramePacketTCP) { +TEST_P(QuicFramerTest, ConstructCongestionFeedbackFramePacketTCP) { QuicPacketHeader header; header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210); header.public_header.reset_flag = false; @@ -2576,7 +2597,7 @@ TEST_F(QuicFramerTest, ConstructCongestionFeedbackFramePacketTCP) { AsChars(packet), arraysize(packet)); } -TEST_F(QuicFramerTest, ConstructCongestionFeedbackFramePacketInterArrival) { +TEST_P(QuicFramerTest, ConstructCongestionFeedbackFramePacketInterArrival) { QuicPacketHeader header; header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210); header.public_header.reset_flag = false; @@ -2649,7 +2670,7 @@ TEST_F(QuicFramerTest, ConstructCongestionFeedbackFramePacketInterArrival) { AsChars(packet), arraysize(packet)); } -TEST_F(QuicFramerTest, ConstructCongestionFeedbackFramePacketFixRate) { +TEST_P(QuicFramerTest, ConstructCongestionFeedbackFramePacketFixRate) { QuicPacketHeader header; header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210); header.public_header.reset_flag = false; @@ -2696,7 +2717,7 @@ TEST_F(QuicFramerTest, ConstructCongestionFeedbackFramePacketFixRate) { AsChars(packet), arraysize(packet)); } -TEST_F(QuicFramerTest, ConstructCongestionFeedbackFramePacketInvalidFeedback) { +TEST_P(QuicFramerTest, ConstructCongestionFeedbackFramePacketInvalidFeedback) { QuicPacketHeader header; header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210); header.public_header.reset_flag = false; @@ -2718,7 +2739,7 @@ TEST_F(QuicFramerTest, ConstructCongestionFeedbackFramePacketInvalidFeedback) { ASSERT_TRUE(data == NULL); } -TEST_F(QuicFramerTest, ConstructRstFramePacket) { +TEST_P(QuicFramerTest, ConstructRstFramePacket) { QuicPacketHeader header; header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210); header.public_header.reset_flag = false; @@ -2772,7 +2793,7 @@ TEST_F(QuicFramerTest, ConstructRstFramePacket) { AsChars(packet), arraysize(packet)); } -TEST_F(QuicFramerTest, ConstructCloseFramePacket) { +TEST_P(QuicFramerTest, ConstructCloseFramePacket) { QuicPacketHeader header; header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210); header.public_header.reset_flag = false; @@ -2849,7 +2870,7 @@ TEST_F(QuicFramerTest, ConstructCloseFramePacket) { AsChars(packet), arraysize(packet)); } -TEST_F(QuicFramerTest, ConstructGoAwayPacket) { +TEST_P(QuicFramerTest, ConstructGoAwayPacket) { QuicPacketHeader header; header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210); header.public_header.reset_flag = false; @@ -2903,7 +2924,7 @@ TEST_F(QuicFramerTest, ConstructGoAwayPacket) { AsChars(packet), arraysize(packet)); } -TEST_F(QuicFramerTest, ConstructPublicResetPacket) { +TEST_P(QuicFramerTest, ConstructPublicResetPacket) { QuicPublicResetPacket reset_packet; reset_packet.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210); reset_packet.public_header.reset_flag = true; @@ -2934,7 +2955,7 @@ TEST_F(QuicFramerTest, ConstructPublicResetPacket) { AsChars(packet), arraysize(packet)); } -TEST_F(QuicFramerTest, ConstructFecPacket) { +TEST_P(QuicFramerTest, ConstructFecPacket) { QuicPacketHeader header; header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210); header.public_header.reset_flag = false; @@ -2979,7 +3000,7 @@ TEST_F(QuicFramerTest, ConstructFecPacket) { AsChars(packet), arraysize(packet)); } -TEST_F(QuicFramerTest, EncryptPacket) { +TEST_P(QuicFramerTest, EncryptPacket) { QuicPacketSequenceNumber sequence_number = GG_UINT64_C(0x123456789ABC); unsigned char packet[] = { // public flags (8 byte guid) @@ -3013,7 +3034,7 @@ TEST_F(QuicFramerTest, EncryptPacket) { EXPECT_TRUE(CheckEncryption(sequence_number, raw.get())); } -TEST_F(QuicFramerTest, EncryptPacketWithVersionFlag) { +TEST_P(QuicFramerTest, EncryptPacketWithVersionFlag) { QuicPacketSequenceNumber sequence_number = GG_UINT64_C(0x123456789ABC); unsigned char packet[] = { // public flags (version, 8 byte guid) @@ -3052,7 +3073,7 @@ TEST_F(QuicFramerTest, EncryptPacketWithVersionFlag) { // TODO(rch): re-enable after https://codereview.chromium.org/11820005/ // lands. Currently this is causing valgrind problems, but it should be // fixed in the followup CL. -TEST_F(QuicFramerTest, DISABLED_CalculateLargestReceived) { +TEST_P(QuicFramerTest, DISABLED_CalculateLargestReceived) { SequenceNumberSet missing; missing.insert(1); missing.insert(5); @@ -3071,7 +3092,7 @@ TEST_F(QuicFramerTest, DISABLED_CalculateLargestReceived) { } // TODO(rch) enable after landing the revised truncation CL. -TEST_F(QuicFramerTest, DISABLED_Truncation) { +TEST_P(QuicFramerTest, DISABLED_Truncation) { QuicPacketHeader header; header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210); header.public_header.reset_flag = false; @@ -3127,7 +3148,7 @@ TEST_F(QuicFramerTest, DISABLED_Truncation) { ASSERT_TRUE(framer_.ProcessPacket(*close_packet)); } -TEST_F(QuicFramerTest, CleanTruncation) { +TEST_P(QuicFramerTest, CleanTruncation) { QuicPacketHeader header; header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210); header.public_header.reset_flag = false; @@ -3207,7 +3228,7 @@ TEST_F(QuicFramerTest, CleanTruncation) { EXPECT_EQ(original_raw_length, raw_close_packet->length()); } -TEST_F(QuicFramerTest, EntropyFlagTest) { +TEST_P(QuicFramerTest, EntropyFlagTest) { unsigned char packet[] = { // public flags (8 byte guid) 0x3C, @@ -3246,7 +3267,7 @@ TEST_F(QuicFramerTest, EntropyFlagTest) { EXPECT_FALSE(visitor_.header_->fec_flag); }; -TEST_F(QuicFramerTest, FecEntropyTest) { +TEST_P(QuicFramerTest, FecEntropyTest) { unsigned char packet[] = { // public flags (8 byte guid) 0x3C, @@ -3287,7 +3308,7 @@ TEST_F(QuicFramerTest, FecEntropyTest) { EXPECT_EQ(1 << 4, visitor_.header_->entropy_hash); }; -TEST_F(QuicFramerTest, StopPacketProcessing) { +TEST_P(QuicFramerTest, StopPacketProcessing) { unsigned char packet[] = { // public flags (8 byte guid) 0x3C, @@ -3348,7 +3369,7 @@ TEST_F(QuicFramerTest, StopPacketProcessing) { EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); } -TEST_F(QuicFramerTest, ConnectionCloseWithInvalidAck) { +TEST_P(QuicFramerTest, ConnectionCloseWithInvalidAck) { unsigned char packet[] = { // public flags (8 byte guid) 0x3C, diff --git a/net/quic/quic_http_stream_test.cc b/net/quic/quic_http_stream_test.cc index d9919f0..b09e7a3 100644 --- a/net/quic/quic_http_stream_test.cc +++ b/net/quic/quic_http_stream_test.cc @@ -46,7 +46,7 @@ class TestQuicConnection : public QuicConnection { TestQuicConnection(QuicGuid guid, IPEndPoint address, QuicConnectionHelper* helper) - : QuicConnection(guid, address, helper, false) { + : QuicConnection(guid, address, helper, false, QuicVersionMax()) { } void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm) { @@ -118,7 +118,7 @@ class QuicHttpStreamTest : public ::testing::TestWithParam<bool> { use_closing_stream_(false), read_buffer_(new IOBufferWithSize(4096)), guid_(2), - framer_(kQuicVersion1, QuicTime::Zero(), false), + framer_(QuicVersionMax(), QuicTime::Zero(), false), creator_(guid_, &framer_, &random_, false) { IPAddressNumber ip; CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip)); @@ -168,6 +168,8 @@ class QuicHttpStreamTest : public ::testing::TestWithParam<bool> { runner_ = new TestTaskRunner(&clock_); send_algorithm_ = new MockSendAlgorithm(); receive_algorithm_ = new TestReceiveAlgorithm(NULL); + EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly( + testing::Return(QuicTime::Delta::Zero())); EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _)). WillRepeatedly(testing::Return(QuicTime::Delta::Zero())); helper_ = new QuicConnectionHelper(runner_.get(), &clock_, diff --git a/net/quic/quic_network_transaction_unittest.cc b/net/quic/quic_network_transaction_unittest.cc index a52b867..2aaf45d 100644 --- a/net/quic/quic_network_transaction_unittest.cc +++ b/net/quic/quic_network_transaction_unittest.cc @@ -141,7 +141,7 @@ class QuicNetworkTransactionTest : public PlatformTest { feedback.tcp.accumulated_number_of_lost_packets = 0; feedback.tcp.receive_window = 256000; - QuicFramer framer(kQuicVersion1, QuicTime::Zero(), false); + QuicFramer framer(QuicVersionMax(), QuicTime::Zero(), false); QuicFrames frames; frames.push_back(QuicFrame(&ack)); frames.push_back(QuicFrame(&feedback)); @@ -193,7 +193,7 @@ class QuicNetworkTransactionTest : public PlatformTest { scoped_ptr<QuicEncryptedPacket> ConstructPacket( const QuicPacketHeader& header, const QuicFrame& frame) { - QuicFramer framer(kQuicVersion1, QuicTime::Zero(), false); + QuicFramer framer(QuicVersionMax(), QuicTime::Zero(), false); QuicFrames frames; frames.push_back(frame); scoped_ptr<QuicPacket> packet( diff --git a/net/quic/quic_packet_creator.cc b/net/quic/quic_packet_creator.cc index 51071f9..eec8ab3 100644 --- a/net/quic/quic_packet_creator.cc +++ b/net/quic/quic_packet_creator.cc @@ -213,7 +213,7 @@ SerializedPacket QuicPacketCreator::SerializeConnectionClose( } QuicEncryptedPacket* QuicPacketCreator::SerializeVersionNegotiationPacket( - const QuicTagVector& supported_versions) { + const QuicVersionVector& supported_versions) { DCHECK(is_server_); QuicPacketPublicHeader header; header.guid = guid_; diff --git a/net/quic/quic_packet_creator.h b/net/quic/quic_packet_creator.h index 8abd49c..6c21a94 100644 --- a/net/quic/quic_packet_creator.h +++ b/net/quic/quic_packet_creator.h @@ -129,7 +129,7 @@ class NET_EXPORT_PRIVATE QuicPacketCreator : public QuicFecBuilderInterface { // serialized packet to a random bool and returns that value as a member of // SerializedPacket. QuicEncryptedPacket* SerializeVersionNegotiationPacket( - const QuicTagVector& supported_versions); + const QuicVersionVector& supported_versions); QuicPacketSequenceNumber sequence_number() const { return sequence_number_; diff --git a/net/quic/quic_packet_creator_test.cc b/net/quic/quic_packet_creator_test.cc index 7a8daa4c..b55f350 100644 --- a/net/quic/quic_packet_creator_test.cc +++ b/net/quic/quic_packet_creator_test.cc @@ -30,8 +30,8 @@ namespace { class QuicPacketCreatorTest : public ::testing::TestWithParam<bool> { protected: QuicPacketCreatorTest() - : server_framer_(kQuicVersion1, QuicTime::Zero(), true), - client_framer_(kQuicVersion1, QuicTime::Zero(), false), + : server_framer_(QuicVersionMax(), QuicTime::Zero(), true), + client_framer_(QuicVersionMax(), QuicTime::Zero(), false), id_(1), sequence_number_(0), guid_(2), @@ -179,8 +179,8 @@ TEST_F(QuicPacketCreatorTest, CreateStreamFrameFinOnly) { TEST_F(QuicPacketCreatorTest, SerializeVersionNegotiationPacket) { QuicPacketCreatorPeer::SetIsServer(&creator_, true); - QuicTagVector versions; - versions.push_back(kQuicVersion1); + QuicVersionVector versions; + versions.push_back(QuicVersionMax()); scoped_ptr<QuicEncryptedPacket> encrypted( creator_.SerializeVersionNegotiationPacket(versions)); diff --git a/net/quic/quic_packet_entropy_manager.cc b/net/quic/quic_packet_entropy_manager.cc deleted file mode 100644 index 5f152c0..0000000 --- a/net/quic/quic_packet_entropy_manager.cc +++ /dev/null @@ -1,165 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/quic/quic_packet_entropy_manager.h" - -#include "base/logging.h" -#include "net/base/linked_hash_map.h" - -using std::make_pair; -using std::max; -using std::min; - -namespace net { - -QuicPacketEntropyManager::QuicPacketEntropyManager() - : sent_packets_entropy_hash_(0), - received_packets_entropy_hash_(0), - largest_received_sequence_number_(0) {} - -QuicPacketEntropyManager::~QuicPacketEntropyManager() {} - -QuicPacketSequenceNumber -QuicPacketEntropyManager::LargestReceivedSequenceNumber() const { - if (received_packets_entropy_.empty()) { - return 0; - } - return received_packets_entropy_.rbegin()->first; -} - -void QuicPacketEntropyManager::RecordReceivedPacketEntropyHash( - QuicPacketSequenceNumber sequence_number, - QuicPacketEntropyHash entropy_hash) { - if (sequence_number < largest_received_sequence_number_) { - DLOG(INFO) << "Ignoring received packet entropy for sequence_number:" - << sequence_number << " less than largest_peer_sequence_number:" - << largest_received_sequence_number_; - return; - } - received_packets_entropy_.insert(make_pair(sequence_number, entropy_hash)); - received_packets_entropy_hash_ ^= entropy_hash; - DVLOG(2) << "setting cumulative received entropy hash to: " - << static_cast<int>(received_packets_entropy_hash_) - << " updated with sequence number " << sequence_number - << " entropy hash: " << static_cast<int>(entropy_hash); -} - -void QuicPacketEntropyManager::RecordSentPacketEntropyHash( - QuicPacketSequenceNumber sequence_number, - QuicPacketEntropyHash entropy_hash) { - // TODO(satyamshekhar): Check this logic again when/if we enable packet - // reordering. - sent_packets_entropy_hash_ ^= entropy_hash; - sent_packets_entropy_.insert( - make_pair(sequence_number, - make_pair(entropy_hash, sent_packets_entropy_hash_))); - DVLOG(2) << "setting cumulative sent entropy hash to: " - << static_cast<int>(sent_packets_entropy_hash_) - << " updated with sequence number " << sequence_number - << " entropy hash: " << static_cast<int>(entropy_hash); -} - -QuicPacketEntropyHash QuicPacketEntropyManager::ReceivedEntropyHash( - QuicPacketSequenceNumber sequence_number) const { - DCHECK_LE(sequence_number, LargestReceivedSequenceNumber()); - DCHECK_GE(sequence_number, largest_received_sequence_number_); - if (sequence_number == LargestReceivedSequenceNumber()) { - return received_packets_entropy_hash_; - } - - ReceivedEntropyMap::const_iterator it = - received_packets_entropy_.upper_bound(sequence_number); - // When this map is empty we should only query entropy for - // |largest_received_sequence_number_|. - LOG_IF(WARNING, it != received_packets_entropy_.end()) - << "largest_received: " << LargestReceivedSequenceNumber() - << " sequence_number: " << sequence_number; - - // TODO(satyamshekhar): Make this O(1). - QuicPacketEntropyHash hash = received_packets_entropy_hash_; - for (; it != received_packets_entropy_.end(); ++it) { - hash ^= it->second; - } - return hash; -} - -QuicPacketEntropyHash QuicPacketEntropyManager::SentEntropyHash( - QuicPacketSequenceNumber sequence_number) const { - SentEntropyMap::const_iterator it = - sent_packets_entropy_.find(sequence_number); - if (it == sent_packets_entropy_.end()) { - // Should only happen when we have not received ack for any packet. - DCHECK_EQ(0u, sequence_number); - return 0; - } - return it->second.second; -} - -void QuicPacketEntropyManager::RecalculateReceivedEntropyHash( - QuicPacketSequenceNumber peer_least_unacked, - QuicPacketEntropyHash entropy_hash) { - DLOG_IF(WARNING, peer_least_unacked > LargestReceivedSequenceNumber()) - << "Prematurely updating the entropy manager before registering the " - << "entropy of the containing packet creates a temporary inconsistency."; - if (peer_least_unacked < largest_received_sequence_number_) { - DLOG(INFO) << "Ignoring received peer_least_unacked:" << peer_least_unacked - << " less than largest_peer_sequence_number:" - << largest_received_sequence_number_; - return; - } - largest_received_sequence_number_ = peer_least_unacked; - received_packets_entropy_hash_ = entropy_hash; - ReceivedEntropyMap::iterator it = - received_packets_entropy_.lower_bound(peer_least_unacked); - // TODO(satyamshekhar): Make this O(1). - for (; it != received_packets_entropy_.end(); ++it) { - received_packets_entropy_hash_ ^= it->second; - } - // Discard entropies before least unacked. - received_packets_entropy_.erase( - received_packets_entropy_.begin(), - received_packets_entropy_.lower_bound( - min(peer_least_unacked, LargestReceivedSequenceNumber()))); -} - -bool QuicPacketEntropyManager::IsValidEntropy( - QuicPacketSequenceNumber sequence_number, - const SequenceNumberSet& missing_packets, - QuicPacketEntropyHash entropy_hash) const { - SentEntropyMap::const_iterator entropy_it = - sent_packets_entropy_.find(sequence_number); - if (entropy_it == sent_packets_entropy_.end()) { - DCHECK_EQ(0u, sequence_number); - // Close connection if something goes wrong. - return 0 == sequence_number; - } - QuicPacketEntropyHash expected_entropy_hash = entropy_it->second.second; - for (SequenceNumberSet::const_iterator it = missing_packets.begin(); - it != missing_packets.end(); ++it) { - entropy_it = sent_packets_entropy_.find(*it); - DCHECK(entropy_it != sent_packets_entropy_.end()); - expected_entropy_hash ^= entropy_it->second.first; - } - DLOG_IF(WARNING, entropy_hash != expected_entropy_hash) - << "Invalid entropy hash: " << static_cast<int>(entropy_hash) - << " expected entropy hash: " << static_cast<int>(expected_entropy_hash); - return entropy_hash == expected_entropy_hash; -} - -void QuicPacketEntropyManager::ClearSentEntropyBefore( - QuicPacketSequenceNumber sequence_number) { - if (sent_packets_entropy_.empty()) { - return; - } - SentEntropyMap::iterator it = sent_packets_entropy_.begin(); - while (it->first < sequence_number) { - sent_packets_entropy_.erase(it); - it = sent_packets_entropy_.begin(); - DCHECK(it != sent_packets_entropy_.end()); - } - DVLOG(2) << "Cleared entropy before: " - << sent_packets_entropy_.begin()->first; -} - -} // namespace net diff --git a/net/quic/quic_packet_entropy_manager.h b/net/quic/quic_packet_entropy_manager.h deleted file mode 100644 index fb205a4..0000000 --- a/net/quic/quic_packet_entropy_manager.h +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// Manages the packet entropy calculation for both sent and received packets -// for a connection. - -#ifndef NET_QUIC_QUIC_PACKET_ENTROPY_MANAGER_H_ -#define NET_QUIC_QUIC_PACKET_ENTROPY_MANAGER_H_ - -#include "net/base/linked_hash_map.h" -#include "net/quic/quic_framer.h" -#include "net/quic/quic_protocol.h" - -namespace net { - -// Records all sent and received packets by a connection to track the cumulative -// entropy of both sent and received packets separately. It is used by the -// connection to validate an ack frame sent by the peer as a preventive measure -// against the optimistic ack attack. Also, called by the framer when it -// truncates an ack frame to get the correct entropy value for the ack frame -// being serialized. -class NET_EXPORT_PRIVATE QuicPacketEntropyManager : - public QuicReceivedEntropyHashCalculatorInterface { - public: - QuicPacketEntropyManager(); - virtual ~QuicPacketEntropyManager(); - - // Record the received entropy hash against |sequence_number|. - void RecordReceivedPacketEntropyHash(QuicPacketSequenceNumber sequence_number, - QuicPacketEntropyHash entropy_hash); - - // Record |entropy_hash| for sent packet corresponding to |sequence_number|. - void RecordSentPacketEntropyHash(QuicPacketSequenceNumber sequence_number, - QuicPacketEntropyHash entropy_hash); - - // QuicReceivedEntropyHashCalculatorInterface - // Called by QuicFramer, when the outgoing ack gets truncated, to recalculate - // the received entropy hash for the truncated ack frame. - virtual QuicPacketEntropyHash ReceivedEntropyHash( - QuicPacketSequenceNumber sequence_number) const OVERRIDE; - - QuicPacketEntropyHash SentEntropyHash( - QuicPacketSequenceNumber sequence_number) const; - - QuicPacketSequenceNumber LargestReceivedSequenceNumber() const; - - // Recalculate the received entropy hash and clears old packet entropies, - // now that the sender sent us the |entropy_hash| for packets up to, - // but not including, |peer_least_unacked|. - void RecalculateReceivedEntropyHash( - QuicPacketSequenceNumber peer_least_unacked, - QuicPacketEntropyHash entropy_hash); - - // Returns true if |entropy_hash| matches the expected sent entropy hash - // up to |sequence_number| removing sequence numbers from |missing_packets|. - bool IsValidEntropy(QuicPacketSequenceNumber sequence_number, - const SequenceNumberSet& missing_packets, - QuicPacketEntropyHash entropy_hash) const; - - // Removes not required entries from |sent_packets_entropy_| before - // |sequence_number|. - void ClearSentEntropyBefore(QuicPacketSequenceNumber sequence_number); - - QuicPacketEntropyHash sent_packets_entropy_hash() const { - return sent_packets_entropy_hash_; - } - - QuicPacketEntropyHash received_packets_entropy_hash() const { - return received_packets_entropy_hash_; - } - - private: - typedef linked_hash_map<QuicPacketSequenceNumber, - std::pair<QuicPacketEntropyHash, - QuicPacketEntropyHash> > SentEntropyMap; - typedef std::map<QuicPacketSequenceNumber, - QuicPacketEntropyHash> ReceivedEntropyMap; - - // Linked hash map from sequence numbers to the sent entropy hash up to the - // sequence number in the key. - SentEntropyMap sent_packets_entropy_; - - // Cumulative hash of entropy of all sent packets. - QuicPacketEntropyHash sent_packets_entropy_hash_; - - // TODO(satyamshekhar): Can be optimized using an interval set like data - // structure. - // Map of received sequence numbers to their corresponding entropy. - // Every received packet has an entry, and packets without the entropy bit set - // have an entropy value of 0. - // TODO(ianswett): When the entropy flag is off, the entropy should not be 0. - ReceivedEntropyMap received_packets_entropy_; - - // Cumulative hash of entropy of all received packets. - QuicPacketEntropyHash received_packets_entropy_hash_; - - // The largest sequence number cleared by RecalculateReceivedEntropyHash. - // Received entropy cannot be calculated for numbers less than it. - QuicPacketSequenceNumber largest_received_sequence_number_; -}; - -} // namespace net - -#endif // NET_QUIC_QUIC_PACKET_ENTROPY_MANAGER_H_ diff --git a/net/quic/quic_packet_entropy_manager_test.cc b/net/quic/quic_packet_entropy_manager_test.cc deleted file mode 100644 index 0016211..0000000 --- a/net/quic/quic_packet_entropy_manager_test.cc +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/quic/quic_packet_entropy_manager.h" - -#include <algorithm> -#include <vector> - -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -using std::make_pair; -using std::pair; -using std::vector; - -namespace net { -namespace test { -namespace { - -class QuicPacketEntropyManagerTest : public ::testing::Test { - protected: - QuicPacketEntropyManager entropy_manager_; -}; - -TEST_F(QuicPacketEntropyManagerTest, ReceivedPacketEntropyHash) { - vector<pair<QuicPacketSequenceNumber, QuicPacketEntropyHash> > entropies; - entropies.push_back(make_pair(1, 12)); - entropies.push_back(make_pair(7, 1)); - entropies.push_back(make_pair(2, 33)); - entropies.push_back(make_pair(5, 3)); - entropies.push_back(make_pair(8, 34)); - - for (size_t i = 0; i < entropies.size(); ++i) { - entropy_manager_.RecordReceivedPacketEntropyHash(entropies[i].first, - entropies[i].second); - } - - sort(entropies.begin(), entropies.end()); - - QuicPacketEntropyHash hash = 0; - size_t index = 0; - for (size_t i = 1; i <= (*entropies.rbegin()).first; ++i) { - if (entropies[index].first == i) { - hash ^= entropies[index].second; - ++index; - } - EXPECT_EQ(hash, entropy_manager_.ReceivedEntropyHash(i)); - } -}; - -TEST_F(QuicPacketEntropyManagerTest, EntropyHashBelowLeastObserved) { - EXPECT_EQ(0, entropy_manager_.ReceivedEntropyHash(0)); - entropy_manager_.RecordReceivedPacketEntropyHash(4, 5); - EXPECT_EQ(0, entropy_manager_.ReceivedEntropyHash(3)); -}; - -TEST_F(QuicPacketEntropyManagerTest, EntropyHashAboveLargestObserved) { - EXPECT_EQ(0, entropy_manager_.ReceivedEntropyHash(0)); - entropy_manager_.RecordReceivedPacketEntropyHash(4, 5); - EXPECT_EQ(0, entropy_manager_.ReceivedEntropyHash(3)); -}; - -TEST_F(QuicPacketEntropyManagerTest, RecalculateReceivedEntropyHash) { - vector<pair<QuicPacketSequenceNumber, QuicPacketEntropyHash> > entropies; - entropies.push_back(make_pair(1, 12)); - entropies.push_back(make_pair(2, 1)); - entropies.push_back(make_pair(3, 33)); - entropies.push_back(make_pair(4, 3)); - entropies.push_back(make_pair(5, 34)); - entropies.push_back(make_pair(6, 29)); - - QuicPacketEntropyHash entropy_hash = 0; - for (size_t i = 0; i < entropies.size(); ++i) { - entropy_manager_.RecordReceivedPacketEntropyHash(entropies[i].first, - entropies[i].second); - entropy_hash ^= entropies[i].second; - } - EXPECT_EQ(entropy_hash, entropy_manager_.ReceivedEntropyHash(6)); - - // Now set the entropy hash up to 4 to be 100. - entropy_hash ^= 100; - for (size_t i = 0; i < 3; ++i) { - entropy_hash ^= entropies[i].second; - } - entropy_manager_.RecalculateReceivedEntropyHash(4, 100); - EXPECT_EQ(entropy_hash, entropy_manager_.ReceivedEntropyHash(6)); - - // Ensure it doesn't change with an old received sequence number or entropy. - entropy_manager_.RecordReceivedPacketEntropyHash(1, 50); - EXPECT_EQ(entropy_hash, entropy_manager_.ReceivedEntropyHash(6)); - - entropy_manager_.RecalculateReceivedEntropyHash(1, 50); - EXPECT_EQ(entropy_hash, entropy_manager_.ReceivedEntropyHash(6)); -} - -TEST_F(QuicPacketEntropyManagerTest, SentEntropyHash) { - EXPECT_EQ(0, entropy_manager_.SentEntropyHash(0)); - - vector<pair<QuicPacketSequenceNumber, QuicPacketEntropyHash> > entropies; - entropies.push_back(make_pair(1, 12)); - entropies.push_back(make_pair(2, 1)); - entropies.push_back(make_pair(3, 33)); - entropies.push_back(make_pair(4, 3)); - - for (size_t i = 0; i < entropies.size(); ++i) { - entropy_manager_.RecordSentPacketEntropyHash(entropies[i].first, - entropies[i].second); - } - - QuicPacketEntropyHash hash = 0; - for (size_t i = 0; i < entropies.size(); ++i) { - hash ^= entropies[i].second; - EXPECT_EQ(hash, entropy_manager_.SentEntropyHash(i + 1)); - } -} - -TEST_F(QuicPacketEntropyManagerTest, IsValidEntropy) { - QuicPacketEntropyHash entropies[10] = - {12, 1, 33, 3, 32, 100, 28, 42, 22, 255}; - for (size_t i = 0; i < 10; ++i) { - entropy_manager_.RecordSentPacketEntropyHash(i + 1, entropies[i]); - } - - SequenceNumberSet missing_packets; - missing_packets.insert(1); - missing_packets.insert(4); - missing_packets.insert(7); - missing_packets.insert(8); - - QuicPacketEntropyHash entropy_hash = 0; - for (size_t i = 0; i < 10; ++i) { - if (missing_packets.find(i + 1) == missing_packets.end()) { - entropy_hash ^= entropies[i]; - } - } - - EXPECT_TRUE(entropy_manager_.IsValidEntropy(10, missing_packets, - entropy_hash)); -} - -} // namespace -} // namespace test -} // namespace net diff --git a/net/quic/quic_packet_generator.cc b/net/quic/quic_packet_generator.cc index e6aeac7..08bad947 100644 --- a/net/quic/quic_packet_generator.cc +++ b/net/quic/quic_packet_generator.cc @@ -112,11 +112,21 @@ QuicConsumedData QuicPacketGenerator::ConsumeData(QuicStreamId id, return QuicConsumedData(total_bytes_consumed, fin_consumed); } +bool QuicPacketGenerator::CanSendWithNextPendingFrameAddition() const { + DCHECK(HasPendingFrames()); + HasRetransmittableData retransmittable = + (should_send_ack_ || should_send_feedback_) ? NO_RETRANSMITTABLE_DATA + : HAS_RETRANSMITTABLE_DATA; + if (retransmittable == HAS_RETRANSMITTABLE_DATA) { + DCHECK(!queued_control_frames_.empty()); // These are retransmittable. + } + return delegate_->CanWrite(NOT_RETRANSMISSION, retransmittable); +} + void QuicPacketGenerator::SendQueuedFrames() { packet_creator_->MaybeStartFEC(); - while (HasPendingFrames() && delegate_->CanWrite(NOT_RETRANSMISSION, - packet_creator_->HasPendingFrames() ? - HAS_RETRANSMITTABLE_DATA : NO_RETRANSMITTABLE_DATA)) { + // Only add pending frames if we are SURE we can then send the whole packet. + while (HasPendingFrames() && CanSendWithNextPendingFrameAddition()) { if (!AddNextPendingFrame()) { // Packet was full, so serialize and send it. SerializeAndSendPacket(); @@ -159,28 +169,26 @@ bool QuicPacketGenerator::HasPendingFrames() const { bool QuicPacketGenerator::AddNextPendingFrame() { if (should_send_ack_) { - pending_ack_frame_.reset(delegate_->CreateAckFrame()); - if (!AddFrame(QuicFrame(pending_ack_frame_.get()))) { - // packet was full - return false; - } - should_send_ack_ = false; - return true; + pending_ack_frame_.reset((delegate_->CreateAckFrame())); + // If we can't this add the frame now, then we still need to do so later. + should_send_ack_ = !AddFrame(QuicFrame(pending_ack_frame_.get())); + // Return success if we have cleared out this flag (i.e., added the frame). + // If we still need to send, then the frame is full, and we have failed. + return !should_send_ack_; } if (should_send_feedback_) { - pending_feedback_frame_.reset(delegate_->CreateFeedbackFrame()); - if (!AddFrame(QuicFrame(pending_feedback_frame_.get()))) { - // packet was full - return false; - } - should_send_feedback_ = false; - return true; + pending_feedback_frame_.reset((delegate_->CreateFeedbackFrame())); + // If we can't this add the frame now, then we still need to do so later. + should_send_feedback_ = !AddFrame(QuicFrame(pending_feedback_frame_.get())); + // Return success if we have cleared out this flag (i.e., added the frame). + // If we still need to send, then the frame is full, and we have failed. + return !should_send_feedback_; } DCHECK(!queued_control_frames_.empty()); if (!AddFrame(queued_control_frames_.back())) { - // packet was full + // Packet was full. return false; } queued_control_frames_.pop_back(); diff --git a/net/quic/quic_packet_generator.h b/net/quic/quic_packet_generator.h index f47a540..ab0dbe2 100644 --- a/net/quic/quic_packet_generator.h +++ b/net/quic/quic_packet_generator.h @@ -108,7 +108,13 @@ class NET_EXPORT_PRIVATE QuicPacketGenerator { private: void SendQueuedFrames(); + // Test to see if we have pending ack, feedback, or control frames. bool HasPendingFrames() const; + // Test to see if the addition of a pending frame (which might be + // retransmittable) would still allow the resulting packet to be sent now. + bool CanSendWithNextPendingFrameAddition() const; + // Add exactly one pending frame, preferring ack over feedback over control + // frames. bool AddNextPendingFrame(); bool AddFrame(const QuicFrame& frame); @@ -120,10 +126,15 @@ class NET_EXPORT_PRIVATE QuicPacketGenerator { QuicPacketCreator* packet_creator_; QuicFrames queued_control_frames_; bool should_flush_; + // Flags to indicate the need for just-in-time construction of a frame. bool should_send_ack_; + bool should_send_feedback_; + // If we put a non-retransmittable frame (namley ack or feedback frame) in + // this packet, then we have to hold a reference to it until we flush (and + // serialize it). Retransmittable frames are referenced elsewhere so that they + // can later be (optionally) retransmitted. scoped_ptr<QuicAckFrame> pending_ack_frame_; scoped_ptr<QuicCongestionFeedbackFrame> pending_feedback_frame_; - bool should_send_feedback_; DISALLOW_COPY_AND_ASSIGN(QuicPacketGenerator); }; diff --git a/net/quic/quic_packet_generator_test.cc b/net/quic/quic_packet_generator_test.cc index c3c4fc1..4511251 100644 --- a/net/quic/quic_packet_generator_test.cc +++ b/net/quic/quic_packet_generator_test.cc @@ -39,9 +39,26 @@ class MockDelegate : public QuicPacketGenerator::DelegateInterface { MOCK_METHOD0(CreateFeedbackFrame, QuicCongestionFeedbackFrame*()); MOCK_METHOD1(OnSerializedPacket, bool(const SerializedPacket& packet)); - void SetCanWrite(bool can_write) { + void SetCanWriteAnything() { EXPECT_CALL(*this, CanWrite(NOT_RETRANSMISSION, _)) - .WillRepeatedly(Return(can_write)); + .WillRepeatedly(Return(true)); + EXPECT_CALL(*this, CanWrite(NOT_RETRANSMISSION, NO_RETRANSMITTABLE_DATA)) + .WillRepeatedly(Return(true)); + } + + void SetCanNotWrite() { + EXPECT_CALL(*this, CanWrite(NOT_RETRANSMISSION, _)) + .WillRepeatedly(Return(false)); + EXPECT_CALL(*this, CanWrite(NOT_RETRANSMISSION, NO_RETRANSMITTABLE_DATA)) + .WillRepeatedly(Return(false)); + } + + // Use this when only ack and feedback frames should be allowed to be written. + void SetCanWriteOnlyNonRetransmittable() { + EXPECT_CALL(*this, CanWrite(NOT_RETRANSMISSION, _)) + .WillRepeatedly(Return(false)); + EXPECT_CALL(*this, CanWrite(NOT_RETRANSMISSION, NO_RETRANSMITTABLE_DATA)) + .WillRepeatedly(Return(true)); } private: @@ -77,7 +94,7 @@ struct PacketContents { class QuicPacketGeneratorTest : public ::testing::Test { protected: QuicPacketGeneratorTest() - : framer_(kQuicVersion1, QuicTime::Zero(), false), + : framer_(QuicVersionMax(), QuicTime::Zero(), false), creator_(42, &framer_, &random_, false), generator_(&delegate_, NULL, &creator_), packet_(0, NULL, 0, NULL), @@ -194,14 +211,14 @@ class QuicPacketGeneratorTest : public ::testing::Test { }; TEST_F(QuicPacketGeneratorTest, ShouldSendAck_NotWritable) { - delegate_.SetCanWrite(false); + delegate_.SetCanNotWrite(); generator_.SetShouldSendAck(false); EXPECT_TRUE(generator_.HasQueuedFrames()); } TEST_F(QuicPacketGeneratorTest, ShouldSendAck_WritableAndShouldNotFlush) { - delegate_.SetCanWrite(true); + delegate_.SetCanWriteOnlyNonRetransmittable(); generator_.StartBatchOperations(); EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame())); @@ -211,7 +228,7 @@ TEST_F(QuicPacketGeneratorTest, ShouldSendAck_WritableAndShouldNotFlush) { } TEST_F(QuicPacketGeneratorTest, ShouldSendAck_WritableAndShouldFlush) { - delegate_.SetCanWrite(true); + delegate_.SetCanWriteOnlyNonRetransmittable(); EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame())); EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce( @@ -227,7 +244,7 @@ TEST_F(QuicPacketGeneratorTest, ShouldSendAck_WritableAndShouldFlush) { TEST_F(QuicPacketGeneratorTest, ShouldSendAckWithFeedback_WritableAndShouldNotFlush) { - delegate_.SetCanWrite(true); + delegate_.SetCanWriteOnlyNonRetransmittable(); generator_.StartBatchOperations(); EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame())); @@ -240,7 +257,7 @@ TEST_F(QuicPacketGeneratorTest, TEST_F(QuicPacketGeneratorTest, ShouldSendAckWithFeedback_WritableAndShouldFlush) { - delegate_.SetCanWrite(true); + delegate_.SetCanWriteOnlyNonRetransmittable(); EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame())); EXPECT_CALL(delegate_, CreateFeedbackFrame()).WillOnce( @@ -259,14 +276,21 @@ TEST_F(QuicPacketGeneratorTest, } TEST_F(QuicPacketGeneratorTest, AddControlFrame_NotWritable) { - delegate_.SetCanWrite(false); + delegate_.SetCanNotWrite(); + + generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame())); + EXPECT_TRUE(generator_.HasQueuedFrames()); +} + +TEST_F(QuicPacketGeneratorTest, AddControlFrame_OnlyAckWritable) { + delegate_.SetCanWriteOnlyNonRetransmittable(); generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame())); EXPECT_TRUE(generator_.HasQueuedFrames()); } TEST_F(QuicPacketGeneratorTest, AddControlFrame_WritableAndShouldNotFlush) { - delegate_.SetCanWrite(true); + delegate_.SetCanWriteAnything(); generator_.StartBatchOperations(); generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame())); @@ -274,7 +298,7 @@ TEST_F(QuicPacketGeneratorTest, AddControlFrame_WritableAndShouldNotFlush) { } TEST_F(QuicPacketGeneratorTest, AddControlFrame_WritableAndShouldFlush) { - delegate_.SetCanWrite(true); + delegate_.SetCanWriteAnything(); EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce( DoAll(SaveArg<0>(&packet_), Return(true))); @@ -288,7 +312,7 @@ TEST_F(QuicPacketGeneratorTest, AddControlFrame_WritableAndShouldFlush) { } TEST_F(QuicPacketGeneratorTest, ConsumeData_NotWritable) { - delegate_.SetCanWrite(false); + delegate_.SetCanNotWrite(); QuicConsumedData consumed = generator_.ConsumeData(1, "foo", 2, true); EXPECT_EQ(0u, consumed.bytes_consumed); @@ -297,7 +321,7 @@ TEST_F(QuicPacketGeneratorTest, ConsumeData_NotWritable) { } TEST_F(QuicPacketGeneratorTest, ConsumeData_WritableAndShouldNotFlush) { - delegate_.SetCanWrite(true); + delegate_.SetCanWriteAnything(); generator_.StartBatchOperations(); QuicConsumedData consumed = generator_.ConsumeData(1, "foo", 2, true); @@ -307,7 +331,7 @@ TEST_F(QuicPacketGeneratorTest, ConsumeData_WritableAndShouldNotFlush) { } TEST_F(QuicPacketGeneratorTest, ConsumeData_WritableAndShouldFlush) { - delegate_.SetCanWrite(true); + delegate_.SetCanWriteAnything(); EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce( DoAll(SaveArg<0>(&packet_), Return(true))); @@ -323,7 +347,7 @@ TEST_F(QuicPacketGeneratorTest, ConsumeData_WritableAndShouldFlush) { TEST_F(QuicPacketGeneratorTest, ConsumeDataMultipleTimes_WritableAndShouldNotFlush) { - delegate_.SetCanWrite(true); + delegate_.SetCanWriteAnything(); generator_.StartBatchOperations(); generator_.ConsumeData(1, "foo", 2, true); @@ -334,7 +358,7 @@ TEST_F(QuicPacketGeneratorTest, } TEST_F(QuicPacketGeneratorTest, ConsumeData_BatchOperations) { - delegate_.SetCanWrite(true); + delegate_.SetCanWriteAnything(); generator_.StartBatchOperations(); generator_.ConsumeData(1, "foo", 2, true); @@ -355,7 +379,7 @@ TEST_F(QuicPacketGeneratorTest, ConsumeData_BatchOperations) { } TEST_F(QuicPacketGeneratorTest, ConsumeDataFEC) { - delegate_.SetCanWrite(true); + delegate_.SetCanWriteAnything(); // Send FEC every two packets. creator_.options()->max_packets_per_fec_group = 2; @@ -391,7 +415,7 @@ TEST_F(QuicPacketGeneratorTest, ConsumeDataFEC) { } TEST_F(QuicPacketGeneratorTest, ConsumeDataSendsFecAtEnd) { - delegate_.SetCanWrite(true); + delegate_.SetCanWriteAnything(); // Send FEC every six packets. creator_.options()->max_packets_per_fec_group = 6; @@ -420,13 +444,13 @@ TEST_F(QuicPacketGeneratorTest, ConsumeDataSendsFecAtEnd) { } TEST_F(QuicPacketGeneratorTest, NotWritableThenBatchOperations) { - delegate_.SetCanWrite(false); + delegate_.SetCanNotWrite(); generator_.SetShouldSendAck(true); generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame())); EXPECT_TRUE(generator_.HasQueuedFrames()); - delegate_.SetCanWrite(true); + delegate_.SetCanWriteAnything(); generator_.StartBatchOperations(); @@ -456,13 +480,13 @@ TEST_F(QuicPacketGeneratorTest, NotWritableThenBatchOperations) { } TEST_F(QuicPacketGeneratorTest, NotWritableThenBatchOperations2) { - delegate_.SetCanWrite(false); + delegate_.SetCanNotWrite(); generator_.SetShouldSendAck(true); generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame())); EXPECT_TRUE(generator_.HasQueuedFrames()); - delegate_.SetCanWrite(true); + delegate_.SetCanWriteAnything(); generator_.StartBatchOperations(); diff --git a/net/quic/quic_protocol.cc b/net/quic/quic_protocol.cc index 051a640..abbbadf 100644 --- a/net/quic/quic_protocol.cc +++ b/net/quic/quic_protocol.cc @@ -3,7 +3,9 @@ // found in the LICENSE file. #include "net/quic/quic_protocol.h" + #include "base/stl_util.h" +#include "net/quic/quic_utils.h" using base::StringPiece; using std::map; @@ -52,13 +54,6 @@ size_t GetStartOfEncryptedData( kPrivateFlagsSize; } -uint32 MakeQuicTag(char a, char b, char c, char d) { - return static_cast<uint32>(a) | - static_cast<uint32>(b) << 8 | - static_cast<uint32>(c) << 16 | - static_cast<uint32>(d) << 24; -} - QuicPacketPublicHeader::QuicPacketPublicHeader() : guid(0), guid_length(PACKET_8BYTE_GUID), @@ -119,6 +114,69 @@ QuicStreamFrame::QuicStreamFrame(QuicStreamId stream_id, data(data) { } +uint32 MakeQuicTag(char a, char b, char c, char d) { + return static_cast<uint32>(a) | + static_cast<uint32>(b) << 8 | + static_cast<uint32>(c) << 16 | + static_cast<uint32>(d) << 24; +} + +QuicVersion QuicVersionMax() { return kSupportedQuicVersions[0]; } + +QuicTag QuicVersionToQuicTag(const QuicVersion version) { + switch (version) { + case QUIC_VERSION_6: + return MakeQuicTag('Q', '0', '0', '6'); + // case QUIC_VERSION_7 + // return MakeQuicTag('Q', '0', '0', '7'); + default: + // This shold be an ERROR because we should never attempt to convert an + // invalid QuicVersion to be written to the wire. + LOG(ERROR) << "Unsupported QuicVersion: " << version; + return 0; + } +} + +QuicVersion QuicTagToQuicVersion(const QuicTag version_tag) { + const QuicTag quic_tag_v6 = MakeQuicTag('Q', '0', '0', '6'); + // const QuicTag quic_tag_v7 = MakeQuicTag('Q', '0', '0', '7'); + + if (version_tag == quic_tag_v6) { + return QUIC_VERSION_6; + // } else if (version_tag == quic_tag_v7) { + // return QUIC_VERSION_7; + } else { + // Reading from the client so this should not be considered an ERROR. + DLOG(INFO) << "Unsupported QuicTag version: " + << QuicUtils::TagToString(version_tag); + return QUIC_VERSION_UNSUPPORTED; + } +} + +string QuicVersionToString(const QuicVersion version) { + // TODO(rjshade): Possibly start using RETURN_STRING_LITERAL here when we + // start supporting a lot of versions. + switch (version) { + case QUIC_VERSION_6: + return "QUIC_VERSION_6"; + // case QUIC_VERSION_7: + // return "QUIC_VERSION_7"; + default: + return "QUIC_VERSION_UNSUPPORTED"; + } +} + +string QuicVersionArrayToString(const QuicVersion versions[], + int num_versions) { + string result = ""; + for (int i = 0; i < num_versions; ++i) { + const QuicVersion& version = versions[i]; + result.append(QuicVersionToString(version)); + result.append(","); + } + return result; +} + ostream& operator<<(ostream& os, const QuicPacketHeader& header) { os << "{ guid: " << header.public_header.guid << ", guid_length:" << header.public_header.guid_length diff --git a/net/quic/quic_protocol.h b/net/quic/quic_protocol.h index 4090f4c..93a5333 100644 --- a/net/quic/quic_protocol.h +++ b/net/quic/quic_protocol.h @@ -63,9 +63,6 @@ const size_t kPublicResetNonceSize = 8; // Signifies that the QuicPacket will contain version of the protocol. const bool kIncludeVersion = true; -// Returns true if |version| is a supported protocol version. -NET_EXPORT_PRIVATE bool IsSupportedVersion(QuicTag version); - // Index of the first byte in a QUIC packet which is used in hash calculation. const size_t kStartOfHashData = 0; @@ -175,6 +172,59 @@ enum QuicPacketPrivateFlags { PACKET_PRIVATE_FLAGS_MAX = (1 << 3) - 1 }; +// The available versions of QUIC. Guaranteed that the integer value of the enum +// will match the version number. +// When adding a new version to this enum you should add it to +// kSupportedVersions (if appropriate), and also add a new case to the helper +// methods QuicVersionToQuicTag, and QuicTagToQuicVersion. +enum QuicVersion { + // Special case to indicate unknown/unsupported QUIC version. + QUIC_VERSION_UNSUPPORTED = 0, + + QUIC_VERSION_6 = 6, // Current version. +}; + +// This vector contains QUIC versions which we currently support. +// This should be ordered such that the highest supported version is the first +// element, with subsequent elements in descending order (versions can be +// skipped as necessary). +static const QuicVersion kSupportedQuicVersions[] = {QUIC_VERSION_6}; + +typedef std::vector<QuicVersion> QuicVersionVector; + +// Upper limit on versions we support. +NET_EXPORT_PRIVATE QuicVersion QuicVersionMax(); + +// QuicTag is written to and read from the wire, but we prefer to use +// the more readable QuicVersion at other levels. +// Helper function which translates from a QuicVersion to a QuicTag. Returns 0 +// if QuicVersion is unsupported. +NET_EXPORT_PRIVATE QuicTag QuicVersionToQuicTag(const QuicVersion version); + +// Returns appropriate QuicVersion from a QuicTag. +// Returns QUIC_VERSION_UNSUPPORTED if version_tag cannot be understood. +NET_EXPORT_PRIVATE QuicVersion QuicTagToQuicVersion(const QuicTag version_tag); + +// Helper function which translates from a QuicVersion to a string. +// Returns strings corresponding to enum names (e.g. QUIC_VERSION_6). +NET_EXPORT_PRIVATE std::string QuicVersionToString(const QuicVersion version); + +// Returns comma separated list of string representations of QuicVersion enum +// values in the supplied QuicVersionArray. +NET_EXPORT_PRIVATE std::string QuicVersionArrayToString( + const QuicVersion versions[], int num_versions); + +// Version and Crypto tags are written to the wire with a big-endian +// representation of the name of the tag. For example +// the client hello tag (CHLO) will be written as the +// following 4 bytes: 'C' 'H' 'L' 'O'. Since it is +// stored in memory as a little endian uint32, we need +// to reverse the order of the bytes. + +// MakeQuicTag returns a value given the four bytes. For example: +// MakeQuicTag('C', 'H', 'L', 'O'); +NET_EXPORT_PRIVATE QuicTag MakeQuicTag(char a, char b, char c, char d); + // Size in bytes of the data or fec packet header. NET_EXPORT_PRIVATE size_t GetPacketHeaderSize(QuicPacketHeader header); @@ -323,27 +373,6 @@ enum QuicErrorCode { QUIC_LAST_ERROR, }; -// Version and Crypto tags are written to the wire with a big-endian -// representation of the name of the tag. For example -// the client hello tag (CHLO) will be written as the -// following 4 bytes: 'C' 'H' 'L' 'O'. Since it is -// stored in memory as a little endian uint32, we need -// to reverse the order of the bytes. -// -// The TAG macro is used in header files to ensure that we don't create static -// initialisers. In normal code, the MakeQuicTag function should be used. -#define TAG(a, b, c, d) ((d << 24) + (c << 16) + (b << 8) + a) -const QuicTag kUnsupportedVersion = -1; -// Each time the wire format changes, this need needs to be incremented. -// At some point, we will actually freeze the wire format and make an official -// version number, but this works for now. -const QuicTag kQuicVersion1 = TAG('Q', '0', '0', '6'); -#undef TAG - -// MakeQuicTag returns a value given the four bytes. For example: -// MakeQuicTag('C', 'H', 'L', 'O'); -uint32 NET_EXPORT_PRIVATE MakeQuicTag(char a, char b, char c, char d); - struct NET_EXPORT_PRIVATE QuicPacketPublicHeader { QuicPacketPublicHeader(); explicit QuicPacketPublicHeader(const QuicPacketPublicHeader& other); @@ -357,7 +386,7 @@ struct NET_EXPORT_PRIVATE QuicPacketPublicHeader { bool reset_flag; bool version_flag; QuicSequenceNumberLength sequence_number_length; - QuicTagVector versions; + QuicVersionVector versions; }; // Header for Data or FEC packets. diff --git a/net/quic/quic_protocol_test.cc b/net/quic/quic_protocol_test.cc index 271cca6..a22cb62 100644 --- a/net/quic/quic_protocol_test.cc +++ b/net/quic/quic_protocol_test.cc @@ -43,6 +43,104 @@ TEST(QuicProtocolTest, InsertMissingPacketsBetween) { } } +TEST(QuicProtocolTest, QuicVersionToQuicTag) { + // If you add a new version to the QuicVersion enum you will need to add a new + // case to QuicVersionToQuicTag, otherwise this test will fail. + + // TODO(rtenneti): Enable checking of Log(ERROR) messages. +#if 0 + // Any logs would indicate an unsupported version which we don't expect. + ScopedMockLog log(kDoNotCaptureLogsYet); + EXPECT_CALL(log, Log(_, _, _)).Times(0); + log.StartCapturingLogs(); +#endif + + // Explicitly test a specific version. + EXPECT_EQ(MakeQuicTag('Q', '0', '0', '6'), + QuicVersionToQuicTag(QUIC_VERSION_6)); + + // Loop over all supported versions and make sure that we never hit the + // default case (i.e. all supported versions should be successfully converted + // to valid QuicTags). + for (size_t i = 0; i < arraysize(kSupportedQuicVersions); ++i) { + const QuicVersion& version = kSupportedQuicVersions[i]; + EXPECT_LT(0u, QuicVersionToQuicTag(version)); + } +} + +TEST(QuicProtocolTest, QuicVersionToQuicTagUnsupported) { + // TODO(rtenneti): Enable checking of Log(ERROR) messages. +#if 0 + // TODO(rjshade): Change to DFATAL once we actually support multiple versions, + // and QuicConnectionTest::SendVersionNegotiationPacket can be changed to use + // mis-matched versions rather than relying on QUIC_VERSION_UNSUPPORTED. + ScopedMockLog log(kDoNotCaptureLogsYet); + EXPECT_CALL(log, Log(ERROR, _, "Unsupported QuicVersion: 0")).Times(1); + log.StartCapturingLogs(); +#endif + + EXPECT_EQ(0u, QuicVersionToQuicTag(QUIC_VERSION_UNSUPPORTED)); +} + +TEST(QuicProtocolTest, QuicTagToQuicVersion) { + // If you add a new version to the QuicVersion enum you will need to add a new + // case to QuicTagToQuicVersion, otherwise this test will fail. + + // TODO(rtenneti): Enable checking of Log(ERROR) messages. +#if 0 + // Any logs would indicate an unsupported version which we don't expect. + ScopedMockLog log(kDoNotCaptureLogsYet); + EXPECT_CALL(log, Log(_, _, _)).Times(0); + log.StartCapturingLogs(); +#endif + + // Explicitly test specific versions. + EXPECT_EQ(QUIC_VERSION_6, + QuicTagToQuicVersion(MakeQuicTag('Q', '0', '0', '6'))); + + for (size_t i = 0; i < arraysize(kSupportedQuicVersions); ++i) { + const QuicVersion& version = kSupportedQuicVersions[i]; + + // Get the tag from the version (we can loop over QuicVersions easily). + QuicTag tag = QuicVersionToQuicTag(version); + EXPECT_LT(0u, tag); + + // Now try converting back. + QuicVersion tag_to_quic_version = QuicTagToQuicVersion(tag); + EXPECT_EQ(version, tag_to_quic_version); + EXPECT_NE(QUIC_VERSION_UNSUPPORTED, tag_to_quic_version); + } +} + +TEST(QuicProtocolTest, QuicTagToQuicVersionUnsupported) { + // TODO(rtenneti): Enable checking of Log(ERROR) messages. +#if 0 + ScopedMockLog log(kDoNotCaptureLogsYet); +#ifndef NDEBUG + EXPECT_CALL(log, Log(INFO, _, "Unsupported QuicTag version: FAKE")).Times(1); +#endif + log.StartCapturingLogs(); +#endif + + EXPECT_EQ(QUIC_VERSION_UNSUPPORTED, + QuicTagToQuicVersion(MakeQuicTag('F', 'A', 'K', 'E'))); +} + +TEST(QuicProtocolTest, QuicVersionToString) { + EXPECT_EQ("QUIC_VERSION_6", + QuicVersionToString(QUIC_VERSION_6)); + EXPECT_EQ("QUIC_VERSION_UNSUPPORTED", + QuicVersionToString(QUIC_VERSION_UNSUPPORTED)); + + QuicVersion single_version[] = {QUIC_VERSION_6}; + EXPECT_EQ("QUIC_VERSION_6,", QuicVersionArrayToString(single_version, + arraysize(single_version))); + // QuicVersion multiple_versions[] = {QUIC_VERSION_7, QUIC_VERSION_6}; + // EXPECT_EQ("QUIC_VERSION_7,QUIC_VERSION_6,", + // QuicVersionArrayToString(multiple_versions, + // arraysize(multiple_versions))); +} + } // namespace } // namespace test } // namespace net diff --git a/net/quic/quic_received_entropy_manager.cc b/net/quic/quic_received_entropy_manager.cc index e69de29..57020eb 100644 --- a/net/quic/quic_received_entropy_manager.cc +++ b/net/quic/quic_received_entropy_manager.cc @@ -0,0 +1,98 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/quic/quic_received_entropy_manager.h" + +#include "base/logging.h" +#include "net/base/linked_hash_map.h" + +using std::make_pair; +using std::max; +using std::min; + +namespace net { + +QuicReceivedEntropyManager::QuicReceivedEntropyManager() + : packets_entropy_hash_(0), + largest_sequence_number_(0) {} + +QuicReceivedEntropyManager::~QuicReceivedEntropyManager() {} + +QuicPacketSequenceNumber +QuicReceivedEntropyManager::LargestSequenceNumber() const { + if (packets_entropy_.empty()) { + return 0; + } + return packets_entropy_.rbegin()->first; +} + +void QuicReceivedEntropyManager::RecordPacketEntropyHash( + QuicPacketSequenceNumber sequence_number, + QuicPacketEntropyHash entropy_hash) { + if (sequence_number < largest_sequence_number_) { + DLOG(INFO) << "Ignoring received packet entropy for sequence_number:" + << sequence_number << " less than largest_peer_sequence_number:" + << largest_sequence_number_; + return; + } + packets_entropy_.insert(make_pair(sequence_number, entropy_hash)); + packets_entropy_hash_ ^= entropy_hash; + DVLOG(2) << "setting cumulative received entropy hash to: " + << static_cast<int>(packets_entropy_hash_) + << " updated with sequence number " << sequence_number + << " entropy hash: " << static_cast<int>(entropy_hash); +} + +QuicPacketEntropyHash QuicReceivedEntropyManager::EntropyHash( + QuicPacketSequenceNumber sequence_number) const { + DCHECK_LE(sequence_number, LargestSequenceNumber()); + DCHECK_GE(sequence_number, largest_sequence_number_); + if (sequence_number == LargestSequenceNumber()) { + return packets_entropy_hash_; + } + + ReceivedEntropyMap::const_iterator it = + packets_entropy_.upper_bound(sequence_number); + // When this map is empty we should only query entropy for + // |largest_received_sequence_number_|. + LOG_IF(WARNING, it != packets_entropy_.end()) + << "largest_received: " << LargestSequenceNumber() + << " sequence_number: " << sequence_number; + + // TODO(satyamshekhar): Make this O(1). + QuicPacketEntropyHash hash = packets_entropy_hash_; + for (; it != packets_entropy_.end(); ++it) { + hash ^= it->second; + } + return hash; +} + +void QuicReceivedEntropyManager::RecalculateEntropyHash( + QuicPacketSequenceNumber peer_least_unacked, + QuicPacketEntropyHash entropy_hash) { + DLOG_IF(WARNING, peer_least_unacked > LargestSequenceNumber()) + << "Prematurely updating the entropy manager before registering the " + << "entropy of the containing packet creates a temporary inconsistency."; + if (peer_least_unacked < largest_sequence_number_) { + DLOG(INFO) << "Ignoring received peer_least_unacked:" << peer_least_unacked + << " less than largest_peer_sequence_number:" + << largest_sequence_number_; + return; + } + largest_sequence_number_ = peer_least_unacked; + packets_entropy_hash_ = entropy_hash; + ReceivedEntropyMap::iterator it = + packets_entropy_.lower_bound(peer_least_unacked); + // TODO(satyamshekhar): Make this O(1). + for (; it != packets_entropy_.end(); ++it) { + packets_entropy_hash_ ^= it->second; + } + // Discard entropies before least unacked. + packets_entropy_.erase( + packets_entropy_.begin(), + packets_entropy_.lower_bound( + min(peer_least_unacked, LargestSequenceNumber()))); +} + +} // namespace net diff --git a/net/quic/quic_received_entropy_manager.h b/net/quic/quic_received_entropy_manager.h index e69de29..d969834 100644 --- a/net/quic/quic_received_entropy_manager.h +++ b/net/quic/quic_received_entropy_manager.h @@ -0,0 +1,70 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Manages the packet entropy calculation for both sent and received packets +// for a connection. + +#ifndef NET_QUIC_QUIC_RECEIVED_ENTROPY_MANAGER_H_ +#define NET_QUIC_QUIC_RECEIVED_ENTROPY_MANAGER_H_ + +#include "net/quic/quic_framer.h" +#include "net/quic/quic_protocol.h" + +namespace net { + +// Records all received packets by a connection to track the cumulative +// entropy of received packets. Also, called by the framer when it truncates +// an ack frame to calculate the correct entropy value for the ack frame being +// serialized. +class NET_EXPORT_PRIVATE QuicReceivedEntropyManager : + public QuicReceivedEntropyHashCalculatorInterface { + public: + QuicReceivedEntropyManager(); + virtual ~QuicReceivedEntropyManager(); + + // Record the received entropy hash against |sequence_number|. + void RecordPacketEntropyHash(QuicPacketSequenceNumber sequence_number, + QuicPacketEntropyHash entropy_hash); + + // QuicReceivedEntropyHashCalculatorInterface + // Called by QuicFramer, when the outgoing ack gets truncated, to recalculate + // the received entropy hash for the truncated ack frame. + virtual QuicPacketEntropyHash EntropyHash( + QuicPacketSequenceNumber sequence_number) const OVERRIDE; + + QuicPacketSequenceNumber LargestSequenceNumber() const; + + // Recalculate the entropy hash and clears old packet entropies, + // now that the sender sent us the |entropy_hash| for packets up to, + // but not including, |peer_least_unacked|. + void RecalculateEntropyHash(QuicPacketSequenceNumber peer_least_unacked, + QuicPacketEntropyHash entropy_hash); + + QuicPacketEntropyHash packets_entropy_hash() const { + return packets_entropy_hash_; + } + + private: + typedef std::map<QuicPacketSequenceNumber, + QuicPacketEntropyHash> ReceivedEntropyMap; + + // TODO(satyamshekhar): Can be optimized using an interval set like data + // structure. + // Map of received sequence numbers to their corresponding entropy. + // Every received packet has an entry, and packets without the entropy bit set + // have an entropy value of 0. + // TODO(ianswett): When the entropy flag is off, the entropy should not be 0. + ReceivedEntropyMap packets_entropy_; + + // Cumulative hash of entropy of all received packets. + QuicPacketEntropyHash packets_entropy_hash_; + + // The largest sequence number cleared by RecalculateEntropyHash. + // Received entropy cannot be calculated for numbers less than it. + QuicPacketSequenceNumber largest_sequence_number_; +}; + +} // namespace net + +#endif // NET_QUIC_QUIC_RECEIVED_ENTROPY_MANAGER_H_ diff --git a/net/quic/quic_received_entropy_manager_test.cc b/net/quic/quic_received_entropy_manager_test.cc index e69de29..c857315e 100644 --- a/net/quic/quic_received_entropy_manager_test.cc +++ b/net/quic/quic_received_entropy_manager_test.cc @@ -0,0 +1,99 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/quic/quic_received_entropy_manager.h" + +#include <algorithm> +#include <vector> + +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using std::make_pair; +using std::pair; +using std::vector; + +namespace net { +namespace test { +namespace { + +class QuicReceivedEntropyManagerTest : public ::testing::Test { + protected: + QuicReceivedEntropyManager entropy_manager_; +}; + +TEST_F(QuicReceivedEntropyManagerTest, ReceivedPacketEntropyHash) { + vector<pair<QuicPacketSequenceNumber, QuicPacketEntropyHash> > entropies; + entropies.push_back(make_pair(1, 12)); + entropies.push_back(make_pair(7, 1)); + entropies.push_back(make_pair(2, 33)); + entropies.push_back(make_pair(5, 3)); + entropies.push_back(make_pair(8, 34)); + + for (size_t i = 0; i < entropies.size(); ++i) { + entropy_manager_.RecordPacketEntropyHash(entropies[i].first, + entropies[i].second); + } + + sort(entropies.begin(), entropies.end()); + + QuicPacketEntropyHash hash = 0; + size_t index = 0; + for (size_t i = 1; i <= (*entropies.rbegin()).first; ++i) { + if (entropies[index].first == i) { + hash ^= entropies[index].second; + ++index; + } + EXPECT_EQ(hash, entropy_manager_.EntropyHash(i)); + } +} + +TEST_F(QuicReceivedEntropyManagerTest, EntropyHashBelowLeastObserved) { + EXPECT_EQ(0, entropy_manager_.EntropyHash(0)); + entropy_manager_.RecordPacketEntropyHash(4, 5); + EXPECT_EQ(0, entropy_manager_.EntropyHash(3)); +} + +TEST_F(QuicReceivedEntropyManagerTest, EntropyHashAboveLargestObserved) { + EXPECT_EQ(0, entropy_manager_.EntropyHash(0)); + entropy_manager_.RecordPacketEntropyHash(4, 5); + EXPECT_EQ(0, entropy_manager_.EntropyHash(3)); +} + +TEST_F(QuicReceivedEntropyManagerTest, RecalculateEntropyHash) { + vector<pair<QuicPacketSequenceNumber, QuicPacketEntropyHash> > entropies; + entropies.push_back(make_pair(1, 12)); + entropies.push_back(make_pair(2, 1)); + entropies.push_back(make_pair(3, 33)); + entropies.push_back(make_pair(4, 3)); + entropies.push_back(make_pair(5, 34)); + entropies.push_back(make_pair(6, 29)); + + QuicPacketEntropyHash entropy_hash = 0; + for (size_t i = 0; i < entropies.size(); ++i) { + entropy_manager_.RecordPacketEntropyHash(entropies[i].first, + entropies[i].second); + entropy_hash ^= entropies[i].second; + } + EXPECT_EQ(entropy_hash, entropy_manager_.EntropyHash(6)); + + // Now set the entropy hash up to 4 to be 100. + entropy_hash ^= 100; + for (size_t i = 0; i < 3; ++i) { + entropy_hash ^= entropies[i].second; + } + entropy_manager_.RecalculateEntropyHash(4, 100); + EXPECT_EQ(entropy_hash, entropy_manager_.EntropyHash(6)); + + // Ensure it doesn't change with an old received sequence number or entropy. + entropy_manager_.RecordPacketEntropyHash(1, 50); + EXPECT_EQ(entropy_hash, entropy_manager_.EntropyHash(6)); + + entropy_manager_.RecalculateEntropyHash(1, 50); + EXPECT_EQ(entropy_hash, entropy_manager_.EntropyHash(6)); +} + +} // namespace +} // namespace test +} // namespace net diff --git a/net/quic/quic_sent_entropy_manager.cc b/net/quic/quic_sent_entropy_manager.cc index e69de29..0f33e2d 100644 --- a/net/quic/quic_sent_entropy_manager.cc +++ b/net/quic/quic_sent_entropy_manager.cc @@ -0,0 +1,87 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/quic/quic_sent_entropy_manager.h" + +#include "base/logging.h" +#include "net/base/linked_hash_map.h" + +using std::make_pair; +using std::max; +using std::min; + +namespace net { + +QuicSentEntropyManager::QuicSentEntropyManager() + : packets_entropy_hash_(0) {} + +QuicSentEntropyManager::~QuicSentEntropyManager() {} + +void QuicSentEntropyManager::RecordPacketEntropyHash( + QuicPacketSequenceNumber sequence_number, + QuicPacketEntropyHash entropy_hash) { + // TODO(satyamshekhar): Check this logic again when/if we enable packet + // reordering. + packets_entropy_hash_ ^= entropy_hash; + packets_entropy_.insert( + make_pair(sequence_number, + make_pair(entropy_hash, packets_entropy_hash_))); + DVLOG(2) << "setting cumulative sent entropy hash to: " + << static_cast<int>(packets_entropy_hash_) + << " updated with sequence number " << sequence_number + << " entropy hash: " << static_cast<int>(entropy_hash); +} + +QuicPacketEntropyHash QuicSentEntropyManager::EntropyHash( + QuicPacketSequenceNumber sequence_number) const { + SentEntropyMap::const_iterator it = + packets_entropy_.find(sequence_number); + if (it == packets_entropy_.end()) { + // Should only happen when we have not received ack for any packet. + DCHECK_EQ(0u, sequence_number); + return 0; + } + return it->second.second; +} + +bool QuicSentEntropyManager::IsValidEntropy( + QuicPacketSequenceNumber sequence_number, + const SequenceNumberSet& missing_packets, + QuicPacketEntropyHash entropy_hash) const { + SentEntropyMap::const_iterator entropy_it = + packets_entropy_.find(sequence_number); + if (entropy_it == packets_entropy_.end()) { + DCHECK_EQ(0u, sequence_number); + // Close connection if something goes wrong. + return 0 == sequence_number; + } + QuicPacketEntropyHash expected_entropy_hash = entropy_it->second.second; + for (SequenceNumberSet::const_iterator it = missing_packets.begin(); + it != missing_packets.end(); ++it) { + entropy_it = packets_entropy_.find(*it); + DCHECK(entropy_it != packets_entropy_.end()); + expected_entropy_hash ^= entropy_it->second.first; + } + DLOG_IF(WARNING, entropy_hash != expected_entropy_hash) + << "Invalid entropy hash: " << static_cast<int>(entropy_hash) + << " expected entropy hash: " << static_cast<int>(expected_entropy_hash); + return entropy_hash == expected_entropy_hash; +} + +void QuicSentEntropyManager::ClearEntropyBefore( + QuicPacketSequenceNumber sequence_number) { + if (packets_entropy_.empty()) { + return; + } + SentEntropyMap::iterator it = packets_entropy_.begin(); + while (it->first < sequence_number) { + packets_entropy_.erase(it); + it = packets_entropy_.begin(); + DCHECK(it != packets_entropy_.end()); + } + DVLOG(2) << "Cleared entropy before: " + << packets_entropy_.begin()->first; +} + +} // namespace net diff --git a/net/quic/quic_sent_entropy_manager.h b/net/quic/quic_sent_entropy_manager.h index e69de29..4f684fc 100644 --- a/net/quic/quic_sent_entropy_manager.h +++ b/net/quic/quic_sent_entropy_manager.h @@ -0,0 +1,62 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Manages the packet entropy calculation for both sent and received packets +// for a connection. + +#ifndef NET_QUIC_QUIC_SENT_ENTROPY_MANAGER_H_ +#define NET_QUIC_QUIC_SENT_ENTROPY_MANAGER_H_ + +#include "net/base/linked_hash_map.h" +#include "net/quic/quic_framer.h" +#include "net/quic/quic_protocol.h" + +namespace net { + +// Records all sent packets by a connection to track the cumulative entropy of +// sent packets. It is used by the connection to validate an ack +// frame sent by the peer as a preventive measure against the optimistic ack +// attack. +class NET_EXPORT_PRIVATE QuicSentEntropyManager { + public: + QuicSentEntropyManager(); + virtual ~QuicSentEntropyManager(); + + // Record |entropy_hash| for sent packet corresponding to |sequence_number|. + void RecordPacketEntropyHash(QuicPacketSequenceNumber sequence_number, + QuicPacketEntropyHash entropy_hash); + + QuicPacketEntropyHash EntropyHash( + QuicPacketSequenceNumber sequence_number) const; + + // Returns true if |entropy_hash| matches the expected sent entropy hash + // up to |sequence_number| removing sequence numbers from |missing_packets|. + bool IsValidEntropy(QuicPacketSequenceNumber sequence_number, + const SequenceNumberSet& missing_packets, + QuicPacketEntropyHash entropy_hash) const; + + // Removes not required entries from |packets_entropy_| before + // |sequence_number|. + void ClearEntropyBefore(QuicPacketSequenceNumber sequence_number); + + QuicPacketEntropyHash packets_entropy_hash() const { + return packets_entropy_hash_; + } + + private: + typedef linked_hash_map<QuicPacketSequenceNumber, + std::pair<QuicPacketEntropyHash, + QuicPacketEntropyHash> > SentEntropyMap; + + // Linked hash map from sequence numbers to the sent entropy hash up to the + // sequence number in the key. + SentEntropyMap packets_entropy_; + + // Cumulative hash of entropy of all sent packets. + QuicPacketEntropyHash packets_entropy_hash_; +}; + +} // namespace net + +#endif // NET_QUIC_QUIC_SENT_ENTROPY_MANAGER_H_ diff --git a/net/quic/quic_sent_entropy_manager_test.cc b/net/quic/quic_sent_entropy_manager_test.cc index e69de29..e4e9847 100644 --- a/net/quic/quic_sent_entropy_manager_test.cc +++ b/net/quic/quic_sent_entropy_manager_test.cc @@ -0,0 +1,73 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/quic/quic_sent_entropy_manager.h" + +#include <algorithm> +#include <vector> + +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using std::make_pair; +using std::pair; +using std::vector; + +namespace net { +namespace test { +namespace { + +class QuicSentEntropyManagerTest : public ::testing::Test { + protected: + QuicSentEntropyManager entropy_manager_; +}; + +TEST_F(QuicSentEntropyManagerTest, SentEntropyHash) { + EXPECT_EQ(0, entropy_manager_.EntropyHash(0)); + + vector<pair<QuicPacketSequenceNumber, QuicPacketEntropyHash> > entropies; + entropies.push_back(make_pair(1, 12)); + entropies.push_back(make_pair(2, 1)); + entropies.push_back(make_pair(3, 33)); + entropies.push_back(make_pair(4, 3)); + + for (size_t i = 0; i < entropies.size(); ++i) { + entropy_manager_.RecordPacketEntropyHash(entropies[i].first, + entropies[i].second); + } + + QuicPacketEntropyHash hash = 0; + for (size_t i = 0; i < entropies.size(); ++i) { + hash ^= entropies[i].second; + EXPECT_EQ(hash, entropy_manager_.EntropyHash(i + 1)); + } +} + +TEST_F(QuicSentEntropyManagerTest, IsValidEntropy) { + QuicPacketEntropyHash entropies[10] = + {12, 1, 33, 3, 32, 100, 28, 42, 22, 255}; + for (size_t i = 0; i < 10; ++i) { + entropy_manager_.RecordPacketEntropyHash(i + 1, entropies[i]); + } + + SequenceNumberSet missing_packets; + missing_packets.insert(1); + missing_packets.insert(4); + missing_packets.insert(7); + missing_packets.insert(8); + + QuicPacketEntropyHash entropy_hash = 0; + for (size_t i = 0; i < 10; ++i) { + if (missing_packets.find(i + 1) == missing_packets.end()) { + entropy_hash ^= entropies[i]; + } + } + + EXPECT_TRUE(entropy_manager_.IsValidEntropy(10, missing_packets, + entropy_hash)); +} + +} // namespace +} // namespace test +} // namespace net diff --git a/net/quic/quic_stream_factory.cc b/net/quic/quic_stream_factory.cc index af2d881..ceae162 100644 --- a/net/quic/quic_stream_factory.cc +++ b/net/quic/quic_stream_factory.cc @@ -440,7 +440,8 @@ QuicClientSession* QuicStreamFactory::CreateSession( random_generator_, socket); - QuicConnection* connection = new QuicConnection(guid, addr, helper, false); + QuicConnection* connection = new QuicConnection(guid, addr, helper, false, + QuicVersionMax()); QuicCryptoClientConfig* crypto_config = GetOrCreateCryptoConfig(host_port_proxy_pair); diff --git a/net/quic/quic_stream_factory_test.cc b/net/quic/quic_stream_factory_test.cc index 383ca9a..2427cf8 100644 --- a/net/quic/quic_stream_factory_test.cc +++ b/net/quic/quic_stream_factory_test.cc @@ -72,7 +72,7 @@ class QuicStreamFactoryTest : public ::testing::Test { feedback.tcp.accumulated_number_of_lost_packets = 0; feedback.tcp.receive_window = 16000; - QuicFramer framer(kQuicVersion1, QuicTime::Zero(), false); + QuicFramer framer(QuicVersionMax(), QuicTime::Zero(), false); QuicFrames frames; frames.push_back(QuicFrame(&ack)); frames.push_back(QuicFrame(&feedback)); @@ -106,7 +106,7 @@ class QuicStreamFactoryTest : public ::testing::Test { scoped_ptr<QuicEncryptedPacket> ConstructPacket( const QuicPacketHeader& header, const QuicFrame& frame) { - QuicFramer framer(kQuicVersion1, QuicTime::Zero(), false); + QuicFramer framer(QuicVersionMax(), QuicTime::Zero(), false); QuicFrames frames; frames.push_back(frame); scoped_ptr<QuicPacket> packet( diff --git a/net/quic/quic_stream_sequencer.cc b/net/quic/quic_stream_sequencer.cc index 146a77c..c58f2cc 100644 --- a/net/quic/quic_stream_sequencer.cc +++ b/net/quic/quic_stream_sequencer.cc @@ -74,10 +74,19 @@ bool QuicStreamSequencer::OnStreamFrame(const QuicStreamFrame& frame) { return true; } + if (frame.fin) { + CloseStreamAtOffset(frame.offset + frame.data.size()); + } + QuicStreamOffset byte_offset = frame.offset; const char* data = frame.data.data(); size_t data_len = frame.data.size(); + if (data_len == 0) { + // TODO(rch): Close the stream if there was no data and no fin. + return true; + } + if (byte_offset == num_bytes_consumed_) { DVLOG(1) << "Processing byte offset " << byte_offset; size_t bytes_consumed = stream_->ProcessRawData(data, data_len); diff --git a/net/quic/quic_stream_sequencer.h b/net/quic/quic_stream_sequencer.h index bb5b29e..fe9fba5 100644 --- a/net/quic/quic_stream_sequencer.h +++ b/net/quic/quic_stream_sequencer.h @@ -49,9 +49,6 @@ class NET_EXPORT_PRIVATE QuicStreamSequencer { // this will return true, or it will be rejected and this will return false. bool OnStreamFrame(const QuicStreamFrame& frame); - // Wait until we've seen 'offset' bytes, and then terminate the stream. - void CloseStreamAtOffset(QuicStreamOffset offset); - // Once data is buffered, it's up to the stream to read it when the stream // can handle more data. The following three functions make that possible. @@ -86,6 +83,9 @@ class NET_EXPORT_PRIVATE QuicStreamSequencer { // TODO(alyssar) use something better than strings. typedef map<QuicStreamOffset, string> FrameMap; + // Wait until we've seen 'offset' bytes, and then terminate the stream. + void CloseStreamAtOffset(QuicStreamOffset offset); + bool MaybeCloseStream(); ReliableQuicStream* stream_; // The stream which owns this sequencer. diff --git a/net/quic/quic_stream_sequencer_test.cc b/net/quic/quic_stream_sequencer_test.cc index af8a961..691af32 100644 --- a/net/quic/quic_stream_sequencer_test.cc +++ b/net/quic/quic_stream_sequencer_test.cc @@ -32,15 +32,26 @@ class QuicStreamSequencerPeer : public QuicStreamSequencer { } QuicStreamSequencerPeer(int32 max_mem, ReliableQuicStream* stream) - : QuicStreamSequencer(max_mem, stream) {} + : QuicStreamSequencer(max_mem, stream) { + } + + virtual bool OnFinFrame(QuicStreamOffset byte_offset, + const char* data) { + QuicStreamFrame frame; + frame.stream_id = 1; + frame.offset = byte_offset; + frame.data = StringPiece(data); + frame.fin = true; + return OnStreamFrame(frame); + } virtual bool OnFrame(QuicStreamOffset byte_offset, - const char* data, - uint32 data_len) { + const char* data) { QuicStreamFrame frame; frame.stream_id = 1; frame.offset = byte_offset; - frame.data = StringPiece(data, data_len); + frame.data = StringPiece(data); + frame.fin = false; return OnStreamFrame(frame); } @@ -127,12 +138,12 @@ TEST_F(QuicStreamSequencerTest, RejectOldFrame) { EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)) .WillOnce(Return(3)); - EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3)); + EXPECT_TRUE(sequencer_->OnFrame(0, "abc")); EXPECT_EQ(0u, sequencer_->frames()->size()); EXPECT_EQ(3u, sequencer_->num_bytes_consumed()); // Ignore this - it matches a past sequence number and we should not see it // again. - EXPECT_TRUE(sequencer_->OnFrame(0, "def", 3)); + EXPECT_TRUE(sequencer_->OnFrame(0, "def")); EXPECT_EQ(0u, sequencer_->frames()->size()); } @@ -142,40 +153,53 @@ TEST_F(QuicStreamSequencerTest, RejectOverlyLargeFrame) { "Setting max frame memory to 2. " "Some frames will be impossible to handle."); - EXPECT_DEBUG_DEATH(sequencer_->OnFrame(0, "abc", 3), ""); + EXPECT_DEBUG_DEATH(sequencer_->OnFrame(0, "abc"), ""); */ } TEST_F(QuicStreamSequencerTest, DropFramePastBuffering) { sequencer_->SetMemoryLimit(3); - EXPECT_FALSE(sequencer_->OnFrame(3, "abc", 3)); + EXPECT_FALSE(sequencer_->OnFrame(3, "abc")); } TEST_F(QuicStreamSequencerTest, RejectBufferedFrame) { EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)); - EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3)); + EXPECT_TRUE(sequencer_->OnFrame(0, "abc")); EXPECT_EQ(1u, sequencer_->frames()->size()); EXPECT_EQ(0u, sequencer_->num_bytes_consumed()); // Ignore this - it matches a buffered frame. // Right now there's no checking that the payload is consistent. - EXPECT_TRUE(sequencer_->OnFrame(0, "def", 3)); + EXPECT_TRUE(sequencer_->OnFrame(0, "def")); EXPECT_EQ(1u, sequencer_->frames()->size()); } TEST_F(QuicStreamSequencerTest, FullFrameConsumed) { EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3)); - EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3)); + EXPECT_TRUE(sequencer_->OnFrame(0, "abc")); EXPECT_EQ(0u, sequencer_->frames()->size()); EXPECT_EQ(3u, sequencer_->num_bytes_consumed()); } +TEST_F(QuicStreamSequencerTest, EmptyFrame) { + EXPECT_TRUE(sequencer_->OnFrame(0, "")); + EXPECT_EQ(0u, sequencer_->frames()->size()); + EXPECT_EQ(0u, sequencer_->num_bytes_consumed()); +} + +TEST_F(QuicStreamSequencerTest, EmptyFinFrame) { + EXPECT_CALL(stream_, TerminateFromPeer(true)); + EXPECT_TRUE(sequencer_->OnFinFrame(0, "")); + EXPECT_EQ(0u, sequencer_->frames()->size()); + EXPECT_EQ(0u, sequencer_->num_bytes_consumed()); +} + TEST_F(QuicStreamSequencerTest, PartialFrameConsumed) { EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(2)); - EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3)); + EXPECT_TRUE(sequencer_->OnFrame(0, "abc")); EXPECT_EQ(1u, sequencer_->frames()->size()); EXPECT_EQ(2u, sequencer_->num_bytes_consumed()); EXPECT_EQ("c", sequencer_->frames()->find(2)->second); @@ -184,14 +208,14 @@ TEST_F(QuicStreamSequencerTest, PartialFrameConsumed) { TEST_F(QuicStreamSequencerTest, NextxFrameNotConsumed) { EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(0)); - EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3)); + EXPECT_TRUE(sequencer_->OnFrame(0, "abc")); EXPECT_EQ(1u, sequencer_->frames()->size()); EXPECT_EQ(0u, sequencer_->num_bytes_consumed()); EXPECT_EQ("abc", sequencer_->frames()->find(0)->second); } TEST_F(QuicStreamSequencerTest, FutureFrameNotProcessed) { - EXPECT_TRUE(sequencer_->OnFrame(3, "abc", 3)); + EXPECT_TRUE(sequencer_->OnFrame(3, "abc")); EXPECT_EQ(1u, sequencer_->frames()->size()); EXPECT_EQ(0u, sequencer_->num_bytes_consumed()); EXPECT_EQ("abc", sequencer_->frames()->find(3)->second); @@ -199,11 +223,11 @@ TEST_F(QuicStreamSequencerTest, FutureFrameNotProcessed) { TEST_F(QuicStreamSequencerTest, OutOfOrderFrameProcessed) { // Buffer the first - EXPECT_TRUE(sequencer_->OnFrame(6, "ghi", 3)); + EXPECT_TRUE(sequencer_->OnFrame(6, "ghi")); EXPECT_EQ(1u, sequencer_->frames()->size()); EXPECT_EQ(0u, sequencer_->num_bytes_consumed()); // Buffer the second - EXPECT_TRUE(sequencer_->OnFrame(3, "def", 3)); + EXPECT_TRUE(sequencer_->OnFrame(3, "def")); EXPECT_EQ(2u, sequencer_->frames()->size()); EXPECT_EQ(0u, sequencer_->num_bytes_consumed()); @@ -213,7 +237,7 @@ TEST_F(QuicStreamSequencerTest, OutOfOrderFrameProcessed) { EXPECT_CALL(stream_, ProcessData(StrEq("ghi"), 3)).WillOnce(Return(3)); // Ack right away - EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3)); + EXPECT_TRUE(sequencer_->OnFrame(0, "abc")); EXPECT_EQ(9u, sequencer_->num_bytes_consumed()); EXPECT_EQ(0u, sequencer_->frames()->size()); @@ -223,28 +247,28 @@ TEST_F(QuicStreamSequencerTest, OutOfOrderFramesProcessedWithBuffering) { sequencer_->SetMemoryLimit(9); // Too far to buffer. - EXPECT_FALSE(sequencer_->OnFrame(9, "jkl", 3)); + EXPECT_FALSE(sequencer_->OnFrame(9, "jkl")); // We can afford to buffer this. - EXPECT_TRUE(sequencer_->OnFrame(6, "ghi", 3)); + EXPECT_TRUE(sequencer_->OnFrame(6, "ghi")); EXPECT_EQ(0u, sequencer_->num_bytes_consumed()); InSequence s; EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3)); // Ack right away - EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3)); + EXPECT_TRUE(sequencer_->OnFrame(0, "abc")); EXPECT_EQ(3u, sequencer_->num_bytes_consumed()); // We should be willing to buffer this now. - EXPECT_TRUE(sequencer_->OnFrame(9, "jkl", 3)); + EXPECT_TRUE(sequencer_->OnFrame(9, "jkl")); EXPECT_EQ(3u, sequencer_->num_bytes_consumed()); EXPECT_CALL(stream_, ProcessData(StrEq("def"), 3)).WillOnce(Return(3)); EXPECT_CALL(stream_, ProcessData(StrEq("ghi"), 3)).WillOnce(Return(3)); EXPECT_CALL(stream_, ProcessData(StrEq("jkl"), 3)).WillOnce(Return(3)); - EXPECT_TRUE(sequencer_->OnFrame(3, "def", 3)); + EXPECT_TRUE(sequencer_->OnFrame(3, "def")); EXPECT_EQ(12u, sequencer_->num_bytes_consumed()); EXPECT_EQ(0u, sequencer_->frames()->size()); } @@ -273,25 +297,25 @@ TEST_F(QuicStreamSequencerTest, OutOfOrderFramesBlockignWithReadv) { EXPECT_CALL(stream_, ProcessData(StrEq("def"), 3)).WillOnce(Return(0)); EXPECT_CALL(stream_, ProcessData(StrEq("pqr"), 3)).WillOnce(Return(3)); - EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3)); - EXPECT_TRUE(sequencer_->OnFrame(3, "def", 3)); - EXPECT_TRUE(sequencer_->OnFrame(9, "jkl", 3)); - EXPECT_FALSE(sequencer_->OnFrame(12, "mno", 3)); - EXPECT_TRUE(sequencer_->OnFrame(6, "ghi", 3)); + EXPECT_TRUE(sequencer_->OnFrame(0, "abc")); + EXPECT_TRUE(sequencer_->OnFrame(3, "def")); + EXPECT_TRUE(sequencer_->OnFrame(9, "jkl")); + EXPECT_FALSE(sequencer_->OnFrame(12, "mno")); + EXPECT_TRUE(sequencer_->OnFrame(6, "ghi")); // Read 3 bytes. EXPECT_EQ(3, sequencer_->Readv(iov, 2)); EXPECT_EQ(0, strncmp(buffer, "def", 3)); // Now we have space to bufer this. - EXPECT_TRUE(sequencer_->OnFrame(12, "mno", 3)); + EXPECT_TRUE(sequencer_->OnFrame(12, "mno")); // Read the remaining 9 bytes. iov[1].iov_len = 19; EXPECT_EQ(9, sequencer_->Readv(iov, 2)); EXPECT_EQ(0, strncmp(buffer, "ghijklmno", 9)); - EXPECT_TRUE(sequencer_->OnFrame(15, "pqr", 3)); + EXPECT_TRUE(sequencer_->OnFrame(15, "pqr")); } // Same as above, just using a different method for reading. @@ -303,11 +327,11 @@ TEST_F(QuicStreamSequencerTest, OutOfOrderFramesBlockignWithGetReadableRegion) { EXPECT_CALL(stream_, ProcessData(StrEq("def"), 3)).WillOnce(Return(0)); EXPECT_CALL(stream_, ProcessData(StrEq("pqr"), 3)).WillOnce(Return(3)); - EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3)); - EXPECT_TRUE(sequencer_->OnFrame(3, "def", 3)); - EXPECT_TRUE(sequencer_->OnFrame(9, "jkl", 3)); - EXPECT_FALSE(sequencer_->OnFrame(12, "mno", 3)); - EXPECT_TRUE(sequencer_->OnFrame(6, "ghi", 3)); + EXPECT_TRUE(sequencer_->OnFrame(0, "abc")); + EXPECT_TRUE(sequencer_->OnFrame(3, "def")); + EXPECT_TRUE(sequencer_->OnFrame(9, "jkl")); + EXPECT_FALSE(sequencer_->OnFrame(12, "mno")); + EXPECT_TRUE(sequencer_->OnFrame(6, "ghi")); // Read 3 bytes. const char* expected[] = {"def", "ghi", "jkl"}; @@ -317,7 +341,7 @@ TEST_F(QuicStreamSequencerTest, OutOfOrderFramesBlockignWithGetReadableRegion) { ASSERT_EQ(3, sequencer_->Readv(&read_iov, 1)); // Now we have space to bufer this. - EXPECT_TRUE(sequencer_->OnFrame(12, "mno", 3)); + EXPECT_TRUE(sequencer_->OnFrame(12, "mno")); // Read the remaining 9 bytes. const char* expected2[] = {"ghi", "jkl", "mno"}; @@ -325,7 +349,7 @@ TEST_F(QuicStreamSequencerTest, OutOfOrderFramesBlockignWithGetReadableRegion) { read_iov.iov_len = 9; ASSERT_EQ(9, sequencer_->Readv(&read_iov, 1)); - EXPECT_TRUE(sequencer_->OnFrame(15, "pqr", 3)); + EXPECT_TRUE(sequencer_->OnFrame(15, "pqr")); } // Same as above, just using a different method for reading. @@ -335,9 +359,9 @@ TEST_F(QuicStreamSequencerTest, MarkConsumed) { InSequence s; EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(0)); - EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3)); - EXPECT_TRUE(sequencer_->OnFrame(3, "def", 3)); - EXPECT_TRUE(sequencer_->OnFrame(6, "ghi", 3)); + EXPECT_TRUE(sequencer_->OnFrame(0, "abc")); + EXPECT_TRUE(sequencer_->OnFrame(3, "def")); + EXPECT_TRUE(sequencer_->OnFrame(6, "ghi")); // Peek into the data. const char* expected[] = {"abc", "def", "ghi"}; @@ -366,45 +390,44 @@ TEST_F(QuicStreamSequencerTest, BasicHalfCloseOrdered) { InSequence s; EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3)); - EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3)); - EXPECT_CALL(stream_, TerminateFromPeer(true)); - sequencer_->CloseStreamAtOffset(3); + EXPECT_TRUE(sequencer_->OnFinFrame(0, "abc")); + EXPECT_EQ(3u, sequencer_->close_offset()); } TEST_F(QuicStreamSequencerTest, BasicHalfCloseUnorderedWithFlush) { - sequencer_->CloseStreamAtOffset(6); + sequencer_->OnFinFrame(6, ""); EXPECT_EQ(6u, sequencer_->close_offset()); InSequence s; EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3)); EXPECT_CALL(stream_, ProcessData(StrEq("def"), 3)).WillOnce(Return(3)); EXPECT_CALL(stream_, TerminateFromPeer(true)); - EXPECT_TRUE(sequencer_->OnFrame(3, "def", 3)); - EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3)); + EXPECT_TRUE(sequencer_->OnFrame(3, "def")); + EXPECT_TRUE(sequencer_->OnFrame(0, "abc")); } TEST_F(QuicStreamSequencerTest, BasicHalfUnordered) { - sequencer_->CloseStreamAtOffset(3); + sequencer_->OnFinFrame(3, ""); EXPECT_EQ(3u, sequencer_->close_offset()); InSequence s; EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3)); EXPECT_CALL(stream_, TerminateFromPeer(true)); - EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3)); + EXPECT_TRUE(sequencer_->OnFrame(0, "abc")); } TEST_F(QuicStreamSequencerTest, TerminateWithReadv) { char buffer[3]; - sequencer_->CloseStreamAtOffset(3); + sequencer_->OnFinFrame(3, ""); EXPECT_EQ(3u, sequencer_->close_offset()); EXPECT_FALSE(sequencer_->IsHalfClosed()); EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(0)); - EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3)); + EXPECT_TRUE(sequencer_->OnFrame(0, "abc")); iovec iov = { &buffer[0], 3 }; int bytes_read = sequencer_->Readv(&iov, 1); @@ -413,18 +436,18 @@ TEST_F(QuicStreamSequencerTest, TerminateWithReadv) { } TEST_F(QuicStreamSequencerTest, MutipleOffsets) { - sequencer_->CloseStreamAtOffset(3); + sequencer_->OnFinFrame(3, ""); EXPECT_EQ(3u, sequencer_->close_offset()); EXPECT_CALL(stream_, Close(QUIC_MULTIPLE_TERMINATION_OFFSETS)); - sequencer_->CloseStreamAtOffset(5); + sequencer_->OnFinFrame(5, ""); EXPECT_EQ(3u, sequencer_->close_offset()); EXPECT_CALL(stream_, Close(QUIC_MULTIPLE_TERMINATION_OFFSETS)); - sequencer_->CloseStreamAtOffset(1); + sequencer_->OnFinFrame(1, ""); EXPECT_EQ(3u, sequencer_->close_offset()); - sequencer_->CloseStreamAtOffset(3); + sequencer_->OnFinFrame(3, ""); EXPECT_EQ(3u, sequencer_->close_offset()); } @@ -479,9 +502,9 @@ TEST_F(QuicSequencerRandomTest, RandomFramesNoDroppingNoBackup) { int index = OneToN(list_.size()) - 1; LOG(ERROR) << "Sending index " << index << " " << list_[index].second.data(); - EXPECT_TRUE(sequencer_->OnFrame( - list_[index].first, list_[index].second.data(), - list_[index].second.size())); + EXPECT_TRUE(sequencer_->OnFrame(list_[index].first, + list_[index].second.data())); + list_.erase(list_.begin() + index); } } @@ -502,9 +525,9 @@ TEST_F(QuicSequencerRandomTest, RandomFramesDroppingNoBackup) { int index = OneToN(list_.size()) - 1; LOG(ERROR) << "Sending index " << index << " " << list_[index].second.data(); - bool acked = sequencer_->OnFrame( - list_[index].first, list_[index].second.data(), - list_[index].second.size()); + bool acked = sequencer_->OnFrame(list_[index].first, + list_[index].second.data()); + if (acked) { list_.erase(list_.begin() + index); } diff --git a/net/quic/reliable_quic_stream.cc b/net/quic/reliable_quic_stream.cc index 0fa5b7a..9b2bde5 100644 --- a/net/quic/reliable_quic_stream.cc +++ b/net/quic/reliable_quic_stream.cc @@ -22,6 +22,7 @@ ReliableQuicStream::ReliableQuicStream(QuicStreamId id, stream_bytes_written_(0), headers_decompressed_(false), headers_id_(0), + decompression_failed_(false), stream_error_(QUIC_STREAM_NO_ERROR), connection_error_(QUIC_NO_ERROR), read_side_closed_(false), @@ -57,10 +58,6 @@ bool ReliableQuicStream::OnStreamFrame(const QuicStreamFrame& frame) { bool accepted = sequencer_.OnStreamFrame(frame); - if (frame.fin) { - sequencer_.CloseStreamAtOffset(frame.offset + frame.data.size()); - } - return accepted; } @@ -267,6 +264,9 @@ uint32 ReliableQuicStream::ProcessRawData(const char* data, uint32 data_len) { data_len -= missing_size; } DCHECK_NE(0u, headers_id_); + if (data_len == 0) { + return total_bytes_consumed; + } // Once the headers are finished, we simply pass the data through. if (headers_decompressed_) { @@ -274,7 +274,7 @@ uint32 ReliableQuicStream::ProcessRawData(const char* data, uint32 data_len) { if (!decompressed_headers_.empty()) { ProcessHeaderData(); } - if (decompressed_headers_.empty() && data_len > 0) { + if (decompressed_headers_.empty()) { DVLOG(1) << "Delegating procesing to ProcessData"; total_bytes_consumed += ProcessData(data, data_len); } @@ -304,20 +304,39 @@ uint32 ReliableQuicStream::ProcessRawData(const char* data, uint32 data_len) { // Decompressed data will be delivered to decompressed_headers_. size_t bytes_consumed = session_->decompressor()->DecompressData( StringPiece(data, data_len), this); + DCHECK_NE(0u, bytes_consumed); + if (bytes_consumed > data_len) { + DCHECK(false) << "DecompressData returned illegal value"; + OnDecompressionError(); + return total_bytes_consumed; + } total_bytes_consumed += bytes_consumed; + data += bytes_consumed; + data_len -= bytes_consumed; + + if (decompression_failed_) { + // The session will have been closed in OnDecompressionError. + return total_bytes_consumed; + } // Headers are complete if the decompressor has moved on to the // next stream. headers_decompressed_ = session_->decompressor()->current_header_id() != headers_id_; + if (!headers_decompressed_) { + DCHECK_EQ(0u, data_len); + } ProcessHeaderData(); + if (!headers_decompressed_ || !decompressed_headers_.empty()) { + return total_bytes_consumed; + } + // We have processed all of the decompressed data but we might // have some more raw data to process. - if (decompressed_headers_.empty() && bytes_consumed < data_len) { - total_bytes_consumed += ProcessData(data + bytes_consumed, - data_len - bytes_consumed); + if (data_len > 0) { + total_bytes_consumed += ProcessData(data, data_len); } // The sequencer will push any additional buffered frames if this data @@ -344,6 +363,7 @@ void ReliableQuicStream::OnDecompressorAvailable() { DCHECK_EQ(headers_id_, session_->decompressor()->current_header_id()); DCHECK(!headers_decompressed_); + DCHECK(!decompression_failed_); DCHECK_EQ(0u, decompressed_headers_.length()); size_t total_bytes_consumed = 0; @@ -359,6 +379,9 @@ void ReliableQuicStream::OnDecompressorAvailable() { total_bytes_consumed += session_->decompressor()->DecompressData( StringPiece(static_cast<char*>(iovecs[i].iov_base), iovecs[i].iov_len), this); + if (decompression_failed_) { + return; + } headers_decompressed_ = session_->decompressor()->current_header_id() != headers_id_; @@ -381,6 +404,8 @@ bool ReliableQuicStream::OnDecompressedData(StringPiece data) { } void ReliableQuicStream::OnDecompressionError() { + DCHECK(!decompression_failed_); + decompression_failed_ = true; session_->connection()->SendConnectionClose(QUIC_DECOMPRESSION_FAILURE); } diff --git a/net/quic/reliable_quic_stream.h b/net/quic/reliable_quic_stream.h index 05abaef..3f5150b 100644 --- a/net/quic/reliable_quic_stream.h +++ b/net/quic/reliable_quic_stream.h @@ -172,6 +172,8 @@ class NET_EXPORT_PRIVATE ReliableQuicStream : public // Contains a copy of the decompressed headers_ until they are consumed // via ProcessData or Readv. string decompressed_headers_; + // True if an error was encountered during decompression. + bool decompression_failed_; // Stream error code received from a RstStreamFrame or error code sent by the // visitor or sequencer in the RstStreamFrame. diff --git a/net/quic/reliable_quic_stream_test.cc b/net/quic/reliable_quic_stream_test.cc index dc5c160..c73c5b1 100644 --- a/net/quic/reliable_quic_stream_test.cc +++ b/net/quic/reliable_quic_stream_test.cc @@ -44,6 +44,7 @@ class TestStream : public ReliableQuicStream { } virtual uint32 ProcessData(const char* data, uint32 data_len) OVERRIDE { + EXPECT_NE(0u, data_len); DVLOG(1) << "ProcessData data_len: " << data_len; data_ += string(data, data_len); return should_process_data_ ? data_len : 0; @@ -66,6 +67,30 @@ class ReliableQuicStreamTest : public ::testing::TestWithParam<bool> { headers_[":host"] = "www.google.com"; headers_[":path"] = "/index.hml"; headers_[":scheme"] = "https"; + headers_["cookie"] = + "__utma=208381060.1228362404.1372200928.1372200928.1372200928.1; " + "__utmc=160408618; " + "GX=DQAAAOEAAACWJYdewdE9rIrW6qw3PtVi2-d729qaa-74KqOsM1NVQblK4VhX" + "hoALMsy6HOdDad2Sz0flUByv7etmo3mLMidGrBoljqO9hSVA40SLqpG_iuKKSHX" + "RW3Np4bq0F0SDGDNsW0DSmTS9ufMRrlpARJDS7qAI6M3bghqJp4eABKZiRqebHT" + "pMU-RXvTI5D5oCF1vYxYofH_l1Kviuiy3oQ1kS1enqWgbhJ2t61_SNdv-1XJIS0" + "O3YeHLmVCs62O6zp89QwakfAWK9d3IDQvVSJzCQsvxvNIvaZFa567MawWlXg0Rh" + "1zFMi5vzcns38-8_Sns; " + "GA=v*2%2Fmem*57968640*47239936%2Fmem*57968640*47114716%2Fno-nm-" + "yj*15%2Fno-cc-yj*5%2Fpc-ch*133685%2Fpc-s-cr*133947%2Fpc-s-t*1339" + "47%2Fno-nm-yj*4%2Fno-cc-yj*1%2Fceft-as*1%2Fceft-nqas*0%2Fad-ra-c" + "v_p%2Fad-nr-cv_p-f*1%2Fad-v-cv_p*859%2Fad-ns-cv_p-f*1%2Ffn-v-ad%" + "2Fpc-t*250%2Fpc-cm*461%2Fpc-s-cr*722%2Fpc-s-t*722%2Fau_p*4" + "SICAID=AJKiYcHdKgxum7KMXG0ei2t1-W4OD1uW-ecNsCqC0wDuAXiDGIcT_HA2o1" + "3Rs1UKCuBAF9g8rWNOFbxt8PSNSHFuIhOo2t6bJAVpCsMU5Laa6lewuTMYI8MzdQP" + "ARHKyW-koxuhMZHUnGBJAM1gJODe0cATO_KGoX4pbbFxxJ5IicRxOrWK_5rU3cdy6" + "edlR9FsEdH6iujMcHkbE5l18ehJDwTWmBKBzVD87naobhMMrF6VvnDGxQVGp9Ir_b" + "Rgj3RWUoPumQVCxtSOBdX0GlJOEcDTNCzQIm9BSfetog_eP_TfYubKudt5eMsXmN6" + "QnyXHeGeK2UINUzJ-D30AFcpqYgH9_1BvYSpi7fc7_ydBU8TaD8ZRxvtnzXqj0RfG" + "tuHghmv3aD-uzSYJ75XDdzKdizZ86IG6Fbn1XFhYZM-fbHhm3mVEXnyRW4ZuNOLFk" + "Fas6LMcVC6Q8QLlHYbXBpdNFuGbuZGUnav5C-2I_-46lL0NGg3GewxGKGHvHEfoyn" + "EFFlEYHsBQ98rXImL8ySDycdLEFvBPdtctPmWCfTxwmoSMLHU2SCVDhbqMWU5b0yr" + "JBCScs_ejbKaqBDoB7ZGxTvqlrB__2ZmnHHjCr8RgMRtKNtIeuZAo "; } void Initialize(bool stream_should_process_data) { @@ -263,6 +288,21 @@ TEST_F(ReliableQuicStreamTest, ProcessHeadersAndBodyFragments) { ASSERT_EQ(SpdyUtils::SerializeUncompressedHeaders(headers_) + body, stream_->data()) << "fragment_size: " << fragment_size; } + + for (size_t split_point = 1; split_point < data.size() - 1; ++split_point) { + Initialize(kShouldProcessData); + + StringPiece fragment1(data.data(), split_point); + QuicStreamFrame frame1(kStreamId, false, 0, fragment1); + stream_->OnStreamFrame(frame1); + + StringPiece fragment2(data.data() + split_point, data.size() - split_point); + QuicStreamFrame frame2(kStreamId, false, split_point, fragment2); + stream_->OnStreamFrame(frame2); + + ASSERT_EQ(SpdyUtils::SerializeUncompressedHeaders(headers_) + body, + stream_->data()) << "split_point: " << split_point; + } } TEST_F(ReliableQuicStreamTest, ProcessHeadersAndBodyReadv) { @@ -279,7 +319,7 @@ TEST_F(ReliableQuicStreamTest, ProcessHeadersAndBodyReadv) { stream_->OnStreamFrame(frame); EXPECT_EQ(uncompressed_headers, stream_->data()); - char buffer[1024]; + char buffer[2048]; ASSERT_LT(data.length(), arraysize(buffer)); struct iovec vec; vec.iov_base = buffer; @@ -348,6 +388,43 @@ TEST_F(ReliableQuicStreamTest, ProcessHeadersUsingReadvWithMultipleIovecs) { } } +TEST_F(ReliableQuicStreamTest, ProcessCorruptHeadersEarly) { + Initialize(kShouldProcessData); + + string compressed_headers1 = compressor_->CompressHeaders(headers_); + QuicStreamFrame frame1(stream_->id(), false, 0, compressed_headers1); + string decompressed_headers1 = + SpdyUtils::SerializeUncompressedHeaders(headers_); + + headers_["content-type"] = "text/plain"; + string compressed_headers2 = compressor_->CompressHeaders(headers_); + compressed_headers2[4] ^= 0xA1; // Corrupt the comressed data. + QuicStreamFrame frame2(stream2_->id(), false, 0, compressed_headers2); + string decompressed_headers2 = + SpdyUtils::SerializeUncompressedHeaders(headers_); + + // Deliver frame2 to stream2 out of order. The decompressor is not + // available yet, so no data will be processed. The compressed data + // will be buffered until OnDecompressorAvailable() is called + // to process it. + stream2_->OnStreamFrame(frame2); + EXPECT_EQ("", stream2_->data()); + + // Now deliver frame1 to stream1. The decompressor is available so + // the data will be processed, and the decompressor will become + // available for stream2. + stream_->OnStreamFrame(frame1); + EXPECT_EQ(decompressed_headers1, stream_->data()); + + // Verify that the decompressor is available, and inform stream2 + // that it can now decompress the buffered compressed data. Since + // the compressed data is corrupt, the stream will shutdown the session. + EXPECT_EQ(2u, session_->decompressor()->current_header_id()); + EXPECT_CALL(*connection_, SendConnectionClose(QUIC_DECOMPRESSION_FAILURE)); + stream2_->OnDecompressorAvailable(); + EXPECT_EQ("", stream2_->data()); +} + TEST_F(ReliableQuicStreamTest, ProcessHeadersEarly) { Initialize(kShouldProcessData); @@ -362,12 +439,21 @@ TEST_F(ReliableQuicStreamTest, ProcessHeadersEarly) { string decompressed_headers2 = SpdyUtils::SerializeUncompressedHeaders(headers_); + // Deliver frame2 to stream2 out of order. The decompressor is not + // available yet, so no data will be processed. The compressed data + // will be buffered until OnDecompressorAvailable() is called + // to process it. stream2_->OnStreamFrame(frame2); - EXPECT_EQ("", stream_->data()); + EXPECT_EQ("", stream2_->data()); + // Now deliver frame1 to stream1. The decompressor is available so + // the data will be processed, and the decompressor will become + // available for stream2. stream_->OnStreamFrame(frame1); EXPECT_EQ(decompressed_headers1, stream_->data()); + // Verify that the decompressor is available, and inform stream2 + // that it can now decompress the buffered compressed data. EXPECT_EQ(2u, session_->decompressor()->current_header_id()); stream2_->OnDecompressorAvailable(); EXPECT_EQ(decompressed_headers2, stream2_->data()); diff --git a/net/quic/test_tools/quic_connection_peer.cc b/net/quic/test_tools/quic_connection_peer.cc index 8c4c245..330aa06 100644 --- a/net/quic/test_tools/quic_connection_peer.cc +++ b/net/quic/test_tools/quic_connection_peer.cc @@ -89,7 +89,7 @@ size_t QuicConnectionPeer::GetRetransmissionCount( QuicPacketEntropyHash QuicConnectionPeer::GetSentEntropyHash( QuicConnection* connection, QuicPacketSequenceNumber sequence_number) { - return connection->entropy_manager_.SentEntropyHash(sequence_number); + return connection->sent_entropy_manager_.EntropyHash(sequence_number); } // static @@ -98,7 +98,7 @@ bool QuicConnectionPeer::IsValidEntropy( QuicPacketSequenceNumber largest_observed, const SequenceNumberSet& missing_packets, QuicPacketEntropyHash entropy_hash) { - return connection->entropy_manager_.IsValidEntropy( + return connection->sent_entropy_manager_.IsValidEntropy( largest_observed, missing_packets, entropy_hash); } @@ -106,7 +106,8 @@ bool QuicConnectionPeer::IsValidEntropy( QuicPacketEntropyHash QuicConnectionPeer::ReceivedEntropyHash( QuicConnection* connection, QuicPacketSequenceNumber sequence_number) { - return connection->entropy_manager_.ReceivedEntropyHash(sequence_number); + return connection->received_entropy_manager_.EntropyHash( + sequence_number); } // static diff --git a/net/quic/test_tools/quic_framer_peer.cc b/net/quic/test_tools/quic_framer_peer.cc index f31299c..5ec52dc 100644 --- a/net/quic/test_tools/quic_framer_peer.cc +++ b/net/quic/test_tools/quic_framer_peer.cc @@ -34,7 +34,7 @@ void QuicFramerPeer::SetIsServer(QuicFramer* framer, bool is_server) { framer->is_server_ = is_server; } -void QuicFramerPeer::SetVersion(QuicFramer* framer, QuicTag version) { +void QuicFramerPeer::SetVersion(QuicFramer* framer, QuicVersion version) { framer->quic_version_ = version; } diff --git a/net/quic/test_tools/quic_framer_peer.h b/net/quic/test_tools/quic_framer_peer.h index 7a2da5c..0508f5c 100644 --- a/net/quic/test_tools/quic_framer_peer.h +++ b/net/quic/test_tools/quic_framer_peer.h @@ -24,7 +24,7 @@ class QuicFramerPeer { QuicFramer* framer, QuicPacketSequenceNumber packet_sequence_number); static void SetIsServer(QuicFramer* framer, bool is_server); - static void SetVersion(QuicFramer* framer, QuicTag version); + static void SetVersion(QuicFramer* framer, QuicVersion version); private: DISALLOW_COPY_AND_ASSIGN(QuicFramerPeer); diff --git a/net/quic/test_tools/quic_test_utils.cc b/net/quic/test_tools/quic_test_utils.cc index 809f28a..3f122ba 100644 --- a/net/quic/test_tools/quic_test_utils.cc +++ b/net/quic/test_tools/quic_test_utils.cc @@ -55,7 +55,7 @@ MockFramerVisitor::MockFramerVisitor() { MockFramerVisitor::~MockFramerVisitor() { } -bool NoOpFramerVisitor::OnProtocolVersionMismatch(QuicTag version) { +bool NoOpFramerVisitor::OnProtocolVersionMismatch(QuicVersion version) { return false; } @@ -189,7 +189,7 @@ MockConnection::MockConnection(QuicGuid guid, IPEndPoint address, bool is_server) : QuicConnection(guid, address, new testing::NiceMock<MockHelper>(), - is_server), + is_server, QuicVersionMax()), has_mock_helper_(true) { } @@ -197,7 +197,7 @@ MockConnection::MockConnection(QuicGuid guid, IPEndPoint address, QuicConnectionHelperInterface* helper, bool is_server) - : QuicConnection(guid, address, helper, is_server), + : QuicConnection(guid, address, helper, is_server, QuicVersionMax()), has_mock_helper_(false) { } @@ -354,7 +354,7 @@ static QuicPacket* ConstructPacketFromHandshakeMessage( bool should_include_version) { CryptoFramer crypto_framer; scoped_ptr<QuicData> data(crypto_framer.ConstructHandshakeMessage(message)); - QuicFramer quic_framer(kQuicVersion1, QuicTime::Zero(), false); + QuicFramer quic_framer(QuicVersionMax(), QuicTime::Zero(), false); QuicPacketHeader header; header.public_header.guid = guid; @@ -403,7 +403,7 @@ size_t GetPacketLengthForOneStream( PACKET_6BYTE_SEQUENCE_NUMBER, is_in_fec_group); } -QuicPacketEntropyHash TestEntropyCalculator::ReceivedEntropyHash( +QuicPacketEntropyHash TestEntropyCalculator::EntropyHash( QuicPacketSequenceNumber sequence_number) const { return 1u; } diff --git a/net/quic/test_tools/quic_test_utils.h b/net/quic/test_tools/quic_test_utils.h index d67fb9c..d24a2a5 100644 --- a/net/quic/test_tools/quic_test_utils.h +++ b/net/quic/test_tools/quic_test_utils.h @@ -53,7 +53,7 @@ class MockFramerVisitor : public QuicFramerVisitorInterface { MOCK_METHOD1(OnError, void(QuicFramer* framer)); // The constructor sets this up to return false by default. - MOCK_METHOD1(OnProtocolVersionMismatch, bool(QuicTag version)); + MOCK_METHOD1(OnProtocolVersionMismatch, bool(QuicVersion version)); MOCK_METHOD0(OnPacket, void()); MOCK_METHOD1(OnPublicResetPacket, void(const QuicPublicResetPacket& header)); MOCK_METHOD1(OnVersionNegotiationPacket, @@ -88,7 +88,7 @@ class NoOpFramerVisitor : public QuicFramerVisitorInterface { virtual void OnVersionNegotiationPacket( const QuicVersionNegotiationPacket& packet) OVERRIDE {} virtual void OnRevivedPacket() OVERRIDE {} - virtual bool OnProtocolVersionMismatch(QuicTag version) OVERRIDE; + virtual bool OnProtocolVersionMismatch(QuicVersion version) OVERRIDE; virtual bool OnPacketHeader(const QuicPacketHeader& header) OVERRIDE; virtual void OnFecProtectedPayload(base::StringPiece payload) OVERRIDE {} virtual bool OnStreamFrame(const QuicStreamFrame& frame) OVERRIDE; @@ -245,7 +245,7 @@ class MockConnection : public QuicConnection { QuicConnection::ProcessUdpPacket(self_address, peer_address, packet); } - virtual bool OnProtocolVersionMismatch(QuicTag version) OVERRIDE { + virtual bool OnProtocolVersionMismatch(QuicVersion version) OVERRIDE { return false; } @@ -338,6 +338,7 @@ class MockSendAlgorithm : public SendAlgorithmInterface { HasRetransmittableData)); MOCK_METHOD0(BandwidthEstimate, QuicBandwidth(void)); MOCK_METHOD0(SmoothedRtt, QuicTime::Delta(void)); + MOCK_METHOD0(RetransmissionDelay, QuicTime::Delta(void)); private: DISALLOW_COPY_AND_ASSIGN(MockSendAlgorithm); @@ -349,7 +350,7 @@ class TestEntropyCalculator : TestEntropyCalculator() { } virtual ~TestEntropyCalculator() { } - virtual QuicPacketEntropyHash ReceivedEntropyHash( + virtual QuicPacketEntropyHash EntropyHash( QuicPacketSequenceNumber sequence_number) const OVERRIDE; }; diff --git a/net/quic/test_tools/simple_quic_framer.cc b/net/quic/test_tools/simple_quic_framer.cc index 7e77b0f..46be3a8 100644 --- a/net/quic/test_tools/simple_quic_framer.cc +++ b/net/quic/test_tools/simple_quic_framer.cc @@ -25,7 +25,7 @@ class SimpleFramerVisitor : public QuicFramerVisitorInterface { error_ = framer->error(); } - virtual bool OnProtocolVersionMismatch(QuicTag version) OVERRIDE { + virtual bool OnProtocolVersionMismatch(QuicVersion version) OVERRIDE { return false; } @@ -128,7 +128,7 @@ class SimpleFramerVisitor : public QuicFramerVisitorInterface { }; SimpleQuicFramer::SimpleQuicFramer() - : framer_(kQuicVersion1, QuicTime::Zero(), true) { + : framer_(QuicVersionMax(), QuicTime::Zero(), true) { } SimpleQuicFramer::~SimpleQuicFramer() { diff --git a/net/tools/quic/end_to_end_test.cc b/net/tools/quic/end_to_end_test.cc index 23e9b56..310c393 100644 --- a/net/tools/quic/end_to_end_test.cc +++ b/net/tools/quic/end_to_end_test.cc @@ -107,7 +107,12 @@ class ServerThread : public base::SimpleThread { DISALLOW_COPY_AND_ASSIGN(ServerThread); }; -class EndToEndTest : public ::testing::Test { +class EndToEndTest : public ::testing::TestWithParam<QuicVersion> { + public: + static void SetUpTestCase() { + QuicInMemoryCache::GetInstance()->ResetForTests(); + } + protected: EndToEndTest() : server_hostname_("example.com"), @@ -123,16 +128,14 @@ class EndToEndTest : public ::testing::Test { "HTTP/1.1", "200", "OK", kFooResponseBody); AddToCache("GET", "https://www.google.com/bar", "HTTP/1.1", "200", "OK", kBarResponseBody); - } - - static void SetUpTestCase() { - QuicInMemoryCache::GetInstance()->ResetForTests(); + version_ = GetParam(); } virtual QuicTestClient* CreateQuicClient() { QuicTestClient* client = new QuicTestClient(server_address_, server_hostname_, - client_config_); + client_config_, + version_); client->Connect(); return client; } @@ -205,9 +208,15 @@ class EndToEndTest : public ::testing::Test { bool server_started_; QuicConfig client_config_; QuicConfig server_config_; + QuicVersion version_; }; -TEST_F(EndToEndTest, SimpleRequestResponse) { +// Run all end to end tests with QUIC version 6. +INSTANTIATE_TEST_CASE_P(EndToEndTests, + EndToEndTest, + ::testing::Values(QUIC_VERSION_6)); + +TEST_P(EndToEndTest, SimpleRequestResponse) { // TODO(rtenneti): Delete this when NSS is supported. if (!Aes128Gcm12Encrypter::IsSupported()) { LOG(INFO) << "AES GCM not supported. Test skipped."; @@ -222,7 +231,7 @@ TEST_F(EndToEndTest, SimpleRequestResponse) { // TODO(rch): figure out how to detect missing v6 supprt (like on the linux // try bots) and selectively disable this test. -TEST_F(EndToEndTest, DISABLED_SimpleRequestResponsev6) { +TEST_P(EndToEndTest, DISABLED_SimpleRequestResponsev6) { // TODO(rtenneti): Delete this when NSS is supported. if (!Aes128Gcm12Encrypter::IsSupported()) { LOG(INFO) << "AES GCM not supported. Test skipped."; @@ -238,7 +247,7 @@ TEST_F(EndToEndTest, DISABLED_SimpleRequestResponsev6) { EXPECT_EQ(200u, client_->response_headers()->parsed_response_code()); } -TEST_F(EndToEndTest, SeparateFinPacket) { +TEST_P(EndToEndTest, SeparateFinPacket) { // TODO(rtenneti): Delete this when NSS is supported. if (!Aes128Gcm12Encrypter::IsSupported()) { LOG(INFO) << "AES GCM not supported. Test skipped."; @@ -268,7 +277,7 @@ TEST_F(EndToEndTest, SeparateFinPacket) { EXPECT_EQ(200u, client_->response_headers()->parsed_response_code()); } -TEST_F(EndToEndTest, MultipleRequestResponse) { +TEST_P(EndToEndTest, MultipleRequestResponse) { // TODO(rtenneti): Delete this when NSS is supported. if (!Aes128Gcm12Encrypter::IsSupported()) { LOG(INFO) << "AES GCM not supported. Test skipped."; @@ -283,7 +292,7 @@ TEST_F(EndToEndTest, MultipleRequestResponse) { EXPECT_EQ(200u, client_->response_headers()->parsed_response_code()); } -TEST_F(EndToEndTest, MultipleClients) { +TEST_P(EndToEndTest, MultipleClients) { // TODO(rtenneti): Delete this when NSS is supported. if (!Aes128Gcm12Encrypter::IsSupported()) { LOG(INFO) << "AES GCM not supported. Test skipped."; @@ -312,7 +321,7 @@ TEST_F(EndToEndTest, MultipleClients) { EXPECT_EQ(200u, client2->response_headers()->parsed_response_code()); } -TEST_F(EndToEndTest, RequestOverMultiplePackets) { +TEST_P(EndToEndTest, RequestOverMultiplePackets) { // TODO(rtenneti): Delete this when NSS is supported. if (!Aes128Gcm12Encrypter::IsSupported()) { LOG(INFO) << "AES GCM not supported. Test skipped."; @@ -344,7 +353,7 @@ TEST_F(EndToEndTest, RequestOverMultiplePackets) { EXPECT_EQ(200u, client_->response_headers()->parsed_response_code()); } -TEST_F(EndToEndTest, MultipleFramesRandomOrder) { +TEST_P(EndToEndTest, MultipleFramesRandomOrder) { // TODO(rtenneti): Delete this when NSS is supported. if (!Aes128Gcm12Encrypter::IsSupported()) { LOG(INFO) << "AES GCM not supported. Test skipped."; @@ -377,7 +386,7 @@ TEST_F(EndToEndTest, MultipleFramesRandomOrder) { EXPECT_EQ(200u, client_->response_headers()->parsed_response_code()); } -TEST_F(EndToEndTest, PostMissingBytes) { +TEST_P(EndToEndTest, PostMissingBytes) { // TODO(rtenneti): Delete this when NSS is supported. if (!Aes128Gcm12Encrypter::IsSupported()) { LOG(INFO) << "AES GCM not supported. Test skipped."; @@ -399,7 +408,7 @@ TEST_F(EndToEndTest, PostMissingBytes) { EXPECT_EQ(500u, client_->response_headers()->parsed_response_code()); } -TEST_F(EndToEndTest, LargePost) { +TEST_P(EndToEndTest, LargePost) { // TODO(rtenneti): Delete this when NSS is supported. if (!Aes128Gcm12Encrypter::IsSupported()) { LOG(INFO) << "AES GCM not supported. Test skipped."; @@ -420,7 +429,7 @@ TEST_F(EndToEndTest, LargePost) { } // TODO(ianswett): Enable once b/9295090 is fixed. -TEST_F(EndToEndTest, DISABLED_LargePostFEC) { +TEST_P(EndToEndTest, DISABLED_LargePostFEC) { // FLAGS_fake_packet_loss_percentage = 30; ASSERT_TRUE(Initialize()); client_->options()->max_packets_per_fec_group = 6; @@ -445,7 +454,7 @@ TEST_F(EndToEndTest, DISABLED_LargePostFEC) { EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request)); } -/*TEST_F(EndToEndTest, PacketTooLarge) { +/*TEST_P(EndToEndTest, PacketTooLarge) { FLAGS_quic_allow_oversized_packets_for_test = true; ASSERT_TRUE(Initialize()); @@ -462,7 +471,7 @@ TEST_F(EndToEndTest, DISABLED_LargePostFEC) { EXPECT_EQ(QUIC_PACKET_TOO_LARGE, client_->connection_error()); }*/ -TEST_F(EndToEndTest, InvalidStream) { +TEST_P(EndToEndTest, InvalidStream) { // TODO(rtenneti): Delete this when NSS is supported. if (!Aes128Gcm12Encrypter::IsSupported()) { LOG(INFO) << "AES GCM not supported. Test skipped."; @@ -487,7 +496,7 @@ TEST_F(EndToEndTest, InvalidStream) { } // TODO(rch): this test seems to cause net_unittests timeouts :| -TEST_F(EndToEndTest, DISABLED_MultipleTermination) { +TEST_P(EndToEndTest, DISABLED_MultipleTermination) { // TODO(rtenneti): Delete this when NSS is supported. if (!Aes128Gcm12Encrypter::IsSupported()) { LOG(INFO) << "AES GCM not supported. Test skipped."; @@ -535,7 +544,7 @@ TEST_F(EndToEndTest, DISABLED_MultipleTermination) { #endif } -TEST_F(EndToEndTest, Timeout) { +TEST_P(EndToEndTest, Timeout) { client_config_.set_idle_connection_state_lifetime( QuicTime::Delta::FromMicroseconds(500), QuicTime::Delta::FromMicroseconds(500)); @@ -547,7 +556,7 @@ TEST_F(EndToEndTest, Timeout) { } } -TEST_F(EndToEndTest, LimitMaxOpenStreams) { +TEST_P(EndToEndTest, LimitMaxOpenStreams) { // Server limits the number of max streams to 2. server_config_.set_max_streams_per_connection(2, 2); // Client tries to negotiate for 10. @@ -559,7 +568,7 @@ TEST_F(EndToEndTest, LimitMaxOpenStreams) { EXPECT_EQ(2u, client_negotiated_config->max_streams_per_connection()); } -TEST_F(EndToEndTest, ResetConnection) { +TEST_P(EndToEndTest, ResetConnection) { // TODO(rtenneti): Delete this when NSS is supported. if (!Aes128Gcm12Encrypter::IsSupported()) { LOG(INFO) << "AES GCM not supported. Test skipped."; @@ -597,7 +606,7 @@ class WrongAddressWriter : public QuicPacketWriter { int fd_; }; -TEST_F(EndToEndTest, ConnectionMigration) { +TEST_P(EndToEndTest, ConnectionMigration) { // TODO(rtenneti): Delete this when NSS is supported. if (!Aes128Gcm12Encrypter::IsSupported()) { LOG(INFO) << "AES GCM not supported. Test skipped."; diff --git a/net/tools/quic/quic_client.cc b/net/tools/quic/quic_client.cc index b7e8d78..0d3baa9 100644 --- a/net/tools/quic/quic_client.cc +++ b/net/tools/quic/quic_client.cc @@ -31,20 +31,23 @@ namespace tools { const int kEpollFlags = EPOLLIN | EPOLLOUT | EPOLLET; QuicClient::QuicClient(IPEndPoint server_address, - const string& server_hostname) + const string& server_hostname, + const QuicVersion version) : server_address_(server_address), server_hostname_(server_hostname), local_port_(0), fd_(-1), initialized_(false), packets_dropped_(0), - overflow_supported_(false) { + overflow_supported_(false), + version_(version) { config_.SetDefaults(); } QuicClient::QuicClient(IPEndPoint server_address, const string& server_hostname, - const QuicConfig& config) + const QuicConfig& config, + const QuicVersion version) : server_address_(server_address), server_hostname_(server_hostname), config_(config), @@ -52,7 +55,8 @@ QuicClient::QuicClient(IPEndPoint server_address, fd_(-1), initialized_(false), packets_dropped_(0), - overflow_supported_(false) { + overflow_supported_(false), + version_(version) { } QuicClient::~QuicClient() { @@ -152,7 +156,7 @@ bool QuicClient::StartConnect() { config_, new QuicConnection(guid, server_address_, new QuicEpollConnectionHelper(fd_, &epoll_server_), - false), + false, version_), &crypto_config_)); return session_->CryptoConnect(); } diff --git a/net/tools/quic/quic_client.h b/net/tools/quic/quic_client.h index 77b2eec..2b9b9e7 100644 --- a/net/tools/quic/quic_client.h +++ b/net/tools/quic/quic_client.h @@ -34,10 +34,12 @@ class QuicClientPeer; class QuicClient : public EpollCallbackInterface { public: - QuicClient(IPEndPoint server_address, const std::string& server_hostname); + QuicClient(IPEndPoint server_address, const std::string& server_hostname, + const QuicVersion version); QuicClient(IPEndPoint server_address, const std::string& server_hostname, - const QuicConfig& config); + const QuicConfig& config, + const QuicVersion version); virtual ~QuicClient(); @@ -130,6 +132,13 @@ class QuicClient : public EpollCallbackInterface { crypto_config_.SetProofVerifier(verifier); } + // SetChannelIDSigner sets a ChannelIDSigner that will be called when the + // server supports channel IDs to sign a message proving possession of the + // given ChannelID. This object takes ownership of |signer|. + void SetChannelIDSigner(ChannelIDSigner* signer) { + crypto_config_.SetChannelIDSigner(signer); + } + private: friend class net::tools::test::QuicClientPeer; @@ -177,6 +186,9 @@ class QuicClient : public EpollCallbackInterface { // because the socket would otherwise overflow. bool overflow_supported_; + // Which QUIC version does this client talk? + QuicVersion version_; + DISALLOW_COPY_AND_ASSIGN(QuicClient); }; diff --git a/net/tools/quic/quic_client_bin.cc b/net/tools/quic/quic_client_bin.cc index 13fbfc0..e13bea5 100644 --- a/net/tools/quic/quic_client_bin.cc +++ b/net/tools/quic/quic_client_bin.cc @@ -13,6 +13,7 @@ #include "base/logging.h" #include "base/strings/string_number_conversions.h" #include "net/base/ip_endpoint.h" +#include "net/quic/quic_protocol.h" #include "net/tools/quic/quic_client.h" int32 FLAGS_port = 6121; @@ -42,8 +43,9 @@ int main(int argc, char *argv[]) { net::IPAddressNumber addr; CHECK(net::ParseIPLiteralToNumber(FLAGS_address, &addr)); + // TODO(rjshade): Set version on command line. net::tools::QuicClient client( - net::IPEndPoint(addr, FLAGS_port), FLAGS_hostname); + net::IPEndPoint(addr, FLAGS_port), FLAGS_hostname, net::QuicVersionMax()); client.Initialize(); diff --git a/net/tools/quic/quic_dispatcher.cc b/net/tools/quic/quic_dispatcher.cc index bfff5e6..d702b1d 100644 --- a/net/tools/quic/quic_dispatcher.cc +++ b/net/tools/quic/quic_dispatcher.cc @@ -94,7 +94,8 @@ void QuicDispatcher::ProcessPacket(const IPEndPoint& server_address, if (session == NULL) { DLOG(INFO) << "Failed to create session for " << guid; // Add this guid fo the time-wait state, to safely nack future packets. - time_wait_list_manager_->AddGuidToTimeWait(guid); + // We don't know the version here, so assume latest. + time_wait_list_manager_->AddGuidToTimeWait(guid, QuicVersionMax()); time_wait_list_manager_->ProcessPacket(server_address, client_address, guid, @@ -114,7 +115,8 @@ void QuicDispatcher::ProcessPacket(const IPEndPoint& server_address, void QuicDispatcher::CleanUpSession(SessionMap::iterator it) { QuicSession* session = it->second; write_blocked_list_.RemoveBlockedObject(session->connection()); - time_wait_list_manager_->AddGuidToTimeWait(it->first); + time_wait_list_manager_->AddGuidToTimeWait(it->first, + session->connection()->version()); session_map_.erase(it); } @@ -188,7 +190,8 @@ QuicSession* QuicDispatcher::CreateQuicSession( QuicConnectionHelperInterface* helper = new QuicEpollConnectionHelper(this, epoll_server); QuicServerSession* session = new QuicServerSession( - config_, new QuicConnection(guid, client_address, helper, true), this); + config_, new QuicConnection(guid, client_address, helper, true, + QuicVersionMax()), this); session->InitializeSession(crypto_config_); return session; } diff --git a/net/tools/quic/quic_dispatcher.h b/net/tools/quic/quic_dispatcher.h index 521475b38..bbf8d9b 100644 --- a/net/tools/quic/quic_dispatcher.h +++ b/net/tools/quic/quic_dispatcher.h @@ -104,6 +104,10 @@ class QuicDispatcher : public QuicPacketWriter, public QuicSessionOwner { const QuicConfig& config_; const QuicCryptoServerConfig& crypto_config_; + QuicTimeWaitListManager* time_wait_list_manager() { + return time_wait_list_manager_.get(); + } + private: friend class net::tools::test::QuicDispatcherPeer; diff --git a/net/tools/quic/quic_epoll_connection_helper_test.cc b/net/tools/quic/quic_epoll_connection_helper_test.cc index 519e2e8..f765242 100644 --- a/net/tools/quic/quic_epoll_connection_helper_test.cc +++ b/net/tools/quic/quic_epoll_connection_helper_test.cc @@ -39,7 +39,7 @@ class TestConnectionHelper : public QuicEpollConnectionHelper { virtual int WritePacketToWire(const QuicEncryptedPacket& packet, int* error) OVERRIDE { - QuicFramer framer(kQuicVersion1, QuicTime::Zero(), true); + QuicFramer framer(QuicVersionMax(), QuicTime::Zero(), true); FramerVisitorCapturingFrames visitor; framer.set_visitor(&visitor); EXPECT_TRUE(framer.ProcessPacket(packet)); @@ -59,7 +59,7 @@ class TestConnection : public QuicConnection { TestConnection(QuicGuid guid, IPEndPoint address, TestConnectionHelper* helper) - : QuicConnection(guid, address, helper, false) { + : QuicConnection(guid, address, helper, false, QuicVersionMax()) { } void SendAck() { @@ -77,7 +77,7 @@ class QuicEpollConnectionHelperTest : public ::testing::Test { protected: QuicEpollConnectionHelperTest() : guid_(42), - framer_(kQuicVersion1, QuicTime::Zero(), false), + framer_(QuicVersionMax(), QuicTime::Zero(), false), send_algorithm_(new testing::StrictMock<MockSendAlgorithm>), helper_(new TestConnectionHelper(0, &epoll_server_)), connection_(guid_, IPEndPoint(), helper_), @@ -120,6 +120,8 @@ class QuicEpollConnectionHelperTest : public ::testing::Test { TEST_F(QuicEpollConnectionHelperTest, DISABLED_TestRetransmission) { //FLAGS_fake_packet_loss_percentage = 100; + EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly( + Return(QuicTime::Delta::Zero())); const int64 kDefaultRetransmissionTimeMs = 500; const char buffer[] = "foo"; @@ -178,6 +180,8 @@ TEST_F(QuicEpollConnectionHelperTest, TimeoutAfterSend) { TEST_F(QuicEpollConnectionHelperTest, SendSchedulerDelayThenSend) { // Test that if we send a packet with a delay, it ends up queued. + EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly( + Return(QuicTime::Delta::Zero())); QuicPacket* packet = ConstructDataPacket(1, 0); EXPECT_CALL( *send_algorithm_, TimeUntilSend(_, NOT_RETRANSMISSION, _)).WillOnce( diff --git a/net/tools/quic/quic_server_session.h b/net/tools/quic/quic_server_session.h index ba3ebd6..604b9fc 100644 --- a/net/tools/quic/quic_server_session.h +++ b/net/tools/quic/quic_server_session.h @@ -48,6 +48,8 @@ class QuicServerSession : public QuicSession { virtual void InitializeSession(const QuicCryptoServerConfig& crypto_config); + const QuicCryptoServerStream* crypto_stream() { return crypto_stream_.get(); } + protected: // QuicSession methods: virtual ReliableQuicStream* CreateIncomingReliableStream( diff --git a/net/tools/quic/quic_time_wait_list_manager.cc b/net/tools/quic/quic_time_wait_list_manager.cc index 3bc2d41..7d5862a 100644 --- a/net/tools/quic/quic_time_wait_list_manager.cc +++ b/net/tools/quic/quic_time_wait_list_manager.cc @@ -18,6 +18,8 @@ #include "net/quic/quic_protocol.h" #include "net/quic/quic_utils.h" +using std::make_pair; + namespace net { namespace tools { @@ -91,7 +93,7 @@ class QuicTimeWaitListManager::QueuedPacket { QuicTimeWaitListManager::QuicTimeWaitListManager( QuicPacketWriter* writer, EpollServer* epoll_server) - : framer_(kQuicVersion1, + : framer_(QUIC_VERSION_6, QuicTime::Zero(), // unused true), epoll_server_(epoll_server), @@ -110,10 +112,12 @@ QuicTimeWaitListManager::~QuicTimeWaitListManager() { STLDeleteElements(&pending_packets_queue_); } -void QuicTimeWaitListManager::AddGuidToTimeWait(QuicGuid guid) { +void QuicTimeWaitListManager::AddGuidToTimeWait(QuicGuid guid, + QuicVersion version) { DCHECK(!IsGuidInTimeWait(guid)); // Initialize the guid with 0 packets received. - guid_map_.insert(std::make_pair(guid, 0)); + GuidData data(0, version); + guid_map_.insert(make_pair(guid, data)); time_ordered_guid_list_.push_back(new GuidAddTime(guid, clock_.ApproximateNow())); } @@ -130,11 +134,20 @@ void QuicTimeWaitListManager::ProcessPacket( DCHECK(IsGuidInTimeWait(guid)); server_address_ = server_address; client_address_ = client_address; - // TODO(satyamshekhar): Also store the version of protocol for and - // update the protocol version of the framer before processing. + + // Set the framer to the appropriate version for this GUID, before processing. + QuicVersion version = GetQuicVersionFromGuid(guid); + framer_.set_version(version); + framer_.ProcessPacket(packet); } +QuicVersion QuicTimeWaitListManager::GetQuicVersionFromGuid(QuicGuid guid) { + GuidMapIterator it = guid_map_.find(guid); + DCHECK(it != guid_map_.end()); + return (it->second).version; +} + bool QuicTimeWaitListManager::OnCanWrite() { is_write_blocked_ = false; while (!is_write_blocked_ && !pending_packets_queue_.empty()) { @@ -154,7 +167,7 @@ void QuicTimeWaitListManager::OnError(QuicFramer* framer) { } bool QuicTimeWaitListManager::OnProtocolVersionMismatch( - QuicTag received_version) { + QuicVersion received_version) { // Drop such packets whose version don't match. return false; } @@ -192,8 +205,8 @@ bool QuicTimeWaitListManager::OnPacketHeader(const QuicPacketHeader& header) { GuidMapIterator it = guid_map_.find(header.public_header.guid); DCHECK(it != guid_map_.end()); // Increment the received packet count. - ++(it->second); - if (ShouldSendPublicReset(it->second)) { + ++((it->second).num_packets); + if (ShouldSendPublicReset((it->second).num_packets)) { // We don't need the packet anymore. Just tell the client what sequence // number we rejected. SendPublicReset(server_address_, diff --git a/net/tools/quic/quic_time_wait_list_manager.h b/net/tools/quic/quic_time_wait_list_manager.h index 2b07334..815b9d9 100644 --- a/net/tools/quic/quic_time_wait_list_manager.h +++ b/net/tools/quic/quic_time_wait_list_manager.h @@ -44,8 +44,9 @@ class QuicTimeWaitListManager : public QuicBlockedWriterInterface, // any packet bearing this guid should not be processed while the guid remains // in this list. Public reset packets are sent to the clients by the time wait // list manager that send packets to guids in this state. DCHECKs that guid is - // not already on the list. - void AddGuidToTimeWait(QuicGuid guid); + // not already on the list. Pass in the version as well so that if a public + // reset packet needs to be sent the framer version can be set first. + void AddGuidToTimeWait(QuicGuid guid, QuicVersion version); // Returns true if the guid is in time wait state, false otherwise. Packets // received for this guid should not lead to creation of new QuicSessions. @@ -71,7 +72,7 @@ class QuicTimeWaitListManager : public QuicBlockedWriterInterface, // FramerVisitorInterface virtual void OnError(QuicFramer* framer) OVERRIDE; - virtual bool OnProtocolVersionMismatch(QuicTag received_version) OVERRIDE; + virtual bool OnProtocolVersionMismatch(QuicVersion received_version) OVERRIDE; virtual bool OnPacketHeader(const QuicPacketHeader& header) OVERRIDE; virtual void OnPacket() OVERRIDE {} virtual void OnPublicResetPacket( @@ -94,6 +95,8 @@ class QuicTimeWaitListManager : public QuicBlockedWriterInterface, virtual bool OnGoAwayFrame(const QuicGoAwayFrame& frame) OVERRIDE; virtual void OnFecData(const QuicFecData& fec) OVERRIDE {} + QuicVersion version() const { return framer_.version(); } + protected: // Exposed for tests. bool is_write_blocked() const { return is_write_blocked_; } @@ -105,6 +108,11 @@ class QuicTimeWaitListManager : public QuicBlockedWriterInterface, // Exposed for tests. const QuicTime::Delta time_wait_period() const { return kTimeWaitPeriod_; } + // Given a GUID that exists in the time wait list, returns the QuicVersion + // associated with it. Used internally to set the framer version before + // writing the public reset packet. + QuicVersion GetQuicVersionFromGuid(QuicGuid guid); + private: // Stores the guid and the time it was added to time wait state. struct GuidAddTime; @@ -132,8 +140,14 @@ class QuicTimeWaitListManager : public QuicBlockedWriterInterface, // A map from a recently closed guid to the number of packets received after // the termination of the connection bound to the guid. - base::hash_map<QuicGuid, int> guid_map_; - typedef base::hash_map<QuicGuid, int>::iterator GuidMapIterator; + struct GuidData { + GuidData(int num_packets_, QuicVersion version_) + : num_packets(num_packets_), version(version_) {} + int num_packets; + QuicVersion version; + }; + base::hash_map<QuicGuid, GuidData> guid_map_; + typedef base::hash_map<QuicGuid, GuidData>::iterator GuidMapIterator; // Maintains a list of GuidAddTime elements which it owns, in the // order they should be deleted. diff --git a/net/tools/quic/test_tools/quic_test_client.cc b/net/tools/quic/test_tools/quic_test_client.cc index 9825425..eb26078 100644 --- a/net/tools/quic/test_tools/quic_test_client.cc +++ b/net/tools/quic/test_tools/quic_test_client.cc @@ -88,15 +88,17 @@ BalsaHeaders* MungeHeaders(const BalsaHeaders* const_headers, return headers; } -QuicTestClient::QuicTestClient(IPEndPoint address, const string& hostname) - : client_(address, hostname) { +QuicTestClient::QuicTestClient(IPEndPoint address, const string& hostname, + const QuicVersion version) + : client_(address, hostname, version) { Initialize(address, hostname); } QuicTestClient::QuicTestClient(IPEndPoint address, const string& hostname, - bool secure) - : client_(address, hostname) { + bool secure, + const QuicVersion version) + : client_(address, hostname, version) { Initialize(address, hostname); secure_ = secure; // TODO(alyssar, agl) uncomment here and below when default certs are allowed. @@ -105,8 +107,9 @@ QuicTestClient::QuicTestClient(IPEndPoint address, QuicTestClient::QuicTestClient(IPEndPoint address, const string& hostname, - const QuicConfig& config) - : client_(address, hostname, config) { + const QuicConfig& config, + const QuicVersion version) + : client_(address, hostname, config, version) { Initialize(address, hostname); } diff --git a/net/tools/quic/test_tools/quic_test_client.h b/net/tools/quic/test_tools/quic_test_client.h index d277100..051c011 100644 --- a/net/tools/quic/test_tools/quic_test_client.h +++ b/net/tools/quic/test_tools/quic_test_client.h @@ -26,13 +26,16 @@ class HTTPMessage; // A toy QUIC client used for testing. class QuicTestClient : public ReliableQuicStream::Visitor { public: - QuicTestClient(IPEndPoint server_address, const string& server_hostname); + QuicTestClient(IPEndPoint server_address, const string& server_hostname, + const QuicVersion version); QuicTestClient(IPEndPoint server_address, const string& server_hostname, - bool secure); + bool secure, + const QuicVersion version); QuicTestClient(IPEndPoint server_address, const string& server_hostname, - const QuicConfig& config); + const QuicConfig& config, + const QuicVersion version); virtual ~QuicTestClient(); @@ -114,6 +117,7 @@ class QuicTestClient : public ReliableQuicStream::Visitor { // If true, the client will always reconnect if necessary before creating a // stream. bool auto_reconnect_; + // proof_verifier_ points to a RecordingProofVerifier that is owned by // client_. ProofVerifier* proof_verifier_; diff --git a/net/tools/quic/test_tools/quic_test_utils.cc b/net/tools/quic/test_tools/quic_test_utils.cc index 05c3a57..95f1fb2 100644 --- a/net/tools/quic/test_tools/quic_test_utils.cc +++ b/net/tools/quic/test_tools/quic_test_utils.cc @@ -20,7 +20,8 @@ MockConnection::MockConnection(QuicGuid guid, EpollServer* eps, bool is_server) : QuicConnection(guid, address, - new QuicEpollConnectionHelper(fd, eps), is_server), + new QuicEpollConnectionHelper(fd, eps), is_server, + QuicVersionMax()), has_mock_helper_(false) { } @@ -28,7 +29,7 @@ MockConnection::MockConnection(QuicGuid guid, IPEndPoint address, bool is_server) : QuicConnection(guid, address, new testing::NiceMock<MockHelper>(), - is_server), + is_server, QuicVersionMax()), has_mock_helper_(true) { } @@ -36,7 +37,7 @@ MockConnection::MockConnection(QuicGuid guid, IPEndPoint address, QuicConnectionHelperInterface* helper, bool is_server) - : QuicConnection(guid, address, helper, is_server), + : QuicConnection(guid, address, helper, is_server, QuicVersionMax()), has_mock_helper_(false) { } diff --git a/net/tools/quic/test_tools/quic_test_utils.h b/net/tools/quic/test_tools/quic_test_utils.h index 68f4de4..31ea1815 100644 --- a/net/tools/quic/test_tools/quic_test_utils.h +++ b/net/tools/quic/test_tools/quic_test_utils.h @@ -63,7 +63,7 @@ class MockConnection : public QuicConnection { return QuicConnection::ProcessUdpPacket(self_address, peer_address, packet); } - virtual bool OnProtocolVersionMismatch(QuicTag version) { return false; } + virtual bool OnProtocolVersionMismatch(QuicVersion version) { return false; } private: const bool has_mock_helper_; |