summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/net.gyp9
-rw-r--r--net/quic/congestion_control/fix_rate_sender.cc14
-rw-r--r--net/quic/congestion_control/fix_rate_sender.h1
-rw-r--r--net/quic/congestion_control/inter_arrival_sender.cc29
-rw-r--r--net/quic/congestion_control/inter_arrival_sender.h1
-rw-r--r--net/quic/congestion_control/quic_congestion_manager.cc35
-rw-r--r--net/quic/congestion_control/send_algorithm_interface.h5
-rw-r--r--net/quic/congestion_control/tcp_cubic_sender.cc38
-rw-r--r--net/quic/congestion_control/tcp_cubic_sender.h10
-rw-r--r--net/quic/congestion_control/tcp_cubic_sender_test.cc31
-rw-r--r--net/quic/crypto/aes_128_gcm_12_encrypter.h2
-rw-r--r--net/quic/crypto/aes_128_gcm_12_encrypter_nss.cc8
-rw-r--r--net/quic/crypto/aes_128_gcm_12_encrypter_openssl.cc8
-rw-r--r--net/quic/crypto/common_cert_set_0.c6
-rw-r--r--net/quic/crypto/common_cert_set_1_50.inc267
-rw-r--r--net/quic/crypto/common_cert_set_51_100.inc100
-rw-r--r--net/quic/crypto/common_cert_set_test.cc4
-rw-r--r--net/quic/crypto/crypto_handshake.cc7
-rw-r--r--net/quic/crypto/crypto_server_config.cc87
-rw-r--r--net/quic/crypto/crypto_server_config.h3
-rw-r--r--net/quic/crypto/proof_source.h1
-rw-r--r--net/quic/crypto/proof_source_chromium.cc1
-rw-r--r--net/quic/crypto/proof_source_chromium.h1
-rw-r--r--net/quic/crypto/proof_test.cc7
-rw-r--r--net/quic/quic_connection.cc68
-rw-r--r--net/quic/quic_connection.h25
-rw-r--r--net/quic/quic_connection_helper_test.cc12
-rw-r--r--net/quic/quic_connection_logger.cc3
-rw-r--r--net/quic/quic_connection_logger.h2
-rw-r--r--net/quic/quic_connection_test.cc74
-rw-r--r--net/quic/quic_crypto_server_stream_test.cc3
-rw-r--r--net/quic/quic_framer.cc34
-rw-r--r--net/quic/quic_framer.h26
-rw-r--r--net/quic/quic_framer_test.cc171
-rw-r--r--net/quic/quic_http_stream_test.cc6
-rw-r--r--net/quic/quic_network_transaction_unittest.cc4
-rw-r--r--net/quic/quic_packet_creator.cc2
-rw-r--r--net/quic/quic_packet_creator.h2
-rw-r--r--net/quic/quic_packet_creator_test.cc8
-rw-r--r--net/quic/quic_packet_entropy_manager.cc165
-rw-r--r--net/quic/quic_packet_entropy_manager.h105
-rw-r--r--net/quic/quic_packet_entropy_manager_test.cc144
-rw-r--r--net/quic/quic_packet_generator.cc44
-rw-r--r--net/quic/quic_packet_generator.h13
-rw-r--r--net/quic/quic_packet_generator_test.cc68
-rw-r--r--net/quic/quic_protocol.cc72
-rw-r--r--net/quic/quic_protocol.h79
-rw-r--r--net/quic/quic_protocol_test.cc98
-rw-r--r--net/quic/quic_received_entropy_manager.cc98
-rw-r--r--net/quic/quic_received_entropy_manager.h70
-rw-r--r--net/quic/quic_received_entropy_manager_test.cc99
-rw-r--r--net/quic/quic_sent_entropy_manager.cc87
-rw-r--r--net/quic/quic_sent_entropy_manager.h62
-rw-r--r--net/quic/quic_sent_entropy_manager_test.cc73
-rw-r--r--net/quic/quic_stream_factory.cc3
-rw-r--r--net/quic/quic_stream_factory_test.cc4
-rw-r--r--net/quic/quic_stream_sequencer.cc9
-rw-r--r--net/quic/quic_stream_sequencer.h6
-rw-r--r--net/quic/quic_stream_sequencer_test.cc141
-rw-r--r--net/quic/reliable_quic_stream.cc41
-rw-r--r--net/quic/reliable_quic_stream.h2
-rw-r--r--net/quic/reliable_quic_stream_test.cc90
-rw-r--r--net/quic/test_tools/quic_connection_peer.cc7
-rw-r--r--net/quic/test_tools/quic_framer_peer.cc2
-rw-r--r--net/quic/test_tools/quic_framer_peer.h2
-rw-r--r--net/quic/test_tools/quic_test_utils.cc10
-rw-r--r--net/quic/test_tools/quic_test_utils.h9
-rw-r--r--net/quic/test_tools/simple_quic_framer.cc4
-rw-r--r--net/tools/quic/end_to_end_test.cc55
-rw-r--r--net/tools/quic/quic_client.cc14
-rw-r--r--net/tools/quic/quic_client.h16
-rw-r--r--net/tools/quic/quic_client_bin.cc4
-rw-r--r--net/tools/quic/quic_dispatcher.cc9
-rw-r--r--net/tools/quic/quic_dispatcher.h4
-rw-r--r--net/tools/quic/quic_epoll_connection_helper_test.cc10
-rw-r--r--net/tools/quic/quic_server_session.h2
-rw-r--r--net/tools/quic/quic_time_wait_list_manager.cc29
-rw-r--r--net/tools/quic/quic_time_wait_list_manager.h24
-rw-r--r--net/tools/quic/test_tools/quic_test_client.cc15
-rw-r--r--net/tools/quic/test_tools/quic_test_client.h10
-rw-r--r--net/tools/quic/test_tools/quic_test_utils.cc7
-rw-r--r--net/tools/quic/test_tools/quic_test_utils.h2
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_;