summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorrtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-26 14:51:56 +0000
committerrtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-26 14:51:56 +0000
commit48878097c79f472be47c9c518bd07041762af6c1 (patch)
treeb3b8f0adb99d2bf9356917c4ca9fed4daa2f3a9a /net
parent581ec2af841f60e4a36fdee26013c2ada2933c70 (diff)
downloadchromium_src-48878097c79f472be47c9c518bd07041762af6c1.zip
chromium_src-48878097c79f472be47c9c518bd07041762af6c1.tar.gz
chromium_src-48878097c79f472be47c9c518bd07041762af6c1.tar.bz2
Land Recent QUIC changes.
Implemented RTO calculation for TCP sender. Merge internal change: 49182038 Introduce a different proof-demand type for ECDSA certs. In cl/48309237, wtc enabled ECDSA certificates for QUIC. However, Windows XP can't cope with them so we mustn't return ECDSA certs to those clients. The value of ECDSA over RSA in QUIC is much less than in TLS because the server doesn't need to sign every connection. However, they are likely to be ~192 bytes smaller, which might be useful. This change disables ECDSA certificates for the <X509> tag and introduces a new <X59E> tag by which the client can advertise that it supports ECDSA certificates. Merge internal change: 49170028 Added whitespace. Merge internal change: 49130502 QUIC: check that encryption sequence numbers always increase. Since sequence number reuse is causes the end of the world, check that it never happens. This makes me feel more warm and fuzzy. Merge internal change: 49113162 QUIC: Send larger client hellos when hoping for certificates. With cl/49050453, larger client hellos can get larger rejection messages. This change causes the client to send larger client hellos when it's likely that we'll be getting certificates. In the event that the certificates fit in the larger space, but not the smaller one, this saves a round trip. Merge internal change: 49109243 QUIC: allow larger ClientHellos to get larger certificate chains. At the moment we hope that the certificate chain compression gets the certs down to under 400 bytes and then we feel ok about sending them in a reply to an unverified source address. But since we're switching to 2K certs that's basically hopeless: the leaf certificate will have two, uncompressable blobs in it: the public key and the signature and, for 2K, they are 256 bytes each. This change allows a client to send a client hello with more padding and get a larger reply to an unverified source address. What we don't want is to become a DDoS amplifier so we make the attacker work in order to get more from us. Merge internal change: 49050453 QUIC: Update the common certificate set with GIAG2. This doesn't break the protocol, but it does mean that clients with the old certificate set won't be able to elide any certificates. But since Chrome isn't working with QUIC HTTPS yet anyway, that's not a problem. Merge internal change: 49050091 Modify QuicStreamSequencer::OnStreamFrame to not call ProcessRawData with zero length data. Fixes http://crbug.com/257041 Merge internal change: 48912969 BUG=257041 Change ReliableQuicStream::OnStreamFrame to simply delegate fin handling to the QuicStreamSequencer. Merge internal change: 48900554 Spliting QuicPacketEntropyManager into QuicReceivedEntropyManager and QuicSentEntropyManager, in preparation for a larger refactor to create a ReceivedPacketManager. Merge internal change: 48860732 Add a test to recreate the invalid ack created when an Ack is sent immediately in response to a received ack, but the incoming ack's corresponding headers, and hence packet entropy, has not been processed. Merge internal change: 48848920 Aggregate ACK and Feedback frames properly. Existing code tried to pack acks with feedback info, and regulate transmission of control packets. There was a bug where it sometimes didn't pack together an ack with a feedback frame (specifically when we were blocked from sending non-retransmittable data). There was a second bug wherein a control frame might be prematurely serialized, when it could *not* be sent immediately. Specifically when the control frame was the first frame in a packet, and non-retransmittable data could be sent, the control frame could be errantly added. We now consistently aggregate ack frames with feedback frames in a single packet whenever the coalescing won't delay the sending of the just-in-time calculated frames. We now also avoid adding a control frame into a packet unless we are sure it can be sent immediately (so that we don't block or delay future ack and feedback transmission). The CL includes updates to tests so that they fail with the old code, but pass with the new code, as well as a bunch of additions to comments. This CL is based on the Chromium CL 17341005 (which is not landing until its merge time comes around), and resolves chromium bug 256116. FIXED=9502307 Merge internal change: 48841932 BUG=256116 Add logging to the QUIC write path. merge chromium CL: 17518002 Merge internal change: 48811324 Most of the changes were already in chromium except for comment change. Fix broken test (opt mode) in cl/48802264. Merge internal change: 48806857 Demote LOG(ERROR) to DLOG(INFO) when a client sends a packet with unsupported version. This should not be considered an ERROR server-side, as a client is free to send us whatever they like. We deal with it by sending a version negotiation packet and all is well. Updated tests, and added some comments. Merge internal change: 48802264 Added time_wait_list_manager helper method to QuicDispatcher. Merge internal change: 48787571 QUIC: encode the cluster in the first four bytes of the orbit value. In order to try and measure, in Chrome, when we might have saved a round-trip with a cluster-wide strike-register we need to know when we hit another server in the same cluster. We could do that by IP address somewhat, but it's a little complex and there's the /8 vs /5 between core and .... This change causes the first four bytes of the orbit to include a hash of the cluster (or ... rack name) so that we can easily track this in Chrome. Merge internal change: 48784059 Fix a bug in ReliableQuicStream::OnDecompressorAvailable where a decompression failure would result in an infinite loop. Merge internal change: 48696905 patch from issue 20054002 Enabling ChannelId for QUIC, and passing the ChannelId header to google backends if we're using it. Not flag protected as we're not doing secure-quic in prod yet. Merge internal change: 48645878 * Removed QuicTag kQuicVersion1 * Replaced this with enum QuicVersion, which currently has QUIC_VERSION_6 and QUIC_VERSION_7 * End to end tests are run with both versions * Framer tests are run with both versions * QuicConnection now takes a QuicVersion parameter * TimeWaitListManager now stores QuicVersion in the GUID map and sets the framer version appropriately using this before sending reset Merge internal change: 48634592 R=rch@chromium.org Review URL: https://chromiumcodereview.appspot.com/20227003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@213914 0039d316-1c4b-4281-b951-d872f2087c98
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_;