summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrjshade <rjshade@chromium.org>2016-03-11 12:42:17 -0800
committerCommit bot <commit-bot@chromium.org>2016-03-11 20:43:47 +0000
commitd069aaee0b3affb6004d8cf3a276c32e248a2a3d (patch)
treece0e89ab98a7ca09ac5df43122928a1f5aebf44b
parentab26b6681dde41b4141fef09decf9c4e930aee85 (diff)
downloadchromium_src-d069aaee0b3affb6004d8cf3a276c32e248a2a3d.zip
chromium_src-d069aaee0b3affb6004d8cf3a276c32e248a2a3d.tar.gz
chromium_src-d069aaee0b3affb6004d8cf3a276c32e248a2a3d.tar.bz2
Landing Recent QUIC changes until 2016-03-07 19:39 UTC
Up to, and including internal change 116570346 Add a new QUIC Ack Decimation mode that is reordering tolerant. Protected by FLAG_quic_ack_decimation2. Merge internal change: 115853846 https://codereview.chromium.org/1777293002/ Deprecating FLAG_quic_batch_writes Merge internal change: 115880164 https://codereview.chromium.org/1780913002/ Deprecate FLAG_quic_validate_stk_without_scid Merge internal change: 115885351 https://codereview.chromium.org/1780923002/ Deprecate FLAG_quic_use_new_tcp_sender Merge internal change: 115890504 https://codereview.chromium.org/1785663003/ Deprecate FLAG_quic_use_new_idle_timeout Merge internal change: 115904466 https://codereview.chromium.org/1785693003/ Deprecate FLAG_quic_block_unencrypted_writes Merge internal change: 115909446 https://codereview.chromium.org/1784643006/ Clang formatting net/quic. Merge internal change: 115992556 https://codereview.chromium.org/1780783003/ Optionally defer responding to a QUIC ACK until all ACK processing has completed for an EpollServer iteration. Guarded by FLAG_quic_connection_defer_ack_response Merge internal change: 114770052 https://codereview.chromium.org/1782053003/ Deprecate FLAG_require_strike_register_or_server_nonce Merge internal change: 115891009 https://codereview.chromium.org/1785613005/ Add a boolean use_stateless_rejects_if_peer_supported argument to the QuicCryptoServerStream constructor instead of consulting FLAG_enable_quic_stateless_reject_support directly. No behavior change expected. Merge internal change: 115844136 https://codereview.chromium.org/1783713003/ Remove FEC from send path. Merge internal change: 115997404 https://codereview.chromium.org/1784903003/ Remove FEC code from receive path. Drop received FEC packet. Merge internal change: 116134765 https://codereview.chromium.org/1782143003/ Only cancel QUIC alarms if they have been set. Protected behind FLAG_quic_only_cancel_set_alarms Merge internal change: 116142833 https://codereview.chromium.org/1781073002/ Call QuicAlarm::IsSet instead of looking at deadline_ directly, rename some variables for readability. Merge internal change: 116146641 https://codereview.chromium.org/1778243005/ Add whether QUIC's unencrypted stream data was received or about to be sent in the error log. Logging only change. Merge internal change: 116152506 https://codereview.chromium.org/1782193002/ Temporarily store the raw QUIC packet in QuicConnection. Merge internal change: 116180343 https://codereview.chromium.org/1779313002/ Deprecate FLAG_quic_no_unencrypted_fec. Merge internal change: 116244697 https://codereview.chromium.org/1780573006/ Make ShouldCreateOutgoingDynamicStream a virtual method. Merge internal change: 116249386 https://codereview.chromium.org/1784933003/ Correctly handle EINTR during sendmsg in QuicSocketUtils::WritePacket. Merge internal change: 116261116 https://codereview.chromium.org/1780323002/ Simplify QUIC's encryption path now that FEC is gone. Protected by FLAG_quic_inplace_encryption. Merge internal change: 116266391 https://codereview.chromium.org/1785513003/ Remove the force param from QuicPacketGenerator::SetMaxPacketLength because path MTU packets should not be sent if the MTU cannot be changed. Not flag protected. Merge internal change: 116273065 https://codereview.chromium.org/1781043004/ Remove lastest_revived_packet from QuicAckFrame since FEC is gone. No functional change expected. Wire format is not changed yet. Merge internal change: 116411121 https://codereview.chromium.org/1787443002/ Remove is_fec_packet from TransmissionInfo and SerializedPacket. No functional change. Merge internal change: 116555910 https://codereview.chromium.org/1785853002/ Remove FEC related connection options and update FEC related comment in code base. Merge internal change: 116566297 https://codereview.chromium.org/1785863002/ Switch "const StringPiece&" to just "StringPiece" in QUIC code. No functional change. Not flag protected. Merge internal change: 116570346 https://codereview.chromium.org/1787453002/ Add a QuicCompressedCertsCache instance to QuicDispatcher, plumbing to QuicServerSessionBase but not used. No behavior change. Merge internal change: 116277134 https://codereview.chromium.org/1783783003/ Add more detailed logging to QUIC's ack validation. No functional change. Merge internal change: 116277228 https://codereview.chromium.org/1784963002/ Remove max_packet_length from QuicPacketGenerator, because it is no longer necessary with FEC gone. Not flag protected. Merge internal change: 116387934 https://codereview.chromium.org/1777423002/ Add QuicCompressedCertsCache* to QuicCrytoServerStream plumbed from QuicServerSessionBase. No behavior change. Merge internal change: 116388439 https://codereview.chromium.org/1782743005/ Remove unused return value from QuicAlarm::Delegate::OnAlarm. No behavior change, not protected. The only place in the codebase that returns something other than QuicTime::Zero() is the DelayAlarm in PacketDroppingTestWriter. I've the implementation of OnAlarm in there to set the alarm directly to the new time, rather than relying on the return value. Merge internal change: 116389752 https://codereview.chromium.org/1779883005/ Add a QUIC ScopedPacketBundler to send an ack when the ack alarm goes off. No functional change. Not flag protected. Merge internal change: 116391846 https://codereview.chromium.org/1786493003/ OnStreamEnd is now called instead of the sentinel call of OnStreamFrameData(stream_id, nullptr, 0, true). Protected by the flag FLAGS_spdy_on_stream_end. Merge internal change: 116272960 https://codereview.chromium.org/1777163003/ R=rch@chromium.org BUG= Review URL: https://codereview.chromium.org/1781123002 Cr-Commit-Position: refs/heads/master@{#380718}
-rw-r--r--net/net.gypi6
-rw-r--r--net/quic/congestion_control/pacing_sender_test.cc5
-rw-r--r--net/quic/congestion_control/send_algorithm_interface.cc36
-rw-r--r--net/quic/congestion_control/tcp_cubic_bytes_sender.cc390
-rw-r--r--net/quic/congestion_control/tcp_cubic_bytes_sender.h151
-rw-r--r--net/quic/congestion_control/tcp_cubic_bytes_sender_test.cc743
-rw-r--r--net/quic/congestion_control/tcp_cubic_sender.cc401
-rw-r--r--net/quic/congestion_control/tcp_cubic_sender.h152
-rw-r--r--net/quic/congestion_control/tcp_cubic_sender_test.cc887
-rw-r--r--net/quic/crypto/aead_base_decrypter.h6
-rw-r--r--net/quic/crypto/aead_base_decrypter_nss.cc4
-rw-r--r--net/quic/crypto/aead_base_decrypter_openssl.cc4
-rw-r--r--net/quic/crypto/aes_128_gcm_12_decrypter.h2
-rw-r--r--net/quic/crypto/aes_128_gcm_12_decrypter_nss.cc2
-rw-r--r--net/quic/crypto/chacha20_poly1305_decrypter.h2
-rw-r--r--net/quic/crypto/chacha20_poly1305_decrypter_nss.cc9
-rw-r--r--net/quic/crypto/chacha20_poly1305_rfc7539_decrypter.h2
-rw-r--r--net/quic/crypto/chacha20_poly1305_rfc7539_decrypter_nss.cc2
-rw-r--r--net/quic/crypto/crypto_protocol.h11
-rw-r--r--net/quic/crypto/crypto_server_test.cc75
-rw-r--r--net/quic/crypto/curve25519_key_exchange.cc8
-rw-r--r--net/quic/crypto/curve25519_key_exchange.h4
-rw-r--r--net/quic/crypto/key_exchange.h2
-rw-r--r--net/quic/crypto/null_decrypter.cc4
-rw-r--r--net/quic/crypto/null_decrypter.h7
-rw-r--r--net/quic/crypto/p256_key_exchange.h2
-rw-r--r--net/quic/crypto/p256_key_exchange_nss.cc2
-rw-r--r--net/quic/crypto/p256_key_exchange_openssl.cc2
-rw-r--r--net/quic/crypto/quic_crypto_server_config.cc59
-rw-r--r--net/quic/crypto/quic_crypto_server_config_test.cc3
-rw-r--r--net/quic/crypto/quic_decrypter.h4
-rw-r--r--net/quic/quic_alarm.cc30
-rw-r--r--net/quic/quic_alarm.h11
-rw-r--r--net/quic/quic_alarm_test.cc18
-rw-r--r--net/quic/quic_chromium_client_session_test.cc2
-rw-r--r--net/quic/quic_chromium_client_stream_test.cc12
-rw-r--r--net/quic/quic_chromium_connection_helper_test.cc5
-rw-r--r--net/quic/quic_client_promised_info.cc3
-rw-r--r--net/quic/quic_client_promised_info.h2
-rw-r--r--net/quic/quic_config_test.cc11
-rw-r--r--net/quic/quic_connection.cc339
-rw-r--r--net/quic/quic_connection.h71
-rw-r--r--net/quic/quic_connection_logger.cc11
-rw-r--r--net/quic/quic_connection_logger.h2
-rw-r--r--net/quic/quic_connection_stats.cc1
-rw-r--r--net/quic/quic_connection_stats.h5
-rw-r--r--net/quic/quic_connection_test.cc1407
-rw-r--r--net/quic/quic_crypto_client_stream_test.cc11
-rw-r--r--net/quic/quic_crypto_server_stream.cc5
-rw-r--r--net/quic/quic_crypto_server_stream.h8
-rw-r--r--net/quic/quic_crypto_server_stream_test.cc19
-rw-r--r--net/quic/quic_flags.cc42
-rw-r--r--net/quic/quic_flags.h11
-rw-r--r--net/quic/quic_framer.cc152
-rw-r--r--net/quic/quic_framer.h46
-rw-r--r--net/quic/quic_framer_test.cc466
-rw-r--r--net/quic/quic_headers_stream.cc3
-rw-r--r--net/quic/quic_headers_stream_test.cc83
-rw-r--r--net/quic/quic_multipath_received_packet_manager.cc12
-rw-r--r--net/quic/quic_multipath_received_packet_manager.h3
-rw-r--r--net/quic/quic_multipath_received_packet_manager_test.cc8
-rw-r--r--net/quic/quic_packet_creator.cc363
-rw-r--r--net/quic/quic_packet_creator.h143
-rw-r--r--net/quic/quic_packet_creator_test.cc636
-rw-r--r--net/quic/quic_packet_generator.cc103
-rw-r--r--net/quic/quic_packet_generator.h58
-rw-r--r--net/quic/quic_packet_generator_test.cc987
-rw-r--r--net/quic/quic_protocol.cc43
-rw-r--r--net/quic/quic_protocol.h47
-rw-r--r--net/quic/quic_received_packet_manager.cc19
-rw-r--r--net/quic/quic_received_packet_manager.h5
-rw-r--r--net/quic/quic_received_packet_manager_test.cc55
-rw-r--r--net/quic/quic_sent_packet_manager.cc24
-rw-r--r--net/quic/quic_sent_packet_manager.h11
-rw-r--r--net/quic/quic_sent_packet_manager_test.cc136
-rw-r--r--net/quic/quic_session.cc16
-rw-r--r--net/quic/quic_session.h6
-rw-r--r--net/quic/quic_session_test.cc37
-rw-r--r--net/quic/quic_spdy_stream_test.cc16
-rw-r--r--net/quic/quic_unacked_packet_map.cc3
-rw-r--r--net/quic/quic_unacked_packet_map.h4
-rw-r--r--net/quic/quic_write_blocked_list.h1
-rw-r--r--net/quic/quic_write_blocked_list_test.cc1
-rw-r--r--net/quic/reliable_quic_stream.cc17
-rw-r--r--net/quic/reliable_quic_stream.h11
-rw-r--r--net/quic/reliable_quic_stream_test.cc167
-rw-r--r--net/quic/test_tools/crypto_test_utils.cc5
-rw-r--r--net/quic/test_tools/mock_quic_dispatcher.cc5
-rw-r--r--net/quic/test_tools/quic_connection_peer.cc18
-rw-r--r--net/quic/test_tools/quic_connection_peer.h10
-rw-r--r--net/quic/test_tools/quic_packet_creator_peer.cc50
-rw-r--r--net/quic/test_tools/quic_packet_creator_peer.h13
-rw-r--r--net/quic/test_tools/quic_test_utils.cc48
-rw-r--r--net/quic/test_tools/quic_test_utils.h38
-rw-r--r--net/quic/test_tools/reliable_quic_stream_peer.cc6
-rw-r--r--net/quic/test_tools/reliable_quic_stream_peer.h2
-rw-r--r--net/quic/test_tools/simple_quic_framer.cc13
-rw-r--r--net/quic/test_tools/simple_quic_framer.h1
-rw-r--r--net/spdy/buffered_spdy_framer.cc2
-rw-r--r--net/spdy/spdy_framer.cc18
-rw-r--r--net/spdy/spdy_framer.h5
-rw-r--r--net/spdy/spdy_framer_test.cc341
-rw-r--r--net/tools/quic/end_to_end_test.cc155
-rw-r--r--net/tools/quic/quic_client_session_test.cc5
-rw-r--r--net/tools/quic/quic_dispatcher.cc24
-rw-r--r--net/tools/quic/quic_dispatcher.h11
-rw-r--r--net/tools/quic/quic_dispatcher_test.cc86
-rw-r--r--net/tools/quic/quic_epoll_connection_helper_test.cc5
-rw-r--r--net/tools/quic/quic_server_session_base.cc7
-rw-r--r--net/tools/quic/quic_server_session_base.h17
-rw-r--r--net/tools/quic/quic_server_session_base_test.cc37
-rw-r--r--net/tools/quic/quic_simple_server_session.cc16
-rw-r--r--net/tools/quic/quic_simple_server_session.h6
-rw-r--r--net/tools/quic/quic_simple_server_session_test.cc36
-rw-r--r--net/tools/quic/quic_simple_server_stream_test.cc50
-rw-r--r--net/tools/quic/quic_socket_utils.cc5
-rw-r--r--net/tools/quic/quic_time_wait_list_manager.cc4
-rw-r--r--net/tools/quic/test_tools/packet_dropping_test_writer.cc14
-rw-r--r--net/tools/quic/test_tools/packet_dropping_test_writer.h3
-rw-r--r--net/tools/quic/test_tools/quic_dispatcher_peer.cc6
-rw-r--r--net/tools/quic/test_tools/quic_dispatcher_peer.h2
-rw-r--r--net/tools/quic/test_tools/quic_test_client.cc12
-rw-r--r--net/tools/quic/test_tools/quic_test_client.h6
-rw-r--r--net/tools/quic/test_tools/quic_test_server.cc31
-rw-r--r--net/tools/quic/test_tools/quic_test_server.h6
125 files changed, 1651 insertions, 8163 deletions
diff --git a/net/net.gypi b/net/net.gypi
index fec3bcc..762355d 100644
--- a/net/net.gypi
+++ b/net/net.gypi
@@ -236,10 +236,6 @@
'quic/congestion_control/rtt_stats.h',
'quic/congestion_control/send_algorithm_interface.cc',
'quic/congestion_control/send_algorithm_interface.h',
- 'quic/congestion_control/tcp_cubic_bytes_sender.cc',
- 'quic/congestion_control/tcp_cubic_bytes_sender.h',
- 'quic/congestion_control/tcp_cubic_sender.cc',
- 'quic/congestion_control/tcp_cubic_sender.h',
'quic/congestion_control/tcp_cubic_sender_base.cc',
'quic/congestion_control/tcp_cubic_sender_base.h',
'quic/congestion_control/tcp_cubic_sender_bytes.cc',
@@ -1549,8 +1545,6 @@
'quic/congestion_control/rtt_stats_test.cc',
'quic/congestion_control/send_algorithm_simulator.cc',
'quic/congestion_control/send_algorithm_simulator.h',
- 'quic/congestion_control/tcp_cubic_bytes_sender_test.cc',
- 'quic/congestion_control/tcp_cubic_sender_test.cc',
'quic/congestion_control/tcp_cubic_sender_bytes_test.cc',
'quic/congestion_control/tcp_cubic_sender_packets_test.cc',
'quic/crypto/aes_128_gcm_12_decrypter_test.cc',
diff --git a/net/quic/congestion_control/pacing_sender_test.cc b/net/quic/congestion_control/pacing_sender_test.cc
index 4cd5ac6..d5e2fc0 100644
--- a/net/quic/congestion_control/pacing_sender_test.cc
+++ b/net/quic/congestion_control/pacing_sender_test.cc
@@ -91,8 +91,9 @@ class PacingSenderTest : public ::testing::Test {
.WillOnce(Return(zero_time_));
// Verify that the packet is delayed.
EXPECT_EQ(delay.ToMicroseconds(),
- pacing_sender_->TimeUntilSend(clock_.Now(), kBytesInFlight,
- HAS_RETRANSMITTABLE_DATA)
+ pacing_sender_
+ ->TimeUntilSend(clock_.Now(), kBytesInFlight,
+ HAS_RETRANSMITTABLE_DATA)
.ToMicroseconds());
}
}
diff --git a/net/quic/congestion_control/send_algorithm_interface.cc b/net/quic/congestion_control/send_algorithm_interface.cc
index 20821a6..83de14f 100644
--- a/net/quic/congestion_control/send_algorithm_interface.cc
+++ b/net/quic/congestion_control/send_algorithm_interface.cc
@@ -4,8 +4,6 @@
#include "net/quic/congestion_control/send_algorithm_interface.h"
-#include "net/quic/congestion_control/tcp_cubic_bytes_sender.h"
-#include "net/quic/congestion_control/tcp_cubic_sender.h"
#include "net/quic/congestion_control/tcp_cubic_sender_bytes.h"
#include "net/quic/congestion_control/tcp_cubic_sender_packets.h"
#include "net/quic/quic_flags.h"
@@ -27,39 +25,19 @@ SendAlgorithmInterface* SendAlgorithmInterface::Create(
kDefaultTCPMSS;
switch (congestion_control_type) {
case kCubic:
- if (FLAGS_quic_use_new_tcp_sender) {
- return new TcpCubicSenderPackets(
- clock, rtt_stats, false /* don't use Reno */,
- initial_congestion_window, max_congestion_window, stats);
- }
- return new TcpCubicSender(clock, rtt_stats, false /* don't use Reno */,
- initial_congestion_window,
- max_congestion_window, stats);
+ return new TcpCubicSenderPackets(
+ clock, rtt_stats, false /* don't use Reno */,
+ initial_congestion_window, max_congestion_window, stats);
case kCubicBytes:
- if (FLAGS_quic_use_new_tcp_sender) {
- return new TcpCubicSenderBytes(
- clock, rtt_stats, false /* don't use Reno */,
- initial_congestion_window, max_congestion_window, stats);
- }
- return new TcpCubicBytesSender(
+ return new TcpCubicSenderBytes(
clock, rtt_stats, false /* don't use Reno */,
initial_congestion_window, max_congestion_window, stats);
case kReno:
- if (FLAGS_quic_use_new_tcp_sender) {
- return new TcpCubicSenderPackets(clock, rtt_stats, true /* use Reno */,
- initial_congestion_window,
- max_congestion_window, stats);
- }
- return new TcpCubicSender(clock, rtt_stats, true /* use Reno */,
- initial_congestion_window,
- max_congestion_window, stats);
- case kRenoBytes:
- if (FLAGS_quic_use_new_tcp_sender) {
- return new TcpCubicSenderBytes(clock, rtt_stats, true /* use Reno */,
+ return new TcpCubicSenderPackets(clock, rtt_stats, true /* use Reno */,
initial_congestion_window,
max_congestion_window, stats);
- }
- return new TcpCubicBytesSender(clock, rtt_stats, true /* use Reno */,
+ case kRenoBytes:
+ return new TcpCubicSenderBytes(clock, rtt_stats, true /* use Reno */,
initial_congestion_window,
max_congestion_window, stats);
case kBBR:
diff --git a/net/quic/congestion_control/tcp_cubic_bytes_sender.cc b/net/quic/congestion_control/tcp_cubic_bytes_sender.cc
deleted file mode 100644
index 2ceb719..0000000
--- a/net/quic/congestion_control/tcp_cubic_bytes_sender.cc
+++ /dev/null
@@ -1,390 +0,0 @@
-// Copyright (c) 2015 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/congestion_control/tcp_cubic_bytes_sender.h"
-
-#include <algorithm>
-
-#include "net/quic/congestion_control/prr_sender.h"
-#include "net/quic/congestion_control/rtt_stats.h"
-#include "net/quic/crypto/crypto_protocol.h"
-#include "net/quic/proto/cached_network_parameters.pb.h"
-#include "net/quic/quic_bug_tracker.h"
-#include "net/quic/quic_flags.h"
-
-using std::max;
-using std::min;
-
-namespace net {
-
-namespace {
-// Constants based on TCP defaults.
-// The minimum cwnd based on RFC 3782 (TCP NewReno) for cwnd reductions on a
-// fast retransmission.
-const QuicByteCount kDefaultMinimumCongestionWindow = 2 * kDefaultTCPMSS;
-const QuicByteCount kMaxBurstBytes = 3 * kDefaultTCPMSS;
-const float kRenoBeta = 0.7f; // Reno backoff factor.
-const uint32_t kDefaultNumConnections = 2; // N-connection emulation.
-} // namespace
-
-TcpCubicBytesSender::TcpCubicBytesSender(
- const QuicClock* clock,
- const RttStats* rtt_stats,
- bool reno,
- QuicPacketCount initial_tcp_congestion_window,
- QuicPacketCount max_congestion_window,
- QuicConnectionStats* stats)
- : cubic_(clock),
- rtt_stats_(rtt_stats),
- stats_(stats),
- reno_(reno),
- num_connections_(kDefaultNumConnections),
- num_acked_packets_(0),
- largest_sent_packet_number_(0),
- largest_acked_packet_number_(0),
- largest_sent_at_last_cutback_(0),
- congestion_window_(initial_tcp_congestion_window * kDefaultTCPMSS),
- min_congestion_window_(kDefaultMinimumCongestionWindow),
- min4_mode_(false),
- max_congestion_window_(max_congestion_window * kDefaultTCPMSS),
- slowstart_threshold_(max_congestion_window * kDefaultTCPMSS),
- last_cutback_exited_slowstart_(false),
- initial_tcp_congestion_window_(initial_tcp_congestion_window *
- kDefaultTCPMSS),
- initial_max_tcp_congestion_window_(max_congestion_window *
- kDefaultTCPMSS),
- slow_start_large_reduction_(false) {}
-
-TcpCubicBytesSender::~TcpCubicBytesSender() {}
-
-void TcpCubicBytesSender::SetFromConfig(const QuicConfig& config,
- Perspective perspective) {
- if (perspective == Perspective::IS_SERVER) {
- if (config.HasReceivedConnectionOptions() &&
- ContainsQuicTag(config.ReceivedConnectionOptions(), kIW10)) {
- // Initial window experiment.
- congestion_window_ = 10 * kDefaultTCPMSS;
- }
- if (config.HasReceivedConnectionOptions() &&
- ContainsQuicTag(config.ReceivedConnectionOptions(), kMIN1)) {
- // Min CWND experiment.
- min_congestion_window_ = kDefaultTCPMSS;
- }
- if (config.HasReceivedConnectionOptions() &&
- ContainsQuicTag(config.ReceivedConnectionOptions(), kMIN4)) {
- // Min CWND of 4 experiment.
- min4_mode_ = true;
- min_congestion_window_ = kDefaultTCPMSS;
- }
- if (config.HasReceivedConnectionOptions() &&
- ContainsQuicTag(config.ReceivedConnectionOptions(), kSSLR)) {
- // Slow Start Fast Exit experiment.
- slow_start_large_reduction_ = true;
- }
- }
-}
-
-void TcpCubicBytesSender::ResumeConnectionState(
- const CachedNetworkParameters& cached_network_params,
- bool max_bandwidth_resumption) {
- QuicBandwidth bandwidth = QuicBandwidth::FromBytesPerSecond(
- max_bandwidth_resumption
- ? cached_network_params.max_bandwidth_estimate_bytes_per_second()
- : cached_network_params.bandwidth_estimate_bytes_per_second());
- QuicTime::Delta rtt_ms =
- QuicTime::Delta::FromMilliseconds(cached_network_params.min_rtt_ms());
-
- // Make sure CWND is in appropriate range (in case of bad data).
- QuicByteCount new_congestion_window = bandwidth.ToBytesPerPeriod(rtt_ms);
- congestion_window_ =
- max(min(new_congestion_window, kMaxCongestionWindow * kDefaultTCPMSS),
- kMinCongestionWindowForBandwidthResumption * kDefaultTCPMSS);
-}
-
-void TcpCubicBytesSender::SetNumEmulatedConnections(int num_connections) {
- num_connections_ = max(1, num_connections);
- cubic_.SetNumConnections(num_connections_);
-}
-
-void TcpCubicBytesSender::SetMaxCongestionWindow(
- QuicByteCount max_congestion_window) {
- max_congestion_window_ = max_congestion_window;
-}
-
-float TcpCubicBytesSender::RenoBeta() const {
- // kNConnectionBeta is the backoff factor after loss for our N-connection
- // emulation, which emulates the effective backoff of an ensemble of N
- // TCP-Reno connections on a single loss event. The effective multiplier is
- // computed as:
- return (num_connections_ - 1 + kRenoBeta) / num_connections_;
-}
-
-void TcpCubicBytesSender::OnCongestionEvent(
- bool rtt_updated,
- QuicByteCount bytes_in_flight,
- const CongestionVector& acked_packets,
- const CongestionVector& lost_packets) {
- if (rtt_updated && InSlowStart() &&
- hybrid_slow_start_.ShouldExitSlowStart(
- rtt_stats_->latest_rtt(), rtt_stats_->min_rtt(),
- congestion_window_ / kDefaultTCPMSS)) {
- slowstart_threshold_ = congestion_window_;
- }
- for (CongestionVector::const_iterator it = lost_packets.begin();
- it != lost_packets.end(); ++it) {
- OnPacketLost(it->first, bytes_in_flight);
- }
- for (CongestionVector::const_iterator it = acked_packets.begin();
- it != acked_packets.end(); ++it) {
- OnPacketAcked(it->first, it->second, bytes_in_flight);
- }
-}
-
-void TcpCubicBytesSender::OnPacketAcked(QuicPacketNumber acked_packet_number,
- QuicByteCount acked_bytes,
- QuicByteCount bytes_in_flight) {
- largest_acked_packet_number_ =
- max(acked_packet_number, largest_acked_packet_number_);
- if (InRecovery()) {
- // PRR is used when in recovery.
- prr_.OnPacketAcked(acked_bytes);
- return;
- }
- MaybeIncreaseCwnd(acked_packet_number, acked_bytes, bytes_in_flight);
- if (InSlowStart()) {
- hybrid_slow_start_.OnPacketAcked(acked_packet_number);
- }
-}
-
-void TcpCubicBytesSender::OnPacketLost(QuicPacketNumber packet_number,
- QuicByteCount bytes_in_flight) {
- // TCP NewReno (RFC6582) says that once a loss occurs, any losses in packets
- // already sent should be treated as a single loss event, since it's expected.
- if (packet_number <= largest_sent_at_last_cutback_) {
- if (last_cutback_exited_slowstart_) {
- ++stats_->slowstart_packets_lost;
- if (slow_start_large_reduction_) {
- // Reduce congestion window by 1 MSS for every loss.
- congestion_window_ =
- max(congestion_window_ - kDefaultTCPMSS, min_congestion_window_);
- slowstart_threshold_ = congestion_window_;
- }
- }
- DVLOG(1) << "Ignoring loss for largest_missing:" << packet_number
- << " because it was sent prior to the last CWND cutback.";
- return;
- }
- ++stats_->tcp_loss_events;
- last_cutback_exited_slowstart_ = InSlowStart();
- if (InSlowStart()) {
- ++stats_->slowstart_packets_lost;
- }
-
- prr_.OnPacketLost(bytes_in_flight);
-
- // TODO(jri): Separate out all of slow start into a separate class.
- if (slow_start_large_reduction_ && InSlowStart()) {
- DCHECK_LT(kDefaultTCPMSS, congestion_window_);
- congestion_window_ = congestion_window_ - kDefaultTCPMSS;
- } else if (reno_) {
- congestion_window_ = congestion_window_ * RenoBeta();
- } else {
- congestion_window_ =
- cubic_.CongestionWindowAfterPacketLoss(congestion_window_);
- }
- // Enforce TCP's minimum congestion window of 2*MSS.
- if (congestion_window_ < min_congestion_window_) {
- congestion_window_ = min_congestion_window_;
- }
- slowstart_threshold_ = congestion_window_;
- largest_sent_at_last_cutback_ = largest_sent_packet_number_;
- // Reset packet count from congestion avoidance mode. We start counting again
- // when we're out of recovery.
- num_acked_packets_ = 0;
- DVLOG(1) << "Incoming loss; congestion window: " << congestion_window_
- << " slowstart threshold: " << slowstart_threshold_;
-}
-
-bool TcpCubicBytesSender::OnPacketSent(
- QuicTime /*sent_time*/,
- QuicByteCount /*bytes_in_flight*/,
- QuicPacketNumber packet_number,
- QuicByteCount bytes,
- HasRetransmittableData is_retransmittable) {
- if (InSlowStart()) {
- ++(stats_->slowstart_packets_sent);
- }
-
- // Only update bytes_in_flight_ for data packets.
- if (is_retransmittable != HAS_RETRANSMITTABLE_DATA) {
- return false;
- }
- if (InRecovery()) {
- // PRR is used when in recovery.
- prr_.OnPacketSent(bytes);
- }
- DCHECK_LT(largest_sent_packet_number_, packet_number);
- largest_sent_packet_number_ = packet_number;
- hybrid_slow_start_.OnPacketSent(packet_number);
- return true;
-}
-
-QuicTime::Delta TcpCubicBytesSender::TimeUntilSend(
- QuicTime /* now */,
- QuicByteCount bytes_in_flight,
- HasRetransmittableData has_retransmittable_data) const {
- if (has_retransmittable_data == NO_RETRANSMITTABLE_DATA) {
- DCHECK(!FLAGS_quic_respect_send_alarm2);
- // For TCP we can always send an ACK immediately.
- return QuicTime::Delta::Zero();
- }
- if (InRecovery()) {
- // PRR is used when in recovery.
- return prr_.TimeUntilSend(GetCongestionWindow(), bytes_in_flight,
- slowstart_threshold_);
- }
- if (GetCongestionWindow() > bytes_in_flight) {
- return QuicTime::Delta::Zero();
- }
- if (min4_mode_ && bytes_in_flight < 4 * kDefaultTCPMSS) {
- return QuicTime::Delta::Zero();
- }
- return QuicTime::Delta::Infinite();
-}
-
-QuicBandwidth TcpCubicBytesSender::PacingRate() const {
- // We pace at twice the rate of the underlying sender's bandwidth estimate
- // during slow start and 1.25x during congestion avoidance to ensure pacing
- // doesn't prevent us from filling the window.
- QuicTime::Delta srtt = rtt_stats_->smoothed_rtt();
- if (srtt.IsZero()) {
- srtt = QuicTime::Delta::FromMicroseconds(rtt_stats_->initial_rtt_us());
- }
- const QuicBandwidth bandwidth =
- QuicBandwidth::FromBytesAndTimeDelta(GetCongestionWindow(), srtt);
- return bandwidth.Scale(InSlowStart() ? 2 : 1.25);
-}
-
-QuicBandwidth TcpCubicBytesSender::BandwidthEstimate() const {
- QuicTime::Delta srtt = rtt_stats_->smoothed_rtt();
- if (srtt.IsZero()) {
- // If we haven't measured an rtt, the bandwidth estimate is unknown.
- return QuicBandwidth::Zero();
- }
- return QuicBandwidth::FromBytesAndTimeDelta(GetCongestionWindow(), srtt);
-}
-
-QuicTime::Delta TcpCubicBytesSender::RetransmissionDelay() const {
- if (rtt_stats_->smoothed_rtt().IsZero()) {
- return QuicTime::Delta::Zero();
- }
- return rtt_stats_->smoothed_rtt().Add(
- rtt_stats_->mean_deviation().Multiply(4));
-}
-
-QuicByteCount TcpCubicBytesSender::GetCongestionWindow() const {
- return congestion_window_;
-}
-
-bool TcpCubicBytesSender::InSlowStart() const {
- return congestion_window_ < slowstart_threshold_;
-}
-
-QuicByteCount TcpCubicBytesSender::GetSlowStartThreshold() const {
- return slowstart_threshold_;
-}
-
-bool TcpCubicBytesSender::IsCwndLimited(QuicByteCount bytes_in_flight) const {
- if (bytes_in_flight >= congestion_window_) {
- return true;
- }
- const QuicByteCount available_bytes = congestion_window_ - bytes_in_flight;
- const bool slow_start_limited =
- InSlowStart() && bytes_in_flight > congestion_window_ / 2;
- return slow_start_limited || available_bytes <= kMaxBurstBytes;
-}
-
-bool TcpCubicBytesSender::InRecovery() const {
- return largest_acked_packet_number_ <= largest_sent_at_last_cutback_ &&
- largest_acked_packet_number_ != 0;
-}
-
-// Called when we receive an ack. Normal TCP tracks how many packets one ack
-// represents, but quic has a separate ack for each packet.
-void TcpCubicBytesSender::MaybeIncreaseCwnd(
- QuicPacketNumber acked_packet_number,
- QuicByteCount acked_bytes,
- QuicByteCount bytes_in_flight) {
- QUIC_BUG_IF(InRecovery()) << "Never increase the CWND during recovery.";
- // Do not increase the congestion window unless the sender is close to using
- // the current window.
- if (!IsCwndLimited(bytes_in_flight)) {
- cubic_.OnApplicationLimited();
- return;
- }
- if (congestion_window_ >= max_congestion_window_) {
- return;
- }
- if (InSlowStart()) {
- // TCP slow start, exponential growth, increase by one for each ACK.
- congestion_window_ += kDefaultTCPMSS;
- DVLOG(1) << "Slow start; congestion window: " << congestion_window_
- << " slowstart threshold: " << slowstart_threshold_;
- return;
- }
- // Congestion avoidance.
- if (reno_) {
- // Classic Reno congestion avoidance.
- ++num_acked_packets_;
- // Divide by num_connections to smoothly increase the CWND at a faster rate
- // than conventional Reno.
- if (num_acked_packets_ * num_connections_ >=
- congestion_window_ / kDefaultTCPMSS) {
- congestion_window_ += kDefaultTCPMSS;
- num_acked_packets_ = 0;
- }
-
- DVLOG(1) << "Reno; congestion window: " << congestion_window_
- << " slowstart threshold: " << slowstart_threshold_
- << " congestion window count: " << num_acked_packets_;
- } else {
- congestion_window_ =
- min(max_congestion_window_,
- cubic_.CongestionWindowAfterAck(acked_bytes, congestion_window_,
- rtt_stats_->min_rtt()));
- DVLOG(1) << "Cubic; congestion window: " << congestion_window_
- << " slowstart threshold: " << slowstart_threshold_;
- }
-}
-
-void TcpCubicBytesSender::OnRetransmissionTimeout(bool packets_retransmitted) {
- largest_sent_at_last_cutback_ = 0;
- if (!packets_retransmitted) {
- return;
- }
- cubic_.Reset();
- hybrid_slow_start_.Restart();
- slowstart_threshold_ = congestion_window_ / 2;
- congestion_window_ = min_congestion_window_;
-}
-
-CongestionControlType TcpCubicBytesSender::GetCongestionControlType() const {
- return reno_ ? kRenoBytes : kCubicBytes;
-}
-
-void TcpCubicBytesSender::OnConnectionMigration() {
- hybrid_slow_start_.Restart();
- cubic_.Reset();
- prr_ = PrrSender();
- num_acked_packets_ = 0;
- largest_sent_packet_number_ = 0;
- largest_acked_packet_number_ = 0;
- largest_sent_at_last_cutback_ = 0;
- congestion_window_ = initial_tcp_congestion_window_;
- max_congestion_window_ = initial_max_tcp_congestion_window_;
- slowstart_threshold_ = initial_max_tcp_congestion_window_;
- last_cutback_exited_slowstart_ = false;
-}
-
-} // namespace net
diff --git a/net/quic/congestion_control/tcp_cubic_bytes_sender.h b/net/quic/congestion_control/tcp_cubic_bytes_sender.h
deleted file mode 100644
index e1b0185..0000000
--- a/net/quic/congestion_control/tcp_cubic_bytes_sender.h
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright (c) 2015 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.
-
-// TCP cubic send side congestion algorithm, emulates the behavior of TCP cubic.
-
-#ifndef NET_QUIC_CONGESTION_CONTROL_TCP_CUBIC_BYTES_SENDER_H_
-#define NET_QUIC_CONGESTION_CONTROL_TCP_CUBIC_BYTES_SENDER_H_
-
-#include <stdint.h>
-
-#include "base/macros.h"
-#include "net/base/net_export.h"
-#include "net/quic/congestion_control/cubic_bytes.h"
-#include "net/quic/congestion_control/hybrid_slow_start.h"
-#include "net/quic/congestion_control/prr_sender.h"
-#include "net/quic/congestion_control/send_algorithm_interface.h"
-#include "net/quic/quic_bandwidth.h"
-#include "net/quic/quic_connection_stats.h"
-#include "net/quic/quic_protocol.h"
-#include "net/quic/quic_time.h"
-
-namespace net {
-
-class RttStats;
-
-namespace test {
-class TcpCubicBytesSenderPeer;
-} // namespace test
-
-class NET_EXPORT_PRIVATE TcpCubicBytesSender : public SendAlgorithmInterface {
- public:
- TcpCubicBytesSender(const QuicClock* clock,
- const RttStats* rtt_stats,
- bool reno,
- QuicPacketCount initial_tcp_congestion_window,
- QuicPacketCount max_congestion_window,
- QuicConnectionStats* stats);
- ~TcpCubicBytesSender() override;
-
- // Start implementation of SendAlgorithmInterface.
- void SetFromConfig(const QuicConfig& config,
- Perspective perspective) override;
- void ResumeConnectionState(
- const CachedNetworkParameters& cached_network_params,
- bool max_bandwidth_resumption) override;
- void SetNumEmulatedConnections(int num_connections) override;
- void SetMaxCongestionWindow(QuicByteCount max_congestion_window) override;
- void OnCongestionEvent(bool rtt_updated,
- QuicByteCount bytes_in_flight,
- const CongestionVector& acked_packets,
- const CongestionVector& lost_packets) override;
- bool OnPacketSent(QuicTime sent_time,
- QuicByteCount bytes_in_flight,
- QuicPacketNumber packet_number,
- QuicByteCount bytes,
- HasRetransmittableData is_retransmittable) override;
- void OnRetransmissionTimeout(bool packets_retransmitted) override;
- void OnConnectionMigration() override;
- QuicTime::Delta TimeUntilSend(
- QuicTime now,
- QuicByteCount bytes_in_flight,
- HasRetransmittableData has_retransmittable_data) const override;
- QuicBandwidth PacingRate() const override;
- QuicBandwidth BandwidthEstimate() const override;
- QuicTime::Delta RetransmissionDelay() const override;
- QuicByteCount GetCongestionWindow() const override;
- bool InSlowStart() const override;
- bool InRecovery() const override;
- QuicByteCount GetSlowStartThreshold() const override;
- CongestionControlType GetCongestionControlType() const override;
- // End implementation of SendAlgorithmInterface.
-
- private:
- friend class test::TcpCubicBytesSenderPeer;
-
- // Compute the TCP Reno beta based on the current number of connections.
- float RenoBeta() const;
-
- // TODO(ianswett): Remove these and migrate to OnCongestionEvent.
- void OnPacketAcked(QuicPacketNumber acked_packet_number,
- QuicByteCount acked_bytes,
- QuicByteCount bytes_in_flight);
- void OnPacketLost(QuicPacketNumber largest_loss,
- QuicByteCount bytes_in_flight);
-
- void MaybeIncreaseCwnd(QuicPacketNumber acked_packet_number,
- QuicByteCount acked_bytes,
- QuicByteCount bytes_in_flight);
- bool IsCwndLimited(QuicByteCount bytes_in_flight) const;
-
- HybridSlowStart hybrid_slow_start_;
- CubicBytes cubic_;
- PrrSender prr_;
- const RttStats* rtt_stats_;
- QuicConnectionStats* stats_;
-
- // If true, Reno congestion control is used instead of Cubic.
- const bool reno_;
-
- // Number of connections to simulate.
- uint32_t num_connections_;
-
- // ACK counter for the Reno implementation.
- uint64_t num_acked_packets_;
-
- // Track the largest packet that has been sent.
- QuicPacketNumber largest_sent_packet_number_;
-
- // Track the largest packet that has been acked.
- QuicPacketNumber largest_acked_packet_number_;
-
- // Track the largest packet number outstanding when a CWND cutback occurs.
- QuicPacketNumber largest_sent_at_last_cutback_;
-
- // Congestion window in bytes.
- QuicByteCount congestion_window_;
-
- // Minimum congestion window in bytes.
- QuicByteCount min_congestion_window_;
-
- // Whether to use 4 packets as the actual min, but pace lower.
- bool min4_mode_;
-
- // Maximum congestion window in bytes.
- QuicByteCount max_congestion_window_;
-
- // Slow start congestion window in bytes, aka ssthresh.
- QuicByteCount slowstart_threshold_;
-
- // Whether the last loss event caused us to exit slowstart. Used for stats
- // collection of slowstart_packets_lost.
- bool last_cutback_exited_slowstart_;
-
- // Initial TCP congestion window in bytes. This variable can only be set when
- // this algorithm is created.
- const QuicByteCount initial_tcp_congestion_window_;
-
- // Initial maximum TCP congestion window in bytes. This variable can only be
- // set when this algorithm is created.
- const QuicByteCount initial_max_tcp_congestion_window_;
-
- // When true, exit slow start with large cutback of congestion window.
- bool slow_start_large_reduction_;
-
- DISALLOW_COPY_AND_ASSIGN(TcpCubicBytesSender);
-};
-
-} // namespace net
-
-#endif // NET_QUIC_CONGESTION_CONTROL_TCP_CUBIC_BYTES_SENDER_H_
diff --git a/net/quic/congestion_control/tcp_cubic_bytes_sender_test.cc b/net/quic/congestion_control/tcp_cubic_bytes_sender_test.cc
deleted file mode 100644
index 3089435..0000000
--- a/net/quic/congestion_control/tcp_cubic_bytes_sender_test.cc
+++ /dev/null
@@ -1,743 +0,0 @@
-// Copyright (c) 2015 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/congestion_control/tcp_cubic_bytes_sender.h"
-
-#include <algorithm>
-
-#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-#include "net/quic/congestion_control/rtt_stats.h"
-#include "net/quic/crypto/crypto_protocol.h"
-#include "net/quic/proto/cached_network_parameters.pb.h"
-#include "net/quic/quic_flags.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/quic_config_peer.h"
-#include "net/quic/test_tools/quic_test_utils.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace net {
-namespace test {
-
-// TODO(ianswett): A number of theses tests were written with the assumption of
-// an initial CWND of 10. They have carefully calculated values which should be
-// updated to be based on kInitialCongestionWindow.
-const uint32_t kInitialCongestionWindowPackets = 10;
-const uint32_t kDefaultWindowTCP =
- kInitialCongestionWindowPackets * kDefaultTCPMSS;
-const float kRenoBeta = 0.7f; // Reno backoff factor.
-
-class TcpCubicBytesSenderPeer : public TcpCubicBytesSender {
- public:
- TcpCubicBytesSenderPeer(const QuicClock* clock, bool reno)
- : TcpCubicBytesSender(clock,
- &rtt_stats_,
- reno,
- kInitialCongestionWindowPackets,
- kMaxCongestionWindow,
- &stats_) {}
-
- const HybridSlowStart& hybrid_slow_start() const {
- return hybrid_slow_start_;
- }
-
- float GetRenoBeta() const { return RenoBeta(); }
-
- RttStats rtt_stats_;
- QuicConnectionStats stats_;
-};
-
-class TcpCubicBytesSenderTest : public ::testing::Test {
- protected:
- TcpCubicBytesSenderTest()
- : one_ms_(QuicTime::Delta::FromMilliseconds(1)),
- sender_(new TcpCubicBytesSenderPeer(&clock_, true)),
- packet_number_(1),
- acked_packet_number_(0),
- bytes_in_flight_(0) {}
-
- int SendAvailableSendWindow() {
- // Send as long as TimeUntilSend returns Zero.
- int packets_sent = 0;
- bool can_send = sender_->TimeUntilSend(clock_.Now(), bytes_in_flight_,
- HAS_RETRANSMITTABLE_DATA)
- .IsZero();
- while (can_send) {
- sender_->OnPacketSent(clock_.Now(), bytes_in_flight_, packet_number_++,
- kDefaultTCPMSS, HAS_RETRANSMITTABLE_DATA);
- ++packets_sent;
- bytes_in_flight_ += kDefaultTCPMSS;
- can_send = sender_->TimeUntilSend(clock_.Now(), bytes_in_flight_,
- HAS_RETRANSMITTABLE_DATA)
- .IsZero();
- }
- return packets_sent;
- }
-
- // Normal is that TCP acks every other segment.
- void AckNPackets(int n) {
- sender_->rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(60),
- QuicTime::Delta::Zero(), clock_.Now());
- SendAlgorithmInterface::CongestionVector acked_packets;
- SendAlgorithmInterface::CongestionVector lost_packets;
- for (int i = 0; i < n; ++i) {
- ++acked_packet_number_;
- acked_packets.push_back(
- std::make_pair(acked_packet_number_, kDefaultTCPMSS));
- }
- sender_->OnCongestionEvent(true, bytes_in_flight_, acked_packets,
- lost_packets);
- bytes_in_flight_ -= n * kDefaultTCPMSS;
- clock_.AdvanceTime(one_ms_);
- }
-
- void LoseNPackets(int n) {
- SendAlgorithmInterface::CongestionVector acked_packets;
- SendAlgorithmInterface::CongestionVector lost_packets;
- for (int i = 0; i < n; ++i) {
- ++acked_packet_number_;
- lost_packets.push_back(
- std::make_pair(acked_packet_number_, kDefaultTCPMSS));
- }
- sender_->OnCongestionEvent(false, bytes_in_flight_, acked_packets,
- lost_packets);
- bytes_in_flight_ -= n * kDefaultTCPMSS;
- }
-
- // Does not increment acked_packet_number_.
- void LosePacket(QuicPacketNumber packet_number) {
- SendAlgorithmInterface::CongestionVector acked_packets;
- SendAlgorithmInterface::CongestionVector lost_packets;
- lost_packets.push_back(std::make_pair(packet_number, kDefaultTCPMSS));
- sender_->OnCongestionEvent(false, bytes_in_flight_, acked_packets,
- lost_packets);
- bytes_in_flight_ -= kDefaultTCPMSS;
- }
-
- const QuicTime::Delta one_ms_;
- MockClock clock_;
- scoped_ptr<TcpCubicBytesSenderPeer> sender_;
- QuicPacketNumber packet_number_;
- QuicPacketNumber acked_packet_number_;
- QuicByteCount bytes_in_flight_;
-};
-
-TEST_F(TcpCubicBytesSenderTest, SimpleSender) {
- // At startup make sure we are at the default.
- EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
- // At startup make sure we can send.
- EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0, HAS_RETRANSMITTABLE_DATA)
- .IsZero());
- // Make sure we can send.
- EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0, HAS_RETRANSMITTABLE_DATA)
- .IsZero());
- // And that window is un-affected.
- EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
-
- // Fill the send window with data, then verify that we can't send.
- SendAvailableSendWindow();
- EXPECT_FALSE(sender_->TimeUntilSend(clock_.Now(),
- sender_->GetCongestionWindow(),
- HAS_RETRANSMITTABLE_DATA)
- .IsZero());
-}
-
-TEST_F(TcpCubicBytesSenderTest, ApplicationLimitedSlowStart) {
- // Send exactly 10 packets and ensure the CWND ends at 14 packets.
- const int kNumberOfAcks = 5;
- // At startup make sure we can send.
- EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0, HAS_RETRANSMITTABLE_DATA)
- .IsZero());
- // Make sure we can send.
- EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0, HAS_RETRANSMITTABLE_DATA)
- .IsZero());
-
- SendAvailableSendWindow();
- for (int i = 0; i < kNumberOfAcks; ++i) {
- AckNPackets(2);
- }
- QuicByteCount bytes_to_send = sender_->GetCongestionWindow();
- // It's expected 2 acks will arrive when the bytes_in_flight are greater than
- // half the CWND.
- EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * 2, bytes_to_send);
-}
-
-TEST_F(TcpCubicBytesSenderTest, ExponentialSlowStart) {
- const int kNumberOfAcks = 20;
- // At startup make sure we can send.
- EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0, HAS_RETRANSMITTABLE_DATA)
- .IsZero());
- EXPECT_EQ(QuicBandwidth::Zero(), sender_->BandwidthEstimate());
- // Make sure we can send.
- EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0, HAS_RETRANSMITTABLE_DATA)
- .IsZero());
-
- for (int i = 0; i < kNumberOfAcks; ++i) {
- // Send our full send window.
- SendAvailableSendWindow();
- AckNPackets(2);
- }
- const QuicByteCount cwnd = sender_->GetCongestionWindow();
- EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * kNumberOfAcks, cwnd);
- EXPECT_EQ(QuicBandwidth::FromBytesAndTimeDelta(
- cwnd, sender_->rtt_stats_.smoothed_rtt()),
- sender_->BandwidthEstimate());
-}
-
-TEST_F(TcpCubicBytesSenderTest, SlowStartPacketLoss) {
- sender_->SetNumEmulatedConnections(1);
- const int kNumberOfAcks = 10;
- for (int i = 0; i < kNumberOfAcks; ++i) {
- // Send our full send window.
- SendAvailableSendWindow();
- AckNPackets(2);
- }
- SendAvailableSendWindow();
- QuicByteCount expected_send_window =
- kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Lose a packet to exit slow start.
- LoseNPackets(1);
- size_t packets_in_recovery_window = expected_send_window / kDefaultTCPMSS;
-
- // We should now have fallen out of slow start with a reduced window.
- expected_send_window *= kRenoBeta;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Recovery phase. We need to ack every packet in the recovery window before
- // we exit recovery.
- size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS;
- DVLOG(1) << "number_packets: " << number_of_packets_in_window;
- AckNPackets(packets_in_recovery_window);
- SendAvailableSendWindow();
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // We need to ack an entire window before we increase CWND by 1.
- AckNPackets(number_of_packets_in_window - 2);
- SendAvailableSendWindow();
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Next ack should increase cwnd by 1.
- AckNPackets(1);
- expected_send_window += kDefaultTCPMSS;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Now RTO and ensure slow start gets reset.
- EXPECT_TRUE(sender_->hybrid_slow_start().started());
- sender_->OnRetransmissionTimeout(true);
- EXPECT_FALSE(sender_->hybrid_slow_start().started());
-}
-
-TEST_F(TcpCubicBytesSenderTest, SlowStartPacketLossWithLargeReduction) {
- QuicConfig config;
- QuicTagVector options;
- options.push_back(kSSLR);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- sender_->SetFromConfig(config, Perspective::IS_SERVER);
-
- sender_->SetNumEmulatedConnections(1);
- const int kNumberOfAcks = 10;
- for (int i = 0; i < kNumberOfAcks; ++i) {
- // Send our full send window.
- SendAvailableSendWindow();
- AckNPackets(2);
- }
- SendAvailableSendWindow();
- QuicByteCount expected_send_window =
- kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Lose a packet to exit slow start. We should now have fallen out of
- // slow start with a window reduced by 1.
- LoseNPackets(1);
- expected_send_window -= kDefaultTCPMSS;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Lose 5 packets in recovery and verify that congestion window is reduced
- // further.
- LoseNPackets(5);
- expected_send_window -= 5 * kDefaultTCPMSS;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- size_t packets_in_recovery_window = expected_send_window / kDefaultTCPMSS;
-
- // Recovery phase. We need to ack every packet in the recovery window before
- // we exit recovery.
- size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS;
- DVLOG(1) << "number_packets: " << number_of_packets_in_window;
- AckNPackets(packets_in_recovery_window);
- SendAvailableSendWindow();
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // We need to ack an entire window before we increase CWND by 1.
- AckNPackets(number_of_packets_in_window - 1);
- SendAvailableSendWindow();
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Next ack should increase cwnd by 1.
- AckNPackets(1);
- expected_send_window += kDefaultTCPMSS;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Now RTO and ensure slow start gets reset.
- EXPECT_TRUE(sender_->hybrid_slow_start().started());
- sender_->OnRetransmissionTimeout(true);
- EXPECT_FALSE(sender_->hybrid_slow_start().started());
-}
-
-TEST_F(TcpCubicBytesSenderTest, NoPRRWhenLessThanOnePacketInFlight) {
- SendAvailableSendWindow();
- LoseNPackets(kInitialCongestionWindowPackets - 1);
- AckNPackets(1);
- // PRR will allow 2 packets for every ack during recovery.
- EXPECT_EQ(2, SendAvailableSendWindow());
- // Simulate abandoning all packets by supplying a bytes_in_flight of 0.
- // PRR should now allow a packet to be sent, even though prr's state variables
- // believe it has sent enough packets.
- EXPECT_EQ(QuicTime::Delta::Zero(),
- sender_->TimeUntilSend(clock_.Now(), 0, HAS_RETRANSMITTABLE_DATA));
-}
-
-TEST_F(TcpCubicBytesSenderTest, SlowStartPacketLossPRR) {
- sender_->SetNumEmulatedConnections(1);
- // Test based on the first example in RFC6937.
- // Ack 10 packets in 5 acks to raise the CWND to 20, as in the example.
- const int kNumberOfAcks = 5;
- for (int i = 0; i < kNumberOfAcks; ++i) {
- // Send our full send window.
- SendAvailableSendWindow();
- AckNPackets(2);
- }
- SendAvailableSendWindow();
- QuicByteCount expected_send_window =
- kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- LoseNPackets(1);
-
- // We should now have fallen out of slow start with a reduced window.
- size_t send_window_before_loss = expected_send_window;
- expected_send_window *= kRenoBeta;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Testing TCP proportional rate reduction.
- // We should send packets paced over the received acks for the remaining
- // outstanding packets. The number of packets before we exit recovery is the
- // original CWND minus the packet that has been lost and the one which
- // triggered the loss.
- size_t remaining_packets_in_recovery =
- send_window_before_loss / kDefaultTCPMSS - 2;
-
- for (size_t i = 0; i < remaining_packets_in_recovery; ++i) {
- AckNPackets(1);
- SendAvailableSendWindow();
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
- }
-
- // We need to ack another window before we increase CWND by 1.
- size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS;
- for (size_t i = 0; i < number_of_packets_in_window; ++i) {
- AckNPackets(1);
- EXPECT_EQ(1, SendAvailableSendWindow());
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
- }
-
- AckNPackets(1);
- expected_send_window += kDefaultTCPMSS;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicBytesSenderTest, SlowStartBurstPacketLossPRR) {
- sender_->SetNumEmulatedConnections(1);
- // Test based on the second example in RFC6937, though we also implement
- // forward acknowledgements, so the first two incoming acks will trigger
- // PRR immediately.
- // Ack 20 packets in 10 acks to raise the CWND to 30.
- const int kNumberOfAcks = 10;
- for (int i = 0; i < kNumberOfAcks; ++i) {
- // Send our full send window.
- SendAvailableSendWindow();
- AckNPackets(2);
- }
- SendAvailableSendWindow();
- QuicByteCount expected_send_window =
- kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Lose one more than the congestion window reduction, so that after loss,
- // bytes_in_flight is lesser than the congestion window.
- size_t send_window_after_loss = kRenoBeta * expected_send_window;
- size_t num_packets_to_lose =
- (expected_send_window - send_window_after_loss) / kDefaultTCPMSS + 1;
- LoseNPackets(num_packets_to_lose);
- // Immediately after the loss, ensure at least one packet can be sent.
- // Losses without subsequent acks can occur with timer based loss detection.
- EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), bytes_in_flight_,
- HAS_RETRANSMITTABLE_DATA)
- .IsZero());
- AckNPackets(1);
-
- // We should now have fallen out of slow start with a reduced window.
- expected_send_window *= kRenoBeta;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Only 2 packets should be allowed to be sent, per PRR-SSRB.
- EXPECT_EQ(2, SendAvailableSendWindow());
-
- // Ack the next packet, which triggers another loss.
- LoseNPackets(1);
- AckNPackets(1);
-
- // Send 2 packets to simulate PRR-SSRB.
- EXPECT_EQ(2, SendAvailableSendWindow());
-
- // Ack the next packet, which triggers another loss.
- LoseNPackets(1);
- AckNPackets(1);
-
- // Send 2 packets to simulate PRR-SSRB.
- EXPECT_EQ(2, SendAvailableSendWindow());
-
- // Exit recovery and return to sending at the new rate.
- for (int i = 0; i < kNumberOfAcks; ++i) {
- AckNPackets(1);
- EXPECT_EQ(1, SendAvailableSendWindow());
- }
-}
-
-TEST_F(TcpCubicBytesSenderTest, RTOCongestionWindow) {
- EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
- // Expect the window to decrease to the minimum once the RTO fires and slow
- // start threshold to be set to 1/2 of the CWND.
- sender_->OnRetransmissionTimeout(true);
- EXPECT_EQ(2 * kDefaultTCPMSS, sender_->GetCongestionWindow());
- EXPECT_EQ(5u * kDefaultTCPMSS, sender_->GetSlowStartThreshold());
-}
-
-TEST_F(TcpCubicBytesSenderTest, RTOCongestionWindowNoRetransmission) {
- EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
-
- // Expect the window to remain unchanged if the RTO fires but no packets are
- // retransmitted.
- sender_->OnRetransmissionTimeout(false);
- EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicBytesSenderTest, RetransmissionDelay) {
- const int64_t kRttMs = 10;
- const int64_t kDeviationMs = 3;
- EXPECT_EQ(QuicTime::Delta::Zero(), sender_->RetransmissionDelay());
-
- sender_->rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(kRttMs),
- QuicTime::Delta::Zero(), clock_.Now());
-
- // 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 finally the smoothed rtt
- // is added which is the initial 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_->rtt_stats_.UpdateRtt(
- QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs),
- QuicTime::Delta::Zero(), clock_.Now());
- sender_->rtt_stats_.UpdateRtt(
- QuicTime::Delta::FromMilliseconds(kRttMs - kDeviationMs),
- QuicTime::Delta::Zero(), clock_.Now());
- }
- expected_delay = QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs * 4);
-
- EXPECT_NEAR(kRttMs, sender_->rtt_stats_.smoothed_rtt().ToMilliseconds(), 1);
- EXPECT_NEAR(expected_delay.ToMilliseconds(),
- sender_->RetransmissionDelay().ToMilliseconds(), 1);
- EXPECT_EQ(static_cast<int64_t>(
- sender_->GetCongestionWindow() * kNumMicrosPerSecond /
- sender_->rtt_stats_.smoothed_rtt().ToMicroseconds()),
- sender_->BandwidthEstimate().ToBytesPerSecond());
-}
-
-TEST_F(TcpCubicBytesSenderTest, TcpCubicResetEpochOnQuiescence) {
- const int kMaxCongestionWindow = 50;
- const QuicByteCount kMaxCongestionWindowBytes =
- kMaxCongestionWindow * kDefaultTCPMSS;
- int num_sent = SendAvailableSendWindow();
-
- // Make sure we fall out of slow start.
- QuicByteCount saved_cwnd = sender_->GetCongestionWindow();
- LoseNPackets(1);
- EXPECT_GT(saved_cwnd, sender_->GetCongestionWindow());
-
- // Ack the rest of the outstanding packets to get out of recovery.
- for (int i = 1; i < num_sent; ++i) {
- AckNPackets(1);
- }
- EXPECT_EQ(0u, bytes_in_flight_);
-
- // Send a new window of data and ack all; cubic growth should occur.
- saved_cwnd = sender_->GetCongestionWindow();
- num_sent = SendAvailableSendWindow();
- for (int i = 0; i < num_sent; ++i) {
- AckNPackets(1);
- }
- EXPECT_LT(saved_cwnd, sender_->GetCongestionWindow());
- EXPECT_GT(kMaxCongestionWindowBytes, sender_->GetCongestionWindow());
- EXPECT_EQ(0u, bytes_in_flight_);
-
- // Quiescent time of 100 seconds
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100000));
-
- // Send new window of data and ack one packet. Cubic epoch should have
- // been reset; ensure cwnd increase is not dramatic.
- saved_cwnd = sender_->GetCongestionWindow();
- SendAvailableSendWindow();
- AckNPackets(1);
- EXPECT_NEAR(saved_cwnd, sender_->GetCongestionWindow(), kDefaultTCPMSS);
- EXPECT_GT(kMaxCongestionWindowBytes, sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicBytesSenderTest, MultipleLossesInOneWindow) {
- SendAvailableSendWindow();
- const QuicByteCount initial_window = sender_->GetCongestionWindow();
- LosePacket(acked_packet_number_ + 1);
- const QuicByteCount post_loss_window = sender_->GetCongestionWindow();
- EXPECT_GT(initial_window, post_loss_window);
- LosePacket(acked_packet_number_ + 3);
- EXPECT_EQ(post_loss_window, sender_->GetCongestionWindow());
- LosePacket(packet_number_ - 1);
- EXPECT_EQ(post_loss_window, sender_->GetCongestionWindow());
-
- // Lose a later packet and ensure the window decreases.
- LosePacket(packet_number_);
- EXPECT_GT(post_loss_window, sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicBytesSenderTest, DontTrackAckPackets) {
- // Send a packet with no retransmittable data, and ensure it's not tracked.
- EXPECT_FALSE(sender_->OnPacketSent(clock_.Now(), bytes_in_flight_,
- packet_number_++, kDefaultTCPMSS,
- NO_RETRANSMITTABLE_DATA));
-
- // Send a data packet with retransmittable data, and ensure it is tracked.
- EXPECT_TRUE(sender_->OnPacketSent(clock_.Now(), bytes_in_flight_,
- packet_number_++, kDefaultTCPMSS,
- HAS_RETRANSMITTABLE_DATA));
-}
-
-TEST_F(TcpCubicBytesSenderTest, ConfigureMaxInitialWindow) {
- QuicConfig config;
-
- // Verify that kCOPT: kIW10 forces the congestion window to the default of 10.
- QuicTagVector options;
- options.push_back(kIW10);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- sender_->SetFromConfig(config, Perspective::IS_SERVER);
- EXPECT_EQ(10u * kDefaultTCPMSS, sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicBytesSenderTest, 2ConnectionCongestionAvoidanceAtEndOfRecovery) {
- sender_->SetNumEmulatedConnections(2);
- // Ack 10 packets in 5 acks to raise the CWND to 20.
- const int kNumberOfAcks = 5;
- for (int i = 0; i < kNumberOfAcks; ++i) {
- // Send our full send window.
- SendAvailableSendWindow();
- AckNPackets(2);
- }
- SendAvailableSendWindow();
- QuicByteCount expected_send_window =
- kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- LoseNPackets(1);
-
- // We should now have fallen out of slow start with a reduced window.
- expected_send_window = expected_send_window * sender_->GetRenoBeta();
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // No congestion window growth should occur in recovery phase, i.e., until the
- // currently outstanding 20 packets are acked.
- for (int i = 0; i < 10; ++i) {
- // Send our full send window.
- SendAvailableSendWindow();
- EXPECT_TRUE(sender_->InRecovery());
- AckNPackets(2);
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
- }
- EXPECT_FALSE(sender_->InRecovery());
-
- // Out of recovery now. Congestion window should not grow for half an RTT.
- size_t packets_in_send_window = expected_send_window / kDefaultTCPMSS;
- SendAvailableSendWindow();
- AckNPackets(packets_in_send_window / 2 - 2);
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Next ack should increase congestion window by 1MSS.
- SendAvailableSendWindow();
- AckNPackets(2);
- expected_send_window += kDefaultTCPMSS;
- packets_in_send_window += 1;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Congestion window should remain steady again for half an RTT.
- SendAvailableSendWindow();
- AckNPackets(packets_in_send_window / 2 - 1);
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Next ack should cause congestion window to grow by 1MSS.
- SendAvailableSendWindow();
- AckNPackets(2);
- expected_send_window += kDefaultTCPMSS;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicBytesSenderTest, 1ConnectionCongestionAvoidanceAtEndOfRecovery) {
- sender_->SetNumEmulatedConnections(1);
- // Ack 10 packets in 5 acks to raise the CWND to 20.
- const int kNumberOfAcks = 5;
- for (int i = 0; i < kNumberOfAcks; ++i) {
- // Send our full send window.
- SendAvailableSendWindow();
- AckNPackets(2);
- }
- SendAvailableSendWindow();
- QuicByteCount expected_send_window =
- kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- LoseNPackets(1);
-
- // We should now have fallen out of slow start with a reduced window.
- expected_send_window *= kRenoBeta;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // No congestion window growth should occur in recovery phase, i.e., until the
- // currently outstanding 20 packets are acked.
- for (int i = 0; i < 10; ++i) {
- // Send our full send window.
- SendAvailableSendWindow();
- EXPECT_TRUE(sender_->InRecovery());
- AckNPackets(2);
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
- }
- EXPECT_FALSE(sender_->InRecovery());
-
- // Out of recovery now. Congestion window should not grow during RTT.
- for (uint64_t i = 0; i < expected_send_window / kDefaultTCPMSS - 2; i += 2) {
- // Send our full send window.
- SendAvailableSendWindow();
- AckNPackets(2);
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
- }
-
- // Next ack should cause congestion window to grow by 1MSS.
- SendAvailableSendWindow();
- AckNPackets(2);
- expected_send_window += kDefaultTCPMSS;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicBytesSenderTest, BandwidthResumption) {
- // Test that when provided with CachedNetworkParameters and opted in to the
- // bandwidth resumption experiment, that the TcpCubicSender sets initial CWND
- // appropriately.
-
- // Set some common values.
- CachedNetworkParameters cached_network_params;
- const QuicPacketCount kNumberOfPackets = 123;
- const int kBandwidthEstimateBytesPerSecond =
- kNumberOfPackets * kDefaultTCPMSS;
- cached_network_params.set_bandwidth_estimate_bytes_per_second(
- kBandwidthEstimateBytesPerSecond);
- cached_network_params.set_min_rtt_ms(1000);
-
- // Make sure that a bandwidth estimate results in a changed CWND.
- cached_network_params.set_timestamp(clock_.WallNow().ToUNIXSeconds() -
- (kNumSecondsPerHour - 1));
- sender_->ResumeConnectionState(cached_network_params, false);
- EXPECT_EQ(kNumberOfPackets * kDefaultTCPMSS, sender_->GetCongestionWindow());
-
- // Resumed CWND is limited to be in a sensible range.
- cached_network_params.set_bandwidth_estimate_bytes_per_second(
- (kMaxCongestionWindow + 1) * kDefaultTCPMSS);
- sender_->ResumeConnectionState(cached_network_params, false);
- EXPECT_EQ(kMaxCongestionWindow * kDefaultTCPMSS,
- sender_->GetCongestionWindow());
-
- cached_network_params.set_bandwidth_estimate_bytes_per_second(
- (kMinCongestionWindowForBandwidthResumption - 1) * kDefaultTCPMSS);
- sender_->ResumeConnectionState(cached_network_params, false);
- EXPECT_EQ(kMinCongestionWindowForBandwidthResumption * kDefaultTCPMSS,
- sender_->GetCongestionWindow());
-
- // Resume to the max value.
- cached_network_params.set_max_bandwidth_estimate_bytes_per_second(
- (kMinCongestionWindowForBandwidthResumption + 10) * kDefaultTCPMSS);
- sender_->ResumeConnectionState(cached_network_params, true);
- EXPECT_EQ((kMinCongestionWindowForBandwidthResumption + 10) * kDefaultTCPMSS,
- sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicBytesSenderTest, PaceBelowCWND) {
- QuicConfig config;
-
- // Verify that kCOPT: kMIN4 forces the min CWND to 1 packet, but allows up
- // to 4 to be sent.
- QuicTagVector options;
- options.push_back(kMIN4);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- sender_->SetFromConfig(config, Perspective::IS_SERVER);
- sender_->OnRetransmissionTimeout(true);
- EXPECT_EQ(kDefaultTCPMSS, sender_->GetCongestionWindow());
- EXPECT_TRUE(sender_->TimeUntilSend(QuicTime::Zero(), kDefaultTCPMSS,
- HAS_RETRANSMITTABLE_DATA)
- .IsZero());
- EXPECT_TRUE(sender_->TimeUntilSend(QuicTime::Zero(), 2 * kDefaultTCPMSS,
- HAS_RETRANSMITTABLE_DATA)
- .IsZero());
- EXPECT_TRUE(sender_->TimeUntilSend(QuicTime::Zero(), 3 * kDefaultTCPMSS,
- HAS_RETRANSMITTABLE_DATA)
- .IsZero());
- EXPECT_FALSE(sender_->TimeUntilSend(QuicTime::Zero(), 4 * kDefaultTCPMSS,
- HAS_RETRANSMITTABLE_DATA)
- .IsZero());
-}
-
-TEST_F(TcpCubicBytesSenderTest, ResetAfterConnectionMigration) {
- // Starts from slow start.
- sender_->SetNumEmulatedConnections(1);
- const int kNumberOfAcks = 10;
- for (int i = 0; i < kNumberOfAcks; ++i) {
- // Send our full send window.
- SendAvailableSendWindow();
- AckNPackets(2);
- }
- SendAvailableSendWindow();
- QuicByteCount expected_send_window =
- kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Loses a packet to exit slow start.
- LoseNPackets(1);
-
- // We should now have fallen out of slow start with a reduced window. Slow
- // start threshold is also updated.
- expected_send_window *= kRenoBeta;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
- EXPECT_EQ(expected_send_window, sender_->GetSlowStartThreshold());
-
- // Resets cwnd and slow start threshold on connection migrations.
- sender_->OnConnectionMigration();
- EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
- EXPECT_EQ(kMaxCongestionWindow * kDefaultTCPMSS,
- sender_->GetSlowStartThreshold());
- EXPECT_FALSE(sender_->hybrid_slow_start().started());
-}
-
-} // namespace test
-} // namespace net
diff --git a/net/quic/congestion_control/tcp_cubic_sender.cc b/net/quic/congestion_control/tcp_cubic_sender.cc
deleted file mode 100644
index f78f587..0000000
--- a/net/quic/congestion_control/tcp_cubic_sender.cc
+++ /dev/null
@@ -1,401 +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/congestion_control/tcp_cubic_sender.h"
-
-#include <algorithm>
-
-#include "base/metrics/histogram_macros.h"
-#include "net/quic/congestion_control/prr_sender.h"
-#include "net/quic/congestion_control/rtt_stats.h"
-#include "net/quic/crypto/crypto_protocol.h"
-#include "net/quic/proto/cached_network_parameters.pb.h"
-#include "net/quic/quic_bug_tracker.h"
-#include "net/quic/quic_flags.h"
-
-using std::max;
-using std::min;
-
-namespace net {
-
-namespace {
-// Constants based on TCP defaults.
-// The minimum cwnd based on RFC 3782 (TCP NewReno) for cwnd reductions on a
-// fast retransmission. The cwnd after a timeout is still 1.
-const QuicPacketCount kDefaultMinimumCongestionWindow = 2;
-const QuicByteCount kMaxBurstBytes = 3 * kDefaultTCPMSS;
-const float kRenoBeta = 0.7f; // Reno backoff factor.
-const uint32_t kDefaultNumConnections = 2; // N-connection emulation.
-} // namespace
-
-TcpCubicSender::TcpCubicSender(const QuicClock* clock,
- const RttStats* rtt_stats,
- bool reno,
- QuicPacketCount initial_tcp_congestion_window,
- QuicPacketCount max_tcp_congestion_window,
- QuicConnectionStats* stats)
- : cubic_(clock),
- rtt_stats_(rtt_stats),
- stats_(stats),
- reno_(reno),
- num_connections_(kDefaultNumConnections),
- congestion_window_count_(0),
- largest_sent_packet_number_(0),
- largest_acked_packet_number_(0),
- largest_sent_at_last_cutback_(0),
- congestion_window_(initial_tcp_congestion_window),
- min_congestion_window_(kDefaultMinimumCongestionWindow),
- min4_mode_(false),
- slowstart_threshold_(max_tcp_congestion_window),
- last_cutback_exited_slowstart_(false),
- max_tcp_congestion_window_(max_tcp_congestion_window),
- initial_tcp_congestion_window_(initial_tcp_congestion_window),
- initial_max_tcp_congestion_window_(max_tcp_congestion_window),
- slow_start_large_reduction_(false) {}
-
-TcpCubicSender::~TcpCubicSender() {
- UMA_HISTOGRAM_COUNTS("Net.QuicSession.FinalTcpCwnd", congestion_window_);
-}
-
-void TcpCubicSender::SetFromConfig(const QuicConfig& config,
- Perspective perspective) {
- if (perspective == Perspective::IS_SERVER) {
- if (config.HasReceivedConnectionOptions() &&
- ContainsQuicTag(config.ReceivedConnectionOptions(), kIW03)) {
- // Initial window experiment.
- congestion_window_ = 3;
- }
- if (config.HasReceivedConnectionOptions() &&
- ContainsQuicTag(config.ReceivedConnectionOptions(), kIW10)) {
- // Initial window experiment.
- congestion_window_ = 10;
- }
- if (config.HasReceivedConnectionOptions() &&
- ContainsQuicTag(config.ReceivedConnectionOptions(), kIW20)) {
- // Initial window experiment.
- congestion_window_ = 20;
- }
- if (config.HasReceivedConnectionOptions() &&
- ContainsQuicTag(config.ReceivedConnectionOptions(), kIW50)) {
- // Initial window experiment.
- congestion_window_ = 50;
- }
- if (config.HasReceivedConnectionOptions() &&
- ContainsQuicTag(config.ReceivedConnectionOptions(), kMIN1)) {
- // Min CWND experiment.
- min_congestion_window_ = 1;
- }
- if (config.HasReceivedConnectionOptions() &&
- ContainsQuicTag(config.ReceivedConnectionOptions(), kMIN4)) {
- // Min CWND of 4 experiment.
- min4_mode_ = true;
- min_congestion_window_ = 1;
- }
- if (config.HasReceivedConnectionOptions() &&
- ContainsQuicTag(config.ReceivedConnectionOptions(), kSSLR)) {
- // Slow Start Fast Exit experiment.
- slow_start_large_reduction_ = true;
- }
- }
-}
-
-void TcpCubicSender::ResumeConnectionState(
- const CachedNetworkParameters& cached_network_params,
- bool max_bandwidth_resumption) {
- QuicBandwidth bandwidth = QuicBandwidth::FromBytesPerSecond(
- max_bandwidth_resumption
- ? cached_network_params.max_bandwidth_estimate_bytes_per_second()
- : cached_network_params.bandwidth_estimate_bytes_per_second());
- QuicTime::Delta rtt_ms =
- QuicTime::Delta::FromMilliseconds(cached_network_params.min_rtt_ms());
-
- // Make sure CWND is in appropriate range (in case of bad data).
- QuicPacketCount new_congestion_window =
- bandwidth.ToBytesPerPeriod(rtt_ms) / kDefaultTCPMSS;
- congestion_window_ = max(min(new_congestion_window, kMaxCongestionWindow),
- kMinCongestionWindowForBandwidthResumption);
-}
-
-void TcpCubicSender::SetNumEmulatedConnections(int num_connections) {
- num_connections_ = max(1, num_connections);
- cubic_.SetNumConnections(num_connections_);
-}
-
-void TcpCubicSender::SetMaxCongestionWindow(
- QuicByteCount max_congestion_window) {
- max_tcp_congestion_window_ = max_congestion_window / kDefaultTCPMSS;
-}
-
-float TcpCubicSender::RenoBeta() const {
- // kNConnectionBeta is the backoff factor after loss for our N-connection
- // emulation, which emulates the effective backoff of an ensemble of N
- // TCP-Reno connections on a single loss event. The effective multiplier is
- // computed as:
- return (num_connections_ - 1 + kRenoBeta) / num_connections_;
-}
-
-void TcpCubicSender::OnCongestionEvent(bool rtt_updated,
- QuicByteCount bytes_in_flight,
- const CongestionVector& acked_packets,
- const CongestionVector& lost_packets) {
- if (rtt_updated && InSlowStart() &&
- hybrid_slow_start_.ShouldExitSlowStart(rtt_stats_->latest_rtt(),
- rtt_stats_->min_rtt(),
- congestion_window_)) {
- slowstart_threshold_ = congestion_window_;
- }
- for (CongestionVector::const_iterator it = lost_packets.begin();
- it != lost_packets.end(); ++it) {
- OnPacketLost(it->first, bytes_in_flight);
- }
- for (CongestionVector::const_iterator it = acked_packets.begin();
- it != acked_packets.end(); ++it) {
- OnPacketAcked(it->first, it->second, bytes_in_flight);
- }
-}
-
-void TcpCubicSender::OnPacketAcked(QuicPacketNumber acked_packet_number,
- QuicByteCount acked_bytes,
- QuicByteCount bytes_in_flight) {
- largest_acked_packet_number_ =
- max(acked_packet_number, largest_acked_packet_number_);
- if (InRecovery()) {
- // PRR is used when in recovery.
- prr_.OnPacketAcked(acked_bytes);
- return;
- }
- MaybeIncreaseCwnd(acked_packet_number, bytes_in_flight);
- if (InSlowStart()) {
- hybrid_slow_start_.OnPacketAcked(acked_packet_number);
- }
-}
-
-void TcpCubicSender::OnPacketLost(QuicPacketNumber packet_number,
- QuicByteCount bytes_in_flight) {
- // TCP NewReno (RFC6582) says that once a loss occurs, any losses in packets
- // already sent should be treated as a single loss event, since it's expected.
- if (packet_number <= largest_sent_at_last_cutback_) {
- if (last_cutback_exited_slowstart_) {
- ++stats_->slowstart_packets_lost;
- if (slow_start_large_reduction_) {
- // Reduce congestion window by 1 for every loss.
- congestion_window_ =
- max(congestion_window_ - 1, min_congestion_window_);
- slowstart_threshold_ = congestion_window_;
- }
- }
- DVLOG(1) << "Ignoring loss for largest_missing:" << packet_number
- << " because it was sent prior to the last CWND cutback.";
- return;
- }
- ++stats_->tcp_loss_events;
- last_cutback_exited_slowstart_ = InSlowStart();
- if (InSlowStart()) {
- ++stats_->slowstart_packets_lost;
- }
-
- prr_.OnPacketLost(bytes_in_flight);
-
- // TODO(jri): Separate out all of slow start into a separate class.
- if (slow_start_large_reduction_ && InSlowStart()) {
- DCHECK_LT(1u, congestion_window_);
- congestion_window_ = congestion_window_ - 1;
- } else if (reno_) {
- congestion_window_ = congestion_window_ * RenoBeta();
- } else {
- congestion_window_ =
- cubic_.CongestionWindowAfterPacketLoss(congestion_window_);
- }
- // Enforce a minimum congestion window.
- if (congestion_window_ < min_congestion_window_) {
- congestion_window_ = min_congestion_window_;
- }
- slowstart_threshold_ = congestion_window_;
- largest_sent_at_last_cutback_ = largest_sent_packet_number_;
- // reset packet count from congestion avoidance mode. We start
- // counting again when we're out of recovery.
- congestion_window_count_ = 0;
- DVLOG(1) << "Incoming loss; congestion window: " << congestion_window_
- << " slowstart threshold: " << slowstart_threshold_;
-}
-
-bool TcpCubicSender::OnPacketSent(QuicTime /*sent_time*/,
- QuicByteCount /*bytes_in_flight*/,
- QuicPacketNumber packet_number,
- QuicByteCount bytes,
- HasRetransmittableData is_retransmittable) {
- if (InSlowStart()) {
- ++(stats_->slowstart_packets_sent);
- }
-
- // Only update bytes_in_flight_ for data packets.
- if (is_retransmittable != HAS_RETRANSMITTABLE_DATA) {
- return false;
- }
- if (InRecovery()) {
- // PRR is used when in recovery.
- prr_.OnPacketSent(bytes);
- }
- DCHECK_LT(largest_sent_packet_number_, packet_number);
- largest_sent_packet_number_ = packet_number;
- hybrid_slow_start_.OnPacketSent(packet_number);
- return true;
-}
-
-QuicTime::Delta TcpCubicSender::TimeUntilSend(
- QuicTime /* now */,
- QuicByteCount bytes_in_flight,
- HasRetransmittableData has_retransmittable_data) const {
- if (has_retransmittable_data == NO_RETRANSMITTABLE_DATA) {
- DCHECK(!FLAGS_quic_respect_send_alarm2);
- // For TCP we can always send an ACK immediately.
- return QuicTime::Delta::Zero();
- }
- if (InRecovery()) {
- // PRR is used when in recovery.
- return prr_.TimeUntilSend(GetCongestionWindow(), bytes_in_flight,
- slowstart_threshold_ * kDefaultTCPMSS);
- }
- if (GetCongestionWindow() > bytes_in_flight) {
- return QuicTime::Delta::Zero();
- }
- if (min4_mode_ && bytes_in_flight < 4 * kDefaultTCPMSS) {
- return QuicTime::Delta::Zero();
- }
- return QuicTime::Delta::Infinite();
-}
-
-QuicBandwidth TcpCubicSender::PacingRate() const {
- // We pace at twice the rate of the underlying sender's bandwidth estimate
- // during slow start and 1.25x during congestion avoidance to ensure pacing
- // doesn't prevent us from filling the window.
- QuicTime::Delta srtt = rtt_stats_->smoothed_rtt();
- if (srtt.IsZero()) {
- srtt = QuicTime::Delta::FromMicroseconds(rtt_stats_->initial_rtt_us());
- }
- const QuicBandwidth bandwidth =
- QuicBandwidth::FromBytesAndTimeDelta(GetCongestionWindow(), srtt);
- return bandwidth.Scale(InSlowStart() ? 2 : 1.25);
-}
-
-QuicBandwidth TcpCubicSender::BandwidthEstimate() const {
- QuicTime::Delta srtt = rtt_stats_->smoothed_rtt();
- if (srtt.IsZero()) {
- // If we haven't measured an rtt, the bandwidth estimate is unknown.
- return QuicBandwidth::Zero();
- }
- return QuicBandwidth::FromBytesAndTimeDelta(GetCongestionWindow(), srtt);
-}
-
-QuicTime::Delta TcpCubicSender::RetransmissionDelay() const {
- if (rtt_stats_->smoothed_rtt().IsZero()) {
- return QuicTime::Delta::Zero();
- }
- return rtt_stats_->smoothed_rtt().Add(
- rtt_stats_->mean_deviation().Multiply(4));
-}
-
-QuicByteCount TcpCubicSender::GetCongestionWindow() const {
- return congestion_window_ * kDefaultTCPMSS;
-}
-
-bool TcpCubicSender::InSlowStart() const {
- return congestion_window_ < slowstart_threshold_;
-}
-
-QuicByteCount TcpCubicSender::GetSlowStartThreshold() const {
- return slowstart_threshold_ * kDefaultTCPMSS;
-}
-
-bool TcpCubicSender::IsCwndLimited(QuicByteCount bytes_in_flight) const {
- const QuicByteCount congestion_window_bytes = GetCongestionWindow();
- if (bytes_in_flight >= congestion_window_bytes) {
- return true;
- }
- const QuicByteCount available_bytes =
- congestion_window_bytes - bytes_in_flight;
- const bool slow_start_limited =
- InSlowStart() && bytes_in_flight > congestion_window_bytes / 2;
- return slow_start_limited || available_bytes <= kMaxBurstBytes;
-}
-
-bool TcpCubicSender::InRecovery() const {
- return largest_acked_packet_number_ <= largest_sent_at_last_cutback_ &&
- largest_acked_packet_number_ != 0;
-}
-
-// Called when we receive an ack. Normal TCP tracks how many packets one ack
-// represents, but quic has a separate ack for each packet.
-void TcpCubicSender::MaybeIncreaseCwnd(QuicPacketNumber acked_packet_number,
- QuicByteCount bytes_in_flight) {
- QUIC_BUG_IF(InRecovery()) << "Never increase the CWND during recovery.";
- // Do not increase the congestion window unless the sender is close to using
- // the current window.
- if (!IsCwndLimited(bytes_in_flight)) {
- cubic_.OnApplicationLimited();
- return;
- }
- if (congestion_window_ >= max_tcp_congestion_window_) {
- return;
- }
- if (InSlowStart()) {
- // TCP slow start, exponential growth, increase by one for each ACK.
- ++congestion_window_;
- DVLOG(1) << "Slow start; congestion window: " << congestion_window_
- << " slowstart threshold: " << slowstart_threshold_;
- return;
- }
- // Congestion avoidance
- if (reno_) {
- // Classic Reno congestion avoidance.
- ++congestion_window_count_;
- // Divide by num_connections to smoothly increase the CWND at a faster
- // rate than conventional Reno.
- if (congestion_window_count_ * num_connections_ >= congestion_window_) {
- ++congestion_window_;
- congestion_window_count_ = 0;
- }
-
- DVLOG(1) << "Reno; congestion window: " << congestion_window_
- << " slowstart threshold: " << slowstart_threshold_
- << " congestion window count: " << congestion_window_count_;
- } else {
- congestion_window_ = min(max_tcp_congestion_window_,
- cubic_.CongestionWindowAfterAck(
- congestion_window_, rtt_stats_->min_rtt()));
- DVLOG(1) << "Cubic; congestion window: " << congestion_window_
- << " slowstart threshold: " << slowstart_threshold_;
- }
-}
-
-void TcpCubicSender::OnRetransmissionTimeout(bool packets_retransmitted) {
- largest_sent_at_last_cutback_ = 0;
- if (!packets_retransmitted) {
- return;
- }
- cubic_.Reset();
- hybrid_slow_start_.Restart();
- slowstart_threshold_ = congestion_window_ / 2;
- congestion_window_ = min_congestion_window_;
-}
-
-void TcpCubicSender::OnConnectionMigration() {
- hybrid_slow_start_.Restart();
- cubic_.Reset();
- prr_ = PrrSender();
- congestion_window_count_ = 0;
- largest_sent_packet_number_ = 0;
- largest_acked_packet_number_ = 0;
- largest_sent_at_last_cutback_ = 0;
- congestion_window_ = initial_tcp_congestion_window_;
- slowstart_threshold_ = initial_max_tcp_congestion_window_;
- last_cutback_exited_slowstart_ = false;
- max_tcp_congestion_window_ = initial_max_tcp_congestion_window_;
-}
-
-CongestionControlType TcpCubicSender::GetCongestionControlType() const {
- return reno_ ? kReno : kCubic;
-}
-
-} // namespace net
diff --git a/net/quic/congestion_control/tcp_cubic_sender.h b/net/quic/congestion_control/tcp_cubic_sender.h
deleted file mode 100644
index 9b253a3..0000000
--- a/net/quic/congestion_control/tcp_cubic_sender.h
+++ /dev/null
@@ -1,152 +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.
-//
-// TCP cubic send side congestion algorithm, emulates the behavior of TCP cubic.
-
-#ifndef NET_QUIC_CONGESTION_CONTROL_TCP_CUBIC_SENDER_H_
-#define NET_QUIC_CONGESTION_CONTROL_TCP_CUBIC_SENDER_H_
-
-#include <stdint.h>
-
-#include "base/compiler_specific.h"
-#include "base/macros.h"
-#include "net/base/net_export.h"
-#include "net/quic/congestion_control/cubic.h"
-#include "net/quic/congestion_control/hybrid_slow_start.h"
-#include "net/quic/congestion_control/prr_sender.h"
-#include "net/quic/congestion_control/send_algorithm_interface.h"
-#include "net/quic/quic_bandwidth.h"
-#include "net/quic/quic_connection_stats.h"
-#include "net/quic/quic_protocol.h"
-#include "net/quic/quic_time.h"
-
-namespace net {
-
-class RttStats;
-
-namespace test {
-class TcpCubicSenderPeer;
-} // namespace test
-
-class NET_EXPORT_PRIVATE TcpCubicSender : public SendAlgorithmInterface {
- public:
- // Reno option and max_tcp_congestion_window are provided for testing.
- TcpCubicSender(const QuicClock* clock,
- const RttStats* rtt_stats,
- bool reno,
- QuicPacketCount initial_tcp_congestion_window,
- QuicPacketCount max_tcp_congestion_window,
- QuicConnectionStats* stats);
- ~TcpCubicSender() override;
-
- // Start implementation of SendAlgorithmInterface.
- void SetFromConfig(const QuicConfig& config,
- Perspective perspective) override;
- void ResumeConnectionState(
- const CachedNetworkParameters& cached_network_params,
- bool max_bandwidth_resumption) override;
- void SetNumEmulatedConnections(int num_connections) override;
- void SetMaxCongestionWindow(QuicByteCount max_congestion_window) override;
- void OnCongestionEvent(bool rtt_updated,
- QuicByteCount bytes_in_flight,
- const CongestionVector& acked_packets,
- const CongestionVector& lost_packets) override;
- bool OnPacketSent(QuicTime sent_time,
- QuicByteCount bytes_in_flight,
- QuicPacketNumber packet_number,
- QuicByteCount bytes,
- HasRetransmittableData is_retransmittable) override;
- void OnRetransmissionTimeout(bool packets_retransmitted) override;
- void OnConnectionMigration() override;
- QuicTime::Delta TimeUntilSend(
- QuicTime now,
- QuicByteCount bytes_in_flight,
- HasRetransmittableData has_retransmittable_data) const override;
- QuicBandwidth PacingRate() const override;
- QuicBandwidth BandwidthEstimate() const override;
- QuicTime::Delta RetransmissionDelay() const override;
- QuicByteCount GetCongestionWindow() const override;
- bool InSlowStart() const override;
- bool InRecovery() const override;
- QuicByteCount GetSlowStartThreshold() const override;
- CongestionControlType GetCongestionControlType() const override;
- // End implementation of SendAlgorithmInterface.
-
- private:
- friend class test::TcpCubicSenderPeer;
-
- // Compute the TCP Reno beta based on the current number of connections.
- float RenoBeta() const;
-
- // TODO(ianswett): Remove these and migrate to OnCongestionEvent.
- void OnPacketAcked(QuicPacketNumber acked_packet_number,
- QuicByteCount acked_bytes,
- QuicByteCount bytes_in_flight);
- void OnPacketLost(QuicPacketNumber largest_loss,
- QuicByteCount bytes_in_flight);
-
- void MaybeIncreaseCwnd(QuicPacketNumber acked_packet_number,
- QuicByteCount bytes_in_flight);
- bool IsCwndLimited(QuicByteCount bytes_in_flight) const;
-
- HybridSlowStart hybrid_slow_start_;
- Cubic cubic_;
- PrrSender prr_;
- const RttStats* rtt_stats_;
- QuicConnectionStats* stats_;
-
- // If true, Reno congestion control is used instead of Cubic.
- const bool reno_;
-
- // Number of connections to simulate.
- uint32_t num_connections_;
-
- // ACK counter for the Reno implementation.
- uint64_t congestion_window_count_;
-
- // Track the largest packet that has been sent.
- QuicPacketNumber largest_sent_packet_number_;
-
- // Track the largest packet that has been acked.
- QuicPacketNumber largest_acked_packet_number_;
-
- // Track the largest packet number outstanding when a CWND cutback occurs.
- QuicPacketNumber largest_sent_at_last_cutback_;
-
- // Congestion window in packets.
- QuicPacketCount congestion_window_;
-
- // Minimum congestion window in packets.
- QuicPacketCount min_congestion_window_;
-
- // Whether to use 4 packets as the actual min, but pace lower.
- bool min4_mode_;
-
- // Slow start congestion window in packets, aka ssthresh.
- QuicPacketCount slowstart_threshold_;
-
- // Whether the last loss event caused us to exit slowstart.
- // Used for stats collection of slowstart_packets_lost
- bool last_cutback_exited_slowstart_;
-
- // Maximum number of outstanding packets for tcp.
- QuicPacketCount max_tcp_congestion_window_;
-
- // Initial TCP congestion window. This variable can only be set when this
- // algorithm is created.
- const QuicPacketCount initial_tcp_congestion_window_;
-
- // Initial maximum TCP congestion window. This variable can only be set when
- // this algorithm is created.
- const QuicPacketCount initial_max_tcp_congestion_window_;
-
- // When true, exit slow start with large cutback of congestion window.
- bool slow_start_large_reduction_;
-
- DISALLOW_COPY_AND_ASSIGN(TcpCubicSender);
-};
-
-} // namespace net
-
-#endif // NET_QUIC_CONGESTION_CONTROL_TCP_CUBIC_SENDER_H_
diff --git a/net/quic/congestion_control/tcp_cubic_sender_test.cc b/net/quic/congestion_control/tcp_cubic_sender_test.cc
deleted file mode 100644
index 13ae6c1..0000000
--- a/net/quic/congestion_control/tcp_cubic_sender_test.cc
+++ /dev/null
@@ -1,887 +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/congestion_control/tcp_cubic_sender.h"
-
-#include <algorithm>
-
-#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-#include "net/quic/congestion_control/rtt_stats.h"
-#include "net/quic/crypto/crypto_protocol.h"
-#include "net/quic/proto/cached_network_parameters.pb.h"
-#include "net/quic/quic_flags.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/quic_config_peer.h"
-#include "net/quic/test_tools/quic_test_utils.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using std::min;
-
-namespace net {
-namespace test {
-
-// TODO(ianswett): A number of theses tests were written with the assumption of
-// an initial CWND of 10. They have carefully calculated values which should be
-// updated to be based on kInitialCongestionWindow.
-const uint32_t kInitialCongestionWindowPackets = 10;
-const uint32_t kDefaultWindowTCP =
- kInitialCongestionWindowPackets * kDefaultTCPMSS;
-const float kRenoBeta = 0.7f; // Reno backoff factor.
-
-class TcpCubicSenderPeer : public TcpCubicSender {
- public:
- TcpCubicSenderPeer(const QuicClock* clock,
- bool reno,
- QuicPacketCount max_tcp_congestion_window)
- : TcpCubicSender(clock,
- &rtt_stats_,
- reno,
- kInitialCongestionWindowPackets,
- max_tcp_congestion_window,
- &stats_) {}
-
- QuicPacketCount congestion_window() { return congestion_window_; }
-
- QuicPacketCount slowstart_threshold() { return slowstart_threshold_; }
-
- const HybridSlowStart& hybrid_slow_start() const {
- return hybrid_slow_start_;
- }
-
- float GetRenoBeta() const { return RenoBeta(); }
-
- RttStats rtt_stats_;
- QuicConnectionStats stats_;
-};
-
-class TcpCubicSenderTest : public ::testing::Test {
- protected:
- TcpCubicSenderTest()
- : one_ms_(QuicTime::Delta::FromMilliseconds(1)),
- sender_(new TcpCubicSenderPeer(&clock_, true, kMaxCongestionWindow)),
- packet_number_(1),
- acked_packet_number_(0),
- bytes_in_flight_(0) {}
-
- int SendAvailableSendWindow() {
- // Send as long as TimeUntilSend returns Zero.
- int packets_sent = 0;
- bool can_send = sender_->TimeUntilSend(clock_.Now(), bytes_in_flight_,
- HAS_RETRANSMITTABLE_DATA)
- .IsZero();
- while (can_send) {
- sender_->OnPacketSent(clock_.Now(), bytes_in_flight_, packet_number_++,
- kDefaultTCPMSS, HAS_RETRANSMITTABLE_DATA);
- ++packets_sent;
- bytes_in_flight_ += kDefaultTCPMSS;
- can_send = sender_->TimeUntilSend(clock_.Now(), bytes_in_flight_,
- HAS_RETRANSMITTABLE_DATA)
- .IsZero();
- }
- return packets_sent;
- }
-
- // Normal is that TCP acks every other segment.
- void AckNPackets(int n) {
- sender_->rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(60),
- QuicTime::Delta::Zero(), clock_.Now());
- SendAlgorithmInterface::CongestionVector acked_packets;
- SendAlgorithmInterface::CongestionVector lost_packets;
- for (int i = 0; i < n; ++i) {
- ++acked_packet_number_;
- acked_packets.push_back(
- std::make_pair(acked_packet_number_, kDefaultTCPMSS));
- }
- sender_->OnCongestionEvent(true, bytes_in_flight_, acked_packets,
- lost_packets);
- bytes_in_flight_ -= n * kDefaultTCPMSS;
- clock_.AdvanceTime(one_ms_);
- }
-
- void LoseNPackets(int n) {
- SendAlgorithmInterface::CongestionVector acked_packets;
- SendAlgorithmInterface::CongestionVector lost_packets;
- for (int i = 0; i < n; ++i) {
- ++acked_packet_number_;
- lost_packets.push_back(
- std::make_pair(acked_packet_number_, kDefaultTCPMSS));
- }
- sender_->OnCongestionEvent(false, bytes_in_flight_, acked_packets,
- lost_packets);
- bytes_in_flight_ -= n * kDefaultTCPMSS;
- }
-
- // Does not increment acked_packet_number_.
- void LosePacket(QuicPacketNumber packet_number) {
- SendAlgorithmInterface::CongestionVector acked_packets;
- SendAlgorithmInterface::CongestionVector lost_packets;
- lost_packets.push_back(std::make_pair(packet_number, kDefaultTCPMSS));
- sender_->OnCongestionEvent(false, bytes_in_flight_, acked_packets,
- lost_packets);
- bytes_in_flight_ -= kDefaultTCPMSS;
- }
-
- const QuicTime::Delta one_ms_;
- MockClock clock_;
- scoped_ptr<TcpCubicSenderPeer> sender_;
- QuicPacketNumber packet_number_;
- QuicPacketNumber acked_packet_number_;
- QuicByteCount bytes_in_flight_;
-};
-
-TEST_F(TcpCubicSenderTest, SimpleSender) {
- // At startup make sure we are at the default.
- EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
- // At startup make sure we can send.
- EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0, HAS_RETRANSMITTABLE_DATA)
- .IsZero());
- // Make sure we can send.
- EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0, HAS_RETRANSMITTABLE_DATA)
- .IsZero());
- // And that window is un-affected.
- EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
-
- // Fill the send window with data, then verify that we can't send.
- SendAvailableSendWindow();
- EXPECT_FALSE(sender_->TimeUntilSend(clock_.Now(),
- sender_->GetCongestionWindow(),
- HAS_RETRANSMITTABLE_DATA)
- .IsZero());
-}
-
-TEST_F(TcpCubicSenderTest, ApplicationLimitedSlowStart) {
- // Send exactly 10 packets and ensure the CWND ends at 14 packets.
- const int kNumberOfAcks = 5;
- // At startup make sure we can send.
- EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0, HAS_RETRANSMITTABLE_DATA)
- .IsZero());
- // Make sure we can send.
- EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0, HAS_RETRANSMITTABLE_DATA)
- .IsZero());
-
- SendAvailableSendWindow();
- for (int i = 0; i < kNumberOfAcks; ++i) {
- AckNPackets(2);
- }
- QuicByteCount bytes_to_send = sender_->GetCongestionWindow();
- // It's expected 2 acks will arrive when the bytes_in_flight are greater than
- // half the CWND.
- EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * 2, bytes_to_send);
-}
-
-TEST_F(TcpCubicSenderTest, ExponentialSlowStart) {
- const int kNumberOfAcks = 20;
- // At startup make sure we can send.
- EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0, HAS_RETRANSMITTABLE_DATA)
- .IsZero());
- EXPECT_EQ(QuicBandwidth::Zero(), sender_->BandwidthEstimate());
- // Make sure we can send.
- EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0, HAS_RETRANSMITTABLE_DATA)
- .IsZero());
-
- for (int i = 0; i < kNumberOfAcks; ++i) {
- // Send our full send window.
- SendAvailableSendWindow();
- AckNPackets(2);
- }
- const QuicByteCount cwnd = sender_->GetCongestionWindow();
- EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * kNumberOfAcks, cwnd);
- EXPECT_EQ(QuicBandwidth::FromBytesAndTimeDelta(
- cwnd, sender_->rtt_stats_.smoothed_rtt()),
- sender_->BandwidthEstimate());
-}
-
-TEST_F(TcpCubicSenderTest, SlowStartPacketLoss) {
- sender_->SetNumEmulatedConnections(1);
- const int kNumberOfAcks = 10;
- for (int i = 0; i < kNumberOfAcks; ++i) {
- // Send our full send window.
- SendAvailableSendWindow();
- AckNPackets(2);
- }
- SendAvailableSendWindow();
- QuicByteCount expected_send_window =
- kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Lose a packet to exit slow start.
- LoseNPackets(1);
- size_t packets_in_recovery_window = expected_send_window / kDefaultTCPMSS;
-
- // We should now have fallen out of slow start with a reduced window.
- expected_send_window *= kRenoBeta;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Recovery phase. We need to ack every packet in the recovery window before
- // we exit recovery.
- size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS;
- DVLOG(1) << "number_packets: " << number_of_packets_in_window;
- AckNPackets(packets_in_recovery_window);
- SendAvailableSendWindow();
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // We need to ack an entire window before we increase CWND by 1.
- AckNPackets(number_of_packets_in_window - 2);
- SendAvailableSendWindow();
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Next ack should increase cwnd by 1.
- AckNPackets(1);
- expected_send_window += kDefaultTCPMSS;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Now RTO and ensure slow start gets reset.
- EXPECT_TRUE(sender_->hybrid_slow_start().started());
- sender_->OnRetransmissionTimeout(true);
- EXPECT_FALSE(sender_->hybrid_slow_start().started());
-}
-
-TEST_F(TcpCubicSenderTest, SlowStartPacketLossWithLargeReduction) {
- QuicConfig config;
- QuicTagVector options;
- options.push_back(kSSLR);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- sender_->SetFromConfig(config, Perspective::IS_SERVER);
-
- sender_->SetNumEmulatedConnections(1);
- const int kNumberOfAcks = 10;
- for (int i = 0; i < kNumberOfAcks; ++i) {
- // Send our full send window.
- SendAvailableSendWindow();
- AckNPackets(2);
- }
- SendAvailableSendWindow();
- QuicByteCount expected_send_window =
- kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Lose a packet to exit slow start. We should now have fallen out of
- // slow start with a window reduced by 1.
- LoseNPackets(1);
- expected_send_window -= kDefaultTCPMSS;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Lose 5 packets in recovery and verify that congestion window is reduced
- // further.
- LoseNPackets(5);
- expected_send_window -= 5 * kDefaultTCPMSS;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- size_t packets_in_recovery_window = expected_send_window / kDefaultTCPMSS;
-
- // Recovery phase. We need to ack every packet in the recovery window before
- // we exit recovery.
- size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS;
- DVLOG(1) << "number_packets: " << number_of_packets_in_window;
- AckNPackets(packets_in_recovery_window);
- SendAvailableSendWindow();
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // We need to ack the rest of the window before cwnd increases by 1.
- AckNPackets(number_of_packets_in_window - 1);
- SendAvailableSendWindow();
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Next ack should increase cwnd by 1.
- AckNPackets(1);
- expected_send_window += kDefaultTCPMSS;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Now RTO and ensure slow start gets reset.
- EXPECT_TRUE(sender_->hybrid_slow_start().started());
- sender_->OnRetransmissionTimeout(true);
- EXPECT_FALSE(sender_->hybrid_slow_start().started());
-}
-
-TEST_F(TcpCubicSenderTest, NoPRRWhenLessThanOnePacketInFlight) {
- SendAvailableSendWindow();
- LoseNPackets(kInitialCongestionWindowPackets - 1);
- AckNPackets(1);
- // PRR will allow 2 packets for every ack during recovery.
- EXPECT_EQ(2, SendAvailableSendWindow());
- // Simulate abandoning all packets by supplying a bytes_in_flight of 0.
- // PRR should now allow a packet to be sent, even though prr's state
- // variables believe it has sent enough packets.
- EXPECT_EQ(QuicTime::Delta::Zero(),
- sender_->TimeUntilSend(clock_.Now(), 0, HAS_RETRANSMITTABLE_DATA));
-}
-
-TEST_F(TcpCubicSenderTest, SlowStartPacketLossPRR) {
- sender_->SetNumEmulatedConnections(1);
- // Test based on the first example in RFC6937.
- // Ack 10 packets in 5 acks to raise the CWND to 20, as in the example.
- const int kNumberOfAcks = 5;
- for (int i = 0; i < kNumberOfAcks; ++i) {
- // Send our full send window.
- SendAvailableSendWindow();
- AckNPackets(2);
- }
- SendAvailableSendWindow();
- QuicByteCount expected_send_window =
- kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- LoseNPackets(1);
-
- // We should now have fallen out of slow start with a reduced window.
- size_t send_window_before_loss = expected_send_window;
- expected_send_window *= kRenoBeta;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Testing TCP proportional rate reduction.
- // We should send packets paced over the received acks for the remaining
- // outstanding packets. The number of packets before we exit recovery is the
- // original CWND minus the packet that has been lost and the one which
- // triggered the loss.
- size_t remaining_packets_in_recovery =
- send_window_before_loss / kDefaultTCPMSS - 2;
-
- for (size_t i = 0; i < remaining_packets_in_recovery; ++i) {
- AckNPackets(1);
- SendAvailableSendWindow();
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
- }
-
- // We need to ack another window before we increase CWND by 1.
- size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS;
- for (size_t i = 0; i < number_of_packets_in_window; ++i) {
- AckNPackets(1);
- EXPECT_EQ(1, SendAvailableSendWindow());
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
- }
-
- AckNPackets(1);
- expected_send_window += kDefaultTCPMSS;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicSenderTest, SlowStartBurstPacketLossPRR) {
- sender_->SetNumEmulatedConnections(1);
- // Test based on the second example in RFC6937, though we also implement
- // forward acknowledgements, so the first two incoming acks will trigger
- // PRR immediately.
- // Ack 20 packets in 10 acks to raise the CWND to 30.
- const int kNumberOfAcks = 10;
- for (int i = 0; i < kNumberOfAcks; ++i) {
- // Send our full send window.
- SendAvailableSendWindow();
- AckNPackets(2);
- }
- SendAvailableSendWindow();
- QuicByteCount expected_send_window =
- kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Lose one more than the congestion window reduction, so that after loss,
- // bytes_in_flight is lesser than the congestion window.
- size_t send_window_after_loss = kRenoBeta * expected_send_window;
- size_t num_packets_to_lose =
- (expected_send_window - send_window_after_loss) / kDefaultTCPMSS + 1;
- LoseNPackets(num_packets_to_lose);
- // Immediately after the loss, ensure at least one packet can be sent.
- // Losses without subsequent acks can occur with timer based loss detection.
- EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), bytes_in_flight_,
- HAS_RETRANSMITTABLE_DATA)
- .IsZero());
- AckNPackets(1);
-
- // We should now have fallen out of slow start with a reduced window.
- expected_send_window *= kRenoBeta;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Only 2 packets should be allowed to be sent, per PRR-SSRB
- EXPECT_EQ(2, SendAvailableSendWindow());
-
- // Ack the next packet, which triggers another loss.
- LoseNPackets(1);
- AckNPackets(1);
-
- // Send 2 packets to simulate PRR-SSRB.
- EXPECT_EQ(2, SendAvailableSendWindow());
-
- // Ack the next packet, which triggers another loss.
- LoseNPackets(1);
- AckNPackets(1);
-
- // Send 2 packets to simulate PRR-SSRB.
- EXPECT_EQ(2, SendAvailableSendWindow());
-
- // Exit recovery and return to sending at the new rate.
- for (int i = 0; i < kNumberOfAcks; ++i) {
- AckNPackets(1);
- EXPECT_EQ(1, SendAvailableSendWindow());
- }
-}
-
-TEST_F(TcpCubicSenderTest, RTOCongestionWindow) {
- EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
- EXPECT_EQ(kMaxCongestionWindow, sender_->slowstart_threshold());
-
- // Expect the window to decrease to the minimum once the RTO fires
- // and slow start threshold to be set to 1/2 of the CWND.
- sender_->OnRetransmissionTimeout(true);
- EXPECT_EQ(2 * kDefaultTCPMSS, sender_->GetCongestionWindow());
- EXPECT_EQ(5u, sender_->slowstart_threshold());
-}
-
-TEST_F(TcpCubicSenderTest, RTOCongestionWindowNoRetransmission) {
- EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
-
- // Expect the window to remain unchanged if the RTO fires but no
- // packets are retransmitted.
- sender_->OnRetransmissionTimeout(false);
- EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicSenderTest, RetransmissionDelay) {
- const int64_t kRttMs = 10;
- const int64_t kDeviationMs = 3;
- EXPECT_EQ(QuicTime::Delta::Zero(), sender_->RetransmissionDelay());
-
- sender_->rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(kRttMs),
- QuicTime::Delta::Zero(), clock_.Now());
-
- // 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 finally the
- // smoothed rtt is added which is the initial 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_->rtt_stats_.UpdateRtt(
- QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs),
- QuicTime::Delta::Zero(), clock_.Now());
- sender_->rtt_stats_.UpdateRtt(
- QuicTime::Delta::FromMilliseconds(kRttMs - kDeviationMs),
- QuicTime::Delta::Zero(), clock_.Now());
- }
- expected_delay = QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs * 4);
-
- EXPECT_NEAR(kRttMs, sender_->rtt_stats_.smoothed_rtt().ToMilliseconds(), 1);
- EXPECT_NEAR(expected_delay.ToMilliseconds(),
- sender_->RetransmissionDelay().ToMilliseconds(), 1);
- EXPECT_EQ(static_cast<int64_t>(
- sender_->GetCongestionWindow() * kNumMicrosPerSecond /
- sender_->rtt_stats_.smoothed_rtt().ToMicroseconds()),
- sender_->BandwidthEstimate().ToBytesPerSecond());
-}
-
-TEST_F(TcpCubicSenderTest, SlowStartMaxSendWindow) {
- const QuicPacketCount kMaxCongestionWindowTCP = 50;
- const int kNumberOfAcks = 100;
- sender_.reset(
- new TcpCubicSenderPeer(&clock_, false, kMaxCongestionWindowTCP));
-
- for (int i = 0; i < kNumberOfAcks; ++i) {
- // Send our full send window.
- SendAvailableSendWindow();
- AckNPackets(2);
- }
- QuicByteCount expected_send_window = kMaxCongestionWindowTCP * kDefaultTCPMSS;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicSenderTest, TcpRenoMaxCongestionWindow) {
- const QuicPacketCount kMaxCongestionWindowTCP = 50;
- const int kNumberOfAcks = 1000;
- sender_.reset(new TcpCubicSenderPeer(&clock_, true, kMaxCongestionWindowTCP));
-
- SendAvailableSendWindow();
- AckNPackets(2);
- // Make sure we fall out of slow start.
- LoseNPackets(1);
-
- for (int i = 0; i < kNumberOfAcks; ++i) {
- // Send our full send window.
- SendAvailableSendWindow();
- AckNPackets(2);
- }
-
- QuicByteCount expected_send_window = kMaxCongestionWindowTCP * kDefaultTCPMSS;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicSenderTest, TcpCubicMaxCongestionWindow) {
- const QuicPacketCount kMaxCongestionWindowTCP = 50;
- // Set to 10000 to compensate for small cubic alpha.
- const int kNumberOfAcks = 10000;
-
- sender_.reset(
- new TcpCubicSenderPeer(&clock_, false, kMaxCongestionWindowTCP));
-
- SendAvailableSendWindow();
- AckNPackets(2);
- // Make sure we fall out of slow start.
- LoseNPackets(1);
-
- for (int i = 0; i < kNumberOfAcks; ++i) {
- // Send our full send window.
- SendAvailableSendWindow();
- AckNPackets(2);
- }
-
- QuicByteCount expected_send_window = kMaxCongestionWindowTCP * kDefaultTCPMSS;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicSenderTest, TcpCubicResetEpochOnQuiescence) {
- const int kMaxCongestionWindow = 50;
- const QuicByteCount kMaxCongestionWindowBytes =
- kMaxCongestionWindow * kDefaultTCPMSS;
- sender_.reset(new TcpCubicSenderPeer(&clock_, false, kMaxCongestionWindow));
-
- int num_sent = SendAvailableSendWindow();
-
- // Make sure we fall out of slow start.
- QuicByteCount saved_cwnd = sender_->GetCongestionWindow();
- LoseNPackets(1);
- EXPECT_GT(saved_cwnd, sender_->GetCongestionWindow());
-
- // Ack the rest of the outstanding packets to get out of recovery.
- for (int i = 1; i < num_sent; ++i) {
- AckNPackets(1);
- }
- EXPECT_EQ(0u, bytes_in_flight_);
-
- // Send a new window of data and ack all; cubic growth should occur.
- saved_cwnd = sender_->GetCongestionWindow();
- num_sent = SendAvailableSendWindow();
- for (int i = 0; i < num_sent; ++i) {
- AckNPackets(1);
- }
- EXPECT_LT(saved_cwnd, sender_->GetCongestionWindow());
- EXPECT_GT(kMaxCongestionWindowBytes, sender_->GetCongestionWindow());
- EXPECT_EQ(0u, bytes_in_flight_);
-
- // Quiescent time of 100 seconds
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100000));
-
- // Send new window of data and ack one packet. Cubic epoch should have
- // been reset; ensure cwnd increase is not dramatic.
- saved_cwnd = sender_->GetCongestionWindow();
- SendAvailableSendWindow();
- AckNPackets(1);
- EXPECT_NEAR(saved_cwnd, sender_->GetCongestionWindow(), kDefaultTCPMSS);
- EXPECT_GT(kMaxCongestionWindowBytes, sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicSenderTest, TcpCubicShiftedEpochOnQuiescence) {
- ValueRestore<bool> old_flag(&FLAGS_shift_quic_cubic_epoch_when_app_limited,
- true);
- const int kMaxCongestionWindow = 50;
- const QuicByteCount kMaxCongestionWindowBytes =
- kMaxCongestionWindow * kDefaultTCPMSS;
- sender_.reset(new TcpCubicSenderPeer(&clock_, false, kMaxCongestionWindow));
-
- int num_sent = SendAvailableSendWindow();
-
- // Make sure we fall out of slow start.
- QuicByteCount saved_cwnd = sender_->GetCongestionWindow();
- LoseNPackets(1);
- EXPECT_GT(saved_cwnd, sender_->GetCongestionWindow());
-
- // Ack the rest of the outstanding packets to get out of recovery.
- for (int i = 1; i < num_sent; ++i) {
- AckNPackets(1);
- }
- EXPECT_EQ(0u, bytes_in_flight_);
-
- // Send a new window of data and ack all; cubic growth should occur.
- saved_cwnd = sender_->GetCongestionWindow();
- num_sent = SendAvailableSendWindow();
- for (int i = 0; i < num_sent; ++i) {
- AckNPackets(1);
- }
- EXPECT_LT(saved_cwnd, sender_->GetCongestionWindow());
- EXPECT_GT(kMaxCongestionWindowBytes, sender_->GetCongestionWindow());
- EXPECT_EQ(0u, bytes_in_flight_);
-
- // Quiescent time of 100 seconds
- clock_.AdvanceTime(QuicTime::Delta::FromSeconds(100));
-
- // Send new window of data and ack one packet. Cubic epoch should have
- // been reset; ensure cwnd increase is not dramatic.
- saved_cwnd = sender_->GetCongestionWindow();
- SendAvailableSendWindow();
- AckNPackets(1);
- EXPECT_NEAR(saved_cwnd, sender_->GetCongestionWindow(), kDefaultTCPMSS);
- EXPECT_GT(kMaxCongestionWindowBytes, sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicSenderTest, MultipleLossesInOneWindow) {
- SendAvailableSendWindow();
- const QuicByteCount initial_window = sender_->GetCongestionWindow();
- LosePacket(acked_packet_number_ + 1);
- const QuicByteCount post_loss_window = sender_->GetCongestionWindow();
- EXPECT_GT(initial_window, post_loss_window);
- LosePacket(acked_packet_number_ + 3);
- EXPECT_EQ(post_loss_window, sender_->GetCongestionWindow());
- LosePacket(packet_number_ - 1);
- EXPECT_EQ(post_loss_window, sender_->GetCongestionWindow());
-
- // Lose a later packet and ensure the window decreases.
- LosePacket(packet_number_);
- EXPECT_GT(post_loss_window, sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicSenderTest, DontTrackAckPackets) {
- // Send a packet with no retransmittable data, and ensure it's not tracked.
- EXPECT_FALSE(sender_->OnPacketSent(clock_.Now(), bytes_in_flight_,
- packet_number_++, kDefaultTCPMSS,
- NO_RETRANSMITTABLE_DATA));
-
- // Send a data packet with retransmittable data, and ensure it is tracked.
- EXPECT_TRUE(sender_->OnPacketSent(clock_.Now(), bytes_in_flight_,
- packet_number_++, kDefaultTCPMSS,
- HAS_RETRANSMITTABLE_DATA));
-}
-
-TEST_F(TcpCubicSenderTest, ConfigureInitialWindow) {
- QuicConfig config;
-
- QuicTagVector options;
- options.push_back(kIW03);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- sender_->SetFromConfig(config, Perspective::IS_SERVER);
- EXPECT_EQ(3u, sender_->congestion_window());
-
- options.clear();
- options.push_back(kIW10);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- sender_->SetFromConfig(config, Perspective::IS_SERVER);
- EXPECT_EQ(10u, sender_->congestion_window());
-
- options.clear();
- options.push_back(kIW20);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- sender_->SetFromConfig(config, Perspective::IS_SERVER);
- EXPECT_EQ(20u, sender_->congestion_window());
-
- options.clear();
- options.push_back(kIW50);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- sender_->SetFromConfig(config, Perspective::IS_SERVER);
- EXPECT_EQ(50u, sender_->congestion_window());
-}
-
-TEST_F(TcpCubicSenderTest, ConfigureMinimumWindow) {
- QuicConfig config;
-
- // Verify that kCOPT: kMIN1 forces the min CWND to 1 packet.
- QuicTagVector options;
- options.push_back(kMIN1);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- sender_->SetFromConfig(config, Perspective::IS_SERVER);
- sender_->OnRetransmissionTimeout(true);
- EXPECT_EQ(1u, sender_->congestion_window());
-}
-
-TEST_F(TcpCubicSenderTest, 2ConnectionCongestionAvoidanceAtEndOfRecovery) {
- sender_->SetNumEmulatedConnections(2);
- // Ack 10 packets in 5 acks to raise the CWND to 20.
- const int kNumberOfAcks = 5;
- for (int i = 0; i < kNumberOfAcks; ++i) {
- // Send our full send window.
- SendAvailableSendWindow();
- AckNPackets(2);
- }
- SendAvailableSendWindow();
- QuicByteCount expected_send_window =
- kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- LoseNPackets(1);
-
- // We should now have fallen out of slow start with a reduced window.
- expected_send_window = expected_send_window * sender_->GetRenoBeta();
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // No congestion window growth should occur in recovery phase, i.e., until the
- // currently outstanding 20 packets are acked.
- for (int i = 0; i < 10; ++i) {
- // Send our full send window.
- SendAvailableSendWindow();
- EXPECT_TRUE(sender_->InRecovery());
- AckNPackets(2);
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
- }
- EXPECT_FALSE(sender_->InRecovery());
-
- // Out of recovery now. Congestion window should not grow for half an RTT.
- size_t packets_in_send_window = expected_send_window / kDefaultTCPMSS;
- SendAvailableSendWindow();
- AckNPackets(packets_in_send_window / 2 - 2);
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Next ack should increase congestion window by 1MSS.
- SendAvailableSendWindow();
- AckNPackets(2);
- expected_send_window += kDefaultTCPMSS;
- packets_in_send_window += 1;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Congestion window should remain steady again for half an RTT.
- SendAvailableSendWindow();
- AckNPackets(packets_in_send_window / 2 - 1);
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Next ack should cause congestion window to grow by 1MSS.
- SendAvailableSendWindow();
- AckNPackets(2);
- expected_send_window += kDefaultTCPMSS;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicSenderTest, 1ConnectionCongestionAvoidanceAtEndOfRecovery) {
- sender_->SetNumEmulatedConnections(1);
- // Ack 10 packets in 5 acks to raise the CWND to 20.
- const int kNumberOfAcks = 5;
- for (int i = 0; i < kNumberOfAcks; ++i) {
- // Send our full send window.
- SendAvailableSendWindow();
- AckNPackets(2);
- }
- SendAvailableSendWindow();
- QuicByteCount expected_send_window =
- kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- LoseNPackets(1);
-
- // We should now have fallen out of slow start with a reduced window.
- expected_send_window *= kRenoBeta;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // No congestion window growth should occur in recovery phase, i.e., until the
- // currently outstanding 20 packets are acked.
- for (int i = 0; i < 10; ++i) {
- // Send our full send window.
- SendAvailableSendWindow();
- EXPECT_TRUE(sender_->InRecovery());
- AckNPackets(2);
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
- }
- EXPECT_FALSE(sender_->InRecovery());
-
- // Out of recovery now. Congestion window should not grow during RTT.
- for (uint64_t i = 0; i < expected_send_window / kDefaultTCPMSS - 2; i += 2) {
- // Send our full send window.
- SendAvailableSendWindow();
- AckNPackets(2);
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
- }
-
- // Next ack should cause congestion window to grow by 1MSS.
- SendAvailableSendWindow();
- AckNPackets(2);
- expected_send_window += kDefaultTCPMSS;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicSenderTest, BandwidthResumption) {
- // Test that when provided with CachedNetworkParameters and opted in to the
- // bandwidth resumption experiment, that the TcpCubicSender sets initial CWND
- // appropriately.
-
- // Set some common values.
- CachedNetworkParameters cached_network_params;
- const QuicPacketCount kNumberOfPackets = 123;
- const int kBandwidthEstimateBytesPerSecond =
- kNumberOfPackets * kDefaultTCPMSS;
- cached_network_params.set_bandwidth_estimate_bytes_per_second(
- kBandwidthEstimateBytesPerSecond);
- cached_network_params.set_min_rtt_ms(1000);
-
- // Make sure that a bandwidth estimate results in a changed CWND.
- cached_network_params.set_timestamp(clock_.WallNow().ToUNIXSeconds() -
- (kNumSecondsPerHour - 1));
- sender_->ResumeConnectionState(cached_network_params, false);
- EXPECT_EQ(kNumberOfPackets, sender_->congestion_window());
-
- // Resumed CWND is limited to be in a sensible range.
- cached_network_params.set_bandwidth_estimate_bytes_per_second(
- (kMaxCongestionWindow + 1) * kDefaultTCPMSS);
- sender_->ResumeConnectionState(cached_network_params, false);
- EXPECT_EQ(kMaxCongestionWindow, sender_->congestion_window());
-
- cached_network_params.set_bandwidth_estimate_bytes_per_second(
- (kMinCongestionWindowForBandwidthResumption - 1) * kDefaultTCPMSS);
- sender_->ResumeConnectionState(cached_network_params, false);
- EXPECT_EQ(kMinCongestionWindowForBandwidthResumption,
- sender_->congestion_window());
-
- // Resume to the max value.
- cached_network_params.set_max_bandwidth_estimate_bytes_per_second(
- (kMinCongestionWindowForBandwidthResumption + 10) * kDefaultTCPMSS);
- sender_->ResumeConnectionState(cached_network_params, true);
- EXPECT_EQ((kMinCongestionWindowForBandwidthResumption + 10) * kDefaultTCPMSS,
- sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicSenderTest, PaceBelowCWND) {
- QuicConfig config;
-
- // Verify that kCOPT: kMIN4 forces the min CWND to 1 packet, but allows up
- // to 4 to be sent.
- QuicTagVector options;
- options.push_back(kMIN4);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- sender_->SetFromConfig(config, Perspective::IS_SERVER);
- sender_->OnRetransmissionTimeout(true);
- EXPECT_EQ(1u, sender_->congestion_window());
- EXPECT_TRUE(sender_->TimeUntilSend(QuicTime::Zero(), kDefaultTCPMSS,
- HAS_RETRANSMITTABLE_DATA)
- .IsZero());
- EXPECT_TRUE(sender_->TimeUntilSend(QuicTime::Zero(), 2 * kDefaultTCPMSS,
- HAS_RETRANSMITTABLE_DATA)
- .IsZero());
- EXPECT_TRUE(sender_->TimeUntilSend(QuicTime::Zero(), 3 * kDefaultTCPMSS,
- HAS_RETRANSMITTABLE_DATA)
- .IsZero());
- EXPECT_FALSE(sender_->TimeUntilSend(QuicTime::Zero(), 4 * kDefaultTCPMSS,
- HAS_RETRANSMITTABLE_DATA)
- .IsZero());
-}
-
-TEST_F(TcpCubicSenderTest, ResetAfterConnectionMigration) {
- EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
- EXPECT_EQ(kMaxCongestionWindow, sender_->slowstart_threshold());
-
- // Starts with slow start.
- sender_->SetNumEmulatedConnections(1);
- const int kNumberOfAcks = 10;
- for (int i = 0; i < kNumberOfAcks; ++i) {
- // Send our full send window.
- SendAvailableSendWindow();
- AckNPackets(2);
- }
- SendAvailableSendWindow();
- QuicByteCount expected_send_window =
- kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
- // Loses a packet to exit slow start.
- LoseNPackets(1);
-
- // We should now have fallen out of slow start with a reduced window. Slow
- // start threshold is also updated.
- expected_send_window *= kRenoBeta;
- EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
- EXPECT_EQ(expected_send_window / kDefaultTCPMSS,
- sender_->slowstart_threshold());
-
- // Resets cwnd and slow start threshold on connection migrations.
- sender_->OnConnectionMigration();
- EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
- EXPECT_EQ(kMaxCongestionWindow, sender_->slowstart_threshold());
- EXPECT_FALSE(sender_->hybrid_slow_start().started());
-}
-
-} // namespace test
-} // namespace net
diff --git a/net/quic/crypto/aead_base_decrypter.h b/net/quic/crypto/aead_base_decrypter.h
index edd110b..c76f11f 100644
--- a/net/quic/crypto/aead_base_decrypter.h
+++ b/net/quic/crypto/aead_base_decrypter.h
@@ -40,8 +40,8 @@ class NET_EXPORT_PRIVATE AeadBaseDecrypter : public QuicDecrypter {
bool SetNoncePrefix(base::StringPiece nonce_prefix) override;
bool DecryptPacket(QuicPathId path_id,
QuicPacketNumber packet_number,
- const base::StringPiece& associated_data,
- const base::StringPiece& ciphertext,
+ base::StringPiece associated_data,
+ base::StringPiece ciphertext,
char* output,
size_t* output_length,
size_t max_output_length) override;
@@ -65,7 +65,7 @@ class NET_EXPORT_PRIVATE AeadBaseDecrypter : public QuicDecrypter {
};
virtual void FillAeadParams(base::StringPiece nonce,
- const base::StringPiece& associated_data,
+ base::StringPiece associated_data,
size_t auth_tag_size,
AeadParams* aead_params) const = 0;
#endif // !defined(USE_OPENSSL)
diff --git a/net/quic/crypto/aead_base_decrypter_nss.cc b/net/quic/crypto/aead_base_decrypter_nss.cc
index 26e72ee..46228cc 100644
--- a/net/quic/crypto/aead_base_decrypter_nss.cc
+++ b/net/quic/crypto/aead_base_decrypter_nss.cc
@@ -49,8 +49,8 @@ bool AeadBaseDecrypter::SetNoncePrefix(StringPiece nonce_prefix) {
bool AeadBaseDecrypter::DecryptPacket(QuicPathId path_id,
QuicPacketNumber packet_number,
- const StringPiece& associated_data,
- const StringPiece& ciphertext,
+ StringPiece associated_data,
+ StringPiece ciphertext,
char* output,
size_t* output_length,
size_t max_output_length) {
diff --git a/net/quic/crypto/aead_base_decrypter_openssl.cc b/net/quic/crypto/aead_base_decrypter_openssl.cc
index 512b804..097cb4f 100644
--- a/net/quic/crypto/aead_base_decrypter_openssl.cc
+++ b/net/quic/crypto/aead_base_decrypter_openssl.cc
@@ -81,8 +81,8 @@ bool AeadBaseDecrypter::SetNoncePrefix(StringPiece nonce_prefix) {
bool AeadBaseDecrypter::DecryptPacket(QuicPathId path_id,
QuicPacketNumber packet_number,
- const StringPiece& associated_data,
- const StringPiece& ciphertext,
+ StringPiece associated_data,
+ StringPiece ciphertext,
char* output,
size_t* output_length,
size_t max_output_length) {
diff --git a/net/quic/crypto/aes_128_gcm_12_decrypter.h b/net/quic/crypto/aes_128_gcm_12_decrypter.h
index d0d305a..f8b1196 100644
--- a/net/quic/crypto/aes_128_gcm_12_decrypter.h
+++ b/net/quic/crypto/aes_128_gcm_12_decrypter.h
@@ -33,7 +33,7 @@ class NET_EXPORT_PRIVATE Aes128Gcm12Decrypter : public AeadBaseDecrypter {
protected:
// AeadBaseDecrypter methods:
void FillAeadParams(base::StringPiece nonce,
- const base::StringPiece& associated_data,
+ base::StringPiece associated_data,
size_t auth_tag_size,
AeadParams* aead_params) const override;
#endif
diff --git a/net/quic/crypto/aes_128_gcm_12_decrypter_nss.cc b/net/quic/crypto/aes_128_gcm_12_decrypter_nss.cc
index abbc565..d4480f4 100644
--- a/net/quic/crypto/aes_128_gcm_12_decrypter_nss.cc
+++ b/net/quic/crypto/aes_128_gcm_12_decrypter_nss.cc
@@ -28,7 +28,7 @@ Aes128Gcm12Decrypter::Aes128Gcm12Decrypter()
Aes128Gcm12Decrypter::~Aes128Gcm12Decrypter() {}
void Aes128Gcm12Decrypter::FillAeadParams(StringPiece nonce,
- const StringPiece& associated_data,
+ StringPiece associated_data,
size_t auth_tag_size,
AeadParams* aead_params) const {
aead_params->len = sizeof(aead_params->data.gcm_params);
diff --git a/net/quic/crypto/chacha20_poly1305_decrypter.h b/net/quic/crypto/chacha20_poly1305_decrypter.h
index fad9bbb..1e0fd05 100644
--- a/net/quic/crypto/chacha20_poly1305_decrypter.h
+++ b/net/quic/crypto/chacha20_poly1305_decrypter.h
@@ -34,7 +34,7 @@ class NET_EXPORT_PRIVATE ChaCha20Poly1305Decrypter : public AeadBaseDecrypter {
protected:
// AeadBaseDecrypter methods:
void FillAeadParams(base::StringPiece nonce,
- const base::StringPiece& associated_data,
+ base::StringPiece associated_data,
size_t auth_tag_size,
AeadParams* aead_params) const override;
#endif
diff --git a/net/quic/crypto/chacha20_poly1305_decrypter_nss.cc b/net/quic/crypto/chacha20_poly1305_decrypter_nss.cc
index 893f8a7..aeff43a 100644
--- a/net/quic/crypto/chacha20_poly1305_decrypter_nss.cc
+++ b/net/quic/crypto/chacha20_poly1305_decrypter_nss.cc
@@ -29,11 +29,10 @@ ChaCha20Poly1305Decrypter::ChaCha20Poly1305Decrypter()
ChaCha20Poly1305Decrypter::~ChaCha20Poly1305Decrypter() {}
-void ChaCha20Poly1305Decrypter::FillAeadParams(
- StringPiece nonce,
- const StringPiece& associated_data,
- size_t auth_tag_size,
- AeadParams* aead_params) const {
+void ChaCha20Poly1305Decrypter::FillAeadParams(StringPiece nonce,
+ StringPiece associated_data,
+ size_t auth_tag_size,
+ AeadParams* aead_params) const {
aead_params->len = sizeof(aead_params->data.nss_aead_params);
CK_NSS_AEAD_PARAMS* nss_aead_params = &aead_params->data.nss_aead_params;
nss_aead_params->pIv =
diff --git a/net/quic/crypto/chacha20_poly1305_rfc7539_decrypter.h b/net/quic/crypto/chacha20_poly1305_rfc7539_decrypter.h
index 3889216..57609d0 100644
--- a/net/quic/crypto/chacha20_poly1305_rfc7539_decrypter.h
+++ b/net/quic/crypto/chacha20_poly1305_rfc7539_decrypter.h
@@ -42,7 +42,7 @@ class NET_EXPORT_PRIVATE ChaCha20Poly1305Rfc7539Decrypter
protected:
// AeadBaseDecrypter methods:
void FillAeadParams(base::StringPiece nonce,
- const base::StringPiece& associated_data,
+ base::StringPiece associated_data,
size_t auth_tag_size,
AeadParams* aead_params) const override;
#endif
diff --git a/net/quic/crypto/chacha20_poly1305_rfc7539_decrypter_nss.cc b/net/quic/crypto/chacha20_poly1305_rfc7539_decrypter_nss.cc
index 8c830e9..799a2c5 100644
--- a/net/quic/crypto/chacha20_poly1305_rfc7539_decrypter_nss.cc
+++ b/net/quic/crypto/chacha20_poly1305_rfc7539_decrypter_nss.cc
@@ -43,7 +43,7 @@ uint32_t ChaCha20Poly1305Rfc7539Decrypter::cipher_id() const {
void ChaCha20Poly1305Rfc7539Decrypter::FillAeadParams(
base::StringPiece nonce,
- const base::StringPiece& associated_data,
+ base::StringPiece associated_data,
size_t auth_tag_size,
AeadParams* aead_params) const {}
diff --git a/net/quic/crypto/crypto_protocol.h b/net/quic/crypto/crypto_protocol.h
index 5d2f71f..14d3fab 100644
--- a/net/quic/crypto/crypto_protocol.h
+++ b/net/quic/crypto/crypto_protocol.h
@@ -89,6 +89,8 @@ const QuicTag kMIN4 = TAG('M', 'I', 'N', '4'); // Min CWND of 4 packets,
const QuicTag kTLPR = TAG('T', 'L', 'P', 'R'); // Tail loss probe delay of
// 0.5RTT.
const QuicTag kACKD = TAG('A', 'C', 'K', 'D'); // Ack decimation style acking.
+const QuicTag kAKD2 = TAG('A', 'K', 'D', '2'); // Ack decimation tolerating
+ // out of order packets.
const QuicTag kSSLR = TAG('S', 'S', 'L', 'R'); // Slow Start Large Reduction.
// Optional support of truncated Connection IDs. If sent by a peer, the value
@@ -99,15 +101,6 @@ const QuicTag kTCID = TAG('T', 'C', 'I', 'D'); // Connection ID truncation.
// Multipath option.
const QuicTag kMPTH = TAG('M', 'P', 'T', 'H'); // Enable multipath.
-// FEC options
-const QuicTag kFHDR = TAG('F', 'H', 'D', 'R'); // FEC protect headers
-const QuicTag kFSTR = TAG('F', 'S', 'T', 'R'); // FEC protect all streams
-// Set FecSendPolicy for sending FEC packet only when FEC alarm goes off.
-const QuicTag kFSPA = TAG('F', 'S', 'P', 'A');
-// Run an experiment that sets FecTimeOut alarm to 0.25RTT.
-// TODO(rtenneti): Delete it after the experiment.
-const QuicTag kFRTT = TAG('F', 'R', 'T', 'T');
-
// Enable bandwidth resumption experiment.
const QuicTag kBWRE = TAG('B', 'W', 'R', 'E'); // Bandwidth resumption.
const QuicTag kBWMX = TAG('B', 'W', 'M', 'X'); // Max bandwidth resumption.
diff --git a/net/quic/crypto/crypto_server_test.cc b/net/quic/crypto/crypto_server_test.cc
index 8c0e3ee..85cf2aa 100644
--- a/net/quic/crypto/crypto_server_test.cc
+++ b/net/quic/crypto/crypto_server_test.cc
@@ -507,7 +507,6 @@ TEST_P(CryptoServerTest, RejectTooLarge) {
}
TEST_P(CryptoServerTest, RejectTooLargeButValidSTK) {
- ValueRestore<bool> old_flag(&FLAGS_quic_validate_stk_without_scid, true);
// Check that the server replies with no certificate when a CHLO is
// constructed with a PDMD but no SKT when the REJ would be too large.
// clang-format off
@@ -540,37 +539,6 @@ TEST_P(CryptoServerTest, RejectTooLargeButValidSTK) {
CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
}
-TEST_P(CryptoServerTest, RejectTooLargeButValidSTKWithoutFlag) {
- ValueRestore<bool> old_flag(&FLAGS_quic_validate_stk_without_scid, false);
- // Check that the server replies with no certificate when a CHLO is
- // constructed with a PDMD but no SKT when the REJ would be too large.
- // clang-format off
- CryptoHandshakeMessage msg = CryptoTestUtils::Message(
- "CHLO",
- "AEAD", "AESG",
- "KEXS", "C255",
- "PUBS", pub_hex_.c_str(),
- "NONC", nonce_hex_.c_str(),
- "#004b5453", srct_hex_.c_str(),
- "PDMD", "X509",
- "VER\0", client_version_string_.c_str(),
- "$padding", static_cast<int>(kClientHelloMinimumSize),
- nullptr);
- // clang-format on
-
- // The REJ will be larger than the CHLO so no PROF or CRT will be sent.
- config_.set_chlo_multiplier(1);
-
- ShouldSucceed(msg);
- StringPiece cert, proof, cert_sct;
- EXPECT_FALSE(out_.GetStringPiece(kCertificateTag, &cert));
- EXPECT_FALSE(out_.GetStringPiece(kPROF, &proof));
- EXPECT_FALSE(out_.GetStringPiece(kCertificateSCTTag, &cert_sct));
- const HandshakeFailureReason kRejectReasons[] = {
- SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
- CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
-}
-
TEST_P(CryptoServerTest, TooSmall) {
// clang-format off
ShouldFailMentioning("too small", CryptoTestUtils::Message(
@@ -758,50 +726,7 @@ TEST_P(CryptoServerTest, CorruptMultipleTags) {
};
}
-TEST_P(CryptoServerTest, ReplayProtection) {
- if (client_version_ > QUIC_VERSION_30) {
- return;
- }
- FLAGS_require_strike_register_or_server_nonce = false;
- // This tests that disabling replay protection works.
- // clang-format off
- CryptoHandshakeMessage msg = CryptoTestUtils::Message(
- "CHLO",
- "AEAD", "AESG",
- "KEXS", "C255",
- "SCID", scid_hex_.c_str(),
- "#004b5453", srct_hex_.c_str(),
- "PUBS", pub_hex_.c_str(),
- "NONC", nonce_hex_.c_str(),
- "XLCT", XlctHexString().c_str(),
- "VER\0", client_version_string_.c_str(),
- "$padding", static_cast<int>(kClientHelloMinimumSize),
- nullptr);
- // clang-format on
- ShouldSucceed(msg);
- // The message should be rejected because the strike-register is still
- // quiescent.
- CheckRejectTag();
-
- const HandshakeFailureReason kRejectReasons[] = {
- CLIENT_NONCE_INVALID_TIME_FAILURE};
- CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
-
- config_.set_replay_protection(false);
-
- ShouldSucceed(msg);
- // The message should be accepted now.
- ASSERT_EQ(kSHLO, out_.tag());
- CheckServerHello(out_);
-
- ShouldSucceed(msg);
- // The message should accepted twice when replay protection is off.
- ASSERT_EQ(kSHLO, out_.tag());
- CheckServerHello(out_);
-}
-
TEST_P(CryptoServerTest, NoServerNonce) {
- FLAGS_require_strike_register_or_server_nonce = true;
// When no server nonce is present and no strike register is configured,
// the CHLO should be rejected.
// clang-format off
diff --git a/net/quic/crypto/curve25519_key_exchange.cc b/net/quic/crypto/curve25519_key_exchange.cc
index cf97add..6545d21 100644
--- a/net/quic/crypto/curve25519_key_exchange.cc
+++ b/net/quic/crypto/curve25519_key_exchange.cc
@@ -18,8 +18,7 @@ Curve25519KeyExchange::Curve25519KeyExchange() {}
Curve25519KeyExchange::~Curve25519KeyExchange() {}
// static
-Curve25519KeyExchange* Curve25519KeyExchange::New(
- const StringPiece& private_key) {
+Curve25519KeyExchange* Curve25519KeyExchange::New(StringPiece private_key) {
Curve25519KeyExchange* ka;
// We don't want to #include the NaCl headers in the public header file, so
// we use literals for the sizes of private_key_ and public_key_. Here we
@@ -58,9 +57,8 @@ KeyExchange* Curve25519KeyExchange::NewKeyPair(QuicRandom* rand) const {
return Curve25519KeyExchange::New(private_value);
}
-bool Curve25519KeyExchange::CalculateSharedKey(
- const StringPiece& peer_public_value,
- string* out_result) const {
+bool Curve25519KeyExchange::CalculateSharedKey(StringPiece peer_public_value,
+ string* out_result) const {
if (peer_public_value.size() != crypto::curve25519::kBytes) {
return false;
}
diff --git a/net/quic/crypto/curve25519_key_exchange.h b/net/quic/crypto/curve25519_key_exchange.h
index 1637bbb..a95cf7f 100644
--- a/net/quic/crypto/curve25519_key_exchange.h
+++ b/net/quic/crypto/curve25519_key_exchange.h
@@ -26,7 +26,7 @@ class NET_EXPORT_PRIVATE Curve25519KeyExchange : public KeyExchange {
// New creates a new object from a private key. If the private key is
// invalid, nullptr is returned.
- static Curve25519KeyExchange* New(const base::StringPiece& private_key);
+ static Curve25519KeyExchange* New(base::StringPiece private_key);
// NewPrivateKey returns a private key, generated from |rand|, suitable for
// passing to |New|.
@@ -34,7 +34,7 @@ class NET_EXPORT_PRIVATE Curve25519KeyExchange : public KeyExchange {
// KeyExchange interface.
KeyExchange* NewKeyPair(QuicRandom* rand) const override;
- bool CalculateSharedKey(const base::StringPiece& peer_public_value,
+ bool CalculateSharedKey(base::StringPiece peer_public_value,
std::string* shared_key) const override;
base::StringPiece public_value() const override;
QuicTag tag() const override;
diff --git a/net/quic/crypto/key_exchange.h b/net/quic/crypto/key_exchange.h
index 8690f0e..a6de1c3 100644
--- a/net/quic/crypto/key_exchange.h
+++ b/net/quic/crypto/key_exchange.h
@@ -29,7 +29,7 @@ class NET_EXPORT_PRIVATE KeyExchange {
// CalculateSharedKey computes the shared key between the local private key
// (which is implicitly known by a KeyExchange object) and a public value
// from the peer.
- virtual bool CalculateSharedKey(const base::StringPiece& peer_public_value,
+ virtual bool CalculateSharedKey(base::StringPiece peer_public_value,
std::string* shared_key) const = 0;
// public_value returns the local public key which can be sent to a peer in
diff --git a/net/quic/crypto/null_decrypter.cc b/net/quic/crypto/null_decrypter.cc
index 52217b5..43adb67 100644
--- a/net/quic/crypto/null_decrypter.cc
+++ b/net/quic/crypto/null_decrypter.cc
@@ -27,8 +27,8 @@ bool NullDecrypter::SetNoncePrefix(StringPiece nonce_prefix) {
bool NullDecrypter::DecryptPacket(QuicPathId /*path_id*/,
QuicPacketNumber /*packet_number*/,
- const StringPiece& associated_data,
- const StringPiece& ciphertext,
+ StringPiece associated_data,
+ StringPiece ciphertext,
char* output,
size_t* output_length,
size_t max_output_length) {
diff --git a/net/quic/crypto/null_decrypter.h b/net/quic/crypto/null_decrypter.h
index 91b5856..e5e15b2 100644
--- a/net/quic/crypto/null_decrypter.h
+++ b/net/quic/crypto/null_decrypter.h
@@ -30,8 +30,8 @@ class NET_EXPORT_PRIVATE NullDecrypter : public QuicDecrypter {
bool SetNoncePrefix(base::StringPiece nonce_prefix) override;
bool DecryptPacket(QuicPathId path_id,
QuicPacketNumber packet_number,
- const base::StringPiece& associated_data,
- const base::StringPiece& ciphertext,
+ base::StringPiece associated_data,
+ base::StringPiece ciphertext,
char* output,
size_t* output_length,
size_t max_output_length) override;
@@ -43,8 +43,7 @@ class NET_EXPORT_PRIVATE NullDecrypter : public QuicDecrypter {
private:
bool ReadHash(QuicDataReader* reader, uint128* hash);
- uint128 ComputeHash(const base::StringPiece data1,
- const base::StringPiece data2) const;
+ uint128 ComputeHash(base::StringPiece data1, base::StringPiece data2) const;
DISALLOW_COPY_AND_ASSIGN(NullDecrypter);
};
diff --git a/net/quic/crypto/p256_key_exchange.h b/net/quic/crypto/p256_key_exchange.h
index e6855aa..197adfe 100644
--- a/net/quic/crypto/p256_key_exchange.h
+++ b/net/quic/crypto/p256_key_exchange.h
@@ -42,7 +42,7 @@ class NET_EXPORT_PRIVATE P256KeyExchange : public KeyExchange {
// KeyExchange interface.
KeyExchange* NewKeyPair(QuicRandom* rand) const override;
- bool CalculateSharedKey(const base::StringPiece& peer_public_value,
+ bool CalculateSharedKey(base::StringPiece peer_public_value,
std::string* shared_key) const override;
base::StringPiece public_value() const override;
QuicTag tag() const override;
diff --git a/net/quic/crypto/p256_key_exchange_nss.cc b/net/quic/crypto/p256_key_exchange_nss.cc
index 576825f..c5529ab 100644
--- a/net/quic/crypto/p256_key_exchange_nss.cc
+++ b/net/quic/crypto/p256_key_exchange_nss.cc
@@ -153,7 +153,7 @@ KeyExchange* P256KeyExchange::NewKeyPair(QuicRandom* /*rand*/) const {
return P256KeyExchange::New(private_value);
}
-bool P256KeyExchange::CalculateSharedKey(const StringPiece& peer_public_value,
+bool P256KeyExchange::CalculateSharedKey(StringPiece peer_public_value,
string* out_result) const {
if (peer_public_value.size() != kUncompressedP256PointBytes ||
peer_public_value[0] != kUncompressedECPointForm) {
diff --git a/net/quic/crypto/p256_key_exchange_openssl.cc b/net/quic/crypto/p256_key_exchange_openssl.cc
index 7a9707e..9703a2e 100644
--- a/net/quic/crypto/p256_key_exchange_openssl.cc
+++ b/net/quic/crypto/p256_key_exchange_openssl.cc
@@ -77,7 +77,7 @@ KeyExchange* P256KeyExchange::NewKeyPair(QuicRandom* /*rand*/) const {
return P256KeyExchange::New(private_value);
}
-bool P256KeyExchange::CalculateSharedKey(const StringPiece& peer_public_value,
+bool P256KeyExchange::CalculateSharedKey(StringPiece peer_public_value,
string* out_result) const {
if (peer_public_value.size() != kUncompressedP256PointBytes) {
DVLOG(1) << "Peer public value is invalid";
diff --git a/net/quic/crypto/quic_crypto_server_config.cc b/net/quic/crypto/quic_crypto_server_config.cc
index cd14bc1..25d344b 100644
--- a/net/quic/crypto/quic_crypto_server_config.cc
+++ b/net/quic/crypto/quic_crypto_server_config.cc
@@ -997,23 +997,21 @@ void QuicCryptoServerConfig::EvaluateClientHello(
HandshakeFailureReason source_address_token_error = MAX_FAILURE_REASON;
StringPiece srct;
- if (FLAGS_quic_validate_stk_without_scid) {
- if (client_hello.GetStringPiece(kSourceAddressTokenTag, &srct)) {
- Config& config =
- requested_config != nullptr ? *requested_config : *primary_config;
- source_address_token_error =
- ParseSourceAddressToken(config, srct, &info->source_address_tokens);
-
- if (source_address_token_error == HANDSHAKE_OK) {
- source_address_token_error = ValidateSourceAddressTokens(
- info->source_address_tokens, info->client_ip, info->now,
- &client_hello_state->cached_network_params);
- }
- info->valid_source_address_token =
- (source_address_token_error == HANDSHAKE_OK);
- } else {
- source_address_token_error = SOURCE_ADDRESS_TOKEN_INVALID_FAILURE;
+ if (client_hello.GetStringPiece(kSourceAddressTokenTag, &srct)) {
+ Config& config =
+ requested_config != nullptr ? *requested_config : *primary_config;
+ source_address_token_error =
+ ParseSourceAddressToken(config, srct, &info->source_address_tokens);
+
+ if (source_address_token_error == HANDSHAKE_OK) {
+ source_address_token_error = ValidateSourceAddressTokens(
+ info->source_address_tokens, info->client_ip, info->now,
+ &client_hello_state->cached_network_params);
}
+ info->valid_source_address_token =
+ (source_address_token_error == HANDSHAKE_OK);
+ } else {
+ source_address_token_error = SOURCE_ADDRESS_TOKEN_INVALID_FAILURE;
}
if (!requested_config.get()) {
@@ -1028,23 +1026,6 @@ void QuicCryptoServerConfig::EvaluateClientHello(
return;
}
- if (!FLAGS_quic_validate_stk_without_scid) {
- if (client_hello.GetStringPiece(kSourceAddressTokenTag, &srct)) {
- source_address_token_error = ParseSourceAddressToken(
- *requested_config, srct, &info->source_address_tokens);
-
- if (source_address_token_error == HANDSHAKE_OK) {
- source_address_token_error = ValidateSourceAddressTokens(
- info->source_address_tokens, info->client_ip, info->now,
- &client_hello_state->cached_network_params);
- }
- info->valid_source_address_token =
- (source_address_token_error == HANDSHAKE_OK);
- } else {
- source_address_token_error = SOURCE_ADDRESS_TOKEN_INVALID_FAILURE;
- }
- }
-
bool found_error = false;
if (source_address_token_error != HANDSHAKE_OK) {
info->reject_reasons.push_back(source_address_token_error);
@@ -1140,18 +1121,6 @@ void QuicCryptoServerConfig::EvaluateClientHello(
StrikeRegisterClient* strike_register_client;
{
base::AutoLock locked(strike_register_client_lock_);
-
- if (strike_register_client_.get() == nullptr) {
- if (!FLAGS_require_strike_register_or_server_nonce) {
- strike_register_client_.reset(new LocalStrikeRegisterClient(
- strike_register_max_entries_,
- static_cast<uint32_t>(info->now.ToUNIXSeconds()),
- strike_register_window_secs_, primary_orbit,
- strike_register_no_startup_period_
- ? StrikeRegister::NO_STARTUP_PERIOD_NEEDED
- : StrikeRegister::DENY_REQUESTS_AT_STARTUP));
- }
- }
strike_register_client = strike_register_client_.get();
}
diff --git a/net/quic/crypto/quic_crypto_server_config_test.cc b/net/quic/crypto/quic_crypto_server_config_test.cc
index f3f9de7..0585a19 100644
--- a/net/quic/crypto/quic_crypto_server_config_test.cc
+++ b/net/quic/crypto/quic_crypto_server_config_test.cc
@@ -145,7 +145,8 @@ class QuicCryptoServerConfigPeer {
}
ASSERT_TRUE(found) << "Failed to find match for " << i.first
- << " in configs:\n" << ConfigsDebug();
+ << " in configs:\n"
+ << ConfigsDebug();
}
}
diff --git a/net/quic/crypto/quic_decrypter.h b/net/quic/crypto/quic_decrypter.h
index 3e55170..4f2be96 100644
--- a/net/quic/crypto/quic_decrypter.h
+++ b/net/quic/crypto/quic_decrypter.h
@@ -52,8 +52,8 @@ class NET_EXPORT_PRIVATE QuicDecrypter {
// to non-authentic inputs, as opposed to other reasons for failure.
virtual bool DecryptPacket(QuicPathId path_id,
QuicPacketNumber packet_number,
- const base::StringPiece& associated_data,
- const base::StringPiece& ciphertext,
+ base::StringPiece associated_data,
+ base::StringPiece ciphertext,
char* output,
size_t* output_length,
size_t max_output_length) = 0;
diff --git a/net/quic/quic_alarm.cc b/net/quic/quic_alarm.cc
index b978a14..ca407b5 100644
--- a/net/quic/quic_alarm.cc
+++ b/net/quic/quic_alarm.cc
@@ -5,6 +5,7 @@
#include "net/quic/quic_alarm.h"
#include "base/logging.h"
+#include "net/quic/quic_flags.h"
namespace net {
@@ -13,29 +14,33 @@ QuicAlarm::QuicAlarm(QuicArenaScopedPtr<Delegate> delegate)
QuicAlarm::~QuicAlarm() {}
-void QuicAlarm::Set(QuicTime deadline) {
+void QuicAlarm::Set(QuicTime new_deadline) {
DCHECK(!IsSet());
- DCHECK(deadline.IsInitialized());
- deadline_ = deadline;
+ DCHECK(new_deadline.IsInitialized());
+ deadline_ = new_deadline;
SetImpl();
}
void QuicAlarm::Cancel() {
+ if (FLAGS_quic_only_cancel_set_alarms && !IsSet()) {
+ // Don't try to cancel an alarm that hasn't been set.
+ return;
+ }
deadline_ = QuicTime::Zero();
CancelImpl();
}
-void QuicAlarm::Update(QuicTime deadline, QuicTime::Delta granularity) {
- if (!deadline.IsInitialized()) {
+void QuicAlarm::Update(QuicTime new_deadline, QuicTime::Delta granularity) {
+ if (!new_deadline.IsInitialized()) {
Cancel();
return;
}
- if (std::abs(deadline.Subtract(deadline_).ToMicroseconds()) <
+ if (std::abs(new_deadline.Subtract(deadline_).ToMicroseconds()) <
granularity.ToMicroseconds()) {
return;
}
Cancel();
- Set(deadline);
+ Set(new_deadline);
}
bool QuicAlarm::IsSet() const {
@@ -43,19 +48,12 @@ bool QuicAlarm::IsSet() const {
}
void QuicAlarm::Fire() {
- if (!deadline_.IsInitialized()) {
+ if (!IsSet()) {
return;
}
deadline_ = QuicTime::Zero();
- QuicTime deadline = delegate_->OnAlarm();
- // delegate_->OnAlarm() might call Set(), in which case deadline_
- // will already contain the new value, so don't overwrite it. Also,
- // OnAlarm() might delete |this| so check |deadline| before
- // |deadline_|.
- if (deadline.IsInitialized() && !deadline_.IsInitialized()) {
- Set(deadline);
- }
+ delegate_->OnAlarm();
}
} // namespace net
diff --git a/net/quic/quic_alarm.h b/net/quic/quic_alarm.h
index a775cfb5..53a823f 100644
--- a/net/quic/quic_alarm.h
+++ b/net/quic/quic_alarm.h
@@ -24,10 +24,8 @@ class NET_EXPORT_PRIVATE QuicAlarm {
public:
virtual ~Delegate() {}
- // Invoked when the alarm fires. If the return value is not
- // infinite, then the alarm will be rescheduled at the
- // specified time.
- virtual QuicTime OnAlarm() = 0;
+ // Invoked when the alarm fires.
+ virtual void OnAlarm() = 0;
};
explicit QuicAlarm(QuicArenaScopedPtr<Delegate> delegate);
@@ -36,7 +34,7 @@ class NET_EXPORT_PRIVATE QuicAlarm {
// Sets the alarm to fire at |deadline|. Must not be called while
// the alarm is set. To reschedule an alarm, call Cancel() first,
// then Set().
- void Set(QuicTime deadline);
+ void Set(QuicTime new_deadline);
// Cancels the alarm. May be called repeatedly. Does not
// guarantee that the underlying scheduling system will remove
@@ -47,8 +45,9 @@ class NET_EXPORT_PRIVATE QuicAlarm {
// Cancels and sets the alarm if the |deadline| is farther from the current
// deadline than |granularity|, and otherwise does nothing. If |deadline| is
// not initialized, the alarm is cancelled.
- void Update(QuicTime deadline, QuicTime::Delta granularity);
+ void Update(QuicTime new_deadline, QuicTime::Delta granularity);
+ // Returns true if |deadline_| has been set to a non-zero time.
bool IsSet() const;
QuicTime deadline() const { return deadline_; }
diff --git a/net/quic/quic_alarm_test.cc b/net/quic/quic_alarm_test.cc
index 0ae6459..0509090 100644
--- a/net/quic/quic_alarm_test.cc
+++ b/net/quic/quic_alarm_test.cc
@@ -17,7 +17,7 @@ namespace {
class MockDelegate : public QuicAlarm::Delegate {
public:
- MOCK_METHOD0(OnAlarm, QuicTime());
+ MOCK_METHOD0(OnAlarm, void());
};
class DestructiveDelegate : public QuicAlarm::Delegate {
@@ -26,10 +26,9 @@ class DestructiveDelegate : public QuicAlarm::Delegate {
void set_alarm(QuicAlarm* alarm) { alarm_ = alarm; }
- QuicTime OnAlarm() override {
+ void OnAlarm() override {
DCHECK(alarm_);
delete alarm_;
- return QuicTime::Zero();
}
private:
@@ -137,28 +136,17 @@ TEST_F(QuicAlarmTest, UpdateWithZero) {
TEST_F(QuicAlarmTest, Fire) {
QuicTime deadline = QuicTime::Zero().Add(QuicTime::Delta::FromSeconds(7));
alarm_.Set(deadline);
- EXPECT_CALL(*delegate_, OnAlarm()).WillOnce(Return(QuicTime::Zero()));
alarm_.FireAlarm();
EXPECT_FALSE(alarm_.IsSet());
EXPECT_FALSE(alarm_.scheduled());
EXPECT_EQ(QuicTime::Zero(), alarm_.deadline());
}
-TEST_F(QuicAlarmTest, FireAndResetViaReturn) {
- alarm_.Set(deadline_);
- EXPECT_CALL(*delegate_, OnAlarm()).WillOnce(Return(deadline2_));
- alarm_.FireAlarm();
- EXPECT_TRUE(alarm_.IsSet());
- EXPECT_TRUE(alarm_.scheduled());
- EXPECT_EQ(deadline2_, alarm_.deadline());
-}
-
TEST_F(QuicAlarmTest, FireAndResetViaSet) {
alarm_.Set(deadline_);
new_deadline_ = deadline2_;
EXPECT_CALL(*delegate_, OnAlarm())
- .WillOnce(DoAll(Invoke(this, &QuicAlarmTest::ResetAlarm),
- Return(QuicTime::Zero())));
+ .WillOnce(Invoke(this, &QuicAlarmTest::ResetAlarm));
alarm_.FireAlarm();
EXPECT_TRUE(alarm_.IsSet());
EXPECT_TRUE(alarm_.scheduled());
diff --git a/net/quic/quic_chromium_client_session_test.cc b/net/quic/quic_chromium_client_session_test.cc
index bb1a57a..2de5d3c 100644
--- a/net/quic/quic_chromium_client_session_test.cc
+++ b/net/quic/quic_chromium_client_session_test.cc
@@ -368,7 +368,7 @@ TEST_P(QuicChromiumClientSessionTest, MigrateToSocket) {
iov[0].iov_base = data;
iov[0].iov_len = 4;
session_->WritevData(5, QuicIOVector(iov, arraysize(iov), 4), 0, false,
- MAY_FEC_PROTECT, nullptr);
+ nullptr);
EXPECT_TRUE(socket_data.AllReadDataConsumed());
EXPECT_TRUE(socket_data.AllWriteDataConsumed());
diff --git a/net/quic/quic_chromium_client_stream_test.cc b/net/quic/quic_chromium_client_stream_test.cc
index f384304..19c427c 100644
--- a/net/quic/quic_chromium_client_stream_test.cc
+++ b/net/quic/quic_chromium_client_stream_test.cc
@@ -60,12 +60,11 @@ class MockQuicClientSessionBase : public QuicClientSessionBase {
MOCK_METHOD1(CreateIncomingDynamicStream, QuicSpdyStream*(QuicStreamId id));
MOCK_METHOD1(CreateOutgoingDynamicStream,
QuicChromiumClientStream*(SpdyPriority priority));
- MOCK_METHOD6(WritevData,
+ MOCK_METHOD5(WritevData,
QuicConsumedData(QuicStreamId id,
QuicIOVector data,
QuicStreamOffset offset,
bool fin,
- FecProtection fec_protection,
QuicAckListenerInterface*));
MOCK_METHOD3(SendRstStream,
void(QuicStreamId stream_id,
@@ -102,7 +101,6 @@ class MockQuicClientSessionBase : public QuicClientSessionBase {
const QuicIOVector& data,
QuicStreamOffset offset,
bool fin,
- FecProtection fec_protection,
QuicAckListenerInterface* ack_notifier_delegate);
void OnProofValid(
@@ -125,7 +123,7 @@ MockQuicClientSessionBase::MockQuicClientSessionBase(
DefaultQuicConfig()) {
crypto_stream_.reset(new QuicCryptoStream(this));
Initialize();
- ON_CALL(*this, WritevData(_, _, _, _, _, _))
+ ON_CALL(*this, WritevData(_, _, _, _, _))
.WillByDefault(testing::Return(QuicConsumedData(0, false)));
}
@@ -335,7 +333,7 @@ TEST_P(QuicChromiumClientStreamTest, WriteStreamData) {
const size_t kDataLen = arraysize(kData1);
// All data written.
- EXPECT_CALL(session_, WritevData(stream_->id(), _, _, _, _, _))
+ EXPECT_CALL(session_, WritevData(stream_->id(), _, _, _, _))
.WillOnce(Return(QuicConsumedData(kDataLen, true)));
TestCompletionCallback callback;
EXPECT_EQ(OK, stream_->WriteStreamData(base::StringPiece(kData1, kDataLen),
@@ -350,7 +348,7 @@ TEST_P(QuicChromiumClientStreamTest, WriteStreamDataAsync) {
const size_t kDataLen = arraysize(kData1);
// No data written.
- EXPECT_CALL(session_, WritevData(stream_->id(), _, _, _, _, _))
+ EXPECT_CALL(session_, WritevData(stream_->id(), _, _, _, _))
.WillOnce(Return(QuicConsumedData(0, false)));
TestCompletionCallback callback;
EXPECT_EQ(ERR_IO_PENDING,
@@ -359,7 +357,7 @@ TEST_P(QuicChromiumClientStreamTest, WriteStreamDataAsync) {
ASSERT_FALSE(callback.have_result());
// All data written.
- EXPECT_CALL(session_, WritevData(stream_->id(), _, _, _, _, _))
+ EXPECT_CALL(session_, WritevData(stream_->id(), _, _, _, _))
.WillOnce(Return(QuicConsumedData(kDataLen, true)));
stream_->OnCanWrite();
ASSERT_TRUE(callback.have_result());
diff --git a/net/quic/quic_chromium_connection_helper_test.cc b/net/quic/quic_chromium_connection_helper_test.cc
index aefa22a..9fab8fb 100644
--- a/net/quic/quic_chromium_connection_helper_test.cc
+++ b/net/quic/quic_chromium_connection_helper_test.cc
@@ -17,10 +17,7 @@ class TestDelegate : public QuicAlarm::Delegate {
public:
TestDelegate() : fired_(false) {}
- QuicTime OnAlarm() override {
- fired_ = true;
- return QuicTime::Zero();
- }
+ void OnAlarm() override { fired_ = true; }
bool fired() const { return fired_; }
void Clear() { fired_ = false; }
diff --git a/net/quic/quic_client_promised_info.cc b/net/quic/quic_client_promised_info.cc
index 3b8740c4..d3816bf 100644
--- a/net/quic/quic_client_promised_info.cc
+++ b/net/quic/quic_client_promised_info.cc
@@ -23,10 +23,9 @@ QuicClientPromisedInfo::QuicClientPromisedInfo(QuicClientSessionBase* session,
QuicClientPromisedInfo::~QuicClientPromisedInfo() {}
-QuicTime QuicClientPromisedInfo::CleanupAlarm::OnAlarm() {
+void QuicClientPromisedInfo::CleanupAlarm::OnAlarm() {
DVLOG(1) << "self GC alarm for stream " << promised_->id_;
promised_->Reset(QUIC_STREAM_CANCELLED);
- return QuicTime::Zero();
}
void QuicClientPromisedInfo::Init() {
diff --git a/net/quic/quic_client_promised_info.h b/net/quic/quic_client_promised_info.h
index 300c41f..f4bb50f 100644
--- a/net/quic/quic_client_promised_info.h
+++ b/net/quic/quic_client_promised_info.h
@@ -83,7 +83,7 @@ class NET_EXPORT_PRIVATE QuicClientPromisedInfo
explicit CleanupAlarm(QuicClientPromisedInfo* promised)
: promised_(promised) {}
- QuicTime OnAlarm() override;
+ void OnAlarm() override;
QuicClientPromisedInfo* promised_;
};
diff --git a/net/quic/quic_config_test.cc b/net/quic/quic_config_test.cc
index ec1c6aa..b18673e 100644
--- a/net/quic/quic_config_test.cc
+++ b/net/quic/quic_config_test.cc
@@ -77,7 +77,6 @@ TEST_F(QuicConfigTest, ProcessClientHello) {
client_config.SetSocketReceiveBufferToSend(kDefaultSocketReceiveBuffer);
QuicTagVector copt;
copt.push_back(kTBBR);
- copt.push_back(kFHDR);
client_config.SetConnectionOptionsToSend(copt);
CryptoHandshakeMessage msg;
client_config.ToHandshakeMessage(&msg);
@@ -102,10 +101,9 @@ TEST_F(QuicConfigTest, ProcessClientHello) {
EXPECT_EQ(kDefaultMaxStreamsPerConnection, config_.MaxStreamsPerConnection());
EXPECT_EQ(10 * kNumMicrosPerMilli, config_.ReceivedInitialRoundTripTimeUs());
EXPECT_TRUE(config_.HasReceivedConnectionOptions());
- EXPECT_EQ(3u, config_.ReceivedConnectionOptions().size());
+ EXPECT_EQ(2u, config_.ReceivedConnectionOptions().size());
EXPECT_EQ(config_.ReceivedConnectionOptions()[0], kIW50);
EXPECT_EQ(config_.ReceivedConnectionOptions()[1], kTBBR);
- EXPECT_EQ(config_.ReceivedConnectionOptions()[2], kFHDR);
EXPECT_EQ(config_.ReceivedInitialStreamFlowControlWindowBytes(),
2 * kInitialStreamFlowControlWindowForTest);
EXPECT_EQ(config_.ReceivedInitialSessionFlowControlWindowBytes(),
@@ -228,12 +226,9 @@ TEST_F(QuicConfigTest, HasClientSentConnectionOption) {
QuicConfig client_config;
QuicTagVector copt;
copt.push_back(kTBBR);
- copt.push_back(kFHDR);
client_config.SetConnectionOptionsToSend(copt);
EXPECT_TRUE(client_config.HasClientSentConnectionOption(
kTBBR, Perspective::IS_CLIENT));
- EXPECT_TRUE(client_config.HasClientSentConnectionOption(
- kFHDR, Perspective::IS_CLIENT));
CryptoHandshakeMessage msg;
client_config.ToHandshakeMessage(&msg);
@@ -245,11 +240,9 @@ TEST_F(QuicConfigTest, HasClientSentConnectionOption) {
EXPECT_TRUE(config_.negotiated());
EXPECT_TRUE(config_.HasReceivedConnectionOptions());
- EXPECT_EQ(2u, config_.ReceivedConnectionOptions().size());
+ EXPECT_EQ(1u, config_.ReceivedConnectionOptions().size());
EXPECT_TRUE(
config_.HasClientSentConnectionOption(kTBBR, Perspective::IS_SERVER));
- EXPECT_TRUE(
- config_.HasClientSentConnectionOption(kFHDR, Perspective::IS_SERVER));
}
} // namespace
diff --git a/net/quic/quic_connection.cc b/net/quic/quic_connection.cc
index a210022..74bc9e3 100644
--- a/net/quic/quic_connection.cc
+++ b/net/quic/quic_connection.cc
@@ -31,7 +31,6 @@
#include "net/quic/quic_bandwidth.h"
#include "net/quic/quic_bug_tracker.h"
#include "net/quic/quic_config.h"
-#include "net/quic/quic_fec_group.h"
#include "net/quic/quic_flags.h"
#include "net/quic/quic_packet_generator.h"
#include "net/quic/quic_utils.h"
@@ -60,10 +59,6 @@ namespace {
// This will likely have to be tuned.
const QuicPacketNumber kMaxPacketGap = 5000;
-// Limit the number of FEC groups to two. If we get enough out of order packets
-// that this becomes limiting, we can revisit.
-const size_t kMaxFecGroups = 2;
-
// Maximum number of acks received before sending an ack in response.
const QuicPacketCount kMaxPacketsReceivedBeforeAckSend = 20;
@@ -91,10 +86,10 @@ class AckAlarm : public QuicAlarm::Delegate {
public:
explicit AckAlarm(QuicConnection* connection) : connection_(connection) {}
- QuicTime OnAlarm() override {
+ void OnAlarm() override {
DCHECK(connection_->ack_frame_updated());
- connection_->SendAck();
- return QuicTime::Zero();
+ QuicConnection::ScopedPacketBundler bundler(connection_,
+ QuicConnection::SEND_ACK);
}
private:
@@ -111,10 +106,7 @@ class RetransmissionAlarm : public QuicAlarm::Delegate {
explicit RetransmissionAlarm(QuicConnection* connection)
: connection_(connection) {}
- QuicTime OnAlarm() override {
- connection_->OnRetransmissionTimeout();
- return QuicTime::Zero();
- }
+ void OnAlarm() override { connection_->OnRetransmissionTimeout(); }
private:
QuicConnection* connection_;
@@ -128,11 +120,7 @@ class SendAlarm : public QuicAlarm::Delegate {
public:
explicit SendAlarm(QuicConnection* connection) : connection_(connection) {}
- QuicTime OnAlarm() override {
- connection_->WriteIfNotBlocked();
- // Never reschedule the alarm, since CanWrite does that.
- return QuicTime::Zero();
- }
+ void OnAlarm() override { connection_->WriteAndBundleAcksIfNotBlocked(); }
private:
QuicConnection* connection_;
@@ -144,11 +132,7 @@ class TimeoutAlarm : public QuicAlarm::Delegate {
public:
explicit TimeoutAlarm(QuicConnection* connection) : connection_(connection) {}
- QuicTime OnAlarm() override {
- connection_->CheckForTimeout();
- // Never reschedule the alarm, since CheckForTimeout does that.
- return QuicTime::Zero();
- }
+ void OnAlarm() override { connection_->CheckForTimeout(); }
private:
QuicConnection* connection_;
@@ -160,10 +144,7 @@ class PingAlarm : public QuicAlarm::Delegate {
public:
explicit PingAlarm(QuicConnection* connection) : connection_(connection) {}
- QuicTime OnAlarm() override {
- connection_->OnPingTimeout();
- return QuicTime::Zero();
- }
+ void OnAlarm() override { connection_->OnPingTimeout(); }
private:
QuicConnection* connection_;
@@ -176,11 +157,7 @@ class MtuDiscoveryAlarm : public QuicAlarm::Delegate {
explicit MtuDiscoveryAlarm(QuicConnection* connection)
: connection_(connection) {}
- QuicTime OnAlarm() override {
- connection_->DiscoverMtu();
- // DiscoverMtu() handles rescheduling the alarm by itself.
- return QuicTime::Zero();
- }
+ void OnAlarm() override { connection_->DiscoverMtu(); }
private:
QuicConnection* connection_;
@@ -188,23 +165,6 @@ class MtuDiscoveryAlarm : public QuicAlarm::Delegate {
DISALLOW_COPY_AND_ASSIGN(MtuDiscoveryAlarm);
};
-// This alarm may be scheduled when an FEC protected packet is sent out.
-class FecAlarm : public QuicAlarm::Delegate {
- public:
- explicit FecAlarm(QuicPacketGenerator* packet_generator)
- : packet_generator_(packet_generator) {}
-
- QuicTime OnAlarm() override {
- packet_generator_->OnFecTimeout();
- return QuicTime::Zero();
- }
-
- private:
- QuicPacketGenerator* packet_generator_;
-
- DISALLOW_COPY_AND_ASSIGN(FecAlarm);
-};
-
// Listens for acks of MTU discovery packets and raises the maximum packet size
// of the connection if the probe succeeds.
class MtuDiscoveryAckListener : public QuicAckListenerInterface {
@@ -265,8 +225,8 @@ QuicConnection::QuicConnection(QuicConnectionId connection_id,
peer_address_(address),
migrating_peer_port_(0),
last_packet_decrypted_(false),
- last_packet_revived_(false),
last_size_(0),
+ current_packet_data_(nullptr),
last_decrypted_packet_level_(ENCRYPTION_NONE),
should_last_packet_instigate_acks_(false),
largest_seen_packet_with_ack_(0),
@@ -278,11 +238,13 @@ QuicConnection::QuicConnection(QuicConnectionId connection_id,
received_packet_manager_(&stats_),
ack_queued_(false),
num_retransmittable_packets_received_since_last_ack_sent_(0),
+ last_ack_had_missing_packets_(false),
num_packets_received_since_last_ack_sent_(0),
stop_waiting_count_(0),
- ack_decimation_enabled_(false),
+ ack_mode_(TCP_ACKING),
delay_setting_retransmission_alarm_(false),
pending_retransmission_alarm_(false),
+ defer_send_in_response_to_packets_(false),
arena_(),
ack_alarm_(helper->CreateAlarm(arena_.New<AckAlarm>(this), &arena_)),
retransmission_alarm_(
@@ -302,8 +264,6 @@ QuicConnection::QuicConnection(QuicConnectionId connection_id,
random_generator_,
helper->GetBufferAllocator(),
this),
- fec_alarm_(helper->CreateAlarm(arena_.New<FecAlarm>(&packet_generator_),
- &arena_)),
idle_network_timeout_(QuicTime::Delta::Infinite()),
handshake_timeout_(QuicTime::Delta::Infinite()),
time_of_last_received_packet_(clock_->ApproximateNow()),
@@ -356,7 +316,6 @@ QuicConnection::~QuicConnection() {
if (termination_packets_.get() != nullptr) {
STLDeleteElements(termination_packets_.get());
}
- STLDeleteValues(&group_map_);
ClearQueuedPackets();
}
@@ -395,16 +354,6 @@ void QuicConnection::SetFromConfig(const QuicConfig& config) {
}
max_undecryptable_packets_ = config.max_undecryptable_packets();
- if (config.HasClientSentConnectionOption(kFSPA, perspective_)) {
- packet_generator_.set_fec_send_policy(FecSendPolicy::FEC_ALARM_TRIGGER);
- }
- if (config.HasClientSentConnectionOption(kFRTT, perspective_)) {
- // TODO(rtenneti): Delete this code after the 0.25 RTT FEC experiment.
- const float kFecTimeoutRttMultiplier = 0.25;
- packet_generator_.set_rtt_multiplier_for_fec_timeout(
- kFecTimeoutRttMultiplier);
- }
-
if (config.HasClientSentConnectionOption(kMTUH, perspective_)) {
SetMtuDiscoveryTarget(kMtuDiscoveryTargetPacketSizeHigh);
}
@@ -415,7 +364,11 @@ void QuicConnection::SetFromConfig(const QuicConfig& config) {
debug_visitor_->OnSetFromConfig(config);
}
if (config.HasClientSentConnectionOption(kACKD, perspective_)) {
- ack_decimation_enabled_ = true;
+ ack_mode_ = ACK_DECIMATION;
+ }
+ if (FLAGS_quic_ack_decimation2 &&
+ config.HasClientSentConnectionOption(kAKD2, perspective_)) {
+ ack_mode_ = ACK_DECIMATION_WITH_REORDERING;
}
}
@@ -470,20 +423,8 @@ void QuicConnection::OnError(QuicFramer* framer) {
SendConnectionCloseWithDetails(framer->error(), framer->detailed_error());
}
-void QuicConnection::MaybeSetFecAlarm(QuicPacketNumber packet_number) {
- if (fec_alarm_->IsSet()) {
- return;
- }
- QuicTime::Delta timeout = packet_generator_.GetFecTimeout(packet_number);
- if (!timeout.IsInfinite()) {
- fec_alarm_->Update(clock_->ApproximateNow().Add(timeout),
- QuicTime::Delta::FromMilliseconds(1));
- }
-}
-
void QuicConnection::OnPacket() {
last_packet_decrypted_ = false;
- last_packet_revived_ = false;
}
void QuicConnection::OnPublicResetPacket(const QuicPublicResetPacket& packet) {
@@ -601,8 +542,6 @@ void QuicConnection::OnVersionNegotiationPacket(
RetransmitUnackedPackets(ALL_UNACKED_RETRANSMISSION);
}
-void QuicConnection::OnRevivedPacket() {}
-
bool QuicConnection::OnUnauthenticatedPublicHeader(
const QuicPacketPublicHeader& header) {
if (header.connection_id == connection_id_) {
@@ -689,15 +628,6 @@ bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) {
return true;
}
-void QuicConnection::OnFecProtectedPayload(StringPiece payload) {
- DCHECK_EQ(IN_FEC_GROUP, last_header_.is_in_fec_group);
- DCHECK_NE(0u, last_header_.fec_group);
- QuicFecGroup* group = GetFecGroup();
- if (group != nullptr) {
- group->Update(last_decrypted_packet_level_, last_header_, payload);
- }
-}
-
bool QuicConnection::OnStreamFrame(const QuicStreamFrame& frame) {
DCHECK(connected_);
if (debug_visitor_ != nullptr) {
@@ -708,6 +638,7 @@ bool QuicConnection::OnStreamFrame(const QuicStreamFrame& frame) {
QUIC_BUG << ENDPOINT
<< "Received an unencrypted data frame: closing connection"
<< " packet_number:" << last_header_.packet_number
+ << " stream_id:" << frame.stream_id
<< " received_packets:" << received_packet_manager_.ack_frame();
SendConnectionCloseWithDetails(QUIC_UNENCRYPTED_STREAM_DATA,
"Unencrypted stream data seen");
@@ -773,8 +704,6 @@ void QuicConnection::ProcessStopWaitingFrame(
const QuicStopWaitingFrame& stop_waiting) {
largest_seen_packet_with_stop_waiting_ = last_header_.packet_number;
received_packet_manager_.UpdatePacketInformationSentByPeer(stop_waiting);
- // Possibly close any FecGroups which are now irrelevant.
- CloseFecGroupsBefore(stop_waiting.least_unacked + 1);
}
bool QuicConnection::OnStopWaitingFrame(const QuicStopWaitingFrame& frame) {
@@ -820,7 +749,10 @@ const char* QuicConnection::ValidateAckFrame(const QuicAckFrame& incoming_ack) {
if (incoming_ack.largest_observed < sent_packet_manager_.largest_observed()) {
LOG(WARNING) << ENDPOINT << "Peer's largest_observed packet decreased:"
<< incoming_ack.largest_observed << " vs "
- << sent_packet_manager_.largest_observed();
+ << sent_packet_manager_.largest_observed()
+ << " packet_number:" << last_header_.packet_number
+ << " largest seen with ack:" << largest_seen_packet_with_ack_
+ << " connection_id: " << connection_id_;
// A new ack has a diminished largest_observed value. Error out.
// If this was an old packet, we wouldn't even have checked.
return "Largest observed too low";
@@ -854,14 +786,6 @@ const char* QuicConnection::ValidateAckFrame(const QuicAckFrame& incoming_ack) {
return "Invalid entropy";
}
- if (incoming_ack.latest_revived_packet != 0 &&
- !incoming_ack.missing_packets.Contains(
- incoming_ack.latest_revived_packet)) {
- LOG(WARNING) << ENDPOINT
- << "Peer specified revived packet which was not missing."
- << " revived_packet:" << incoming_ack.latest_revived_packet;
- return "Invalid revived packet";
- }
return nullptr;
}
@@ -887,15 +811,6 @@ const char* QuicConnection::ValidateStopWaitingFrame(
return nullptr;
}
-void QuicConnection::OnFecData(StringPiece redundancy) {
- DCHECK_EQ(IN_FEC_GROUP, last_header_.is_in_fec_group);
- DCHECK_NE(0u, last_header_.fec_group);
- QuicFecGroup* group = GetFecGroup();
- if (group != nullptr) {
- group->UpdateFec(last_decrypted_packet_level_, last_header_, redundancy);
- }
-}
-
bool QuicConnection::OnRstStreamFrame(const QuicRstStreamFrame& frame) {
DCHECK(connected_);
if (debug_visitor_ != nullptr) {
@@ -987,8 +902,7 @@ void QuicConnection::OnPacketComplete() {
return;
}
- DVLOG(1) << ENDPOINT << (last_packet_revived_ ? "Revived" : "Got")
- << " packet " << last_header_.packet_number << " for "
+ DVLOG(1) << ENDPOINT << "Got packet " << last_header_.packet_number << " for "
<< last_header_.public_header.connection_id;
// An ack will be sent if a missing retransmittable packet was received;
@@ -996,15 +910,11 @@ void QuicConnection::OnPacketComplete() {
should_last_packet_instigate_acks_ &&
received_packet_manager_.IsMissing(last_header_.packet_number);
- // Record received or revived packet to populate ack info correctly before
- // processing stream frames, since the processing may result in a response
- // packet with a bundled ack.
- if (last_packet_revived_) {
- received_packet_manager_.RecordPacketRevived(last_header_.packet_number);
- } else {
- received_packet_manager_.RecordPacketReceived(
- last_size_, last_header_, time_of_last_received_packet_);
- }
+ // Record received to populate ack info correctly before processing stream
+ // frames, since the processing may result in a response packet with a bundled
+ // ack.
+ received_packet_manager_.RecordPacketReceived(last_size_, last_header_,
+ time_of_last_received_packet_);
// Process stop waiting frames here, instead of inline, because the packet
// needs to be considered 'received' before the entropy can be updated.
@@ -1019,7 +929,6 @@ void QuicConnection::OnPacketComplete() {
ClearLastFrames();
MaybeCloseIfTooManyOutstandingPackets();
- MaybeProcessRevivedPacket();
}
void QuicConnection::MaybeQueueAck(bool was_missing) {
@@ -1033,13 +942,16 @@ void QuicConnection::MaybeQueueAck(bool was_missing) {
// Determine whether the newly received packet was missing before recording
// the received packet.
- if (was_missing) {
+ // Ack decimation with reordering relies on the timer to send an ack, but if
+ // missing packets we reported in the previous ack, send an ack immediately.
+ if (was_missing && (ack_mode_ != ACK_DECIMATION_WITH_REORDERING ||
+ last_ack_had_missing_packets_)) {
ack_queued_ = true;
}
if (should_last_packet_instigate_acks_ && !ack_queued_) {
++num_retransmittable_packets_received_since_last_ack_sent_;
- if (ack_decimation_enabled_ &&
+ if (ack_mode_ != TCP_ACKING &&
last_header_.packet_number > kMinReceivedBeforeAckDecimation) {
// Ack up to 10 packets at once.
if (num_retransmittable_packets_received_since_last_ack_sent_ >=
@@ -1064,10 +976,18 @@ void QuicConnection::MaybeQueueAck(bool was_missing) {
}
// If there are new missing packets to report, send an ack immediately.
- // TODO(ianswett): Consider allowing 1ms of reordering for the
- // ack decimation experiment.
if (received_packet_manager_.HasNewMissingPackets()) {
- ack_queued_ = true;
+ if (ack_mode_ == ACK_DECIMATION_WITH_REORDERING) {
+ // Wait the minimum of an eighth min_rtt and the existing ack time.
+ QuicTime ack_time = clock_->ApproximateNow().Add(
+ sent_packet_manager_.GetRttStats()->min_rtt().Multiply(0.125));
+ if (!ack_alarm_->IsSet() || ack_alarm_->deadline() > ack_time) {
+ ack_alarm_->Cancel();
+ ack_alarm_->Set(ack_time);
+ }
+ } else {
+ ack_queued_ = true;
+ }
}
}
@@ -1119,11 +1039,14 @@ void QuicConnection::MaybeSendInResponseToPacket() {
if (!connected_) {
return;
}
- ScopedPacketBundler bundler(this, ack_queued_ ? SEND_ACK : NO_ACK);
-
// Now that we have received an ack, we might be able to send packets which
// are queued locally, or drain streams which are blocked.
- WriteIfNotBlocked();
+ if (defer_send_in_response_to_packets_) {
+ send_alarm_->Cancel();
+ send_alarm_->Set(clock_->ApproximateNow());
+ } else {
+ WriteAndBundleAcksIfNotBlocked();
+ }
}
void QuicConnection::SendVersionNegotiationPacket() {
@@ -1162,7 +1085,6 @@ QuicConsumedData QuicConnection::SendStreamData(
QuicIOVector iov,
QuicStreamOffset offset,
bool fin,
- FecProtection fec_protection,
QuicAckListenerInterface* listener) {
if (!fin && iov.total_length == 0) {
QUIC_BUG << "Attempt to send empty stream frame";
@@ -1184,8 +1106,7 @@ QuicConsumedData QuicConnection::SendStreamData(
// processing left that may cause received_info_ to change.
ScopedRetransmissionScheduler alarm_delayer(this);
ScopedPacketBundler ack_bundler(this, BUNDLE_PENDING_ACK);
- return packet_generator_.ConsumeData(id, iov, offset, fin, fec_protection,
- listener);
+ return packet_generator_.ConsumeData(id, iov, offset, fin, listener);
}
void QuicConnection::SendRstStream(QuicStreamId id,
@@ -1263,7 +1184,7 @@ const QuicConnectionStats& QuicConnection::GetStats() {
stats_.srtt_us = srtt.ToMicroseconds();
stats_.estimated_bandwidth = sent_packet_manager_.BandwidthEstimate();
- stats_.max_packet_size = packet_generator_.GetMaxPacketLength();
+ stats_.max_packet_size = packet_generator_.GetCurrentMaxPacketLength();
stats_.max_received_packet_size = largest_received_packet_size_;
return stats_;
}
@@ -1278,6 +1199,7 @@ void QuicConnection::ProcessUdpPacket(const IPEndPoint& self_address,
debug_visitor_->OnPacketReceived(self_address, peer_address, packet);
}
last_size_ = packet.length();
+ current_packet_data_ = packet.data();
if (FLAGS_check_peer_address_change_after_decryption) {
last_packet_destination_address_ = self_address;
@@ -1309,6 +1231,7 @@ void QuicConnection::ProcessUdpPacket(const IPEndPoint& self_address,
}
DVLOG(1) << ENDPOINT << "Unable to process packet. Last packet processed: "
<< last_header_.packet_number;
+ current_packet_data_ = nullptr;
return;
}
@@ -1316,6 +1239,7 @@ void QuicConnection::ProcessUdpPacket(const IPEndPoint& self_address,
MaybeProcessUndecryptablePackets();
MaybeSendInResponseToPacket();
SetPingAlarm();
+ current_packet_data_ = nullptr;
}
void QuicConnection::CheckForAddressMigration(const IPEndPoint& self_address,
@@ -1384,7 +1308,19 @@ void QuicConnection::WriteIfNotBlocked() {
}
}
+void QuicConnection::WriteAndBundleAcksIfNotBlocked() {
+ if (!writer_->IsWriteBlocked()) {
+ ScopedPacketBundler bundler(this, ack_queued_ ? SEND_ACK : NO_ACK);
+ OnCanWrite();
+ }
+}
+
bool QuicConnection::ProcessValidatedPacket(const QuicPacketHeader& header) {
+ if (header.fec_flag) {
+ // Drop any FEC packet.
+ return false;
+ }
+
if (FLAGS_check_peer_address_change_after_decryption) {
if (perspective_ == Perspective::IS_SERVER &&
IsInitializedIPEndPoint(self_address_) &&
@@ -1459,7 +1395,7 @@ bool QuicConnection::ProcessValidatedPacket(const QuicPacketHeader& header) {
if (perspective_ == Perspective::IS_SERVER &&
encryption_level_ == ENCRYPTION_NONE &&
- last_size_ > packet_generator_.GetMaxPacketLength()) {
+ last_size_ > packet_generator_.GetCurrentMaxPacketLength()) {
SetMaxPacketLength(last_size_);
}
return true;
@@ -1492,7 +1428,6 @@ void QuicConnection::WritePendingRetransmissions() {
}
// Re-packetize the frames with a new packet number for retransmission.
- // Retransmitted data packets do not use FEC, even when it's enabled.
// Retransmitted packets use the same packet number length as the
// original.
// Flush the packet generator before making a new packet.
@@ -1615,13 +1550,11 @@ bool QuicConnection::WritePacket(SerializedPacket* packet) {
}
DCHECK_LE(encrypted_length, kMaxPacketSize);
- DCHECK_LE(encrypted_length, packet_generator_.GetMaxPacketLength());
+ DCHECK_LE(encrypted_length, packet_generator_.GetCurrentMaxPacketLength());
DVLOG(1) << ENDPOINT << "Sending packet " << packet_number << " : "
- << (packet->is_fec_packet
- ? "FEC "
- : (IsRetransmittable(*packet) == HAS_RETRANSMITTABLE_DATA
- ? "data bearing "
- : " ack only "))
+ << (IsRetransmittable(*packet) == HAS_RETRANSMITTABLE_DATA
+ ? "data bearing "
+ : " ack only ")
<< ", encryption level: "
<< QuicUtils::EncryptionLevelToString(packet->encryption_level)
<< ", encrypted length:" << encrypted_length;
@@ -1663,7 +1596,6 @@ bool QuicConnection::WritePacket(SerializedPacket* packet) {
}
}
SetPingAlarm();
- MaybeSetFecAlarm(packet_number);
MaybeSetMtuAlarm();
DVLOG(1) << ENDPOINT << "time we began writing last sent packet: "
<< packet_send_time.ToDebuggingValue();
@@ -1751,10 +1683,6 @@ void QuicConnection::OnSerializedPacket(SerializedPacket* serialized_packet) {
CloseConnection(QUIC_ENCRYPTION_FAILURE, ConnectionCloseSource::FROM_SELF);
return;
}
- if (serialized_packet->is_fec_packet && fec_alarm_->IsSet()) {
- // If an FEC packet is serialized with the FEC alarm set, cancel the alarm.
- fec_alarm_->Cancel();
- }
SendOrQueuePacket(serialized_packet);
}
@@ -1765,17 +1693,7 @@ void QuicConnection::OnUnrecoverableError(QuicErrorCode error,
CloseConnection(error, source);
}
-void QuicConnection::OnResetFecGroup() {
- if (!fec_alarm_->IsSet()) {
- return;
- }
- // If an FEC Group is closed with the FEC alarm set, cancel the alarm.
- fec_alarm_->Cancel();
-}
-
void QuicConnection::OnCongestionWindowChange() {
- packet_generator_.OnCongestionWindowChange(
- sent_packet_manager_.EstimateMaxPacketsInFlight(max_packet_length()));
visitor_->OnCongestionWindowChange(clock_->ApproximateNow());
}
@@ -1786,9 +1704,9 @@ void QuicConnection::OnRttChange() {
rtt = QuicTime::Delta::FromMicroseconds(
sent_packet_manager_.GetRttStats()->initial_rtt_us());
}
+
if (debug_visitor_)
debug_visitor_->OnRttChanged(rtt);
- packet_generator_.OnRttChange(rtt);
}
void QuicConnection::OnPathDegrading() {
@@ -1853,6 +1771,7 @@ void QuicConnection::SendAck() {
ack_queued_ = false;
stop_waiting_count_ = 0;
num_retransmittable_packets_received_since_last_ack_sent_ = 0;
+ last_ack_had_missing_packets_ = received_packet_manager_.HasMissingPackets();
num_packets_received_since_last_ack_sent_ = 0;
packet_generator_.SetShouldSendAck(true);
@@ -1969,75 +1888,6 @@ void QuicConnection::MaybeProcessUndecryptablePackets() {
}
}
-void QuicConnection::MaybeProcessRevivedPacket() {
- QuicFecGroup* group = GetFecGroup();
- if (!connected_ || group == nullptr || !group->CanRevive()) {
- return;
- }
- QuicPacketHeader revived_header;
- char revived_payload[kMaxPacketSize];
- size_t len = group->Revive(&revived_header, revived_payload, kMaxPacketSize);
- if (!received_packet_manager_.IsAwaitingPacket(
- revived_header.packet_number)) {
- // Close this FEC group because all packets in the group has been received.
- group_map_.erase(last_header_.fec_group);
- delete group;
- return;
- }
- revived_header.public_header.connection_id = connection_id_;
- revived_header.public_header.connection_id_length =
- last_header_.public_header.connection_id_length;
- revived_header.public_header.version_flag = false;
- revived_header.public_header.reset_flag = false;
- revived_header.public_header.packet_number_length =
- last_header_.public_header.packet_number_length;
- revived_header.fec_flag = false;
- revived_header.is_in_fec_group = NOT_IN_FEC_GROUP;
- revived_header.fec_group = 0;
- group_map_.erase(last_header_.fec_group);
- last_decrypted_packet_level_ = group->EffectiveEncryptionLevel();
- DCHECK_LT(last_decrypted_packet_level_, NUM_ENCRYPTION_LEVELS);
- delete group;
-
- last_packet_revived_ = true;
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnRevivedPacket(revived_header,
- StringPiece(revived_payload, len));
- }
-
- ++stats_.packets_revived;
- framer_.ProcessRevivedPacket(&revived_header,
- StringPiece(revived_payload, len));
-}
-
-QuicFecGroup* QuicConnection::GetFecGroup() {
- QuicFecGroupNumber fec_group_num = last_header_.fec_group;
- if (fec_group_num == 0 ||
- (fec_group_num <
- received_packet_manager_.peer_least_packet_awaiting_ack() &&
- !ContainsKey(group_map_, fec_group_num))) {
- // If the group number is below peer_least_packet_awaiting_ack and this
- // group does not exist, which means this group has missing packets below
- // |peer_least_packet_awaiting_ack| which we would never receive, so return
- // nullptr.
- return nullptr;
- }
- if (!ContainsKey(group_map_, fec_group_num)) {
- if (group_map_.size() >= kMaxFecGroups) { // Too many groups
- if (fec_group_num < group_map_.begin()->first) {
- // The group being requested is a group we've seen before and deleted.
- // Don't recreate it.
- return nullptr;
- }
- // Clear the lowest group number.
- delete group_map_.begin()->second;
- group_map_.erase(group_map_.begin());
- }
- group_map_[fec_group_num] = new QuicFecGroup(fec_group_num);
- }
- return group_map_[fec_group_num];
-}
-
void QuicConnection::SendConnectionCloseWithDetails(QuicErrorCode error,
const string& details) {
if (!connected_) {
@@ -2087,7 +1937,6 @@ void QuicConnection::CloseConnection(QuicErrorCode error,
// connection is closed.
ack_alarm_->Cancel();
ping_alarm_->Cancel();
- fec_alarm_->Cancel();
resume_writes_alarm_->Cancel();
retransmission_alarm_->Cancel();
send_alarm_->Cancel();
@@ -2112,31 +1961,12 @@ void QuicConnection::SendGoAway(QuicErrorCode error,
QuicFrame(new QuicGoAwayFrame(error, last_good_stream_id, reason)));
}
-void QuicConnection::CloseFecGroupsBefore(QuicPacketNumber packet_number) {
- FecGroupMap::iterator it = group_map_.begin();
- while (it != group_map_.end()) {
- // If the group doesn't protect this packet we can ignore it.
- if (!it->second->IsWaitingForPacketBefore(packet_number)) {
- ++it;
- continue;
- }
- QuicFecGroup* fec_group = it->second;
- DCHECK(!fec_group->CanRevive());
- FecGroupMap::iterator next = it;
- ++next;
- group_map_.erase(it);
- delete fec_group;
- it = next;
- }
-}
-
QuicByteCount QuicConnection::max_packet_length() const {
- return packet_generator_.GetMaxPacketLength();
+ return packet_generator_.GetCurrentMaxPacketLength();
}
void QuicConnection::SetMaxPacketLength(QuicByteCount length) {
- return packet_generator_.SetMaxPacketLength(LimitMaxPacketSize(length),
- /*force=*/false);
+ return packet_generator_.SetMaxPacketLength(LimitMaxPacketSize(length));
}
bool QuicConnection::HasQueuedData() const {
@@ -2184,14 +2014,8 @@ void QuicConnection::SetNetworkTimeouts(QuicTime::Delta handshake_timeout,
void QuicConnection::CheckForTimeout() {
QuicTime now = clock_->ApproximateNow();
- QuicTime time_of_last_packet = QuicTime::Zero();
- if (!FLAGS_quic_use_new_idle_timeout) {
- time_of_last_packet =
- max(time_of_last_received_packet_, time_of_last_sent_new_packet_);
- } else {
- time_of_last_packet =
- max(time_of_last_received_packet_, last_send_for_timeout_);
- }
+ QuicTime time_of_last_packet =
+ max(time_of_last_received_packet_, last_send_for_timeout_);
// |delta| can be < 0 as |now| is approximate time but |time_of_last_packet|
// is accurate time. However, this should not change the behavior of
@@ -2502,4 +2326,11 @@ bool QuicConnection::ack_frame_updated() const {
return received_packet_manager_.ack_frame_updated();
}
+StringPiece QuicConnection::GetCurrentPacket() {
+ if (current_packet_data_ == nullptr) {
+ return StringPiece();
+ }
+ return StringPiece(current_packet_data_, last_size_);
+}
+
} // namespace net
diff --git a/net/quic/quic_connection.h b/net/quic/quic_connection.h
index b9e9ef7..bf4e85c 100644
--- a/net/quic/quic_connection.h
+++ b/net/quic/quic_connection.h
@@ -54,7 +54,6 @@ class QuicClock;
class QuicConfig;
class QuicConnection;
class QuicEncrypter;
-class QuicFecGroup;
class QuicRandom;
namespace test {
@@ -234,11 +233,6 @@ class NET_EXPORT_PRIVATE QuicConnectionDebugVisitor
virtual void OnVersionNegotiationPacket(
const QuicVersionNegotiationPacket& packet) {}
- // Called after a packet has been successfully parsed which results
- // in the revival of a packet via FEC.
- virtual void OnRevivedPacket(const QuicPacketHeader& revived_header,
- base::StringPiece payload) {}
-
// Called when the connection is closed.
virtual void OnConnectionClosed(QuicErrorCode error,
ConnectionCloseSource source) {}
@@ -307,6 +301,8 @@ class NET_EXPORT_PRIVATE QuicConnection
BUNDLE_PENDING_ACK = 2,
};
+ enum AckMode { TCP_ACKING, ACK_DECIMATION, ACK_DECIMATION_WITH_REORDERING };
+
// Constructs a new QuicConnection for |connection_id| and |address| using
// |writer| to write packets. |owns_writer| specifies whether the connection
// takes ownership of |writer|. |helper| must outlive this connection.
@@ -342,10 +338,7 @@ class NET_EXPORT_PRIVATE QuicConnection
// Returns a pair with the number of bytes consumed from data, and a boolean
// indicating if the fin bit was consumed. This does not indicate the data
// has been sent on the wire: it may have been turned into a packet and queued
- // if the socket was unexpectedly blocked. |fec_protection| indicates if
- // data is to be FEC protected. Note that data that is sent immediately
- // following MUST_FEC_PROTECT data may get protected by falling within the
- // same FEC group.
+ // if the socket was unexpectedly blocked.
// If |listener| is provided, then it will be informed once ACKs have been
// received for all the packets written in this call.
// The |listener| is not owned by the QuicConnection and must outlive it.
@@ -353,7 +346,6 @@ class NET_EXPORT_PRIVATE QuicConnection
QuicIOVector iov,
QuicStreamOffset offset,
bool fin,
- FecProtection fec_protection,
QuicAckListenerInterface* listener);
// Send a RST_STREAM frame to the peer.
@@ -392,8 +384,7 @@ class NET_EXPORT_PRIVATE QuicConnection
const QuicConnectionStats& GetStats();
// Processes an incoming UDP packet (consisting of a QuicEncryptedPacket) from
- // the peer. If processing this packet permits a packet to be revived from
- // its FEC group that packet will be revived and processed.
+ // the peer.
// In a client, the packet may be "stray" and have a different connection ID
// than that of this connection.
virtual void ProcessUdpPacket(const IPEndPoint& self_address,
@@ -412,6 +403,10 @@ class NET_EXPORT_PRIVATE QuicConnection
// If the socket is not blocked, writes queued packets.
void WriteIfNotBlocked();
+ // If the socket is not blocked, writes queued packets and bundles any pending
+ // ACKs.
+ void WriteAndBundleAcksIfNotBlocked();
+
// Set the packet writer.
void SetQuicPacketWriter(QuicPacketWriter* writer, bool owns_writer) {
DCHECK(writer != nullptr);
@@ -440,13 +435,11 @@ class NET_EXPORT_PRIVATE QuicConnection
void OnPublicResetPacket(const QuicPublicResetPacket& packet) override;
void OnVersionNegotiationPacket(
const QuicVersionNegotiationPacket& packet) override;
- void OnRevivedPacket() override;
bool OnUnauthenticatedPublicHeader(
const QuicPacketPublicHeader& header) override;
bool OnUnauthenticatedHeader(const QuicPacketHeader& header) override;
void OnDecryptedPacket(EncryptionLevel level) override;
bool OnPacketHeader(const QuicPacketHeader& header) override;
- void OnFecProtectedPayload(base::StringPiece payload) override;
bool OnStreamFrame(const QuicStreamFrame& frame) override;
bool OnAckFrame(const QuicAckFrame& frame) override;
bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override;
@@ -457,7 +450,6 @@ class NET_EXPORT_PRIVATE QuicConnection
bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override;
bool OnBlockedFrame(const QuicBlockedFrame& frame) override;
bool OnPathCloseFrame(const QuicPathCloseFrame& frame) override;
- void OnFecData(base::StringPiece redundnancy) override;
void OnPacketComplete() override;
// QuicPacketGenerator::DelegateInterface
@@ -470,7 +462,6 @@ class NET_EXPORT_PRIVATE QuicConnection
void OnSerializedPacket(SerializedPacket* packet) override;
void OnUnrecoverableError(QuicErrorCode error,
ConnectionCloseSource source) override;
- void OnResetFecGroup() override;
// QuicSentPacketManager::NetworkChangeVisitor
void OnCongestionWindowChange() override;
@@ -516,8 +507,6 @@ class NET_EXPORT_PRIVATE QuicConnection
return server_supported_versions_;
}
- size_t NumFecGroups() const { return group_map_.size(); }
-
// Testing only.
size_t NumQueuedPackets() const { return queued_packets_.size(); }
@@ -555,10 +544,6 @@ class NET_EXPORT_PRIVATE QuicConnection
// remaining unacked packets.
void OnRetransmissionTimeout();
- // Called when a data packet is sent. Starts an alarm if the data sent in
- // |packet_number| was FEC protected.
- void MaybeSetFecAlarm(QuicPacketNumber packet_number);
-
// Retransmits all unacked packets with retransmittable frames if
// |retransmission_type| is ALL_UNACKED_PACKETS, otherwise retransmits only
// initially encrypted packets. Used when the negotiated protocol version is
@@ -676,6 +661,8 @@ class NET_EXPORT_PRIVATE QuicConnection
QuicConnectionHelperInterface* helper() { return helper_; }
+ base::StringPiece GetCurrentPacket();
+
protected:
// Send a packet to the peer, and takes ownership of the packet if the packet
// cannot be written immediately.
@@ -711,12 +698,18 @@ class NET_EXPORT_PRIVATE QuicConnection
per_packet_options_ = options;
}
+ // If |defer| is true, configures the connection to defer sending packets in
+ // response to an ACK to the SendAlarm. If |defer| is false, packets may be
+ // sent immediately after receiving an ACK.
+ void set_defer_send_in_response_to_packets(bool defer) {
+ defer_send_in_response_to_packets_ = defer;
+ }
+
private:
friend class test::QuicConnectionPeer;
friend class test::PacketSavingConnection;
typedef std::list<SerializedPacket> QueuedPacketList;
- typedef std::map<QuicFecGroupNumber, QuicFecGroup*> FecGroupMap;
// Writes the given packet to socket, encrypted with packet's
// encryption_level. Returns true on successful write, and false if the writer
@@ -767,10 +760,6 @@ class NET_EXPORT_PRIVATE QuicConnection
// Attempts to process any queued undecryptable packets.
void MaybeProcessUndecryptablePackets();
- // If a packet can be revived from the current FEC group, then
- // revive and process the packet.
- void MaybeProcessRevivedPacket();
-
void ProcessAckFrame(const QuicAckFrame& incoming_ack);
void ProcessStopWaitingFrame(const QuicStopWaitingFrame& stop_waiting);
@@ -787,13 +776,6 @@ class NET_EXPORT_PRIVATE QuicConnection
// to be sent if there are no outstanding packets.
QuicPacketNumber GetLeastUnacked() const;
- // Get the FEC group associate with the last processed packet or nullptr, if
- // the group has already been deleted.
- QuicFecGroup* GetFecGroup();
-
- // Closes any FEC groups protecting packets before |packet_number|.
- void CloseFecGroupsBefore(QuicPacketNumber packet_number);
-
// Sets the timeout alarm to the appropriate value, if any.
void SetTimeoutAlarm();
@@ -865,8 +847,10 @@ class NET_EXPORT_PRIVATE QuicConnection
// True if the last packet has gotten far enough in the framer to be
// decrypted.
bool last_packet_decrypted_;
- bool last_packet_revived_; // True if the last packet was revived from FEC.
QuicByteCount last_size_; // Size of the last received packet.
+ // TODO(rch): remove this when b/27221014 is fixed.
+ const char* current_packet_data_; // UDP payload of packet currently being
+ // parsed or nullptr.
EncryptionLevel last_decrypted_packet_level_;
QuicPacketHeader last_header_;
QuicStopWaitingFrame last_stop_waiting_frame_;
@@ -910,8 +894,6 @@ class NET_EXPORT_PRIVATE QuicConnection
// This is particularly important on mobile, where connections are short.
bool silent_close_enabled_;
- FecGroupMap group_map_;
-
QuicReceivedPacketManager received_packet_manager_;
QuicSentEntropyManager sent_entropy_manager_;
@@ -919,13 +901,15 @@ class NET_EXPORT_PRIVATE QuicConnection
bool ack_queued_;
// How many retransmittable packets have arrived without sending an ack.
QuicPacketCount num_retransmittable_packets_received_since_last_ack_sent_;
+ // Whether there were missing packets in the last sent ack.
+ bool last_ack_had_missing_packets_;
// How many consecutive packets have arrived without sending an ack.
QuicPacketCount num_packets_received_since_last_ack_sent_;
// Indicates how many consecutive times an ack has arrived which indicates
// the peer needs to stop waiting for some packets.
int stop_waiting_count_;
- // When true, ack only every 10 packets as long as they arrive close together.
- bool ack_decimation_enabled_;
+ // Indicates the current ack mode, defaults to acking every 2 packets.
+ AckMode ack_mode_;
// Indicates the retransmit alarm is going to be set by the
// ScopedRetransmitAlarmDelayer
@@ -933,6 +917,10 @@ class NET_EXPORT_PRIVATE QuicConnection
// Indicates the retransmission alarm needs to be set.
bool pending_retransmission_alarm_;
+ // If true, defer sending data in response to received packets to the
+ // SendAlarm.
+ bool defer_send_in_response_to_packets_;
+
// Arena to store class implementations within the QuicConnection.
QuicConnectionArena arena_;
@@ -959,9 +947,6 @@ class NET_EXPORT_PRIVATE QuicConnection
QuicPacketGenerator packet_generator_;
- // An alarm that fires when an FEC packet should be sent.
- QuicArenaScopedPtr<QuicAlarm> fec_alarm_;
-
// Network idle time before this connection is closed.
QuicTime::Delta idle_network_timeout_;
// The connection will wait this long for the handshake to complete.
diff --git a/net/quic/quic_connection_logger.cc b/net/quic/quic_connection_logger.cc
index 6b82396..ad4775d 100644
--- a/net/quic/quic_connection_logger.cc
+++ b/net/quic/quic_connection_logger.cc
@@ -124,9 +124,6 @@ scoped_ptr<base::Value> NetLogQuicAckFrameCallback(
for (QuicPacketNumber packet : frame->missing_packets)
missing->AppendString(base::Uint64ToString(packet));
- dict->SetString("latest_revived_packet",
- base::Int64ToString(frame->latest_revived_packet));
-
base::ListValue* received = new base::ListValue();
dict->Set("received_packet_times", received);
const PacketTimeVector& received_times = frame->received_packet_times;
@@ -640,14 +637,6 @@ void QuicConnectionLogger::OnVersionNegotiationPacket(
base::Bind(&NetLogQuicVersionNegotiationPacketCallback, &packet));
}
-void QuicConnectionLogger::OnRevivedPacket(
- const QuicPacketHeader& revived_header,
- base::StringPiece payload) {
- net_log_.AddEvent(
- NetLog::TYPE_QUIC_SESSION_PACKET_HEADER_REVIVED,
- base::Bind(&NetLogQuicPacketHeaderCallback, &revived_header));
-}
-
void QuicConnectionLogger::OnCryptoHandshakeMessageReceived(
const CryptoHandshakeMessage& message) {
net_log_.AddEvent(
diff --git a/net/quic/quic_connection_logger.h b/net/quic/quic_connection_logger.h
index f059ef9..4aba233 100644
--- a/net/quic/quic_connection_logger.h
+++ b/net/quic/quic_connection_logger.h
@@ -69,8 +69,6 @@ class NET_EXPORT_PRIVATE QuicConnectionLogger
void OnPublicResetPacket(const QuicPublicResetPacket& packet) override;
void OnVersionNegotiationPacket(
const QuicVersionNegotiationPacket& packet) override;
- void OnRevivedPacket(const QuicPacketHeader& revived_header,
- base::StringPiece payload) override;
void OnConnectionClosed(QuicErrorCode error,
ConnectionCloseSource source) override;
void OnSuccessfulVersionNegotiation(const QuicVersion& version) override;
diff --git a/net/quic/quic_connection_stats.cc b/net/quic/quic_connection_stats.cc
index f314452..bb3130f 100644
--- a/net/quic/quic_connection_stats.cc
+++ b/net/quic/quic_connection_stats.cc
@@ -24,7 +24,6 @@ QuicConnectionStats::QuicConnectionStats()
packets_lost(0),
slowstart_packets_sent(0),
slowstart_packets_lost(0),
- packets_revived(0),
packets_dropped(0),
crypto_retransmit_count(0),
loss_timeout_count(0),
diff --git a/net/quic/quic_connection_stats.h b/net/quic/quic_connection_stats.h
index 2787612..b955b66 100644
--- a/net/quic/quic_connection_stats.h
+++ b/net/quic/quic_connection_stats.h
@@ -26,7 +26,7 @@ struct NET_EXPORT_PRIVATE QuicConnectionStats {
std::ostream& os,
const QuicConnectionStats& s);
- QuicByteCount bytes_sent; // Includes retransmissions, fec.
+ QuicByteCount bytes_sent; // Includes retransmissions.
QuicPacketCount packets_sent;
// Non-retransmitted bytes sent in a stream frame.
QuicByteCount stream_bytes_sent;
@@ -35,7 +35,7 @@ struct NET_EXPORT_PRIVATE QuicConnectionStats {
// These include version negotiation and public reset packets, which do not
// have packet numbers or frame data.
- QuicByteCount bytes_received; // Includes duplicate data for a stream, fec.
+ QuicByteCount bytes_received; // Includes duplicate data for a stream.
// Includes packets which were not processable.
QuicPacketCount packets_received;
// Excludes packets which were not processable.
@@ -55,7 +55,6 @@ struct NET_EXPORT_PRIVATE QuicConnectionStats {
// Number of packets lost exiting slow start.
QuicPacketCount slowstart_packets_lost;
- QuicPacketCount packets_revived;
QuicPacketCount packets_dropped; // Duplicate or less than least unacked.
size_t crypto_retransmit_count;
// Count of times the loss detection alarm fired. At least one packet should
diff --git a/net/quic/quic_connection_test.cc b/net/quic/quic_connection_test.cc
index c30ac0a..969fcf2 100644
--- a/net/quic/quic_connection_test.cc
+++ b/net/quic/quic_connection_test.cc
@@ -141,8 +141,8 @@ class TaggingDecrypter : public QuicDecrypter {
bool DecryptPacket(QuicPathId path_id,
QuicPacketNumber packet_number,
- const StringPiece& associated_data,
- const StringPiece& ciphertext,
+ StringPiece associated_data,
+ StringPiece ciphertext,
char* output,
size_t* output_length,
size_t max_output_length) override {
@@ -482,31 +482,9 @@ class TestConnection : public QuicConnection {
QuicStreamOffset offset,
bool fin,
QuicAckListenerInterface* listener) {
- return SendStreamDataWithStringHelper(id, data, offset, fin,
- MAY_FEC_PROTECT, listener);
- }
-
- QuicConsumedData SendStreamDataWithStringWithFec(
- QuicStreamId id,
- StringPiece data,
- QuicStreamOffset offset,
- bool fin,
- QuicAckListenerInterface* listener) {
- return SendStreamDataWithStringHelper(id, data, offset, fin,
- MUST_FEC_PROTECT, listener);
- }
-
- QuicConsumedData SendStreamDataWithStringHelper(
- QuicStreamId id,
- StringPiece data,
- QuicStreamOffset offset,
- bool fin,
- FecProtection fec_protection,
- QuicAckListenerInterface* listener) {
struct iovec iov;
QuicIOVector data_iov(MakeIOVector(data, &iov));
- return QuicConnection::SendStreamData(id, data_iov, offset, fin,
- fec_protection, listener);
+ return QuicConnection::SendStreamData(id, data_iov, offset, fin, listener);
}
QuicConsumedData SendStreamData3() {
@@ -514,20 +492,11 @@ class TestConnection : public QuicConnection {
nullptr);
}
- QuicConsumedData SendStreamData3WithFec() {
- return SendStreamDataWithStringWithFec(kClientDataStreamId1, "food", 0,
- !kFin, nullptr);
- }
-
QuicConsumedData SendStreamData5() {
return SendStreamDataWithString(kClientDataStreamId2, "food2", 0, !kFin,
nullptr);
}
- QuicConsumedData SendStreamData5WithFec() {
- return SendStreamDataWithStringWithFec(kClientDataStreamId2, "food2", 0,
- !kFin, nullptr);
- }
// Ensures the connection can write stream data before writing.
QuicConsumedData EnsureWritableAndSendStreamData5() {
EXPECT_TRUE(CanWriteStreamData());
@@ -586,11 +555,6 @@ class TestConnection : public QuicConnection {
QuicConnectionPeer::GetPingAlarm(this));
}
- TestConnectionHelper::TestAlarm* GetFecAlarm() {
- return reinterpret_cast<TestConnectionHelper::TestAlarm*>(
- QuicConnectionPeer::GetFecAlarm(this));
- }
-
TestConnectionHelper::TestAlarm* GetResumeWritesAlarm() {
return reinterpret_cast<TestConnectionHelper::TestAlarm*>(
QuicConnectionPeer::GetResumeWritesAlarm(this));
@@ -617,6 +581,7 @@ class TestConnection : public QuicConnection {
}
using QuicConnection::SelectMutualVersion;
+ using QuicConnection::set_defer_send_in_response_to_packets;
private:
TestPacketWriter* writer() {
@@ -626,34 +591,23 @@ class TestConnection : public QuicConnection {
DISALLOW_COPY_AND_ASSIGN(TestConnection);
};
-// Used for testing packets revived from FEC packets.
-class FecQuicConnectionDebugVisitor : public QuicConnectionDebugVisitor {
- public:
- void OnRevivedPacket(const QuicPacketHeader& header,
- StringPiece data) override {
- revived_header_ = header;
- }
-
- // Public accessor method.
- QuicPacketHeader revived_header() const { return revived_header_; }
+enum class AckResponse { kDefer, kImmediate };
- private:
- QuicPacketHeader revived_header_;
-};
-
-// Run tests with combinations of {QuicVersion, fec_send_policy}.
+// Run tests with combinations of {QuicVersion, AckResponse}.
struct TestParams {
- TestParams(QuicVersion version, FecSendPolicy fec_send_policy)
- : version(version), fec_send_policy(fec_send_policy) {}
+ TestParams(QuicVersion version, AckResponse ack_response)
+ : version(version), ack_response(ack_response) {}
friend ostream& operator<<(ostream& os, const TestParams& p) {
os << "{ client_version: " << QuicVersionToString(p.version)
- << " fec_send_policy: " << p.fec_send_policy << " }";
+ << " ack_response: "
+ << (p.ack_response == AckResponse::kDefer ? "defer" : "immediate")
+ << " }";
return os;
}
QuicVersion version;
- FecSendPolicy fec_send_policy;
+ AckResponse ack_response;
};
// Constructs various test permutations.
@@ -661,8 +615,10 @@ vector<TestParams> GetTestParams() {
vector<TestParams> params;
QuicVersionVector all_supported_versions = QuicSupportedVersions();
for (size_t i = 0; i < all_supported_versions.size(); ++i) {
- params.push_back(TestParams(all_supported_versions[i], FEC_ANY_TRIGGER));
- params.push_back(TestParams(all_supported_versions[i], FEC_ALARM_TRIGGER));
+ for (AckResponse ack_response :
+ {AckResponse::kDefer, AckResponse::kImmediate}) {
+ params.push_back(TestParams(all_supported_versions[i], ack_response));
+ }
}
return params;
}
@@ -696,12 +652,13 @@ class QuicConnectionTest : public ::testing::TestWithParam<TestParams> {
frame2_(1, false, 3, StringPiece(data2)),
packet_number_length_(PACKET_6BYTE_PACKET_NUMBER),
connection_id_length_(PACKET_8BYTE_CONNECTION_ID) {
+ connection_.set_defer_send_in_response_to_packets(GetParam().ack_response ==
+ AckResponse::kDefer);
FLAGS_quic_always_log_bugs_for_tests = true;
connection_.set_visitor(&visitor_);
connection_.SetSendAlgorithm(send_algorithm_);
connection_.SetLossAlgorithm(loss_algorithm_);
framer_.set_received_entropy_calculator(&entropy_calculator_);
- generator_->set_fec_send_policy(GetParam().fec_send_policy);
EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _))
.WillRepeatedly(Return(QuicTime::Delta::Zero()));
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
@@ -735,7 +692,6 @@ class QuicConnectionTest : public ::testing::TestWithParam<TestParams> {
// TODO(ianswett): Fix QuicConnectionTests so they don't attempt to write
// non-crypto stream data at ENCRYPTION_NONE.
FLAGS_quic_never_write_unencrypted_data = false;
- FLAGS_quic_no_unencrypted_fec = false;
}
QuicVersion version() { return GetParam().version; }
@@ -761,7 +717,10 @@ class QuicConnectionTest : public ::testing::TestWithParam<TestParams> {
void ProcessPacket(QuicPathId path_id, QuicPacketNumber number) {
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- ProcessDataPacket(path_id, number, 0, !kEntropyFlag);
+ ProcessDataPacket(path_id, number, !kEntropyFlag);
+ if (connection_.GetSendAlarm()->IsSet()) {
+ connection_.GetSendAlarm()->Fire();
+ }
}
QuicPacketEntropyHash ProcessFramePacket(QuicFrame frame) {
@@ -785,6 +744,9 @@ class QuicConnectionTest : public ::testing::TestWithParam<TestParams> {
self_address, peer_address,
QuicEncryptedPacket(serialized_packet.encrypted_buffer,
serialized_packet.encrypted_length));
+ if (connection_.GetSendAlarm()->IsSet()) {
+ connection_.GetSendAlarm()->Fire();
+ }
return serialized_packet.entropy_hash;
}
@@ -814,33 +776,32 @@ class QuicConnectionTest : public ::testing::TestWithParam<TestParams> {
size_t ProcessDataPacket(QuicPathId path_id,
QuicPacketNumber number,
- QuicFecGroupNumber fec_group,
bool entropy_flag) {
- return ProcessDataPacketAtLevel(path_id, number, fec_group, entropy_flag,
- false, ENCRYPTION_NONE);
+ return ProcessDataPacketAtLevel(path_id, number, entropy_flag, false,
+ ENCRYPTION_NONE);
}
size_t ProcessDataPacketAtLevel(QuicPathId path_id,
QuicPacketNumber number,
- QuicFecGroupNumber fec_group,
bool entropy_flag,
bool has_stop_waiting,
EncryptionLevel level) {
- scoped_ptr<QuicPacket> packet(ConstructDataPacket(
- path_id, number, fec_group, entropy_flag, has_stop_waiting));
+ scoped_ptr<QuicPacket> packet(
+ ConstructDataPacket(path_id, number, entropy_flag, has_stop_waiting));
char buffer[kMaxPacketSize];
size_t encrypted_length = framer_.EncryptPayload(
level, path_id, number, *packet, buffer, kMaxPacketSize);
connection_.ProcessUdpPacket(
kSelfAddress, kPeerAddress,
QuicEncryptedPacket(buffer, encrypted_length, false));
+ if (connection_.GetSendAlarm()->IsSet()) {
+ connection_.GetSendAlarm()->Fire();
+ }
return encrypted_length;
}
- void ProcessClosePacket(QuicPathId path_id,
- QuicPacketNumber number,
- QuicFecGroupNumber fec_group) {
- scoped_ptr<QuicPacket> packet(ConstructClosePacket(number, fec_group));
+ void ProcessClosePacket(QuicPathId path_id, QuicPacketNumber number) {
+ scoped_ptr<QuicPacket> packet(ConstructClosePacket(number));
char buffer[kMaxPacketSize];
size_t encrypted_length = framer_.EncryptPayload(
ENCRYPTION_NONE, path_id, number, *packet, buffer, kMaxPacketSize);
@@ -849,106 +810,6 @@ class QuicConnectionTest : public ::testing::TestWithParam<TestParams> {
QuicEncryptedPacket(buffer, encrypted_length, false));
}
- size_t ProcessFecProtectedPacket(QuicPathId path_id,
- QuicPacketNumber number,
- bool expect_revival,
- bool entropy_flag,
- bool has_stop_waiting) {
- return ProcessFecProtectedPacketAtLevel(path_id, number, 1, expect_revival,
- entropy_flag, has_stop_waiting,
- ENCRYPTION_NONE);
- }
-
- size_t ProcessFecProtectedPacketAtLevel(QuicPathId path_id,
- QuicPacketNumber number,
- QuicFecGroupNumber fec_group,
- bool expect_revival,
- bool entropy_flag,
- bool has_stop_waiting,
- EncryptionLevel level) {
- if (expect_revival) {
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- }
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1).RetiresOnSaturation();
- return ProcessDataPacketAtLevel(path_id, number, fec_group, entropy_flag,
- has_stop_waiting, level);
- }
-
- // Processes an FEC packet that covers the packets that would have been
- // received.
- size_t ProcessFecPacket(QuicPathId path_id,
- QuicPacketNumber number,
- QuicPacketNumber min_protected_packet,
- bool expect_revival,
- bool entropy_flag,
- QuicPacket* packet) {
- return ProcessFecPacketAtLevel(path_id, number, min_protected_packet,
- expect_revival, entropy_flag, packet,
- ENCRYPTION_NONE);
- }
-
- // Processes an FEC packet that covers the packets that would have been
- // received.
- size_t ProcessFecPacketAtLevel(QuicPathId path_id,
- QuicPacketNumber number,
- QuicPacketNumber min_protected_packet,
- bool expect_revival,
- bool entropy_flag,
- QuicPacket* packet,
- EncryptionLevel level) {
- if (expect_revival) {
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- }
-
- // Construct the decrypted data packet so we can compute the correct
- // redundancy. If |packet| has been provided then use that, otherwise
- // construct a default data packet.
- scoped_ptr<QuicPacket> data_packet;
- if (packet) {
- data_packet.reset(packet);
- } else {
- data_packet.reset(ConstructDataPacket(path_id, number, 1, !kEntropyFlag,
- !kHasStopWaiting));
- }
-
- QuicPacketHeader header;
- header.public_header.connection_id = connection_id_;
- header.public_header.packet_number_length = packet_number_length_;
- header.public_header.connection_id_length = connection_id_length_;
- header.public_header.multipath_flag = path_id != kDefaultPathId;
- header.path_id = path_id;
- header.packet_number = number;
- header.entropy_flag = entropy_flag;
- header.fec_flag = true;
- header.is_in_fec_group = IN_FEC_GROUP;
- header.fec_group = min_protected_packet;
-
- // Since all data packets in this test have the same payload, the
- // redundancy is either equal to that payload or the xor of that payload
- // with itself, depending on the number of packets.
- if (((number - min_protected_packet) % 2) == 0) {
- for (size_t i = GetStartOfFecProtectedData(
- header.public_header.connection_id_length,
- header.public_header.version_flag,
- header.public_header.multipath_flag,
- header.public_header.packet_number_length);
- i < data_packet->length(); ++i) {
- data_packet->mutable_data()[i] ^= data_packet->data()[i];
- }
- }
-
- scoped_ptr<QuicPacket> fec_packet(
- framer_.BuildFecPacket(header, data_packet->FecProtectedData()));
- char buffer[kMaxPacketSize];
- size_t encrypted_length = framer_.EncryptPayload(
- level, path_id, number, *fec_packet, buffer, kMaxPacketSize);
-
- connection_.ProcessUdpPacket(
- kSelfAddress, kPeerAddress,
- QuicEncryptedPacket(buffer, encrypted_length, false));
- return encrypted_length;
- }
-
QuicByteCount SendStreamDataToPeer(QuicStreamId id,
StringPiece data,
QuicStreamOffset offset,
@@ -1015,7 +876,6 @@ class QuicConnectionTest : public ::testing::TestWithParam<TestParams> {
QuicPacket* ConstructDataPacket(QuicPathId path_id,
QuicPacketNumber number,
- QuicFecGroupNumber fec_group,
bool entropy_flag,
bool has_stop_waiting) {
QuicPacketHeader header;
@@ -1026,8 +886,8 @@ class QuicConnectionTest : public ::testing::TestWithParam<TestParams> {
header.entropy_flag = entropy_flag;
header.path_id = path_id;
header.packet_number = number;
- header.is_in_fec_group = fec_group == 0u ? NOT_IN_FEC_GROUP : IN_FEC_GROUP;
- header.fec_group = fec_group;
+ header.is_in_fec_group = NOT_IN_FEC_GROUP;
+ header.fec_group = 0;
QuicFrames frames;
frames.push_back(QuicFrame(&frame1_));
@@ -1037,13 +897,12 @@ class QuicConnectionTest : public ::testing::TestWithParam<TestParams> {
return ConstructPacket(header, frames);
}
- QuicPacket* ConstructClosePacket(QuicPacketNumber number,
- QuicFecGroupNumber fec_group) {
+ QuicPacket* ConstructClosePacket(QuicPacketNumber number) {
QuicPacketHeader header;
header.public_header.connection_id = connection_id_;
header.packet_number = number;
- header.is_in_fec_group = fec_group == 0u ? NOT_IN_FEC_GROUP : IN_FEC_GROUP;
- header.fec_group = fec_group;
+ header.is_in_fec_group = NOT_IN_FEC_GROUP;
+ header.fec_group = 0;
QuicConnectionCloseFrame qccf;
qccf.error_code = QUIC_PEER_GOING_AWAY;
@@ -1099,7 +958,7 @@ class QuicConnectionTest : public ::testing::TestWithParam<TestParams> {
ConnectionCloseSource::FROM_SELF));
// Call ProcessDataPacket rather than ProcessPacket, as we should not get a
// packet call to the visitor.
- ProcessDataPacket(kDefaultPathId, 6000, 0, !kEntropyFlag);
+ ProcessDataPacket(kDefaultPathId, 6000, !kEntropyFlag);
EXPECT_FALSE(QuicConnectionPeer::GetConnectionClosePacket(&connection_) ==
nullptr);
}
@@ -1346,7 +1205,7 @@ TEST_P(QuicConnectionTest, DuplicatePacket) {
// Send packet 3 again, but do not set the expectation that
// the visitor OnStreamFrame() will be called.
- ProcessDataPacket(kDefaultPathId, 3, 0, !kEntropyFlag);
+ ProcessDataPacket(kDefaultPathId, 3, !kEntropyFlag);
EXPECT_EQ(3u, outgoing_ack()->largest_observed);
EXPECT_TRUE(IsMissing(2));
EXPECT_TRUE(IsMissing(1));
@@ -1387,7 +1246,7 @@ TEST_P(QuicConnectionTest, RejectPacketTooFarOut) {
ConnectionCloseSource::FROM_SELF));
// Call ProcessDataPacket rather than ProcessPacket, as we should not get a
// packet call to the visitor.
- ProcessDataPacket(kDefaultPathId, 6000, 0, !kEntropyFlag);
+ ProcessDataPacket(kDefaultPathId, 6000, !kEntropyFlag);
EXPECT_FALSE(QuicConnectionPeer::GetConnectionClosePacket(&connection_) ==
nullptr);
}
@@ -1398,7 +1257,7 @@ TEST_P(QuicConnectionTest, RejectUnencryptedStreamData) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_UNENCRYPTED_STREAM_DATA,
ConnectionCloseSource::FROM_SELF));
- EXPECT_DFATAL(ProcessDataPacket(kDefaultPathId, 1, 0, !kEntropyFlag), "");
+ EXPECT_DFATAL(ProcessDataPacket(kDefaultPathId, 1, !kEntropyFlag), "");
EXPECT_FALSE(QuicConnectionPeer::GetConnectionClosePacket(&connection_) ==
nullptr);
const vector<QuicConnectionCloseFrame>& connection_close_frames =
@@ -1867,412 +1726,6 @@ TEST_P(QuicConnectionTest, RecordSentTimeBeforePacketSent) {
<< ". Actual time = " << actual_recorded_send_time.ToDebuggingValue();
}
-TEST_P(QuicConnectionTest, FECSending) {
- // All packets carry version info till version is negotiated.
- size_t payload_length;
- // GetPacketLengthForOneStream() assumes a stream offset of 0 in determining
- // packet length. The size of the offset field in a stream frame is 0 for
- // offset 0, and 2 for non-zero offsets up through 64K. Increase
- // max_packet_length by 2 so that subsequent packets containing subsequent
- // stream frames with non-zero offets will fit within the packet length.
- size_t length =
- 2 + GetPacketLengthForOneStream(
- connection_.version(), kIncludeVersion, !kIncludePathId,
- PACKET_8BYTE_CONNECTION_ID, PACKET_1BYTE_PACKET_NUMBER,
- IN_FEC_GROUP, &payload_length);
- connection_.SetMaxPacketLength(length);
-
- if (generator_->fec_send_policy() == FEC_ALARM_TRIGGER) {
- // Send 4 protected data packets. FEC packet is not sent.
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA))
- .Times(4);
- } else {
- // Send 4 protected data packets, which should also trigger 1 FEC packet.
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA))
- .Times(5);
- }
- // The first stream frame will have 2 fewer overhead bytes than the other 3.
- const string payload(payload_length * 4 + 2, 'a');
- connection_.SendStreamDataWithStringWithFec(1, payload, 0, !kFin, nullptr);
- // Expect the FEC group to be closed after SendStreamDataWithString.
- EXPECT_FALSE(creator_->IsFecGroupOpen());
- EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
-}
-
-TEST_P(QuicConnectionTest, FECQueueing) {
- // All packets carry version info till version is negotiated.
- size_t payload_length;
- size_t length = GetPacketLengthForOneStream(
- connection_.version(), kIncludeVersion, !kIncludePathId,
- PACKET_8BYTE_CONNECTION_ID, PACKET_1BYTE_PACKET_NUMBER, IN_FEC_GROUP,
- &payload_length);
- connection_.SetMaxPacketLength(length);
- EXPECT_TRUE(QuicPacketCreatorPeer::IsFecEnabled(creator_));
-
- EXPECT_EQ(0u, connection_.NumQueuedPackets());
- BlockOnNextWrite();
- const string payload(payload_length, 'a');
- connection_.SendStreamDataWithStringWithFec(1, payload, 0, !kFin, nullptr);
- EXPECT_FALSE(creator_->IsFecGroupOpen());
- EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
- if (generator_->fec_send_policy() == FEC_ALARM_TRIGGER) {
- // Expect the first data packet to be queued and not the FEC packet.
- EXPECT_EQ(1u, connection_.NumQueuedPackets());
- } else {
- // Expect the first data packet and the fec packet to be queued.
- EXPECT_EQ(2u, connection_.NumQueuedPackets());
- }
-}
-
-TEST_P(QuicConnectionTest, FECAlarmStoppedWhenFECPacketSent) {
- EXPECT_TRUE(QuicPacketCreatorPeer::IsFecEnabled(creator_));
- EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
- EXPECT_FALSE(connection_.GetFecAlarm()->IsSet());
-
- creator_->set_max_packets_per_fec_group(2);
-
- // 1 Data packet. FEC alarm should be set.
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, 1u, _, HAS_RETRANSMITTABLE_DATA))
- .Times(1);
- connection_.SendStreamDataWithStringWithFec(3, "foo", 0, true, nullptr);
- EXPECT_TRUE(connection_.GetFecAlarm()->IsSet());
-
- if (generator_->fec_send_policy() == FEC_ALARM_TRIGGER) {
- // If FEC send policy is FEC_ALARM_TRIGGER, FEC packet is not sent.
- // FEC alarm should not be set.
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA))
- .Times(1);
- } else {
- // Second data packet triggers FEC packet out. FEC alarm should not be set.
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA))
- .Times(2);
- }
- connection_.SendStreamDataWithStringWithFec(5, "foo", 0, true, nullptr);
- if (generator_->fec_send_policy() == FEC_ANY_TRIGGER) {
- EXPECT_TRUE(writer_->header().fec_flag);
- }
- EXPECT_FALSE(creator_->IsFecGroupOpen());
- EXPECT_FALSE(connection_.GetFecAlarm()->IsSet());
-}
-
-TEST_P(QuicConnectionTest, FECAlarmStoppedOnConnectionClose) {
- EXPECT_TRUE(QuicPacketCreatorPeer::IsFecEnabled(creator_));
- EXPECT_FALSE(connection_.GetFecAlarm()->IsSet());
- creator_->set_max_packets_per_fec_group(100);
-
- // 1 Data packet. FEC alarm should be set.
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, 1u, _, HAS_RETRANSMITTABLE_DATA))
- .Times(1);
- connection_.SendStreamDataWithStringWithFec(3, "foo", 0, kFin, nullptr);
- EXPECT_TRUE(connection_.GetFecAlarm()->IsSet());
-
- EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_NO_ERROR,
- ConnectionCloseSource::FROM_SELF));
- // Closing connection should stop the FEC alarm.
- connection_.CloseConnection(QUIC_NO_ERROR, ConnectionCloseSource::FROM_SELF);
- EXPECT_FALSE(connection_.GetFecAlarm()->IsSet());
-}
-
-TEST_P(QuicConnectionTest, RemoveFECFromInflightOnRetransmissionTimeout) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_TRUE(QuicPacketCreatorPeer::IsFecEnabled(creator_));
- EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
- EXPECT_FALSE(connection_.GetFecAlarm()->IsSet());
-
- // 1 Data packet. FEC alarm should be set.
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, 1u, _, HAS_RETRANSMITTABLE_DATA))
- .Times(1);
- connection_.SendStreamDataWithStringWithFec(3, "foo", 0, !kFin, nullptr);
- EXPECT_TRUE(connection_.GetFecAlarm()->IsSet());
- size_t protected_packet =
- QuicSentPacketManagerPeer::GetBytesInFlight(manager_);
-
- // Force FEC timeout to send FEC packet out.
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, 2u, _, HAS_RETRANSMITTABLE_DATA))
- .Times(1);
- connection_.GetFecAlarm()->Fire();
- EXPECT_TRUE(writer_->header().fec_flag);
-
- size_t fec_packet = protected_packet;
- EXPECT_EQ(protected_packet + fec_packet,
- QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
- clock_.AdvanceTime(DefaultRetransmissionTime());
-
- // On RTO, both data and FEC packets are removed from inflight, only the data
- // packet is retransmitted, and this retransmission (but not FEC) gets added
- // back into the inflight.
- EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- connection_.GetRetransmissionAlarm()->Fire();
-
- // The retransmission of packet 1 will be 3 bytes smaller than packet 1, since
- // the first transmission will have 1 byte for FEC group number and 2 bytes of
- // stream frame size, which are absent in the retransmission.
- size_t retransmitted_packet = protected_packet - 3;
- EXPECT_EQ(protected_packet + retransmitted_packet,
- QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
- EXPECT_FALSE(connection_.GetFecAlarm()->IsSet());
-
- // Receive ack for the retransmission. No data should be outstanding.
- QuicAckFrame ack = InitAckFrame(3);
- NackPacket(1, &ack);
- NackPacket(2, &ack);
- SendAlgorithmInterface::CongestionVector lost_packets;
- lost_packets.push_back(std::make_pair(1, kMaxPacketSize));
- EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _))
- .WillOnce(SetArgPointee<3>(lost_packets));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
- ProcessAckPacket(&ack);
-
- // Ensure the alarm is not set since all packets have been acked or abandoned.
- EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
- EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
-}
-
-TEST_P(QuicConnectionTest, RemoveFECFromInflightOnLossRetransmission) {
- EXPECT_TRUE(QuicPacketCreatorPeer::IsFecEnabled(creator_));
- EXPECT_FALSE(connection_.GetFecAlarm()->IsSet());
-
- // 1 FEC-protected data packet. FEC alarm should be set.
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA))
- .Times(1);
- connection_.SendStreamDataWithStringWithFec(3, "foo", 0, kFin, nullptr);
- EXPECT_TRUE(connection_.GetFecAlarm()->IsSet());
- size_t protected_packet =
- QuicSentPacketManagerPeer::GetBytesInFlight(manager_);
-
- // Force FEC timeout to send FEC packet out.
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA))
- .Times(1);
- connection_.GetFecAlarm()->Fire();
- EXPECT_TRUE(writer_->header().fec_flag);
- size_t fec_packet = protected_packet;
- EXPECT_EQ(protected_packet + fec_packet,
- QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
-
- // Send more data to trigger NACKs. Note that all data starts at stream offset
- // 0 to ensure the same packet size, for ease of testing.
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA))
- .Times(4);
- connection_.SendStreamDataWithString(5, "foo", 0, kFin, nullptr);
- connection_.SendStreamDataWithString(7, "foo", 0, kFin, nullptr);
- connection_.SendStreamDataWithString(9, "foo", 0, kFin, nullptr);
- connection_.SendStreamDataWithString(11, "foo", 0, kFin, nullptr);
-
- // An unprotected packet will be 3 bytes smaller than an FEC-protected packet,
- // since the protected packet will have 1 byte for FEC group number and
- // 2 bytes of stream frame size, which are absent in the unprotected packet.
- size_t unprotected_packet = protected_packet - 3;
- EXPECT_EQ(protected_packet + fec_packet + 4 * unprotected_packet,
- QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
- EXPECT_FALSE(connection_.GetFecAlarm()->IsSet());
-
- // Ack data packets, and NACK FEC packet and one data packet. Triggers
- // NACK-based loss detection of both packets, but only data packet is
- // retransmitted and considered outstanding.
- QuicAckFrame ack = InitAckFrame(6);
- NackPacket(2, &ack);
- NackPacket(3, &ack);
- SendAlgorithmInterface::CongestionVector lost_packets;
- lost_packets.push_back(std::make_pair(2, kMaxPacketSize));
- lost_packets.push_back(std::make_pair(3, kMaxPacketSize));
- EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _))
- .WillOnce(SetArgPointee<3>(lost_packets));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA))
- .Times(1);
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- ProcessAckPacket(&ack);
- // On receiving this ack from the server, the client will no longer send
- // version number in subsequent packets, including in this retransmission.
- size_t unprotected_packet_no_version = unprotected_packet - 4;
- EXPECT_EQ(unprotected_packet_no_version,
- QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
-
- // Receive ack for the retransmission. No data should be outstanding.
- QuicAckFrame ack2 = InitAckFrame(7);
- NackPacket(2, &ack2);
- NackPacket(3, &ack2);
- EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
- ProcessAckPacket(&ack2);
- EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
-}
-
-TEST_P(QuicConnectionTest, FECRemainsInflightOnTLPOfEarlierData) {
- // This test checks if TLP is sent correctly when a data and an FEC packet
- // are outstanding. TLP should be sent for the data packet when the
- // retransmission alarm fires.
- // Turn on TLP for this test.
- QuicSentPacketManagerPeer::SetMaxTailLossProbes(manager_, 1);
- EXPECT_TRUE(QuicPacketCreatorPeer::IsFecEnabled(creator_));
- EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
- EXPECT_FALSE(connection_.GetFecAlarm()->IsSet());
-
- // 1 Data packet. FEC alarm should be set.
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, 1u, _, HAS_RETRANSMITTABLE_DATA))
- .Times(1);
- connection_.SendStreamDataWithStringWithFec(3, "foo", 0, kFin, nullptr);
- EXPECT_TRUE(connection_.GetFecAlarm()->IsSet());
- size_t protected_packet =
- QuicSentPacketManagerPeer::GetBytesInFlight(manager_);
- EXPECT_LT(0u, protected_packet);
-
- // Force FEC timeout to send FEC packet out.
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, 2u, _, HAS_RETRANSMITTABLE_DATA))
- .Times(1);
- connection_.GetFecAlarm()->Fire();
- EXPECT_TRUE(writer_->header().fec_flag);
- size_t fec_packet = protected_packet;
- EXPECT_EQ(protected_packet + fec_packet,
- QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
-
- // TLP alarm should be set.
- QuicTime retransmission_time =
- connection_.GetRetransmissionAlarm()->deadline();
- EXPECT_NE(QuicTime::Zero(), retransmission_time);
- // Simulate the retransmission alarm firing and sending a TLP, so send
- // algorithm's OnRetransmissionTimeout is not called.
- clock_.AdvanceTime(retransmission_time.Subtract(clock_.Now()));
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, 3u, _, HAS_RETRANSMITTABLE_DATA))
- .Times(1);
- connection_.GetRetransmissionAlarm()->Fire();
- // The TLP retransmission of packet 1 will be 3 bytes smaller than packet 1,
- // since packet 1 will have 1 byte for FEC group number and 2 bytes of stream
- // frame size, which are absent in the the TLP retransmission.
- size_t tlp_packet = protected_packet - 3;
- EXPECT_EQ(protected_packet + fec_packet + tlp_packet,
- QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
-}
-
-TEST_P(QuicConnectionTest, FECRemainsInflightOnTLPOfLaterData) {
- // Tests if TLP is sent correctly when data packet 1 and an FEC packet are
- // sent followed by data packet 2, and data packet 1 is acked. TLP should be
- // sent for data packet 2 when the retransmission alarm fires. Turn on TLP for
- // this test.
- QuicSentPacketManagerPeer::SetMaxTailLossProbes(manager_, 1);
- EXPECT_TRUE(QuicPacketCreatorPeer::IsFecEnabled(creator_));
- EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
- EXPECT_FALSE(connection_.GetFecAlarm()->IsSet());
-
- // 1 Data packet. FEC alarm should be set.
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, 1u, _, HAS_RETRANSMITTABLE_DATA))
- .Times(1);
- connection_.SendStreamDataWithStringWithFec(3, "foo", 0, kFin, nullptr);
- EXPECT_TRUE(connection_.GetFecAlarm()->IsSet());
- size_t protected_packet =
- QuicSentPacketManagerPeer::GetBytesInFlight(manager_);
- EXPECT_LT(0u, protected_packet);
-
- // Force FEC timeout to send FEC packet out.
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, 2u, _, HAS_RETRANSMITTABLE_DATA))
- .Times(1);
- connection_.GetFecAlarm()->Fire();
- EXPECT_TRUE(writer_->header().fec_flag);
- // Protected data packet and FEC packet oustanding.
- size_t fec_packet = protected_packet;
- EXPECT_EQ(protected_packet + fec_packet,
- QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
-
- // Send 1 unprotected data packet. No FEC alarm should be set.
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, 3u, _, HAS_RETRANSMITTABLE_DATA))
- .Times(1);
- connection_.SendStreamDataWithString(5, "foo", 0, kFin, nullptr);
- EXPECT_FALSE(connection_.GetFecAlarm()->IsSet());
- // Protected data packet, FEC packet, and unprotected data packet oustanding.
- // An unprotected packet will be 3 bytes smaller than an FEC-protected packet,
- // since the protected packet will have 1 byte for FEC group number and
- // 2 bytes of stream frame size, which are absent in the unprotected packet.
- size_t unprotected_packet = protected_packet - 3;
- EXPECT_EQ(protected_packet + fec_packet + unprotected_packet,
- QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
-
- // Receive ack for first data packet. FEC and second data packet are still
- // outstanding.
- QuicAckFrame ack = InitAckFrame(1);
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- ProcessAckPacket(&ack);
- // FEC packet and unprotected data packet oustanding.
- EXPECT_EQ(fec_packet + unprotected_packet,
- QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
-
- // TLP alarm should be set.
- QuicTime retransmission_time =
- connection_.GetRetransmissionAlarm()->deadline();
- EXPECT_NE(QuicTime::Zero(), retransmission_time);
- // Simulate the retransmission alarm firing and sending a TLP, so send
- // algorithm's OnRetransmissionTimeout is not called.
- clock_.AdvanceTime(retransmission_time.Subtract(clock_.Now()));
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, 4u, _, HAS_RETRANSMITTABLE_DATA))
- .Times(1);
- connection_.GetRetransmissionAlarm()->Fire();
-
- // Having received an ack from the server, the client will no longer send
- // version number in subsequent packets, including in this retransmission.
- size_t tlp_packet_no_version = unprotected_packet - 4;
- EXPECT_EQ(fec_packet + unprotected_packet + tlp_packet_no_version,
- QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
-}
-
-TEST_P(QuicConnectionTest, NoTLPForFECPacket) {
- // Turn on TLP for this test.
- QuicSentPacketManagerPeer::SetMaxTailLossProbes(manager_, 1);
- EXPECT_TRUE(QuicPacketCreatorPeer::IsFecEnabled(creator_));
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
- // Send 1 FEC-protected data packet. FEC alarm should be set.
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA))
- .Times(1);
- connection_.SendStreamDataWithStringWithFec(3, "foo", 0, !kFin, nullptr);
- EXPECT_TRUE(connection_.GetFecAlarm()->IsSet());
- // Force FEC timeout to send FEC packet out.
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA))
- .Times(1);
- connection_.GetFecAlarm()->Fire();
- EXPECT_TRUE(writer_->header().fec_flag);
-
- // Ack data packet, but not FEC packet.
- QuicAckFrame ack = InitAckFrame(1);
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
- ProcessAckPacket(&ack);
-
- // No TLP alarm for FEC, but retransmission alarm should be set for an RTO.
- EXPECT_LT(0u, QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
- EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
- QuicTime rto_time = connection_.GetRetransmissionAlarm()->deadline();
- EXPECT_NE(QuicTime::Zero(), rto_time);
-
- // Simulate the retransmission alarm firing. FEC packet is no longer
- // outstanding.
- clock_.AdvanceTime(rto_time.Subtract(clock_.Now()));
- connection_.GetRetransmissionAlarm()->Fire();
-
- EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
- EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
-}
-
TEST_P(QuicConnectionTest, FramePacking) {
// Send an ack and two stream frames in 1 packet by queueing them.
{
@@ -2333,34 +1786,11 @@ TEST_P(QuicConnectionTest, FramePackingCryptoThenNonCrypto) {
EXPECT_EQ(kClientDataStreamId1, writer_->stream_frames()[0]->stream_id);
}
-TEST_P(QuicConnectionTest, FramePackingFEC) {
- EXPECT_TRUE(QuicPacketCreatorPeer::IsFecEnabled(creator_));
-
- // Queue an ack and two stream frames. Ack gets flushed when FEC is turned on
- // for sending protected data; two stream frames are packed in 1 packet.
- {
- QuicConnection::ScopedPacketBundler bundler(&connection_,
- QuicConnection::SEND_ACK);
- connection_.SendStreamData3WithFec();
- connection_.SendStreamData5WithFec();
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- }
- EXPECT_EQ(0u, connection_.NumQueuedPackets());
- EXPECT_FALSE(connection_.HasQueuedData());
-
- // Parse the last packet and ensure it's in an fec group.
- EXPECT_EQ(2u, writer_->header().fec_group);
- EXPECT_EQ(2u, writer_->frame_count());
-
- // FEC alarm should be set.
- EXPECT_TRUE(connection_.GetFecAlarm()->IsSet());
-}
-
TEST_P(QuicConnectionTest, FramePackingAckResponse) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
// Process a data packet to queue up a pending ack.
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- ProcessDataPacket(kDefaultPathId, 1, 1, kEntropyFlag);
+ ProcessDataPacket(kDefaultPathId, 1, kEntropyFlag);
EXPECT_CALL(visitor_, OnCanWrite())
.WillOnce(DoAll(IgnoreResult(InvokeWithoutArgs(
@@ -2398,8 +1828,7 @@ TEST_P(QuicConnectionTest, FramePackingSendv) {
iov[0].iov_len = 2;
iov[1].iov_base = data + 2;
iov[1].iov_len = 2;
- connection_.SendStreamData(1, QuicIOVector(iov, 2, 4), 0, !kFin,
- MAY_FEC_PROTECT, nullptr);
+ connection_.SendStreamData(1, QuicIOVector(iov, 2, 4), 0, !kFin, nullptr);
EXPECT_EQ(0u, connection_.NumQueuedPackets());
EXPECT_FALSE(connection_.HasQueuedData());
@@ -2424,8 +1853,7 @@ TEST_P(QuicConnectionTest, FramePackingSendvQueued) {
iov[0].iov_len = 2;
iov[1].iov_base = data + 2;
iov[1].iov_len = 2;
- connection_.SendStreamData(1, QuicIOVector(iov, 2, 4), 0, !kFin,
- MAY_FEC_PROTECT, nullptr);
+ connection_.SendStreamData(1, QuicIOVector(iov, 2, 4), 0, !kFin, nullptr);
EXPECT_EQ(1u, connection_.NumQueuedPackets());
EXPECT_TRUE(connection_.HasQueuedData());
@@ -2445,7 +1873,7 @@ TEST_P(QuicConnectionTest, SendingZeroBytes) {
// Send a zero byte write with a fin using writev.
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
QuicIOVector empty_iov(nullptr, 0, 0);
- connection_.SendStreamData(1, empty_iov, 0, kFin, MAY_FEC_PROTECT, nullptr);
+ connection_.SendStreamData(1, empty_iov, 0, kFin, nullptr);
EXPECT_EQ(0u, connection_.NumQueuedPackets());
EXPECT_FALSE(connection_.HasQueuedData());
@@ -2985,128 +2413,6 @@ TEST_P(QuicConnectionTest, DontLatchUnackedPacket) {
EXPECT_EQ(6u, stop_waiting()->least_unacked);
}
-TEST_P(QuicConnectionTest, ReviveMissingPacketAfterFecPacket) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
- // Don't send missing packet 1.
- ProcessFecPacket(kDefaultPathId, 2, 1, true, !kEntropyFlag, nullptr);
- // Entropy flag should be false, so entropy should be 0.
- EXPECT_EQ(0u, QuicConnectionPeer::ReceivedEntropyHash(&connection_, 2));
-}
-
-TEST_P(QuicConnectionTest, ReviveMissingPacketWithVaryingSeqNumLengths) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
- // Set up a debug visitor to the connection.
- scoped_ptr<FecQuicConnectionDebugVisitor> fec_visitor(
- new FecQuicConnectionDebugVisitor());
- connection_.set_debug_visitor(fec_visitor.get());
-
- QuicPacketNumber fec_packet = 0;
- // clang-format off
- QuicPacketNumberLength lengths[] = {
- PACKET_6BYTE_PACKET_NUMBER, PACKET_4BYTE_PACKET_NUMBER,
- PACKET_2BYTE_PACKET_NUMBER, PACKET_1BYTE_PACKET_NUMBER};
- // clang-format on
- // For each packet number length size, revive a packet and check sequence
- // number length in the revived packet.
- for (size_t i = 0; i < arraysize(lengths); ++i) {
- // Set packet_number_length_ (for data and FEC packets).
- packet_number_length_ = lengths[i];
- fec_packet += 2;
- // Don't send missing packet, but send fec packet right after it.
- ProcessFecPacket(kDefaultPathId, fec_packet, fec_packet - 1, true,
- !kEntropyFlag, nullptr);
- // packet number length in the revived header should be the same as
- // in the original data/fec packet headers.
- EXPECT_EQ(packet_number_length_,
- fec_visitor->revived_header().public_header.packet_number_length);
- }
-}
-
-TEST_P(QuicConnectionTest, ReviveMissingPacketWithVaryingConnectionIdLengths) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
- // Set up a debug visitor to the connection.
- scoped_ptr<FecQuicConnectionDebugVisitor> fec_visitor(
- new FecQuicConnectionDebugVisitor());
- connection_.set_debug_visitor(fec_visitor.get());
-
- QuicPacketNumber fec_packet = 0;
- QuicConnectionIdLength lengths[] = {
- PACKET_8BYTE_CONNECTION_ID, PACKET_4BYTE_CONNECTION_ID,
- PACKET_1BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID};
- // For each connection id length size, revive a packet and check connection
- // id length in the revived packet.
- for (size_t i = 0; i < arraysize(lengths); ++i) {
- // Set connection id length (for data and FEC packets).
- connection_id_length_ = lengths[i];
- fec_packet += 2;
- // Don't send missing packet, but send fec packet right after it.
- ProcessFecPacket(kDefaultPathId, fec_packet, fec_packet - 1, true,
- !kEntropyFlag, nullptr);
- // Connection id length in the revived header should be the same as
- // in the original data/fec packet headers.
- EXPECT_EQ(connection_id_length_,
- fec_visitor->revived_header().public_header.connection_id_length);
- }
-}
-
-TEST_P(QuicConnectionTest, ReviveMissingPacketAfterDataPacketThenFecPacket) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
- ProcessFecProtectedPacket(kDefaultPathId, 1, false, kEntropyFlag,
- !kHasStopWaiting);
- // Don't send missing packet 2.
- ProcessFecPacket(kDefaultPathId, 3, 1, true, !kEntropyFlag, nullptr);
- // Entropy flag should be true, so entropy should not be 0.
- EXPECT_NE(0u, QuicConnectionPeer::ReceivedEntropyHash(&connection_, 2));
-}
-
-TEST_P(QuicConnectionTest, ReviveMissingPacketAfterDataPacketsThenFecPacket) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
- ProcessFecProtectedPacket(kDefaultPathId, 1, false, !kEntropyFlag,
- !kHasStopWaiting);
- // Don't send missing packet 2.
- ProcessFecProtectedPacket(kDefaultPathId, 3, false, !kEntropyFlag,
- !kHasStopWaiting);
- ProcessFecPacket(kDefaultPathId, 4, 1, true, kEntropyFlag, nullptr);
- // Ensure QUIC no longer revives entropy for lost packets.
- EXPECT_EQ(0u, QuicConnectionPeer::ReceivedEntropyHash(&connection_, 2));
- EXPECT_NE(0u, QuicConnectionPeer::ReceivedEntropyHash(&connection_, 4));
-}
-
-TEST_P(QuicConnectionTest, ReviveMissingPacketAfterDataPacket) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
- // Don't send missing packet 1.
- ProcessFecPacket(kDefaultPathId, 3, 1, false, !kEntropyFlag, nullptr);
- // Out of order.
- ProcessFecProtectedPacket(kDefaultPathId, 2, true, !kEntropyFlag,
- !kHasStopWaiting);
- // Entropy flag should be false, so entropy should be 0.
- EXPECT_EQ(0u, QuicConnectionPeer::ReceivedEntropyHash(&connection_, 2));
-}
-
-TEST_P(QuicConnectionTest, ReviveMissingPacketAfterDataPackets) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
- ProcessFecProtectedPacket(kDefaultPathId, 1, false, !kEntropyFlag,
- !kHasStopWaiting);
- // Don't send missing packet 2.
- ProcessFecPacket(kDefaultPathId, 6, 1, false, kEntropyFlag, nullptr);
- ProcessFecProtectedPacket(kDefaultPathId, 3, false, kEntropyFlag,
- !kHasStopWaiting);
- ProcessFecProtectedPacket(kDefaultPathId, 4, false, kEntropyFlag,
- !kHasStopWaiting);
- ProcessFecProtectedPacket(kDefaultPathId, 5, true, !kEntropyFlag,
- !kHasStopWaiting);
- // Ensure entropy is not revived for the missing packet.
- EXPECT_EQ(0u, QuicConnectionPeer::ReceivedEntropyHash(&connection_, 2));
- EXPECT_NE(0u, QuicConnectionPeer::ReceivedEntropyHash(&connection_, 3));
-}
-
TEST_P(QuicConnectionTest, TLP) {
QuicSentPacketManagerPeer::SetMaxTailLossProbes(manager_, 1);
@@ -3315,7 +2621,7 @@ TEST_P(QuicConnectionTest, BufferNonDecryptablePackets) {
// Process an encrypted packet which can not yet be decrypted which should
// result in the packet being buffered.
- ProcessDataPacketAtLevel(kDefaultPathId, 1, 0, kEntropyFlag, !kHasStopWaiting,
+ ProcessDataPacketAtLevel(kDefaultPathId, 1, kEntropyFlag, !kHasStopWaiting,
ENCRYPTION_INITIAL);
// Transition to the new encryption state and process another encrypted packet
@@ -3324,55 +2630,16 @@ TEST_P(QuicConnectionTest, BufferNonDecryptablePackets) {
connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
connection_.SetEncrypter(ENCRYPTION_INITIAL, new TaggingEncrypter(tag));
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(2);
- ProcessDataPacketAtLevel(kDefaultPathId, 2, 0, kEntropyFlag, !kHasStopWaiting,
+ ProcessDataPacketAtLevel(kDefaultPathId, 2, kEntropyFlag, !kHasStopWaiting,
ENCRYPTION_INITIAL);
// Finally, process a third packet and note that we do not reprocess the
// buffered packet.
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- ProcessDataPacketAtLevel(kDefaultPathId, 3, 0, kEntropyFlag, !kHasStopWaiting,
+ ProcessDataPacketAtLevel(kDefaultPathId, 3, kEntropyFlag, !kHasStopWaiting,
ENCRYPTION_INITIAL);
}
-TEST_P(QuicConnectionTest, ProcessBufferedFECGroup) {
- // SetFromConfig is always called after construction from InitializeSession.
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- QuicConfig config;
- config.set_max_undecryptable_packets(100);
- connection_.SetFromConfig(config);
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- use_tagging_decrypter();
-
- const uint8_t tag = 0x07;
- framer_.SetEncrypter(ENCRYPTION_INITIAL, new TaggingEncrypter(tag));
-
- // Don't send packet 1 and buffer initially encrypted packets.
- ProcessFecProtectedPacketAtLevel(kDefaultPathId, 2, 1, false, !kEntropyFlag,
- !kHasStopWaiting, ENCRYPTION_INITIAL);
- ProcessFecPacketAtLevel(kDefaultPathId, 3, 1, false, kEntropyFlag, nullptr,
- ENCRYPTION_INITIAL);
- // Since the packets were buffered, no FEC group should be open.
- ASSERT_EQ(0u, connection_.NumFecGroups());
-
- // Now send non-fec protected ack packet and close the group.
- QuicStopWaitingFrame frame = InitStopWaitingFrame(4);
- ProcessStopWaitingPacketAtLevel(kDefaultPathId, 4, &frame,
- ENCRYPTION_INITIAL);
-
- // Transition to the new encryption state and process another encrypted packet
- // which should result in the original packets being processed. The missing
- // packet should be revived before the STOP_WAITING packet is processed.
- connection_.SetDecrypter(ENCRYPTION_INITIAL, new StrictTaggingDecrypter(tag));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
- connection_.SetEncrypter(ENCRYPTION_INITIAL, new TaggingEncrypter(tag));
-
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(2).RetiresOnSaturation();
- ProcessDataPacketAtLevel(kDefaultPathId, 5, 0, kEntropyFlag, !kHasStopWaiting,
- ENCRYPTION_INITIAL);
- const QuicConnectionStats& stats = connection_.GetStats();
- EXPECT_EQ(1u, stats.packets_revived);
-}
-
TEST_P(QuicConnectionTest, Buffer100NonDecryptablePackets) {
// SetFromConfig is always called after construction from InitializeSession.
EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
@@ -3388,8 +2655,8 @@ TEST_P(QuicConnectionTest, Buffer100NonDecryptablePackets) {
// Process an encrypted packet which can not yet be decrypted which should
// result in the packet being buffered.
for (QuicPacketNumber i = 1; i <= 100; ++i) {
- ProcessDataPacketAtLevel(kDefaultPathId, i, 0, kEntropyFlag,
- !kHasStopWaiting, ENCRYPTION_INITIAL);
+ ProcessDataPacketAtLevel(kDefaultPathId, i, kEntropyFlag, !kHasStopWaiting,
+ ENCRYPTION_INITIAL);
}
// Transition to the new encryption state and process another encrypted packet
@@ -3398,14 +2665,14 @@ TEST_P(QuicConnectionTest, Buffer100NonDecryptablePackets) {
connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
connection_.SetEncrypter(ENCRYPTION_INITIAL, new TaggingEncrypter(tag));
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(101);
- ProcessDataPacketAtLevel(kDefaultPathId, 101, 0, kEntropyFlag,
- !kHasStopWaiting, ENCRYPTION_INITIAL);
+ ProcessDataPacketAtLevel(kDefaultPathId, 101, kEntropyFlag, !kHasStopWaiting,
+ ENCRYPTION_INITIAL);
// Finally, process a third packet and note that we do not reprocess the
// buffered packet.
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- ProcessDataPacketAtLevel(kDefaultPathId, 102, 0, kEntropyFlag,
- !kHasStopWaiting, ENCRYPTION_INITIAL);
+ ProcessDataPacketAtLevel(kDefaultPathId, 102, kEntropyFlag, !kHasStopWaiting,
+ ENCRYPTION_INITIAL);
}
TEST_P(QuicConnectionTest, TestRetransmitOrder) {
@@ -3501,53 +2768,6 @@ TEST_P(QuicConnectionTest, TestQueued) {
EXPECT_EQ(0u, connection_.NumQueuedPackets());
}
-TEST_P(QuicConnectionTest, CloseFecGroup) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- // Don't send missing packet 1.
- // Don't send missing packet 2.
- ProcessFecProtectedPacket(kDefaultPathId, 3, false, !kEntropyFlag,
- !kHasStopWaiting);
- // Don't send missing FEC packet 3.
- ASSERT_EQ(1u, connection_.NumFecGroups());
-
- // Now send non-fec protected ack packet and close the group.
- QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 4);
- QuicStopWaitingFrame frame = InitStopWaitingFrame(5);
- ProcessStopWaitingPacket(&frame);
- ASSERT_EQ(0u, connection_.NumFecGroups());
-}
-
-TEST_P(QuicConnectionTest,
- CloseFecGroupUnderStopWaitingAndWaitingForPacketsBelowStopWaiting) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- // Don't send missing packet 1.
- ProcessFecProtectedPacket(kDefaultPathId, 2, false, !kEntropyFlag,
- !kHasStopWaiting);
- EXPECT_EQ(1u, connection_.NumFecGroups());
- stop_waiting_ = InitStopWaitingFrame(2);
- ProcessFecProtectedPacket(kDefaultPathId, 3, false, !kEntropyFlag,
- kHasStopWaiting);
- // This Fec group would be closed.
- EXPECT_EQ(0u, connection_.NumFecGroups());
-}
-
-TEST_P(QuicConnectionTest,
- DoNotCloseFecGroupUnderStopWaitingButNotWaitingForPacketsBelow) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- ProcessFecProtectedPacket(kDefaultPathId, 1, false, !kEntropyFlag,
- !kHasStopWaiting);
- ProcessFecProtectedPacket(kDefaultPathId, 2, false, !kEntropyFlag,
- !kHasStopWaiting);
- // Don't send missing packet 3.
- EXPECT_EQ(1u, connection_.NumFecGroups());
- stop_waiting_ = InitStopWaitingFrame(2);
- ProcessFecProtectedPacket(kDefaultPathId, 3, false, !kEntropyFlag,
- kHasStopWaiting);
- // This group will not be closed because this group is not waiting for packets
- // below stop waiting.
- EXPECT_EQ(1u, connection_.NumFecGroups());
-}
-
TEST_P(QuicConnectionTest, InitialTimeout) {
EXPECT_TRUE(connection_.connected());
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
@@ -3573,7 +2793,6 @@ TEST_P(QuicConnectionTest, InitialTimeout) {
EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
- EXPECT_FALSE(connection_.GetFecAlarm()->IsSet());
EXPECT_FALSE(connection_.GetResumeWritesAlarm()->IsSet());
EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
@@ -3617,7 +2836,6 @@ TEST_P(QuicConnectionTest, HandshakeTimeout) {
EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
- EXPECT_FALSE(connection_.GetFecAlarm()->IsSet());
EXPECT_FALSE(connection_.GetResumeWritesAlarm()->IsSet());
EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
@@ -3898,110 +3116,7 @@ TEST_P(QuicConnectionTest, NoMtuDiscoveryAfterConnectionClosed) {
EXPECT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
}
-TEST_P(QuicConnectionTest, OldTimeoutAfterSend) {
- ValueRestore<bool> old_flags(&FLAGS_quic_use_new_idle_timeout, false);
- EXPECT_TRUE(connection_.connected());
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- QuicConfig config;
- connection_.SetFromConfig(config);
- EXPECT_FALSE(QuicConnectionPeer::IsSilentCloseEnabled(&connection_));
-
- const QuicTime::Delta initial_idle_timeout =
- QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
- const QuicTime::Delta five_ms = QuicTime::Delta::FromMilliseconds(5);
- QuicTime default_timeout = clock_.ApproximateNow().Add(initial_idle_timeout);
-
- // When we send a packet, the timeout will change to 5ms +
- // kInitialIdleTimeoutSecs.
- clock_.AdvanceTime(five_ms);
-
- // Send an ack so we don't set the retransmission alarm.
- SendAckPacketToPeer();
- EXPECT_EQ(default_timeout, connection_.GetTimeoutAlarm()->deadline());
-
- // The original alarm will fire. We should not time out because we had a
- // network event at t=5ms. The alarm will reregister.
- clock_.AdvanceTime(initial_idle_timeout.Subtract(five_ms));
- EXPECT_EQ(default_timeout, clock_.ApproximateNow());
- connection_.GetTimeoutAlarm()->Fire();
- EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
- EXPECT_TRUE(connection_.connected());
- EXPECT_EQ(default_timeout.Add(five_ms),
- connection_.GetTimeoutAlarm()->deadline());
-
- // This time, we should time out.
- EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_NETWORK_IDLE_TIMEOUT,
- ConnectionCloseSource::FROM_SELF));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
- clock_.AdvanceTime(five_ms);
- EXPECT_EQ(default_timeout.Add(five_ms), clock_.ApproximateNow());
- connection_.GetTimeoutAlarm()->Fire();
- EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
- EXPECT_FALSE(connection_.connected());
-}
-
-TEST_P(QuicConnectionTest, OldTimeoutAfterSendSilentClose) {
- ValueRestore<bool> old_flags(&FLAGS_quic_use_new_idle_timeout, false);
- // Same test as above, but complete a handshake which enables silent close,
- // causing no connection close packet to be sent.
- EXPECT_TRUE(connection_.connected());
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- QuicConfig config;
-
- // Create a handshake message that also enables silent close.
- CryptoHandshakeMessage msg;
- string error_details;
- QuicConfig client_config;
- client_config.SetInitialStreamFlowControlWindowToSend(
- kInitialStreamFlowControlWindowForTest);
- client_config.SetInitialSessionFlowControlWindowToSend(
- kInitialSessionFlowControlWindowForTest);
- client_config.SetIdleConnectionStateLifetime(
- QuicTime::Delta::FromSeconds(kDefaultIdleTimeoutSecs),
- QuicTime::Delta::FromSeconds(kDefaultIdleTimeoutSecs));
- client_config.ToHandshakeMessage(&msg);
- const QuicErrorCode error =
- config.ProcessPeerHello(msg, CLIENT, &error_details);
- EXPECT_EQ(QUIC_NO_ERROR, error);
-
- connection_.SetFromConfig(config);
- EXPECT_TRUE(QuicConnectionPeer::IsSilentCloseEnabled(&connection_));
-
- const QuicTime::Delta default_idle_timeout =
- QuicTime::Delta::FromSeconds(kDefaultIdleTimeoutSecs - 1);
- const QuicTime::Delta five_ms = QuicTime::Delta::FromMilliseconds(5);
- QuicTime default_timeout = clock_.ApproximateNow().Add(default_idle_timeout);
-
- // When we send a packet, the timeout will change to 5ms +
- // kInitialIdleTimeoutSecs.
- clock_.AdvanceTime(five_ms);
-
- // Send an ack so we don't set the retransmission alarm.
- SendAckPacketToPeer();
- EXPECT_EQ(default_timeout, connection_.GetTimeoutAlarm()->deadline());
-
- // The original alarm will fire. We should not time out because we had a
- // network event at t=5ms. The alarm will reregister.
- clock_.AdvanceTime(default_idle_timeout.Subtract(five_ms));
- EXPECT_EQ(default_timeout, clock_.ApproximateNow());
- connection_.GetTimeoutAlarm()->Fire();
- EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
- EXPECT_TRUE(connection_.connected());
- EXPECT_EQ(default_timeout.Add(five_ms),
- connection_.GetTimeoutAlarm()->deadline());
-
- // This time, we should time out.
- EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_NETWORK_IDLE_TIMEOUT,
- ConnectionCloseSource::FROM_SELF));
- clock_.AdvanceTime(five_ms);
- EXPECT_EQ(default_timeout.Add(five_ms), clock_.ApproximateNow());
- connection_.GetTimeoutAlarm()->Fire();
- EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
- EXPECT_FALSE(connection_.connected());
-}
-
TEST_P(QuicConnectionTest, TimeoutAfterSend) {
- ValueRestore<bool> old_flags(&FLAGS_quic_use_new_idle_timeout, true);
EXPECT_TRUE(connection_.connected());
EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
QuicConfig config;
@@ -4047,7 +3162,6 @@ TEST_P(QuicConnectionTest, TimeoutAfterSend) {
}
TEST_P(QuicConnectionTest, NewTimeoutAfterSendSilentClose) {
- ValueRestore<bool> old_flags(&FLAGS_quic_use_new_idle_timeout, true);
// Same test as above, but complete a handshake which enables silent close,
// causing no connection close packet to be sent.
EXPECT_TRUE(connection_.connected());
@@ -4159,7 +3273,6 @@ TEST_P(QuicConnectionTest, TimeoutAfterReceive) {
}
TEST_P(QuicConnectionTest, TimeoutAfterReceiveNotSendWhenUnacked) {
- ValueRestore<bool> old_flags(&FLAGS_quic_use_new_idle_timeout, true);
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
EXPECT_TRUE(connection_.connected());
EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
@@ -4220,8 +3333,8 @@ TEST_P(QuicConnectionTest, TimeoutAfterReceiveNotSendWhenUnacked) {
TEST_P(QuicConnectionTest, SendScheduler) {
// Test that if we send a packet without delay, it is not queued.
- QuicPacket* packet = ConstructDataPacket(kDefaultPathId, 1, 0, !kEntropyFlag,
- !kHasStopWaiting);
+ QuicPacket* packet =
+ ConstructDataPacket(kDefaultPathId, 1, !kEntropyFlag, !kHasStopWaiting);
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
connection_.SendPacket(ENCRYPTION_NONE, kDefaultPathId, 1, packet,
kTestEntropyHash, HAS_RETRANSMITTABLE_DATA, false,
@@ -4233,8 +3346,8 @@ TEST_P(QuicConnectionTest, FailToSendFirstPacket) {
// Test that the connection does not crash when it fails to send the first
// packet at which point self_address_ might be uninitialized.
EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(1);
- QuicPacket* packet = ConstructDataPacket(kDefaultPathId, 1, 0, !kEntropyFlag,
- !kHasStopWaiting);
+ QuicPacket* packet =
+ ConstructDataPacket(kDefaultPathId, 1, !kEntropyFlag, !kHasStopWaiting);
writer_->SetShouldWriteFail();
connection_.SendPacket(ENCRYPTION_NONE, kDefaultPathId, 1, packet,
kTestEntropyHash, HAS_RETRANSMITTABLE_DATA, false,
@@ -4242,8 +3355,8 @@ TEST_P(QuicConnectionTest, FailToSendFirstPacket) {
}
TEST_P(QuicConnectionTest, SendSchedulerEAGAIN) {
- QuicPacket* packet = ConstructDataPacket(kDefaultPathId, 1, 0, !kEntropyFlag,
- !kHasStopWaiting);
+ QuicPacket* packet =
+ ConstructDataPacket(kDefaultPathId, 1, !kEntropyFlag, !kHasStopWaiting);
BlockOnNextWrite();
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 1, _, _)).Times(0);
connection_.SendPacket(ENCRYPTION_NONE, kDefaultPathId, 1, packet,
@@ -4257,8 +3370,7 @@ TEST_P(QuicConnectionTest, TestQueueLimitsOnSendStreamData) {
size_t payload_length;
size_t length = GetPacketLengthForOneStream(
connection_.version(), kIncludeVersion, !kIncludePathId,
- PACKET_8BYTE_CONNECTION_ID, PACKET_1BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP,
- &payload_length);
+ PACKET_8BYTE_CONNECTION_ID, PACKET_1BYTE_PACKET_NUMBER, &payload_length);
connection_.SetMaxPacketLength(length);
// Queue the first packet.
@@ -4279,11 +3391,10 @@ TEST_P(QuicConnectionTest, LoopThroughSendingPackets) {
// offset 0, and 2 for non-zero offsets up through 16K. Increase
// max_packet_length by 2 so that subsequent packets containing subsequent
// stream frames with non-zero offets will fit within the packet length.
- size_t length =
- 2 + GetPacketLengthForOneStream(
- connection_.version(), kIncludeVersion, !kIncludePathId,
- PACKET_8BYTE_CONNECTION_ID, PACKET_1BYTE_PACKET_NUMBER,
- NOT_IN_FEC_GROUP, &payload_length);
+ size_t length = 2 + GetPacketLengthForOneStream(
+ connection_.version(), kIncludeVersion,
+ !kIncludePathId, PACKET_8BYTE_CONNECTION_ID,
+ PACKET_1BYTE_PACKET_NUMBER, &payload_length);
connection_.SetMaxPacketLength(length);
// Queue the first packet.
@@ -4356,8 +3467,8 @@ TEST_P(QuicConnectionTest, SendDelayedAck) {
// The same as ProcessPacket(1) except that ENCRYPTION_INITIAL is used
// instead of ENCRYPTION_NONE.
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- ProcessDataPacketAtLevel(kDefaultPathId, 1, 0, !kEntropyFlag,
- !kHasStopWaiting, ENCRYPTION_INITIAL);
+ ProcessDataPacketAtLevel(kDefaultPathId, 1, !kEntropyFlag, !kHasStopWaiting,
+ ENCRYPTION_INITIAL);
// Check if delayed ack timer is running for the expected interval.
EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
@@ -4372,7 +3483,7 @@ TEST_P(QuicConnectionTest, SendDelayedAck) {
}
TEST_P(QuicConnectionTest, SendDelayedAckDecimation) {
- QuicConnectionPeer::EnableAckDecimation(&connection_);
+ QuicConnectionPeer::SetAckMode(&connection_, QuicConnection::ACK_DECIMATION);
const size_t kMinRttMs = 40;
RttStats* rtt_stats = QuicSentPacketManagerPeer::GetRttStats(manager_);
@@ -4394,15 +3505,15 @@ TEST_P(QuicConnectionTest, SendDelayedAckDecimation) {
QuicPacketNumber kFirstDecimatedPacket = 101;
for (unsigned int i = 0; i < kFirstDecimatedPacket - 1; ++i) {
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- ProcessDataPacketAtLevel(kDefaultPathId, 1 + i, 0, !kEntropyFlag,
+ ProcessDataPacketAtLevel(kDefaultPathId, 1 + i, !kEntropyFlag,
!kHasStopWaiting, ENCRYPTION_INITIAL);
}
EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
// The same as ProcessPacket(1) except that ENCRYPTION_INITIAL is used
// instead of ENCRYPTION_NONE.
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- ProcessDataPacketAtLevel(kDefaultPathId, kFirstDecimatedPacket, 0,
- !kEntropyFlag, !kHasStopWaiting, ENCRYPTION_INITIAL);
+ ProcessDataPacketAtLevel(kDefaultPathId, kFirstDecimatedPacket, !kEntropyFlag,
+ !kHasStopWaiting, ENCRYPTION_INITIAL);
// Check if delayed ack timer is running for the expected interval.
EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
@@ -4412,7 +3523,131 @@ TEST_P(QuicConnectionTest, SendDelayedAckDecimation) {
for (int i = 0; i < 9; ++i) {
EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- ProcessDataPacketAtLevel(kDefaultPathId, kFirstDecimatedPacket + 1 + i, 0,
+ ProcessDataPacketAtLevel(kDefaultPathId, kFirstDecimatedPacket + 1 + i,
+ !kEntropyFlag, !kHasStopWaiting,
+ ENCRYPTION_INITIAL);
+ }
+ // Check that ack is sent and that delayed ack alarm is reset.
+ EXPECT_EQ(2u, writer_->frame_count());
+ EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+ EXPECT_FALSE(writer_->ack_frames().empty());
+ EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+}
+
+TEST_P(QuicConnectionTest, SendDelayedAckDecimationWithReordering) {
+ FLAGS_quic_ack_decimation2 = true;
+ QuicConnectionPeer::SetAckMode(
+ &connection_, QuicConnection::ACK_DECIMATION_WITH_REORDERING);
+
+ const size_t kMinRttMs = 40;
+ RttStats* rtt_stats = QuicSentPacketManagerPeer::GetRttStats(manager_);
+ rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
+ QuicTime::Delta::Zero(), QuicTime::Zero());
+ // The ack time should be based on min_rtt/4, since it's less than the
+ // default delayed ack time.
+ QuicTime ack_time = clock_.ApproximateNow().Add(
+ QuicTime::Delta::FromMilliseconds(kMinRttMs / 4));
+ EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+ EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ const uint8_t tag = 0x07;
+ connection_.SetDecrypter(ENCRYPTION_INITIAL, new StrictTaggingDecrypter(tag));
+ framer_.SetEncrypter(ENCRYPTION_INITIAL, new TaggingEncrypter(tag));
+ // Process a packet from the non-crypto stream.
+ frame1_.stream_id = 3;
+
+ // Process all the initial packets in order so there aren't missing packets.
+ QuicPacketNumber kFirstDecimatedPacket = 101;
+ for (unsigned int i = 0; i < kFirstDecimatedPacket - 1; ++i) {
+ EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+ ProcessDataPacketAtLevel(kDefaultPathId, 1 + i, !kEntropyFlag,
+ !kHasStopWaiting, ENCRYPTION_INITIAL);
+ }
+ EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ // The same as ProcessPacket(1) except that ENCRYPTION_INITIAL is used
+ // instead of ENCRYPTION_NONE.
+ EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+ ProcessDataPacketAtLevel(kDefaultPathId, kFirstDecimatedPacket, !kEntropyFlag,
+ !kHasStopWaiting, ENCRYPTION_INITIAL);
+
+ // Check if delayed ack timer is running for the expected interval.
+ EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
+
+ // Process packet 10 first and ensure the alarm is one eighth min_rtt.
+ EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+ ProcessDataPacketAtLevel(kDefaultPathId, kFirstDecimatedPacket + 9,
+ !kEntropyFlag, !kHasStopWaiting, ENCRYPTION_INITIAL);
+ ack_time = clock_.ApproximateNow().Add(QuicTime::Delta::FromMilliseconds(5));
+ EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
+
+ // The 10th received packet causes an ack to be sent.
+ for (int i = 0; i < 8; ++i) {
+ EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+ ProcessDataPacketAtLevel(kDefaultPathId, kFirstDecimatedPacket + 1 + i,
+ !kEntropyFlag, !kHasStopWaiting,
+ ENCRYPTION_INITIAL);
+ }
+ // Check that ack is sent and that delayed ack alarm is reset.
+ EXPECT_EQ(2u, writer_->frame_count());
+ EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+ EXPECT_FALSE(writer_->ack_frames().empty());
+ EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+}
+
+TEST_P(QuicConnectionTest, SendDelayedAckDecimationWithLargeReordering) {
+ FLAGS_quic_ack_decimation2 = true;
+ QuicConnectionPeer::SetAckMode(
+ &connection_, QuicConnection::ACK_DECIMATION_WITH_REORDERING);
+
+ const size_t kMinRttMs = 40;
+ RttStats* rtt_stats = QuicSentPacketManagerPeer::GetRttStats(manager_);
+ rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
+ QuicTime::Delta::Zero(), QuicTime::Zero());
+ // The ack time should be based on min_rtt/4, since it's less than the
+ // default delayed ack time.
+ QuicTime ack_time = clock_.ApproximateNow().Add(
+ QuicTime::Delta::FromMilliseconds(kMinRttMs / 4));
+ EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+ EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ const uint8_t tag = 0x07;
+ connection_.SetDecrypter(ENCRYPTION_INITIAL, new StrictTaggingDecrypter(tag));
+ framer_.SetEncrypter(ENCRYPTION_INITIAL, new TaggingEncrypter(tag));
+ // Process a packet from the non-crypto stream.
+ frame1_.stream_id = 3;
+
+ // Process all the initial packets in order so there aren't missing packets.
+ QuicPacketNumber kFirstDecimatedPacket = 101;
+ for (unsigned int i = 0; i < kFirstDecimatedPacket - 1; ++i) {
+ EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+ ProcessDataPacketAtLevel(kDefaultPathId, 1 + i, !kEntropyFlag,
+ !kHasStopWaiting, ENCRYPTION_INITIAL);
+ }
+ EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ // The same as ProcessPacket(1) except that ENCRYPTION_INITIAL is used
+ // instead of ENCRYPTION_NONE.
+ EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+ ProcessDataPacketAtLevel(kDefaultPathId, kFirstDecimatedPacket, !kEntropyFlag,
+ !kHasStopWaiting, ENCRYPTION_INITIAL);
+
+ // Check if delayed ack timer is running for the expected interval.
+ EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
+
+ // Process packet 10 first and ensure the alarm is one eighth min_rtt.
+ EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+ ProcessDataPacketAtLevel(kDefaultPathId, kFirstDecimatedPacket + 19,
+ !kEntropyFlag, !kHasStopWaiting, ENCRYPTION_INITIAL);
+ ack_time = clock_.ApproximateNow().Add(QuicTime::Delta::FromMilliseconds(5));
+ EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
+
+ // The 10th received packet causes an ack to be sent.
+ for (int i = 0; i < 8; ++i) {
+ EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+ ProcessDataPacketAtLevel(kDefaultPathId, kFirstDecimatedPacket + 1 + i,
!kEntropyFlag, !kHasStopWaiting,
ENCRYPTION_INITIAL);
}
@@ -4421,6 +3656,18 @@ TEST_P(QuicConnectionTest, SendDelayedAckDecimation) {
EXPECT_FALSE(writer_->stop_waiting_frames().empty());
EXPECT_FALSE(writer_->ack_frames().empty());
EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+
+ // The next packet received in order will cause an immediate ack,
+ // because it fills a hole.
+ EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+ ProcessDataPacketAtLevel(kDefaultPathId, kFirstDecimatedPacket + 10,
+ !kEntropyFlag, !kHasStopWaiting, ENCRYPTION_INITIAL);
+ // Check that ack is sent and that delayed ack alarm is reset.
+ EXPECT_EQ(2u, writer_->frame_count());
+ EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+ EXPECT_FALSE(writer_->ack_frames().empty());
+ EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
}
TEST_P(QuicConnectionTest, SendDelayedAckOnHandshakeConfirmed) {
@@ -4594,7 +3841,7 @@ TEST_P(QuicConnectionTest, NoAckSentForClose) {
EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_PEER_GOING_AWAY,
ConnectionCloseSource::FROM_PEER));
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
- ProcessClosePacket(kDefaultPathId, 2, 0);
+ ProcessClosePacket(kDefaultPathId, 2);
}
TEST_P(QuicConnectionTest, SendWhenDisconnected) {
@@ -4605,8 +3852,8 @@ TEST_P(QuicConnectionTest, SendWhenDisconnected) {
ConnectionCloseSource::FROM_SELF);
EXPECT_FALSE(connection_.connected());
EXPECT_FALSE(connection_.CanWriteStreamData());
- QuicPacket* packet = ConstructDataPacket(kDefaultPathId, 1, 0, !kEntropyFlag,
- !kHasStopWaiting);
+ QuicPacket* packet =
+ ConstructDataPacket(kDefaultPathId, 1, !kEntropyFlag, !kHasStopWaiting);
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 1, _, _)).Times(0);
connection_.SendPacket(ENCRYPTION_NONE, kDefaultPathId, 1, packet,
kTestEntropyHash, HAS_RETRANSMITTABLE_DATA, false,
@@ -4684,30 +3931,19 @@ TEST_P(QuicConnectionTest, MissingPacketsBeforeLeastUnacked) {
TEST_P(QuicConnectionTest, ReceivedEntropyHashCalculation) {
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AtLeast(1));
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- ProcessDataPacket(kDefaultPathId, 1, 1, kEntropyFlag);
- ProcessDataPacket(kDefaultPathId, 4, 1, kEntropyFlag);
- ProcessDataPacket(kDefaultPathId, 3, 1, !kEntropyFlag);
- ProcessDataPacket(kDefaultPathId, 7, 1, kEntropyFlag);
- EXPECT_EQ(146u, outgoing_ack()->entropy_hash);
-}
-
-TEST_P(QuicConnectionTest, ReceivedEntropyHashCalculationHalfFEC) {
- // FEC packets should not change the entropy hash calculation.
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AtLeast(1));
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- ProcessDataPacket(kDefaultPathId, 1, 1, kEntropyFlag);
- ProcessFecPacket(kDefaultPathId, 4, 1, false, kEntropyFlag, nullptr);
- ProcessDataPacket(kDefaultPathId, 3, 3, !kEntropyFlag);
- ProcessFecPacket(kDefaultPathId, 7, 3, false, kEntropyFlag, nullptr);
+ ProcessDataPacket(kDefaultPathId, 1, kEntropyFlag);
+ ProcessDataPacket(kDefaultPathId, 4, kEntropyFlag);
+ ProcessDataPacket(kDefaultPathId, 3, !kEntropyFlag);
+ ProcessDataPacket(kDefaultPathId, 7, kEntropyFlag);
EXPECT_EQ(146u, outgoing_ack()->entropy_hash);
}
TEST_P(QuicConnectionTest, UpdateEntropyForReceivedPackets) {
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AtLeast(1));
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- ProcessDataPacket(kDefaultPathId, 1, 1, kEntropyFlag);
- ProcessDataPacket(kDefaultPathId, 5, 1, kEntropyFlag);
- ProcessDataPacket(kDefaultPathId, 4, 1, !kEntropyFlag);
+ ProcessDataPacket(kDefaultPathId, 1, kEntropyFlag);
+ ProcessDataPacket(kDefaultPathId, 5, kEntropyFlag);
+ ProcessDataPacket(kDefaultPathId, 4, !kEntropyFlag);
EXPECT_EQ(34u, outgoing_ack()->entropy_hash);
// Make 4th packet my least unacked, and update entropy for 2, 3 packets.
QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 5);
@@ -4726,9 +3962,9 @@ TEST_P(QuicConnectionTest, UpdateEntropyForReceivedPackets) {
TEST_P(QuicConnectionTest, UpdateEntropyHashUptoCurrentPacket) {
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AtLeast(1));
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- ProcessDataPacket(kDefaultPathId, 1, 1, kEntropyFlag);
- ProcessDataPacket(kDefaultPathId, 5, 1, !kEntropyFlag);
- ProcessDataPacket(kDefaultPathId, 22, 1, kEntropyFlag);
+ ProcessDataPacket(kDefaultPathId, 1, kEntropyFlag);
+ ProcessDataPacket(kDefaultPathId, 5, !kEntropyFlag);
+ ProcessDataPacket(kDefaultPathId, 22, kEntropyFlag);
EXPECT_EQ(66u, outgoing_ack()->entropy_hash);
QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 22);
QuicPacketEntropyHash random_entropy_hash = 85u;
@@ -4739,7 +3975,7 @@ TEST_P(QuicConnectionTest, UpdateEntropyHashUptoCurrentPacket) {
ack_entropy_hash = ProcessStopWaitingPacket(&frame);
EXPECT_EQ((random_entropy_hash + ack_entropy_hash),
outgoing_ack()->entropy_hash);
- ProcessDataPacket(kDefaultPathId, 25, 1, kEntropyFlag);
+ ProcessDataPacket(kDefaultPathId, 25, kEntropyFlag);
EXPECT_EQ((random_entropy_hash + ack_entropy_hash + (1 << (25 % 8))),
outgoing_ack()->entropy_hash);
}
@@ -4761,7 +3997,7 @@ TEST_P(QuicConnectionTest, EntropyCalculationForTruncatedAck) {
} else {
entropy[i] = entropy[i - 1];
}
- ProcessDataPacket(kDefaultPathId, i, 1, entropy_flag);
+ ProcessDataPacket(kDefaultPathId, i, entropy_flag);
}
for (int i = 1; i < 50; ++i) {
EXPECT_EQ(entropy[i],
@@ -4965,52 +4201,6 @@ TEST_P(QuicConnectionTest, CheckSendStats) {
EXPECT_EQ(kDefaultMaxPacketSize, stats.max_packet_size);
}
-TEST_P(QuicConnectionTest, CheckReceiveStats) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
- size_t received_bytes = 0;
- received_bytes += ProcessFecProtectedPacket(kDefaultPathId, 1, false,
- !kEntropyFlag, !kHasStopWaiting);
- received_bytes += ProcessFecProtectedPacket(kDefaultPathId, 3, false,
- !kEntropyFlag, !kHasStopWaiting);
- // Should be counted against dropped packets.
- received_bytes += ProcessDataPacket(kDefaultPathId, 3, 1, !kEntropyFlag);
- received_bytes +=
- ProcessFecPacket(kDefaultPathId, 4, 1, true, !kEntropyFlag, nullptr);
-
- EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
- .WillOnce(Return(QuicBandwidth::Zero()));
-
- const QuicConnectionStats& stats = connection_.GetStats();
- EXPECT_EQ(received_bytes, stats.bytes_received);
- EXPECT_EQ(4u, stats.packets_received);
-
- EXPECT_EQ(1u, stats.packets_revived);
- EXPECT_EQ(1u, stats.packets_dropped);
-}
-
-TEST_P(QuicConnectionTest, TestFecGroupLimits) {
- // Create and return a group for 1.
- ASSERT_TRUE(QuicConnectionPeer::GetFecGroup(&connection_, 1) != nullptr);
-
- // Create and return a group for 2.
- ASSERT_TRUE(QuicConnectionPeer::GetFecGroup(&connection_, 2) != nullptr);
-
- // Create and return a group for 4. This should remove 1 but not 2.
- ASSERT_TRUE(QuicConnectionPeer::GetFecGroup(&connection_, 4) != nullptr);
- ASSERT_TRUE(QuicConnectionPeer::GetFecGroup(&connection_, 1) == nullptr);
- ASSERT_TRUE(QuicConnectionPeer::GetFecGroup(&connection_, 2) != nullptr);
-
- // Create and return a group for 3. This will kill off 2.
- ASSERT_TRUE(QuicConnectionPeer::GetFecGroup(&connection_, 3) != nullptr);
- ASSERT_TRUE(QuicConnectionPeer::GetFecGroup(&connection_, 2) == nullptr);
-
- // Verify that adding 5 kills off 3, despite 4 being created before 3.
- ASSERT_TRUE(QuicConnectionPeer::GetFecGroup(&connection_, 5) != nullptr);
- ASSERT_TRUE(QuicConnectionPeer::GetFecGroup(&connection_, 4) != nullptr);
- ASSERT_TRUE(QuicConnectionPeer::GetFecGroup(&connection_, 3) == nullptr);
-}
-
TEST_P(QuicConnectionTest, ProcessFramesIfPacketClosedConnection) {
// Construct a packet with stream frame and connection close frame.
QuicPacketHeader header;
@@ -5252,116 +4442,6 @@ TEST_P(QuicConnectionTest, AckNotifierCallbackForAckOfNackedPacket) {
ProcessAckPacket(&third_ack_frame);
}
-TEST_P(QuicConnectionTest, AckNotifierFECTriggerCallback) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
- // Create a listener which we expect to be called.
- scoped_refptr<MockAckListener> listener(new MockAckListener);
- EXPECT_CALL(*listener, OnPacketAcked(_, _)).Times(1);
- // Send some data, which will register the listener to be notified.
- connection_.SendStreamDataWithString(1, "foo", 0, !kFin, listener.get());
- connection_.SendStreamDataWithString(2, "bar", 0, !kFin, nullptr);
-
- // Process an ACK from the server with a revived packet, which should trigger
- // the callback.
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
- QuicAckFrame frame = InitAckFrame(2);
- NackPacket(1, &frame);
- frame.latest_revived_packet = 1;
- ProcessAckPacket(&frame);
- // If the ack is processed again, the notifier should not be called again.
- ProcessAckPacket(&frame);
-}
-
-TEST_P(QuicConnectionTest, AckNotifierCallbackAfterFECRecovery) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(visitor_, OnCanWrite());
-
- // Create a listener which we expect to be called.
- scoped_refptr<MockAckListener> listener(new MockAckListener);
- EXPECT_CALL(*listener, OnPacketAcked(_, _)).Times(1);
-
- // Expect ACKs for 1 packet.
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
-
- // Send one packet, and register to be notified on ACK.
- connection_.SendStreamDataWithString(1, "foo", 0, !kFin, listener.get());
-
- // Ack packet gets dropped, but we receive an FEC packet that covers it.
- // Should recover the Ack packet and trigger the notification callback.
- QuicFrames frames;
-
- QuicAckFrame ack_frame = InitAckFrame(1);
- frames.push_back(QuicFrame(&ack_frame));
-
- // Dummy stream frame to satisfy expectations set elsewhere.
- frames.push_back(QuicFrame(&frame1_));
-
- QuicPacketHeader ack_header;
- ack_header.public_header.connection_id = connection_id_;
- ack_header.public_header.reset_flag = false;
- ack_header.public_header.version_flag = false;
- ack_header.entropy_flag = !kEntropyFlag;
- ack_header.fec_flag = true;
- ack_header.packet_number = 1;
- ack_header.is_in_fec_group = IN_FEC_GROUP;
- ack_header.fec_group = 1;
-
- QuicPacket* packet = BuildUnsizedDataPacket(&framer_, ack_header, frames);
-
- // Take the packet which contains the ACK frame, and construct and deliver an
- // FEC packet which allows the ACK packet to be recovered.
- ProcessFecPacket(kDefaultPathId, 2, 1, true, !kEntropyFlag, packet);
-}
-
-TEST_P(QuicConnectionTest, NetworkChangeVisitorCwndCallbackChangesFecState) {
- size_t max_packets_per_fec_group = creator_->max_packets_per_fec_group();
-
- QuicSentPacketManager::NetworkChangeVisitor* visitor =
- QuicSentPacketManagerPeer::GetNetworkChangeVisitor(manager_);
- EXPECT_TRUE(visitor);
-
- // Increase FEC group size by increasing congestion window to a large number.
- EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
- .WillRepeatedly(Return(1000 * kDefaultTCPMSS));
- visitor->OnCongestionWindowChange();
- EXPECT_LT(max_packets_per_fec_group, creator_->max_packets_per_fec_group());
-}
-
-TEST_P(QuicConnectionTest, NetworkChangeVisitorConfigCallbackChangesFecState) {
- QuicSentPacketManager::NetworkChangeVisitor* visitor =
- QuicSentPacketManagerPeer::GetNetworkChangeVisitor(manager_);
- EXPECT_TRUE(visitor);
- EXPECT_EQ(QuicTime::Delta::Zero(),
- QuicPacketCreatorPeer::GetFecTimeout(creator_));
-
- // Verify that sending a config with a new initial rtt changes fec timeout.
- // Create and process a config with a non-zero initial RTT.
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- QuicConfig config;
- config.SetInitialRoundTripTimeUsToSend(300000);
- connection_.SetFromConfig(config);
- EXPECT_LT(QuicTime::Delta::Zero(),
- QuicPacketCreatorPeer::GetFecTimeout(creator_));
-}
-
-TEST_P(QuicConnectionTest, NetworkChangeVisitorRttCallbackChangesFecState) {
- // Verify that sending a config with a new initial rtt changes fec timeout.
- QuicSentPacketManager::NetworkChangeVisitor* visitor =
- QuicSentPacketManagerPeer::GetNetworkChangeVisitor(manager_);
- EXPECT_TRUE(visitor);
- EXPECT_EQ(QuicTime::Delta::Zero(),
- QuicPacketCreatorPeer::GetFecTimeout(creator_));
-
- // Increase FEC timeout by increasing RTT.
- RttStats* rtt_stats = QuicSentPacketManagerPeer::GetRttStats(manager_);
- rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(300),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- visitor->OnRttChange();
- EXPECT_LT(QuicTime::Delta::Zero(),
- QuicPacketCreatorPeer::GetFecTimeout(creator_));
-}
-
TEST_P(QuicConnectionTest, OnPacketHeaderDebugVisitor) {
QuicPacketHeader header;
@@ -5422,43 +4502,6 @@ TEST_P(QuicConnectionTest, NoDataNoFin) {
"Attempt to send empty stream frame");
}
-TEST_P(QuicConnectionTest, FecSendPolicyReceivedConnectionOption) {
- // Test sending SetReceivedConnectionOptions when FEC send policy is
- // FEC_ANY_TRIGGER.
- if (GetParam().fec_send_policy == FEC_ALARM_TRIGGER) {
- return;
- }
- connection_.set_perspective(Perspective::IS_SERVER);
-
- // Test ReceivedConnectionOptions.
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- QuicConfig config;
- QuicTagVector copt;
- copt.push_back(kFSPA);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, copt);
- EXPECT_EQ(FEC_ANY_TRIGGER, generator_->fec_send_policy());
- connection_.SetFromConfig(config);
- EXPECT_EQ(FEC_ALARM_TRIGGER, generator_->fec_send_policy());
-}
-
-// TODO(rtenneti): Delete this code after the 0.25 RTT FEC experiment.
-TEST_P(QuicConnectionTest, FecRTTMultiplierReceivedConnectionOption) {
- connection_.set_perspective(Perspective::IS_SERVER);
-
- // Test ReceivedConnectionOptions.
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- QuicConfig config;
- QuicTagVector copt;
- copt.push_back(kFRTT);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, copt);
- float rtt_multiplier_for_fec_timeout =
- QuicPacketCreatorPeer::GetRttMultiplierForFecTimeout(creator_);
- connection_.SetFromConfig(config);
- // New RTT multiplier is half of the old RTT multiplier.
- EXPECT_EQ(rtt_multiplier_for_fec_timeout,
- QuicPacketCreatorPeer::GetRttMultiplierForFecTimeout(creator_) * 2);
-}
-
TEST_P(QuicConnectionTest, DoNotSendGoAwayTwice) {
EXPECT_FALSE(connection_.goaway_sent());
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
diff --git a/net/quic/quic_crypto_client_stream_test.cc b/net/quic/quic_crypto_client_stream_test.cc
index e95582c..01ea2d4 100644
--- a/net/quic/quic_crypto_client_stream_test.cc
+++ b/net/quic/quic_crypto_client_stream_test.cc
@@ -263,6 +263,8 @@ class QuicCryptoClientStreamStatelessTest : public ::testing::Test {
server_crypto_config_(QuicCryptoServerConfig::TESTING,
QuicRandom::GetInstance(),
CryptoTestUtils::ProofSourceForTesting()),
+ server_compressed_certs_cache_(
+ QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
server_id_(kServerHostname, kServerPort, PRIVACY_MODE_DISABLED) {
TestQuicSpdyClientSession* client_session = nullptr;
CreateClientSessionForTest(
@@ -288,10 +290,10 @@ class QuicCryptoClientStreamStatelessTest : public ::testing::Test {
// Initializes the server_stream_ for stateless rejects.
void InitializeFakeStatelessRejectServer() {
TestQuicSpdyServerSession* server_session = nullptr;
- CreateServerSessionForTest(server_id_, QuicTime::Delta::FromSeconds(100000),
- QuicSupportedVersions(), &helper_,
- &server_crypto_config_, &server_connection_,
- &server_session);
+ CreateServerSessionForTest(
+ server_id_, QuicTime::Delta::FromSeconds(100000),
+ QuicSupportedVersions(), &helper_, &server_crypto_config_,
+ &server_compressed_certs_cache_, &server_connection_, &server_session);
CHECK(server_session);
server_session_.reset(server_session);
CryptoTestUtils::FakeServerOptions options;
@@ -312,6 +314,7 @@ class QuicCryptoClientStreamStatelessTest : public ::testing::Test {
PacketSavingConnection* server_connection_;
scoped_ptr<TestQuicSpdyServerSession> server_session_;
QuicCryptoServerConfig server_crypto_config_;
+ QuicCompressedCertsCache server_compressed_certs_cache_;
QuicServerId server_id_;
};
diff --git a/net/quic/quic_crypto_server_stream.cc b/net/quic/quic_crypto_server_stream.cc
index f53602e..41a701e 100644
--- a/net/quic/quic_crypto_server_stream.cc
+++ b/net/quic/quic_crypto_server_stream.cc
@@ -48,15 +48,18 @@ void ServerHelloNotifier::OnPacketRetransmitted(int /*retransmitted_bytes*/) {}
QuicCryptoServerStream::QuicCryptoServerStream(
const QuicCryptoServerConfig* crypto_config,
+ QuicCompressedCertsCache* compressed_certs_cache,
+ bool use_stateless_rejects_if_peer_supported,
QuicSession* session)
: QuicCryptoServerStreamBase(session),
crypto_config_(crypto_config),
+ compressed_certs_cache_(compressed_certs_cache),
validate_client_hello_cb_(nullptr),
num_handshake_messages_(0),
num_handshake_messages_with_server_nonces_(0),
num_server_config_update_messages_sent_(0),
use_stateless_rejects_if_peer_supported_(
- FLAGS_enable_quic_stateless_reject_support),
+ use_stateless_rejects_if_peer_supported),
peer_supports_stateless_rejects_(false) {
DCHECK_EQ(Perspective::IS_SERVER, session->connection()->perspective());
}
diff --git a/net/quic/quic_crypto_server_stream.h b/net/quic/quic_crypto_server_stream.h
index fc9a7f3..b78e888 100644
--- a/net/quic/quic_crypto_server_stream.h
+++ b/net/quic/quic_crypto_server_stream.h
@@ -11,6 +11,7 @@
#include "base/macros.h"
#include "net/quic/crypto/crypto_handshake.h"
+#include "net/quic/crypto/quic_compressed_certs_cache.h"
#include "net/quic/crypto/quic_crypto_server_config.h"
#include "net/quic/proto/source_address_token.pb.h"
#include "net/quic/quic_config.h"
@@ -52,7 +53,6 @@ class NET_EXPORT_PRIVATE ServerHelloNotifier : public QuicAckListenerInterface {
// various code and test refactoring.
class NET_EXPORT_PRIVATE QuicCryptoServerStreamBase : public QuicCryptoStream {
public:
- // |crypto_config| must outlive the stream.
explicit QuicCryptoServerStreamBase(QuicSession* session)
: QuicCryptoStream(session) {}
~QuicCryptoServerStreamBase() override {}
@@ -93,6 +93,8 @@ class NET_EXPORT_PRIVATE QuicCryptoServerStream
public:
// |crypto_config| must outlive the stream.
QuicCryptoServerStream(const QuicCryptoServerConfig* crypto_config,
+ QuicCompressedCertsCache* compressed_certs_cache,
+ bool use_stateless_rejects_if_peer_supported,
QuicSession* session);
~QuicCryptoServerStream() override;
@@ -165,6 +167,10 @@ class NET_EXPORT_PRIVATE QuicCryptoServerStream
// crypto_config_ contains crypto parameters for the handshake.
const QuicCryptoServerConfig* crypto_config_;
+ // compressed_certs_cache_ contains a set of most recently compressed certs.
+ // Owned by QuicDispatcher.
+ QuicCompressedCertsCache* compressed_certs_cache_;
+
// Server's certificate chain and signature of the server config, as provided
// by ProofSource::GetProof.
QuicCryptoProof crypto_proof_;
diff --git a/net/quic/quic_crypto_server_stream_test.cc b/net/quic/quic_crypto_server_stream_test.cc
index 4b32c18..d4eea18 100644
--- a/net/quic/quic_crypto_server_stream_test.cc
+++ b/net/quic/quic_crypto_server_stream_test.cc
@@ -70,6 +70,8 @@ class QuicCryptoServerStreamTest : public ::testing::TestWithParam<bool> {
: server_crypto_config_(QuicCryptoServerConfig::TESTING,
QuicRandom::GetInstance(),
CryptoTestUtils::ProofSourceForTesting()),
+ server_compressed_certs_cache_(
+ QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
server_id_(kServerHostname, kServerPort, PRIVACY_MODE_DISABLED),
client_crypto_config_(CryptoTestUtils::ProofVerifierForTesting()) {
FLAGS_enable_quic_stateless_reject_support = false;
@@ -107,11 +109,10 @@ class QuicCryptoServerStreamTest : public ::testing::TestWithParam<bool> {
void InitializeServer() {
TestQuicSpdyServerSession* server_session = nullptr;
helpers_.push_back(new MockConnectionHelper);
-
- CreateServerSessionForTest(server_id_, QuicTime::Delta::FromSeconds(100000),
- supported_versions_, helpers_.back(),
- &server_crypto_config_, &server_connection_,
- &server_session);
+ CreateServerSessionForTest(
+ server_id_, QuicTime::Delta::FromSeconds(100000), supported_versions_,
+ helpers_.back(), &server_crypto_config_,
+ &server_compressed_certs_cache_, &server_connection_, &server_session);
CHECK(server_session);
server_session_.reset(server_session);
CryptoTestUtils::FakeServerOptions options;
@@ -186,6 +187,7 @@ class QuicCryptoServerStreamTest : public ::testing::TestWithParam<bool> {
PacketSavingConnection* server_connection_;
scoped_ptr<TestQuicSpdyServerSession> server_session_;
QuicCryptoServerConfig server_crypto_config_;
+ QuicCompressedCertsCache server_compressed_certs_cache_;
QuicServerId server_id_;
// Client state
@@ -375,11 +377,10 @@ TEST_P(QuicCryptoServerStreamTest, ZeroRTT) {
server_stream());
}
- if (FLAGS_require_strike_register_or_server_nonce &&
- !AsyncStrikeRegisterVerification()) {
- EXPECT_EQ(2, client_stream()->num_sent_client_hellos());
- } else {
+ if (AsyncStrikeRegisterVerification()) {
EXPECT_EQ(1, client_stream()->num_sent_client_hellos());
+ } else {
+ EXPECT_EQ(2, client_stream()->num_sent_client_hellos());
}
}
diff --git a/net/quic/quic_flags.cc b/net/quic/quic_flags.cc
index 9878561..7dea7ec 100644
--- a/net/quic/quic_flags.cc
+++ b/net/quic/quic_flags.cc
@@ -62,46 +62,21 @@ bool FLAGS_quic_measure_headers_hol_blocking_time = true;
// Disable QUIC's userspace pacing.
bool FLAGS_quic_disable_pacing = false;
-// If true, QUIC connections will timeout when packets are not being recieved,
-// even if they are being sent.
-bool FLAGS_quic_use_new_idle_timeout = true;
-
// If true, don't send QUIC packets if the send alarm is set.
bool FLAGS_quic_respect_send_alarm2 = true;
-// If true, allow each quic stream to write 16k blocks rather than doing a round
-// robin of one packet per session when ack clocked or paced.
-bool FLAGS_quic_batch_writes = true;
-
-// If true, QUIC sessions will write block streams that attempt to write
-// unencrypted data.
-bool FLAGS_quic_block_unencrypted_writes = true;
-
// If true, Close the connection instead of writing unencrypted stream data.
bool FLAGS_quic_never_write_unencrypted_data = true;
-// If true, clear the FEC group instead of sending it with ENCRYPTION_NONE.
-// Close the connection if we ever try to serialized unencrypted FEC.
-bool FLAGS_quic_no_unencrypted_fec = true;
-
// If true, reject any incoming QUIC which does not have the FIXD tag.
bool FLAGS_quic_require_fix = true;
// If true, headers stream will support receiving PUSH_PROMISE frames.
bool FLAGS_quic_supports_push_promise = false;
-// If true, QUIC servers will attempt to validate a client's source
-// address token using the primary config, even if no server config id
-// is present in the client hello.
-bool FLAGS_quic_validate_stk_without_scid = true;
-
// If true, QUIC will support RFC 7539 variants of ChaCha20 Poly1305.
bool FLAGS_quic_use_rfc7539 = true;
-// If true, require QUIC connections to use a valid server nonce or a non-local
-// strike register.
-bool FLAGS_require_strike_register_or_server_nonce = true;
-
// When turn on, log packet loss into transport connection stats LossEvent.
bool FLAGS_quic_log_loss_event = true;
@@ -141,3 +116,20 @@ bool FLAGS_quic_save_initial_subkey_secret = true;
// If true, the QUIC dispatcher will directly send version negotiation packets
// without needing to create a QUIC session first.
bool FLAGS_quic_stateless_version_negotiation = false;
+
+// QUIC Ack Decimation with tolerance for packet reordering.
+bool FLAGS_quic_ack_decimation2 = true;
+
+// If true, QUIC connections will defer responding to ACKs to their send alarms.
+bool FLAGS_quic_connection_defer_ack_response = true;
+
+// If true, calls to QuicAlarm::Cancel don't do anything if the alarm is not
+// set.
+bool FLAGS_quic_only_cancel_set_alarms = true;
+
+// Simplify QUIC's write path for inplace encryption now that FEC is gone.
+bool FLAGS_quic_inplace_encryption2 = true;
+
+// If true, SpdyFramer will call OnStreamEnd from SpdyFramerVisitorInterface
+// instead of empty-data sentinel calls when the stream is to be ended.
+bool FLAGS_spdy_on_stream_end = true;
diff --git a/net/quic/quic_flags.h b/net/quic/quic_flags.h
index a110e57..c50d527 100644
--- a/net/quic/quic_flags.h
+++ b/net/quic/quic_flags.h
@@ -23,19 +23,13 @@ NET_EXPORT_PRIVATE extern bool FLAGS_quic_require_handshake_confirmation;
NET_EXPORT_PRIVATE extern bool FLAGS_shift_quic_cubic_epoch_when_app_limited;
NET_EXPORT_PRIVATE extern bool FLAGS_quic_measure_headers_hol_blocking_time;
NET_EXPORT_PRIVATE extern bool FLAGS_quic_disable_pacing;
-NET_EXPORT_PRIVATE extern bool FLAGS_quic_use_new_idle_timeout;
NET_EXPORT_PRIVATE extern bool FLAGS_quic_respect_send_alarm2;
-NET_EXPORT_PRIVATE extern bool FLAGS_quic_batch_writes;
-NET_EXPORT_PRIVATE extern bool FLAGS_quic_block_unencrypted_writes;
NET_EXPORT_PRIVATE extern bool FLAGS_quic_never_write_unencrypted_data;
-NET_EXPORT_PRIVATE extern bool FLAGS_quic_no_unencrypted_fec;
NET_EXPORT_PRIVATE extern bool FLAGS_quic_require_fix;
NET_EXPORT_PRIVATE extern bool FLAGS_quic_stateless_version_negotiation;
NET_EXPORT_PRIVATE extern bool FLAGS_quic_supports_push_promise;
NET_EXPORT_PRIVATE extern bool FLAGS_quic_supports_push_promise;
-NET_EXPORT_PRIVATE extern bool FLAGS_quic_validate_stk_without_scid;
NET_EXPORT_PRIVATE extern bool FLAGS_quic_use_rfc7539;
-NET_EXPORT_PRIVATE extern bool FLAGS_require_strike_register_or_server_nonce;
NET_EXPORT_PRIVATE extern bool FLAGS_quic_log_loss_event;
NET_EXPORT_PRIVATE extern bool FLAGS_quic_include_path_id_in_iv;
NET_EXPORT_PRIVATE extern bool FLAGS_quic_cede_correctly;
@@ -46,5 +40,10 @@ NET_EXPORT_PRIVATE extern bool FLAGS_check_peer_address_change_after_decryption;
NET_EXPORT_PRIVATE extern bool FLAGS_quic_log_received_parameters;
NET_EXPORT_PRIVATE extern bool FLAGS_quic_use_new_tcp_sender;
NET_EXPORT_PRIVATE extern bool FLAGS_quic_save_initial_subkey_secret;
+NET_EXPORT_PRIVATE extern bool FLAGS_quic_ack_decimation2;
+NET_EXPORT_PRIVATE extern bool FLAGS_quic_connection_defer_ack_response;
+NET_EXPORT_PRIVATE extern bool FLAGS_quic_only_cancel_set_alarms;
+NET_EXPORT_PRIVATE extern bool FLAGS_quic_inplace_encryption2;
+NET_EXPORT_PRIVATE extern bool FLAGS_spdy_on_stream_end;
#endif // NET_QUIC_QUIC_FLAGS_H_
diff --git a/net/quic/quic_framer.cc b/net/quic/quic_framer.cc
index ac58d57..fa667f2 100644
--- a/net/quic/quic_framer.cc
+++ b/net/quic/quic_framer.cc
@@ -159,13 +159,10 @@ QuicFramer::~QuicFramer() {}
// static
size_t QuicFramer::GetMinStreamFrameSize(QuicStreamId stream_id,
QuicStreamOffset offset,
- bool last_frame_in_packet,
- InFecGroup is_in_fec_group) {
- bool no_stream_frame_length =
- last_frame_in_packet && is_in_fec_group == NOT_IN_FEC_GROUP;
+ bool last_frame_in_packet) {
return kQuicFrameTypeSize + GetStreamIdSize(stream_id) +
GetStreamOffsetSize(offset) +
- (no_stream_frame_length ? 0 : kQuicStreamPayloadLengthSize);
+ (last_frame_in_packet ? 0 : kQuicStreamPayloadLengthSize);
}
// static
@@ -270,7 +267,6 @@ size_t QuicFramer::GetSerializedFrameLength(
size_t free_bytes,
bool first_frame,
bool last_frame,
- InFecGroup is_in_fec_group,
QuicPacketNumberLength packet_number_length) {
// Prevent a rare crash reported in b/19458523.
if ((frame.type == STREAM_FRAME || frame.type == ACK_FRAME) &&
@@ -278,7 +274,6 @@ size_t QuicFramer::GetSerializedFrameLength(
QUIC_BUG << "Cannot compute the length of a null frame. "
<< "type:" << frame.type << "free_bytes:" << free_bytes
<< " first_frame:" << first_frame << " last_frame:" << last_frame
- << " is_in_fec:" << is_in_fec_group
<< " seq num length:" << packet_number_length;
set_error(QUIC_INTERNAL_ERROR);
visitor_->OnError(this);
@@ -288,8 +283,8 @@ size_t QuicFramer::GetSerializedFrameLength(
// PADDING implies end of packet.
return free_bytes;
}
- size_t frame_len = ComputeFrameLength(frame, last_frame, is_in_fec_group,
- packet_number_length);
+ size_t frame_len =
+ ComputeFrameLength(frame, last_frame, packet_number_length);
if (frame_len <= free_bytes) {
// Frame fits within packet. Note that acks may be truncated.
return frame_len;
@@ -336,9 +331,7 @@ size_t QuicFramer::BuildDataPacket(const QuicPacketHeader& header,
size_t i = 0;
for (const QuicFrame& frame : frames) {
// Determine if we should write stream frame length in header.
- const bool no_stream_frame_length =
- (header.is_in_fec_group == NOT_IN_FEC_GROUP) &&
- (i == frames.size() - 1);
+ const bool no_stream_frame_length = i == frames.size() - 1;
if (!AppendTypeByte(frame, no_stream_frame_length, &writer)) {
QUIC_BUG << "AppendTypeByte failed";
return 0;
@@ -421,31 +414,6 @@ size_t QuicFramer::BuildDataPacket(const QuicPacketHeader& header,
return writer.length();
}
-QuicPacket* QuicFramer::BuildFecPacket(const QuicPacketHeader& header,
- StringPiece redundancy) {
- DCHECK_EQ(IN_FEC_GROUP, header.is_in_fec_group);
- DCHECK_NE(0u, header.fec_group);
- size_t len = GetPacketHeaderSize(header);
- len += redundancy.length();
-
- scoped_ptr<char[]> buffer(new char[len]);
- QuicDataWriter writer(len, buffer.get());
- if (!AppendPacketHeader(header, &writer)) {
- QUIC_BUG << "AppendPacketHeader failed";
- return nullptr;
- }
-
- if (!writer.WriteBytes(redundancy.data(), redundancy.length())) {
- QUIC_BUG << "Failed to add FEC";
- return nullptr;
- }
-
- return new QuicPacket(
- buffer.release(), len, true, header.public_header.connection_id_length,
- header.public_header.version_flag, header.public_header.multipath_flag,
- header.public_header.packet_number_length);
-}
-
// static
QuicEncryptedPacket* QuicFramer::BuildPublicResetPacket(
const QuicPublicResetPacket& packet) {
@@ -619,19 +587,12 @@ bool QuicFramer::ProcessDataPacket(QuicDataReader* encrypted_reader,
return RaiseError(QUIC_PACKET_TOO_LARGE);
}
+ DCHECK(!header.fec_flag);
// Handle the payload.
- if (!header.fec_flag) {
- if (header.is_in_fec_group == IN_FEC_GROUP) {
- StringPiece payload = reader.PeekRemainingPayload();
- visitor_->OnFecProtectedPayload(payload);
- }
- if (!ProcessFrameData(&reader, header)) {
- DCHECK_NE(QUIC_NO_ERROR, error_); // ProcessFrameData sets the error.
- DLOG(WARNING) << "Unable to process frame data.";
- return false;
- }
- } else {
- visitor_->OnFecData(reader.ReadRemainingPayload());
+ if (!ProcessFrameData(&reader, header)) {
+ DCHECK_NE(QUIC_NO_ERROR, error_); // ProcessFrameData sets the error.
+ DLOG(WARNING) << "Unable to process frame data.";
+ return false;
}
visitor_->OnPacketComplete();
@@ -679,36 +640,9 @@ bool QuicFramer::ProcessPublicResetPacket(
return true;
}
-bool QuicFramer::ProcessRevivedPacket(QuicPacketHeader* header,
- StringPiece payload) {
- visitor_->OnRevivedPacket();
-
- header->entropy_hash = GetPacketEntropyHash(*header);
-
- if (!visitor_->OnPacketHeader(*header)) {
- return true;
- }
-
- if (payload.length() > kMaxPacketSize) {
- set_detailed_error("Revived packet too large.");
- return RaiseError(QUIC_PACKET_TOO_LARGE);
- }
-
- QuicDataReader reader(payload.data(), payload.length());
- if (!ProcessFrameData(&reader, *header)) {
- DCHECK_NE(QUIC_NO_ERROR, error_); // ProcessFrameData sets the error.
- DLOG(WARNING) << "Unable to process frame data.";
- return false;
- }
-
- visitor_->OnPacketComplete();
- return true;
-}
-
bool QuicFramer::AppendPacketHeader(const QuicPacketHeader& header,
QuicDataWriter* writer) {
DVLOG(1) << "Appending header: " << header;
- DCHECK(header.fec_group > 0 || header.is_in_fec_group == NOT_IN_FEC_GROUP);
uint8_t public_flags = 0;
if (header.public_header.reset_flag) {
public_flags |= PACKET_PUBLIC_FLAGS_RST;
@@ -785,30 +719,10 @@ bool QuicFramer::AppendPacketHeader(const QuicPacketHeader& header,
if (header.entropy_flag) {
private_flags |= PACKET_PRIVATE_FLAGS_ENTROPY;
}
- if (header.is_in_fec_group == IN_FEC_GROUP) {
- private_flags |= PACKET_PRIVATE_FLAGS_FEC_GROUP;
- }
- if (header.fec_flag) {
- private_flags |= PACKET_PRIVATE_FLAGS_FEC;
- }
if (!writer->WriteUInt8(private_flags)) {
return false;
}
- // The FEC group number is the packet number of the first fec
- // protected packet, or 0 if this packet is not protected.
- if (header.is_in_fec_group == IN_FEC_GROUP) {
- DCHECK_LE(header.fec_group, header.packet_number);
- DCHECK_LT(header.packet_number - header.fec_group, 255u);
- // Offset from the current packet number to the first fec
- // protected packet.
- uint8_t first_fec_protected_packet_offset =
- static_cast<uint8_t>(header.packet_number - header.fec_group);
- if (!writer->WriteBytes(&first_fec_protected_packet_offset, 1)) {
- return false;
- }
- }
-
return true;
}
@@ -1470,7 +1384,6 @@ bool QuicFramer::ProcessAckFrame(QuicDataReader* reader,
set_detailed_error("Unable to read revived packet.");
return false;
}
- ack_frame->latest_revived_packet = revived_packet;
}
return true;
@@ -1718,6 +1631,27 @@ void QuicFramer::SetEncrypter(EncryptionLevel level, QuicEncrypter* encrypter) {
encrypter_[level].reset(encrypter);
}
+size_t QuicFramer::EncryptInPlace(EncryptionLevel level,
+ QuicPathId path_id,
+ QuicPacketNumber packet_number,
+ size_t ad_len,
+ size_t total_len,
+ size_t buffer_len,
+ char* buffer) {
+ size_t output_length = 0;
+ if (!encrypter_[level]->EncryptPacket(
+ path_id, packet_number,
+ StringPiece(buffer, ad_len), // Associated data
+ StringPiece(buffer + ad_len, total_len - ad_len), // Plaintext
+ buffer + ad_len, // Destination buffer
+ &output_length, buffer_len - ad_len)) {
+ RaiseError(QUIC_ENCRYPTION_FAILURE);
+ return 0;
+ }
+
+ return ad_len + output_length;
+}
+
size_t QuicFramer::EncryptPayload(EncryptionLevel level,
QuicPathId path_id,
QuicPacketNumber packet_number,
@@ -1768,7 +1702,7 @@ bool QuicFramer::DecryptPayload(QuicDataReader* encrypted_reader,
size_t* decrypted_length) {
StringPiece encrypted = encrypted_reader->ReadRemainingPayload();
DCHECK(decrypter_.get() != nullptr);
- const StringPiece& associated_data = GetAssociatedDataFromEncryptedPacket(
+ StringPiece associated_data = GetAssociatedDataFromEncryptedPacket(
packet, header.public_header.connection_id_length,
header.public_header.version_flag, header.public_header.multipath_flag,
header.public_header.packet_number_length);
@@ -1822,9 +1756,6 @@ size_t QuicFramer::GetAckFrameSize(
ack_size += kNumberOfNackRangesSize + kNumberOfRevivedPacketsSize;
ack_size += min(ack_info.nack_ranges.size(), kMaxNackRanges) *
(missing_packet_number_length + PACKET_1BYTE_PACKET_NUMBER);
- if (ack.latest_revived_packet != 0) {
- ack_size += largest_observed_length;
- }
}
// In version 23, if the ack will be truncated due to too many nack ranges,
@@ -1849,13 +1780,12 @@ size_t QuicFramer::GetAckFrameSize(
size_t QuicFramer::ComputeFrameLength(
const QuicFrame& frame,
bool last_frame_in_packet,
- InFecGroup is_in_fec_group,
QuicPacketNumberLength packet_number_length) {
switch (frame.type) {
case STREAM_FRAME:
return GetMinStreamFrameSize(frame.stream_frame->stream_id,
frame.stream_frame->offset,
- last_frame_in_packet, is_in_fec_group) +
+ last_frame_in_packet) +
frame.stream_frame->frame_length;
case ACK_FRAME: {
return GetAckFrameSize(*frame.ack_frame, packet_number_length);
@@ -2114,24 +2044,12 @@ bool QuicFramer::AppendAckFrameAndTypeByte(const QuicPacketHeader& header,
DCHECK_EQ(num_missing_ranges, num_ranges_written);
// Append revived packets.
- // If not all the revived packets fit, only mention the ones that do.
- uint8_t num_revived_packets = frame.latest_revived_packet == 0 ? 0 : 1;
- if (((writer->capacity() - writer->length()) / largest_observed_length) ==
- 0) {
- num_revived_packets = 0;
- }
+ // FEC is not supported.
+ uint8_t num_revived_packets = 0;
if (!writer->WriteBytes(&num_revived_packets, 1)) {
return false;
}
- if (num_revived_packets > 0) {
- QUIC_BUG_IF(!frame.missing_packets.Contains(frame.latest_revived_packet));
- if (!AppendPacketSequenceNumber(largest_observed_length,
- frame.latest_revived_packet, writer)) {
- return false;
- }
- }
-
return true;
}
diff --git a/net/quic/quic_framer.h b/net/quic/quic_framer.h
index 3cc2426..a0a0db1 100644
--- a/net/quic/quic_framer.h
+++ b/net/quic/quic_framer.h
@@ -91,10 +91,6 @@ class NET_EXPORT_PRIVATE QuicFramerVisitorInterface {
virtual void OnVersionNegotiationPacket(
const QuicVersionNegotiationPacket& packet) = 0;
- // Called when a lost packet has been recovered via FEC,
- // before it has been processed.
- virtual void OnRevivedPacket() = 0;
-
// Called when the public header has been parsed, but has not been
// authenticated. If it returns false, framing for this packet will cease.
virtual bool OnUnauthenticatedPublicHeader(
@@ -113,10 +109,6 @@ class NET_EXPORT_PRIVATE QuicFramerVisitorInterface {
// If OnPacketHeader returns false, framing for this packet will cease.
virtual bool OnPacketHeader(const QuicPacketHeader& header) = 0;
- // Called when a data packet is parsed that is part of an FEC group.
- // |payload| is the non-encrypted FEC protected payload of the packet.
- virtual void OnFecProtectedPayload(base::StringPiece payload) = 0;
-
// Called when a StreamFrame has been parsed.
virtual bool OnStreamFrame(const QuicStreamFrame& frame) = 0;
@@ -149,9 +141,6 @@ class NET_EXPORT_PRIVATE QuicFramerVisitorInterface {
// Called when a PathCloseFrame has been parsed.
virtual bool OnPathCloseFrame(const QuicPathCloseFrame& frame) = 0;
- // Called when FEC data has been parsed.
- virtual void OnFecData(base::StringPiece redundancy) = 0;
-
// Called when a packet has been completely processed.
virtual void OnPacketComplete() = 0;
};
@@ -173,8 +162,6 @@ class NET_EXPORT_PRIVATE QuicReceivedEntropyHashCalculatorInterface {
// Class for parsing and constructing QUIC packets. It has a
// QuicFramerVisitorInterface that is called when packets are parsed.
-// It also has a QuicFecBuilder that is called when packets are constructed
-// in order to generate FEC data for subsequently building FEC packets.
class NET_EXPORT_PRIVATE QuicFramer {
public:
// Constructs a new framer that installs a kNULL QuicEncrypter and
@@ -228,18 +215,10 @@ class NET_EXPORT_PRIVATE QuicFramer {
// ignored.
bool ProcessPacket(const QuicEncryptedPacket& packet);
- // Pass a data packet that was revived from FEC data into the framer
- // for parsing.
- // Return true if the packet was processed succesfully. |payload| must be
- // the complete DECRYPTED payload of the revived packet.
- bool ProcessRevivedPacket(QuicPacketHeader* header,
- base::StringPiece payload);
-
// Largest size in bytes of all stream frame fields without the payload.
static size_t GetMinStreamFrameSize(QuicStreamId stream_id,
QuicStreamOffset offset,
- bool last_frame_in_packet,
- InFecGroup is_in_fec_group);
+ bool last_frame_in_packet);
// Size in bytes of all ack frame fields without the missing packets.
static size_t GetMinAckFrameSize(
QuicPacketNumberLength largest_observed_length);
@@ -276,7 +255,6 @@ class NET_EXPORT_PRIVATE QuicFramer {
size_t free_bytes,
bool first_frame_in_packet,
bool last_frame_in_packet,
- InFecGroup is_in_fec_group,
QuicPacketNumberLength packet_number_length);
// Returns the associated data from the encrypted packet |encrypted| as a
@@ -296,12 +274,6 @@ class NET_EXPORT_PRIVATE QuicFramer {
char* buffer,
size_t packet_length);
- // Returns a QuicPacket* that is owned by the caller, and is populated with
- // the fields in |header| and |fec|. Returns nullptr if the packet could
- // not be created.
- QuicPacket* BuildFecPacket(const QuicPacketHeader& header,
- base::StringPiece redundancy);
-
// Returns a new public reset packet, owned by the caller.
static QuicEncryptedPacket* BuildPublicResetPacket(
const QuicPublicResetPacket& packet);
@@ -335,6 +307,17 @@ class NET_EXPORT_PRIVATE QuicFramer {
// takes ownership of |encrypter|.
void SetEncrypter(EncryptionLevel level, QuicEncrypter* encrypter);
+ // Encrypts a payload in |buffer|. |ad_len| is the length of the associated
+ // data. |total_len| is the length of the associated data plus plaintext.
+ // |buffer_len| is the full length of the allocated buffer.
+ size_t EncryptInPlace(EncryptionLevel level,
+ QuicPathId path_id,
+ QuicPacketNumber packet_number,
+ size_t ad_len,
+ size_t total_len,
+ size_t buffer_len,
+ char* buffer);
+
// Returns the length of the data encrypted into |buffer| if |buffer_len| is
// long enough, and otherwise 0.
size_t EncryptPayload(EncryptionLevel level,
@@ -467,7 +450,6 @@ class NET_EXPORT_PRIVATE QuicFramer {
// Computes the wire size in bytes of the payload of |frame|.
size_t ComputeFrameLength(const QuicFrame& frame,
bool last_frame_in_packet,
- InFecGroup is_in_fec_group,
QuicPacketNumberLength packet_number_length);
static bool AppendPacketSequenceNumber(
@@ -529,12 +511,12 @@ class NET_EXPORT_PRIVATE QuicFramer {
// TODO(fayang): this set is never cleaned up. A possible improvement is to
// use intervals.
std::unordered_set<QuicPathId> closed_paths_;
- // Map mapping path id to packet number of last successfully decrypted/revived
+ // Map mapping path id to packet number of last successfully decrypted
// received packet.
std::unordered_map<QuicPathId, QuicPacketNumber> last_packet_numbers_;
// Updated by ProcessPacketHeader when it succeeds.
QuicPacketNumber last_packet_number_;
- // The path on which last successfully decrypted/revived packet was received.
+ // The path on which last successfully decrypted packet was received.
QuicPathId last_path_id_;
// Updated by WritePacketHeader.
QuicConnectionId last_serialized_connection_id_;
diff --git a/net/quic/quic_framer_test.cc b/net/quic/quic_framer_test.cc
index 025fb83..d770db9 100644
--- a/net/quic/quic_framer_test.cc
+++ b/net/quic/quic_framer_test.cc
@@ -106,29 +106,6 @@ size_t GetPrivateFlagsOffset(bool include_version,
packet_number_length;
}
-// Index into the fec group offset in the header.
-size_t GetFecGroupOffset(QuicConnectionIdLength connection_id_length,
- bool include_version,
- bool include_path_id) {
- return GetPrivateFlagsOffset(connection_id_length, include_version,
- include_path_id) +
- kPrivateFlagsSize;
-}
-
-size_t GetFecGroupOffset(bool include_version, bool include_path_id) {
- return GetPrivateFlagsOffset(PACKET_8BYTE_CONNECTION_ID, include_version,
- include_path_id) +
- kPrivateFlagsSize;
-}
-
-size_t GetFecGroupOffset(bool include_version,
- bool include_path_id,
- QuicPacketNumberLength packet_number_length) {
- return GetPrivateFlagsOffset(include_version, include_path_id,
- packet_number_length) +
- kPrivateFlagsSize;
-}
-
// Index into the message tag of the public reset packet.
// Public resets always have full connection_ids.
const size_t kPublicResetPacketMessageTagOffset =
@@ -177,8 +154,8 @@ class TestDecrypter : public QuicDecrypter {
bool SetNoncePrefix(StringPiece nonce_prefix) override { return true; }
bool DecryptPacket(QuicPathId path_id,
QuicPacketNumber packet_number,
- const StringPiece& associated_data,
- const StringPiece& ciphertext,
+ StringPiece associated_data,
+ StringPiece ciphertext,
char* output,
size_t* output_length,
size_t max_output_length) override {
@@ -208,9 +185,7 @@ class TestQuicVisitor : public QuicFramerVisitorInterface {
version_mismatch_(0),
packet_count_(0),
frame_count_(0),
- fec_count_(0),
complete_packets_(0),
- revived_packets_(0),
accept_packet_(true),
accept_public_header_(true) {}
@@ -239,8 +214,6 @@ class TestQuicVisitor : public QuicFramerVisitorInterface {
version_negotiation_packet_.reset(new QuicVersionNegotiationPacket(packet));
}
- void OnRevivedPacket() override { ++revived_packets_; }
-
bool OnProtocolVersionMismatch(QuicVersion version) override {
DVLOG(1) << "QuicFramer Version Mismatch, version: " << version;
++version_mismatch_;
@@ -260,6 +233,10 @@ class TestQuicVisitor : public QuicFramerVisitorInterface {
void OnDecryptedPacket(EncryptionLevel level) override {}
bool OnPacketHeader(const QuicPacketHeader& header) override {
+ if (header.fec_flag) {
+ // Drop any FEC packet.
+ return false;
+ }
++packet_count_;
header_.reset(new QuicPacketHeader(header));
return accept_packet_;
@@ -277,10 +254,6 @@ class TestQuicVisitor : public QuicFramerVisitorInterface {
return true;
}
- void OnFecProtectedPayload(StringPiece payload) override {
- fec_protected_payload_ = payload.as_string();
- }
-
bool OnAckFrame(const QuicAckFrame& frame) override {
++frame_count_;
ack_frames_.push_back(new QuicAckFrame(frame));
@@ -299,11 +272,6 @@ class TestQuicVisitor : public QuicFramerVisitorInterface {
return true;
}
- void OnFecData(StringPiece redundancy) override {
- ++fec_count_;
- fec_data_redundancy_.push_back(redundancy.as_string());
- }
-
void OnPacketComplete() override { ++complete_packets_; }
bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override {
@@ -341,9 +309,7 @@ class TestQuicVisitor : public QuicFramerVisitorInterface {
int version_mismatch_;
int packet_count_;
int frame_count_;
- int fec_count_;
int complete_packets_;
- int revived_packets_;
bool accept_packet_;
bool accept_public_header_;
@@ -355,7 +321,6 @@ class TestQuicVisitor : public QuicFramerVisitorInterface {
vector<QuicAckFrame*> ack_frames_;
vector<QuicStopWaitingFrame*> stop_waiting_frames_;
vector<QuicPingFrame*> ping_frames_;
- string fec_protected_payload_;
QuicRstStreamFrame rst_stream_frame_;
QuicConnectionCloseFrame connection_close_frame_;
QuicGoAwayFrame goaway_frame_;
@@ -363,7 +328,6 @@ class TestQuicVisitor : public QuicFramerVisitorInterface {
QuicBlockedFrame blocked_frame_;
QuicPathCloseFrame path_close_frame_;
vector<string*> stream_data_;
- vector<string> fec_data_redundancy_;
};
class QuicFramerTest : public ::testing::TestWithParam<QuicVersion> {
@@ -481,8 +445,7 @@ class QuicFramerTest : public ::testing::TestWithParam<QuicVersion> {
CheckProcessingFails(
packet,
i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, include_version,
- !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER,
- NOT_IN_FEC_GROUP),
+ !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER),
expected_error, QUIC_INVALID_STREAM_DATA);
}
}
@@ -648,10 +611,10 @@ TEST_P(QuicFramerTest, LargePacket) {
memset(packet + GetPacketHeaderSize(
PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, !kIncludePathId,
- PACKET_6BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP), 0,
+ PACKET_6BYTE_PACKET_NUMBER), 0,
kMaxPacketSize - GetPacketHeaderSize(
PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, !kIncludePathId,
- PACKET_6BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP) + 1);
+ PACKET_6BYTE_PACKET_NUMBER) + 1);
// clang-format on
QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
@@ -696,8 +659,7 @@ TEST_P(QuicFramerTest, PacketHeader) {
// Now test framing boundaries.
for (size_t i = 0;
i < GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER,
- NOT_IN_FEC_GROUP);
+ !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER);
++i) {
string expected_error;
if (i < kConnectionIdOffset) {
@@ -706,10 +668,8 @@ TEST_P(QuicFramerTest, PacketHeader) {
expected_error = "Unable to read ConnectionId.";
} else if (i < GetPrivateFlagsOffset(!kIncludeVersion, !kIncludePathId)) {
expected_error = "Unable to read packet number.";
- } else if (i < GetFecGroupOffset(!kIncludeVersion, !kIncludePathId)) {
- expected_error = "Unable to read private flags.";
} else {
- expected_error = "Unable to read first fec protected packet offset.";
+ expected_error = "Unable to read private flags.";
}
CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_PACKET_HEADER);
}
@@ -749,8 +709,7 @@ TEST_P(QuicFramerTest, PacketHeaderWith4ByteConnectionId) {
// Now test framing boundaries.
for (size_t i = 0;
i < GetPacketHeaderSize(PACKET_4BYTE_CONNECTION_ID, !kIncludeVersion,
- !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER,
- NOT_IN_FEC_GROUP);
+ !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER);
++i) {
string expected_error;
if (i < kConnectionIdOffset) {
@@ -761,11 +720,8 @@ TEST_P(QuicFramerTest, PacketHeaderWith4ByteConnectionId) {
} else if (i < GetPrivateFlagsOffset(PACKET_4BYTE_CONNECTION_ID,
!kIncludeVersion, !kIncludePathId)) {
expected_error = "Unable to read packet number.";
- } else if (i < GetFecGroupOffset(PACKET_4BYTE_CONNECTION_ID,
- !kIncludeVersion, !kIncludePathId)) {
- expected_error = "Unable to read private flags.";
} else {
- expected_error = "Unable to read first fec protected packet offset.";
+ expected_error = "Unable to read private flags.";
}
CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_PACKET_HEADER);
}
@@ -805,8 +761,7 @@ TEST_P(QuicFramerTest, PacketHeader1ByteConnectionId) {
// Now test framing boundaries.
for (size_t i = 0;
i < GetPacketHeaderSize(PACKET_1BYTE_CONNECTION_ID, !kIncludeVersion,
- !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER,
- NOT_IN_FEC_GROUP);
+ !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER);
++i) {
string expected_error;
if (i < kConnectionIdOffset) {
@@ -817,11 +772,8 @@ TEST_P(QuicFramerTest, PacketHeader1ByteConnectionId) {
} else if (i < GetPrivateFlagsOffset(PACKET_1BYTE_CONNECTION_ID,
!kIncludeVersion, !kIncludePathId)) {
expected_error = "Unable to read packet number.";
- } else if (i < GetFecGroupOffset(PACKET_1BYTE_CONNECTION_ID,
- !kIncludeVersion, !kIncludePathId)) {
- expected_error = "Unable to read private flags.";
} else {
- expected_error = "Unable to read first fec protected packet offset.";
+ expected_error = "Unable to read private flags.";
}
CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_PACKET_HEADER);
}
@@ -861,8 +813,7 @@ TEST_P(QuicFramerTest, PacketHeaderWith0ByteConnectionId) {
// Now test framing boundaries.
for (size_t i = 0;
i < GetPacketHeaderSize(PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
- !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER,
- NOT_IN_FEC_GROUP);
+ !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER);
++i) {
string expected_error;
if (i < kConnectionIdOffset) {
@@ -873,11 +824,8 @@ TEST_P(QuicFramerTest, PacketHeaderWith0ByteConnectionId) {
} else if (i < GetPrivateFlagsOffset(PACKET_0BYTE_CONNECTION_ID,
!kIncludeVersion, !kIncludePathId)) {
expected_error = "Unable to read packet number.";
- } else if (i < GetFecGroupOffset(PACKET_0BYTE_CONNECTION_ID,
- !kIncludeVersion, !kIncludePathId)) {
- expected_error = "Unable to read private flags.";
} else {
- expected_error = "Unable to read first fec protected packet offset.";
+ expected_error = "Unable to read private flags.";
}
CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_PACKET_HEADER);
}
@@ -918,8 +866,7 @@ TEST_P(QuicFramerTest, PacketHeaderWithVersionFlag) {
// Now test framing boundaries.
for (size_t i = 0;
i < GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, kIncludeVersion,
- !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER,
- NOT_IN_FEC_GROUP);
+ !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER);
++i) {
string expected_error;
if (i < kConnectionIdOffset) {
@@ -930,10 +877,8 @@ TEST_P(QuicFramerTest, PacketHeaderWithVersionFlag) {
expected_error = "Unable to read protocol version.";
} else if (i < GetPrivateFlagsOffset(kIncludeVersion, !kIncludePathId)) {
expected_error = "Unable to read packet number.";
- } else if (i < GetFecGroupOffset(kIncludeVersion, !kIncludePathId)) {
- expected_error = "Unable to read private flags.";
} else {
- expected_error = "Unable to read first fec protected packet offset.";
+ expected_error = "Unable to read private flags.";
}
CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_PACKET_HEADER);
}
@@ -975,8 +920,7 @@ TEST_P(QuicFramerTest, PacketHeaderWithMultipathFlag) {
// Now test framing boundaries.
for (size_t i = 0;
i < GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- kIncludePathId, PACKET_6BYTE_PACKET_NUMBER,
- NOT_IN_FEC_GROUP);
+ kIncludePathId, PACKET_6BYTE_PACKET_NUMBER);
++i) {
string expected_error;
if (i < kConnectionIdOffset) {
@@ -988,10 +932,8 @@ TEST_P(QuicFramerTest, PacketHeaderWithMultipathFlag) {
expected_error = "Unable to read path id.";
} else if (i < GetPrivateFlagsOffset(!kIncludeVersion, kIncludePathId)) {
expected_error = "Unable to read packet number.";
- } else if (i < GetFecGroupOffset(!kIncludeVersion, kIncludePathId)) {
- expected_error = "Unable to read private flags.";
} else {
- expected_error = "Unable to read first fec protected packet offset.";
+ expected_error = "Unable to read private flags.";
}
CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_PACKET_HEADER);
}
@@ -1036,8 +978,7 @@ TEST_P(QuicFramerTest, PacketHeaderWithBothVersionFlagAndMultipathFlag) {
// Now test framing boundaries.
for (size_t i = 0;
i < GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- kIncludePathId, PACKET_6BYTE_PACKET_NUMBER,
- NOT_IN_FEC_GROUP);
+ kIncludePathId, PACKET_6BYTE_PACKET_NUMBER);
++i) {
string expected_error;
if (i < kConnectionIdOffset) {
@@ -1051,10 +992,8 @@ TEST_P(QuicFramerTest, PacketHeaderWithBothVersionFlagAndMultipathFlag) {
expected_error = "Unable to read path id.";
} else if (i < GetPrivateFlagsOffset(kIncludeVersion, kIncludePathId)) {
expected_error = "Unable to read packet number.";
- } else if (i < GetFecGroupOffset(kIncludeVersion, kIncludePathId)) {
- expected_error = "Unable to read private flags.";
} else {
- expected_error = "Unable to read first fec protected packet offset.";
+ expected_error = "Unable to read private flags.";
}
CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_PACKET_HEADER);
}
@@ -1201,8 +1140,7 @@ TEST_P(QuicFramerTest, PacketHeaderWith4BytePacketNumber) {
// Now test framing boundaries.
for (size_t i = 0;
i < GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- !kIncludePathId, PACKET_4BYTE_PACKET_NUMBER,
- NOT_IN_FEC_GROUP);
+ !kIncludePathId, PACKET_4BYTE_PACKET_NUMBER);
++i) {
string expected_error;
if (i < kConnectionIdOffset) {
@@ -1212,11 +1150,8 @@ TEST_P(QuicFramerTest, PacketHeaderWith4BytePacketNumber) {
} else if (i < GetPrivateFlagsOffset(!kIncludeVersion, !kIncludePathId,
PACKET_4BYTE_PACKET_NUMBER)) {
expected_error = "Unable to read packet number.";
- } else if (i < GetFecGroupOffset(!kIncludeVersion, !kIncludePathId,
- PACKET_4BYTE_PACKET_NUMBER)) {
- expected_error = "Unable to read private flags.";
} else {
- expected_error = "Unable to read first fec protected packet offset.";
+ expected_error = "Unable to read private flags.";
}
CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_PACKET_HEADER);
}
@@ -1256,8 +1191,7 @@ TEST_P(QuicFramerTest, PacketHeaderWith2BytePacketNumber) {
// Now test framing boundaries.
for (size_t i = 0;
i < GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- !kIncludePathId, PACKET_2BYTE_PACKET_NUMBER,
- NOT_IN_FEC_GROUP);
+ !kIncludePathId, PACKET_2BYTE_PACKET_NUMBER);
++i) {
string expected_error;
if (i < kConnectionIdOffset) {
@@ -1267,11 +1201,8 @@ TEST_P(QuicFramerTest, PacketHeaderWith2BytePacketNumber) {
} else if (i < GetPrivateFlagsOffset(!kIncludeVersion, !kIncludePathId,
PACKET_2BYTE_PACKET_NUMBER)) {
expected_error = "Unable to read packet number.";
- } else if (i < GetFecGroupOffset(!kIncludeVersion, !kIncludePathId,
- PACKET_2BYTE_PACKET_NUMBER)) {
- expected_error = "Unable to read private flags.";
} else {
- expected_error = "Unable to read first fec protected packet offset.";
+ expected_error = "Unable to read private flags.";
}
CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_PACKET_HEADER);
}
@@ -1311,8 +1242,7 @@ TEST_P(QuicFramerTest, PacketHeaderWith1BytePacketNumber) {
// Now test framing boundaries.
for (size_t i = 0;
i < GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- !kIncludePathId, PACKET_1BYTE_PACKET_NUMBER,
- NOT_IN_FEC_GROUP);
+ !kIncludePathId, PACKET_1BYTE_PACKET_NUMBER);
++i) {
string expected_error;
if (i < kConnectionIdOffset) {
@@ -1322,11 +1252,8 @@ TEST_P(QuicFramerTest, PacketHeaderWith1BytePacketNumber) {
} else if (i < GetPrivateFlagsOffset(!kIncludeVersion, !kIncludePathId,
PACKET_1BYTE_PACKET_NUMBER)) {
expected_error = "Unable to read packet number.";
- } else if (i < GetFecGroupOffset(!kIncludeVersion, !kIncludePathId,
- PACKET_1BYTE_PACKET_NUMBER)) {
- expected_error = "Unable to read private flags.";
} else {
- expected_error = "Unable to read first fec protected packet offset.";
+ expected_error = "Unable to read private flags.";
}
CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_PACKET_HEADER);
}
@@ -1504,8 +1431,7 @@ TEST_P(QuicFramerTest, PaddingFrame) {
// A packet with no frames is not acceptable.
CheckProcessingFails(
packet, GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER,
- NOT_IN_FEC_GROUP),
+ !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER),
"Packet has no frames.", QUIC_MISSING_PAYLOAD);
}
@@ -1823,114 +1749,6 @@ TEST_P(QuicFramerTest, RejectPublicHeader) {
ASSERT_FALSE(visitor_.header_.get());
}
-TEST_P(QuicFramerTest, RevivedStreamFrame) {
- // clang-format off
- unsigned char payload[] = {
- // frame type (stream frame with fin)
- 0xFF,
- // stream id
- 0x04, 0x03, 0x02, 0x01,
- // offset
- 0x54, 0x76, 0x10, 0x32,
- 0xDC, 0xFE, 0x98, 0xBA,
- // data length
- 0x0c, 0x00,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!',
- };
- // clang-format on
-
- QuicPacketHeader header;
- header.public_header.connection_id = kConnectionId;
- header.public_header.reset_flag = false;
- header.public_header.version_flag = false;
- header.fec_flag = true;
- header.entropy_flag = true;
- header.packet_number = kPacketNumber;
- header.fec_group = 0;
-
- // Do not encrypt the payload because the revived payload is post-encryption.
- EXPECT_TRUE(framer_.ProcessRevivedPacket(
- &header, StringPiece(AsChars(payload), arraysize(payload))));
-
- EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
- ASSERT_EQ(1, visitor_.revived_packets_);
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_EQ(kConnectionId, visitor_.header_->public_header.connection_id);
- EXPECT_FALSE(visitor_.header_->public_header.reset_flag);
- EXPECT_FALSE(visitor_.header_->public_header.version_flag);
- EXPECT_TRUE(visitor_.header_->fec_flag);
- EXPECT_TRUE(visitor_.header_->entropy_flag);
- EXPECT_EQ(1 << (header.packet_number % 8), visitor_.header_->entropy_hash);
- EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
- EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
- EXPECT_EQ(0u, visitor_.header_->fec_group);
-
- ASSERT_EQ(1u, visitor_.stream_frames_.size());
- EXPECT_EQ(0u, visitor_.ack_frames_.size());
- EXPECT_EQ(kStreamId, visitor_.stream_frames_[0]->stream_id);
- EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
- EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
- CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]);
-}
-
-TEST_P(QuicFramerTest, StreamFrameInFecGroup) {
- // clang-format off
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x3C,
- // connection_id
- 0x10, 0x32, 0x54, 0x76,
- 0x98, 0xBA, 0xDC, 0xFE,
- // packet number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
- // private flags (fec group)
- 0x02,
- // first fec protected packet offset
- 0x02,
-
- // frame type (stream frame with fin)
- 0xFF,
- // stream id
- 0x04, 0x03, 0x02, 0x01,
- // offset
- 0x54, 0x76, 0x10, 0x32,
- 0xDC, 0xFE, 0x98, 0xBA,
- // data length
- 0x0c, 0x00,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!',
- };
- // clang-format on
-
- QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
- EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-
- EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludePathId));
- EXPECT_EQ(IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
- EXPECT_EQ(kPacketNumber - 2, visitor_.header_->fec_group);
- const size_t fec_offset =
- GetStartOfFecProtectedData(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER);
- EXPECT_EQ(
- string(AsChars(packet) + fec_offset, arraysize(packet) - fec_offset),
- visitor_.fec_protected_payload_);
-
- ASSERT_EQ(1u, visitor_.stream_frames_.size());
- EXPECT_EQ(0u, visitor_.ack_frames_.size());
- EXPECT_EQ(kStreamId, visitor_.stream_frames_[0]->stream_id);
- EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
- EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
- CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]);
-}
-
TEST_P(QuicFramerTest, AckFrameTwoTimestamp) {
// clang-format off
unsigned char packet[] = {
@@ -2046,8 +1864,7 @@ TEST_P(QuicFramerTest, AckFrameTwoTimestamp) {
CheckProcessingFails(
packet,
i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER,
- NOT_IN_FEC_GROUP),
+ !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER),
expected_error, QUIC_INVALID_ACK_DATA);
}
}
@@ -2153,8 +1970,7 @@ TEST_P(QuicFramerTest, AckFrameOneTimestamp) {
CheckProcessingFails(
packet,
i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER,
- NOT_IN_FEC_GROUP),
+ !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER),
expected_error, QUIC_INVALID_ACK_DATA);
}
}
@@ -2248,8 +2064,7 @@ TEST_P(QuicFramerTest, AckFrame) {
CheckProcessingFails(
packet,
i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER,
- NOT_IN_FEC_GROUP),
+ !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER),
expected_error, QUIC_INVALID_ACK_DATA);
}
}
@@ -2353,8 +2168,7 @@ TEST_P(QuicFramerTest, AckFrameRevivedPackets) {
CheckProcessingFails(
packet,
i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER,
- NOT_IN_FEC_GROUP),
+ !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER),
expected_error, QUIC_INVALID_ACK_DATA);
}
}
@@ -2462,7 +2276,6 @@ TEST_P(QuicFramerTest, AckFrame500Nacks) {
QuicAckFrame* frame = visitor_.ack_frames_[0];
EXPECT_EQ(0xBA, frame->entropy_hash);
EXPECT_EQ(kLargestObserved, frame->largest_observed);
- EXPECT_EQ(0u, frame->latest_revived_packet);
ASSERT_EQ(500u, frame->missing_packets.NumPacketsSlow());
EXPECT_EQ(kMissingPacket - 499, frame->missing_packets.Min());
EXPECT_EQ(kMissingPacket, frame->missing_packets.Max());
@@ -2529,8 +2342,7 @@ TEST_P(QuicFramerTest, StopWaitingFrame) {
CheckProcessingFails(
packet,
i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER,
- NOT_IN_FEC_GROUP),
+ !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER),
expected_error, QUIC_INVALID_STOP_WAITING_DATA);
}
}
@@ -2590,8 +2402,7 @@ TEST_P(QuicFramerTest, RstStreamFrameQuic) {
CheckProcessingFails(
packet,
i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER,
- NOT_IN_FEC_GROUP),
+ !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER),
expected_error, QUIC_INVALID_RST_STREAM_DATA);
}
}
@@ -2651,8 +2462,7 @@ TEST_P(QuicFramerTest, ConnectionCloseFrame) {
CheckProcessingFails(
packet,
i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER,
- NOT_IN_FEC_GROUP),
+ !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER),
expected_error, QUIC_INVALID_CONNECTION_CLOSE_DATA);
}
}
@@ -2714,8 +2524,7 @@ TEST_P(QuicFramerTest, GoAwayFrame) {
CheckProcessingFails(
packet,
i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER,
- NOT_IN_FEC_GROUP),
+ !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER),
expected_error, QUIC_INVALID_GOAWAY_DATA);
}
}
@@ -2767,8 +2576,7 @@ TEST_P(QuicFramerTest, WindowUpdateFrame) {
CheckProcessingFails(
packet,
i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER,
- NOT_IN_FEC_GROUP),
+ !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER),
expected_error, QUIC_INVALID_WINDOW_UPDATE_DATA);
}
}
@@ -2811,8 +2619,7 @@ TEST_P(QuicFramerTest, BlockedFrame) {
CheckProcessingFails(
packet,
i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER,
- NOT_IN_FEC_GROUP),
+ !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER),
expected_error, QUIC_INVALID_BLOCKED_DATA);
}
}
@@ -2887,8 +2694,7 @@ TEST_P(QuicFramerTest, PathCloseFrame) {
CheckProcessingFails(
packet,
i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- kIncludePathId, PACKET_6BYTE_PACKET_NUMBER,
- NOT_IN_FEC_GROUP),
+ kIncludePathId, PACKET_6BYTE_PACKET_NUMBER),
expected_error, QUIC_INVALID_PATH_CLOSE_DATA);
}
}
@@ -3102,7 +2908,7 @@ TEST_P(QuicFramerTest, VersionNegotiationPacket) {
}
}
-TEST_P(QuicFramerTest, FecPacket) {
+TEST_P(QuicFramerTest, DropFecPacket) {
// clang-format off
unsigned char packet[] = {
// public flags (8 byte connection_id)
@@ -3130,13 +2936,7 @@ TEST_P(QuicFramerTest, FecPacket) {
EXPECT_TRUE(framer_.ProcessPacket(encrypted));
EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludePathId));
-
- EXPECT_EQ(0u, visitor_.stream_frames_.size());
- EXPECT_EQ(0u, visitor_.ack_frames_.size());
- ASSERT_EQ(1, visitor_.fec_count_);
- EXPECT_EQ("abcdefghijklmnop", visitor_.fec_data_redundancy_[0]);
+ EXPECT_FALSE(visitor_.header_.get());
}
TEST_P(QuicFramerTest, BuildPaddingFramePacket) {
@@ -3173,9 +2973,9 @@ TEST_P(QuicFramerTest, BuildPaddingFramePacket) {
};
// clang-format on
- uint64_t header_size = GetPacketHeaderSize(
- PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, !kIncludePathId,
- PACKET_6BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP);
+ uint64_t header_size =
+ GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
+ !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER);
memset(packet + header_size + 1, 0x00, kMaxPacketSize - header_size - 1);
scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
@@ -3220,9 +3020,9 @@ TEST_P(QuicFramerTest, Build4ByteSequenceNumberPaddingFramePacket) {
};
// clang-format on
- uint64_t header_size = GetPacketHeaderSize(
- PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, !kIncludePathId,
- PACKET_4BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP);
+ uint64_t header_size =
+ GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
+ !kIncludePathId, PACKET_4BYTE_PACKET_NUMBER);
memset(packet + header_size + 1, 0x00, kMaxPacketSize - header_size - 1);
scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
@@ -3267,9 +3067,9 @@ TEST_P(QuicFramerTest, Build2ByteSequenceNumberPaddingFramePacket) {
};
// clang-format on
- uint64_t header_size = GetPacketHeaderSize(
- PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, !kIncludePathId,
- PACKET_2BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP);
+ uint64_t header_size =
+ GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
+ !kIncludePathId, PACKET_2BYTE_PACKET_NUMBER);
memset(packet + header_size + 1, 0x00, kMaxPacketSize - header_size - 1);
scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
@@ -3314,9 +3114,9 @@ TEST_P(QuicFramerTest, Build1ByteSequenceNumberPaddingFramePacket) {
};
// clang-format on
- uint64_t header_size = GetPacketHeaderSize(
- PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, !kIncludePathId,
- PACKET_1BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP);
+ uint64_t header_size =
+ GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
+ !kIncludePathId, PACKET_1BYTE_PACKET_NUMBER);
memset(packet + header_size + 1, 0x00, kMaxPacketSize - header_size - 1);
scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
@@ -3378,55 +3178,6 @@ TEST_P(QuicFramerTest, BuildStreamFramePacket) {
arraysize(packet));
}
-TEST_P(QuicFramerTest, BuildStreamFramePacketInFecGroup) {
- QuicPacketHeader header;
- header.public_header.connection_id = kConnectionId;
- header.public_header.reset_flag = false;
- header.public_header.version_flag = false;
- header.fec_flag = false;
- header.entropy_flag = true;
- header.packet_number = kPacketNumber;
- header.is_in_fec_group = IN_FEC_GROUP;
- header.fec_group = kPacketNumber;
-
- QuicStreamFrame stream_frame(kStreamId, true, kStreamOffset,
- StringPiece("hello world!"));
-
- QuicFrames frames;
- frames.push_back(QuicFrame(&stream_frame));
- // clang-format off
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x3C,
- // connection_id
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE,
- // packet number
- 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12,
- // private flags (entropy, is_in_fec_group)
- 0x03,
- // FEC group
- 0x00,
- // frame type (stream frame with fin and data length field)
- 0xFF,
- // stream id
- 0x04, 0x03, 0x02, 0x01,
- // offset
- 0x54, 0x76, 0x10, 0x32, 0xDC, 0xFE, 0x98, 0xBA,
- // data length (since packet is in an FEC group)
- 0x0C, 0x00,
- // data
- 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '!',
- };
- // clang-format on
-
- scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
- test::CompareCharArraysWithHexError("constructed packet", data->data(),
- data->length(), AsChars(packet),
- arraysize(packet));
-}
-
TEST_P(QuicFramerTest, BuildStreamFramePacketWithVersionFlag) {
QuicPacketHeader header;
header.public_header.connection_id = kConnectionId;
@@ -4372,50 +4123,6 @@ TEST_P(QuicFramerTest, BuildPublicResetPacketWithClientAddress) {
arraysize(packet));
}
-TEST_P(QuicFramerTest, BuildFecPacket) {
- QuicPacketHeader header;
- header.public_header.connection_id = kConnectionId;
- header.public_header.reset_flag = false;
- header.public_header.version_flag = false;
- header.fec_flag = true;
- header.entropy_flag = true;
- header.packet_number = kPacketNumber;
- header.is_in_fec_group = IN_FEC_GROUP;
- header.fec_group = kPacketNumber - 1;
-
- string redundancy = "abcdefghijklmnop";
-
- // clang-format off
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x3C,
- // connection_id
- 0x10, 0x32, 0x54, 0x76,
- 0x98, 0xBA, 0xDC, 0xFE,
- // packet number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
- // private flags (entropy & fec group & fec packet)
- 0x07,
- // first fec protected packet offset
- 0x01,
-
- // redundancy
- 'a', 'b', 'c', 'd',
- 'e', 'f', 'g', 'h',
- 'i', 'j', 'k', 'l',
- 'm', 'n', 'o', 'p',
- };
- // clang-format on
-
- scoped_ptr<QuicPacket> data(framer_.BuildFecPacket(header, redundancy));
- ASSERT_TRUE(data != nullptr);
-
- test::CompareCharArraysWithHexError("constructed packet", data->data(),
- data->length(), AsChars(packet),
- arraysize(packet));
-}
-
TEST_P(QuicFramerTest, EncryptPacket) {
QuicPacketNumber packet_number = kPacketNumber;
// clang-format off
@@ -4428,10 +4135,8 @@ TEST_P(QuicFramerTest, EncryptPacket) {
// packet number
0xBC, 0x9A, 0x78, 0x56,
0x34, 0x12,
- // private flags (fec group & fec packet)
- 0x06,
- // first fec protected packet offset
- 0x01,
+ // private flags
+ 0x00,
// redundancy
'a', 'b', 'c', 'd',
@@ -4467,10 +4172,8 @@ TEST_P(QuicFramerTest, EncryptPacketWithVersionFlag) {
// packet number
0xBC, 0x9A, 0x78, 0x56,
0x34, 0x12,
- // private flags (fec group & fec flags)
- 0x06,
- // first fec protected packet offset
- 0x01,
+ // private flags
+ 0x00,
// redundancy
'a', 'b', 'c', 'd',
@@ -4506,10 +4209,8 @@ TEST_P(QuicFramerTest, EncryptPacketWithMultipathFlag) {
// packet number
0xBC, 0x9A, 0x78, 0x56,
0x34, 0x12,
- // private flags (fec group & fec flags)
- 0x06,
- // first fec protected packet offset
- 0x01,
+ // private flags
+ 0x00,
// redundancy
'a', 'b', 'c', 'd',
@@ -4546,10 +4247,8 @@ TEST_P(QuicFramerTest, EncryptPacketWithBothVersionFlagAndMultipathFlag) {
// packet number
0xBC, 0x9A, 0x78, 0x56,
0x34, 0x12,
- // private flags (fec group & fec flags)
- 0x06,
- // first fec protected packet offset
- 0x01,
+ // private flags
+ 0x00,
// redundancy
'a', 'b', 'c', 'd',
@@ -4731,45 +4430,6 @@ TEST_P(QuicFramerTest, EntropyFlagTest) {
EXPECT_FALSE(visitor_.header_->fec_flag);
};
-TEST_P(QuicFramerTest, FecEntropyTest) {
- // clang-format off
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x3C,
- // connection_id
- 0x10, 0x32, 0x54, 0x76,
- 0x98, 0xBA, 0xDC, 0xFE,
- // packet number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
- // private flags (Entropy & fec group & FEC)
- 0x07,
- // first fec protected packet offset
- 0xFF,
-
- // frame type (stream frame with fin and no length)
- 0xDF,
- // stream id
- 0x04, 0x03, 0x02, 0x01,
- // offset
- 0x54, 0x76, 0x10, 0x32,
- 0xDC, 0xFE, 0x98, 0xBA,
- // data
- 'h', 'e', 'l', 'l',
- 'o', ' ', 'w', 'o',
- 'r', 'l', 'd', '!',
- };
- // clang-format on
-
- QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
- EXPECT_TRUE(framer_.ProcessPacket(encrypted));
- EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(visitor_.header_->fec_flag);
- EXPECT_TRUE(visitor_.header_->entropy_flag);
- EXPECT_EQ(1 << 4, visitor_.header_->entropy_hash);
-};
-
TEST_P(QuicFramerTest, StopPacketProcessing) {
// clang-format off
unsigned char packet[] = {
diff --git a/net/quic/quic_headers_stream.cc b/net/quic/quic_headers_stream.cc
index b62717c..88a6186 100644
--- a/net/quic/quic_headers_stream.cc
+++ b/net/quic/quic_headers_stream.cc
@@ -66,7 +66,8 @@ class QuicHeadersStream::SpdyFramerVisitor
}
void OnStreamEnd(SpdyStreamId stream_id) override {
- LOG(DFATAL) << "Unimplemented.";
+ // The framer invokes OnStreamEnd after processing a SYN_STREAM
+ // or SYN_REPLY frame that had the fin bit set.
}
void OnStreamPadding(SpdyStreamId stream_id, size_t len) override {
diff --git a/net/quic/quic_headers_stream_test.cc b/net/quic/quic_headers_stream_test.cc
index a821fb2..2f51bab 100644
--- a/net/quic/quic_headers_stream_test.cc
+++ b/net/quic/quic_headers_stream_test.cc
@@ -93,19 +93,26 @@ class MockVisitor : public SpdyFramerVisitorInterface {
MOCK_METHOD2(OnUnknownFrame, bool(SpdyStreamId stream_id, int frame_type));
};
-// Run all tests with each version, and client or server
+// Run all tests with each version, perspective (client or server),
+// and relevant flag options (false or true)
struct TestParams {
- TestParams(QuicVersion version, Perspective perspective)
- : version(version), perspective(perspective) {}
+ TestParams(QuicVersion version,
+ Perspective perspective,
+ bool spdy_on_stream_end)
+ : version(version),
+ perspective(perspective),
+ spdy_on_stream_end(spdy_on_stream_end) {}
friend ostream& operator<<(ostream& os, const TestParams& p) {
os << "{ version: " << QuicVersionToString(p.version);
- os << ", perspective: " << p.perspective << " }";
+ os << ", perspective: " << p.perspective;
+ os << ", spdy_on_stream_end: " << p.spdy_on_stream_end << " }";
return os;
}
QuicVersion version;
Perspective perspective;
+ bool spdy_on_stream_end;
};
// Constructs various test permutations.
@@ -113,8 +120,10 @@ vector<TestParams> GetTestParams() {
vector<TestParams> params;
QuicVersionVector all_supported_versions = QuicSupportedVersions();
for (const QuicVersion version : all_supported_versions) {
- params.push_back(TestParams(version, Perspective::IS_CLIENT));
- params.push_back(TestParams(version, Perspective::IS_SERVER));
+ params.push_back(TestParams(version, Perspective::IS_CLIENT, true));
+ params.push_back(TestParams(version, Perspective::IS_SERVER, true));
+ params.push_back(TestParams(version, Perspective::IS_CLIENT, false));
+ params.push_back(TestParams(version, Perspective::IS_SERVER, false));
}
FLAGS_quic_supports_push_promise = true;
return params;
@@ -129,14 +138,15 @@ class QuicHeadersStreamTest : public ::testing::TestWithParam<TestParams> {
session_(connection_),
headers_stream_(QuicSpdySessionPeer::GetHeadersStream(&session_)),
body_("hello world"),
- framer_(HTTP2),
stream_frame_(kHeadersStreamId, /*fin=*/false, /*offset=*/0, ""),
next_promised_stream_id_(2) {
FLAGS_quic_always_log_bugs_for_tests = true;
headers_[":version"] = "HTTP/1.1";
headers_[":status"] = "200 Ok";
headers_["content-length"] = "11";
- framer_.set_visitor(&visitor_);
+ FLAGS_spdy_on_stream_end = GetParam().spdy_on_stream_end;
+ framer_ = std::unique_ptr<SpdyFramer>(new SpdyFramer(HTTP2));
+ framer_->set_visitor(&visitor_);
EXPECT_EQ(version(), session_.connection()->version());
EXPECT_TRUE(headers_stream_ != nullptr);
VLOG(1) << GetParam();
@@ -176,7 +186,7 @@ class QuicHeadersStreamTest : public ::testing::TestWithParam<TestParams> {
SpdyPriority priority,
SpdyFrameType type) {
// Write the headers and capture the outgoing data
- EXPECT_CALL(session_, WritevData(kHeadersStreamId, _, _, false, _, nullptr))
+ EXPECT_CALL(session_, WritevData(kHeadersStreamId, _, _, false, nullptr))
.WillOnce(WithArgs<1>(Invoke(this, &QuicHeadersStreamTest::SaveIov)));
headers_stream_->WriteHeaders(stream_id, headers_, fin, priority, nullptr);
@@ -197,11 +207,15 @@ class QuicHeadersStreamTest : public ::testing::TestWithParam<TestParams> {
.WillRepeatedly(WithArgs<1, 2>(
Invoke(this, &QuicHeadersStreamTest::SaveHeaderData)));
if (fin) {
- EXPECT_CALL(visitor_, OnStreamFrameData(stream_id, nullptr, 0, true));
+ if (FLAGS_spdy_on_stream_end) {
+ EXPECT_CALL(visitor_, OnStreamEnd(stream_id));
+ } else {
+ EXPECT_CALL(visitor_, OnStreamFrameData(stream_id, nullptr, 0, true));
+ }
}
- framer_.ProcessInput(saved_data_.data(), saved_data_.length());
- EXPECT_FALSE(framer_.HasError())
- << SpdyFramer::ErrorCodeToString(framer_.error_code());
+ framer_->ProcessInput(saved_data_.data(), saved_data_.length());
+ EXPECT_FALSE(framer_->HasError())
+ << SpdyFramer::ErrorCodeToString(framer_->error_code());
CheckHeaders();
saved_data_.clear();
@@ -209,7 +223,7 @@ class QuicHeadersStreamTest : public ::testing::TestWithParam<TestParams> {
void CheckHeaders() {
SpdyHeaderBlock headers;
- EXPECT_TRUE(framer_.ParseHeaderBlockInBuffer(
+ EXPECT_TRUE(framer_->ParseHeaderBlockInBuffer(
saved_header_data_.data(), saved_header_data_.length(), &headers));
EXPECT_EQ(headers_, headers);
saved_header_data_.clear();
@@ -240,7 +254,7 @@ class QuicHeadersStreamTest : public ::testing::TestWithParam<TestParams> {
string body_;
string saved_data_;
string saved_header_data_;
- SpdyFramer framer_;
+ std::unique_ptr<SpdyFramer> framer_;
StrictMock<MockVisitor> visitor_;
QuicStreamFrame stream_frame_;
QuicStreamId next_promised_stream_id_;
@@ -276,8 +290,7 @@ TEST_P(QuicHeadersStreamTest, WritePushPromises) {
QuicStreamId promised_stream_id = NextPromisedStreamId();
if (perspective() == Perspective::IS_SERVER) {
// Write the headers and capture the outgoing data
- EXPECT_CALL(session_,
- WritevData(kHeadersStreamId, _, _, false, _, nullptr))
+ EXPECT_CALL(session_, WritevData(kHeadersStreamId, _, _, false, nullptr))
.WillOnce(WithArgs<1>(Invoke(this, &QuicHeadersStreamTest::SaveIov)));
headers_stream_->WritePushPromise(stream_id, promised_stream_id, headers_,
nullptr);
@@ -288,9 +301,9 @@ TEST_P(QuicHeadersStreamTest, WritePushPromises) {
EXPECT_CALL(visitor_, OnControlFrameHeaderData(stream_id, _, _))
.WillRepeatedly(WithArgs<1, 2>(
Invoke(this, &QuicHeadersStreamTest::SaveHeaderData)));
- framer_.ProcessInput(saved_data_.data(), saved_data_.length());
- EXPECT_FALSE(framer_.HasError())
- << SpdyFramer::ErrorCodeToString(framer_.error_code());
+ framer_->ProcessInput(saved_data_.data(), saved_data_.length());
+ EXPECT_FALSE(framer_->HasError())
+ << SpdyFramer::ErrorCodeToString(framer_->error_code());
CheckHeaders();
saved_data_.clear();
} else {
@@ -313,13 +326,13 @@ TEST_P(QuicHeadersStreamTest, ProcessRawData) {
headers_frame.set_header_block(headers_);
headers_frame.set_fin(fin);
headers_frame.set_has_priority(true);
- frame.reset(framer_.SerializeFrame(headers_frame));
+ frame.reset(framer_->SerializeFrame(headers_frame));
EXPECT_CALL(session_, OnStreamHeadersPriority(stream_id, 0));
} else {
SpdyHeadersIR headers_frame(stream_id);
headers_frame.set_header_block(headers_);
headers_frame.set_fin(fin);
- frame.reset(framer_.SerializeFrame(headers_frame));
+ frame.reset(framer_->SerializeFrame(headers_frame));
}
EXPECT_CALL(session_, OnStreamHeaders(stream_id, _))
.WillRepeatedly(WithArgs<1>(Invoke(
@@ -345,7 +358,7 @@ TEST_P(QuicHeadersStreamTest, ProcessPushPromise) {
scoped_ptr<SpdySerializedFrame> frame;
SpdyPushPromiseIR push_promise(stream_id, promised_stream_id);
push_promise.set_header_block(headers_);
- frame.reset(framer_.SerializeFrame(push_promise));
+ frame.reset(framer_->SerializeFrame(push_promise));
if (perspective() == Perspective::IS_SERVER) {
EXPECT_CALL(*connection_, SendConnectionCloseWithDetails(
QUIC_INVALID_HEADERS_STREAM_DATA,
@@ -382,13 +395,13 @@ TEST_P(QuicHeadersStreamTest, EmptyHeaderHOLBlockedTime) {
headers_frame.set_header_block(headers_);
headers_frame.set_fin(fin);
headers_frame.set_has_priority(true);
- frame.reset(framer_.SerializeFrame(headers_frame));
+ frame.reset(framer_->SerializeFrame(headers_frame));
EXPECT_CALL(session_, OnStreamHeadersPriority(stream_id, 0));
} else {
SpdyHeadersIR headers_frame(stream_id);
headers_frame.set_header_block(headers_);
headers_frame.set_fin(fin);
- frame.reset(framer_.SerializeFrame(headers_frame));
+ frame.reset(framer_->SerializeFrame(headers_frame));
}
EXPECT_CALL(session_, OnStreamHeaders(stream_id, _));
EXPECT_CALL(session_,
@@ -416,13 +429,13 @@ TEST_P(QuicHeadersStreamTest, NonEmptyHeaderHOLBlockedTime) {
headers_frame.set_header_block(headers_);
headers_frame.set_fin(fin);
headers_frame.set_has_priority(true);
- frames[stream_num].reset(framer_.SerializeFrame(headers_frame));
+ frames[stream_num].reset(framer_->SerializeFrame(headers_frame));
EXPECT_CALL(session_, OnStreamHeadersPriority(stream_id, 0)).Times(1);
} else {
SpdyHeadersIR headers_frame(stream_id);
headers_frame.set_header_block(headers_);
headers_frame.set_fin(fin);
- frames[stream_num].reset(framer_.SerializeFrame(headers_frame));
+ frames[stream_num].reset(framer_->SerializeFrame(headers_frame));
}
stream_frames[stream_num].stream_id = stream_frame_.stream_id;
stream_frames[stream_num].offset = stream_frame_.offset;
@@ -466,13 +479,13 @@ TEST_P(QuicHeadersStreamTest, ProcessLargeRawData) {
headers_frame.set_header_block(headers_);
headers_frame.set_fin(fin);
headers_frame.set_has_priority(true);
- frame.reset(framer_.SerializeFrame(headers_frame));
+ frame.reset(framer_->SerializeFrame(headers_frame));
EXPECT_CALL(session_, OnStreamHeadersPriority(stream_id, 0));
} else {
SpdyHeadersIR headers_frame(stream_id);
headers_frame.set_header_block(headers_);
headers_frame.set_fin(fin);
- frame.reset(framer_.SerializeFrame(headers_frame));
+ frame.reset(framer_->SerializeFrame(headers_frame));
}
EXPECT_CALL(session_, OnStreamHeaders(stream_id, _))
.WillRepeatedly(WithArgs<1>(Invoke(
@@ -501,7 +514,7 @@ TEST_P(QuicHeadersStreamTest, ProcessBadData) {
TEST_P(QuicHeadersStreamTest, ProcessSpdyDataFrame) {
SpdyDataIR data(2, "");
- scoped_ptr<SpdySerializedFrame> frame(framer_.SerializeFrame(data));
+ scoped_ptr<SpdySerializedFrame> frame(framer_->SerializeFrame(data));
EXPECT_CALL(*connection_,
SendConnectionCloseWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
"SPDY DATA frame received."))
@@ -514,7 +527,7 @@ TEST_P(QuicHeadersStreamTest, ProcessSpdyDataFrame) {
TEST_P(QuicHeadersStreamTest, ProcessSpdyRstStreamFrame) {
SpdyRstStreamIR data(2, RST_STREAM_PROTOCOL_ERROR);
- scoped_ptr<SpdySerializedFrame> frame(framer_.SerializeFrame(data));
+ scoped_ptr<SpdySerializedFrame> frame(framer_->SerializeFrame(data));
EXPECT_CALL(*connection_,
SendConnectionCloseWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
"SPDY RST_STREAM frame received."))
@@ -528,7 +541,7 @@ TEST_P(QuicHeadersStreamTest, ProcessSpdyRstStreamFrame) {
TEST_P(QuicHeadersStreamTest, ProcessSpdySettingsFrame) {
SpdySettingsIR data;
data.AddSetting(SETTINGS_HEADER_TABLE_SIZE, true, true, 0);
- scoped_ptr<SpdySerializedFrame> frame(framer_.SerializeFrame(data));
+ scoped_ptr<SpdySerializedFrame> frame(framer_->SerializeFrame(data));
EXPECT_CALL(*connection_,
SendConnectionCloseWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
"SPDY SETTINGS frame received."))
@@ -541,7 +554,7 @@ TEST_P(QuicHeadersStreamTest, ProcessSpdySettingsFrame) {
TEST_P(QuicHeadersStreamTest, ProcessSpdyPingFrame) {
SpdyPingIR data(1);
- scoped_ptr<SpdySerializedFrame> frame(framer_.SerializeFrame(data));
+ scoped_ptr<SpdySerializedFrame> frame(framer_->SerializeFrame(data));
EXPECT_CALL(*connection_,
SendConnectionCloseWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
"SPDY PING frame received."))
@@ -554,7 +567,7 @@ TEST_P(QuicHeadersStreamTest, ProcessSpdyPingFrame) {
TEST_P(QuicHeadersStreamTest, ProcessSpdyGoAwayFrame) {
SpdyGoAwayIR data(1, GOAWAY_PROTOCOL_ERROR, "go away");
- scoped_ptr<SpdySerializedFrame> frame(framer_.SerializeFrame(data));
+ scoped_ptr<SpdySerializedFrame> frame(framer_->SerializeFrame(data));
EXPECT_CALL(*connection_,
SendConnectionCloseWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
"SPDY GOAWAY frame received."))
@@ -567,7 +580,7 @@ TEST_P(QuicHeadersStreamTest, ProcessSpdyGoAwayFrame) {
TEST_P(QuicHeadersStreamTest, ProcessSpdyWindowUpdateFrame) {
SpdyWindowUpdateIR data(1, 1);
- scoped_ptr<SpdySerializedFrame> frame(framer_.SerializeFrame(data));
+ scoped_ptr<SpdySerializedFrame> frame(framer_->SerializeFrame(data));
EXPECT_CALL(*connection_, SendConnectionCloseWithDetails(
QUIC_INVALID_HEADERS_STREAM_DATA,
"SPDY WINDOW_UPDATE frame received."))
diff --git a/net/quic/quic_multipath_received_packet_manager.cc b/net/quic/quic_multipath_received_packet_manager.cc
index 6494137..26d7fa0 100644
--- a/net/quic/quic_multipath_received_packet_manager.cc
+++ b/net/quic/quic_multipath_received_packet_manager.cc
@@ -57,18 +57,6 @@ void QuicMultipathReceivedPacketManager::RecordPacketReceived(
manager->RecordPacketReceived(bytes, header, receipt_time);
}
-void QuicMultipathReceivedPacketManager::RecordPacketRevived(
- QuicPathId path_id,
- QuicPacketNumber packet_number) {
- QuicReceivedPacketManager* manager = path_managers_[path_id];
- if (manager == nullptr) {
- QUIC_BUG << "Revived a packet on a non-existent path.";
- return;
- }
-
- manager->RecordPacketRevived(packet_number);
-}
-
bool QuicMultipathReceivedPacketManager::IsMissing(
QuicPathId path_id,
QuicPacketNumber packet_number) {
diff --git a/net/quic/quic_multipath_received_packet_manager.h b/net/quic/quic_multipath_received_packet_manager.h
index dba9244..5f1f3a3 100644
--- a/net/quic/quic_multipath_received_packet_manager.h
+++ b/net/quic/quic_multipath_received_packet_manager.h
@@ -40,9 +40,6 @@ class NET_EXPORT_PRIVATE QuicMultipathReceivedPacketManager {
const QuicPacketHeader& header,
QuicTime receipt_time);
- // Called when packet with |packet_number| is revived on path with |path_id|.
- void RecordPacketRevived(QuicPathId path_id, QuicPacketNumber packet_number);
-
// Checks whether |packet_number| is missing on path with |path_id|.
bool IsMissing(QuicPathId path_id, QuicPacketNumber packet_number);
diff --git a/net/quic/quic_multipath_received_packet_manager_test.cc b/net/quic/quic_multipath_received_packet_manager_test.cc
index e342ae8..8a54a68 100644
--- a/net/quic/quic_multipath_received_packet_manager_test.cc
+++ b/net/quic/quic_multipath_received_packet_manager_test.cc
@@ -100,14 +100,6 @@ TEST_F(QuicMultipathReceivedPacketManagerTest, RecordPacketReceived) {
"Received a packet on a non-existent path");
}
-TEST_F(QuicMultipathReceivedPacketManagerTest, RecordPacketRevived) {
- EXPECT_CALL(*manager_0_, RecordPacketRevived(_)).Times(1);
- multipath_manager_.RecordPacketRevived(kDefaultPathId, header_.packet_number);
- EXPECT_DFATAL(
- multipath_manager_.RecordPacketRevived(kPathId2, header_.packet_number),
- "Revived a packet on a non-existent path");
-}
-
TEST_F(QuicMultipathReceivedPacketManagerTest, IsMissing) {
EXPECT_CALL(*manager_0_, IsMissing(header_.packet_number))
.WillOnce(Return(true));
diff --git a/net/quic/quic_packet_creator.cc b/net/quic/quic_packet_creator.cc
index f4e0cf7..a0a38a5 100644
--- a/net/quic/quic_packet_creator.cc
+++ b/net/quic/quic_packet_creator.cc
@@ -11,7 +11,6 @@
#include "net/quic/crypto/quic_random.h"
#include "net/quic/quic_bug_tracker.h"
#include "net/quic/quic_data_writer.h"
-#include "net/quic/quic_fec_group.h"
#include "net/quic/quic_flags.h"
#include "net/quic/quic_utils.h"
@@ -24,29 +23,6 @@ using std::vector;
namespace net {
-namespace {
-
-// Default max packets in an FEC group.
-static const size_t kDefaultMaxPacketsPerFecGroup = 10;
-// Lowest max packets in an FEC group.
-static const size_t kLowestMaxPacketsPerFecGroup = 2;
-
-// We want to put some space between a protected packet and the FEC packet to
-// avoid losing them both within the same loss episode. On the other hand, we
-// expect to be able to recover from any loss in about an RTT. We resolve this
-// tradeoff by sending an FEC packet atmost half an RTT, or equivalently, half
-// the max number of in-flight packets, the first protected packet. Since we
-// don't want to delay an FEC packet past half an RTT, we set the max FEC group
-// size to be half the current congestion window.
-const float kMaxPacketsInFlightMultiplierForFecGroupSize = 0.5;
-const float kRttMultiplierForFecTimeout = 0.5;
-
-// Minimum timeout for FEC alarm, set to half the minimum Tail Loss Probe
-// timeout of 10ms.
-const int64_t kMinFecTimeoutMs = 5u;
-
-} // namespace
-
// A QuicRandom wrapper that gets a bucket of entropy and distributes it
// bit-by-bit. Replenishes the bucket as needed. Not thread-safe. Expose this
// class if single bit randomness is needed elsewhere.
@@ -104,13 +80,7 @@ QuicPacketCreator::QuicPacketCreator(QuicConnectionId connection_id,
0,
0,
false,
- false),
- should_fec_protect_next_packet_(false),
- fec_protect_(false),
- max_packets_per_fec_group_(kDefaultMaxPacketsPerFecGroup),
- fec_send_policy_(FEC_ANY_TRIGGER),
- fec_timeout_(QuicTime::Delta::Zero()),
- rtt_multiplier_for_fec_timeout_(kRttMultiplierForFecTimeout) {
+ false) {
SetMaxPacketLength(kDefaultMaxPacketSize);
}
@@ -118,15 +88,6 @@ QuicPacketCreator::~QuicPacketCreator() {
QuicUtils::DeleteFrames(&packet_.retransmittable_frames);
}
-void QuicPacketCreator::OnBuiltFecProtectedPayload(
- const QuicPacketHeader& header,
- StringPiece payload) {
- if (fec_group_.get() != nullptr) {
- DCHECK_NE(0u, header.fec_group);
- fec_group_->Update(packet_.encryption_level, header, payload);
- }
-}
-
void QuicPacketCreator::SetEncrypter(EncryptionLevel level,
QuicEncrypter* encrypter) {
framer_->SetEncrypter(level, encrypter);
@@ -134,8 +95,8 @@ void QuicPacketCreator::SetEncrypter(EncryptionLevel level,
}
bool QuicPacketCreator::CanSetMaxPacketLength() const {
- // |max_packet_length_| should not be changed mid-packet or mid-FEC group.
- return fec_group_.get() == nullptr && queued_frames_.empty();
+ // |max_packet_length_| should not be changed mid-packet.
+ return queued_frames_.empty();
}
void QuicPacketCreator::SetMaxPacketLength(QuicByteCount length) {
@@ -151,81 +112,14 @@ void QuicPacketCreator::SetMaxPacketLength(QuicByteCount length) {
max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_);
}
-void QuicPacketCreator::set_max_packets_per_fec_group(
- size_t max_packets_per_fec_group) {
- max_packets_per_fec_group_ =
- max(kLowestMaxPacketsPerFecGroup, max_packets_per_fec_group);
- DCHECK_LT(0u, max_packets_per_fec_group_);
-}
-
-bool QuicPacketCreator::ShouldSendFec(bool force_close) const {
- return !HasPendingFrames() && fec_group_.get() != nullptr &&
- fec_group_->NumReceivedPackets() > 0 &&
- (force_close ||
- fec_group_->NumReceivedPackets() >= max_packets_per_fec_group_);
-}
-
-void QuicPacketCreator::ResetFecGroup() {
- if (HasPendingFrames()) {
- QUIC_BUG_IF(packet_size_ != 0)
- << "Cannot reset FEC group with pending frames.";
- return;
- }
- fec_group_.reset(nullptr);
-}
-
-bool QuicPacketCreator::IsFecGroupOpen() const {
- return fec_group_.get() != nullptr;
-}
-
-void QuicPacketCreator::StartFecProtectingPackets() {
- if (max_packets_per_fec_group_ == 0) {
- QUIC_BUG << "Cannot start FEC protection when FEC is not enabled.";
- return;
- }
- // TODO(jri): This currently requires that the generator flush out any
- // pending frames when FEC protection is turned on. If current packet can be
- // converted to an FEC protected packet, do it. This will require the
- // generator to check if the resulting expansion still allows the incoming
- // frame to be added to the packet.
- if (HasPendingFrames()) {
- QUIC_BUG << "Cannot start FEC protection with pending frames.";
- return;
- }
- DCHECK(!fec_protect_);
- fec_protect_ = true;
-}
-
-void QuicPacketCreator::StopFecProtectingPackets() {
- if (fec_group_.get() != nullptr) {
- QUIC_BUG << "Cannot stop FEC protection with open FEC group.";
- return;
- }
- DCHECK(fec_protect_);
- fec_protect_ = false;
-}
-
-InFecGroup QuicPacketCreator::MaybeUpdateLengthsAndStartFec() {
- if (fec_group_.get() != nullptr) {
- // Don't update any lengths when an FEC group is open, to ensure same
- // packet header size in all packets within a group.
- return IN_FEC_GROUP;
- }
+void QuicPacketCreator::MaybeUpdatePacketNumberLength() {
if (!queued_frames_.empty()) {
// Don't change creator state if there are frames queued.
- return NOT_IN_FEC_GROUP;
+ return;
}
- // Update packet number length only on packet and FEC group boundaries.
+ // Update packet number length only on packet boundary.
packet_.packet_number_length = next_packet_number_length_;
-
- if (!fec_protect_) {
- return NOT_IN_FEC_GROUP;
- }
- // Start a new FEC group since protection is on. Set the fec group number to
- // the packet number of the next packet.
- fec_group_.reset(new QuicFecGroup(packet_.packet_number + 1));
- return IN_FEC_GROUP;
}
// Stops serializing version of the protocol in packets sent after this call.
@@ -244,11 +138,8 @@ void QuicPacketCreator::UpdatePacketNumberLength(
QuicPacketNumber least_packet_awaited_by_peer,
QuicPacketCount max_packets_in_flight) {
DCHECK_LE(least_packet_awaited_by_peer, packet_.packet_number + 1);
- // Since the packet creator will not change packet number length mid FEC
- // group, include the size of an FEC group to be safe.
- const QuicPacketNumber current_delta = max_packets_per_fec_group_ +
- packet_.packet_number + 1 -
- least_packet_awaited_by_peer;
+ const QuicPacketNumber current_delta =
+ packet_.packet_number + 1 - least_packet_awaited_by_peer;
const uint64_t delta = max(current_delta, max_packets_in_flight);
next_packet_number_length_ =
QuicFramer::GetMinSequenceNumberLength(delta * 4);
@@ -260,15 +151,10 @@ bool QuicPacketCreator::ConsumeData(QuicStreamId id,
QuicStreamOffset offset,
bool fin,
bool needs_padding,
- QuicFrame* frame,
- FecProtection fec_protection) {
+ QuicFrame* frame) {
if (!HasRoomForStreamFrame(id, offset)) {
return false;
}
- if (fec_protection == MUST_FEC_PROTECT) {
- should_fec_protect_next_packet_ = true;
- MaybeStartFecProtection();
- }
CreateStreamFrame(id, iov, iov_offset, offset, fin, frame);
if (!AddFrame(*frame, /*save_retransmittable_frames=*/true)) {
// Fails if we try to write unencrypted stream data.
@@ -278,23 +164,12 @@ bool QuicPacketCreator::ConsumeData(QuicStreamId id,
if (needs_padding) {
packet_.needs_padding = true;
}
- if (fec_protection == MUST_FEC_PROTECT &&
- iov_offset + frame->stream_frame->frame_length == iov.total_length) {
- // Turn off FEC protection when we're done writing protected data.
- DVLOG(1) << "Turning FEC protection OFF";
- should_fec_protect_next_packet_ = false;
- }
return true;
}
bool QuicPacketCreator::HasRoomForStreamFrame(QuicStreamId id,
QuicStreamOffset offset) {
- // TODO(jri): This is a simple safe decision for now, but make
- // is_in_fec_group a parameter. Same as with all public methods in
- // QuicPacketCreator.
- return BytesFree() >
- QuicFramer::GetMinStreamFrameSize(
- id, offset, true, fec_protect_ ? IN_FEC_GROUP : NOT_IN_FEC_GROUP);
+ return BytesFree() > QuicFramer::GetMinStreamFrameSize(id, offset, true);
}
// static
@@ -303,13 +178,11 @@ size_t QuicPacketCreator::StreamFramePacketOverhead(
bool include_version,
bool include_path_id,
QuicPacketNumberLength packet_number_length,
- QuicStreamOffset offset,
- InFecGroup is_in_fec_group) {
+ QuicStreamOffset offset) {
return GetPacketHeaderSize(connection_id_length, include_version,
- include_path_id, packet_number_length,
- is_in_fec_group) +
+ include_path_id, packet_number_length) +
// Assumes this is a stream with a single lone packet.
- QuicFramer::GetMinStreamFrameSize(1u, offset, true, is_in_fec_group);
+ QuicFramer::GetMinStreamFrameSize(1u, offset, true);
}
size_t QuicPacketCreator::CreateStreamFrame(QuicStreamId id,
@@ -319,16 +192,16 @@ size_t QuicPacketCreator::CreateStreamFrame(QuicStreamId id,
bool fin,
QuicFrame* frame) {
DCHECK_GT(max_packet_length_,
- StreamFramePacketOverhead(
- connection_id_length_, kIncludeVersion, kIncludePathId,
- PACKET_6BYTE_PACKET_NUMBER, offset, IN_FEC_GROUP));
+ StreamFramePacketOverhead(connection_id_length_, kIncludeVersion,
+ kIncludePathId,
+ PACKET_6BYTE_PACKET_NUMBER, offset));
- InFecGroup is_in_fec_group = MaybeUpdateLengthsAndStartFec();
+ MaybeUpdatePacketNumberLength();
LOG_IF(DFATAL, !HasRoomForStreamFrame(id, offset))
<< "No room for Stream frame, BytesFree: " << BytesFree()
<< " MinStreamFrameSize: "
- << QuicFramer::GetMinStreamFrameSize(id, offset, true, is_in_fec_group);
+ << QuicFramer::GetMinStreamFrameSize(id, offset, true);
if (iov_offset == iov.total_length) {
QUIC_BUG_IF(!fin) << "Creating a stream frame with no data or fin.";
@@ -339,7 +212,7 @@ size_t QuicPacketCreator::CreateStreamFrame(QuicStreamId id,
const size_t data_size = iov.total_length - iov_offset;
size_t min_frame_size = QuicFramer::GetMinStreamFrameSize(
- id, offset, /* last_frame_in_packet= */ true, is_in_fec_group);
+ id, offset, /* last_frame_in_packet= */ true);
size_t bytes_consumed = min<size_t>(BytesFree() - min_frame_size, data_size);
bool set_fin = fin && bytes_consumed == data_size; // Last frame.
@@ -409,20 +282,16 @@ void QuicPacketCreator::ReserializeAllFrames(
char* buffer,
size_t buffer_len) {
DCHECK(queued_frames_.empty());
- DCHECK(fec_group_.get() == nullptr);
DCHECK(!packet_.needs_padding);
QUIC_BUG_IF(retransmission.retransmittable_frames.empty())
<< "Attempt to serialize empty packet";
const QuicPacketNumberLength saved_length = packet_.packet_number_length;
const QuicPacketNumberLength saved_next_length = next_packet_number_length_;
- const bool saved_should_fec_protect = fec_protect_;
const EncryptionLevel default_encryption_level = packet_.encryption_level;
- // Temporarily set the packet number length, stop FEC protection,
- // and change the encryption level.
+ // Temporarily set the packet number length and change the encryption level.
packet_.packet_number_length = retransmission.packet_number_length;
next_packet_number_length_ = retransmission.packet_number_length;
- fec_protect_ = false;
packet_.needs_padding = retransmission.needs_padding;
// Only preserve the original encryption level if it's a handshake packet or
// if we haven't gone forward secure.
@@ -431,7 +300,7 @@ void QuicPacketCreator::ReserializeAllFrames(
packet_.encryption_level = retransmission.encryption_level;
}
- // Serialize the packet and restore the FEC and packet number length state.
+ // Serialize the packet and restore packet number length state.
for (const QuicFrame& frame : retransmission.retransmittable_frames) {
bool success = AddFrame(frame, false);
DCHECK(success);
@@ -443,7 +312,6 @@ void QuicPacketCreator::ReserializeAllFrames(
// Restore old values.
packet_.packet_number_length = saved_length;
next_packet_number_length_ = saved_next_length;
- fec_protect_ = saved_should_fec_protect;
packet_.encryption_level = default_encryption_level;
}
@@ -461,8 +329,7 @@ void QuicPacketCreator::Flush() {
void QuicPacketCreator::OnSerializedPacket() {
if (packet_.encrypted_buffer == nullptr) {
- QUIC_BUG << "Failed to SerializePacket. fec_policy:" << fec_send_policy()
- << " should_fec_protect_:" << should_fec_protect_next_packet_;
+ QUIC_BUG << "Failed to SerializePacket.";
delegate_->OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET,
ConnectionCloseSource::FROM_SELF);
return;
@@ -470,8 +337,6 @@ void QuicPacketCreator::OnSerializedPacket() {
delegate_->OnSerializedPacket(&packet_);
ClearPacket();
- MaybeSendFecPacketAndCloseGroup(/*force_send_fec=*/false,
- /*is_fec_timeout=*/false);
// Maximum packet size may be only enacted while no packet is currently being
// constructed, so here we have a good opportunity to actually change it.
if (CanSetMaxPacketLength()) {
@@ -484,7 +349,6 @@ void QuicPacketCreator::ClearPacket() {
packet_.has_stop_waiting = false;
packet_.has_crypto_handshake = NOT_HANDSHAKE;
packet_.needs_padding = false;
- packet_.is_fec_packet = false;
packet_.original_packet_number = 0;
packet_.transmission_type = NOT_RETRANSMISSION;
packet_.encrypted_buffer = nullptr;
@@ -502,10 +366,6 @@ bool QuicPacketCreator::HasPendingRetransmittableFrames() const {
}
size_t QuicPacketCreator::ExpansionOnNewFrame() const {
- // If packet is FEC protected, there's no expansion.
- if (fec_protect_) {
- return 0;
- }
// If the last frame in the packet is a stream frame, then it will expand to
// include the stream_length field when a new frame is added.
bool has_trailing_stream_frame =
@@ -523,14 +383,11 @@ size_t QuicPacketCreator::PacketSize() {
if (!queued_frames_.empty()) {
return packet_size_;
}
- if (fec_group_.get() == nullptr) {
- // Update packet number length on packet and FEC boundary.
- packet_.packet_number_length = next_packet_number_length_;
- }
- packet_size_ =
- GetPacketHeaderSize(connection_id_length_, send_version_in_packet_,
- send_path_id_in_packet_, packet_.packet_number_length,
- fec_protect_ ? IN_FEC_GROUP : NOT_IN_FEC_GROUP);
+ // Update packet number length on packet boundary.
+ packet_.packet_number_length = next_packet_number_length_;
+ packet_size_ = GetPacketHeaderSize(
+ connection_id_length_, send_version_in_packet_, send_path_id_in_packet_,
+ packet_.packet_number_length);
return packet_size_;
}
@@ -556,24 +413,13 @@ void QuicPacketCreator::SerializePacket(char* encrypted_buffer,
size_t encrypted_buffer_len) {
DCHECK_LT(0u, encrypted_buffer_len);
QUIC_BUG_IF(queued_frames_.empty()) << "Attempt to serialize empty packet";
- if (fec_group_.get() != nullptr) {
- DCHECK_GE(packet_.packet_number + 1, fec_group_->FecGroupNumber());
- }
QuicPacketHeader header;
// FillPacketHeader increments packet_number_.
- FillPacketHeader(fec_group_ != nullptr ? fec_group_->FecGroupNumber() : 0,
- false, &header);
+ FillPacketHeader(&header);
MaybeAddPadding();
DCHECK_GE(max_plaintext_size_, packet_size_);
- // ACK Frames will be truncated due to length only if they're the only frame
- // in the packet, and if packet_size_ was set to max_plaintext_size_. If
- // truncation due to length occurred, then GetSerializedFrameLength will have
- // returned all bytes free.
- bool possibly_truncated_by_length = packet_size_ == max_plaintext_size_ &&
- queued_frames_.size() == 1 &&
- queued_frames_.back().type == ACK_FRAME;
// Use the packet_size_ instead of the buffer size to ensure smaller
// packet sizes are properly used.
size_t length = framer_->BuildDataPacket(header, queued_frames_,
@@ -583,25 +429,36 @@ void QuicPacketCreator::SerializePacket(char* encrypted_buffer,
return;
}
- // TODO(ianswett) Consider replacing QuicPacket with something else, since
- // it's only used to provide convenience methods to FEC and encryption.
- QuicPacket packet(
- encrypted_buffer, length,
- /* owns_buffer */ false, header.public_header.connection_id_length,
- header.public_header.version_flag, header.public_header.multipath_flag,
- header.public_header.packet_number_length);
- OnBuiltFecProtectedPayload(header, packet.FecProtectedData());
-
+ // ACK Frames will be truncated due to length only if they're the only frame
+ // in the packet, and if packet_size_ was set to max_plaintext_size_. If
+ // truncation due to length occurred, then GetSerializedFrameLength will have
+ // returned all bytes free.
+ bool possibly_truncated_by_length = packet_size_ == max_plaintext_size_ &&
+ queued_frames_.size() == 1 &&
+ queued_frames_.back().type == ACK_FRAME;
// Because of possible truncation, we can't be confident that our
// packet size calculation worked correctly.
if (!possibly_truncated_by_length) {
DCHECK_EQ(packet_size_, length);
}
- // Immediately encrypt the packet, to ensure we don't encrypt the same
- // packet number multiple times.
- size_t encrypted_length = framer_->EncryptPayload(
- packet_.encryption_level, packet_.path_id, packet_.packet_number, packet,
- encrypted_buffer, encrypted_buffer_len);
+ size_t encrypted_length = 0;
+ if (FLAGS_quic_inplace_encryption2) {
+ const size_t ad_len = GetStartOfEncryptedData(header);
+ encrypted_length = framer_->EncryptInPlace(
+ packet_.encryption_level, packet_.path_id, packet_.packet_number,
+ ad_len, length, encrypted_buffer_len, encrypted_buffer);
+ } else {
+ QuicPacket packet(
+ encrypted_buffer, length,
+ /* owns_buffer */ false, header.public_header.connection_id_length,
+ header.public_header.version_flag, header.public_header.multipath_flag,
+ header.public_header.packet_number_length);
+ // Immediately encrypt the packet, to ensure we don't encrypt the same
+ // packet number multiple times.
+ encrypted_length = framer_->EncryptPayload(
+ packet_.encryption_level, packet_.path_id, packet_.packet_number,
+ packet, encrypted_buffer, encrypted_buffer_len);
+ }
if (encrypted_length == 0) {
QUIC_BUG << "Failed to encrypt packet number " << packet_.packet_number;
return;
@@ -614,44 +471,6 @@ void QuicPacketCreator::SerializePacket(char* encrypted_buffer,
packet_.encrypted_length = encrypted_length;
}
-void QuicPacketCreator::SerializeFec(char* buffer, size_t buffer_len) {
- DCHECK_LT(0u, buffer_len);
- if (fec_group_.get() == nullptr || fec_group_->NumReceivedPackets() <= 0) {
- QUIC_BUG << "SerializeFEC called but no group or zero packets in group.";
- return;
- }
- if (FLAGS_quic_no_unencrypted_fec &&
- packet_.encryption_level == ENCRYPTION_NONE) {
- QUIC_BUG << "SerializeFEC must be called with encryption.";
- delegate_->OnUnrecoverableError(QUIC_UNENCRYPTED_FEC_DATA,
- ConnectionCloseSource::FROM_SELF);
- return;
- }
- DCHECK_EQ(0u, queued_frames_.size());
- QuicPacketHeader header;
- FillPacketHeader(fec_group_->FecGroupNumber(), true, &header);
- scoped_ptr<QuicPacket> packet(
- framer_->BuildFecPacket(header, fec_group_->PayloadParity()));
- fec_group_.reset(nullptr);
- packet_size_ = 0;
- QUIC_BUG_IF(packet == nullptr) << "Failed to serialize fec packet for group:"
- << fec_group_->FecGroupNumber();
- DCHECK_GE(max_packet_length_, packet->length());
- // Immediately encrypt the packet, to ensure we don't encrypt the same packet
- // packet number multiple times.
- size_t encrypted_length = framer_->EncryptPayload(
- packet_.encryption_level, packet_.path_id, packet_.packet_number, *packet,
- buffer, buffer_len);
- if (encrypted_length == 0) {
- QUIC_BUG << "Failed to encrypt packet number " << packet_.packet_number;
- return;
- }
- packet_.entropy_hash = QuicFramer::GetPacketEntropyHash(header);
- packet_.encrypted_buffer = buffer;
- packet_.encrypted_length = encrypted_length;
- packet_.is_fec_packet = true;
-}
-
QuicEncryptedPacket* QuicPacketCreator::SerializeVersionNegotiationPacket(
const QuicVersionVector& supported_versions) {
DCHECK_EQ(Perspective::IS_SERVER, framer_->perspective());
@@ -668,21 +487,19 @@ SerializedPacket QuicPacketCreator::NoPacket() {
nullptr, 0, 0, false, false);
}
-void QuicPacketCreator::FillPacketHeader(QuicFecGroupNumber fec_group,
- bool fec_flag,
- QuicPacketHeader* header) {
+void QuicPacketCreator::FillPacketHeader(QuicPacketHeader* header) {
header->public_header.connection_id = connection_id_;
header->public_header.connection_id_length = connection_id_length_;
header->public_header.multipath_flag = send_path_id_in_packet_;
header->public_header.reset_flag = false;
header->public_header.version_flag = send_version_in_packet_;
- header->fec_flag = fec_flag;
+ header->fec_flag = false;
header->path_id = packet_.path_id;
header->packet_number = ++packet_.packet_number;
header->public_header.packet_number_length = packet_.packet_number_length;
header->entropy_flag = random_bool_source_->RandBool();
- header->is_in_fec_group = fec_group == 0 ? NOT_IN_FEC_GROUP : IN_FEC_GROUP;
- header->fec_group = fec_group;
+ header->is_in_fec_group = NOT_IN_FEC_GROUP;
+ header->fec_group = 0;
}
bool QuicPacketCreator::ShouldRetransmit(const QuicFrame& frame) {
@@ -708,10 +525,10 @@ bool QuicPacketCreator::AddFrame(const QuicFrame& frame,
ConnectionCloseSource::FROM_SELF);
return false;
}
- InFecGroup is_in_fec_group = MaybeUpdateLengthsAndStartFec();
+ MaybeUpdatePacketNumberLength();
size_t frame_len = framer_->GetSerializedFrameLength(
- frame, BytesFree(), queued_frames_.empty(), true, is_in_fec_group,
+ frame, BytesFree(), queued_frames_.empty(), true,
packet_.packet_number_length);
if (frame_len == 0) {
// Current open packet is full.
@@ -762,64 +579,6 @@ void QuicPacketCreator::MaybeAddPadding() {
DCHECK(success);
}
-void QuicPacketCreator::MaybeStartFecProtection() {
- if (max_packets_per_fec_group_ == 0 || fec_protect_) {
- // Do not start FEC protection when FEC protection is not enabled or FEC
- // protection is already on.
- return;
- }
- DVLOG(1) << "Turning FEC protection ON";
- // Flush current open packet.
- Flush();
-
- StartFecProtectingPackets();
- DCHECK(fec_protect_);
-}
-
-void QuicPacketCreator::MaybeSendFecPacketAndCloseGroup(bool force_send_fec,
- bool is_fec_timeout) {
- if (ShouldSendFec(force_send_fec)) {
- if ((FLAGS_quic_no_unencrypted_fec &&
- packet_.encryption_level == ENCRYPTION_NONE) ||
- (fec_send_policy_ == FEC_ALARM_TRIGGER && !is_fec_timeout)) {
- ResetFecGroup();
- delegate_->OnResetFecGroup();
- } else {
- // TODO(zhongyi): Change the default 64 alignas value (used the default
- // value from CACHELINE_SIZE).
- ALIGNAS(64) char seralized_fec_buffer[kMaxPacketSize];
- SerializeFec(seralized_fec_buffer, kMaxPacketSize);
- OnSerializedPacket();
- }
- }
-
- if (!should_fec_protect_next_packet_ && fec_protect_ && !IsFecGroupOpen()) {
- StopFecProtectingPackets();
- }
-}
-
-QuicTime::Delta QuicPacketCreator::GetFecTimeout(
- QuicPacketNumber packet_number) {
- // Do not set up FEC alarm for |packet_number| it is not the first packet in
- // the current group.
- if (fec_group_.get() != nullptr &&
- (packet_number == fec_group_->FecGroupNumber())) {
- return QuicTime::Delta::Max(
- fec_timeout_, QuicTime::Delta::FromMilliseconds(kMinFecTimeoutMs));
- }
- return QuicTime::Delta::Infinite();
-}
-
-void QuicPacketCreator::OnCongestionWindowChange(
- QuicPacketCount max_packets_in_flight) {
- set_max_packets_per_fec_group(static_cast<size_t>(
- kMaxPacketsInFlightMultiplierForFecGroupSize * max_packets_in_flight));
-}
-
-void QuicPacketCreator::OnRttChange(QuicTime::Delta rtt) {
- fec_timeout_ = rtt.Multiply(rtt_multiplier_for_fec_timeout_);
-}
-
void QuicPacketCreator::SetCurrentPath(
QuicPathId path_id,
QuicPacketNumber least_packet_awaited_by_peer,
@@ -832,10 +591,6 @@ void QuicPacketCreator::SetCurrentPath(
QUIC_BUG << "Unable to change paths when a packet is under construction.";
return;
}
-
- // Send FEC packet and close FEC group.
- MaybeSendFecPacketAndCloseGroup(/*force_send_fec=*/true,
- /*is_fec_timeout=*/false);
// Save current packet number and load switching path's packet number.
multipath_packet_number_[packet_.path_id] = packet_.packet_number;
std::unordered_map<QuicPathId, QuicPacketNumber>::iterator it =
diff --git a/net/quic/quic_packet_creator.h b/net/quic/quic_packet_creator.h
index fcb4b50..870de4a 100644
--- a/net/quic/quic_packet_creator.h
+++ b/net/quic/quic_packet_creator.h
@@ -3,10 +3,9 @@
// found in the LICENSE file.
//
// Accumulates frames for the next packet until more frames no longer fit or
-// it's time to create a packet from them. Also provides packet creation of
-// FEC packets based on previously created packets. If multipath enabled, only
-// creates packets on one path at the same time. Currently, next packet number
-// is tracked per-path.
+// it's time to create a packet from them. If multipath enabled, only creates
+// packets on one path at the same time. Currently, next packet number is
+// tracked per-path.
#ifndef NET_QUIC_QUIC_PACKET_CREATOR_H_
#define NET_QUIC_QUIC_PACKET_CREATOR_H_
@@ -21,7 +20,6 @@
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_piece.h"
-#include "net/quic/quic_fec_group.h"
#include "net/quic/quic_framer.h"
#include "net/quic/quic_protocol.h"
@@ -50,9 +48,6 @@ class NET_EXPORT_PRIVATE QuicPacketCreator {
// Called when an unrecoverable error is encountered.
virtual void OnUnrecoverableError(QuicErrorCode error,
ConnectionCloseSource source) = 0;
-
- // Called when current FEC group is reset (closed).
- virtual void OnResetFecGroup() = 0;
};
// Interface which gets callbacks from the QuicPacketCreator at interesting
@@ -75,27 +70,6 @@ class NET_EXPORT_PRIVATE QuicPacketCreator {
~QuicPacketCreator();
- // Checks if it's time to send an FEC packet. |force_close| forces this to
- // return true if an FEC group is open.
- bool ShouldSendFec(bool force_close) const;
-
- // If ShouldSendFec returns true, serializes currently constructed FEC packet
- // and calls the delegate on the packet. Resets current FEC group if FEC
- // protection policy is FEC_ALARM_TRIGGER but |is_fec_timeout| is false.
- // Also tries to turn off FEC protection if should_fec_protect_next_packet is
- // false.
- void MaybeSendFecPacketAndCloseGroup(bool force_send_fec,
- bool is_fec_timeout);
-
- // Returns true if an FEC packet is under construction.
- bool IsFecGroupOpen() const;
-
- // Called after sending |packet_number| to determine whether an FEC alarm
- // should be set for sending out an FEC packet. Returns a positive and finite
- // timeout if an FEC alarm should be set, and infinite if no alarm should be
- // set.
- QuicTime::Delta GetFecTimeout(QuicPacketNumber packet_number);
-
// Makes the framer not serialize the protocol version in sent packets.
void StopSendingVersion();
@@ -112,23 +86,20 @@ class NET_EXPORT_PRIVATE QuicPacketCreator {
bool include_version,
bool include_path_id,
QuicPacketNumberLength packet_number_length,
- QuicStreamOffset offset,
- InFecGroup is_in_fec_group);
+ QuicStreamOffset offset);
// Returns false and flushes all pending frames if current open packet is
// full.
// If current packet is not full, converts a raw payload into a stream frame
// that fits into the open packet and adds it to the packet.
// The payload begins at |iov_offset| into the |iov|.
- // Also tries to start FEC protection depends on |fec_protection|.
bool ConsumeData(QuicStreamId id,
QuicIOVector iov,
size_t iov_offset,
QuicStreamOffset offset,
bool fin,
bool needs_padding,
- QuicFrame* frame,
- FecProtection fec_protection);
+ QuicFrame* frame);
// Returns true if current open packet can accommodate more stream frames of
// stream |id| at |offset|, false otherwise.
@@ -136,8 +107,6 @@ class NET_EXPORT_PRIVATE QuicPacketCreator {
// Re-serializes frames with the original packet's packet number length.
// Used for retransmitting packets to ensure they aren't too long.
- // Caller must ensure that any open FEC group is closed before calling this
- // method.
void ReserializeAllFrames(const PendingRetransmission& retransmission,
char* buffer,
size_t buffer_len);
@@ -161,8 +130,7 @@ class NET_EXPORT_PRIVATE QuicPacketCreator {
// Returns the number of bytes that the packet will expand by if a new frame
// is added to the packet. If the last frame was a stream frame, it will
// expand slightly when a new frame is added, and this method returns the
- // amount of expected expansion. If the packet is in an FEC group, no
- // expansion happens and this method always returns zero.
+ // amount of expected expansion.
size_t ExpansionOnNewFrame() const;
// Returns the number of bytes in the current packet, including the header,
@@ -194,12 +162,6 @@ class NET_EXPORT_PRIVATE QuicPacketCreator {
// Returns a dummy packet that is valid but contains no useful information.
static SerializedPacket NoPacket();
- // Called when the congestion window has changed.
- void OnCongestionWindowChange(QuicPacketCount max_packets_in_flight);
-
- // Called when the RTT may have changed.
- void OnRttChange(QuicTime::Delta rtt);
-
// Sets the encryption level that will be applied to new packets.
void set_encryption_level(EncryptionLevel level) {
packet_.encryption_level = level;
@@ -236,35 +198,12 @@ class NET_EXPORT_PRIVATE QuicPacketCreator {
// Sets the path on which subsequent packets will be created. It is the
// caller's responsibility to guarantee no packet is under construction before
- // calling this function. If |path_id| is different from current_path_, the
- // FEC packet (if exists) will be sent and next_packet_number_length_ is
- // recalculated.
+ // calling this function. If |path_id| is different from current_path_,
+ // next_packet_number_length_ is recalculated.
void SetCurrentPath(QuicPathId path_id,
QuicPacketNumber least_packet_awaited_by_peer,
QuicPacketCount max_packets_in_flight);
- // Returns current max number of packets covered by an FEC group.
- size_t max_packets_per_fec_group() const {
- return max_packets_per_fec_group_;
- }
-
- // Sets creator's max number of packets covered by an FEC group.
- // Note: While there are no constraints on |max_packets_per_fec_group|,
- // this setter enforces a min value of kLowestMaxPacketsPerFecGroup.
- // To turn off FEC protection, use StopFecProtectingPackets().
- void set_max_packets_per_fec_group(size_t max_packets_per_fec_group);
-
- FecSendPolicy fec_send_policy() { return fec_send_policy_; }
-
- void set_fec_send_policy(FecSendPolicy fec_send_policy) {
- fec_send_policy_ = fec_send_policy;
- }
-
- void set_rtt_multiplier_for_fec_timeout(
- float rtt_multiplier_for_fec_timeout) {
- rtt_multiplier_for_fec_timeout_ = rtt_multiplier_for_fec_timeout;
- }
-
void set_debug_delegate(DebugDelegate* debug_delegate) {
debug_delegate_ = debug_delegate;
}
@@ -295,18 +234,10 @@ class NET_EXPORT_PRIVATE QuicPacketCreator {
size_t length,
char* buffer);
- // Updates lengths and also starts an FEC group if FEC protection is on and
- // there is not already an FEC group open.
- InFecGroup MaybeUpdateLengthsAndStartFec();
+ // Updates packet number length on packet boundary.
+ void MaybeUpdatePacketNumberLength();
- // Called when a data packet is constructed that is part of an FEC group.
- // |payload| is the non-encrypted FEC protected payload of the packet.
- void OnBuiltFecProtectedPayload(const QuicPacketHeader& header,
- base::StringPiece payload);
-
- void FillPacketHeader(QuicFecGroupNumber fec_group,
- bool fec_flag,
- QuicPacketHeader* header);
+ void FillPacketHeader(QuicPacketHeader* header);
// Adds a |frame| if there is space and returns false and flushes all pending
// frames if there isn't room. If |save_retransmittable_frames| is true,
@@ -326,36 +257,12 @@ class NET_EXPORT_PRIVATE QuicPacketCreator {
void SerializePacket(char* encrypted_buffer, size_t buffer_len);
// Called after a new SerialiedPacket is created to call the delegate's
- // OnSerializedPacket, reset state, and potentially flush FEC groups.
+ // OnSerializedPacket and reset state.
void OnSerializedPacket();
// Clears all fields of packet_ that should be cleared between serializations.
void ClearPacket();
- // Turn on FEC protection for subsequent packets. If no FEC group is currently
- // open, this method flushes current open packet and then turns FEC on.
- void MaybeStartFecProtection();
-
- // Turn on FEC protection for subsequently created packets. FEC should be
- // enabled first (max_packets_per_fec_group should be non-zero) for FEC
- // protection to start.
- void StartFecProtectingPackets();
-
- // Turn off FEC protection for subsequently created packets. If the creator
- // has any open FEC group, call will fail. It is the caller's responsibility
- // to flush out FEC packets in generation, and to verify with ShouldSendFec()
- // that there is no open FEC group.
- void StopFecProtectingPackets();
-
- // Resets (closes) the FEC group. This method should only be called on a
- // packet boundary.
- void ResetFecGroup();
-
- // Packetize FEC data. Sets the entropy hash of the serialized packet to a
- // random bool.
- // Fails if |buffer_len| isn't long enough for the encrypted packet.
- void SerializeFec(char* buffer, size_t buffer_len);
-
// Does not own these delegates or the framer.
DelegateInterface* delegate_;
DebugDelegate* debug_delegate_;
@@ -370,8 +277,8 @@ class NET_EXPORT_PRIVATE QuicPacketCreator {
bool send_path_id_in_packet_;
// Staging variable to hold next packet number length. When sequence
// number length is to be changed, this variable holds the new length until
- // a packet or FEC group boundary, when the creator's packet_number_length_
- // can be changed to this new value.
+ // a packet boundary, when the creator's packet_number_length_ can be changed
+ // to this new value.
QuicPacketNumberLength next_packet_number_length_;
// Maximum length including headers and encryption (UDP payload length.)
QuicByteCount max_packet_length_;
@@ -394,28 +301,6 @@ class NET_EXPORT_PRIVATE QuicPacketCreator {
// Map mapping path_id to last sent packet number on the path.
std::unordered_map<QuicPathId, QuicPacketNumber> multipath_packet_number_;
- // FEC related fields.
- // True when creator is requested to turn on FEC protection. False otherwise.
- // There is a time difference between should_fec_protect_next_packet_ is
- // true/false and FEC is actually turned on/off (e.g., The creator may have an
- // open FEC group even if this variable is false).
- bool should_fec_protect_next_packet_;
- // If true, any created packets will be FEC protected.
- // TODO(fayang): Combine should_fec_protect_next_packet and fec_protect_ to
- // one variable.
- bool fec_protect_;
- scoped_ptr<QuicFecGroup> fec_group_;
- // 0 indicates FEC is disabled.
- size_t max_packets_per_fec_group_;
- // FEC policy that specifies when to send FEC packet.
- FecSendPolicy fec_send_policy_;
- // Timeout used for FEC alarm. Can be set to zero initially or if the SRTT has
- // not yet been set.
- QuicTime::Delta fec_timeout_;
- // The multiplication factor for FEC timeout based on RTT.
- // TODO(rtenneti): Delete this code after the 0.25 RTT FEC experiment.
- float rtt_multiplier_for_fec_timeout_;
-
DISALLOW_COPY_AND_ASSIGN(QuicPacketCreator);
};
diff --git a/net/quic/quic_packet_creator_test.cc b/net/quic/quic_packet_creator_test.cc
index b5dddcf..98e1ef2 100644
--- a/net/quic/quic_packet_creator_test.cc
+++ b/net/quic/quic_packet_creator_test.cc
@@ -82,7 +82,6 @@ class MockDelegate : public QuicPacketCreator::DelegateInterface {
~MockDelegate() override {}
MOCK_METHOD1(OnSerializedPacket, void(SerializedPacket* packet));
- MOCK_METHOD0(OnResetFecGroup, void());
MOCK_METHOD2(OnUnrecoverableError,
void(QuicErrorCode, ConnectionCloseSource source));
@@ -142,7 +141,6 @@ class QuicPacketCreatorTest : public ::testing::TestWithParam<TestParams> {
server_framer_.set_visitor(&framer_visitor_);
// TODO(ianswett): Fix this test so it uses a non-null encrypter.
FLAGS_quic_never_write_unencrypted_data = false;
- FLAGS_quic_no_unencrypted_fec = false;
}
~QuicPacketCreatorTest() override {
@@ -180,11 +178,10 @@ class QuicPacketCreatorTest : public ::testing::TestWithParam<TestParams> {
// Returns the number of bytes consumed by the header of packet, including
// the version.
- size_t GetPacketHeaderOverhead(InFecGroup is_in_fec_group) {
+ size_t GetPacketHeaderOverhead() {
return GetPacketHeaderSize(
creator_.connection_id_length(), kIncludeVersion, !kIncludePathId,
- QuicPacketCreatorPeer::NextPacketNumberLength(&creator_),
- is_in_fec_group);
+ QuicPacketCreatorPeer::NextPacketNumberLength(&creator_));
}
// Returns the number of bytes of overhead that will be added to a packet
@@ -196,9 +193,9 @@ class QuicPacketCreatorTest : public ::testing::TestWithParam<TestParams> {
// Returns the number of bytes consumed by the non-data fields of a stream
// frame, assuming it is the last frame in the packet
- size_t GetStreamFrameOverhead(InFecGroup is_in_fec_group) {
+ size_t GetStreamFrameOverhead() {
return QuicFramer::GetMinStreamFrameSize(kClientDataStreamId1, kOffset,
- true, is_in_fec_group);
+ true);
}
QuicIOVector MakeIOVector(StringPiece s) {
@@ -274,62 +271,6 @@ TEST_P(QuicPacketCreatorTest, SerializeFrames) {
}
}
-TEST_P(QuicPacketCreatorTest, SerializeWithFEC) {
- // Send FEC packet every 6 packets.
- creator_.set_max_packets_per_fec_group(6);
- // Should return false since we do not have enough packets in the FEC group to
- // trigger an FEC packet.
- ASSERT_FALSE(creator_.ShouldSendFec(/*force_close=*/false));
- // Turn on FEC protection.
- QuicFrame frame;
- QuicIOVector io_vector(MakeIOVector("test"));
- ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame,
- MUST_FEC_PROTECT));
- EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(&creator_));
- // Serialize the packet.
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
- creator_.Flush();
-
- {
- InSequence s;
- EXPECT_CALL(framer_visitor_, OnPacket());
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
- EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_));
- EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
- EXPECT_CALL(framer_visitor_, OnFecProtectedPayload(_));
- EXPECT_CALL(framer_visitor_, OnStreamFrame(_));
- EXPECT_CALL(framer_visitor_, OnPacketComplete());
- }
- ProcessPacket(serialized_packet_);
- DeleteSerializedPacket();
-
- // Should return false since we do not have enough packets in the FEC group to
- // trigger an FEC packet.
- ASSERT_FALSE(creator_.ShouldSendFec(/*force_close=*/false));
- // Should return true since there are packets in the FEC group.
- ASSERT_TRUE(creator_.ShouldSendFec(/*force_close=*/true));
-
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
- creator_.MaybeSendFecPacketAndCloseGroup(/*force_send_fec=*/true,
- /*is_fec_timeout=*/false);
- ASSERT_EQ(2u, serialized_packet_.packet_number);
- {
- InSequence s;
- EXPECT_CALL(framer_visitor_, OnPacket());
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
- EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_));
- EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
- EXPECT_CALL(framer_visitor_, OnFecData(_));
- EXPECT_CALL(framer_visitor_, OnPacketComplete());
- }
- ProcessPacket(serialized_packet_);
- DeleteSerializedPacket();
-}
-
TEST_P(QuicPacketCreatorTest, SerializeChangingSequenceNumberLength) {
frames_.push_back(QuicFrame(new QuicAckFrame(MakeAckFrame(0u))));
creator_.AddSavedFrame(frames_[0]);
@@ -460,109 +401,6 @@ TEST_P(QuicPacketCreatorTest, ChangeSequenceNumberLengthMidPacket) {
delete ack_frame.ack_frame;
}
-TEST_P(QuicPacketCreatorTest, SerializeWithFECChangingSequenceNumberLength) {
- // Test goal is to test the following sequence (P1 => generate Packet 1):
- // P1 <change seq num length> P2 FEC,
- // and we expect that packet number length should not change until the end
- // of the open FEC group.
-
- // Send FEC packet every 6 packets.
- creator_.set_max_packets_per_fec_group(6);
- // Should return false since we do not have enough packets in the FEC group to
- // trigger an FEC packet.
- ASSERT_FALSE(creator_.ShouldSendFec(/*force_close=*/false));
-
- // Generate Packet 1.
- QuicFrame frame;
- QuicIOVector io_vector(MakeIOVector("test"));
- ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame,
- MUST_FEC_PROTECT));
- // Change the packet number length mid-FEC group and it should not change.
- QuicPacketCreatorPeer::SetNextPacketNumberLength(&creator_,
- PACKET_4BYTE_PACKET_NUMBER);
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillRepeatedly(
- Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
- creator_.Flush();
- EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
- serialized_packet_.packet_number_length);
-
- {
- InSequence s;
- EXPECT_CALL(framer_visitor_, OnPacket());
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
- EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_));
- EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
- EXPECT_CALL(framer_visitor_, OnFecProtectedPayload(_));
- EXPECT_CALL(framer_visitor_, OnStreamFrame(_));
- EXPECT_CALL(framer_visitor_, OnPacketComplete());
- }
- ProcessPacket(serialized_packet_);
- DeleteSerializedPacket();
-
- // Generate Packet 2.
- ASSERT_TRUE(creator_.ConsumeData(2u, io_vector, 0u, 0u, false, false, &frame,
- MUST_FEC_PROTECT));
- creator_.Flush();
- EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
- serialized_packet_.packet_number_length);
-
- {
- InSequence s;
- EXPECT_CALL(framer_visitor_, OnPacket());
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
- EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_));
- EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
- EXPECT_CALL(framer_visitor_, OnFecProtectedPayload(_));
- EXPECT_CALL(framer_visitor_, OnStreamFrame(_));
- EXPECT_CALL(framer_visitor_, OnPacketComplete());
- }
- ProcessPacket(serialized_packet_);
- DeleteSerializedPacket();
-
- // Should return false since we do not have enough packets in the FEC group to
- // trigger an FEC packet.
- ASSERT_FALSE(creator_.ShouldSendFec(/*force_close=*/false));
- // Should return true since there are packets in the FEC group.
- ASSERT_TRUE(creator_.ShouldSendFec(/*force_close=*/true));
-
- // Force generation of FEC packet.
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
- // Turn off FEC protection.
- creator_.MaybeSendFecPacketAndCloseGroup(/*force_send_fec=*/true,
- /*is_fec_timeout=*/false);
- EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
- serialized_packet_.packet_number_length);
- ASSERT_EQ(3u, serialized_packet_.packet_number);
-
- {
- InSequence s;
- EXPECT_CALL(framer_visitor_, OnPacket());
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
- EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_));
- EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
- EXPECT_CALL(framer_visitor_, OnFecData(_));
- EXPECT_CALL(framer_visitor_, OnPacketComplete());
- }
- ProcessPacket(serialized_packet_);
- DeleteSerializedPacket();
-
- // Ensure the next FEC group starts using the new packet number length.
- ASSERT_TRUE(creator_.ConsumeData(3u, io_vector, 0u, 0u, false, false, &frame,
- MUST_FEC_PROTECT));
- EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(&creator_));
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
- creator_.Flush();
- EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER,
- serialized_packet_.packet_number_length);
- DeleteSerializedPacket();
-}
-
TEST_P(QuicPacketCreatorTest, ReserializeFramesWithSequenceNumberLength) {
// If the original packet number length, the current packet number
// length, and the configured send packet number length are different, the
@@ -659,9 +497,8 @@ TEST_P(QuicPacketCreatorTest, ReserializeFramesWithPadding) {
}
TEST_P(QuicPacketCreatorTest, ReserializeFramesWithFullPacketAndPadding) {
- const size_t overhead = GetPacketHeaderOverhead(NOT_IN_FEC_GROUP) +
- GetEncryptionOverhead() +
- GetStreamFrameOverhead(NOT_IN_FEC_GROUP);
+ const size_t overhead = GetPacketHeaderOverhead() + GetEncryptionOverhead() +
+ GetStreamFrameOverhead();
size_t capacity = kDefaultMaxPacketSize - overhead;
for (int delta = -5; delta <= 0; ++delta) {
string data(capacity + delta, 'A');
@@ -722,75 +559,11 @@ TEST_P(QuicPacketCreatorTest, SerializeConnectionClose) {
ProcessPacket(serialized);
}
-TEST_P(QuicPacketCreatorTest, SwitchFecOnOffWithGroupInProgress) {
- // Send FEC packet every 6 packets.
- creator_.set_max_packets_per_fec_group(6);
- // Turn on FEC protection.
- QuicFrame frame;
- QuicIOVector io_vector(MakeIOVector("test"));
- ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame,
- MUST_FEC_PROTECT));
- EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(&creator_));
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketCreatorTest::ClearSerializedPacket));
- creator_.Flush();
- // We do not have enough packets in the FEC group to trigger an FEC packet.
- EXPECT_FALSE(creator_.ShouldSendFec(/*force_close=*/false));
- // Should return true since there are packets in the FEC group.
- EXPECT_TRUE(creator_.ShouldSendFec(/*force_close=*/true));
-
- // Switching FEC off should not change creator state, since there is an
- // FEC packet under construction.
- EXPECT_DFATAL(QuicPacketCreatorPeer::StopFecProtectingPackets(&creator_),
- "Cannot stop FEC protection with open FEC group.");
- EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(&creator_));
- // Confirm that FEC packet is still under construction.
- EXPECT_TRUE(creator_.ShouldSendFec(/*force_close=*/true));
-
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketCreatorTest::ClearSerializedPacket));
- // Turn off FEC protection.
- creator_.MaybeSendFecPacketAndCloseGroup(/*force_send_fec=*/true,
- /*is_fec_timeout=*/false);
- EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(&creator_));
-}
-
-TEST_P(QuicPacketCreatorTest, SwitchFecOnWithStreamFrameQueued) {
- // Add a stream frame to the creator.
- QuicFrame frame;
- QuicIOVector io_vector(MakeIOVector("test"));
- ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame,
- MAY_FEC_PROTECT));
- EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(&creator_));
- ASSERT_TRUE(frame.stream_frame);
- size_t consumed = frame.stream_frame->frame_length;
- EXPECT_EQ(4u, consumed);
- EXPECT_TRUE(creator_.HasPendingFrames());
-
- // Enable FEC protection, and send FEC packet every 6 packets.
- creator_.set_max_packets_per_fec_group(6);
- EXPECT_TRUE(QuicPacketCreatorPeer::IsFecEnabled(&creator_));
- EXPECT_DFATAL(QuicPacketCreatorPeer::StartFecProtectingPackets(&creator_),
- "Cannot start FEC protection with pending frames.");
- EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(&creator_));
-
- // Start FEC protection after current open packet is flushed.
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketCreatorTest::ClearSerializedPacket));
- ASSERT_TRUE(creator_.ConsumeData(2u, io_vector, 0u, 0u, false, false, &frame,
- MUST_FEC_PROTECT));
- ASSERT_TRUE(frame.stream_frame);
- consumed = frame.stream_frame->frame_length;
- EXPECT_EQ(4u, consumed);
- EXPECT_TRUE(creator_.HasPendingFrames());
- EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(&creator_));
-}
-
TEST_P(QuicPacketCreatorTest, ConsumeData) {
QuicFrame frame;
QuicIOVector io_vector(MakeIOVector("test"));
- ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame,
- MAY_FEC_PROTECT));
+ ASSERT_TRUE(
+ creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame));
ASSERT_TRUE(frame.stream_frame);
size_t consumed = frame.stream_frame->frame_length;
EXPECT_EQ(4u, consumed);
@@ -801,8 +574,8 @@ TEST_P(QuicPacketCreatorTest, ConsumeData) {
TEST_P(QuicPacketCreatorTest, ConsumeDataFin) {
QuicFrame frame;
QuicIOVector io_vector(MakeIOVector("test"));
- ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 10u, true, false, &frame,
- MAY_FEC_PROTECT));
+ ASSERT_TRUE(
+ creator_.ConsumeData(1u, io_vector, 0u, 10u, true, false, &frame));
ASSERT_TRUE(frame.stream_frame);
size_t consumed = frame.stream_frame->frame_length;
EXPECT_EQ(4u, consumed);
@@ -813,8 +586,7 @@ TEST_P(QuicPacketCreatorTest, ConsumeDataFin) {
TEST_P(QuicPacketCreatorTest, ConsumeDataFinOnly) {
QuicFrame frame;
QuicIOVector io_vector(nullptr, 0, 0);
- ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 0u, true, false, &frame,
- MAY_FEC_PROTECT));
+ ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 0u, true, false, &frame));
ASSERT_TRUE(frame.stream_frame);
size_t consumed = frame.stream_frame->frame_length;
EXPECT_EQ(0u, consumed);
@@ -822,28 +594,11 @@ TEST_P(QuicPacketCreatorTest, ConsumeDataFinOnly) {
EXPECT_TRUE(creator_.HasPendingFrames());
}
-TEST_P(QuicPacketCreatorTest, ConsumeDataWithFecProtect) {
- creator_.set_max_packets_per_fec_group(6);
- QuicFrame frame;
- QuicIOVector io_vector(MakeIOVector("test"));
- EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(&creator_));
- ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame,
- MUST_FEC_PROTECT));
- ASSERT_TRUE(frame.stream_frame);
- size_t consumed = frame.stream_frame->frame_length;
- EXPECT_EQ(4u, consumed);
- CheckStreamFrame(frame, 1u, "test", 0u, false);
- EXPECT_TRUE(creator_.HasPendingFrames());
- EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(&creator_));
-}
-
TEST_P(QuicPacketCreatorTest, CreateAllFreeBytesForStreamFrames) {
- const size_t overhead =
- GetPacketHeaderOverhead(NOT_IN_FEC_GROUP) + GetEncryptionOverhead();
+ const size_t overhead = GetPacketHeaderOverhead() + GetEncryptionOverhead();
for (size_t i = overhead; i < overhead + 100; ++i) {
creator_.SetMaxPacketLength(i);
- const bool should_have_room =
- i > overhead + GetStreamFrameOverhead(NOT_IN_FEC_GROUP);
+ const bool should_have_room = i > overhead + GetStreamFrameOverhead();
ASSERT_EQ(should_have_room,
creator_.HasRoomForStreamFrame(kClientDataStreamId1, kOffset));
if (should_have_room) {
@@ -853,8 +608,7 @@ TEST_P(QuicPacketCreatorTest, CreateAllFreeBytesForStreamFrames) {
.WillRepeatedly(
Invoke(this, &QuicPacketCreatorTest::ClearSerializedPacket));
ASSERT_TRUE(creator_.ConsumeData(kClientDataStreamId1, io_vector, 0u,
- kOffset, false, false, &frame,
- MAY_FEC_PROTECT));
+ kOffset, false, false, &frame));
ASSERT_TRUE(frame.stream_frame);
size_t bytes_consumed = frame.stream_frame->frame_length;
EXPECT_LT(0u, bytes_consumed);
@@ -865,9 +619,8 @@ TEST_P(QuicPacketCreatorTest, CreateAllFreeBytesForStreamFrames) {
TEST_P(QuicPacketCreatorTest, StreamFrameConsumption) {
// Compute the total overhead for a single frame in packet.
- const size_t overhead = GetPacketHeaderOverhead(NOT_IN_FEC_GROUP) +
- GetEncryptionOverhead() +
- GetStreamFrameOverhead(NOT_IN_FEC_GROUP);
+ const size_t overhead = GetPacketHeaderOverhead() + GetEncryptionOverhead() +
+ GetStreamFrameOverhead();
size_t capacity = kDefaultMaxPacketSize - overhead;
// Now, test various sizes around this size.
for (int delta = -5; delta <= 5; ++delta) {
@@ -876,8 +629,7 @@ TEST_P(QuicPacketCreatorTest, StreamFrameConsumption) {
QuicFrame frame;
QuicIOVector io_vector(MakeIOVector(data));
ASSERT_TRUE(creator_.ConsumeData(kClientDataStreamId1, io_vector, 0u,
- kOffset, false, false, &frame,
- MAY_FEC_PROTECT));
+ kOffset, false, false, &frame));
ASSERT_TRUE(frame.stream_frame);
// BytesFree() returns bytes available for the next frame, which will
@@ -893,63 +645,10 @@ TEST_P(QuicPacketCreatorTest, StreamFrameConsumption) {
}
}
-TEST_P(QuicPacketCreatorTest, StreamFrameConsumptionWithFec) {
- // Send FEC packet every 6 packets.
- creator_.set_max_packets_per_fec_group(6);
- // Turn on FEC protection.
- QuicFrame frame;
- QuicIOVector io_vector(MakeIOVector("test"));
- ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame,
- MUST_FEC_PROTECT));
- EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(&creator_));
-
- // Serialize the packet.
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketCreatorTest::ClearSerializedPacket));
- creator_.Flush();
- // Compute the total overhead for a single frame in packet.
- const size_t overhead = GetPacketHeaderOverhead(IN_FEC_GROUP) +
- GetEncryptionOverhead() +
- GetStreamFrameOverhead(IN_FEC_GROUP);
- size_t capacity = kDefaultMaxPacketSize - overhead;
- // Now, test various sizes around this size.
- for (int delta = -5; delta <= 5; ++delta) {
- string data(capacity + delta, 'A');
- size_t bytes_free = delta > 0 ? 0 : 0 - delta;
- QuicFrame frame;
- QuicIOVector io_vector(MakeIOVector(data));
- ASSERT_TRUE(creator_.ConsumeData(kClientDataStreamId1, io_vector, 0u,
- kOffset, false, false, &frame,
- MUST_FEC_PROTECT));
- ASSERT_TRUE(frame.stream_frame);
- // BytesFree() returns bytes available for the next frame. Since stream
- // frame does not grow for FEC protected packets, this should be the same
- // as bytes_free (bound by 0).
- EXPECT_EQ(0u, creator_.ExpansionOnNewFrame());
- size_t expected_bytes_free = bytes_free > 0 ? bytes_free : 0;
- EXPECT_EQ(expected_bytes_free, creator_.BytesFree()) << "delta: " << delta;
- {
- InSequence s;
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
- // Every 6th packet will generate an extra FEC packet.
- if (delta == -1 || delta == 5) {
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(
- Invoke(this, &QuicPacketCreatorTest::ClearSerializedPacket));
- }
- }
- creator_.Flush();
- ASSERT_TRUE(serialized_packet_.encrypted_buffer);
- DeleteSerializedPacket();
- }
-}
-
TEST_P(QuicPacketCreatorTest, CryptoStreamFramePacketPadding) {
// Compute the total overhead for a single frame in packet.
- const size_t overhead = GetPacketHeaderOverhead(NOT_IN_FEC_GROUP) +
- GetEncryptionOverhead() +
- GetStreamFrameOverhead(NOT_IN_FEC_GROUP);
+ const size_t overhead = GetPacketHeaderOverhead() + GetEncryptionOverhead() +
+ GetStreamFrameOverhead();
ASSERT_GT(kMaxPacketSize, overhead);
size_t capacity = kDefaultMaxPacketSize - overhead;
// Now, test various sizes around this size.
@@ -963,7 +662,7 @@ TEST_P(QuicPacketCreatorTest, CryptoStreamFramePacketPadding) {
.WillRepeatedly(
Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
ASSERT_TRUE(creator_.ConsumeData(kCryptoStreamId, io_vector, 0u, kOffset,
- false, true, &frame, MAY_FEC_PROTECT));
+ false, true, &frame));
ASSERT_TRUE(frame.stream_frame);
size_t bytes_consumed = frame.stream_frame->frame_length;
EXPECT_LT(0u, bytes_consumed);
@@ -984,9 +683,8 @@ TEST_P(QuicPacketCreatorTest, CryptoStreamFramePacketPadding) {
TEST_P(QuicPacketCreatorTest, NonCryptoStreamFramePacketNonPadding) {
// Compute the total overhead for a single frame in packet.
- const size_t overhead = GetPacketHeaderOverhead(NOT_IN_FEC_GROUP) +
- GetEncryptionOverhead() +
- GetStreamFrameOverhead(NOT_IN_FEC_GROUP);
+ const size_t overhead = GetPacketHeaderOverhead() + GetEncryptionOverhead() +
+ GetStreamFrameOverhead();
ASSERT_GT(kDefaultMaxPacketSize, overhead);
size_t capacity = kDefaultMaxPacketSize - overhead;
// Now, test various sizes around this size.
@@ -999,8 +697,7 @@ TEST_P(QuicPacketCreatorTest, NonCryptoStreamFramePacketNonPadding) {
EXPECT_CALL(delegate_, OnSerializedPacket(_))
.WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
ASSERT_TRUE(creator_.ConsumeData(kClientDataStreamId1, io_vector, 0u,
- kOffset, false, false, &frame,
- MAY_FEC_PROTECT));
+ kOffset, false, false, &frame));
ASSERT_TRUE(frame.stream_frame);
size_t bytes_consumed = frame.stream_frame->frame_length;
EXPECT_LT(0u, bytes_consumed);
@@ -1037,29 +734,23 @@ TEST_P(QuicPacketCreatorTest, UpdatePacketSequenceNumberLengthLeastAwaiting) {
EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
QuicPacketCreatorPeer::NextPacketNumberLength(&creator_));
- size_t max_packets_per_fec_group = 10;
- creator_.set_max_packets_per_fec_group(max_packets_per_fec_group);
- QuicPacketCreatorPeer::SetPacketNumber(&creator_,
- 64 - max_packets_per_fec_group);
+ QuicPacketCreatorPeer::SetPacketNumber(&creator_, 64);
creator_.UpdatePacketNumberLength(2, 10000 / kDefaultMaxPacketSize);
EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
QuicPacketCreatorPeer::NextPacketNumberLength(&creator_));
- QuicPacketCreatorPeer::SetPacketNumber(&creator_,
- 64 * 256 - max_packets_per_fec_group);
+ QuicPacketCreatorPeer::SetPacketNumber(&creator_, 64 * 256);
creator_.UpdatePacketNumberLength(2, 10000 / kDefaultMaxPacketSize);
EXPECT_EQ(PACKET_2BYTE_PACKET_NUMBER,
QuicPacketCreatorPeer::NextPacketNumberLength(&creator_));
- QuicPacketCreatorPeer::SetPacketNumber(
- &creator_, 64 * 256 * 256 - max_packets_per_fec_group);
+ QuicPacketCreatorPeer::SetPacketNumber(&creator_, 64 * 256 * 256);
creator_.UpdatePacketNumberLength(2, 10000 / kDefaultMaxPacketSize);
EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER,
QuicPacketCreatorPeer::NextPacketNumberLength(&creator_));
- QuicPacketCreatorPeer::SetPacketNumber(
- &creator_,
- UINT64_C(64) * 256 * 256 * 256 * 256 - max_packets_per_fec_group);
+ QuicPacketCreatorPeer::SetPacketNumber(&creator_,
+ UINT64_C(64) * 256 * 256 * 256 * 256);
creator_.UpdatePacketNumberLength(2, 10000 / kDefaultMaxPacketSize);
EXPECT_EQ(PACKET_6BYTE_PACKET_NUMBER,
QuicPacketCreatorPeer::NextPacketNumberLength(&creator_));
@@ -1125,14 +816,13 @@ TEST_P(QuicPacketCreatorTest, ConsumeDataLargerThanOneStreamFrame) {
QuicPacketCreatorPeer::SendVersionInPacket(&creator_),
QuicPacketCreatorPeer::SendPathIdInPacket(&creator_),
creator_.connection_id_length(), PACKET_1BYTE_PACKET_NUMBER,
- NOT_IN_FEC_GROUP, &payload_length));
+ &payload_length));
QuicFrame frame;
const string too_long_payload(payload_length * 2, 'a');
QuicIOVector io_vector(MakeIOVector(too_long_payload));
EXPECT_CALL(delegate_, OnSerializedPacket(_))
.WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
- ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 0u, true, false, &frame,
- MAY_FEC_PROTECT));
+ ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 0u, true, false, &frame));
ASSERT_TRUE(frame.stream_frame);
size_t consumed = frame.stream_frame->frame_length;
EXPECT_EQ(payload_length, consumed);
@@ -1154,7 +844,7 @@ TEST_P(QuicPacketCreatorTest, AddFrameAndFlush) {
creator_.connection_id_length(),
QuicPacketCreatorPeer::SendVersionInPacket(&creator_),
QuicPacketCreatorPeer::SendPathIdInPacket(&creator_),
- PACKET_1BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP),
+ PACKET_1BYTE_PACKET_NUMBER),
creator_.BytesFree());
// Add a variety of frame types and then a padding frame.
@@ -1164,8 +854,8 @@ TEST_P(QuicPacketCreatorTest, AddFrameAndFlush) {
QuicFrame frame;
QuicIOVector io_vector(MakeIOVector("test"));
- ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame,
- MAY_FEC_PROTECT));
+ ASSERT_TRUE(
+ creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame));
ASSERT_TRUE(frame.stream_frame);
size_t consumed = frame.stream_frame->frame_length;
EXPECT_EQ(4u, consumed);
@@ -1195,8 +885,7 @@ TEST_P(QuicPacketCreatorTest, AddFrameAndFlush) {
GetPacketHeaderSize(
creator_.connection_id_length(),
QuicPacketCreatorPeer::SendVersionInPacket(&creator_),
- /*include_path_id=*/false, PACKET_1BYTE_PACKET_NUMBER,
- NOT_IN_FEC_GROUP),
+ /*include_path_id=*/false, PACKET_1BYTE_PACKET_NUMBER),
creator_.BytesFree());
}
@@ -1210,7 +899,7 @@ TEST_P(QuicPacketCreatorTest, SerializeTruncatedAckFrameWithLargePacketSize) {
// the number of nack ranges that can be fit in an ack frame.
QuicAckFrame ack_frame = MakeAckFrameWithNackRanges(2000u, 0u);
size_t frame_len = client_framer_.GetSerializedFrameLength(
- QuicFrame(&ack_frame), creator_.BytesFree(), true, true, NOT_IN_FEC_GROUP,
+ QuicFrame(&ack_frame), creator_.BytesFree(), true, true,
PACKET_1BYTE_PACKET_NUMBER);
EXPECT_GT(creator_.BytesFree(), frame_len);
EXPECT_GT(creator_.max_packet_length(), creator_.PacketSize());
@@ -1224,8 +913,8 @@ TEST_P(QuicPacketCreatorTest, SerializeTruncatedAckFrameWithLargePacketSize) {
// Make sure that an additional stream frame can be added to the packet.
QuicFrame frame;
QuicIOVector io_vector(MakeIOVector("test"));
- ASSERT_TRUE(creator_.ConsumeData(2u, io_vector, 0u, 0u, false, false, &frame,
- MAY_FEC_PROTECT));
+ ASSERT_TRUE(
+ creator_.ConsumeData(2u, io_vector, 0u, 0u, false, false, &frame));
ASSERT_TRUE(frame.stream_frame);
size_t consumed = frame.stream_frame->frame_length;
EXPECT_EQ(4u, consumed);
@@ -1258,7 +947,7 @@ TEST_P(QuicPacketCreatorTest, SerializeTruncatedAckFrameWithSmallPacketSize) {
// the packet size.
QuicAckFrame ack_frame = MakeAckFrameWithNackRanges(2000u, 0u);
size_t frame_len = client_framer_.GetSerializedFrameLength(
- QuicFrame(&ack_frame), creator_.BytesFree(), true, true, NOT_IN_FEC_GROUP,
+ QuicFrame(&ack_frame), creator_.BytesFree(), true, true,
PACKET_1BYTE_PACKET_NUMBER);
EXPECT_EQ(creator_.BytesFree(), frame_len);
@@ -1305,103 +994,6 @@ TEST_P(QuicPacketCreatorTest, EntropyFlag) {
delete frames_[0].stream_frame;
}
-TEST_P(QuicPacketCreatorTest, ResetFecGroup) {
- // Send FEC packet every 6 packets.
- creator_.set_max_packets_per_fec_group(6);
- // Add a stream frame and turn on FEC protection.
- QuicFrame frame;
- QuicIOVector io_vector(MakeIOVector("test"));
- ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame,
- MUST_FEC_PROTECT));
- // Serialize the packet.
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketCreatorTest::ClearSerializedPacket));
- creator_.Flush();
-
- EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(&creator_));
- EXPECT_TRUE(creator_.IsFecGroupOpen());
- // We do not have enough packets in the FEC group to trigger an FEC packet.
- EXPECT_FALSE(creator_.ShouldSendFec(/*force_close=*/false));
- // Should return true since there are packets in the FEC group.
- EXPECT_TRUE(creator_.ShouldSendFec(/*force_close=*/true));
-
- // FEC group will be reset if FEC police is alarm trigger but FEC alarm does
- // not fire.
- EXPECT_CALL(delegate_, OnResetFecGroup()).Times(1);
- creator_.set_fec_send_policy(FEC_ALARM_TRIGGER);
- creator_.MaybeSendFecPacketAndCloseGroup(/*force_send_fec=*/true,
- /*is_fec_timeout=*/false);
- EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(&creator_));
- EXPECT_FALSE(creator_.IsFecGroupOpen());
- // We do not have enough packets in the FEC group to trigger an FEC packet.
- EXPECT_FALSE(creator_.ShouldSendFec(/*force_close=*/false));
- // Confirm that there is no FEC packet under construction.
- EXPECT_FALSE(creator_.ShouldSendFec(/*force_close=*/true));
-
- char buffer[kMaxPacketSize];
- EXPECT_DFATAL(
- QuicPacketCreatorPeer::SerializeFec(&creator_, buffer, kMaxPacketSize),
- "SerializeFEC called but no group or zero packets in group.");
-
- // Create and send a new FEC protected packet.
- ASSERT_TRUE(creator_.ConsumeData(2u, io_vector, 0u, 0u, false, false, &frame,
- MUST_FEC_PROTECT));
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketCreatorTest::ClearSerializedPacket));
- creator_.Flush();
-
- EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(&creator_));
- EXPECT_TRUE(creator_.IsFecGroupOpen());
- // We do not have enough packets in the FEC group to trigger an FEC packet.
- EXPECT_FALSE(creator_.ShouldSendFec(/*force_close=*/false));
- // Should return true since there are packets in the FEC group.
- EXPECT_TRUE(creator_.ShouldSendFec(/*force_close=*/true));
-
- // Should return false since we do not have enough packets in the FEC group to
- // trigger an FEC packet.
- ASSERT_FALSE(creator_.ShouldSendFec(/*force_close=*/false));
- // Should return true since there are packets in the FEC group.
- ASSERT_TRUE(creator_.ShouldSendFec(/*force_close=*/true));
-
- // Change FEC policy, send FEC packet and close FEC group.
- creator_.set_fec_send_policy(FEC_ANY_TRIGGER);
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
- creator_.MaybeSendFecPacketAndCloseGroup(/*force_send_fec=*/true,
- /*is_fec_timeout=*/false);
- ASSERT_EQ(3u, serialized_packet_.packet_number);
- DeleteSerializedPacket();
-}
-
-TEST_P(QuicPacketCreatorTest, ResetFecGroupWithQueuedFrames) {
- // Send FEC packet every 6 packets.
- creator_.set_max_packets_per_fec_group(6);
- // Add a stream frame to the creator and turn on FEC protection.
- QuicFrame frame;
- QuicIOVector io_vector(MakeIOVector("test"));
- ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame,
- MUST_FEC_PROTECT));
- ASSERT_TRUE(frame.stream_frame);
- size_t consumed = frame.stream_frame->frame_length;
- EXPECT_EQ(4u, consumed);
- EXPECT_TRUE(creator_.HasPendingFrames());
- EXPECT_DFATAL(QuicPacketCreatorPeer::ResetFecGroup(&creator_),
- "Cannot reset FEC group with pending frames.");
-
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketCreatorTest::ClearSerializedPacket));
- creator_.Flush();
- EXPECT_FALSE(creator_.HasPendingFrames());
-
- // FEC group will be reset if FEC police is alarm trigger but FEC alarm does
- // not fire.
- EXPECT_CALL(delegate_, OnResetFecGroup()).Times(1);
- creator_.set_fec_send_policy(FEC_ALARM_TRIGGER);
- creator_.MaybeSendFecPacketAndCloseGroup(/*force_send_fec=*/true,
- /*is_fec_timeout=*/false);
- EXPECT_FALSE(creator_.IsFecGroupOpen());
-}
-
TEST_P(QuicPacketCreatorTest, SetCurrentPath) {
// Current path is the default path.
EXPECT_EQ(kDefaultPathId, QuicPacketCreatorPeer::GetCurrentPath(&creator_));
@@ -1411,8 +1003,8 @@ TEST_P(QuicPacketCreatorTest, SetCurrentPath) {
// Add a stream frame to the creator.
QuicFrame frame;
QuicIOVector io_vector(MakeIOVector("test"));
- ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame,
- MAY_FEC_PROTECT));
+ ASSERT_TRUE(
+ creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame));
ASSERT_TRUE(frame.stream_frame);
size_t consumed = frame.stream_frame->frame_length;
EXPECT_EQ(4u, consumed);
@@ -1443,8 +1035,8 @@ TEST_P(QuicPacketCreatorTest, SetCurrentPath) {
EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
QuicPacketCreatorPeer::NextPacketNumberLength(&creator_));
// Add a stream frame to the creator.
- ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame,
- MAY_FEC_PROTECT));
+ ASSERT_TRUE(
+ creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame));
ASSERT_TRUE(frame.stream_frame);
consumed = frame.stream_frame->frame_length;
EXPECT_EQ(4u, consumed);
@@ -1459,95 +1051,24 @@ TEST_P(QuicPacketCreatorTest, SetCurrentPath) {
QuicPacketCreatorPeer::NextPacketNumberLength(&creator_));
}
-TEST_P(QuicPacketCreatorTest, SetCurrentPathWithFec) {
- // Send FEC packet every 6 packets.
- creator_.set_max_packets_per_fec_group(6);
- // Current path is the default path.
- EXPECT_EQ(kDefaultPathId, QuicPacketCreatorPeer::GetCurrentPath(&creator_));
- EXPECT_EQ(0u, creator_.packet_number());
- EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
- QuicPacketCreatorPeer::NextPacketNumberLength(&creator_));
- EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(&creator_));
- // Add a stream frame to the creator.
- QuicFrame frame;
- QuicIOVector io_vector(MakeIOVector("test"));
- ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame,
- MUST_FEC_PROTECT));
- ASSERT_TRUE(frame.stream_frame);
- size_t consumed = frame.stream_frame->frame_length;
- EXPECT_EQ(4u, consumed);
- EXPECT_TRUE(creator_.HasPendingFrames());
- EXPECT_EQ(0u, creator_.packet_number());
- EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
- QuicPacketCreatorPeer::NextPacketNumberLength(&creator_));
- EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(&creator_));
-
- // Change current path.
- QuicPathId kPathId1 = 1;
- EXPECT_DFATAL(creator_.SetCurrentPath(kPathId1, 1, 0),
- "Unable to change paths when a packet is under construction");
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .Times(2)
- .WillRepeatedly(
- Invoke(this, &QuicPacketCreatorTest::ClearSerializedPacket));
- creator_.Flush();
- EXPECT_FALSE(creator_.HasPendingFrames());
- creator_.SetCurrentPath(kPathId1, 1, 0);
- EXPECT_EQ(kPathId1, QuicPacketCreatorPeer::GetCurrentPath(&creator_));
- EXPECT_FALSE(creator_.HasPendingFrames());
- EXPECT_EQ(0u, creator_.packet_number());
- EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
- QuicPacketCreatorPeer::NextPacketNumberLength(&creator_));
- EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(&creator_));
-
- // Change current path back.
- creator_.SetCurrentPath(kDefaultPathId, 3, 2);
- EXPECT_EQ(kDefaultPathId, QuicPacketCreatorPeer::GetCurrentPath(&creator_));
- // FEC packet consumes a packet number.
- EXPECT_EQ(2u, creator_.packet_number());
- EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
- QuicPacketCreatorPeer::NextPacketNumberLength(&creator_));
- // Add a stream frame to the creator.
- ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame,
- MUST_FEC_PROTECT));
- ASSERT_TRUE(frame.stream_frame);
- consumed = frame.stream_frame->frame_length;
- EXPECT_EQ(4u, consumed);
- EXPECT_TRUE(creator_.HasPendingFrames());
-
- // Does not change current path.
- creator_.SetCurrentPath(kDefaultPathId, 3, 0);
- EXPECT_EQ(kDefaultPathId, QuicPacketCreatorPeer::GetCurrentPath(&creator_));
- EXPECT_TRUE(creator_.HasPendingFrames());
- // FEC packet consumes a packet number.
- EXPECT_EQ(2u, creator_.packet_number());
- EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
- QuicPacketCreatorPeer::NextPacketNumberLength(&creator_));
- EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(&creator_));
-}
-
TEST_P(QuicPacketCreatorTest,
- SetCurrentPathWithFecAndUpdatePacketSequenceNumberLength) {
- // Send FEC packet every 10 packets.
- size_t max_packets_per_fec_group = 10;
- creator_.set_max_packets_per_fec_group(max_packets_per_fec_group);
+ SetCurrentPathAndUpdatePacketSequenceNumberLength) {
// Current path is the default path.
EXPECT_EQ(kDefaultPathId, QuicPacketCreatorPeer::GetCurrentPath(&creator_));
EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
QuicPacketCreatorPeer::NextPacketNumberLength(&creator_));
- QuicPacketCreatorPeer::SetPacketNumber(
- &creator_, 64 * 256 - max_packets_per_fec_group - 2);
+ QuicPacketCreatorPeer::SetPacketNumber(&creator_, 64 * 256 - 2);
// Add a stream frame to the creator and send the packet.
QuicFrame frame;
QuicIOVector io_vector(MakeIOVector("test"));
- ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame,
- MUST_FEC_PROTECT));
+ ASSERT_TRUE(
+ creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame));
EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .Times(2)
+ .Times(1)
.WillRepeatedly(
Invoke(this, &QuicPacketCreatorTest::ClearSerializedPacket));
creator_.Flush();
- EXPECT_EQ(64 * 256 - max_packets_per_fec_group - 1, creator_.packet_number());
+ EXPECT_EQ(UINT64_C(64 * 256 - 1), creator_.packet_number());
creator_.UpdatePacketNumberLength(2, 10000 / kDefaultMaxPacketSize);
EXPECT_EQ(PACKET_2BYTE_PACKET_NUMBER,
QuicPacketCreatorPeer::NextPacketNumberLength(&creator_));
@@ -1561,8 +1082,7 @@ TEST_P(QuicPacketCreatorTest,
// Change current path back.
creator_.SetCurrentPath(kDefaultPathId, 2, 10000 / kDefaultMaxPacketSize);
- // FEC packet consumes a packet number.
- EXPECT_EQ(64 * 256 - max_packets_per_fec_group, creator_.packet_number());
+ EXPECT_EQ(UINT64_C(64 * 256 - 1), creator_.packet_number());
EXPECT_EQ(PACKET_2BYTE_PACKET_NUMBER,
QuicPacketCreatorPeer::NextPacketNumberLength(&creator_));
}
@@ -1574,8 +1094,8 @@ TEST_P(QuicPacketCreatorTest, SerializePacketOnDifferentPath) {
// Add a stream frame to the creator and flush the packet.
QuicFrame frame;
QuicIOVector io_vector(MakeIOVector("test"));
- ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame,
- MAY_FEC_PROTECT));
+ ASSERT_TRUE(
+ creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame));
ASSERT_TRUE(frame.stream_frame);
size_t consumed = frame.stream_frame->frame_length;
EXPECT_EQ(4u, consumed);
@@ -1601,8 +1121,8 @@ TEST_P(QuicPacketCreatorTest, SerializePacketOnDifferentPath) {
QuicPacketCreatorPeer::NextPacketNumberLength(&creator_));
// Add a stream frame to the creator and flush the packet.
- ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame,
- MAY_FEC_PROTECT));
+ ASSERT_TRUE(
+ creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame));
ASSERT_TRUE(frame.stream_frame);
consumed = frame.stream_frame->frame_length;
EXPECT_EQ(4u, consumed);
@@ -1622,56 +1142,6 @@ TEST_P(QuicPacketCreatorTest, AddUnencryptedStreamDataClosesConnection) {
"Cannot send stream data without encryption.");
}
-TEST_P(QuicPacketCreatorTest, DontSendUnencryptedFec) {
- ValueRestore<bool> old_flag(&FLAGS_quic_no_unencrypted_fec, true);
- // Send FEC packet every 6 packets.
- creator_.set_max_packets_per_fec_group(6);
- // Send stream data encrypted with FEC protection.
- creator_.set_encryption_level(ENCRYPTION_INITIAL);
- // Turn on FEC protection.
- QuicFrame frame;
- QuicIOVector io_vector(MakeIOVector("test"));
- ASSERT_TRUE(creator_.ConsumeData(kHeadersStreamId, io_vector, 0u, 0u, false,
- false, &frame, MUST_FEC_PROTECT));
- EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(&creator_));
- // Serialize the packet.
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketCreatorTest::ClearSerializedPacket));
- creator_.Flush();
-
- // The creator will clear the FEC group rather than try to send without
- // encryption.
- creator_.set_encryption_level(ENCRYPTION_NONE);
- EXPECT_CALL(delegate_, OnResetFecGroup());
- creator_.MaybeSendFecPacketAndCloseGroup(true, false);
-}
-
-TEST_P(QuicPacketCreatorTest, SerializeUnencryptedFecClosesConnection) {
- ValueRestore<bool> old_flag(&FLAGS_quic_no_unencrypted_fec, true);
- // Send FEC packet every 6 packets.
- creator_.set_max_packets_per_fec_group(6);
- // Send stream data encrypted with FEC protection.
- creator_.set_encryption_level(ENCRYPTION_INITIAL);
- // Turn on FEC protection.
- QuicFrame frame;
- QuicIOVector io_vector(MakeIOVector("test"));
- ASSERT_TRUE(creator_.ConsumeData(kHeadersStreamId, io_vector, 0u, 0u, false,
- false, &frame, MUST_FEC_PROTECT));
- EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(&creator_));
- // Serialize the packet.
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketCreatorTest::ClearSerializedPacket));
- creator_.Flush();
-
- // Try to send an FEC packet unencrypted.
- creator_.set_encryption_level(ENCRYPTION_NONE);
- EXPECT_CALL(delegate_, OnUnrecoverableError(QUIC_UNENCRYPTED_FEC_DATA, _));
- char seralized_fec_buffer[kMaxPacketSize];
- EXPECT_DFATAL(QuicPacketCreatorPeer::SerializeFec(
- &creator_, seralized_fec_buffer, kMaxPacketSize),
- "SerializeFEC must be called with encryption.");
-}
-
} // namespace
} // namespace test
} // namespace net
diff --git a/net/quic/quic_packet_generator.cc b/net/quic/quic_packet_generator.cc
index 75e1c59..908872e 100644
--- a/net/quic/quic_packet_generator.cc
+++ b/net/quic/quic_packet_generator.cc
@@ -6,7 +6,6 @@
#include "base/logging.h"
#include "net/quic/quic_bug_tracker.h"
-#include "net/quic/quic_fec_group.h"
#include "net/quic/quic_flags.h"
#include "net/quic/quic_utils.h"
@@ -27,22 +26,12 @@ QuicPacketGenerator::QuicPacketGenerator(QuicConnectionId connection_id,
delegate),
batch_mode_(false),
should_send_ack_(false),
- should_send_stop_waiting_(false),
- max_packet_length_(kDefaultMaxPacketSize) {}
+ should_send_stop_waiting_(false) {}
QuicPacketGenerator::~QuicPacketGenerator() {
QuicUtils::DeleteFrames(&queued_control_frames_);
}
-void QuicPacketGenerator::OnCongestionWindowChange(
- QuicPacketCount max_packets_in_flight) {
- packet_creator_.OnCongestionWindowChange(max_packets_in_flight);
-}
-
-void QuicPacketGenerator::OnRttChange(QuicTime::Delta rtt) {
- packet_creator_.OnRttChange(rtt);
-}
-
void QuicPacketGenerator::SetShouldSendAck(bool also_send_stop_waiting) {
if (packet_creator_.has_ack()) {
// Ack already queued, nothing to do.
@@ -56,12 +45,12 @@ void QuicPacketGenerator::SetShouldSendAck(bool also_send_stop_waiting) {
should_send_ack_ = true;
should_send_stop_waiting_ = also_send_stop_waiting;
- SendQueuedFrames(/*flush=*/false, /*is_fec_timeout=*/false);
+ SendQueuedFrames(/*flush=*/false);
}
void QuicPacketGenerator::AddControlFrame(const QuicFrame& frame) {
queued_control_frames_.push_back(frame);
- SendQueuedFrames(/*flush=*/false, /*is_fec_timeout=*/false);
+ SendQueuedFrames(/*flush=*/false);
}
QuicConsumedData QuicPacketGenerator::ConsumeData(
@@ -69,14 +58,13 @@ QuicConsumedData QuicPacketGenerator::ConsumeData(
QuicIOVector iov,
QuicStreamOffset offset,
bool fin,
- FecProtection fec_protection,
QuicAckListenerInterface* listener) {
bool has_handshake = id == kCryptoStreamId;
// To make reasoning about crypto frames easier, we don't combine them with
// other retransmittable frames in a single packet.
const bool flush =
has_handshake && packet_creator_.HasPendingRetransmittableFrames();
- SendQueuedFrames(flush, /*is_fec_timeout=*/false);
+ SendQueuedFrames(flush);
size_t total_bytes_consumed = 0;
bool fin_consumed = false;
@@ -95,7 +83,7 @@ QuicConsumedData QuicPacketGenerator::ConsumeData(
QuicFrame frame;
if (!packet_creator_.ConsumeData(id, iov, total_bytes_consumed,
offset + total_bytes_consumed, fin,
- has_handshake, &frame, fec_protection)) {
+ has_handshake, &frame)) {
// The creator is always flushed if there's not enough room for a new
// stream frame before ConsumeData, so ConsumeData should always succeed.
QUIC_BUG << "Failed to ConsumeData, stream:" << id;
@@ -113,9 +101,6 @@ QuicConsumedData QuicPacketGenerator::ConsumeData(
(bytes_consumed > 0 && packet_creator_.HasPendingFrames()));
if (!InBatchMode()) {
- // TODO(rtenneti): remove MaybeSendFecPacketAndCloseGroup() from inside
- // SerializeAndSendPacket() and make it an explicit call here (and
- // elsewhere where we call SerializeAndSendPacket?).
packet_creator_.Flush();
}
@@ -131,14 +116,9 @@ QuicConsumedData QuicPacketGenerator::ConsumeData(
// Don't allow the handshake to be bundled with other retransmittable frames.
if (has_handshake) {
- SendQueuedFrames(/*flush=*/true, /*is_fec_timeout=*/false);
+ SendQueuedFrames(/*flush=*/true);
}
- // Try to close FEC group since we've either run out of data to send or we're
- // blocked.
- packet_creator_.MaybeSendFecPacketAndCloseGroup(/*force_send_fec=*/false,
- /*is_fec_timeout=*/false);
-
DCHECK(InBatchMode() || !packet_creator_.HasPendingFrames());
return QuicConsumedData(total_bytes_consumed, fin_consumed);
}
@@ -147,8 +127,12 @@ void QuicPacketGenerator::GenerateMtuDiscoveryPacket(
QuicByteCount target_mtu,
QuicAckListenerInterface* listener) {
// MTU discovery frames must be sent by themselves.
- DCHECK(!InBatchMode() && !packet_creator_.HasPendingFrames());
- const QuicByteCount current_mtu = GetMaxPacketLength();
+ if (!packet_creator_.CanSetMaxPacketLength()) {
+ QUIC_BUG << "MTU discovery packets should only be sent when no other "
+ << "frames needs to be sent.";
+ return;
+ }
+ const QuicByteCount current_mtu = GetCurrentMaxPacketLength();
// The MTU discovery frame is allocated on the stack, since it is going to be
// serialized within this function.
@@ -156,7 +140,7 @@ void QuicPacketGenerator::GenerateMtuDiscoveryPacket(
QuicFrame frame(mtu_discovery_frame);
// Send the probe packet with the new length.
- SetMaxPacketLength(target_mtu, /*force=*/true);
+ SetMaxPacketLength(target_mtu);
const bool success = packet_creator_.AddPaddedSavedFrame(frame);
if (listener != nullptr) {
packet_creator_.AddAckListener(listener, 0);
@@ -167,7 +151,7 @@ void QuicPacketGenerator::GenerateMtuDiscoveryPacket(
DCHECK(success);
// Reset the packet length back.
- SetMaxPacketLength(current_mtu, /*force=*/true);
+ SetMaxPacketLength(current_mtu);
}
bool QuicPacketGenerator::CanSendWithNextPendingFrameAddition() const {
@@ -182,7 +166,7 @@ bool QuicPacketGenerator::CanSendWithNextPendingFrameAddition() const {
return delegate_->ShouldGeneratePacket(retransmittable, NOT_HANDSHAKE);
}
-void QuicPacketGenerator::SendQueuedFrames(bool flush, bool is_fec_timeout) {
+void QuicPacketGenerator::SendQueuedFrames(bool flush) {
// Only add pending frames if we are SURE we can then send the whole packet.
while (HasPendingFrames() &&
(flush || CanSendWithNextPendingFrameAddition())) {
@@ -191,23 +175,6 @@ void QuicPacketGenerator::SendQueuedFrames(bool flush, bool is_fec_timeout) {
if (flush || !InBatchMode()) {
packet_creator_.Flush();
}
- packet_creator_.MaybeSendFecPacketAndCloseGroup(flush, is_fec_timeout);
-}
-
-void QuicPacketGenerator::OnFecTimeout() {
- DCHECK(!InBatchMode());
- if (!packet_creator_.ShouldSendFec(true)) {
- QUIC_BUG << "No FEC packet to send on FEC timeout.";
- return;
- }
- // Flush out any pending frames in the generator and the creator, and then
- // send out FEC packet.
- SendQueuedFrames(/*flush=*/true, /*is_fec_timeout=*/true);
-}
-
-QuicTime::Delta QuicPacketGenerator::GetFecTimeout(
- QuicPacketNumber packet_number) {
- return packet_creator_.GetFecTimeout(packet_number);
}
bool QuicPacketGenerator::InBatchMode() {
@@ -220,11 +187,11 @@ void QuicPacketGenerator::StartBatchOperations() {
void QuicPacketGenerator::FinishBatchOperations() {
batch_mode_ = false;
- SendQueuedFrames(/*flush=*/false, /*is_fec_timeout=*/false);
+ SendQueuedFrames(/*flush=*/false);
}
void QuicPacketGenerator::FlushAllQueuedFrames() {
- SendQueuedFrames(/*flush=*/true, /*is_fec_timeout=*/false);
+ SendQueuedFrames(/*flush=*/true);
}
bool QuicPacketGenerator::HasQueuedFrames() const {
@@ -275,29 +242,13 @@ QuicPacketNumber QuicPacketGenerator::packet_number() const {
return packet_creator_.packet_number();
}
-QuicByteCount QuicPacketGenerator::GetMaxPacketLength() const {
- return max_packet_length_;
-}
-
QuicByteCount QuicPacketGenerator::GetCurrentMaxPacketLength() const {
return packet_creator_.max_packet_length();
}
-void QuicPacketGenerator::SetMaxPacketLength(QuicByteCount length, bool force) {
- // If we cannot immediately set new maximum packet length, and the |force|
- // flag is set, we have to flush the contents of the queue and close existing
- // FEC group.
- if (!packet_creator_.CanSetMaxPacketLength() && force) {
- SendQueuedFrames(/*flush=*/true, /*is_fec_timeout=*/false);
- packet_creator_.MaybeSendFecPacketAndCloseGroup(/*force_send_fec=*/true,
- /*is_fec_timeout=*/false);
- DCHECK(packet_creator_.CanSetMaxPacketLength());
- }
-
- max_packet_length_ = length;
- if (packet_creator_.CanSetMaxPacketLength()) {
- packet_creator_.SetMaxPacketLength(length);
- }
+void QuicPacketGenerator::SetMaxPacketLength(QuicByteCount length) {
+ DCHECK(packet_creator_.CanSetMaxPacketLength());
+ packet_creator_.SetMaxPacketLength(length);
}
QuicEncryptedPacket* QuicPacketGenerator::SerializeVersionNegotiationPacket(
@@ -348,18 +299,4 @@ void QuicPacketGenerator::SetCurrentPath(
max_packets_in_flight);
}
-void QuicPacketGenerator::set_rtt_multiplier_for_fec_timeout(
- float rtt_multiplier_for_fec_timeout) {
- packet_creator_.set_rtt_multiplier_for_fec_timeout(
- rtt_multiplier_for_fec_timeout);
-}
-
-FecSendPolicy QuicPacketGenerator::fec_send_policy() {
- return packet_creator_.fec_send_policy();
-}
-
-void QuicPacketGenerator::set_fec_send_policy(FecSendPolicy fec_send_policy) {
- packet_creator_.set_fec_send_policy(fec_send_policy);
-}
-
} // namespace net
diff --git a/net/quic/quic_packet_generator.h b/net/quic/quic_packet_generator.h
index 6d956e3..881d973 100644
--- a/net/quic/quic_packet_generator.h
+++ b/net/quic/quic_packet_generator.h
@@ -36,19 +36,6 @@
// full, it will be serialized and sent to the packet. When batch
// mode is ended via |FinishBatchOperations|, the current packet
// will be serialzied, even if it is not full.
-//
-// FEC behavior also depends on batch mode. In batch mode, FEC packets
-// will be sent after |max_packets_per_group| have been sent, as well
-// as after batch operations are complete. When not in batch mode,
-// an FEC packet will be sent after each write call completes.
-//
-// TODO(rch): This behavior should probably be tuned. When not in batch
-// mode, we should probably set a timer so that several independent
-// operations can be grouped into the same FEC group.
-//
-// When an FEC packet is generated, it will be send to the Delegate,
-// even if the Delegate has become unwritable after handling the
-// data packet immediately proceeding the FEC packet.
#ifndef NET_QUIC_QUIC_PACKET_GENERATOR_H_
#define NET_QUIC_QUIC_PACKET_GENERATOR_H_
@@ -91,12 +78,6 @@ class NET_EXPORT_PRIVATE QuicPacketGenerator {
~QuicPacketGenerator();
- // Called by the connection in the event of the congestion window changing.
- void OnCongestionWindowChange(QuicPacketCount max_packets_in_flight);
-
- // Called by the connection when the RTT may have changed.
- void OnRttChange(QuicTime::Delta rtt);
-
// Indicates that an ACK frame should be sent.
// If |also_send_stop_waiting| is true, then it also indicates that a
// STOP_WAITING frame should be sent as well.
@@ -115,7 +96,6 @@ class NET_EXPORT_PRIVATE QuicPacketGenerator {
QuicIOVector iov,
QuicStreamOffset offset,
bool fin,
- FecProtection fec_protection,
QuicAckListenerInterface* listener);
// Generates an MTU discovery packet of specified size.
@@ -146,8 +126,6 @@ class NET_EXPORT_PRIVATE QuicPacketGenerator {
// Re-serializes frames with the original packet's packet number length.
// Used for retransmitting packets to ensure they aren't too long.
- // Caller must ensure that any open FEC group is closed before calling this
- // method.
void ReserializeAllFrames(const PendingRetransmission& retransmission,
char* buffer,
size_t buffer_len);
@@ -160,16 +138,6 @@ class NET_EXPORT_PRIVATE QuicPacketGenerator {
// Set the minimum number of bytes for the connection id length;
void SetConnectionIdLength(uint32_t length);
- // Called when the FEC alarm fires.
- void OnFecTimeout();
-
- // Called after sending |packet_number| to determine whether an FEC alarm
- // should be set for sending out an FEC packet. Returns a positive and finite
- // timeout if an FEC alarm should be set, and infinite if no alarm should be
- // set. OnFecTimeout should be called to send the FEC packet when the alarm
- // fires.
- QuicTime::Delta GetFecTimeout(QuicPacketNumber packet_number);
-
// Sets the encrypter to use for the encryption level.
void SetEncrypter(EncryptionLevel level, QuicEncrypter* encrypter);
@@ -180,18 +148,12 @@ class NET_EXPORT_PRIVATE QuicPacketGenerator {
// created.
QuicPacketNumber packet_number() const;
- // Returns the maximum packet length. Note that this is the long-term maximum
- // packet length, and it may not be the maximum length of the current packet,
- // if the generator is in the middle of the packet (in batch mode) or FEC
- // group.
- QuicByteCount GetMaxPacketLength() const;
- // Returns the maximum length current packet can actually have.
+ // Returns the maximum length a current packet can actually have.
QuicByteCount GetCurrentMaxPacketLength() const;
- // Set maximum packet length sent. If |force| is set to true, all pending
- // unfinished packets and FEC groups are closed, and the change is enacted
- // immediately. Otherwise, it is enacted at the next opportunity.
- void SetMaxPacketLength(QuicByteCount length, bool force);
+ // Set maximum packet length in the creator immediately. May not be called
+ // when there are frames queued in the creator.
+ void SetMaxPacketLength(QuicByteCount length);
// Sets |path_id| to be the path on which next packet is generated.
void SetCurrentPath(QuicPathId path_id,
@@ -202,15 +164,10 @@ class NET_EXPORT_PRIVATE QuicPacketGenerator {
packet_creator_.set_debug_delegate(debug_delegate);
}
- void set_rtt_multiplier_for_fec_timeout(float rtt_multiplier_for_fec_timeout);
-
- FecSendPolicy fec_send_policy();
- void set_fec_send_policy(FecSendPolicy fec_send_policy);
-
private:
friend class test::QuicPacketGeneratorPeer;
- void SendQueuedFrames(bool flush, bool is_fec_timeout);
+ void SendQueuedFrames(bool flush);
// Test to see if we have pending ack, or control frames.
bool HasPendingFrames() const;
@@ -241,11 +198,6 @@ class NET_EXPORT_PRIVATE QuicPacketGenerator {
QuicAckFrame pending_ack_frame_;
QuicStopWaitingFrame pending_stop_waiting_frame_;
- // Stores the maximum packet size we are allowed to send. This might not be
- // the maximum size we are actually using now, if we are in the middle of the
- // packet.
- QuicByteCount max_packet_length_;
-
DISALLOW_COPY_AND_ASSIGN(QuicPacketGenerator);
};
diff --git a/net/quic/quic_packet_generator_test.cc b/net/quic/quic_packet_generator_test.cc
index e930bc4..133dad5 100644
--- a/net/quic/quic_packet_generator_test.cc
+++ b/net/quic/quic_packet_generator_test.cc
@@ -34,12 +34,6 @@ namespace net {
namespace test {
namespace {
-const int64_t kMinFecTimeoutMs = 5u;
-
-static const FecSendPolicy kFecSendPolicyList[] = {
- FEC_ANY_TRIGGER, FEC_ALARM_TRIGGER,
-};
-
class MockDelegate : public QuicPacketGenerator::DelegateInterface {
public:
MockDelegate() {}
@@ -53,7 +47,6 @@ class MockDelegate : public QuicPacketGenerator::DelegateInterface {
MOCK_METHOD1(OnSerializedPacket, void(SerializedPacket* packet));
MOCK_METHOD2(OnUnrecoverableError,
void(QuicErrorCode, ConnectionCloseSource));
- MOCK_METHOD0(OnResetFecGroup, void());
void SetCanWriteAnything() {
EXPECT_CALL(*this, ShouldGeneratePacket(_, _)).WillRepeatedly(Return(true));
@@ -92,8 +85,7 @@ struct PacketContents {
num_stop_waiting_frames(0),
num_stream_frames(0),
num_ping_frames(0),
- num_mtu_discovery_frames(0),
- fec_group(0) {}
+ num_mtu_discovery_frames(0) {}
size_t num_ack_frames;
size_t num_connection_close_frames;
@@ -103,13 +95,11 @@ struct PacketContents {
size_t num_stream_frames;
size_t num_ping_frames;
size_t num_mtu_discovery_frames;
-
- QuicFecGroupNumber fec_group;
};
} // namespace
-class QuicPacketGeneratorTest : public ::testing::TestWithParam<FecSendPolicy> {
+class QuicPacketGeneratorTest : public ::testing::Test {
public:
QuicPacketGeneratorTest()
: framer_(QuicSupportedVersions(),
@@ -117,10 +107,8 @@ class QuicPacketGeneratorTest : public ::testing::TestWithParam<FecSendPolicy> {
Perspective::IS_CLIENT),
generator_(42, &framer_, &random_, &buffer_allocator_, &delegate_),
creator_(QuicPacketGeneratorPeer::GetPacketCreator(&generator_)) {
- generator_.set_fec_send_policy(GetParam());
// TODO(ianswett): Fix this test so it uses a non-null encrypter.
FLAGS_quic_never_write_unencrypted_data = false;
- FLAGS_quic_no_unencrypted_fec = false;
}
~QuicPacketGeneratorTest() override {
@@ -181,7 +169,6 @@ class QuicPacketGeneratorTest : public ::testing::TestWithParam<FecSendPolicy> {
simple_framer_.stream_frames().size());
EXPECT_EQ(contents.num_stop_waiting_frames,
simple_framer_.stop_waiting_frames().size());
- EXPECT_EQ(contents.fec_group, simple_framer_.header().fec_group);
// From the receiver's perspective, MTU discovery frames are ping frames.
EXPECT_EQ(contents.num_ping_frames + contents.num_mtu_discovery_frames,
@@ -206,16 +193,6 @@ class QuicPacketGeneratorTest : public ::testing::TestWithParam<FecSendPolicy> {
}
}
- void CheckPacketIsFec(size_t packet_index, QuicPacketNumber fec_group) {
- ASSERT_GT(packets_.size(), packet_index);
- const SerializedPacket& packet = packets_[packet_index];
- ASSERT_TRUE(packet.retransmittable_frames.empty());
- ASSERT_TRUE(packet.encrypted_buffer != nullptr);
- ASSERT_TRUE(simple_framer_.ProcessPacket(
- QuicEncryptedPacket(packet.encrypted_buffer, packet.encrypted_length)));
- EXPECT_TRUE(simple_framer_.header().fec_flag);
- }
-
QuicIOVector CreateData(size_t len) {
data_array_.reset(new char[len]);
memset(data_array_.get(), '?', len);
@@ -247,19 +224,14 @@ class MockDebugDelegate : public QuicPacketCreator::DebugDelegate {
MOCK_METHOD1(OnFrameAddedToPacket, void(const QuicFrame&));
};
-// Run all end to end tests with all supported FEC send polocies.
-INSTANTIATE_TEST_CASE_P(FecSendPolicy,
- QuicPacketGeneratorTest,
- ::testing::ValuesIn(kFecSendPolicyList));
-
-TEST_P(QuicPacketGeneratorTest, ShouldSendAck_NotWritable) {
+TEST_F(QuicPacketGeneratorTest, ShouldSendAck_NotWritable) {
delegate_.SetCanNotWrite();
generator_.SetShouldSendAck(false);
EXPECT_TRUE(generator_.HasQueuedFrames());
}
-TEST_P(QuicPacketGeneratorTest, ShouldSendAck_WritableAndShouldNotFlush) {
+TEST_F(QuicPacketGeneratorTest, ShouldSendAck_WritableAndShouldNotFlush) {
StrictMock<MockDebugDelegate> debug_delegate;
generator_.set_debug_delegate(&debug_delegate);
@@ -273,7 +245,7 @@ TEST_P(QuicPacketGeneratorTest, ShouldSendAck_WritableAndShouldNotFlush) {
EXPECT_TRUE(generator_.HasQueuedFrames());
}
-TEST_P(QuicPacketGeneratorTest, ShouldSendAck_WritableAndShouldFlush) {
+TEST_F(QuicPacketGeneratorTest, ShouldSendAck_WritableAndShouldFlush) {
delegate_.SetCanWriteOnlyNonRetransmittable();
EXPECT_CALL(delegate_, PopulateAckFrame(_));
@@ -288,7 +260,7 @@ TEST_P(QuicPacketGeneratorTest, ShouldSendAck_WritableAndShouldFlush) {
CheckPacketContains(contents, 0);
}
-TEST_P(QuicPacketGeneratorTest, ShouldSendAck_MultipleCalls) {
+TEST_F(QuicPacketGeneratorTest, ShouldSendAck_MultipleCalls) {
// Make sure that calling SetShouldSendAck multiple times does not result in a
// crash. Previously this would result in multiple QuicFrames queued in the
// packet generator, with all but the last with internal pointers to freed
@@ -307,21 +279,21 @@ TEST_P(QuicPacketGeneratorTest, ShouldSendAck_MultipleCalls) {
generator_.FinishBatchOperations();
}
-TEST_P(QuicPacketGeneratorTest, AddControlFrame_NotWritable) {
+TEST_F(QuicPacketGeneratorTest, AddControlFrame_NotWritable) {
delegate_.SetCanNotWrite();
generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame()));
EXPECT_TRUE(generator_.HasQueuedFrames());
}
-TEST_P(QuicPacketGeneratorTest, AddControlFrame_OnlyAckWritable) {
+TEST_F(QuicPacketGeneratorTest, AddControlFrame_OnlyAckWritable) {
delegate_.SetCanWriteOnlyNonRetransmittable();
generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame()));
EXPECT_TRUE(generator_.HasQueuedFrames());
}
-TEST_P(QuicPacketGeneratorTest, AddControlFrame_WritableAndShouldNotFlush) {
+TEST_F(QuicPacketGeneratorTest, AddControlFrame_WritableAndShouldNotFlush) {
delegate_.SetCanWriteAnything();
generator_.StartBatchOperations();
@@ -329,7 +301,7 @@ TEST_P(QuicPacketGeneratorTest, AddControlFrame_WritableAndShouldNotFlush) {
EXPECT_TRUE(generator_.HasQueuedFrames());
}
-TEST_P(QuicPacketGeneratorTest, AddControlFrame_NotWritableBatchThenFlush) {
+TEST_F(QuicPacketGeneratorTest, AddControlFrame_NotWritableBatchThenFlush) {
delegate_.SetCanNotWrite();
generator_.StartBatchOperations();
@@ -348,7 +320,7 @@ TEST_P(QuicPacketGeneratorTest, AddControlFrame_NotWritableBatchThenFlush) {
CheckPacketContains(contents, 0);
}
-TEST_P(QuicPacketGeneratorTest, AddControlFrame_WritableAndShouldFlush) {
+TEST_F(QuicPacketGeneratorTest, AddControlFrame_WritableAndShouldFlush) {
delegate_.SetCanWriteAnything();
EXPECT_CALL(delegate_, OnSerializedPacket(_))
@@ -362,34 +334,34 @@ TEST_P(QuicPacketGeneratorTest, AddControlFrame_WritableAndShouldFlush) {
CheckPacketContains(contents, 0);
}
-TEST_P(QuicPacketGeneratorTest, ConsumeData_NotWritable) {
+TEST_F(QuicPacketGeneratorTest, ConsumeData_NotWritable) {
delegate_.SetCanNotWrite();
QuicConsumedData consumed = generator_.ConsumeData(
- kHeadersStreamId, MakeIOVector("foo"), 2, true, MAY_FEC_PROTECT, nullptr);
+ kHeadersStreamId, MakeIOVector("foo"), 2, true, nullptr);
EXPECT_EQ(0u, consumed.bytes_consumed);
EXPECT_FALSE(consumed.fin_consumed);
EXPECT_FALSE(generator_.HasQueuedFrames());
}
-TEST_P(QuicPacketGeneratorTest, ConsumeData_WritableAndShouldNotFlush) {
+TEST_F(QuicPacketGeneratorTest, ConsumeData_WritableAndShouldNotFlush) {
delegate_.SetCanWriteAnything();
generator_.StartBatchOperations();
QuicConsumedData consumed = generator_.ConsumeData(
- kHeadersStreamId, MakeIOVector("foo"), 2, true, MAY_FEC_PROTECT, nullptr);
+ kHeadersStreamId, MakeIOVector("foo"), 2, true, nullptr);
EXPECT_EQ(3u, consumed.bytes_consumed);
EXPECT_TRUE(consumed.fin_consumed);
EXPECT_TRUE(generator_.HasQueuedFrames());
}
-TEST_P(QuicPacketGeneratorTest, ConsumeData_WritableAndShouldFlush) {
+TEST_F(QuicPacketGeneratorTest, ConsumeData_WritableAndShouldFlush) {
delegate_.SetCanWriteAnything();
EXPECT_CALL(delegate_, OnSerializedPacket(_))
.WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
QuicConsumedData consumed = generator_.ConsumeData(
- kHeadersStreamId, MakeIOVector("foo"), 2, true, MAY_FEC_PROTECT, nullptr);
+ kHeadersStreamId, MakeIOVector("foo"), 2, true, nullptr);
EXPECT_EQ(3u, consumed.bytes_consumed);
EXPECT_TRUE(consumed.fin_consumed);
EXPECT_FALSE(generator_.HasQueuedFrames());
@@ -402,14 +374,14 @@ TEST_P(QuicPacketGeneratorTest, ConsumeData_WritableAndShouldFlush) {
// Test the behavior of ConsumeData when the data consumed is for the crypto
// handshake stream. Ensure that the packet is always sent and padded even if
// the generator operates in batch mode.
-TEST_P(QuicPacketGeneratorTest, ConsumeData_Handshake) {
+TEST_F(QuicPacketGeneratorTest, ConsumeData_Handshake) {
delegate_.SetCanWriteAnything();
generator_.StartBatchOperations();
EXPECT_CALL(delegate_, OnSerializedPacket(_))
.WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
QuicConsumedData consumed = generator_.ConsumeData(
- kCryptoStreamId, MakeIOVector("foo"), 0, false, MAY_FEC_PROTECT, nullptr);
+ kCryptoStreamId, MakeIOVector("foo"), 0, false, nullptr);
EXPECT_EQ(3u, consumed.bytes_consumed);
EXPECT_FALSE(generator_.HasQueuedFrames());
@@ -418,38 +390,38 @@ TEST_P(QuicPacketGeneratorTest, ConsumeData_Handshake) {
CheckPacketContains(contents, 0);
ASSERT_EQ(1u, packets_.size());
- ASSERT_EQ(kDefaultMaxPacketSize, generator_.GetMaxPacketLength());
+ ASSERT_EQ(kDefaultMaxPacketSize, generator_.GetCurrentMaxPacketLength());
EXPECT_EQ(kDefaultMaxPacketSize, packets_[0].encrypted_length);
}
-TEST_P(QuicPacketGeneratorTest, ConsumeData_EmptyData) {
+TEST_F(QuicPacketGeneratorTest, ConsumeData_EmptyData) {
EXPECT_DFATAL(generator_.ConsumeData(kHeadersStreamId, MakeIOVector(""), 0,
- false, MAY_FEC_PROTECT, nullptr),
+ false, nullptr),
"Attempt to consume empty data without FIN.");
}
-TEST_P(QuicPacketGeneratorTest,
+TEST_F(QuicPacketGeneratorTest,
ConsumeDataMultipleTimes_WritableAndShouldNotFlush) {
delegate_.SetCanWriteAnything();
generator_.StartBatchOperations();
generator_.ConsumeData(kHeadersStreamId, MakeIOVector("foo"), 2, true,
- MAY_FEC_PROTECT, nullptr);
- QuicConsumedData consumed = generator_.ConsumeData(
- 3, MakeIOVector("quux"), 7, false, MAY_FEC_PROTECT, nullptr);
+ nullptr);
+ QuicConsumedData consumed =
+ generator_.ConsumeData(3, MakeIOVector("quux"), 7, false, nullptr);
EXPECT_EQ(4u, consumed.bytes_consumed);
EXPECT_FALSE(consumed.fin_consumed);
EXPECT_TRUE(generator_.HasQueuedFrames());
}
-TEST_P(QuicPacketGeneratorTest, ConsumeData_BatchOperations) {
+TEST_F(QuicPacketGeneratorTest, ConsumeData_BatchOperations) {
delegate_.SetCanWriteAnything();
generator_.StartBatchOperations();
generator_.ConsumeData(kHeadersStreamId, MakeIOVector("foo"), 2, true,
- MAY_FEC_PROTECT, nullptr);
- QuicConsumedData consumed = generator_.ConsumeData(
- 3, MakeIOVector("quux"), 7, false, MAY_FEC_PROTECT, nullptr);
+ nullptr);
+ QuicConsumedData consumed =
+ generator_.ConsumeData(3, MakeIOVector("quux"), 7, false, nullptr);
EXPECT_EQ(4u, consumed.bytes_consumed);
EXPECT_FALSE(consumed.fin_consumed);
EXPECT_TRUE(generator_.HasQueuedFrames());
@@ -465,246 +437,19 @@ TEST_P(QuicPacketGeneratorTest, ConsumeData_BatchOperations) {
CheckPacketContains(contents, 0);
}
-TEST_P(QuicPacketGeneratorTest, ConsumeDataFecOnMaxGroupSize) {
- delegate_.SetCanWriteAnything();
-
- // Send FEC every two packets.
- creator_->set_max_packets_per_fec_group(2);
-
- {
- InSequence dummy;
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- if (generator_.fec_send_policy() == FEC_ALARM_TRIGGER) {
- // FEC packet is not sent when send policy is FEC_ALARM_TRIGGER, but FEC
- // group is closed.
- EXPECT_CALL(delegate_, OnResetFecGroup()).Times(1);
- } else {
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- }
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- }
-
- // Send enough data to create 3 packets: two full and one partial. Send with
- // MUST_FEC_PROTECT flag.
- size_t data_len = 2 * kDefaultMaxPacketSize + 100;
- QuicConsumedData consumed = generator_.ConsumeData(
- 3, CreateData(data_len), 0, true, MUST_FEC_PROTECT, nullptr);
- EXPECT_EQ(data_len, consumed.bytes_consumed);
- EXPECT_TRUE(consumed.fin_consumed);
- EXPECT_FALSE(generator_.HasQueuedFrames());
-
- CheckPacketHasSingleStreamFrame(0);
- CheckPacketHasSingleStreamFrame(1);
- if (generator_.fec_send_policy() == FEC_ALARM_TRIGGER) {
- // FEC packet is not sent when send policy is FEC_ALARM_TRIGGER.
- CheckPacketHasSingleStreamFrame(2);
- } else {
- CheckPacketIsFec(2, 1);
- CheckPacketHasSingleStreamFrame(3);
- }
- EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(creator_));
-
- // If FEC send policy is FEC_ANY_TRIGGER, then the FEC packet under
- // construction will be sent when one more packet is sent (since FEC group
- // size is 2), or when OnFecTimeout is called. Send more data with
- // MAY_FEC_PROTECT. This packet should also be protected, and FEC packet is
- // sent since FEC group size is reached.
- //
- // If FEC send policy is FEC_ALARM_TRIGGER, FEC group is closed when the group
- // size is reached. FEC packet is not sent.
- {
- InSequence dummy;
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- if (generator_.fec_send_policy() == FEC_ALARM_TRIGGER) {
- EXPECT_CALL(delegate_, OnResetFecGroup()).Times(1);
- } else {
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- }
- }
- consumed = generator_.ConsumeData(5, CreateData(1u), 0, true, MAY_FEC_PROTECT,
- nullptr);
- EXPECT_EQ(1u, consumed.bytes_consumed);
- if (generator_.fec_send_policy() == FEC_ALARM_TRIGGER) {
- CheckPacketHasSingleStreamFrame(3);
- } else {
- CheckPacketHasSingleStreamFrame(4);
- CheckPacketIsFec(5, 4);
- }
- EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
-}
-
-TEST_P(QuicPacketGeneratorTest, ConsumeDataSendsFecOnTimeout) {
- delegate_.SetCanWriteAnything();
- creator_->set_max_packets_per_fec_group(1000);
-
- // Send data with MUST_FEC_PROTECT flag. No FEC packet is emitted, but the
- // creator FEC protects all data.
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- QuicConsumedData consumed = generator_.ConsumeData(3, CreateData(1u), 0, true,
- MUST_FEC_PROTECT, nullptr);
- EXPECT_EQ(1u, consumed.bytes_consumed);
- EXPECT_TRUE(consumed.fin_consumed);
- CheckPacketHasSingleStreamFrame(0);
- EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(creator_));
-
- // Send more data with MAY_FEC_PROTECT. This packet should also be protected,
- // and FEC packet is not yet sent.
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- consumed = generator_.ConsumeData(5, CreateData(1u), 0, true, MAY_FEC_PROTECT,
- nullptr);
- EXPECT_EQ(1u, consumed.bytes_consumed);
- CheckPacketHasSingleStreamFrame(1);
- EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(creator_));
-
- // Calling OnFecTimeout should cause the FEC packet to be emitted.
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- generator_.OnFecTimeout();
- CheckPacketIsFec(2, 1);
- EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
-
- // Subsequent data is protected under the next FEC group. Send enough data to
- // create 2 more packets: one full and one partial.
- {
- InSequence dummy;
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- }
- size_t data_len = kDefaultMaxPacketSize + 1;
- consumed = generator_.ConsumeData(7, CreateData(data_len), 0, true,
- MUST_FEC_PROTECT, nullptr);
- EXPECT_EQ(data_len, consumed.bytes_consumed);
- EXPECT_TRUE(consumed.fin_consumed);
- CheckPacketHasSingleStreamFrame(3);
- CheckPacketHasSingleStreamFrame(4);
- EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(creator_));
-
- // Calling OnFecTimeout should cause the FEC packet to be emitted.
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- generator_.OnFecTimeout();
- CheckPacketIsFec(5, 4);
- EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
-}
-
-TEST_P(QuicPacketGeneratorTest, GetFecTimeoutFiniteOnlyOnFirstPacketInGroup) {
- delegate_.SetCanWriteAnything();
- creator_->set_max_packets_per_fec_group(6);
-
- // Send enough data to create 2 packets: one full and one partial. Send with
- // MUST_FEC_PROTECT flag. No FEC packet is emitted yet, but the creator FEC
- // protects all data.
- {
- InSequence dummy;
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- }
- size_t data_len = 1 * kDefaultMaxPacketSize + 100;
- QuicConsumedData consumed = generator_.ConsumeData(
- 3, CreateData(data_len), 0, true, MUST_FEC_PROTECT, nullptr);
- EXPECT_EQ(data_len, consumed.bytes_consumed);
- EXPECT_TRUE(consumed.fin_consumed);
- EXPECT_FALSE(generator_.HasQueuedFrames());
- CheckPacketHasSingleStreamFrame(0);
- CheckPacketHasSingleStreamFrame(1);
- EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(creator_));
-
- // GetFecTimeout returns finite timeout only for first packet in group.
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(kMinFecTimeoutMs),
- generator_.GetFecTimeout(/*packet_number=*/1u));
- EXPECT_EQ(QuicTime::Delta::Infinite(),
- generator_.GetFecTimeout(/*packet_number=*/2u));
-
- // Send more data with MAY_FEC_PROTECT. This packet should also be protected,
- // and FEC packet is not yet sent.
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- consumed = generator_.ConsumeData(5, CreateData(1u), 0, true, MAY_FEC_PROTECT,
- nullptr);
- CheckPacketHasSingleStreamFrame(2);
- EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(creator_));
-
- // GetFecTimeout returns finite timeout only for first packet in group.
- EXPECT_EQ(QuicTime::Delta::Infinite(),
- generator_.GetFecTimeout(/*packet_number=*/3u));
-
- // Calling OnFecTimeout should cause the FEC packet to be emitted.
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- generator_.OnFecTimeout();
- CheckPacketIsFec(3, /*fec_group=*/1u);
- EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
-
- // Subsequent data is protected under the next FEC group. Send enough data to
- // create 2 more packets: one full and one partial.
- {
- InSequence dummy;
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- }
- data_len = kDefaultMaxPacketSize + 1u;
- consumed = generator_.ConsumeData(7, CreateData(data_len), 0, true,
- MUST_FEC_PROTECT, nullptr);
- EXPECT_EQ(data_len, consumed.bytes_consumed);
- EXPECT_TRUE(consumed.fin_consumed);
- CheckPacketHasSingleStreamFrame(4);
- CheckPacketHasSingleStreamFrame(5);
- EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(creator_));
-
- // GetFecTimeout returns finite timeout for first packet in the new group.
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(kMinFecTimeoutMs),
- generator_.GetFecTimeout(/*packet_number=*/5u));
- EXPECT_EQ(QuicTime::Delta::Infinite(),
- generator_.GetFecTimeout(/*packet_number=*/6u));
-
- // Calling OnFecTimeout should cause the FEC packet to be emitted.
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- generator_.OnFecTimeout();
- CheckPacketIsFec(6, /*fec_group=*/5u);
- EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
-
- // Send more data with MAY_FEC_PROTECT. No FEC protection, so GetFecTimeout
- // returns infinite.
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- consumed = generator_.ConsumeData(9, CreateData(1u), 0, true, MAY_FEC_PROTECT,
- nullptr);
- CheckPacketHasSingleStreamFrame(7);
- EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
- EXPECT_EQ(QuicTime::Delta::Infinite(),
- generator_.GetFecTimeout(/*packet_number=*/8u));
-}
-
-TEST_P(QuicPacketGeneratorTest, ConsumeData_FramesPreviouslyQueued) {
+TEST_F(QuicPacketGeneratorTest, ConsumeData_FramesPreviouslyQueued) {
// Set the packet size be enough for two stream frames with 0 stream offset,
// but not enough for a stream frame of 0 offset and one with non-zero offset.
size_t length =
NullEncrypter().GetCiphertextSize(0) +
GetPacketHeaderSize(
creator_->connection_id_length(), kIncludeVersion, !kIncludePathId,
- QuicPacketCreatorPeer::NextPacketNumberLength(creator_),
- NOT_IN_FEC_GROUP) +
+ QuicPacketCreatorPeer::NextPacketNumberLength(creator_)) +
// Add an extra 3 bytes for the payload and 1 byte so BytesFree is larger
// than the GetMinStreamFrameSize.
- QuicFramer::GetMinStreamFrameSize(1, 0, false, NOT_IN_FEC_GROUP) + 3 +
- QuicFramer::GetMinStreamFrameSize(1, 0, true, NOT_IN_FEC_GROUP) + 1;
- generator_.SetMaxPacketLength(length, /*force=*/false);
+ QuicFramer::GetMinStreamFrameSize(1, 0, false) + 3 +
+ QuicFramer::GetMinStreamFrameSize(1, 0, true) + 1;
+ generator_.SetMaxPacketLength(length);
delegate_.SetCanWriteAnything();
{
InSequence dummy;
@@ -716,9 +461,8 @@ TEST_P(QuicPacketGeneratorTest, ConsumeData_FramesPreviouslyQueued) {
generator_.StartBatchOperations();
// Queue enough data to prevent a stream frame with a non-zero offset from
// fitting.
- QuicConsumedData consumed =
- generator_.ConsumeData(kHeadersStreamId, MakeIOVector("foo"), 0, false,
- MAY_FEC_PROTECT, nullptr);
+ QuicConsumedData consumed = generator_.ConsumeData(
+ kHeadersStreamId, MakeIOVector("foo"), 0, false, nullptr);
EXPECT_EQ(3u, consumed.bytes_consumed);
EXPECT_FALSE(consumed.fin_consumed);
EXPECT_TRUE(generator_.HasQueuedFrames());
@@ -726,7 +470,7 @@ TEST_P(QuicPacketGeneratorTest, ConsumeData_FramesPreviouslyQueued) {
// This frame will not fit with the existing frame, causing the queued frame
// to be serialized, and it will be added to a new open packet.
consumed = generator_.ConsumeData(kHeadersStreamId, MakeIOVector("bar"), 3,
- true, MAY_FEC_PROTECT, nullptr);
+ true, nullptr);
EXPECT_EQ(3u, consumed.bytes_consumed);
EXPECT_TRUE(consumed.fin_consumed);
EXPECT_TRUE(generator_.HasQueuedFrames());
@@ -740,554 +484,7 @@ TEST_P(QuicPacketGeneratorTest, ConsumeData_FramesPreviouslyQueued) {
CheckPacketContains(contents, 1);
}
-TEST_P(QuicPacketGeneratorTest, NoFecPacketSentWhenBatchEnds) {
- delegate_.SetCanWriteAnything();
- creator_->set_max_packets_per_fec_group(6);
-
- generator_.StartBatchOperations();
-
- generator_.ConsumeData(3, MakeIOVector("foo"), 2, true, MUST_FEC_PROTECT,
- nullptr);
- QuicConsumedData consumed = generator_.ConsumeData(
- 5, MakeIOVector("quux"), 7, false, MUST_FEC_PROTECT, nullptr);
- EXPECT_EQ(4u, consumed.bytes_consumed);
- EXPECT_FALSE(consumed.fin_consumed);
- EXPECT_TRUE(generator_.HasQueuedFrames());
-
- // Now both frames will be flushed out, but FEC packet is not yet sent.
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- generator_.FinishBatchOperations();
- EXPECT_FALSE(generator_.HasQueuedFrames());
-
- PacketContents contents;
- contents.num_stream_frames = 2u;
- contents.fec_group = 1u;
- CheckPacketContains(contents, 0);
-
- // Forcing FEC timeout causes FEC packet to be emitted.
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- generator_.OnFecTimeout();
- CheckPacketIsFec(1, /*fec_group=*/1u);
-}
-
-TEST_P(QuicPacketGeneratorTest, FecTimeoutOnRttChange) {
- EXPECT_EQ(QuicTime::Delta::Zero(),
- QuicPacketCreatorPeer::GetFecTimeout(creator_));
- generator_.OnRttChange(QuicTime::Delta::FromMilliseconds(300));
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(150),
- QuicPacketCreatorPeer::GetFecTimeout(creator_));
-}
-
-TEST_P(QuicPacketGeneratorTest, FecGroupSizeOnCongestionWindowChange) {
- delegate_.SetCanWriteAnything();
- creator_->set_max_packets_per_fec_group(50);
- EXPECT_EQ(50u, creator_->max_packets_per_fec_group());
- EXPECT_FALSE(creator_->IsFecGroupOpen());
-
- // On reduced cwnd.
- generator_.OnCongestionWindowChange(7);
- EXPECT_EQ(3u, creator_->max_packets_per_fec_group());
-
- // On increased cwnd.
- generator_.OnCongestionWindowChange(100);
- EXPECT_EQ(50u, creator_->max_packets_per_fec_group());
-
- // On collapsed cwnd.
- generator_.OnCongestionWindowChange(1);
- EXPECT_EQ(2u, creator_->max_packets_per_fec_group());
-}
-
-TEST_P(QuicPacketGeneratorTest, FecGroupSizeChangeWithOpenGroup) {
- delegate_.SetCanWriteAnything();
- generator_.StartBatchOperations();
- creator_->set_max_packets_per_fec_group(50);
- EXPECT_EQ(50u, creator_->max_packets_per_fec_group());
- EXPECT_FALSE(creator_->IsFecGroupOpen());
-
- // Send enough data to create 4 packets with MUST_FEC_PROTECT flag. 3 packets
- // are sent, one is queued in the creator.
- {
- InSequence dummy;
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- }
- size_t data_len = 3 * kDefaultMaxPacketSize + 1;
- QuicConsumedData consumed = generator_.ConsumeData(
- 7, CreateData(data_len), 0, true, MUST_FEC_PROTECT, nullptr);
- EXPECT_EQ(data_len, consumed.bytes_consumed);
- EXPECT_TRUE(creator_->IsFecGroupOpen());
-
- // Change FEC groupsize.
- generator_.OnCongestionWindowChange(2);
- EXPECT_EQ(2u, creator_->max_packets_per_fec_group());
-
- // If FEC send policy is FEC_ANY_TRIGGER, then send enough data to trigger one
- // unprotected data packet, causing the FEC packet to also be sent.
- //
- // If FEC send policy is FEC_ALARM_TRIGGER, FEC group is closed and FEC packet
- // is not sent.
- {
- InSequence dummy;
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- if (generator_.fec_send_policy() == FEC_ALARM_TRIGGER) {
- EXPECT_CALL(delegate_, OnResetFecGroup()).Times(1);
- } else {
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- }
- }
- consumed = generator_.ConsumeData(7, CreateData(kDefaultMaxPacketSize), 0,
- true, MAY_FEC_PROTECT, nullptr);
- EXPECT_EQ(kDefaultMaxPacketSize, consumed.bytes_consumed);
- if (generator_.fec_send_policy() == FEC_ANY_TRIGGER) {
- // Verify that one FEC packet was sent.
- CheckPacketIsFec(4, /*fec_group=*/1u);
- }
- EXPECT_FALSE(creator_->IsFecGroupOpen());
- EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
-}
-
-TEST_P(QuicPacketGeneratorTest, SwitchFecOnOff) {
- delegate_.SetCanWriteAnything();
- creator_->set_max_packets_per_fec_group(2);
- EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
-
- // Send one unprotected data packet.
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- QuicConsumedData consumed = generator_.ConsumeData(5, CreateData(1u), 0, true,
- MAY_FEC_PROTECT, nullptr);
- EXPECT_EQ(1u, consumed.bytes_consumed);
- EXPECT_FALSE(generator_.HasQueuedFrames());
- EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
- // Verify that one data packet was sent.
- PacketContents contents;
- contents.num_stream_frames = 1;
- CheckPacketContains(contents, 0);
-
- {
- InSequence dummy;
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- if (generator_.fec_send_policy() == FEC_ALARM_TRIGGER) {
- // If FEC send policy is FEC_ALARM_TRIGGER, FEC group is closed.
- EXPECT_CALL(delegate_, OnResetFecGroup()).Times(1);
- } else {
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- }
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- }
- // Send enough data to create 3 packets with MUST_FEC_PROTECT flag.
- size_t data_len = 2 * kDefaultMaxPacketSize + 100;
- consumed = generator_.ConsumeData(7, CreateData(data_len), 0, true,
- MUST_FEC_PROTECT, nullptr);
- EXPECT_EQ(data_len, consumed.bytes_consumed);
- EXPECT_FALSE(generator_.HasQueuedFrames());
-
- // If FEC send policy is FEC_ANY_TRIGGER, verify that packets sent were 3 data
- // and 1 FEC.
- //
- // If FEC send policy is FEC_ALARM_TRIGGER, verify that packets sent were 3
- // data and FEC group is closed.
- CheckPacketHasSingleStreamFrame(1);
- CheckPacketHasSingleStreamFrame(2);
- if (generator_.fec_send_policy() == FEC_ALARM_TRIGGER) {
- CheckPacketHasSingleStreamFrame(3);
- } else {
- CheckPacketIsFec(3, /*fec_group=*/2u);
- CheckPacketHasSingleStreamFrame(4);
- }
-
- // Calling OnFecTimeout should emit the pending FEC packet.
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- generator_.OnFecTimeout();
- if (generator_.fec_send_policy() == FEC_ALARM_TRIGGER) {
- CheckPacketIsFec(4, /*fec_group=*/4u);
- } else {
- CheckPacketIsFec(5, /*fec_group=*/5u);
- }
-
- // Send one unprotected data packet.
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- consumed = generator_.ConsumeData(7, CreateData(1u), 0, true, MAY_FEC_PROTECT,
- nullptr);
- EXPECT_EQ(1u, consumed.bytes_consumed);
- EXPECT_FALSE(generator_.HasQueuedFrames());
- EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
- // Verify that one unprotected data packet was sent.
- if (generator_.fec_send_policy() == FEC_ALARM_TRIGGER) {
- CheckPacketContains(contents, 5);
- } else {
- CheckPacketContains(contents, 6);
- }
-}
-
-TEST_P(QuicPacketGeneratorTest, SwitchFecOnWithPendingFrameInCreator) {
- delegate_.SetCanWriteAnything();
- // Enable FEC.
- creator_->set_max_packets_per_fec_group(2);
-
- generator_.StartBatchOperations();
- // Queue enough data to prevent a stream frame with a non-zero offset from
- // fitting.
- QuicConsumedData consumed = generator_.ConsumeData(7, CreateData(1u), 0, true,
- MAY_FEC_PROTECT, nullptr);
- EXPECT_EQ(1u, consumed.bytes_consumed);
- EXPECT_TRUE(creator_->HasPendingFrames());
-
- // Queue protected data for sending. Should cause queued frames to be flushed.
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
- consumed = generator_.ConsumeData(7, CreateData(1u), 0, true,
- MUST_FEC_PROTECT, nullptr);
- EXPECT_EQ(1u, consumed.bytes_consumed);
- PacketContents contents;
- contents.num_stream_frames = 1;
- // Transmitted packet was not FEC protected.
- CheckPacketContains(contents, 0);
- EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(creator_));
- EXPECT_TRUE(creator_->HasPendingFrames());
-}
-
-TEST_P(QuicPacketGeneratorTest, SwitchFecOnWithPendingFramesInGenerator) {
- // Enable FEC.
- creator_->set_max_packets_per_fec_group(2);
-
- // Queue control frames in generator.
- delegate_.SetCanNotWrite();
- generator_.SetShouldSendAck(true);
- delegate_.SetCanWriteAnything();
- generator_.StartBatchOperations();
-
- // Set up frames to write into the creator when control frames are written.
- EXPECT_CALL(delegate_, PopulateAckFrame(_));
- EXPECT_CALL(delegate_, PopulateStopWaitingFrame(_));
-
- // Generator should have queued control frames, and creator should be empty.
- EXPECT_TRUE(generator_.HasQueuedFrames());
- EXPECT_FALSE(creator_->HasPendingFrames());
- EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
-
- // Queue protected data for sending. Should cause queued frames to be flushed.
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- QuicConsumedData consumed = generator_.ConsumeData(7, CreateData(1u), 0, true,
- MUST_FEC_PROTECT, nullptr);
- EXPECT_EQ(1u, consumed.bytes_consumed);
- PacketContents contents;
- contents.num_ack_frames = 1;
- contents.num_stop_waiting_frames = 1;
- CheckPacketContains(contents, 0);
-
- // FEC protection should be on in creator.
- EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(creator_));
-}
-
-TEST_P(QuicPacketGeneratorTest, SwitchFecOnOffWithSubsequentFramesProtected) {
- delegate_.SetCanWriteAnything();
-
- // Enable FEC.
- creator_->set_max_packets_per_fec_group(2);
- EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
-
- // Queue stream frame to be protected in creator.
- generator_.StartBatchOperations();
- QuicConsumedData consumed = generator_.ConsumeData(5, CreateData(1u), 0, true,
- MUST_FEC_PROTECT, nullptr);
- EXPECT_EQ(1u, consumed.bytes_consumed);
- // Creator has a pending protected frame.
- EXPECT_TRUE(creator_->HasPendingFrames());
- EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(creator_));
-
- // Add enough unprotected data to exceed size of current packet, so that
- // current packet is sent. Both frames will be sent out in a single packet.
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- size_t data_len = kDefaultMaxPacketSize;
- consumed = generator_.ConsumeData(5, CreateData(data_len), 0, true,
- MAY_FEC_PROTECT, nullptr);
- EXPECT_EQ(data_len, consumed.bytes_consumed);
- PacketContents contents;
- contents.num_stream_frames = 2u;
- contents.fec_group = 1u;
- CheckPacketContains(contents, 0);
- // FEC protection should still be on in creator.
- EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(creator_));
-}
-
-TEST_P(QuicPacketGeneratorTest, SwitchFecOnOffWithSubsequentPacketsProtected) {
- delegate_.SetCanWriteAnything();
-
- // Enable FEC.
- creator_->set_max_packets_per_fec_group(2);
- EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
-
- // Send first packet, FEC protected.
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- QuicConsumedData consumed = generator_.ConsumeData(5, CreateData(1u), 0, true,
- MUST_FEC_PROTECT, nullptr);
- EXPECT_EQ(1u, consumed.bytes_consumed);
- PacketContents contents;
- contents.num_stream_frames = 1u;
- contents.fec_group = 1u;
- CheckPacketContains(contents, 0);
-
- // FEC should still be on in creator.
- EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(creator_));
-
- // Send unprotected data to cause second packet to be sent, which gets
- // protected because it happens to fall within an open FEC group. Data packet
- // will be followed by FEC packet.
- {
- InSequence dummy;
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- if (generator_.fec_send_policy() == FEC_ALARM_TRIGGER) {
- EXPECT_CALL(delegate_, OnResetFecGroup()).Times(1);
- } else {
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- }
- }
- consumed = generator_.ConsumeData(5, CreateData(1u), 0, true, MAY_FEC_PROTECT,
- nullptr);
- EXPECT_EQ(1u, consumed.bytes_consumed);
- contents.num_stream_frames = 1u;
- CheckPacketContains(contents, 1);
- if (generator_.fec_send_policy() == FEC_ANY_TRIGGER) {
- // FEC packet is sent when send policy is FEC_ANY_TRIGGER.
- CheckPacketIsFec(2, /*fec_group=*/1u);
- }
-
- // FEC protection should be off in creator.
- EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
-}
-
-TEST_P(QuicPacketGeneratorTest, SwitchFecOnOffThenOnWithCreatorProtectionOn) {
- delegate_.SetCanWriteAnything();
- generator_.StartBatchOperations();
-
- // Enable FEC.
- creator_->set_max_packets_per_fec_group(2);
- EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
-
- // Queue one byte of FEC protected data.
- QuicConsumedData consumed = generator_.ConsumeData(5, CreateData(1u), 0, true,
- MUST_FEC_PROTECT, nullptr);
- EXPECT_TRUE(creator_->HasPendingFrames());
-
- // Add more unprotected data causing first packet to be sent, FEC protected.
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- size_t data_len = kDefaultMaxPacketSize;
- consumed = generator_.ConsumeData(5, CreateData(data_len), 0, true,
- MAY_FEC_PROTECT, nullptr);
- EXPECT_EQ(data_len, consumed.bytes_consumed);
- PacketContents contents;
- contents.num_stream_frames = 2u;
- contents.fec_group = 1u;
- CheckPacketContains(contents, 0);
-
- // FEC group is still open in creator.
- EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(creator_));
-
- // Add data that should be protected, large enough to cause second packet to
- // be sent. Data packet should be followed by FEC packet.
- {
- InSequence dummy;
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- if (generator_.fec_send_policy() == FEC_ALARM_TRIGGER) {
- EXPECT_CALL(delegate_, OnResetFecGroup()).Times(1);
- } else {
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- }
- }
- consumed = generator_.ConsumeData(5, CreateData(data_len), 0, true,
- MUST_FEC_PROTECT, nullptr);
- EXPECT_EQ(data_len, consumed.bytes_consumed);
- CheckPacketContains(contents, 1);
- if (generator_.fec_send_policy() == FEC_ANY_TRIGGER) {
- // FEC packet is sent when send policy is FEC_ANY_TRIGGER.
- CheckPacketIsFec(2, /*fec_group=*/1u);
- }
-
- // FEC protection should remain on in creator.
- EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(creator_));
-}
-
-TEST_P(QuicPacketGeneratorTest, ResetFecGroupNoTimeout) {
- delegate_.SetCanWriteAnything();
- // Send FEC packet after 2 packets.
- creator_->set_max_packets_per_fec_group(2);
- EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
-
- // Send two packets so that when this data is consumed, two packets are sent
- // out. In FEC_TRIGGER_ANY, this will cause an FEC packet to be sent out and
- // with FEC_TRIGGER_ALARM, this will cause a Reset to be called. In both
- // cases, the creator's fec protection will be turned off afterwards.
- {
- InSequence dummy;
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- if (generator_.fec_send_policy() == FEC_ALARM_TRIGGER) {
- // FEC packet is not sent when send policy is FEC_ALARM_TRIGGER, but FEC
- // group is closed.
- EXPECT_CALL(delegate_, OnResetFecGroup()).Times(1);
- } else {
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- }
- // Fin Packet.
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- }
- size_t data_len = 2 * kDefaultMaxPacketSize;
- QuicConsumedData consumed = generator_.ConsumeData(
- 5, CreateData(data_len), 0, true, MUST_FEC_PROTECT, nullptr);
- EXPECT_EQ(data_len, consumed.bytes_consumed);
- EXPECT_TRUE(consumed.fin_consumed);
- EXPECT_FALSE(generator_.HasQueuedFrames());
- CheckPacketHasSingleStreamFrame(0);
- CheckPacketHasSingleStreamFrame(1);
- if (generator_.fec_send_policy() == FEC_ALARM_TRIGGER) {
- // FEC packet is not sent when send policy is FEC_ALARM_TRIGGER.
- CheckPacketHasSingleStreamFrame(2);
- } else {
- // FEC packet is sent after 2 packets and when send policy is
- // FEC_ANY_TRIGGER.
- CheckPacketIsFec(2, 1);
- CheckPacketHasSingleStreamFrame(3);
- }
- EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(creator_));
-
- // Do the same send (with MUST_FEC_PROTECT) on a different stream id.
- {
- InSequence dummy;
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- // FEC packet is sent after 2 packets and when send policy is
- // FEC_ANY_TRIGGER. When policy is FEC_ALARM_TRIGGER, FEC group is closed
- // and FEC packet is not sent.
- if (generator_.fec_send_policy() == FEC_ALARM_TRIGGER) {
- EXPECT_CALL(delegate_, OnResetFecGroup()).Times(1);
- } else {
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- }
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- // FEC packet is sent after 2 packets and when send policy is
- // FEC_ANY_TRIGGER. When policy is FEC_ALARM_TRIGGER, FEC group is closed
- // and FEC packet is not sent.
- if (generator_.fec_send_policy() == FEC_ALARM_TRIGGER) {
- EXPECT_CALL(delegate_, OnResetFecGroup()).Times(1);
- } else {
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- }
- }
- consumed = generator_.ConsumeData(7, CreateData(data_len), 0, true,
- MUST_FEC_PROTECT, nullptr);
- EXPECT_EQ(data_len, consumed.bytes_consumed);
- EXPECT_TRUE(consumed.fin_consumed);
- EXPECT_FALSE(generator_.HasQueuedFrames());
- if (generator_.fec_send_policy() == FEC_ALARM_TRIGGER) {
- CheckPacketHasSingleStreamFrame(3);
- CheckPacketHasSingleStreamFrame(4);
- CheckPacketHasSingleStreamFrame(5);
- } else {
- CheckPacketHasSingleStreamFrame(4);
- // FEC packet is sent after 2 packets and when send policy is
- // FEC_ANY_TRIGGER.
- CheckPacketIsFec(5, 4);
- CheckPacketHasSingleStreamFrame(6);
- CheckPacketHasSingleStreamFrame(7);
- // FEC packet is sent after 2 packets and when send policy is
- // FEC_ANY_TRIGGER.
- CheckPacketIsFec(8, 7);
- }
- EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
-
- // Do the another send (with MAY_FEC_PROTECT) on a different stream id, which
- // should not produce an FEC packet because the last FEC group has been
- // closed.
- {
- InSequence dummy;
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- }
- consumed = generator_.ConsumeData(9, CreateData(data_len), 0, true,
- MAY_FEC_PROTECT, nullptr);
- EXPECT_EQ(data_len, consumed.bytes_consumed);
- EXPECT_TRUE(consumed.fin_consumed);
- EXPECT_FALSE(generator_.HasQueuedFrames());
- if (generator_.fec_send_policy() == FEC_ALARM_TRIGGER) {
- CheckPacketHasSingleStreamFrame(6);
- CheckPacketHasSingleStreamFrame(7);
- CheckPacketHasSingleStreamFrame(8);
- } else {
- CheckPacketHasSingleStreamFrame(9);
- CheckPacketHasSingleStreamFrame(10);
- CheckPacketHasSingleStreamFrame(11);
- }
- EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
-}
-
-// 1. Create and send one packet with MUST_FEC_PROTECT.
-// 2. Call FecTimeout, expect FEC packet is sent.
-// 3. Do the same thing over again, with a different stream id.
-TEST_P(QuicPacketGeneratorTest, FecPacketSentOnFecTimeout) {
- delegate_.SetCanWriteAnything();
- creator_->set_max_packets_per_fec_group(1000);
- EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
-
- for (int i = 1; i < 4; i = i + 2) {
- // Send data with MUST_FEC_PROTECT flag. No FEC packet is emitted, but the
- // creator FEC protects all data.
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- QuicConsumedData consumed = generator_.ConsumeData(
- i + 2, CreateData(1u), 0, true, MUST_FEC_PROTECT, nullptr);
- EXPECT_EQ(1u, consumed.bytes_consumed);
- EXPECT_TRUE(consumed.fin_consumed);
- CheckPacketHasSingleStreamFrame(0);
- EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(creator_));
-
- // Calling OnFecTimeout should cause the FEC packet to be emitted.
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- generator_.OnFecTimeout();
- CheckPacketIsFec(i, i);
- EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
- }
-}
-
-TEST_P(QuicPacketGeneratorTest, NotWritableThenBatchOperations) {
+TEST_F(QuicPacketGeneratorTest, NotWritableThenBatchOperations) {
delegate_.SetCanNotWrite();
generator_.SetShouldSendAck(false);
@@ -1302,8 +499,7 @@ TEST_P(QuicPacketGeneratorTest, NotWritableThenBatchOperations) {
EXPECT_CALL(delegate_, PopulateAckFrame(_));
// Send some data and a control frame
- generator_.ConsumeData(3, MakeIOVector("quux"), 7, false, MAY_FEC_PROTECT,
- nullptr);
+ generator_.ConsumeData(3, MakeIOVector("quux"), 7, false, nullptr);
generator_.AddControlFrame(QuicFrame(CreateGoAwayFrame()));
// All five frames will be flushed out in a single packet.
@@ -1320,7 +516,7 @@ TEST_P(QuicPacketGeneratorTest, NotWritableThenBatchOperations) {
CheckPacketContains(contents, 0);
}
-TEST_P(QuicPacketGeneratorTest, NotWritableThenBatchOperations2) {
+TEST_F(QuicPacketGeneratorTest, NotWritableThenBatchOperations2) {
delegate_.SetCanNotWrite();
generator_.SetShouldSendAck(false);
@@ -1345,8 +541,8 @@ TEST_P(QuicPacketGeneratorTest, NotWritableThenBatchOperations2) {
// Send enough data to exceed one packet
size_t data_len = kDefaultMaxPacketSize + 100;
- QuicConsumedData consumed = generator_.ConsumeData(
- 3, CreateData(data_len), 0, true, MAY_FEC_PROTECT, nullptr);
+ QuicConsumedData consumed =
+ generator_.ConsumeData(3, CreateData(data_len), 0, true, nullptr);
EXPECT_EQ(data_len, consumed.bytes_consumed);
EXPECT_TRUE(consumed.fin_consumed);
generator_.AddControlFrame(QuicFrame(CreateGoAwayFrame()));
@@ -1368,7 +564,7 @@ TEST_P(QuicPacketGeneratorTest, NotWritableThenBatchOperations2) {
CheckPacketContains(contents2, 1);
}
-TEST_P(QuicPacketGeneratorTest, TestConnectionIdLength) {
+TEST_F(QuicPacketGeneratorTest, TestConnectionIdLength) {
generator_.SetConnectionIdLength(0);
EXPECT_EQ(PACKET_0BYTE_CONNECTION_ID, creator_->connection_id_length());
generator_.SetConnectionIdLength(1);
@@ -1393,14 +589,14 @@ TEST_P(QuicPacketGeneratorTest, TestConnectionIdLength) {
// Test whether SetMaxPacketLength() works in the situation when the queue is
// empty, and we send three packets worth of data.
-TEST_P(QuicPacketGeneratorTest, SetMaxPacketLength_Initial) {
+TEST_F(QuicPacketGeneratorTest, SetMaxPacketLength_Initial) {
delegate_.SetCanWriteAnything();
// Send enough data for three packets.
size_t data_len = 3 * kDefaultMaxPacketSize + 1;
size_t packet_len = kDefaultMaxPacketSize + 100;
ASSERT_LE(packet_len, kMaxPacketSize);
- generator_.SetMaxPacketLength(packet_len, /*force=*/false);
+ generator_.SetMaxPacketLength(packet_len);
EXPECT_EQ(packet_len, generator_.GetCurrentMaxPacketLength());
EXPECT_CALL(delegate_, OnSerializedPacket(_))
@@ -1409,7 +605,7 @@ TEST_P(QuicPacketGeneratorTest, SetMaxPacketLength_Initial) {
QuicConsumedData consumed =
generator_.ConsumeData(kHeadersStreamId, CreateData(data_len),
/*offset=*/2,
- /*fin=*/true, MAY_FEC_PROTECT, nullptr);
+ /*fin=*/true, nullptr);
EXPECT_EQ(data_len, consumed.bytes_consumed);
EXPECT_TRUE(consumed.fin_consumed);
EXPECT_FALSE(generator_.HasQueuedFrames());
@@ -1426,7 +622,7 @@ TEST_P(QuicPacketGeneratorTest, SetMaxPacketLength_Initial) {
// Test whether SetMaxPacketLength() works in the situation when we first write
// data, then change packet size, then write data again.
-TEST_P(QuicPacketGeneratorTest, SetMaxPacketLength_Middle) {
+TEST_F(QuicPacketGeneratorTest, SetMaxPacketLength_Middle) {
delegate_.SetCanWriteAnything();
// We send enough data to overflow default packet length, but not the altered
@@ -1444,7 +640,7 @@ TEST_P(QuicPacketGeneratorTest, SetMaxPacketLength_Middle) {
QuicConsumedData consumed =
generator_.ConsumeData(kHeadersStreamId, CreateData(data_len),
/*offset=*/2,
- /*fin=*/false, MAY_FEC_PROTECT, nullptr);
+ /*fin=*/false, nullptr);
EXPECT_EQ(data_len, consumed.bytes_consumed);
EXPECT_FALSE(consumed.fin_consumed);
EXPECT_FALSE(generator_.HasQueuedFrames());
@@ -1453,13 +649,13 @@ TEST_P(QuicPacketGeneratorTest, SetMaxPacketLength_Middle) {
ASSERT_EQ(2u, packets_.size());
// Increase packet size.
- generator_.SetMaxPacketLength(packet_len, /*force=*/false);
+ generator_.SetMaxPacketLength(packet_len);
EXPECT_EQ(packet_len, generator_.GetCurrentMaxPacketLength());
// Send a packet after packet size change.
consumed = generator_.ConsumeData(kHeadersStreamId, CreateData(data_len),
2 + data_len,
- /*fin=*/true, MAY_FEC_PROTECT, nullptr);
+ /*fin=*/true, nullptr);
EXPECT_EQ(data_len, consumed.bytes_consumed);
EXPECT_TRUE(consumed.fin_consumed);
EXPECT_FALSE(generator_.HasQueuedFrames());
@@ -1472,63 +668,9 @@ TEST_P(QuicPacketGeneratorTest, SetMaxPacketLength_Middle) {
CheckAllPacketsHaveSingleStreamFrame();
}
-// Test whether SetMaxPacketLength() works correctly when we change the packet
-// size in the middle of the batched packet.
-TEST_P(QuicPacketGeneratorTest, SetMaxPacketLength_Midpacket) {
- delegate_.SetCanWriteAnything();
- generator_.StartBatchOperations();
-
- size_t first_write_len = kDefaultMaxPacketSize / 2;
- size_t second_write_len = kDefaultMaxPacketSize;
- size_t packet_len = kDefaultMaxPacketSize + 100;
- ASSERT_LE(packet_len, kMaxPacketSize);
-
- // First send half of the packet worth of data. We are in the batch mode, so
- // should not cause packet serialization.
- QuicConsumedData consumed =
- generator_.ConsumeData(kHeadersStreamId, CreateData(first_write_len),
- /*offset=*/2,
- /*fin=*/false, MAY_FEC_PROTECT, nullptr);
- EXPECT_EQ(first_write_len, consumed.bytes_consumed);
- EXPECT_FALSE(consumed.fin_consumed);
- EXPECT_TRUE(generator_.HasQueuedFrames());
-
- // Make sure we have no packets so far.
- ASSERT_EQ(0u, packets_.size());
-
- // Increase packet size. Ensure it's not immediately enacted.
- generator_.SetMaxPacketLength(packet_len, /*force=*/false);
- EXPECT_EQ(packet_len, generator_.GetMaxPacketLength());
- EXPECT_EQ(kDefaultMaxPacketSize, generator_.GetCurrentMaxPacketLength());
-
- // We expect to see exactly one packet serialized after that, since we are in
- // batch mode and we have sent approximately 3/2 of our MTU.
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
-
- // Send a packet worth of data to the same stream. This should trigger
- // serialization of other packet.
- consumed =
- generator_.ConsumeData(kHeadersStreamId, CreateData(second_write_len),
- /*offset=*/2 + first_write_len,
- /*fin=*/true, MAY_FEC_PROTECT, nullptr);
- EXPECT_EQ(second_write_len, consumed.bytes_consumed);
- EXPECT_TRUE(consumed.fin_consumed);
- EXPECT_TRUE(generator_.HasQueuedFrames());
-
- // We expect the first packet to contain two frames, and to not reflect the
- // packet size change.
- ASSERT_EQ(1u, packets_.size());
- EXPECT_EQ(kDefaultMaxPacketSize, packets_[0].encrypted_length);
-
- PacketContents contents;
- contents.num_stream_frames = 2;
- CheckPacketContains(contents, 0);
-}
-
// Test whether SetMaxPacketLength() works correctly when we force the change of
// the packet size in the middle of the batched packet.
-TEST_P(QuicPacketGeneratorTest, SetMaxPacketLength_MidpacketFlush) {
+TEST_F(QuicPacketGeneratorTest, SetMaxPacketLength_MidpacketFlush) {
delegate_.SetCanWriteAnything();
generator_.StartBatchOperations();
@@ -1542,7 +684,7 @@ TEST_P(QuicPacketGeneratorTest, SetMaxPacketLength_MidpacketFlush) {
QuicConsumedData consumed =
generator_.ConsumeData(kHeadersStreamId, CreateData(first_write_len),
/*offset=*/2,
- /*fin=*/false, MAY_FEC_PROTECT, nullptr);
+ /*fin=*/false, nullptr);
EXPECT_EQ(first_write_len, consumed.bytes_consumed);
EXPECT_FALSE(consumed.fin_consumed);
EXPECT_TRUE(generator_.HasQueuedFrames());
@@ -1554,9 +696,10 @@ TEST_P(QuicPacketGeneratorTest, SetMaxPacketLength_MidpacketFlush) {
EXPECT_CALL(delegate_, OnSerializedPacket(_))
.WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- // Increase packet size. Ensure it's immediately enacted.
- generator_.SetMaxPacketLength(packet_len, /*force=*/true);
- EXPECT_EQ(packet_len, generator_.GetMaxPacketLength());
+ // Increase packet size after flushing all frames.
+ // Ensure it's immediately enacted.
+ generator_.FlushAllQueuedFrames();
+ generator_.SetMaxPacketLength(packet_len);
EXPECT_EQ(packet_len, generator_.GetCurrentMaxPacketLength());
EXPECT_FALSE(generator_.HasQueuedFrames());
@@ -1571,7 +714,7 @@ TEST_P(QuicPacketGeneratorTest, SetMaxPacketLength_MidpacketFlush) {
consumed =
generator_.ConsumeData(kHeadersStreamId, CreateData(second_write_len),
/*offset=*/2 + first_write_len,
- /*fin=*/true, MAY_FEC_PROTECT, nullptr);
+ /*fin=*/true, nullptr);
EXPECT_EQ(second_write_len, consumed.bytes_consumed);
EXPECT_TRUE(consumed.fin_consumed);
EXPECT_TRUE(generator_.HasQueuedFrames());
@@ -1586,7 +729,7 @@ TEST_P(QuicPacketGeneratorTest, SetMaxPacketLength_MidpacketFlush) {
}
// Test sending an MTU probe, without any surrounding data.
-TEST_P(QuicPacketGeneratorTest, GenerateMtuDiscoveryPacket_Simple) {
+TEST_F(QuicPacketGeneratorTest, GenerateMtuDiscoveryPacket_Simple) {
delegate_.SetCanWriteAnything();
const size_t target_mtu = kDefaultMaxPacketSize + 100;
@@ -1609,7 +752,7 @@ TEST_P(QuicPacketGeneratorTest, GenerateMtuDiscoveryPacket_Simple) {
// Test sending an MTU probe. Surround it with data, to ensure that it resets
// the MTU to the value before the probe was sent.
-TEST_P(QuicPacketGeneratorTest, GenerateMtuDiscoveryPacket_SurroundedByData) {
+TEST_F(QuicPacketGeneratorTest, GenerateMtuDiscoveryPacket_SurroundedByData) {
delegate_.SetCanWriteAnything();
const size_t target_mtu = kDefaultMaxPacketSize + 100;
@@ -1629,7 +772,7 @@ TEST_P(QuicPacketGeneratorTest, GenerateMtuDiscoveryPacket_SurroundedByData) {
QuicConsumedData consumed =
generator_.ConsumeData(kHeadersStreamId, CreateData(data_len),
/*offset=*/2,
- /*fin=*/false, MAY_FEC_PROTECT, nullptr);
+ /*fin=*/false, nullptr);
EXPECT_EQ(data_len, consumed.bytes_consumed);
EXPECT_FALSE(consumed.fin_consumed);
EXPECT_FALSE(generator_.HasQueuedFrames());
@@ -1641,7 +784,7 @@ TEST_P(QuicPacketGeneratorTest, GenerateMtuDiscoveryPacket_SurroundedByData) {
// Send data after the MTU probe.
consumed = generator_.ConsumeData(kHeadersStreamId, CreateData(data_len),
/*offset=*/2 + data_len,
- /*fin=*/true, MAY_FEC_PROTECT, nullptr);
+ /*fin=*/true, nullptr);
EXPECT_EQ(data_len, consumed.bytes_consumed);
EXPECT_TRUE(consumed.fin_consumed);
EXPECT_FALSE(generator_.HasQueuedFrames());
@@ -1661,7 +804,7 @@ TEST_P(QuicPacketGeneratorTest, GenerateMtuDiscoveryPacket_SurroundedByData) {
CheckPacketHasSingleStreamFrame(4);
}
-TEST_P(QuicPacketGeneratorTest, DontCrashOnInvalidStopWaiting) {
+TEST_F(QuicPacketGeneratorTest, DontCrashOnInvalidStopWaiting) {
// Test added to ensure the generator does not crash when an invalid frame is
// added. Because this is an indication of internal programming errors,
// DFATALs are expected.
@@ -1689,12 +832,12 @@ TEST_P(QuicPacketGeneratorTest, DontCrashOnInvalidStopWaiting) {
"for least_unacked_delta: 1001");
}
-TEST_P(QuicPacketGeneratorTest, SetCurrentPath) {
+TEST_F(QuicPacketGeneratorTest, SetCurrentPath) {
delegate_.SetCanWriteAnything();
generator_.StartBatchOperations();
QuicConsumedData consumed = generator_.ConsumeData(
- kHeadersStreamId, MakeIOVector("foo"), 2, true, MAY_FEC_PROTECT, nullptr);
+ kHeadersStreamId, MakeIOVector("foo"), 2, true, nullptr);
EXPECT_EQ(3u, consumed.bytes_consumed);
EXPECT_TRUE(consumed.fin_consumed);
EXPECT_TRUE(generator_.HasQueuedFrames());
diff --git a/net/quic/quic_protocol.cc b/net/quic/quic_protocol.cc
index 7de88d7..d41f8f9 100644
--- a/net/quic/quic_protocol.cc
+++ b/net/quic/quic_protocol.cc
@@ -19,41 +19,33 @@ namespace net {
const char* const kFinalOffsetHeaderKey = ":final-offset";
size_t GetPacketHeaderSize(const QuicPacketHeader& header) {
- return GetPacketHeaderSize(
- header.public_header.connection_id_length,
- header.public_header.version_flag, header.public_header.multipath_flag,
- header.public_header.packet_number_length, header.is_in_fec_group);
+ return GetPacketHeaderSize(header.public_header.connection_id_length,
+ header.public_header.version_flag,
+ header.public_header.multipath_flag,
+ header.public_header.packet_number_length);
}
size_t GetPacketHeaderSize(QuicConnectionIdLength connection_id_length,
bool include_version,
bool include_path_id,
- QuicPacketNumberLength packet_number_length,
- InFecGroup is_in_fec_group) {
+ QuicPacketNumberLength packet_number_length) {
return kPublicFlagsSize + connection_id_length +
(include_version ? kQuicVersionSize : 0) +
(include_path_id ? kQuicPathIdSize : 0) + packet_number_length +
- kPrivateFlagsSize +
- (is_in_fec_group == IN_FEC_GROUP ? kFecGroupSize : 0);
+ kPrivateFlagsSize;
}
-size_t GetStartOfFecProtectedData(QuicConnectionIdLength connection_id_length,
- bool include_version,
- bool include_path_id,
- QuicPacketNumberLength packet_number_length) {
- return GetPacketHeaderSize(connection_id_length, include_version,
- include_path_id, packet_number_length,
- IN_FEC_GROUP);
+size_t GetStartOfEncryptedData(const QuicPacketHeader& header) {
+ return GetPacketHeaderSize(header) - kPrivateFlagsSize;
}
size_t GetStartOfEncryptedData(QuicConnectionIdLength connection_id_length,
bool include_version,
bool include_path_id,
QuicPacketNumberLength packet_number_length) {
- // Don't include the fec size, since encryption starts before private flags.
+ // Encryption starts before private flags.
return GetPacketHeaderSize(connection_id_length, include_version,
- include_path_id, packet_number_length,
- NOT_IN_FEC_GROUP) -
+ include_path_id, packet_number_length) -
kPrivateFlagsSize;
}
@@ -296,8 +288,7 @@ QuicAckFrame::QuicAckFrame()
entropy_hash(0),
is_truncated(false),
largest_observed(0),
- ack_delay_time(QuicTime::Delta::Infinite()),
- latest_revived_packet(0) {}
+ ack_delay_time(QuicTime::Delta::Infinite()) {}
QuicAckFrame::QuicAckFrame(const QuicAckFrame& other) = default;
@@ -533,7 +524,6 @@ ostream& operator<<(ostream& os, const QuicAckFrame& ack_frame) {
<< " ack_delay_time: " << ack_frame.ack_delay_time.ToMicroseconds()
<< " missing_packets: [ " << ack_frame.missing_packets
<< " ] is_truncated: " << ack_frame.is_truncated
- << " revived_packet: " << ack_frame.latest_revived_packet
<< " received_packets: [ ";
for (const std::pair<QuicPacketNumber, QuicTime>& p :
ack_frame.received_packet_times) {
@@ -702,13 +692,6 @@ QuicEncryptedPacket::QuicEncryptedPacket(char* buffer,
bool owns_buffer)
: QuicData(buffer, length, owns_buffer) {}
-StringPiece QuicPacket::FecProtectedData() const {
- const size_t start_of_fec =
- GetStartOfFecProtectedData(connection_id_length_, includes_version_,
- includes_path_id_, packet_number_length_);
- return StringPiece(data() + start_of_fec, length() - start_of_fec);
-}
-
StringPiece QuicPacket::AssociatedData() const {
return StringPiece(data(), GetStartOfEncryptedData(
connection_id_length_, includes_version_,
@@ -751,7 +734,6 @@ SerializedPacket::SerializedPacket(QuicPathId path_id,
packet_number_length(packet_number_length),
encryption_level(ENCRYPTION_NONE),
entropy_hash(entropy_hash),
- is_fec_packet(false),
has_ack(has_ack),
has_stop_waiting(has_stop_waiting),
original_packet_number(0),
@@ -781,7 +763,6 @@ TransmissionInfo::TransmissionInfo()
transmission_type(NOT_RETRANSMISSION),
in_flight(false),
is_unackable(false),
- is_fec_packet(false),
has_crypto_handshake(false),
needs_padding(false),
retransmission(0) {}
@@ -791,7 +772,6 @@ TransmissionInfo::TransmissionInfo(EncryptionLevel level,
TransmissionType transmission_type,
QuicTime sent_time,
QuicPacketLength bytes_sent,
- bool is_fec_packet,
bool has_crypto_handshake,
bool needs_padding)
: encryption_level(level),
@@ -802,7 +782,6 @@ TransmissionInfo::TransmissionInfo(EncryptionLevel level,
transmission_type(transmission_type),
in_flight(false),
is_unackable(false),
- is_fec_packet(is_fec_packet),
has_crypto_handshake(has_crypto_handshake),
needs_padding(needs_padding),
retransmission(0) {}
diff --git a/net/quic/quic_protocol.h b/net/quic/quic_protocol.h
index 1b275cb..25fa411 100644
--- a/net/quic/quic_protocol.h
+++ b/net/quic/quic_protocol.h
@@ -140,6 +140,9 @@ NET_EXPORT_PRIVATE extern const char* const kFinalOffsetHeaderKey;
// Maximum delayed ack time, in ms.
const int64_t kMaxDelayedAckTimeMs = 25;
+// Minimum tail loss probe time in ms.
+static const int64_t kMinTailLossProbeTimeoutMs = 10;
+
// The timeout before the handshake succeeds.
const int64_t kInitialIdleTimeoutSecs = 5;
// The default idle timeout.
@@ -234,26 +237,6 @@ enum class ConnectionCloseSource { FROM_PEER, FROM_SELF };
NET_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
const Perspective& s);
-// Indicates FEC protection level for data being written.
-enum FecProtection {
- MUST_FEC_PROTECT, // Callee must FEC protect this data.
- MAY_FEC_PROTECT // Callee does not have to but may FEC protect this data.
-};
-
-// Indicates FEC policy.
-enum FecPolicy {
- FEC_PROTECT_ALWAYS, // All data in the stream should be FEC protected.
- FEC_PROTECT_OPTIONAL // Data in the stream does not need FEC protection.
-};
-
-// Indicates FEC policy about when to send FEC packet.
-enum FecSendPolicy {
- // Send FEC packet when FEC group is full or when FEC alarm goes off.
- FEC_ANY_TRIGGER,
- // Send FEC packet only when FEC alarm goes off.
- FEC_ALARM_TRIGGER
-};
-
enum QuicFrameType {
// Regular frame types. The values set here cannot change without the
// introduction of a new QUIC version.
@@ -426,24 +409,19 @@ NET_EXPORT_PRIVATE QuicTag MakeQuicTag(char a, char b, char c, char d);
NET_EXPORT_PRIVATE bool ContainsQuicTag(const QuicTagVector& tag_vector,
QuicTag tag);
-// Size in bytes of the data or fec packet header.
+// Size in bytes of the data packet header.
NET_EXPORT_PRIVATE size_t GetPacketHeaderSize(const QuicPacketHeader& header);
NET_EXPORT_PRIVATE size_t
GetPacketHeaderSize(QuicConnectionIdLength connection_id_length,
bool include_version,
bool include_path_id,
- QuicPacketNumberLength packet_number_length,
- InFecGroup is_in_fec_group);
+ QuicPacketNumberLength packet_number_length);
-// Index of the first byte in a QUIC packet of FEC protected data.
+// Index of the first byte in a QUIC packet of encrypted data.
NET_EXPORT_PRIVATE size_t
-GetStartOfFecProtectedData(QuicConnectionIdLength connection_id_length,
- bool include_version,
- bool include_path_id,
- QuicPacketNumberLength packet_number_length);
+GetStartOfEncryptedData(const QuicPacketHeader& header);
-// Index of the first byte in a QUIC packet of encrypted data.
NET_EXPORT_PRIVATE size_t
GetStartOfEncryptedData(QuicConnectionIdLength connection_id_length,
bool include_version,
@@ -709,7 +687,7 @@ struct NET_EXPORT_PRIVATE QuicPacketPublicHeader {
// An integer which cannot be a packet number.
const QuicPacketNumber kInvalidPacketNumber = 0;
-// Header for Data or FEC packets.
+// Header for Data packets.
struct NET_EXPORT_PRIVATE QuicPacketHeader {
QuicPacketHeader();
explicit QuicPacketHeader(const QuicPacketPublicHeader& header);
@@ -998,10 +976,6 @@ struct NET_EXPORT_PRIVATE QuicAckFrame {
// The set of packets which we're expecting and have not received.
PacketNumberQueue missing_packets;
-
- // Packet most recently revived via FEC, 0 if no packet was revived by FEC.
- // If non-zero, must be present in missing_packets.
- QuicPacketNumber latest_revived_packet;
};
// True if the packet number is greater than largest_observed or is listed
@@ -1235,7 +1209,6 @@ class NET_EXPORT_PRIVATE QuicPacket : public QuicData {
bool includes_path_id,
QuicPacketNumberLength packet_number_length);
- base::StringPiece FecProtectedData() const;
base::StringPiece AssociatedData() const;
base::StringPiece Plaintext() const;
@@ -1326,7 +1299,6 @@ struct NET_EXPORT_PRIVATE SerializedPacket {
QuicPacketNumberLength packet_number_length;
EncryptionLevel encryption_level;
QuicPacketEntropyHash entropy_hash;
- bool is_fec_packet;
bool has_ack;
bool has_stop_waiting;
QuicPacketNumber original_packet_number;
@@ -1347,7 +1319,6 @@ struct NET_EXPORT_PRIVATE TransmissionInfo {
TransmissionType transmission_type,
QuicTime sent_time,
QuicPacketLength bytes_sent,
- bool is_fec_packet,
bool has_crypto_handshake,
bool needs_padding);
@@ -1367,8 +1338,6 @@ struct NET_EXPORT_PRIVATE TransmissionInfo {
bool in_flight;
// True if the packet can never be acked, so it can be removed.
bool is_unackable;
- // True if the packet is an FEC packet.
- bool is_fec_packet;
// True if the packet contains stream data from the crypto stream.
bool has_crypto_handshake;
// True if the packet needs padding if it's retransmitted.
diff --git a/net/quic/quic_received_packet_manager.cc b/net/quic/quic_received_packet_manager.cc
index 984aa6f..aa3c9fd 100644
--- a/net/quic/quic_received_packet_manager.cc
+++ b/net/quic/quic_received_packet_manager.cc
@@ -178,18 +178,6 @@ void QuicReceivedPacketManager::RecordPacketReceived(
ack_frame_.received_packet_times.push_back(
std::make_pair(packet_number, receipt_time));
-
- if (ack_frame_.latest_revived_packet == packet_number) {
- ack_frame_.latest_revived_packet = 0;
- }
-}
-
-void QuicReceivedPacketManager::RecordPacketRevived(
- QuicPacketNumber packet_number) {
- QUIC_BUG_IF(!IsAwaitingPacket(packet_number)) << base::StringPrintf(
- "Not waiting for %llu", static_cast<unsigned long long>(packet_number));
- ack_frame_updated_ = true;
- ack_frame_.latest_revived_packet = packet_number;
}
bool QuicReceivedPacketManager::IsMissing(QuicPacketNumber packet_number) {
@@ -259,9 +247,6 @@ QuicPacketEntropyHash QuicReceivedPacketManager::EntropyHash(
bool QuicReceivedPacketManager::DontWaitForPacketsBefore(
QuicPacketNumber least_unacked) {
- if (ack_frame_.latest_revived_packet < least_unacked) {
- ack_frame_.latest_revived_packet = 0;
- }
return ack_frame_.missing_packets.RemoveUpTo(least_unacked);
}
@@ -287,6 +272,10 @@ void QuicReceivedPacketManager::UpdatePacketInformationSentByPeer(
ack_frame_.missing_packets.Min() >= peer_least_packet_awaiting_ack_);
}
+bool QuicReceivedPacketManager::HasMissingPackets() const {
+ return !ack_frame_.missing_packets.Empty();
+}
+
bool QuicReceivedPacketManager::HasNewMissingPackets() const {
return !ack_frame_.missing_packets.Empty() &&
(ack_frame_.largest_observed - ack_frame_.missing_packets.Max()) <=
diff --git a/net/quic/quic_received_packet_manager.h b/net/quic/quic_received_packet_manager.h
index 404f24f..173e47f 100644
--- a/net/quic/quic_received_packet_manager.h
+++ b/net/quic/quic_received_packet_manager.h
@@ -109,8 +109,6 @@ class NET_EXPORT_PRIVATE QuicReceivedPacketManager
const QuicPacketHeader& header,
QuicTime receipt_time);
- virtual void RecordPacketRevived(QuicPacketNumber packet_number);
-
// Checks whether |packet_number| is missing and less than largest observed.
virtual bool IsMissing(QuicPacketNumber packet_number);
@@ -131,6 +129,9 @@ class NET_EXPORT_PRIVATE QuicReceivedPacketManager
virtual void UpdatePacketInformationSentByPeer(
const QuicStopWaitingFrame& stop_waiting);
+ // Returns true if there are any missing packets.
+ bool HasMissingPackets() const;
+
// Returns true when there are new missing packets to be reported within 3
// packets of the largest observed.
virtual bool HasNewMissingPackets() const;
diff --git a/net/quic/quic_received_packet_manager_test.cc b/net/quic/quic_received_packet_manager_test.cc
index 4f2443c..535ddab 100644
--- a/net/quic/quic_received_packet_manager_test.cc
+++ b/net/quic/quic_received_packet_manager_test.cc
@@ -203,10 +203,6 @@ class QuicReceivedPacketManagerTest : public ::testing::Test {
received_manager_.RecordPacketReceived(0u, header, receipt_time);
}
- void RecordPacketRevived(QuicPacketNumber packet_number) {
- received_manager_.RecordPacketRevived(packet_number);
- }
-
QuicConnectionStats stats_;
QuicReceivedPacketManager received_manager_;
};
@@ -354,57 +350,6 @@ TEST_F(QuicReceivedPacketManagerTest, UpdateReceivedConnectionStats) {
EXPECT_EQ(1u, stats_.packets_reordered);
}
-TEST_F(QuicReceivedPacketManagerTest, RevivedPacket) {
- EXPECT_FALSE(received_manager_.ack_frame_updated());
- RecordPacketReceipt(1, 0);
- EXPECT_TRUE(received_manager_.ack_frame_updated());
- RecordPacketReceipt(3, 0);
- RecordPacketRevived(2);
-
- QuicAckFrame ack;
- received_manager_.UpdateReceivedPacketInfo(&ack, QuicTime::Zero());
- EXPECT_FALSE(received_manager_.ack_frame_updated());
- EXPECT_EQ(1u, ack.missing_packets.NumPacketsSlow());
- EXPECT_EQ(2u, ack.missing_packets.Min());
- EXPECT_EQ(2u, ack.latest_revived_packet);
-}
-
-TEST_F(QuicReceivedPacketManagerTest, PacketRevivedThenReceived) {
- EXPECT_FALSE(received_manager_.ack_frame_updated());
- RecordPacketReceipt(1, 0);
- EXPECT_TRUE(received_manager_.ack_frame_updated());
- RecordPacketReceipt(3, 0);
- RecordPacketRevived(2);
- RecordPacketReceipt(2, 0);
-
- QuicAckFrame ack;
- received_manager_.UpdateReceivedPacketInfo(&ack, QuicTime::Zero());
- EXPECT_TRUE(ack.missing_packets.Empty());
- EXPECT_EQ(0u, ack.latest_revived_packet);
-}
-
-TEST_F(QuicReceivedPacketManagerTest, RevivedPacketAckFrameUpdated) {
- EXPECT_FALSE(received_manager_.ack_frame_updated());
- RecordPacketReceipt(1, 0);
- RecordPacketReceipt(3, 0);
- EXPECT_TRUE(received_manager_.ack_frame_updated());
-
- QuicAckFrame ack;
- received_manager_.UpdateReceivedPacketInfo(&ack, QuicTime::Zero());
- EXPECT_FALSE(received_manager_.ack_frame_updated());
- EXPECT_EQ(1u, ack.missing_packets.NumPacketsSlow());
- EXPECT_EQ(2u, ack.missing_packets.Min());
- EXPECT_EQ(0u, ack.latest_revived_packet);
-
- RecordPacketRevived(2);
- EXPECT_TRUE(received_manager_.ack_frame_updated());
- received_manager_.UpdateReceivedPacketInfo(&ack, QuicTime::Zero());
- EXPECT_FALSE(received_manager_.ack_frame_updated());
- EXPECT_EQ(1u, ack.missing_packets.NumPacketsSlow());
- EXPECT_EQ(2u, ack.missing_packets.Min());
- EXPECT_EQ(2u, ack.latest_revived_packet);
-}
-
} // namespace
} // namespace test
} // namespace net
diff --git a/net/quic/quic_sent_packet_manager.cc b/net/quic/quic_sent_packet_manager.cc
index fbe446b..2bdd196 100644
--- a/net/quic/quic_sent_packet_manager.cc
+++ b/net/quic/quic_sent_packet_manager.cc
@@ -47,7 +47,6 @@ static const int64_t kMinHandshakeTimeoutMs = 10;
// Sends up to two tail loss probes before firing an RTO,
// per draft RFC draft-dukkipati-tcpm-tcp-loss-probe.
static const size_t kDefaultMaxTailLossProbes = 2;
-static const int64_t kMinTailLossProbeTimeoutMs = 10;
// Number of unpaced packets to send after quiescence.
static const size_t kInitialUnpacedBurst = 10;
@@ -322,12 +321,6 @@ void QuicSentPacketManager::HandleAckForSentPackets(
}
MarkPacketHandled(packet_number, &(*it), ack_delay_time);
}
-
- // Discard any retransmittable frames associated with revived packets.
- if (ack_frame.latest_revived_packet != 0) {
- MarkPacketNotRetransmittable(ack_frame.latest_revived_packet,
- ack_delay_time);
- }
}
bool QuicSentPacketManager::HasRetransmittableFrames(
@@ -346,9 +339,6 @@ void QuicSentPacketManager::RetransmitUnackedPackets(
(retransmission_type == ALL_UNACKED_RETRANSMISSION ||
it->encryption_level == ENCRYPTION_INITIAL)) {
MarkForRetransmission(packet_number, retransmission_type);
- } else if (it->is_fec_packet) {
- // Remove FEC packets from the packet map, since we can't retransmit them.
- unacked_packets_.RemoveFromInFlight(packet_number);
}
}
}
@@ -487,8 +477,6 @@ void QuicSentPacketManager::MarkPacketNotRetransmittable(
pending_retransmissions_.erase(newest_transmission);
}
- // The AckListener needs to be notified for revived packets,
- // since it indicates the packet arrived from the appliction's perspective.
unacked_packets_.NotifyAndClearListeners(newest_transmission, ack_delay_time);
unacked_packets_.RemoveRetransmittability(packet_number);
}
@@ -568,16 +556,10 @@ bool QuicSentPacketManager::OnPacketSent(
--pending_timer_transmission_count_;
}
- // Only track packets as in flight that the send algorithm wants us to track.
- // Since FEC packets should also be counted towards the congestion window,
- // consider them as retransmittable for the purposes of congestion control.
- HasRetransmittableData has_congestion_controlled_data =
- serialized_packet->is_fec_packet ? HAS_RETRANSMITTABLE_DATA
- : has_retransmittable_data;
// TODO(ianswett): Remove sent_time, because it's unused.
const bool in_flight = send_algorithm_->OnPacketSent(
sent_time, unacked_packets_.bytes_in_flight(), packet_number,
- serialized_packet->encrypted_length, has_congestion_controlled_data);
+ serialized_packet->encrypted_length, has_retransmittable_data);
unacked_packets_.AddSentPacket(serialized_packet, original_packet_number,
transmission_type, sent_time, in_flight);
@@ -733,8 +715,8 @@ void QuicSentPacketManager::InvokeLossDetection(QuicTime time) {
} else {
// Since we will not retransmit this, we need to remove it from
// unacked_packets_. This is either the current transmission of
- // a packet whose previous transmission has been acked, a packet that
- // has been TLP retransmitted, or an FEC packet.
+ // a packet whose previous transmission has been acked or a packet that
+ // has been TLP retransmitted.
unacked_packets_.RemoveFromInFlight(pair.first);
}
}
diff --git a/net/quic/quic_sent_packet_manager.h b/net/quic/quic_sent_packet_manager.h
index 15b12d6..af3b953 100644
--- a/net/quic/quic_sent_packet_manager.h
+++ b/net/quic/quic_sent_packet_manager.h
@@ -133,7 +133,7 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager {
// Processes the incoming ack.
void OnIncomingAck(const QuicAckFrame& ack_frame, QuicTime ack_receive_time);
- // Returns true if the non-FEC packet |packet_number| is unacked.
+ // Returns true if packet |packet_number| is unacked.
bool IsUnacked(QuicPacketNumber packet_number) const;
// Requests retransmission of all unacked packets of |retransmission_type|.
@@ -337,7 +337,10 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager {
QuicByteCount bytes_in_flight);
// Called when frames of |packet_number| has been received but the packet
- // itself has not been received by the peer (e.g., packet is revived by FEC).
+ // itself has not been received by the peer. Currently, this method is not
+ // used.
+ // TODO(fayang): Update the comment when multipath sent packet manager is
+ // landed.
// The packet needs no longer to be retransmitted, but the packet remains
// pending if it is and the congestion control does not consider the packet
// acked.
@@ -375,8 +378,8 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager {
// RTT measurement purposes.
void RemoveObsoletePackets();
- // Newly serialized retransmittable and fec packets are added to this map,
- // which contains owning pointers to any contained frames. If a packet is
+ // Newly serialized retransmittable packets are added to this map, which
+ // contains owning pointers to any contained frames. If a packet is
// retransmitted, this map will contain entries for both the old and the new
// packet. The old packet's retransmittable frames entry will be nullptr,
// while the new packet's entry will contain the frames to retransmit.
diff --git a/net/quic/quic_sent_packet_manager_test.cc b/net/quic/quic_sent_packet_manager_test.cc
index f8cfce7..76de6ed 100644
--- a/net/quic/quic_sent_packet_manager_test.cc
+++ b/net/quic/quic_sent_packet_manager_test.cc
@@ -206,14 +206,6 @@ class QuicSentPacketManagerTest : public ::testing::TestWithParam<bool> {
return packet;
}
- SerializedPacket CreateFecPacket(QuicPacketNumber packet_number) {
- SerializedPacket serialized(kDefaultPathId, packet_number,
- PACKET_6BYTE_PACKET_NUMBER, nullptr,
- kDefaultLength, 0u, false, false);
- serialized.is_fec_packet = true;
- return serialized;
- }
-
void SendDataPacket(QuicPacketNumber packet_number) {
EXPECT_CALL(*send_algorithm_,
OnPacketSent(_, BytesInFlight(), packet_number, _, _))
@@ -238,17 +230,6 @@ class QuicSentPacketManagerTest : public ::testing::TestWithParam<bool> {
HAS_RETRANSMITTABLE_DATA);
}
- void SendFecPacket(QuicPacketNumber packet_number) {
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, BytesInFlight(), packet_number, kDefaultLength,
- HAS_RETRANSMITTABLE_DATA))
- .Times(1)
- .WillOnce(Return(true));
- SerializedPacket packet(CreateFecPacket(packet_number));
- manager_.OnPacketSent(&packet, 0, clock_.Now(), NOT_RETRANSMISSION,
- NO_RETRANSMITTABLE_DATA);
- }
-
void SendAckPacket(QuicPacketNumber packet_number) {
EXPECT_CALL(*send_algorithm_,
OnPacketSent(_, BytesInFlight(), packet_number, kDefaultLength,
@@ -501,76 +482,6 @@ TEST_F(QuicSentPacketManagerTest, RetransmitTwiceThenAckFirst) {
EXPECT_EQ(2u, stats_.packets_spuriously_retransmitted);
}
-TEST_F(QuicSentPacketManagerTest, LoseButDontRetransmitRevivedPacket) {
- StrictMock<MockDebugDelegate> debug_delegate;
- manager_.set_debug_delegate(&debug_delegate);
-
- SendDataPacket(1);
- SendDataPacket(2);
- SendFecPacket(3);
- SendDataPacket(4);
-
- // Ack 2 and 3, and mark 1 as revived.
- QuicAckFrame ack_frame;
- ack_frame.largest_observed = 3;
- ack_frame.missing_packets.Add(1);
- ack_frame.latest_revived_packet = 1;
- QuicPacketNumber acked[] = {2, 3};
- ExpectAcksAndLosses(true, acked, arraysize(acked), nullptr, 0);
- manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
-
- EXPECT_FALSE(manager_.HasPendingRetransmissions());
- QuicPacketNumber unacked[] = {1, 4};
- VerifyUnackedPackets(unacked, arraysize(unacked));
- EXPECT_TRUE(QuicSentPacketManagerPeer::HasPendingPackets(&manager_));
- QuicPacketNumber retransmittable[] = {4};
- VerifyRetransmittablePackets(retransmittable, arraysize(retransmittable));
-
- // Ack the 4th packet and expect the 1st to be considered lost.
- if (FLAGS_quic_log_loss_event) {
- EXPECT_CALL(debug_delegate, OnPacketLoss(1, LOSS_RETRANSMISSION, _));
- }
- ack_frame.largest_observed = 4;
- ExpectAckAndLoss(true, 4, 1);
- manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
-
- EXPECT_FALSE(manager_.HasPendingRetransmissions());
- VerifyRetransmittablePackets(nullptr, 0);
-}
-
-TEST_F(QuicSentPacketManagerTest, MarkLostThenReviveAndDontRetransmitPacket) {
- SendDataPacket(1);
- SendDataPacket(2);
- SendDataPacket(3);
- SendDataPacket(4);
- SendFecPacket(5);
-
- // Ack 2, 3, and 4, and expect the 1st to be considered lost.
- QuicAckFrame ack_frame;
- ack_frame.largest_observed = 4;
- ack_frame.missing_packets.Add(1);
- QuicPacketNumber acked[] = {2, 3, 4};
- QuicPacketNumber lost[] = {1};
- ExpectAcksAndLosses(true, acked, arraysize(acked), lost, arraysize(lost));
- manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
-
- EXPECT_TRUE(manager_.HasPendingRetransmissions());
- QuicPacketNumber unacked[] = {1, 5};
- VerifyUnackedPackets(unacked, arraysize(unacked));
- QuicPacketNumber retransmittable[] = {1};
- VerifyRetransmittablePackets(retransmittable, arraysize(retransmittable));
-
- // Ack 5th packet (FEC) and revive 1st packet. 1st packet should now be
- // removed from pending retransmissions map.
- ack_frame.largest_observed = 5;
- ack_frame.latest_revived_packet = 1;
- ExpectAck(5);
- manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
-
- EXPECT_FALSE(manager_.HasPendingRetransmissions());
- VerifyRetransmittablePackets(nullptr, 0);
-}
-
TEST_F(QuicSentPacketManagerTest, AckPreviousTransmissionThenTruncatedAck) {
SendDataPacket(1);
RetransmitAndSendPacket(1, 2);
@@ -618,53 +529,6 @@ TEST_F(QuicSentPacketManagerTest, GetLeastUnackedUnacked) {
EXPECT_EQ(1u, manager_.GetLeastUnacked());
}
-TEST_F(QuicSentPacketManagerTest, GetLeastUnackedUnackedFec) {
- SendFecPacket(1);
- EXPECT_EQ(1u, manager_.GetLeastUnacked());
-}
-
-TEST_F(QuicSentPacketManagerTest, GetLeastUnackedAndDiscard) {
- VerifyUnackedPackets(nullptr, 0);
-
- SendFecPacket(1);
- EXPECT_EQ(1u, manager_.GetLeastUnacked());
-
- SendFecPacket(2);
- EXPECT_EQ(1u, manager_.GetLeastUnacked());
-
- SendFecPacket(3);
- EXPECT_EQ(1u, manager_.GetLeastUnacked());
-
- QuicPacketNumber unacked[] = {1, 2, 3};
- VerifyUnackedPackets(unacked, arraysize(unacked));
- VerifyRetransmittablePackets(nullptr, 0);
-
- // Ack 2, so there's an rtt update.
- ExpectAck(2);
- QuicAckFrame ack_frame;
- ack_frame.largest_observed = 2;
- ack_frame.missing_packets.Add(1);
- manager_.OnIncomingAck(ack_frame, clock_.Now());
-
- EXPECT_EQ(1u, manager_.GetLeastUnacked());
-}
-
-TEST_F(QuicSentPacketManagerTest, GetSentTime) {
- VerifyUnackedPackets(nullptr, 0);
-
- QuicTime sent_time = clock_.Now();
- SendFecPacket(1);
- QuicTime sent_time2 = clock_.Now();
- SendFecPacket(2);
- QuicPacketNumber unacked[] = {1, 2};
- VerifyUnackedPackets(unacked, arraysize(unacked));
- VerifyRetransmittablePackets(nullptr, 0);
-
- EXPECT_TRUE(manager_.HasUnackedPackets());
- EXPECT_EQ(sent_time, QuicSentPacketManagerPeer::GetSentTime(&manager_, 1));
- EXPECT_EQ(sent_time2, QuicSentPacketManagerPeer::GetSentTime(&manager_, 2));
-}
-
TEST_F(QuicSentPacketManagerTest, AckAckAndUpdateRtt) {
SendDataPacket(1);
SendAckPacket(2);
diff --git a/net/quic/quic_session.cc b/net/quic/quic_session.cc
index d8ec06c..1d880fe 100644
--- a/net/quic/quic_session.cc
+++ b/net/quic/quic_session.cc
@@ -239,16 +239,14 @@ QuicConsumedData QuicSession::WritevData(
QuicIOVector iov,
QuicStreamOffset offset,
bool fin,
- FecProtection fec_protection,
QuicAckListenerInterface* ack_notifier_delegate) {
- if (FLAGS_quic_block_unencrypted_writes && !IsEncryptionEstablished() &&
- id != kCryptoStreamId) {
+ if (!IsEncryptionEstablished() && id != kCryptoStreamId) {
// Do not let streams write without encryption. The calling stream will end
// up write blocked until OnCanWrite is next called.
return QuicConsumedData(0, false);
}
- QuicConsumedData data = connection_->SendStreamData(
- id, iov, offset, fin, fec_protection, ack_notifier_delegate);
+ QuicConsumedData data =
+ connection_->SendStreamData(id, iov, offset, fin, ack_notifier_delegate);
write_blocked_streams_.UpdateBytesForStream(id, data.bytes_consumed);
return data;
}
@@ -530,9 +528,7 @@ void QuicSession::OnCryptoHandshakeEvent(CryptoHandshakeEvent event) {
// to QuicSession since it is the glue.
case ENCRYPTION_FIRST_ESTABLISHED:
// Given any streams blocked by encryption a chance to write.
- if (FLAGS_quic_block_unencrypted_writes) {
- OnCanWrite();
- }
+ OnCanWrite();
break;
case ENCRYPTION_REESTABLISHED:
@@ -540,9 +536,7 @@ void QuicSession::OnCryptoHandshakeEvent(CryptoHandshakeEvent event) {
// decrypted by the peer.
connection_->RetransmitUnackedPackets(ALL_INITIAL_RETRANSMISSION);
// Given any streams blocked by encryption a chance to write.
- if (FLAGS_quic_block_unencrypted_writes) {
- OnCanWrite();
- }
+ OnCanWrite();
break;
case HANDSHAKE_CONFIRMED:
diff --git a/net/quic/quic_session.h b/net/quic/quic_session.h
index e0e3e809..988c000 100644
--- a/net/quic/quic_session.h
+++ b/net/quic/quic_session.h
@@ -94,10 +94,7 @@ class NET_EXPORT_PRIVATE QuicSession : public QuicConnectionVisitorInterface {
// Returns a pair with the number of bytes consumed from data, and a boolean
// indicating if the fin bit was consumed. This does not indicate the data
// has been sent on the wire: it may have been turned into a packet and queued
- // if the socket was unexpectedly blocked. |fec_protection| indicates if
- // data is to be FEC protected. Note that data that is sent immediately
- // following MUST_FEC_PROTECT data may get protected by falling within the
- // same FEC group.
+ // if the socket was unexpectedly blocked.
// If provided, |ack_notifier_delegate| will be registered to be notified when
// we have seen ACKs for all packets resulting from this call.
virtual QuicConsumedData WritevData(
@@ -105,7 +102,6 @@ class NET_EXPORT_PRIVATE QuicSession : public QuicConnectionVisitorInterface {
QuicIOVector iov,
QuicStreamOffset offset,
bool fin,
- FecProtection fec_protection,
QuicAckListenerInterface* ack_notifier_delegate);
// Called by streams when they want to close the stream in both directions.
diff --git a/net/quic/quic_session_test.cc b/net/quic/quic_session_test.cc
index a0da6b9..268b5d2 100644
--- a/net/quic/quic_session_test.cc
+++ b/net/quic/quic_session_test.cc
@@ -155,12 +155,11 @@ class TestSession : public QuicSpdySession {
QuicIOVector data,
QuicStreamOffset offset,
bool fin,
- FecProtection fec_protection,
QuicAckListenerInterface* ack_notifier_delegate) override {
QuicConsumedData consumed(data.total_length, fin);
if (!writev_consumes_all_data_) {
- consumed = QuicSession::WritevData(id, data, offset, fin, fec_protection,
- ack_notifier_delegate);
+ consumed =
+ QuicSession::WritevData(id, data, offset, fin, ack_notifier_delegate);
}
QuicSessionPeer::GetWriteBlockedStreams(this)->UpdateBytesForStream(
id, consumed.bytes_consumed);
@@ -173,8 +172,7 @@ class TestSession : public QuicSpdySession {
QuicConsumedData SendStreamData(QuicStreamId id) {
struct iovec iov;
- return WritevData(id, MakeIOVector("not empty", &iov), 0, true,
- MAY_FEC_PROTECT, nullptr);
+ return WritevData(id, MakeIOVector("not empty", &iov), 0, true, nullptr);
}
QuicConsumedData SendLargeFakeData(QuicStreamId id, int bytes) {
@@ -182,8 +180,7 @@ class TestSession : public QuicSpdySession {
struct iovec iov;
iov.iov_base = nullptr; // should not be read.
iov.iov_len = static_cast<size_t>(bytes);
- return WritevData(id, QuicIOVector(&iov, 1, bytes), 0, true,
- MAY_FEC_PROTECT, nullptr);
+ return WritevData(id, QuicIOVector(&iov, 1, bytes), 0, true, nullptr);
}
using QuicSession::PostProcessAfterData;
@@ -388,29 +385,19 @@ TEST_P(QuicSessionTestServer, OnCanWrite) {
InSequence s;
StreamBlocker stream2_blocker(&session_, stream2->id());
- if (FLAGS_quic_batch_writes) {
- // Reregister, to test the loop limit.
- EXPECT_CALL(*stream2, OnCanWrite())
- .WillOnce(Invoke(&stream2_blocker,
- &StreamBlocker::MarkConnectionLevelWriteBlocked));
- // 2 will get called a second time as it didn't finish its block
- EXPECT_CALL(*stream2, OnCanWrite());
- EXPECT_CALL(*stream6, OnCanWrite());
- // 4 will not get called, as we exceeded the loop limit.
- } else {
- // Reregister, to test the loop limit.
- EXPECT_CALL(*stream2, OnCanWrite())
- .WillOnce(Invoke(&stream2_blocker,
- &StreamBlocker::MarkConnectionLevelWriteBlocked));
- EXPECT_CALL(*stream6, OnCanWrite());
- EXPECT_CALL(*stream4, OnCanWrite());
- }
+ // Reregister, to test the loop limit.
+ EXPECT_CALL(*stream2, OnCanWrite())
+ .WillOnce(Invoke(&stream2_blocker,
+ &StreamBlocker::MarkConnectionLevelWriteBlocked));
+ // 2 will get called a second time as it didn't finish its block
+ EXPECT_CALL(*stream2, OnCanWrite());
+ EXPECT_CALL(*stream6, OnCanWrite());
+ // 4 will not get called, as we exceeded the loop limit.
session_.OnCanWrite();
EXPECT_TRUE(session_.WillingAndAbleToWrite());
}
TEST_P(QuicSessionTestServer, TestBatchedWrites) {
- ValueRestore<bool> old_flag(&FLAGS_quic_batch_writes, true);
TestStream* stream2 = session_.CreateOutgoingDynamicStream(kDefaultPriority);
TestStream* stream4 = session_.CreateOutgoingDynamicStream(kDefaultPriority);
TestStream* stream6 = session_.CreateOutgoingDynamicStream(kDefaultPriority);
diff --git a/net/quic/quic_spdy_stream_test.cc b/net/quic/quic_spdy_stream_test.cc
index 54ebb8a..4f71cb7 100644
--- a/net/quic/quic_spdy_stream_test.cc
+++ b/net/quic/quic_spdy_stream_test.cc
@@ -363,7 +363,7 @@ TEST_P(QuicSpdyStreamTest, StreamFlowControlBlocked) {
GenerateBody(&body, kWindow + kOverflow);
EXPECT_CALL(*connection_, SendBlocked(kClientDataStreamId1));
- EXPECT_CALL(*session_, WritevData(kClientDataStreamId1, _, _, _, _, _))
+ EXPECT_CALL(*session_, WritevData(kClientDataStreamId1, _, _, _, _))
.WillOnce(Return(QuicConsumedData(kWindow, true)));
stream_->WriteOrBufferData(body, false, nullptr);
@@ -609,7 +609,7 @@ TEST_P(QuicSpdyStreamTest, StreamFlowControlFinNotBlocked) {
bool fin = true;
EXPECT_CALL(*connection_, SendBlocked(kClientDataStreamId1)).Times(0);
- EXPECT_CALL(*session_, WritevData(kClientDataStreamId1, _, _, _, _, _))
+ EXPECT_CALL(*session_, WritevData(kClientDataStreamId1, _, _, _, _))
.WillOnce(Return(QuicConsumedData(0, fin)));
stream_->WriteOrBufferData(body, fin, nullptr);
@@ -732,7 +732,7 @@ TEST_P(QuicSpdyStreamTest, WritingTrailersSendsAFin) {
// Test that writing trailers will send a FIN, as Trailers are the last thing
// to be sent on a stream.
Initialize(kShouldProcessData);
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
.Times(AnyNumber())
.WillRepeatedly(Invoke(MockQuicSpdySession::ConsumeAllData));
@@ -753,7 +753,7 @@ TEST_P(QuicSpdyStreamTest, WritingTrailersFinalOffset) {
// Test that when writing trailers, the trailers that are actually sent to the
// peer contain the final offset field indicating last byte of data.
Initialize(kShouldProcessData);
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
.Times(AnyNumber())
.WillRepeatedly(Invoke(MockQuicSpdySession::ConsumeAllData));
@@ -780,7 +780,7 @@ TEST_P(QuicSpdyStreamTest, WritingTrailersClosesWriteSide) {
// Test that if trailers are written after all other data has been written
// (headers and body), that this closes the stream for writing.
Initialize(kShouldProcessData);
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
.Times(AnyNumber())
.WillRepeatedly(Invoke(MockQuicSpdySession::ConsumeAllData));
@@ -805,7 +805,7 @@ TEST_P(QuicSpdyStreamTest, WritingTrailersWithQueuedBytes) {
// Test that the stream is not closed for writing when trailers are sent
// while there are still body bytes queued.
Initialize(kShouldProcessData);
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
.Times(AnyNumber())
.WillRepeatedly(Invoke(MockQuicSpdySession::ConsumeAllData));
@@ -815,7 +815,7 @@ TEST_P(QuicSpdyStreamTest, WritingTrailersWithQueuedBytes) {
// Write non-zero body data, but only consume partially, ensuring queueing.
const int kBodySize = 1 * 1024; // 1 MB
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
.WillOnce(Return(QuicConsumedData(kBodySize - 1, false)));
stream_->WriteOrBufferData(string(kBodySize, 'x'), false, nullptr);
EXPECT_EQ(1u, stream_->queued_data_bytes());
@@ -832,7 +832,7 @@ TEST_P(QuicSpdyStreamTest, WritingTrailersWithQueuedBytes) {
TEST_P(QuicSpdyStreamTest, WritingTrailersAfterFIN) {
// Test that it is not possible to write Trailers after a FIN has been sent.
Initialize(kShouldProcessData);
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
.Times(AnyNumber())
.WillRepeatedly(Invoke(MockQuicSpdySession::ConsumeAllData));
diff --git a/net/quic/quic_unacked_packet_map.cc b/net/quic/quic_unacked_packet_map.cc
index c8a3250..fc72388 100644
--- a/net/quic/quic_unacked_packet_map.cc
+++ b/net/quic/quic_unacked_packet_map.cc
@@ -49,8 +49,7 @@ void QuicUnackedPacketMap::AddSentPacket(SerializedPacket* packet,
packet->has_crypto_handshake == IS_HANDSHAKE;
TransmissionInfo info(packet->encryption_level, packet->packet_number_length,
transmission_type, sent_time, bytes_sent,
- packet->is_fec_packet, has_crypto_handshake,
- packet->needs_padding);
+ has_crypto_handshake, packet->needs_padding);
if (old_packet_number > 0) {
TransferRetransmissionInfo(old_packet_number, packet_number,
transmission_type, &info);
diff --git a/net/quic/quic_unacked_packet_map.h b/net/quic/quic_unacked_packet_map.h
index 8ed6d0a..31fc7f4 100644
--- a/net/quic/quic_unacked_packet_map.h
+++ b/net/quic/quic_unacked_packet_map.h
@@ -175,8 +175,8 @@ class NET_EXPORT_PRIVATE QuicUnackedPacketMap {
QuicPacketNumber largest_sent_packet_;
QuicPacketNumber largest_observed_;
- // Newly serialized retransmittable and fec packets are added to this map,
- // which contains owning pointers to any contained frames. If a packet is
+ // Newly serialized retransmittable packets are added to this map, which
+ // contains owning pointers to any contained frames. If a packet is
// retransmitted, this map will contain entries for both the old and the new
// packet. The old packet's retransmittable frames entry will be nullptr,
// while the new packet's entry will contain the frames to retransmit.
diff --git a/net/quic/quic_write_blocked_list.h b/net/quic/quic_write_blocked_list.h
index d004452..2988a9d 100644
--- a/net/quic/quic_write_blocked_list.h
+++ b/net/quic/quic_write_blocked_list.h
@@ -135,7 +135,6 @@ class NET_EXPORT_PRIVATE QuicWriteBlockedList {
return;
}
bool push_front =
- FLAGS_quic_batch_writes &&
stream_id == batch_write_stream_id_[last_priority_popped_] &&
bytes_left_for_batch_write_[last_priority_popped_] > 0;
priority_write_scheduler_.MarkStreamReady(stream_id, push_front);
diff --git a/net/quic/quic_write_blocked_list_test.cc b/net/quic/quic_write_blocked_list_test.cc
index c970a2f..23009c0 100644
--- a/net/quic/quic_write_blocked_list_test.cc
+++ b/net/quic/quic_write_blocked_list_test.cc
@@ -115,7 +115,6 @@ TEST(QuicWriteBlockedListTest, NoDuplicateEntries) {
}
TEST(QuicWriteBlockedListTest, BatchingWrites) {
- ValueRestore<bool> old_flag(&FLAGS_quic_batch_writes, true);
QuicWriteBlockedList write_blocked_list;
const QuicStreamId id1 = kClientDataStreamId1;
diff --git a/net/quic/reliable_quic_stream.cc b/net/quic/reliable_quic_stream.cc
index eea769d..c4c7d5c 100644
--- a/net/quic/reliable_quic_stream.cc
+++ b/net/quic/reliable_quic_stream.cc
@@ -66,7 +66,6 @@ ReliableQuicStream::ReliableQuicStream(QuicStreamId id, QuicSession* session)
fin_received_(false),
rst_sent_(false),
rst_received_(false),
- fec_policy_(FEC_PROTECT_OPTIONAL),
perspective_(session_->perspective()),
flow_controller_(session_->connection(),
id_,
@@ -81,11 +80,7 @@ ReliableQuicStream::ReliableQuicStream(QuicStreamId id, QuicSession* session)
ReliableQuicStream::~ReliableQuicStream() {}
-void ReliableQuicStream::SetFromConfig() {
- if (session_->config()->HasClientSentConnectionOption(kFSTR, perspective_)) {
- fec_policy_ = FEC_PROTECT_ALWAYS;
- }
-}
+void ReliableQuicStream::SetFromConfig() {}
void ReliableQuicStream::OnStreamFrame(const QuicStreamFrame& frame) {
DCHECK_EQ(frame.stream_id, id_);
@@ -311,9 +306,9 @@ QuicConsumedData ReliableQuicStream::WritevData(
write_length = static_cast<size_t>(send_window);
}
- QuicConsumedData consumed_data = session()->WritevData(
- id(), QuicIOVector(iov, iov_count, write_length), stream_bytes_written_,
- fin, GetFecProtection(), ack_listener);
+ QuicConsumedData consumed_data =
+ session()->WritevData(id(), QuicIOVector(iov, iov_count, write_length),
+ stream_bytes_written_, fin, ack_listener);
stream_bytes_written_ += consumed_data.bytes_consumed;
AddBytesSent(consumed_data.bytes_consumed);
@@ -343,10 +338,6 @@ QuicConsumedData ReliableQuicStream::WritevData(
return consumed_data;
}
-FecProtection ReliableQuicStream::GetFecProtection() {
- return fec_policy_ == FEC_PROTECT_ALWAYS ? MUST_FEC_PROTECT : MAY_FEC_PROTECT;
-}
-
void ReliableQuicStream::CloseReadSide() {
if (read_side_closed_) {
return;
diff --git a/net/quic/reliable_quic_stream.h b/net/quic/reliable_quic_stream.h
index 8e660b2..e0be70b 100644
--- a/net/quic/reliable_quic_stream.h
+++ b/net/quic/reliable_quic_stream.h
@@ -50,7 +50,7 @@ class NET_EXPORT_PRIVATE ReliableQuicStream {
virtual ~ReliableQuicStream();
- // Sets |fec_policy_| parameter from |session_|'s config.
+ // Not in use currently.
void SetFromConfig();
// Called by the session when a (potentially duplicate) stream frame has been
@@ -118,9 +118,6 @@ class NET_EXPORT_PRIVATE ReliableQuicStream {
void set_fin_received(bool fin_received) { fin_received_ = fin_received; }
void set_rst_sent(bool rst_sent) { rst_sent_ = rst_sent; }
- void set_fec_policy(FecPolicy fec_policy) { fec_policy_ = fec_policy; }
- FecPolicy fec_policy() const { return fec_policy_; }
-
void set_rst_received(bool rst_received) { rst_received_ = rst_received; }
void set_stream_error(QuicRstStreamErrorCode error) { stream_error_ = error; }
@@ -198,9 +195,6 @@ class NET_EXPORT_PRIVATE ReliableQuicStream {
// Does not send a FIN. May cause the stream to be closed.
virtual void CloseWriteSide();
- // Helper method that returns FecProtection to use when writing.
- FecProtection GetFecProtection();
-
bool fin_buffered() const { return fin_buffered_; }
const QuicSession* session() const { return session_; }
@@ -287,9 +281,6 @@ class NET_EXPORT_PRIVATE ReliableQuicStream {
// True if this stream has received a RST_STREAM frame.
bool rst_received_;
- // FEC policy to be used for this stream.
- FecPolicy fec_policy_;
-
// Tracks if the session this stream is running under was created by a
// server or a client.
Perspective perspective_;
diff --git a/net/quic/reliable_quic_stream_test.cc b/net/quic/reliable_quic_stream_test.cc
index b006895..8de1863 100644
--- a/net/quic/reliable_quic_stream_test.cc
+++ b/net/quic/reliable_quic_stream_test.cc
@@ -141,7 +141,6 @@ class ReliableQuicStreamTest : public ::testing::TestWithParam<bool> {
QuicIOVector /*iov*/,
QuicStreamOffset /*offset*/,
bool /*fin*/,
- FecProtection /*fec_protection*/,
QuicAckListenerInterface* /*ack_notifier_delegate*/) {
session_->CloseStream(id);
return QuicConsumedData(1, false);
@@ -163,13 +162,12 @@ class ReliableQuicStreamTest : public ::testing::TestWithParam<bool> {
TEST_F(ReliableQuicStreamTest, WriteAllData) {
Initialize(kShouldProcessData);
- size_t length =
- 1 + QuicPacketCreator::StreamFramePacketOverhead(
- PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, !kIncludePathId,
- PACKET_6BYTE_PACKET_NUMBER, 0u, NOT_IN_FEC_GROUP);
+ size_t length = 1 + QuicPacketCreator::StreamFramePacketOverhead(
+ PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
+ !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER, 0u);
connection_->SetMaxPacketLength(length);
- EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
+ EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _))
.WillOnce(Return(QuicConsumedData(kDataLen, true)));
stream_->WriteOrBufferData(kData1, false, nullptr);
EXPECT_FALSE(HasWriteBlockedStreams());
@@ -189,7 +187,7 @@ TEST_F(ReliableQuicStreamTest, BlockIfOnlySomeDataConsumed) {
// Write some data and no fin. If we consume some but not all of the data,
// we should be write blocked a not all the data was consumed.
- EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
+ EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _))
.WillOnce(Return(QuicConsumedData(1, false)));
stream_->WriteOrBufferData(StringPiece(kData1, 2), false, nullptr);
ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams());
@@ -203,7 +201,7 @@ TEST_F(ReliableQuicStreamTest, BlockIfFinNotConsumedWithData) {
// we should be write blocked because the fin was not consumed.
// (This should never actually happen as the fin should be sent out with the
// last data)
- EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
+ EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _))
.WillOnce(Return(QuicConsumedData(2, false)));
stream_->WriteOrBufferData(StringPiece(kData1, 2), true, nullptr);
ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams());
@@ -214,7 +212,7 @@ TEST_F(ReliableQuicStreamTest, BlockIfSoloFinNotConsumed) {
// Write no data and a fin. If we consume nothing we should be write blocked,
// as the fin was not consumed.
- EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
+ EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _))
.WillOnce(Return(QuicConsumedData(0, false)));
stream_->WriteOrBufferData(StringPiece(), true, nullptr);
ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams());
@@ -226,7 +224,7 @@ TEST_F(ReliableQuicStreamTest, CloseOnPartialWrite) {
// Write some data and no fin. However, while writing the data
// close the stream and verify that MarkConnectionLevelWriteBlocked does not
// crash with an unknown stream.
- EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
+ EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _))
.WillOnce(Invoke(this, &ReliableQuicStreamTest::CloseStreamOnWriteError));
stream_->WriteOrBufferData(StringPiece(kData1, 2), false, nullptr);
ASSERT_EQ(0u, write_blocked_list_->NumBlockedStreams());
@@ -236,13 +234,12 @@ TEST_F(ReliableQuicStreamTest, WriteOrBufferData) {
Initialize(kShouldProcessData);
EXPECT_FALSE(HasWriteBlockedStreams());
- size_t length =
- 1 + QuicPacketCreator::StreamFramePacketOverhead(
- PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, !kIncludePathId,
- PACKET_6BYTE_PACKET_NUMBER, 0u, NOT_IN_FEC_GROUP);
+ size_t length = 1 + QuicPacketCreator::StreamFramePacketOverhead(
+ PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
+ !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER, 0u);
connection_->SetMaxPacketLength(length);
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
.WillOnce(Return(QuicConsumedData(kDataLen - 1, false)));
stream_->WriteOrBufferData(kData1, false, nullptr);
EXPECT_TRUE(HasWriteBlockedStreams());
@@ -252,86 +249,14 @@ TEST_F(ReliableQuicStreamTest, WriteOrBufferData) {
// Make sure we get the tail of the first write followed by the bytes_consumed
InSequence s;
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
.WillOnce(Return(QuicConsumedData(1, false)));
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
.WillOnce(Return(QuicConsumedData(kDataLen - 2, false)));
stream_->OnCanWrite();
// And finally the end of the bytes_consumed.
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
- .WillOnce(Return(QuicConsumedData(2, true)));
- stream_->OnCanWrite();
-}
-
-TEST_F(ReliableQuicStreamTest, WriteOrBufferDataWithFecProtectAlways) {
- Initialize(kShouldProcessData);
-
- // Set FEC policy on stream.
- ReliableQuicStreamPeer::SetFecPolicy(stream_, FEC_PROTECT_ALWAYS);
-
- EXPECT_FALSE(HasWriteBlockedStreams());
- size_t length =
- 1 + QuicPacketCreator::StreamFramePacketOverhead(
- PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, !kIncludePathId,
- PACKET_6BYTE_PACKET_NUMBER, 0u, IN_FEC_GROUP);
- connection_->SetMaxPacketLength(length);
-
- // Write first data onto stream, which will cause one session write.
- EXPECT_CALL(*session_, WritevData(_, _, _, _, MUST_FEC_PROTECT, _))
- .WillOnce(Return(QuicConsumedData(kDataLen - 1, false)));
- stream_->WriteOrBufferData(kData1, false, nullptr);
- EXPECT_TRUE(HasWriteBlockedStreams());
-
- // Queue a bytes_consumed write.
- stream_->WriteOrBufferData(kData2, false, nullptr);
-
- // Make sure we get the tail of the first write followed by the bytes_consumed
- InSequence s;
- EXPECT_CALL(*session_, WritevData(_, _, _, _, MUST_FEC_PROTECT, _))
- .WillOnce(Return(QuicConsumedData(1, false)));
- EXPECT_CALL(*session_, WritevData(_, _, _, _, MUST_FEC_PROTECT, _))
- .WillOnce(Return(QuicConsumedData(kDataLen - 2, false)));
- stream_->OnCanWrite();
-
- // And finally the end of the bytes_consumed.
- EXPECT_CALL(*session_, WritevData(_, _, _, _, MUST_FEC_PROTECT, _))
- .WillOnce(Return(QuicConsumedData(2, true)));
- stream_->OnCanWrite();
-}
-
-TEST_F(ReliableQuicStreamTest, WriteOrBufferDataWithFecProtectOptional) {
- Initialize(kShouldProcessData);
-
- // Set FEC policy on stream.
- ReliableQuicStreamPeer::SetFecPolicy(stream_, FEC_PROTECT_OPTIONAL);
-
- EXPECT_FALSE(HasWriteBlockedStreams());
- size_t length =
- 1 + QuicPacketCreator::StreamFramePacketOverhead(
- PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, !kIncludePathId,
- PACKET_6BYTE_PACKET_NUMBER, 0u, NOT_IN_FEC_GROUP);
- connection_->SetMaxPacketLength(length);
-
- // Write first data onto stream, which will cause one session write.
- EXPECT_CALL(*session_, WritevData(_, _, _, _, MAY_FEC_PROTECT, _))
- .WillOnce(Return(QuicConsumedData(kDataLen - 1, false)));
- stream_->WriteOrBufferData(kData1, false, nullptr);
- EXPECT_TRUE(HasWriteBlockedStreams());
-
- // Queue a bytes_consumed write.
- stream_->WriteOrBufferData(kData2, false, nullptr);
-
- // Make sure we get the tail of the first write followed by the bytes_consumed
- InSequence s;
- EXPECT_CALL(*session_, WritevData(_, _, _, _, MAY_FEC_PROTECT, _))
- .WillOnce(Return(QuicConsumedData(1, false)));
- EXPECT_CALL(*session_, WritevData(_, _, _, _, MAY_FEC_PROTECT, _))
- .WillOnce(Return(QuicConsumedData(kDataLen - 2, false)));
- stream_->OnCanWrite();
-
- // And finally the end of the bytes_consumed.
- EXPECT_CALL(*session_, WritevData(_, _, _, _, MAY_FEC_PROTECT, _))
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
.WillOnce(Return(QuicConsumedData(2, true)));
stream_->OnCanWrite();
}
@@ -359,7 +284,7 @@ TEST_F(ReliableQuicStreamTest, RstAlwaysSentIfNoFinSent) {
EXPECT_FALSE(rst_sent());
// Write some data, with no FIN.
- EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
+ EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _))
.WillOnce(Return(QuicConsumedData(1, false)));
stream_->WriteOrBufferData(StringPiece(kData1, 1), false, nullptr);
EXPECT_FALSE(fin_sent());
@@ -382,7 +307,7 @@ TEST_F(ReliableQuicStreamTest, RstNotSentIfFinSent) {
EXPECT_FALSE(rst_sent());
// Write some data, with FIN.
- EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
+ EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _))
.WillOnce(Return(QuicConsumedData(1, true)));
stream_->WriteOrBufferData(StringPiece(kData1, 1), true, nullptr);
EXPECT_TRUE(fin_sent());
@@ -476,26 +401,23 @@ TEST_F(ReliableQuicStreamTest, WriteOrBufferDataWithQuicAckNotifier) {
scoped_refptr<QuicAckListenerInterface> ack_listener;
- EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
+ EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _))
.WillOnce(DoAll(
- WithArgs<5>(Invoke(CreateFunctor(SaveAckListener, &ack_listener))),
+ WithArgs<4>(Invoke(CreateFunctor(SaveAckListener, &ack_listener))),
Return(QuicConsumedData(kFirstWriteSize, false))));
stream_->WriteOrBufferData(kData, false, delegate.get());
EXPECT_TRUE(HasWriteBlockedStreams());
- EXPECT_CALL(*session_,
- WritevData(kTestStreamId, _, _, _, _, ack_listener.get()))
+ EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, ack_listener.get()))
.WillOnce(Return(QuicConsumedData(kSecondWriteSize, false)));
stream_->OnCanWrite();
// No ack expected for an empty write.
- EXPECT_CALL(*session_,
- WritevData(kTestStreamId, _, _, _, _, ack_listener.get()))
+ EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, ack_listener.get()))
.WillOnce(Return(QuicConsumedData(0, false)));
stream_->OnCanWrite();
- EXPECT_CALL(*session_,
- WritevData(kTestStreamId, _, _, _, _, ack_listener.get()))
+ EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, ack_listener.get()))
.WillOnce(Return(QuicConsumedData(kLastWriteSize, false)));
stream_->OnCanWrite();
}
@@ -518,16 +440,16 @@ TEST_F(ReliableQuicStreamTest, WriteOrBufferDataAckNotificationBeforeFlush) {
scoped_refptr<QuicAckListenerInterface> proxy_delegate;
- EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
+ EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _))
.WillOnce(DoAll(
- WithArgs<5>(Invoke(CreateFunctor(SaveAckListener, &proxy_delegate))),
+ WithArgs<4>(Invoke(CreateFunctor(SaveAckListener, &proxy_delegate))),
Return(QuicConsumedData(kInitialWriteSize, false))));
stream_->WriteOrBufferData(kData, false, ack_listener.get());
EXPECT_TRUE(HasWriteBlockedStreams());
- EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
+ EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _))
.WillOnce(DoAll(
- WithArgs<5>(Invoke(CreateFunctor(SaveAckListener, &proxy_delegate))),
+ WithArgs<4>(Invoke(CreateFunctor(SaveAckListener, &proxy_delegate))),
Return(QuicConsumedData(kDataSize - kInitialWriteSize, false))));
stream_->OnCanWrite();
}
@@ -540,9 +462,9 @@ TEST_F(ReliableQuicStreamTest, WriteAndBufferDataWithAckNotiferNoBuffer) {
scoped_refptr<QuicAckListenerInterface> proxy_delegate;
- EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
+ EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _))
.WillOnce(DoAll(
- WithArgs<5>(Invoke(CreateFunctor(SaveAckListener, &proxy_delegate))),
+ WithArgs<4>(Invoke(CreateFunctor(SaveAckListener, &proxy_delegate))),
Return(QuicConsumedData(kDataLen, true))));
stream_->WriteOrBufferData(kData1, true, delegate.get());
EXPECT_FALSE(HasWriteBlockedStreams());
@@ -556,14 +478,14 @@ TEST_F(ReliableQuicStreamTest, BufferOnWriteAndBufferDataWithAckNotifer) {
scoped_refptr<QuicAckListenerInterface> proxy_delegate;
- EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
+ EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _))
.WillOnce(Return(QuicConsumedData(0, false)));
stream_->WriteOrBufferData(kData1, true, delegate.get());
EXPECT_TRUE(HasWriteBlockedStreams());
- EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
+ EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _))
.WillOnce(DoAll(
- WithArgs<5>(Invoke(CreateFunctor(SaveAckListener, &proxy_delegate))),
+ WithArgs<4>(Invoke(CreateFunctor(SaveAckListener, &proxy_delegate))),
Return(QuicConsumedData(kDataLen, true))));
stream_->OnCanWrite();
}
@@ -577,16 +499,16 @@ TEST_F(ReliableQuicStreamTest, WriteAndBufferDataWithAckNotiferOnlyFinRemains) {
scoped_refptr<QuicAckListenerInterface> proxy_delegate;
- EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
+ EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _))
.WillOnce(DoAll(
- WithArgs<5>(Invoke(CreateFunctor(SaveAckListener, &proxy_delegate))),
+ WithArgs<4>(Invoke(CreateFunctor(SaveAckListener, &proxy_delegate))),
Return(QuicConsumedData(kDataLen, false))));
stream_->WriteOrBufferData(kData1, true, delegate.get());
EXPECT_TRUE(HasWriteBlockedStreams());
- EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
+ EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _))
.WillOnce(DoAll(
- WithArgs<5>(Invoke(CreateFunctor(SaveAckListener, &proxy_delegate))),
+ WithArgs<4>(Invoke(CreateFunctor(SaveAckListener, &proxy_delegate))),
Return(QuicConsumedData(0, true))));
stream_->OnCanWrite();
}
@@ -678,7 +600,7 @@ TEST_F(ReliableQuicStreamTest, SetDrainingIncomingOutgoing) {
EXPECT_EQ(1u, session_->GetNumOpenIncomingStreams());
// Outgoing data with FIN.
- EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
+ EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _))
.WillOnce(Return(QuicConsumedData(2, true)));
stream_->WriteOrBufferData(StringPiece(kData1, 2), true, nullptr);
EXPECT_TRUE(stream_->write_side_closed());
@@ -693,7 +615,7 @@ TEST_F(ReliableQuicStreamTest, SetDrainingOutgoingIncoming) {
Initialize(kShouldNotProcessData);
// Outgoing data with FIN.
- EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
+ EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _))
.WillOnce(Return(QuicConsumedData(2, true)));
stream_->WriteOrBufferData(StringPiece(kData1, 2), true, nullptr);
EXPECT_TRUE(stream_->write_side_closed());
@@ -714,26 +636,13 @@ TEST_F(ReliableQuicStreamTest, SetDrainingOutgoingIncoming) {
EXPECT_EQ(0u, session_->GetNumOpenIncomingStreams());
}
-TEST_F(ReliableQuicStreamTest, FecSendPolicyReceivedConnectionOption) {
- Initialize(kShouldProcessData);
-
- // Test ReceivedConnectionOptions.
- QuicConfig* config = session_->config();
- QuicTagVector copt;
- copt.push_back(kFSTR);
- QuicConfigPeer::SetReceivedConnectionOptions(config, copt);
- EXPECT_EQ(FEC_PROTECT_OPTIONAL, stream_->fec_policy());
- stream_->SetFromConfig();
- EXPECT_EQ(FEC_PROTECT_ALWAYS, stream_->fec_policy());
-}
-
TEST_F(ReliableQuicStreamTest, EarlyResponseFinHandling) {
// Verify that if the server completes the response before reading the end of
// the request, the received FIN is recorded.
Initialize(kShouldProcessData);
EXPECT_CALL(*connection_, SendConnectionCloseWithDetails(_, _)).Times(0);
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
.WillRepeatedly(Invoke(MockQuicSpdySession::ConsumeAllData));
// Receive data for the request.
diff --git a/net/quic/test_tools/crypto_test_utils.cc b/net/quic/test_tools/crypto_test_utils.cc
index 4d18cca..bb5f36b 100644
--- a/net/quic/test_tools/crypto_test_utils.cc
+++ b/net/quic/test_tools/crypto_test_utils.cc
@@ -136,11 +136,14 @@ int CryptoTestUtils::HandshakeWithFakeServer(
QuicCryptoServerConfig crypto_config(QuicCryptoServerConfig::TESTING,
QuicRandom::GetInstance(),
ProofSourceForTesting());
+ QuicCompressedCertsCache compressed_certs_cache(
+ QuicCompressedCertsCache::kQuicCompressedCertsCacheSize);
SetupCryptoServerConfigForTest(server_conn->clock(),
server_conn->random_generator(), &config,
&crypto_config, options);
- TestQuicSpdyServerSession server_session(server_conn, config, &crypto_config);
+ TestQuicSpdyServerSession server_session(server_conn, config, &crypto_config,
+ &compressed_certs_cache);
// The client's handshake must have been started already.
CHECK_NE(0u, client_conn->encrypted_packets_.size());
diff --git a/net/quic/test_tools/mock_quic_dispatcher.cc b/net/quic/test_tools/mock_quic_dispatcher.cc
index 66b940b..a313651 100644
--- a/net/quic/test_tools/mock_quic_dispatcher.cc
+++ b/net/quic/test_tools/mock_quic_dispatcher.cc
@@ -13,10 +13,7 @@ MockQuicDispatcher::MockQuicDispatcher(
const QuicConfig& config,
const QuicCryptoServerConfig* crypto_config,
QuicConnectionHelperInterface* helper)
- : QuicDispatcher(config,
- crypto_config,
- QuicSupportedVersions(),
- helper) {}
+ : QuicDispatcher(config, crypto_config, QuicSupportedVersions(), helper) {}
MockQuicDispatcher::~MockQuicDispatcher() {}
diff --git a/net/quic/test_tools/quic_connection_peer.cc b/net/quic/test_tools/quic_connection_peer.cc
index f171bff..8f16fc8d 100644
--- a/net/quic/test_tools/quic_connection_peer.cc
+++ b/net/quic/test_tools/quic_connection_peer.cc
@@ -6,7 +6,6 @@
#include "base/stl_util.h"
#include "net/quic/congestion_control/send_algorithm_interface.h"
-#include "net/quic/quic_connection.h"
#include "net/quic/quic_packet_writer.h"
#include "net/quic/quic_received_packet_manager.h"
#include "net/quic/test_tools/quic_framer_peer.h"
@@ -151,13 +150,6 @@ QuicFramer* QuicConnectionPeer::GetFramer(QuicConnection* connection) {
}
// static
-QuicFecGroup* QuicConnectionPeer::GetFecGroup(QuicConnection* connection,
- int fec_group) {
- connection->last_header_.fec_group = fec_group;
- return connection->GetFecGroup();
-}
-
-// static
QuicAlarm* QuicConnectionPeer::GetAckAlarm(QuicConnection* connection) {
return connection->ack_alarm_.get();
}
@@ -168,11 +160,6 @@ QuicAlarm* QuicConnectionPeer::GetPingAlarm(QuicConnection* connection) {
}
// static
-QuicAlarm* QuicConnectionPeer::GetFecAlarm(QuicConnection* connection) {
- return connection->fec_alarm_.get();
-}
-
-// static
QuicAlarm* QuicConnectionPeer::GetResumeWritesAlarm(
QuicConnection* connection) {
return connection->resume_writes_alarm_.get();
@@ -268,8 +255,9 @@ void QuicConnectionPeer::SetNextMtuProbeAt(QuicConnection* connection,
}
// static
-void QuicConnectionPeer::EnableAckDecimation(QuicConnection* connection) {
- connection->ack_decimation_enabled_ = true;
+void QuicConnectionPeer::SetAckMode(QuicConnection* connection,
+ QuicConnection::AckMode ack_mode) {
+ connection->ack_mode_ = ack_mode;
}
} // namespace test
diff --git a/net/quic/test_tools/quic_connection_peer.h b/net/quic/test_tools/quic_connection_peer.h
index 524eb15..d547dc4 100644
--- a/net/quic/test_tools/quic_connection_peer.h
+++ b/net/quic/test_tools/quic_connection_peer.h
@@ -7,6 +7,7 @@
#include "base/macros.h"
#include "net/base/ip_endpoint.h"
+#include "net/quic/quic_connection.h"
#include "net/quic/quic_connection_stats.h"
#include "net/quic/quic_protocol.h"
@@ -15,11 +16,9 @@ namespace net {
struct QuicAckFrame;
struct QuicPacketHeader;
class QuicAlarm;
-class QuicConnection;
class QuicConnectionHelperInterface;
class QuicConnectionVisitorInterface;
class QuicEncryptedPacket;
-class QuicFecGroup;
class QuicFramer;
class QuicPacketCreator;
class QuicPacketGenerator;
@@ -88,12 +87,8 @@ class QuicConnectionPeer {
static QuicFramer* GetFramer(QuicConnection* connection);
- // Set last_header_->fec_group = fec_group and return connection->GetFecGroup
- static QuicFecGroup* GetFecGroup(QuicConnection* connection, int fec_group);
-
static QuicAlarm* GetAckAlarm(QuicConnection* connection);
static QuicAlarm* GetPingAlarm(QuicConnection* connection);
- static QuicAlarm* GetFecAlarm(QuicConnection* connection);
static QuicAlarm* GetResumeWritesAlarm(QuicConnection* connection);
static QuicAlarm* GetRetransmissionAlarm(QuicConnection* connection);
static QuicAlarm* GetSendAlarm(QuicConnection* connection);
@@ -122,7 +117,8 @@ class QuicConnectionPeer {
QuicPacketCount packets);
static void SetNextMtuProbeAt(QuicConnection* connection,
QuicPacketNumber number);
- static void EnableAckDecimation(QuicConnection* connection);
+ static void SetAckMode(QuicConnection* connection,
+ QuicConnection::AckMode ack_mode);
private:
DISALLOW_COPY_AND_ASSIGN(QuicConnectionPeer);
diff --git a/net/quic/test_tools/quic_packet_creator_peer.cc b/net/quic/test_tools/quic_packet_creator_peer.cc
index 6ec2a72..83b783c 100644
--- a/net/quic/test_tools/quic_packet_creator_peer.cc
+++ b/net/quic/test_tools/quic_packet_creator_peer.cc
@@ -65,10 +65,8 @@ void QuicPacketCreatorPeer::SetPacketNumber(QuicPacketCreator* creator,
// static
void QuicPacketCreatorPeer::FillPacketHeader(QuicPacketCreator* creator,
- QuicFecGroupNumber fec_group,
- bool fec_flag,
QuicPacketHeader* header) {
- creator->FillPacketHeader(fec_group, fec_flag, header);
+ creator->FillPacketHeader(header);
}
// static
@@ -83,35 +81,6 @@ size_t QuicPacketCreatorPeer::CreateStreamFrame(QuicPacketCreator* creator,
}
// static
-bool QuicPacketCreatorPeer::IsFecProtected(QuicPacketCreator* creator) {
- return creator->fec_protect_;
-}
-
-// static
-bool QuicPacketCreatorPeer::IsFecEnabled(QuicPacketCreator* creator) {
- return creator->max_packets_per_fec_group_ > 0;
-}
-
-// static
-void QuicPacketCreatorPeer::StartFecProtectingPackets(
- QuicPacketCreator* creator) {
- creator->StartFecProtectingPackets();
-}
-
-// static
-void QuicPacketCreatorPeer::StopFecProtectingPackets(
- QuicPacketCreator* creator) {
- creator->StopFecProtectingPackets();
-}
-
-// static
-void QuicPacketCreatorPeer::SerializeFec(QuicPacketCreator* creator,
- char* buffer,
- size_t buffer_len) {
- creator->SerializeFec(buffer, buffer_len);
-}
-
-// static
SerializedPacket QuicPacketCreatorPeer::SerializeAllFrames(
QuicPacketCreator* creator,
const QuicFrames& frames,
@@ -132,23 +101,6 @@ SerializedPacket QuicPacketCreatorPeer::SerializeAllFrames(
}
// static
-void QuicPacketCreatorPeer::ResetFecGroup(QuicPacketCreator* creator) {
- creator->ResetFecGroup();
-}
-
-// static
-QuicTime::Delta QuicPacketCreatorPeer::GetFecTimeout(
- QuicPacketCreator* creator) {
- return creator->fec_timeout_;
-}
-
-// static
-float QuicPacketCreatorPeer::GetRttMultiplierForFecTimeout(
- QuicPacketCreator* creator) {
- return creator->rtt_multiplier_for_fec_timeout_;
-}
-
-// static
EncryptionLevel QuicPacketCreatorPeer::GetEncryptionLevel(
QuicPacketCreator* creator) {
return creator->packet_.encryption_level;
diff --git a/net/quic/test_tools/quic_packet_creator_peer.h b/net/quic/test_tools/quic_packet_creator_peer.h
index cc17ca9..6849c1f 100644
--- a/net/quic/test_tools/quic_packet_creator_peer.h
+++ b/net/quic/test_tools/quic_packet_creator_peer.h
@@ -36,8 +36,6 @@ class QuicPacketCreatorPeer {
QuicPacketCreator* creator);
static void SetPacketNumber(QuicPacketCreator* creator, QuicPacketNumber s);
static void FillPacketHeader(QuicPacketCreator* creator,
- QuicFecGroupNumber fec_group,
- bool fec_flag,
QuicPacketHeader* header);
static size_t CreateStreamFrame(QuicPacketCreator* creator,
QuicStreamId id,
@@ -46,21 +44,10 @@ class QuicPacketCreatorPeer {
QuicStreamOffset offset,
bool fin,
QuicFrame* frame);
- static bool IsFecProtected(QuicPacketCreator* creator);
- static bool IsFecEnabled(QuicPacketCreator* creator);
- static void StartFecProtectingPackets(QuicPacketCreator* creator);
- static void StopFecProtectingPackets(QuicPacketCreator* creator);
- static void SerializeFec(QuicPacketCreator* creator,
- char* buffer,
- size_t buffer_len);
static SerializedPacket SerializeAllFrames(QuicPacketCreator* creator,
const QuicFrames& frames,
char* buffer,
size_t buffer_len);
- static void ResetFecGroup(QuicPacketCreator* creator);
- static QuicTime::Delta GetFecTimeout(QuicPacketCreator* creator);
- // TODO(rtenneti): Delete this code after the 0.25 RTT FEC experiment.
- static float GetRttMultiplierForFecTimeout(QuicPacketCreator* creator);
static EncryptionLevel GetEncryptionLevel(QuicPacketCreator* creator);
static QuicPathId GetCurrentPath(QuicPacketCreator* creator);
diff --git a/net/quic/test_tools/quic_test_utils.cc b/net/quic/test_tools/quic_test_utils.cc
index 9911757..1041569 100644
--- a/net/quic/test_tools/quic_test_utils.cc
+++ b/net/quic/test_tools/quic_test_utils.cc
@@ -61,7 +61,7 @@ QuicPacket* BuildUnsizedDataPacket(QuicFramer* framer,
bool last_frame = i == frames.size() - 1;
const size_t frame_size = framer->GetSerializedFrameLength(
frames[i], max_plaintext_size - packet_size, first_frame, last_frame,
- header.is_in_fec_group, header.public_header.packet_number_length);
+ header.public_header.packet_number_length);
DCHECK(frame_size);
packet_size += frame_size;
}
@@ -309,7 +309,7 @@ MockQuicSpdySession::MockQuicSpdySession(QuicConnection* connection)
: QuicSpdySession(connection, DefaultQuicConfig()) {
crypto_stream_.reset(new QuicCryptoStream(this));
Initialize();
- ON_CALL(*this, WritevData(_, _, _, _, _, _))
+ ON_CALL(*this, WritevData(_, _, _, _, _))
.WillByDefault(testing::Return(QuicConsumedData(0, false)));
}
@@ -321,7 +321,6 @@ QuicConsumedData MockQuicSpdySession::ConsumeAllData(
const QuicIOVector& data,
QuicStreamOffset /*offset*/,
bool fin,
- FecProtection /*fec_protection*/,
QuicAckListenerInterface* /*ack_notifier_delegate*/) {
return QuicConsumedData(data.total_length, fin);
}
@@ -329,8 +328,13 @@ QuicConsumedData MockQuicSpdySession::ConsumeAllData(
TestQuicSpdyServerSession::TestQuicSpdyServerSession(
QuicConnection* connection,
const QuicConfig& config,
- const QuicCryptoServerConfig* crypto_config)
- : QuicServerSessionBase(config, connection, &visitor_, crypto_config) {
+ const QuicCryptoServerConfig* crypto_config,
+ QuicCompressedCertsCache* compressed_certs_cache)
+ : QuicServerSessionBase(config,
+ connection,
+ &visitor_,
+ crypto_config,
+ compressed_certs_cache) {
Initialize();
}
@@ -338,8 +342,11 @@ TestQuicSpdyServerSession::~TestQuicSpdyServerSession() {}
QuicCryptoServerStreamBase*
TestQuicSpdyServerSession::CreateQuicCryptoServerStream(
- const QuicCryptoServerConfig* crypto_config) {
- return new QuicCryptoServerStream(crypto_config, this);
+ const QuicCryptoServerConfig* crypto_config,
+ QuicCompressedCertsCache* compressed_certs_cache) {
+ return new QuicCryptoServerStream(crypto_config, compressed_certs_cache,
+ FLAGS_enable_quic_stateless_reject_support,
+ this);
}
QuicCryptoServerStream* TestQuicSpdyServerSession::GetCryptoStream() {
@@ -672,20 +679,18 @@ size_t GetPacketLengthForOneStream(QuicVersion version,
bool include_path_id,
QuicConnectionIdLength connection_id_length,
QuicPacketNumberLength packet_number_length,
- InFecGroup is_in_fec_group,
size_t* payload_length) {
*payload_length = 1;
const size_t stream_length =
NullEncrypter().GetCiphertextSize(*payload_length) +
QuicPacketCreator::StreamFramePacketOverhead(
PACKET_8BYTE_CONNECTION_ID, include_version, include_path_id,
- packet_number_length, 0u, is_in_fec_group);
+ packet_number_length, 0u);
const size_t ack_length =
NullEncrypter().GetCiphertextSize(
QuicFramer::GetMinAckFrameSize(PACKET_1BYTE_PACKET_NUMBER)) +
GetPacketHeaderSize(connection_id_length, include_version,
- include_path_id, packet_number_length,
- is_in_fec_group);
+ include_path_id, packet_number_length);
if (stream_length < ack_length) {
*payload_length = 1 + ack_length - stream_length;
}
@@ -693,7 +698,7 @@ size_t GetPacketLengthForOneStream(QuicVersion version,
return NullEncrypter().GetCiphertextSize(*payload_length) +
QuicPacketCreator::StreamFramePacketOverhead(
connection_id_length, include_version, include_path_id,
- packet_number_length, 0u, is_in_fec_group);
+ packet_number_length, 0u);
}
TestEntropyCalculator::TestEntropyCalculator() {}
@@ -766,13 +771,15 @@ void CreateClientSessionForTest(QuicServerId server_id,
(*client_connection)->AdvanceTime(connection_start_time);
}
-void CreateServerSessionForTest(QuicServerId server_id,
- QuicTime::Delta connection_start_time,
- QuicVersionVector supported_versions,
- MockConnectionHelper* helper,
- QuicCryptoServerConfig* server_crypto_config,
- PacketSavingConnection** server_connection,
- TestQuicSpdyServerSession** server_session) {
+void CreateServerSessionForTest(
+ QuicServerId server_id,
+ QuicTime::Delta connection_start_time,
+ QuicVersionVector supported_versions,
+ MockConnectionHelper* helper,
+ QuicCryptoServerConfig* server_crypto_config,
+ QuicCompressedCertsCache* compressed_certs_cache,
+ PacketSavingConnection** server_connection,
+ TestQuicSpdyServerSession** server_session) {
CHECK(server_crypto_config);
CHECK(server_connection);
CHECK(server_session);
@@ -783,7 +790,8 @@ void CreateServerSessionForTest(QuicServerId server_id,
*server_connection = new PacketSavingConnection(
helper, Perspective::IS_SERVER, supported_versions);
*server_session = new TestQuicSpdyServerSession(
- *server_connection, DefaultQuicConfig(), server_crypto_config);
+ *server_connection, DefaultQuicConfig(), server_crypto_config,
+ compressed_certs_cache);
// We advance the clock initially because the default time is zero and the
// strike register worries that we've just overflowed a uint32_t time.
diff --git a/net/quic/test_tools/quic_test_utils.h b/net/quic/test_tools/quic_test_utils.h
index e669b0c..276490b 100644
--- a/net/quic/test_tools/quic_test_utils.h
+++ b/net/quic/test_tools/quic_test_utils.h
@@ -142,7 +142,6 @@ size_t GetPacketLengthForOneStream(QuicVersion version,
bool include_path_id,
QuicConnectionIdLength connection_id_length,
QuicPacketNumberLength packet_number_length,
- InFecGroup is_in_fec_group,
size_t* payload_length);
// Returns QuicConfig set to default values.
@@ -221,7 +220,6 @@ class MockFramerVisitor : public QuicFramerVisitorInterface {
MOCK_METHOD1(OnPublicResetPacket, void(const QuicPublicResetPacket& header));
MOCK_METHOD1(OnVersionNegotiationPacket,
void(const QuicVersionNegotiationPacket& packet));
- MOCK_METHOD0(OnRevivedPacket, void());
// The constructor sets this up to return true by default.
MOCK_METHOD1(OnUnauthenticatedHeader, bool(const QuicPacketHeader& header));
// The constructor sets this up to return true by default.
@@ -229,12 +227,10 @@ class MockFramerVisitor : public QuicFramerVisitorInterface {
bool(const QuicPacketPublicHeader& header));
MOCK_METHOD1(OnDecryptedPacket, void(EncryptionLevel level));
MOCK_METHOD1(OnPacketHeader, bool(const QuicPacketHeader& header));
- MOCK_METHOD1(OnFecProtectedPayload, void(base::StringPiece payload));
MOCK_METHOD1(OnStreamFrame, bool(const QuicStreamFrame& frame));
MOCK_METHOD1(OnAckFrame, bool(const QuicAckFrame& frame));
MOCK_METHOD1(OnStopWaitingFrame, bool(const QuicStopWaitingFrame& frame));
MOCK_METHOD1(OnPingFrame, bool(const QuicPingFrame& frame));
- MOCK_METHOD1(OnFecData, void(StringPiece redundancy));
MOCK_METHOD1(OnRstStreamFrame, bool(const QuicRstStreamFrame& frame));
MOCK_METHOD1(OnConnectionCloseFrame,
bool(const QuicConnectionCloseFrame& frame));
@@ -257,19 +253,16 @@ class NoOpFramerVisitor : public QuicFramerVisitorInterface {
void OnPublicResetPacket(const QuicPublicResetPacket& packet) override {}
void OnVersionNegotiationPacket(
const QuicVersionNegotiationPacket& packet) override {}
- void OnRevivedPacket() override {}
bool OnProtocolVersionMismatch(QuicVersion version) override;
bool OnUnauthenticatedHeader(const QuicPacketHeader& header) override;
bool OnUnauthenticatedPublicHeader(
const QuicPacketPublicHeader& header) override;
void OnDecryptedPacket(EncryptionLevel level) override {}
bool OnPacketHeader(const QuicPacketHeader& header) override;
- void OnFecProtectedPayload(base::StringPiece payload) override {}
bool OnStreamFrame(const QuicStreamFrame& frame) override;
bool OnAckFrame(const QuicAckFrame& frame) override;
bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override;
bool OnPingFrame(const QuicPingFrame& frame) override;
- void OnFecData(StringPiece redundancy) override {}
bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override;
bool OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override;
bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override;
@@ -461,13 +454,13 @@ class MockQuicSpdySession : public QuicSpdySession {
MOCK_METHOD1(CreateIncomingDynamicStream, QuicSpdyStream*(QuicStreamId id));
MOCK_METHOD1(CreateOutgoingDynamicStream,
QuicSpdyStream*(SpdyPriority priority));
- MOCK_METHOD6(WritevData,
+ MOCK_METHOD5(WritevData,
QuicConsumedData(QuicStreamId id,
QuicIOVector data,
QuicStreamOffset offset,
bool fin,
- FecProtection fec_protection,
QuicAckListenerInterface*));
+
MOCK_METHOD3(SendRstStream,
void(QuicStreamId stream_id,
QuicRstStreamErrorCode error,
@@ -503,7 +496,6 @@ class MockQuicSpdySession : public QuicSpdySession {
const QuicIOVector& data,
QuicStreamOffset offset,
bool fin,
- FecProtection fec_protection,
QuicAckListenerInterface* ack_notifier_delegate);
private:
@@ -516,14 +508,16 @@ class TestQuicSpdyServerSession : public QuicServerSessionBase {
public:
TestQuicSpdyServerSession(QuicConnection* connection,
const QuicConfig& config,
- const QuicCryptoServerConfig* crypto_config);
+ const QuicCryptoServerConfig* crypto_config,
+ QuicCompressedCertsCache* compressed_certs_cache);
~TestQuicSpdyServerSession() override;
MOCK_METHOD1(CreateIncomingDynamicStream, QuicSpdyStream*(QuicStreamId id));
MOCK_METHOD1(CreateOutgoingDynamicStream,
QuicSpdyStream*(SpdyPriority priority));
QuicCryptoServerStreamBase* CreateQuicCryptoServerStream(
- const QuicCryptoServerConfig* crypto_config) override;
+ const QuicCryptoServerConfig* crypto_config,
+ QuicCompressedCertsCache* compressed_certs_cache) override;
QuicCryptoServerStream* GetCryptoStream() override;
@@ -742,9 +736,6 @@ class MockQuicConnectionDebugVisitor : public QuicConnectionDebugVisitor {
MOCK_METHOD1(OnVersionNegotiationPacket,
void(const QuicVersionNegotiationPacket&));
-
- MOCK_METHOD2(OnRevivedPacket,
- void(const QuicPacketHeader&, StringPiece payload));
};
class MockReceivedPacketManager : public QuicReceivedPacketManager {
@@ -756,7 +747,6 @@ class MockReceivedPacketManager : public QuicReceivedPacketManager {
void(QuicByteCount bytes,
const QuicPacketHeader& header,
QuicTime receipt_time));
- MOCK_METHOD1(RecordPacketRevived, void(QuicPacketNumber packet_number));
MOCK_METHOD1(IsMissing, bool(QuicPacketNumber packet_number));
MOCK_METHOD1(IsAwaitingPacket, bool(QuicPacketNumber packet_number));
MOCK_METHOD1(UpdatePacketInformationSentByPeer,
@@ -805,13 +795,15 @@ void CreateClientSessionForTest(QuicServerId server_id,
// server_session.
// server_session: Pointer reference for the newly created server
// session. The new object will be owned by the caller.
-void CreateServerSessionForTest(QuicServerId server_id,
- QuicTime::Delta connection_start_time,
- QuicVersionVector supported_versions,
- MockConnectionHelper* helper,
- QuicCryptoServerConfig* crypto_server_config,
- PacketSavingConnection** server_connection,
- TestQuicSpdyServerSession** server_session);
+void CreateServerSessionForTest(
+ QuicServerId server_id,
+ QuicTime::Delta connection_start_time,
+ QuicVersionVector supported_versions,
+ MockConnectionHelper* helper,
+ QuicCryptoServerConfig* crypto_server_config,
+ QuicCompressedCertsCache* compressed_certs_cache,
+ PacketSavingConnection** server_connection,
+ TestQuicSpdyServerSession** server_session);
// Helper to generate client side stream ids, generalizes
// kClientDataStreamId1 etc. above.
diff --git a/net/quic/test_tools/reliable_quic_stream_peer.cc b/net/quic/test_tools/reliable_quic_stream_peer.cc
index 97a7278..2b419bf 100644
--- a/net/quic/test_tools/reliable_quic_stream_peer.cc
+++ b/net/quic/test_tools/reliable_quic_stream_peer.cc
@@ -79,12 +79,6 @@ uint32_t ReliableQuicStreamPeer::SizeOfQueuedData(ReliableQuicStream* stream) {
}
// static
-void ReliableQuicStreamPeer::SetFecPolicy(ReliableQuicStream* stream,
- FecPolicy fec_policy) {
- stream->set_fec_policy(fec_policy);
-}
-
-// static
bool ReliableQuicStreamPeer::StreamContributesToConnectionFlowControl(
ReliableQuicStream* stream) {
return stream->stream_contributes_to_connection_flow_control_;
diff --git a/net/quic/test_tools/reliable_quic_stream_peer.h b/net/quic/test_tools/reliable_quic_stream_peer.h
index db172da..04bbe7b 100644
--- a/net/quic/test_tools/reliable_quic_stream_peer.h
+++ b/net/quic/test_tools/reliable_quic_stream_peer.h
@@ -35,8 +35,6 @@ class ReliableQuicStreamPeer {
static uint32_t SizeOfQueuedData(ReliableQuicStream* stream);
- static void SetFecPolicy(ReliableQuicStream* stream, FecPolicy fec_policy);
-
static bool StreamContributesToConnectionFlowControl(
ReliableQuicStream* stream);
diff --git a/net/quic/test_tools/simple_quic_framer.cc b/net/quic/test_tools/simple_quic_framer.cc
index 977a367..dd0e0cb 100644
--- a/net/quic/test_tools/simple_quic_framer.cc
+++ b/net/quic/test_tools/simple_quic_framer.cc
@@ -37,7 +37,6 @@ class SimpleFramerVisitor : public QuicFramerVisitorInterface {
const QuicVersionNegotiationPacket& packet) override {
version_negotiation_packet_.reset(new QuicVersionNegotiationPacket(packet));
}
- void OnRevivedPacket() override {}
bool OnUnauthenticatedPublicHeader(
const QuicPacketPublicHeader& header) override {
@@ -53,8 +52,6 @@ class SimpleFramerVisitor : public QuicFramerVisitorInterface {
return true;
}
- void OnFecProtectedPayload(StringPiece payload) override {}
-
bool OnStreamFrame(const QuicStreamFrame& frame) override {
// Save a copy of the data so it is valid after the packet is processed.
string* string_data = new string();
@@ -82,10 +79,6 @@ class SimpleFramerVisitor : public QuicFramerVisitorInterface {
return true;
}
- void OnFecData(StringPiece redundancy) override {
- fec_redundancy_ = redundancy.as_string();
- }
-
bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override {
rst_stream_frames_.push_back(frame);
return true;
@@ -136,7 +129,6 @@ class SimpleFramerVisitor : public QuicFramerVisitorInterface {
return stop_waiting_frames_;
}
const vector<QuicPingFrame>& ping_frames() const { return ping_frames_; }
- StringPiece fec_data() const { return fec_redundancy_; }
const QuicVersionNegotiationPacket* version_negotiation_packet() const {
return version_negotiation_packet_.get();
}
@@ -147,7 +139,6 @@ class SimpleFramerVisitor : public QuicFramerVisitorInterface {
QuicPacketHeader header_;
scoped_ptr<QuicVersionNegotiationPacket> version_negotiation_packet_;
scoped_ptr<QuicPublicResetPacket> public_reset_packet_;
- string fec_redundancy_;
vector<QuicAckFrame> ack_frames_;
vector<QuicStopWaitingFrame> stop_waiting_frames_;
vector<QuicPingFrame> ping_frames_;
@@ -187,10 +178,6 @@ const QuicPacketHeader& SimpleQuicFramer::header() const {
return visitor_->header();
}
-StringPiece SimpleQuicFramer::fec_data() const {
- return visitor_->fec_data();
-}
-
const QuicVersionNegotiationPacket*
SimpleQuicFramer::version_negotiation_packet() const {
return visitor_->version_negotiation_packet();
diff --git a/net/quic/test_tools/simple_quic_framer.h b/net/quic/test_tools/simple_quic_framer.h
index c476550..f09db61 100644
--- a/net/quic/test_tools/simple_quic_framer.h
+++ b/net/quic/test_tools/simple_quic_framer.h
@@ -46,7 +46,6 @@ class SimpleQuicFramer {
const std::vector<QuicGoAwayFrame>& goaway_frames() const;
const std::vector<QuicRstStreamFrame>& rst_stream_frames() const;
const std::vector<QuicStreamFrame*>& stream_frames() const;
- base::StringPiece fec_data() const;
const QuicVersionNegotiationPacket* version_negotiation_packet() const;
QuicFramer* framer();
diff --git a/net/spdy/buffered_spdy_framer.cc b/net/spdy/buffered_spdy_framer.cc
index e76b83d..e7e3d3d 100644
--- a/net/spdy/buffered_spdy_framer.cc
+++ b/net/spdy/buffered_spdy_framer.cc
@@ -202,7 +202,7 @@ void BufferedSpdyFramer::OnStreamFrameData(SpdyStreamId stream_id,
}
void BufferedSpdyFramer::OnStreamEnd(SpdyStreamId stream_id) {
- LOG(DFATAL) << "Unimplemented";
+ visitor_->OnStreamFrameData(stream_id, nullptr, 0, true);
}
void BufferedSpdyFramer::OnStreamPadding(SpdyStreamId stream_id, size_t len) {
diff --git a/net/spdy/spdy_framer.cc b/net/spdy/spdy_framer.cc
index e34345a..5c8d011 100644
--- a/net/spdy/spdy_framer.cc
+++ b/net/spdy/spdy_framer.cc
@@ -14,6 +14,7 @@
#include "base/lazy_instance.h"
#include "base/memory/scoped_ptr.h"
#include "base/metrics/histogram_macros.h"
+#include "net/quic/quic_flags.h"
#include "net/spdy/hpack/hpack_constants.h"
#include "net/spdy/spdy_frame_builder.h"
#include "net/spdy/spdy_frame_reader.h"
@@ -171,7 +172,8 @@ SpdyFramer::SpdyFramer(SpdyMajorVersion version)
enable_compression_(true),
syn_frame_processed_(false),
probable_http_response_(false),
- end_stream_when_done_(false) {
+ end_stream_when_done_(false),
+ spdy_on_stream_end_(FLAGS_spdy_on_stream_end) {
DCHECK(protocol_version_ == SPDY3 || protocol_version_ == HTTP2);
DCHECK_LE(kMaxControlFrameSize,
SpdyConstants::GetFrameMaximumSize(protocol_version_) +
@@ -830,8 +832,12 @@ size_t SpdyFramer::ProcessCommonHeader(const char* data, size_t len) {
} else {
// Empty data frame.
if (current_frame_flags_ & DATA_FLAG_FIN) {
- visitor_->OnStreamFrameData(
- current_frame_stream_id_, NULL, 0, true);
+ if (spdy_on_stream_end_) {
+ visitor_->OnStreamEnd(current_frame_stream_id_);
+ } else {
+ visitor_->OnStreamFrameData(current_frame_stream_id_, nullptr, 0,
+ true);
+ }
}
CHANGE_STATE(SPDY_FRAME_COMPLETE);
}
@@ -2099,7 +2105,11 @@ size_t SpdyFramer::ProcessFramePadding(const char* data, size_t len) {
((current_frame_flags_ & CONTROL_FLAG_FIN) != 0 ||
end_stream_when_done_)) {
end_stream_when_done_ = false;
- visitor_->OnStreamFrameData(current_frame_stream_id_, NULL, 0, true);
+ if (spdy_on_stream_end_) {
+ visitor_->OnStreamEnd(current_frame_stream_id_);
+ } else {
+ visitor_->OnStreamFrameData(current_frame_stream_id_, nullptr, 0, true);
+ }
}
CHANGE_STATE(SPDY_FRAME_COMPLETE);
}
diff --git a/net/spdy/spdy_framer.h b/net/spdy/spdy_framer.h
index 30e7899..6261777 100644
--- a/net/spdy/spdy_framer.h
+++ b/net/spdy/spdy_framer.h
@@ -795,6 +795,11 @@ class NET_EXPORT_PRIVATE SpdyFramer {
// If true, then ProcessInput returns after processing a full frame,
// rather than reading all available input.
bool process_single_input_frame_ = false;
+
+ // Latched value of --FLAGS_spdy_on_stream_end.
+ // If true, OnStreamEnd will be called instead of the sentinel call of
+ // OnStreamFrameData(stream_id, nullptr, 0, true)
+ bool spdy_on_stream_end_;
};
} // namespace net
diff --git a/net/spdy/spdy_framer_test.cc b/net/spdy/spdy_framer_test.cc
index 2dcc855..5e41327 100644
--- a/net/spdy/spdy_framer_test.cc
+++ b/net/spdy/spdy_framer_test.cc
@@ -16,6 +16,7 @@
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
+#include "net/quic/quic_flags.h"
#include "net/spdy/hpack/hpack_constants.h"
#include "net/spdy/mock_spdy_framer_visitor.h"
#include "net/spdy/spdy_frame_builder.h"
@@ -281,7 +282,7 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface,
fin_frame_count_(0),
fin_opaque_data_(),
fin_flag_count_(0),
- zero_length_data_frame_count_(0),
+ end_of_stream_count_(0),
control_frame_header_data_count_(0),
zero_length_control_frame_header_data_count_(0),
data_frame_count_(0),
@@ -312,8 +313,10 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface,
size_t len,
bool fin) override {
EXPECT_EQ(header_stream_id_, stream_id);
- if (len == 0) {
- ++zero_length_data_frame_count_;
+ if (!FLAGS_spdy_on_stream_end) {
+ if (len == 0) {
+ ++end_of_stream_count_;
+ }
}
data_bytes_ += len;
@@ -328,7 +331,9 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface,
}
void OnStreamEnd(SpdyStreamId stream_id) override {
- LOG(DFATAL) << "Unimplemented.";
+ LOG(INFO) << "OnStreamEnd(" << stream_id << ")";
+ EXPECT_EQ(header_stream_id_, stream_id);
+ ++end_of_stream_count_;
}
void OnStreamPadding(SpdyStreamId stream_id, size_t len) override {
@@ -587,7 +592,7 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface,
int fin_frame_count_; // The count of RST_STREAM type frames received.
string fin_opaque_data_;
int fin_flag_count_; // The count of frames with the FIN flag set.
- int zero_length_data_frame_count_; // The count of zero-length data frames.
+ int end_of_stream_count_; // The count of zero-length data frames.
int control_frame_header_data_count_; // The count of chunks received.
// The count of zero-length control frame header data chunks received.
int zero_length_control_frame_header_data_count_;
@@ -1207,7 +1212,7 @@ TEST_P(SpdyFramerTest, Basic) {
}
EXPECT_EQ(0, visitor.fin_flag_count_);
- EXPECT_EQ(0, visitor.zero_length_data_frame_count_);
+ EXPECT_EQ(0, visitor.end_of_stream_count_);
EXPECT_EQ(4, visitor.data_frame_count_);
visitor.fin_opaque_data_.clear();
}
@@ -1289,7 +1294,7 @@ TEST_P(SpdyFramerTest, FinOnDataFrame) {
EXPECT_EQ(16, visitor.data_bytes_);
EXPECT_EQ(0, visitor.fin_frame_count_);
EXPECT_EQ(0, visitor.fin_flag_count_);
- EXPECT_EQ(1, visitor.zero_length_data_frame_count_);
+ EXPECT_EQ(1, visitor.end_of_stream_count_);
EXPECT_EQ(2, visitor.data_frame_count_);
}
@@ -1348,7 +1353,7 @@ TEST_P(SpdyFramerTest, FinOnSynReplyFrame) {
EXPECT_EQ(0, visitor.data_bytes_);
EXPECT_EQ(0, visitor.fin_frame_count_);
EXPECT_EQ(1, visitor.fin_flag_count_);
- EXPECT_EQ(1, visitor.zero_length_data_frame_count_);
+ EXPECT_EQ(1, visitor.end_of_stream_count_);
EXPECT_EQ(0, visitor.data_frame_count_);
}
@@ -1466,7 +1471,7 @@ TEST_P(SpdyFramerTest, UnclosedStreamDataCompressorsOneByteAtATime) {
EXPECT_EQ(arraysize(bytes), static_cast<unsigned>(visitor.data_bytes_));
EXPECT_EQ(0, visitor.fin_frame_count_);
EXPECT_EQ(0, visitor.fin_flag_count_);
- EXPECT_EQ(1, visitor.zero_length_data_frame_count_);
+ EXPECT_EQ(1, visitor.end_of_stream_count_);
EXPECT_EQ(1, visitor.data_frame_count_);
}
@@ -3196,7 +3201,7 @@ TEST_P(SpdyFramerTest, ReadCompressedHeadersHeaderBlock) {
// at least twice.
EXPECT_LE(2, visitor.control_frame_header_data_count_);
EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_);
- EXPECT_EQ(0, visitor.zero_length_data_frame_count_);
+ EXPECT_EQ(0, visitor.end_of_stream_count_);
EXPECT_EQ(headers, visitor.headers_);
}
@@ -3221,7 +3226,7 @@ TEST_P(SpdyFramerTest, ReadCompressedHeadersHeaderBlockWithHalfClose) {
// at least twice.
EXPECT_LE(2, visitor.control_frame_header_data_count_);
EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_);
- EXPECT_EQ(1, visitor.zero_length_data_frame_count_);
+ EXPECT_EQ(1, visitor.end_of_stream_count_);
EXPECT_EQ(headers, visitor.headers_);
}
@@ -3258,7 +3263,7 @@ TEST_P(SpdyFramerTest, ControlFrameAtMaxSizeLimit) {
EXPECT_EQ(0, visitor.error_count_);
EXPECT_EQ(1, visitor.syn_frame_count_);
EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_);
- EXPECT_EQ(0, visitor.zero_length_data_frame_count_);
+ EXPECT_EQ(0, visitor.end_of_stream_count_);
EXPECT_LT(kBigValueSize, visitor.header_buffer_length_);
}
@@ -3403,7 +3408,7 @@ TEST_P(SpdyFramerTest, ControlFrameMuchTooLarge) {
EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
// The framer should not have sent half-close to the visitor.
- EXPECT_EQ(0, visitor.zero_length_data_frame_count_);
+ EXPECT_EQ(0, visitor.end_of_stream_count_);
}
TEST_P(SpdyFramerTest, DecompressCorruptHeaderBlock) {
@@ -3860,7 +3865,7 @@ TEST_P(SpdyFramerTest, ReadHeadersWithContinuation) {
EXPECT_EQ(2, visitor.continuation_count_);
EXPECT_EQ(1, visitor.fin_flag_count_);
EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_);
- EXPECT_EQ(1, visitor.zero_length_data_frame_count_);
+ EXPECT_EQ(1, visitor.end_of_stream_count_);
EXPECT_THAT(visitor.headers_,
testing::ElementsAre(
@@ -3910,7 +3915,7 @@ TEST_P(SpdyFramerTest, ReadPushPromiseWithContinuation) {
EXPECT_EQ(42u, visitor.last_push_promise_promised_stream_);
EXPECT_EQ(2, visitor.continuation_count_);
EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_);
- EXPECT_EQ(0, visitor.zero_length_data_frame_count_);
+ EXPECT_EQ(0, visitor.end_of_stream_count_);
EXPECT_THAT(visitor.headers_,
testing::ElementsAre(
@@ -4384,6 +4389,50 @@ TEST_P(SpdyFramerTest, CatchProbableHttpResponse) {
}
TEST_P(SpdyFramerTest, DataFrameFlagsV2V3) {
+ FLAGS_spdy_on_stream_end = true;
+
+ if (!IsSpdy3()) {
+ return;
+ }
+
+ uint8_t flags = 0;
+ do {
+ SCOPED_TRACE(testing::Message() << "Flags " << flags);
+
+ testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+ SpdyFramer framer(spdy_version_);
+ framer.set_visitor(&visitor);
+
+ SpdyDataIR data_ir(1, "hello");
+ scoped_ptr<SpdyFrame> frame(framer.SerializeData(data_ir));
+ SetFrameFlags(frame.get(), flags, spdy_version_);
+
+ if (flags & ~DATA_FLAG_FIN) {
+ EXPECT_CALL(visitor, OnError(_));
+ } else {
+ EXPECT_CALL(visitor, OnDataFrameHeader(1, 5, flags & DATA_FLAG_FIN));
+ EXPECT_CALL(visitor, OnStreamFrameData(_, _, 5, false));
+ if (flags & DATA_FLAG_FIN) {
+ EXPECT_CALL(visitor, OnStreamEnd(_));
+ }
+ }
+
+ framer.ProcessInput(frame->data(), frame->size());
+ if (flags & ~DATA_FLAG_FIN) {
+ EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_INVALID_DATA_FRAME_FLAGS, framer.error_code())
+ << SpdyFramer::ErrorCodeToString(framer.error_code());
+ } else {
+ EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code())
+ << SpdyFramer::ErrorCodeToString(framer.error_code());
+ }
+ } while (++flags != 0);
+}
+
+TEST_P(SpdyFramerTest, DataFrameFlagsV2V3disabled) {
+ FLAGS_spdy_on_stream_end = false;
+
if (!IsSpdy3()) {
return;
}
@@ -4425,6 +4474,60 @@ TEST_P(SpdyFramerTest, DataFrameFlagsV2V3) {
}
TEST_P(SpdyFramerTest, DataFrameFlagsV4) {
+ FLAGS_spdy_on_stream_end = true;
+
+ if (!IsHttp2()) {
+ return;
+ }
+
+ uint8_t valid_data_flags =
+ DATA_FLAG_FIN | DATA_FLAG_END_SEGMENT | DATA_FLAG_PADDED;
+
+ uint8_t flags = 0;
+ do {
+ SCOPED_TRACE(testing::Message() << "Flags " << flags);
+
+ testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+ SpdyFramer framer(spdy_version_);
+ framer.set_visitor(&visitor);
+
+ SpdyDataIR data_ir(1, "hello");
+ scoped_ptr<SpdyFrame> frame(framer.SerializeData(data_ir));
+ SetFrameFlags(frame.get(), flags, spdy_version_);
+
+ if (flags & ~valid_data_flags) {
+ EXPECT_CALL(visitor, OnError(_));
+ } else {
+ EXPECT_CALL(visitor, OnDataFrameHeader(1, 5, flags & DATA_FLAG_FIN));
+ if (flags & DATA_FLAG_PADDED) {
+ // The first byte of payload is parsed as padding length.
+ EXPECT_CALL(visitor, OnStreamPadding(_, 1));
+ // Expect Error since the frame ends prematurely.
+ EXPECT_CALL(visitor, OnError(_));
+ } else {
+ EXPECT_CALL(visitor, OnStreamFrameData(_, _, 5, false));
+ if (flags & DATA_FLAG_FIN) {
+ EXPECT_CALL(visitor, OnStreamEnd(_));
+ }
+ }
+ }
+
+ framer.ProcessInput(frame->data(), frame->size());
+ if ((flags & ~valid_data_flags) || (flags & DATA_FLAG_PADDED)) {
+ EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_INVALID_DATA_FRAME_FLAGS, framer.error_code())
+ << SpdyFramer::ErrorCodeToString(framer.error_code());
+ } else {
+ EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code())
+ << SpdyFramer::ErrorCodeToString(framer.error_code());
+ }
+ } while (++flags != 0);
+}
+
+TEST_P(SpdyFramerTest, DataFrameFlagsV4disabled) {
+ FLAGS_spdy_on_stream_end = false;
+
if (!IsHttp2()) {
return;
}
@@ -4475,6 +4578,64 @@ TEST_P(SpdyFramerTest, DataFrameFlagsV4) {
}
TEST_P(SpdyFramerTest, SynStreamFrameFlags) {
+ FLAGS_spdy_on_stream_end = true;
+
+ if (!IsSpdy3()) {
+ return;
+ }
+
+ uint8_t flags = 0;
+ do {
+ SCOPED_TRACE(testing::Message() << "Flags " << flags);
+
+ testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+ testing::StrictMock<test::MockDebugVisitor> debug_visitor;
+ SpdyFramer framer(spdy_version_);
+ framer.set_visitor(&visitor);
+ framer.set_debug_visitor(&debug_visitor);
+
+ EXPECT_CALL(debug_visitor, OnSendCompressedFrame(8, SYN_STREAM, _, _));
+
+ SpdySynStreamIR syn_stream(8);
+ syn_stream.set_associated_to_stream_id(3);
+ syn_stream.set_priority(1);
+ syn_stream.SetHeader("foo", "bar");
+ scoped_ptr<SpdyFrame> frame(framer.SerializeSynStream(syn_stream));
+ SetFrameFlags(frame.get(), flags, spdy_version_);
+
+ if (flags & ~(CONTROL_FLAG_FIN | CONTROL_FLAG_UNIDIRECTIONAL)) {
+ EXPECT_CALL(visitor, OnError(_));
+ } else {
+ EXPECT_CALL(debug_visitor, OnReceiveCompressedFrame(8, SYN_STREAM, _));
+ EXPECT_CALL(visitor, OnSynStream(8, 3, 1, flags & CONTROL_FLAG_FIN,
+ flags & CONTROL_FLAG_UNIDIRECTIONAL));
+ EXPECT_CALL(visitor, OnControlFrameHeaderData(8, _, _))
+ .WillRepeatedly(testing::Return(true));
+ if (flags & DATA_FLAG_FIN) {
+ EXPECT_CALL(visitor, OnStreamEnd(_));
+ } else {
+ // Do not close the stream if we are expecting a CONTINUATION frame.
+ EXPECT_CALL(visitor, OnStreamEnd(_)).Times(0);
+ }
+ }
+
+ framer.ProcessInput(frame->data(), frame->size());
+ if (flags & ~(CONTROL_FLAG_FIN | CONTROL_FLAG_UNIDIRECTIONAL)) {
+ EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS,
+ framer.error_code())
+ << SpdyFramer::ErrorCodeToString(framer.error_code());
+ } else {
+ EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code())
+ << SpdyFramer::ErrorCodeToString(framer.error_code());
+ }
+ } while (++flags != 0);
+}
+
+TEST_P(SpdyFramerTest, SynStreamFrameFlagsDisabled) {
+ FLAGS_spdy_on_stream_end = false;
+
if (!IsSpdy3()) {
return;
}
@@ -4529,6 +4690,53 @@ TEST_P(SpdyFramerTest, SynStreamFrameFlags) {
}
TEST_P(SpdyFramerTest, SynReplyFrameFlags) {
+ FLAGS_spdy_on_stream_end = true;
+
+ if (!IsSpdy3()) {
+ return;
+ }
+
+ uint8_t flags = 0;
+ do {
+ SCOPED_TRACE(testing::Message() << "Flags " << flags);
+
+ testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+ SpdyFramer framer(spdy_version_);
+ framer.set_visitor(&visitor);
+
+ SpdySynReplyIR syn_reply(37);
+ syn_reply.SetHeader("foo", "bar");
+ scoped_ptr<SpdyFrame> frame(framer.SerializeSynReply(syn_reply));
+ SetFrameFlags(frame.get(), flags, spdy_version_);
+
+ if (flags & ~CONTROL_FLAG_FIN) {
+ EXPECT_CALL(visitor, OnError(_));
+ } else {
+ EXPECT_CALL(visitor, OnSynReply(37, flags & CONTROL_FLAG_FIN));
+ EXPECT_CALL(visitor, OnControlFrameHeaderData(37, _, _))
+ .WillRepeatedly(testing::Return(true));
+ if (flags & DATA_FLAG_FIN) {
+ EXPECT_CALL(visitor, OnStreamEnd(_));
+ }
+ }
+
+ framer.ProcessInput(frame->data(), frame->size());
+ if (flags & ~CONTROL_FLAG_FIN) {
+ EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS,
+ framer.error_code())
+ << SpdyFramer::ErrorCodeToString(framer.error_code());
+ } else {
+ EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code())
+ << SpdyFramer::ErrorCodeToString(framer.error_code());
+ }
+ } while (++flags != 0);
+}
+
+TEST_P(SpdyFramerTest, SynReplyFrameFlagsDisabled) {
+ FLAGS_spdy_on_stream_end = false;
+
if (!IsSpdy3()) {
return;
}
@@ -4729,6 +4937,99 @@ TEST_P(SpdyFramerTest, GoawayFrameFlags) {
}
TEST_P(SpdyFramerTest, HeadersFrameFlags) {
+ FLAGS_spdy_on_stream_end = true;
+
+ uint8_t flags = 0;
+ do {
+ SCOPED_TRACE(testing::Message() << "Flags " << flags);
+
+ testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+ SpdyFramer framer(spdy_version_);
+ framer.set_visitor(&visitor);
+
+ SpdyHeadersIR headers_ir(57);
+ if (IsHttp2() && (flags & HEADERS_FLAG_PRIORITY)) {
+ headers_ir.set_priority(3);
+ headers_ir.set_has_priority(true);
+ headers_ir.set_parent_stream_id(5);
+ headers_ir.set_exclusive(true);
+ }
+ headers_ir.SetHeader("foo", "bar");
+ std::unique_ptr<SpdyFrame> frame(framer.SerializeHeaders(headers_ir));
+ uint8_t set_flags = flags;
+ if (IsHttp2()) {
+ // TODO(jgraettinger): Add padding to SpdyHeadersIR,
+ // and implement framing.
+ set_flags &= ~HEADERS_FLAG_PADDED;
+ }
+ SetFrameFlags(frame.get(), set_flags, spdy_version_);
+
+ if (!IsHttp2() && flags & ~CONTROL_FLAG_FIN) {
+ EXPECT_CALL(visitor, OnError(_));
+ } else if (IsHttp2() &&
+ flags &
+ ~(CONTROL_FLAG_FIN | HEADERS_FLAG_END_HEADERS |
+ HEADERS_FLAG_END_SEGMENT | HEADERS_FLAG_PADDED |
+ HEADERS_FLAG_PRIORITY)) {
+ EXPECT_CALL(visitor, OnError(_));
+ } else {
+ // Expected callback values
+ SpdyStreamId stream_id = 57;
+ bool has_priority = false;
+ SpdyPriority priority = 0;
+ SpdyStreamId parent_stream_id = 0;
+ bool exclusive = false;
+ bool fin = flags & CONTROL_FLAG_FIN;
+ bool end = IsSpdy3() || (flags & HEADERS_FLAG_END_HEADERS);
+ if (IsHttp2() && flags & HEADERS_FLAG_PRIORITY) {
+ has_priority = true;
+ priority = 3;
+ parent_stream_id = 5;
+ exclusive = true;
+ }
+ EXPECT_CALL(visitor, OnHeaders(stream_id, has_priority, priority,
+ parent_stream_id, exclusive, fin, end));
+ EXPECT_CALL(visitor, OnControlFrameHeaderData(57, _, _))
+ .WillRepeatedly(testing::Return(true));
+ if (flags & DATA_FLAG_FIN &&
+ (IsSpdy3() || flags & HEADERS_FLAG_END_HEADERS)) {
+ EXPECT_CALL(visitor, OnStreamEnd(_));
+ } else {
+ // Do not close the stream if we are expecting a CONTINUATION frame.
+ EXPECT_CALL(visitor, OnStreamEnd(_)).Times(0);
+ }
+ }
+
+ framer.ProcessInput(frame->data(), frame->size());
+ if (IsSpdy3() && flags & ~CONTROL_FLAG_FIN) {
+ EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS,
+ framer.error_code())
+ << SpdyFramer::ErrorCodeToString(framer.error_code());
+ } else if (IsHttp2() &&
+ flags &
+ ~(CONTROL_FLAG_FIN | HEADERS_FLAG_END_HEADERS |
+ HEADERS_FLAG_END_SEGMENT | HEADERS_FLAG_PADDED |
+ HEADERS_FLAG_PRIORITY)) {
+ EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS,
+ framer.error_code())
+ << SpdyFramer::ErrorCodeToString(framer.error_code());
+ } else if (IsHttp2() && ~(flags & HEADERS_FLAG_END_HEADERS)) {
+ EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code())
+ << SpdyFramer::ErrorCodeToString(framer.error_code());
+ } else {
+ EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code())
+ << SpdyFramer::ErrorCodeToString(framer.error_code());
+ }
+ } while (++flags != 0);
+}
+
+TEST_P(SpdyFramerTest, HeadersFrameFlagsDisabled) {
+ FLAGS_spdy_on_stream_end = false;
+
uint8_t flags = 0;
do {
SCOPED_TRACE(testing::Message() << "Flags " << flags);
@@ -4756,11 +5057,11 @@ TEST_P(SpdyFramerTest, HeadersFrameFlags) {
if (!IsHttp2() && flags & ~CONTROL_FLAG_FIN) {
EXPECT_CALL(visitor, OnError(_));
- } else if (IsHttp2() && flags & ~(CONTROL_FLAG_FIN |
- HEADERS_FLAG_END_HEADERS |
- HEADERS_FLAG_END_SEGMENT |
- HEADERS_FLAG_PADDED |
- HEADERS_FLAG_PRIORITY)) {
+ } else if (IsHttp2() &&
+ flags &
+ ~(CONTROL_FLAG_FIN | HEADERS_FLAG_END_HEADERS |
+ HEADERS_FLAG_END_SEGMENT | HEADERS_FLAG_PADDED |
+ HEADERS_FLAG_PRIORITY)) {
EXPECT_CALL(visitor, OnError(_));
} else {
// Expected callback values
diff --git a/net/tools/quic/end_to_end_test.cc b/net/tools/quic/end_to_end_test.cc
index 08e2c8b..441a5d9 100644
--- a/net/tools/quic/end_to_end_test.cc
+++ b/net/tools/quic/end_to_end_test.cc
@@ -92,7 +92,6 @@ struct TestParams {
TestParams(const QuicVersionVector& client_supported_versions,
const QuicVersionVector& server_supported_versions,
QuicVersion negotiated_version,
- bool use_fec,
bool client_supports_stateless_rejects,
bool server_uses_stateless_rejects_if_peer_supported,
QuicTag congestion_control_tag,
@@ -100,7 +99,6 @@ struct TestParams {
: client_supported_versions(client_supported_versions),
server_supported_versions(server_supported_versions),
negotiated_version(negotiated_version),
- use_fec(use_fec),
client_supports_stateless_rejects(client_supports_stateless_rejects),
server_uses_stateless_rejects_if_peer_supported(
server_uses_stateless_rejects_if_peer_supported),
@@ -117,7 +115,6 @@ struct TestParams {
<< p.client_supports_stateless_rejects;
os << " server_uses_stateless_rejects_if_peer_supported: "
<< p.server_uses_stateless_rejects_if_peer_supported;
- os << " use_fec: " << p.use_fec;
os << " congestion_control_tag: "
<< QuicUtils::TagToString(p.congestion_control_tag);
os << " auto_tune_flow_control_window: " << p.auto_tune_flow_control_window
@@ -128,7 +125,6 @@ struct TestParams {
QuicVersionVector client_supported_versions;
QuicVersionVector server_supported_versions;
QuicVersion negotiated_version;
- bool use_fec;
bool client_supports_stateless_rejects;
bool server_uses_stateless_rejects_if_peer_supported;
QuicTag congestion_control_tag;
@@ -164,62 +160,56 @@ vector<TestParams> GetTestParams() {
// TODO(rtenneti): Add kTBBR after BBR code is checked in.
for (const QuicTag congestion_control_tag : {kRENO, kQBIC}) {
for (bool auto_tune_flow_control_window : {true, false}) {
- for (const bool use_fec : {false, true}) {
- const int kMaxEnabledOptions = 5;
- int enabled_options = 0;
- if (congestion_control_tag != kQBIC) {
- ++enabled_options;
- }
- if (use_fec) {
- ++enabled_options;
- }
- if (auto_tune_flow_control_window) {
- ++enabled_options;
- }
- if (client_supports_stateless_rejects) {
- ++enabled_options;
- }
- if (server_uses_stateless_rejects_if_peer_supported) {
- ++enabled_options;
- }
- CHECK_GE(kMaxEnabledOptions, enabled_options);
+ const int kMaxEnabledOptions = 5;
+ int enabled_options = 0;
+ if (congestion_control_tag != kQBIC) {
+ ++enabled_options;
+ }
+ if (auto_tune_flow_control_window) {
+ ++enabled_options;
+ }
+ if (client_supports_stateless_rejects) {
+ ++enabled_options;
+ }
+ if (server_uses_stateless_rejects_if_peer_supported) {
+ ++enabled_options;
+ }
+ CHECK_GE(kMaxEnabledOptions, enabled_options);
+
+ // Run tests with no options, a single option, or all the options
+ // enabled to avoid a combinatorial explosion.
+ if (enabled_options > 1 && enabled_options < kMaxEnabledOptions) {
+ continue;
+ }
- // Run tests with no options, a single option, or all the options
- // enabled to avoid a combinatorial explosion.
- if (enabled_options > 1 && enabled_options < kMaxEnabledOptions) {
+ for (const QuicVersionVector& client_versions : version_buckets) {
+ CHECK(!client_versions.empty());
+ // Add an entry for server and client supporting all versions.
+ params.push_back(TestParams(
+ client_versions, all_supported_versions,
+ client_versions.front(), client_supports_stateless_rejects,
+ server_uses_stateless_rejects_if_peer_supported,
+ congestion_control_tag, auto_tune_flow_control_window));
+
+ // Run version negotiation tests tests with no options, or all
+ // the options enabled to avoid a combinatorial explosion.
+ if (enabled_options > 0 && enabled_options < kMaxEnabledOptions) {
continue;
}
- for (const QuicVersionVector& client_versions : version_buckets) {
- CHECK(!client_versions.empty());
- // Add an entry for server and client supporting all versions.
+ // Test client supporting all versions and server supporting 1
+ // version. Simulate an old server and exercise version downgrade
+ // in the client. Protocol negotiation should occur. Skip the i =
+ // 0 case because it is essentially the same as the default case.
+ for (size_t i = 1; i < client_versions.size(); ++i) {
+ QuicVersionVector server_supported_versions;
+ server_supported_versions.push_back(client_versions[i]);
params.push_back(TestParams(
- client_versions, all_supported_versions,
- client_versions.front(), use_fec,
+ client_versions, server_supported_versions,
+ server_supported_versions.front(),
client_supports_stateless_rejects,
server_uses_stateless_rejects_if_peer_supported,
congestion_control_tag, auto_tune_flow_control_window));
-
- // Run version negotiation tests tests with no options, or all
- // the options enabled to avoid a combinatorial explosion.
- if (enabled_options > 0 && enabled_options < kMaxEnabledOptions) {
- continue;
- }
-
- // Test client supporting all versions and server supporting 1
- // version. Simulate an old server and exercise version downgrade
- // in the client. Protocol negotiation should occur. Skip the i =
- // 0 case because it is essentially the same as the default case.
- for (size_t i = 1; i < client_versions.size(); ++i) {
- QuicVersionVector server_supported_versions;
- server_supported_versions.push_back(client_versions[i]);
- params.push_back(TestParams(
- client_versions, server_supported_versions,
- server_supported_versions.front(), use_fec,
- client_supports_stateless_rejects,
- server_uses_stateless_rejects_if_peer_supported,
- congestion_control_tag, auto_tune_flow_control_window));
- }
}
}
}
@@ -352,10 +342,6 @@ class EndToEndTest : public ::testing::TestWithParam<TestParams> {
// client as well according to the test parameter.
copt.push_back(GetParam().congestion_control_tag);
- if (GetParam().use_fec) {
- // Set FEC config in client's connection options and in client session.
- copt.push_back(kFHDR);
- }
if (GetParam().client_supports_stateless_rejects) {
copt.push_back(kSREJ);
}
@@ -801,14 +787,9 @@ TEST_P(EndToEndTest, LargePostZeroRTTFailure) {
client_->WaitForResponseForMs(-1);
ASSERT_TRUE(client_->client()->connected());
EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request));
- if (FLAGS_require_strike_register_or_server_nonce) {
- EXPECT_EQ(expected_num_hellos_latest_session,
- client_->client()->session()->GetNumSentClientHellos());
- EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
- } else {
- EXPECT_EQ(1, client_->client()->session()->GetNumSentClientHellos());
- EXPECT_EQ(1, client_->client()->GetNumSentClientHellos());
- }
+ EXPECT_EQ(expected_num_hellos_latest_session,
+ client_->client()->session()->GetNumSentClientHellos());
+ EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
client_->Disconnect();
@@ -859,14 +840,9 @@ TEST_P(EndToEndTest, SynchronousRequestZeroRTTFailure) {
client_->WaitForInitialResponse();
ASSERT_TRUE(client_->client()->connected());
EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
- if (FLAGS_require_strike_register_or_server_nonce) {
- EXPECT_EQ(expected_num_hellos_latest_session,
- client_->client()->session()->GetNumSentClientHellos());
- EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
- } else {
- EXPECT_EQ(1, client_->client()->session()->GetNumSentClientHellos());
- EXPECT_EQ(1, client_->client()->GetNumSentClientHellos());
- }
+ EXPECT_EQ(expected_num_hellos_latest_session,
+ client_->client()->session()->GetNumSentClientHellos());
+ EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
client_->Disconnect();
@@ -923,14 +899,9 @@ TEST_P(EndToEndTest, LargePostSynchronousRequest) {
client_->WaitForInitialResponse();
ASSERT_TRUE(client_->client()->connected());
EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request));
- if (FLAGS_require_strike_register_or_server_nonce) {
- EXPECT_EQ(expected_num_hellos_latest_session,
- client_->client()->session()->GetNumSentClientHellos());
- EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
- } else {
- EXPECT_EQ(1, client_->client()->session()->GetNumSentClientHellos());
- EXPECT_EQ(1, client_->client()->GetNumSentClientHellos());
- }
+ EXPECT_EQ(expected_num_hellos_latest_session,
+ client_->client()->session()->GetNumSentClientHellos());
+ EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
client_->Disconnect();
@@ -988,30 +959,6 @@ TEST_P(EndToEndTest, SetInitialReceivedConnectionOptions) {
ContainsQuicTag(server_config_.ReceivedConnectionOptions(), kPRST));
}
-TEST_P(EndToEndTest, CorrectlyConfiguredFec) {
- ASSERT_TRUE(Initialize());
- client_->client()->WaitForCryptoHandshakeConfirmed();
- server_thread_->WaitForCryptoHandshakeConfirmed();
-
- FecPolicy expected_policy = FEC_PROTECT_OPTIONAL;
-
- // Verify that server's FEC configuration is correct.
- server_thread_->Pause();
- QuicDispatcher* dispatcher =
- QuicServerPeer::GetDispatcher(server_thread_->server());
- ASSERT_EQ(1u, dispatcher->session_map().size());
- QuicSpdySession* session = dispatcher->session_map().begin()->second;
- EXPECT_EQ(expected_policy,
- QuicSpdySessionPeer::GetHeadersStream(session)->fec_policy());
- server_thread_->Resume();
-
- // Verify that client's FEC configuration is correct.
- EXPECT_EQ(expected_policy,
- QuicSpdySessionPeer::GetHeadersStream(client_->client()->session())
- ->fec_policy());
- EXPECT_EQ(expected_policy, client_->GetOrCreateStream()->fec_policy());
-}
-
TEST_P(EndToEndTest, LargePostSmallBandwidthLargeBuffer) {
ASSERT_TRUE(Initialize());
SetPacketSendDelay(QuicTime::Delta::FromMicroseconds(1));
diff --git a/net/tools/quic/quic_client_session_test.cc b/net/tools/quic/quic_client_session_test.cc
index ac65bf5..aef861c 100644
--- a/net/tools/quic/quic_client_session_test.cc
+++ b/net/tools/quic/quic_client_session_test.cc
@@ -137,7 +137,6 @@ TEST_P(QuicClientSessionTest, CryptoConnect) {
}
TEST_P(QuicClientSessionTest, NoEncryptionAfterInitialEncryption) {
- ValueRestore<bool> old_flag(&FLAGS_quic_block_unencrypted_writes, true);
// Complete a handshake in order to prime the crypto config for 0-RTT.
CompleteCryptoHandshake();
@@ -171,8 +170,8 @@ TEST_P(QuicClientSessionTest, NoEncryptionAfterInitialEncryption) {
char data[] = "hello world";
struct iovec iov = {data, arraysize(data)};
QuicIOVector iovector(&iov, 1, iov.iov_len);
- QuicConsumedData consumed = session_->WritevData(
- stream->id(), iovector, 0, false, MAY_FEC_PROTECT, nullptr);
+ QuicConsumedData consumed =
+ session_->WritevData(stream->id(), iovector, 0, false, nullptr);
EXPECT_FALSE(consumed.fin_consumed);
EXPECT_EQ(0u, consumed.bytes_consumed);
}
diff --git a/net/tools/quic/quic_dispatcher.cc b/net/tools/quic/quic_dispatcher.cc
index 9cb1059..f662ee3 100644
--- a/net/tools/quic/quic_dispatcher.cc
+++ b/net/tools/quic/quic_dispatcher.cc
@@ -30,11 +30,7 @@ class DeleteSessionsAlarm : public QuicAlarm::Delegate {
explicit DeleteSessionsAlarm(QuicDispatcher* dispatcher)
: dispatcher_(dispatcher) {}
- QuicTime OnAlarm() override {
- dispatcher_->DeleteSessions();
- // Let the dispatcher register the alarm at appropriate time.
- return QuicTime::Zero();
- }
+ void OnAlarm() override { dispatcher_->DeleteSessions(); }
private:
// Not owned.
@@ -51,6 +47,8 @@ QuicDispatcher::QuicDispatcher(const QuicConfig& config,
QuicConnectionHelperInterface* helper)
: config_(config),
crypto_config_(crypto_config),
+ compressed_certs_cache_(
+ QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
helper_(helper),
delete_sessions_alarm_(
helper_->CreateAlarm(new DeleteSessionsAlarm(this))),
@@ -387,14 +385,6 @@ bool QuicDispatcher::OnPacketHeader(const QuicPacketHeader& /*header*/) {
return false;
}
-void QuicDispatcher::OnRevivedPacket() {
- DCHECK(false);
-}
-
-void QuicDispatcher::OnFecProtectedPayload(StringPiece /*payload*/) {
- DCHECK(false);
-}
-
bool QuicDispatcher::OnStreamFrame(const QuicStreamFrame& /*frame*/) {
DCHECK(false);
return false;
@@ -447,10 +437,6 @@ bool QuicDispatcher::OnPathCloseFrame(const QuicPathCloseFrame& frame) {
return false;
}
-void QuicDispatcher::OnFecData(StringPiece /*redundancy*/) {
- DCHECK(false);
-}
-
void QuicDispatcher::OnPacketComplete() {
DCHECK(false);
}
@@ -463,8 +449,8 @@ QuicServerSessionBase* QuicDispatcher::CreateQuicSession(
connection_id, client_address, helper_.get(), CreatePerConnectionWriter(),
/* owns_writer= */ true, Perspective::IS_SERVER, supported_versions_);
- QuicServerSessionBase* session =
- new QuicSimpleServerSession(config_, connection, this, crypto_config_);
+ QuicServerSessionBase* session = new QuicSimpleServerSession(
+ config_, connection, this, crypto_config_, &compressed_certs_cache_);
session->Initialize();
return session;
}
diff --git a/net/tools/quic/quic_dispatcher.h b/net/tools/quic/quic_dispatcher.h
index 3a96176..6ba8f2b 100644
--- a/net/tools/quic/quic_dispatcher.h
+++ b/net/tools/quic/quic_dispatcher.h
@@ -16,6 +16,7 @@
#include "base/memory/scoped_ptr.h"
#include "net/base/ip_endpoint.h"
#include "net/base/linked_hash_map.h"
+#include "net/quic/crypto/quic_compressed_certs_cache.h"
#include "net/quic/quic_blocked_writer_interface.h"
#include "net/quic/quic_connection.h"
#include "net/quic/quic_protocol.h"
@@ -131,8 +132,6 @@ class QuicDispatcher : public QuicServerSessionVisitor,
const QuicVersionNegotiationPacket& packet) override;
void OnDecryptedPacket(EncryptionLevel level) override;
bool OnPacketHeader(const QuicPacketHeader& header) override;
- void OnRevivedPacket() override;
- void OnFecProtectedPayload(base::StringPiece payload) override;
bool OnStreamFrame(const QuicStreamFrame& frame) override;
bool OnAckFrame(const QuicAckFrame& frame) override;
bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override;
@@ -143,7 +142,6 @@ class QuicDispatcher : public QuicServerSessionVisitor,
bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override;
bool OnBlockedFrame(const QuicBlockedFrame& frame) override;
bool OnPathCloseFrame(const QuicPathCloseFrame& frame) override;
- void OnFecData(base::StringPiece redundancy) override;
void OnPacketComplete() override;
protected:
@@ -190,6 +188,10 @@ class QuicDispatcher : public QuicServerSessionVisitor,
const QuicCryptoServerConfig* crypto_config() const { return crypto_config_; }
+ QuicCompressedCertsCache* compressed_certs_cache() {
+ return &compressed_certs_cache_;
+ }
+
QuicFramer* framer() { return &framer_; }
QuicConnectionHelperInterface* helper() { return helper_.get(); }
@@ -223,6 +225,9 @@ class QuicDispatcher : public QuicServerSessionVisitor,
const QuicCryptoServerConfig* crypto_config_;
+ // The cache for most recently compressed certs.
+ QuicCompressedCertsCache compressed_certs_cache_;
+
// The list of connections waiting to write.
WriteBlockedList write_blocked_list_;
diff --git a/net/tools/quic/quic_dispatcher_test.cc b/net/tools/quic/quic_dispatcher_test.cc
index 169dc63..67fb2d6 100644
--- a/net/tools/quic/quic_dispatcher_test.cc
+++ b/net/tools/quic/quic_dispatcher_test.cc
@@ -50,8 +50,13 @@ class TestQuicSpdyServerSession : public QuicServerSessionBase {
public:
TestQuicSpdyServerSession(const QuicConfig& config,
QuicConnection* connection,
- const QuicCryptoServerConfig* crypto_config)
- : QuicServerSessionBase(config, connection, nullptr, crypto_config),
+ const QuicCryptoServerConfig* crypto_config,
+ QuicCompressedCertsCache* compressed_certs_cache)
+ : QuicServerSessionBase(config,
+ connection,
+ nullptr,
+ crypto_config,
+ compressed_certs_cache),
crypto_stream_(QuicServerSessionBase::GetCryptoStream()) {}
~TestQuicSpdyServerSession() override{};
@@ -62,8 +67,11 @@ class TestQuicSpdyServerSession : public QuicServerSessionBase {
QuicSpdyStream*(SpdyPriority priority));
QuicCryptoServerStreamBase* CreateQuicCryptoServerStream(
- const QuicCryptoServerConfig* crypto_config) override {
- return new QuicCryptoServerStream(crypto_config, this);
+ const QuicCryptoServerConfig* crypto_config,
+ QuicCompressedCertsCache* compressed_certs_cache) override {
+ return new QuicCryptoServerStream(
+ crypto_config, compressed_certs_cache,
+ FLAGS_enable_quic_stateless_reject_support, this);
}
void SetCryptoStream(QuicCryptoServerStream* crypto_stream) {
@@ -126,10 +134,12 @@ QuicServerSessionBase* CreateSession(
const IPEndPoint& client_address,
MockConnectionHelper* helper,
const QuicCryptoServerConfig* crypto_config,
+ QuicCompressedCertsCache* compressed_certs_cache,
TestQuicSpdyServerSession** session) {
MockServerConnection* connection =
new MockServerConnection(connection_id, helper, dispatcher);
- *session = new TestQuicSpdyServerSession(config, connection, crypto_config);
+ *session = new TestQuicSpdyServerSession(config, connection, crypto_config,
+ compressed_certs_cache);
connection->set_visitor(*session);
ON_CALL(*connection, SendConnectionCloseWithDetails(_, _))
.WillByDefault(WithoutArgs(Invoke(
@@ -255,17 +265,19 @@ TEST_F(QuicDispatcherTest, ProcessPackets) {
server_address_ = IPEndPoint(net::test::Any4(), 5);
EXPECT_CALL(dispatcher_, CreateQuicSession(1, client_address))
- .WillOnce(testing::Return(CreateSession(&dispatcher_, config_, 1,
- client_address, &mock_helper_,
- &crypto_config_, &session1_)));
+ .WillOnce(testing::Return(CreateSession(
+ &dispatcher_, config_, 1, client_address, &mock_helper_,
+ &crypto_config_, QuicDispatcherPeer::GetCache(&dispatcher_),
+ &session1_)));
ProcessPacket(client_address, 1, true, false, "foo");
EXPECT_EQ(client_address, dispatcher_.current_client_address());
EXPECT_EQ(server_address_, dispatcher_.current_server_address());
EXPECT_CALL(dispatcher_, CreateQuicSession(2, client_address))
- .WillOnce(testing::Return(CreateSession(&dispatcher_, config_, 2,
- client_address, &mock_helper_,
- &crypto_config_, &session2_)));
+ .WillOnce(testing::Return(CreateSession(
+ &dispatcher_, config_, 2, client_address, &mock_helper_,
+ &crypto_config_, QuicDispatcherPeer::GetCache(&dispatcher_),
+ &session2_)));
ProcessPacket(client_address, 2, true, false, "bar");
EXPECT_CALL(*reinterpret_cast<MockConnection*>(session1_->connection()),
@@ -293,9 +305,10 @@ TEST_F(QuicDispatcherTest, StatefulVersionNegotiation) {
server_address_ = IPEndPoint(net::test::Any4(), 5);
EXPECT_CALL(dispatcher_, CreateQuicSession(1, client_address))
- .WillOnce(testing::Return(CreateSession(&dispatcher_, config_, 1,
- client_address, &mock_helper_,
- &crypto_config_, &session1_)));
+ .WillOnce(testing::Return(CreateSession(
+ &dispatcher_, config_, 1, client_address, &mock_helper_,
+ &crypto_config_, QuicDispatcherPeer::GetCache(&dispatcher_),
+ &session1_)));
QuicVersion version = static_cast<QuicVersion>(QuicVersionMin() - 1);
ProcessPacket(client_address, 1, true, version, "foo",
PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, 1);
@@ -305,9 +318,10 @@ TEST_F(QuicDispatcherTest, Shutdown) {
IPEndPoint client_address(net::test::Loopback4(), 1);
EXPECT_CALL(dispatcher_, CreateQuicSession(_, client_address))
- .WillOnce(testing::Return(CreateSession(&dispatcher_, config_, 1,
- client_address, &mock_helper_,
- &crypto_config_, &session1_)));
+ .WillOnce(testing::Return(CreateSession(
+ &dispatcher_, config_, 1, client_address, &mock_helper_,
+ &crypto_config_, QuicDispatcherPeer::GetCache(&dispatcher_),
+ &session1_)));
ProcessPacket(client_address, 1, true, false, "foo");
@@ -324,9 +338,10 @@ TEST_F(QuicDispatcherTest, TimeWaitListManager) {
IPEndPoint client_address(net::test::Loopback4(), 1);
QuicConnectionId connection_id = 1;
EXPECT_CALL(dispatcher_, CreateQuicSession(connection_id, client_address))
- .WillOnce(testing::Return(
- CreateSession(&dispatcher_, config_, connection_id, client_address,
- &mock_helper_, &crypto_config_, &session1_)));
+ .WillOnce(testing::Return(CreateSession(
+ &dispatcher_, config_, connection_id, client_address, &mock_helper_,
+ &crypto_config_, QuicDispatcherPeer::GetCache(&dispatcher_),
+ &session1_)));
ProcessPacket(client_address, connection_id, true, false, "foo");
// Close the connection by sending public reset packet.
@@ -382,8 +397,12 @@ TEST_F(QuicDispatcherTest, NoVersionPacketToTimeWaitListManager) {
class MockQuicCryptoServerStream : public QuicCryptoServerStream {
public:
MockQuicCryptoServerStream(const QuicCryptoServerConfig& crypto_config,
+ QuicCompressedCertsCache* compressed_certs_cache,
QuicSession* session)
- : QuicCryptoServerStream(&crypto_config, session) {}
+ : QuicCryptoServerStream(&crypto_config,
+ compressed_certs_cache,
+ FLAGS_enable_quic_stateless_reject_support,
+ session) {}
void set_handshake_confirmed_for_testing(bool handshake_confirmed) {
handshake_confirmed_ = handshake_confirmed;
}
@@ -468,9 +487,11 @@ class QuicDispatcherStatelessRejectTest
QuicConnectionId connection_id,
const IPEndPoint& client_address) {
CreateSession(&dispatcher_, config_, connection_id, client_address,
- &mock_helper_, &crypto_config_, &session1_);
+ &mock_helper_, &crypto_config_,
+ QuicDispatcherPeer::GetCache(&dispatcher_), &session1_);
- crypto_stream1_ = new MockQuicCryptoServerStream(crypto_config_, session1_);
+ crypto_stream1_ = new MockQuicCryptoServerStream(
+ crypto_config_, QuicDispatcherPeer::GetCache(&dispatcher_), session1_);
session1_->SetCryptoStream(crypto_stream1_);
crypto_stream1_->set_handshake_confirmed_for_testing(
GetParam().crypto_handshake_successful);
@@ -502,9 +523,10 @@ TEST_F(QuicDispatcherTest, OKSeqNoPacketProcessed) {
server_address_ = IPEndPoint(net::test::Any4(), 5);
EXPECT_CALL(dispatcher_, CreateQuicSession(1, client_address))
- .WillOnce(testing::Return(CreateSession(&dispatcher_, config_, 1,
- client_address, &mock_helper_,
- &crypto_config_, &session1_)));
+ .WillOnce(testing::Return(CreateSession(
+ &dispatcher_, config_, 1, client_address, &mock_helper_,
+ &crypto_config_, QuicDispatcherPeer::GetCache(&dispatcher_),
+ &session1_)));
// A packet whose packet number is the largest that is allowed to start a
// connection.
ProcessPacket(client_address, connection_id, true, false, "data",
@@ -650,15 +672,15 @@ class QuicDispatcherWriteBlockedListTest : public QuicDispatcherTest {
IPEndPoint client_address(net::test::Loopback4(), 1);
EXPECT_CALL(dispatcher_, CreateQuicSession(_, client_address))
- .WillOnce(testing::Return(CreateSession(&dispatcher_, config_, 1,
- client_address, &helper_,
- &crypto_config_, &session1_)));
+ .WillOnce(testing::Return(CreateSession(
+ &dispatcher_, config_, 1, client_address, &helper_, &crypto_config_,
+ QuicDispatcherPeer::GetCache(&dispatcher_), &session1_)));
ProcessPacket(client_address, 1, true, false, "foo");
EXPECT_CALL(dispatcher_, CreateQuicSession(_, client_address))
- .WillOnce(testing::Return(CreateSession(&dispatcher_, config_, 2,
- client_address, &helper_,
- &crypto_config_, &session2_)));
+ .WillOnce(testing::Return(CreateSession(
+ &dispatcher_, config_, 2, client_address, &helper_, &crypto_config_,
+ QuicDispatcherPeer::GetCache(&dispatcher_), &session2_)));
ProcessPacket(client_address, 2, true, false, "bar");
blocked_list_ = QuicDispatcherPeer::GetWriteBlockedList(&dispatcher_);
diff --git a/net/tools/quic/quic_epoll_connection_helper_test.cc b/net/tools/quic/quic_epoll_connection_helper_test.cc
index 1e1d22e..f79e0ff 100644
--- a/net/tools/quic/quic_epoll_connection_helper_test.cc
+++ b/net/tools/quic/quic_epoll_connection_helper_test.cc
@@ -18,10 +18,7 @@ class TestDelegate : public QuicAlarm::Delegate {
public:
TestDelegate() : fired_(false) {}
- QuicTime OnAlarm() override {
- fired_ = true;
- return QuicTime::Zero();
- }
+ void OnAlarm() override { fired_ = true; }
bool fired() const { return fired_; }
diff --git a/net/tools/quic/quic_server_session_base.cc b/net/tools/quic/quic_server_session_base.cc
index 63618d4..c8a6dfb 100644
--- a/net/tools/quic/quic_server_session_base.cc
+++ b/net/tools/quic/quic_server_session_base.cc
@@ -18,9 +18,11 @@ QuicServerSessionBase::QuicServerSessionBase(
const QuicConfig& config,
QuicConnection* connection,
QuicServerSessionVisitor* visitor,
- const QuicCryptoServerConfig* crypto_config)
+ const QuicCryptoServerConfig* crypto_config,
+ QuicCompressedCertsCache* compressed_certs_cache)
: QuicSpdySession(connection, config),
crypto_config_(crypto_config),
+ compressed_certs_cache_(compressed_certs_cache),
visitor_(visitor),
bandwidth_resumption_enabled_(false),
bandwidth_estimate_sent_to_client_(QuicBandwidth::Zero()),
@@ -30,7 +32,8 @@ QuicServerSessionBase::QuicServerSessionBase(
QuicServerSessionBase::~QuicServerSessionBase() {}
void QuicServerSessionBase::Initialize() {
- crypto_stream_.reset(CreateQuicCryptoServerStream(crypto_config_));
+ crypto_stream_.reset(
+ CreateQuicCryptoServerStream(crypto_config_, compressed_certs_cache_));
QuicSpdySession::Initialize();
}
diff --git a/net/tools/quic/quic_server_session_base.h b/net/tools/quic/quic_server_session_base.h
index ddfaa98..a93fd9c 100644
--- a/net/tools/quic/quic_server_session_base.h
+++ b/net/tools/quic/quic_server_session_base.h
@@ -16,6 +16,7 @@
#include "base/containers/hash_tables.h"
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
+#include "net/quic/crypto/quic_compressed_certs_cache.h"
#include "net/quic/quic_crypto_server_stream.h"
#include "net/quic/quic_protocol.h"
#include "net/quic/quic_spdy_session.h"
@@ -58,7 +59,8 @@ class QuicServerSessionBase : public QuicSpdySession {
QuicServerSessionBase(const QuicConfig& config,
QuicConnection* connection,
QuicServerSessionVisitor* visitor,
- const QuicCryptoServerConfig* crypto_config);
+ const QuicCryptoServerConfig* crypto_config,
+ QuicCompressedCertsCache* compressed_certs_cache);
// Override the base class to notify the owner of the connection close.
void OnConnectionClosed(QuicErrorCode error,
@@ -77,7 +79,8 @@ class QuicServerSessionBase : public QuicSpdySession {
return crypto_stream_.get();
}
- // Override base class to process FEC config received from client.
+ // Override base class to process bandwidth related config received from
+ // client.
void OnConfigNegotiated() override;
void set_serving_region(const std::string& serving_region) {
@@ -92,7 +95,7 @@ class QuicServerSessionBase : public QuicSpdySession {
// Return false when connection is closed or forward secure encryption hasn't
// established yet or number of server initiated streams already reaches the
// upper limit.
- bool ShouldCreateOutgoingDynamicStream();
+ virtual bool ShouldCreateOutgoingDynamicStream();
// If we should create an incoming stream, returns true. Otherwise
// does error handling, including communicating the error to the client and
@@ -100,7 +103,8 @@ class QuicServerSessionBase : public QuicSpdySession {
virtual bool ShouldCreateIncomingDynamicStream(QuicStreamId id);
virtual QuicCryptoServerStreamBase* CreateQuicCryptoServerStream(
- const QuicCryptoServerConfig* crypto_config) = 0;
+ const QuicCryptoServerConfig* crypto_config,
+ QuicCompressedCertsCache* compressed_certs_cache) = 0;
const QuicCryptoServerConfig* crypto_config() { return crypto_config_; }
@@ -109,6 +113,11 @@ class QuicServerSessionBase : public QuicSpdySession {
friend class test::QuicSimpleServerSessionPeer;
const QuicCryptoServerConfig* crypto_config_;
+
+ // The cache which contains most recently compressed certs.
+ // Owned by QuicDispatcher.
+ QuicCompressedCertsCache* compressed_certs_cache_;
+
scoped_ptr<QuicCryptoServerStreamBase> crypto_stream_;
QuicServerSessionVisitor* visitor_;
diff --git a/net/tools/quic/quic_server_session_base_test.cc b/net/tools/quic/quic_server_session_base_test.cc
index 1d4ed11..4de21a3 100644
--- a/net/tools/quic/quic_server_session_base_test.cc
+++ b/net/tools/quic/quic_server_session_base_test.cc
@@ -73,8 +73,13 @@ class TestServerSession : public QuicServerSessionBase {
TestServerSession(const QuicConfig& config,
QuicConnection* connection,
QuicServerSessionVisitor* visitor,
- const QuicCryptoServerConfig* crypto_config)
- : QuicServerSessionBase(config, connection, visitor, crypto_config) {}
+ const QuicCryptoServerConfig* crypto_config,
+ QuicCompressedCertsCache* compressed_certs_cache)
+ : QuicServerSessionBase(config,
+ connection,
+ visitor,
+ crypto_config,
+ compressed_certs_cache) {}
~TestServerSession() override{};
@@ -101,8 +106,11 @@ class TestServerSession : public QuicServerSessionBase {
}
QuicCryptoServerStreamBase* CreateQuicCryptoServerStream(
- const QuicCryptoServerConfig* crypto_config) override {
- return new QuicCryptoServerStream(crypto_config, this);
+ const QuicCryptoServerConfig* crypto_config,
+ QuicCompressedCertsCache* compressed_certs_cache) override {
+ return new QuicCryptoServerStream(
+ crypto_config, compressed_certs_cache,
+ FLAGS_enable_quic_stateless_reject_support, this);
}
};
@@ -113,7 +121,10 @@ class QuicServerSessionBaseTest : public ::testing::TestWithParam<QuicVersion> {
QuicServerSessionBaseTest()
: crypto_config_(QuicCryptoServerConfig::TESTING,
QuicRandom::GetInstance(),
- CryptoTestUtils::ProofSourceForTesting()) {
+ CryptoTestUtils::ProofSourceForTesting()),
+ compressed_certs_cache_(
+ QuicCompressedCertsCache::kQuicCompressedCertsCacheSize) {
+ FLAGS_quic_always_log_bugs_for_tests = true;
config_.SetMaxStreamsPerConnection(kMaxStreamsForTest, kMaxStreamsForTest);
config_.SetInitialStreamFlowControlWindowToSend(
kInitialStreamFlowControlWindowForTest);
@@ -122,8 +133,9 @@ class QuicServerSessionBaseTest : public ::testing::TestWithParam<QuicVersion> {
connection_ = new StrictMock<MockConnection>(
&helper_, Perspective::IS_SERVER, SupportedVersions(GetParam()));
- session_.reset(
- new TestServerSession(config_, connection_, &owner_, &crypto_config_));
+ session_.reset(new TestServerSession(config_, connection_, &owner_,
+ &crypto_config_,
+ &compressed_certs_cache_));
MockClock clock;
handshake_message_.reset(crypto_config_.AddDefaultConfig(
QuicRandom::GetInstance(), &clock,
@@ -137,6 +149,7 @@ class QuicServerSessionBaseTest : public ::testing::TestWithParam<QuicVersion> {
StrictMock<MockConnection>* connection_;
QuicConfig config_;
QuicCryptoServerConfig crypto_config_;
+ QuicCompressedCertsCache compressed_certs_cache_;
scoped_ptr<TestServerSession> session_;
scoped_ptr<CryptoHandshakeMessage> handshake_message_;
QuicConnectionVisitorInterface* visitor_;
@@ -331,8 +344,12 @@ class MockQuicCryptoServerStream : public QuicCryptoServerStream {
public:
explicit MockQuicCryptoServerStream(
const QuicCryptoServerConfig* crypto_config,
+ QuicCompressedCertsCache* compressed_certs_cache,
QuicSession* session)
- : QuicCryptoServerStream(crypto_config, session) {}
+ : QuicCryptoServerStream(crypto_config,
+ compressed_certs_cache,
+ FLAGS_enable_quic_stateless_reject_support,
+ session) {}
~MockQuicCryptoServerStream() override {}
MOCK_METHOD1(SendServerConfigUpdate,
@@ -366,8 +383,8 @@ TEST_P(QuicServerSessionBaseTest, BandwidthEstimates) {
const string serving_region = "not a real region";
session_->set_serving_region(serving_region);
- MockQuicCryptoServerStream* crypto_stream =
- new MockQuicCryptoServerStream(&crypto_config_, session_.get());
+ MockQuicCryptoServerStream* crypto_stream = new MockQuicCryptoServerStream(
+ &crypto_config_, &compressed_certs_cache_, session_.get());
QuicServerSessionBasePeer::SetCryptoStream(session_.get(), crypto_stream);
// Set some initial bandwidth values.
diff --git a/net/tools/quic/quic_simple_server_session.cc b/net/tools/quic/quic_simple_server_session.cc
index e72383a..5b5b57e 100644
--- a/net/tools/quic/quic_simple_server_session.cc
+++ b/net/tools/quic/quic_simple_server_session.cc
@@ -20,16 +20,24 @@ QuicSimpleServerSession::QuicSimpleServerSession(
const QuicConfig& config,
QuicConnection* connection,
QuicServerSessionVisitor* visitor,
- const QuicCryptoServerConfig* crypto_config)
- : QuicServerSessionBase(config, connection, visitor, crypto_config),
+ const QuicCryptoServerConfig* crypto_config,
+ QuicCompressedCertsCache* compressed_certs_cache)
+ : QuicServerSessionBase(config,
+ connection,
+ visitor,
+ crypto_config,
+ compressed_certs_cache),
highest_promised_stream_id_(0) {}
QuicSimpleServerSession::~QuicSimpleServerSession() {}
QuicCryptoServerStreamBase*
QuicSimpleServerSession::CreateQuicCryptoServerStream(
- const QuicCryptoServerConfig* crypto_config) {
- return new QuicCryptoServerStream(crypto_config, this);
+ const QuicCryptoServerConfig* crypto_config,
+ QuicCompressedCertsCache* compressed_certs_cache) {
+ return new QuicCryptoServerStream(crypto_config, compressed_certs_cache,
+ FLAGS_enable_quic_stateless_reject_support,
+ this);
}
void QuicSimpleServerSession::StreamDraining(QuicStreamId id) {
diff --git a/net/tools/quic/quic_simple_server_session.h b/net/tools/quic/quic_simple_server_session.h
index 0329a66..ea7860dd 100644
--- a/net/tools/quic/quic_simple_server_session.h
+++ b/net/tools/quic/quic_simple_server_session.h
@@ -59,7 +59,8 @@ class QuicSimpleServerSession : public QuicServerSessionBase {
QuicSimpleServerSession(const QuicConfig& config,
QuicConnection* connection,
QuicServerSessionVisitor* visitor,
- const QuicCryptoServerConfig* crypto_config);
+ const QuicCryptoServerConfig* crypto_config,
+ QuicCompressedCertsCache* compressed_certs_cache);
~QuicSimpleServerSession() override;
@@ -97,7 +98,8 @@ class QuicSimpleServerSession : public QuicServerSessionBase {
// QuicServerSessionBaseMethod:
QuicCryptoServerStreamBase* CreateQuicCryptoServerStream(
- const QuicCryptoServerConfig* crypto_config) override;
+ const QuicCryptoServerConfig* crypto_config,
+ QuicCompressedCertsCache* compressed_certs_cache) override;
private:
friend class test::QuicSimpleServerSessionPeer;
diff --git a/net/tools/quic/quic_simple_server_session_test.cc b/net/tools/quic/quic_simple_server_session_test.cc
index e6dcdc9..029fa11 100644
--- a/net/tools/quic/quic_simple_server_session_test.cc
+++ b/net/tools/quic/quic_simple_server_session_test.cc
@@ -83,8 +83,12 @@ class MockQuicCryptoServerStream : public QuicCryptoServerStream {
public:
explicit MockQuicCryptoServerStream(
const QuicCryptoServerConfig* crypto_config,
+ QuicCompressedCertsCache* compressed_certs_cache,
QuicSession* session)
- : QuicCryptoServerStream(crypto_config, session) {}
+ : QuicCryptoServerStream(crypto_config,
+ compressed_certs_cache,
+ FLAGS_enable_quic_stateless_reject_support,
+ session) {}
~MockQuicCryptoServerStream() override {}
MOCK_METHOD1(SendServerConfigUpdate,
@@ -105,12 +109,11 @@ class MockConnectionWithSendStreamData : public MockConnection {
const QuicVersionVector& supported_versions)
: MockConnection(helper, perspective, supported_versions) {}
- MOCK_METHOD6(SendStreamData,
+ MOCK_METHOD5(SendStreamData,
QuicConsumedData(QuicStreamId id,
QuicIOVector iov,
QuicStreamOffset offset,
bool fin,
- FecProtection fec_protection,
QuicAckListenerInterface* listern));
};
@@ -153,7 +156,9 @@ class QuicSimpleServerSessionTest
QuicSimpleServerSessionTest()
: crypto_config_(QuicCryptoServerConfig::TESTING,
QuicRandom::GetInstance(),
- CryptoTestUtils::ProofSourceForTesting()) {
+ CryptoTestUtils::ProofSourceForTesting()),
+ compressed_certs_cache_(
+ QuicCompressedCertsCache::kQuicCompressedCertsCacheSize) {
FLAGS_quic_always_log_bugs_for_tests = true;
config_.SetMaxStreamsPerConnection(kMaxStreamsForTest, kMaxStreamsForTest);
config_.SetInitialStreamFlowControlWindowToSend(
@@ -164,7 +169,8 @@ class QuicSimpleServerSessionTest
connection_ = new StrictMock<MockConnectionWithSendStreamData>(
&helper_, Perspective::IS_SERVER, SupportedVersions(GetParam()));
session_.reset(new QuicSimpleServerSession(config_, connection_, &owner_,
- &crypto_config_));
+ &crypto_config_,
+ &compressed_certs_cache_));
MockClock clock;
handshake_message_.reset(crypto_config_.AddDefaultConfig(
QuicRandom::GetInstance(), &clock,
@@ -182,6 +188,7 @@ class QuicSimpleServerSessionTest
StrictMock<MockConnectionWithSendStreamData>* connection_;
QuicConfig config_;
QuicCryptoServerConfig crypto_config_;
+ QuicCompressedCertsCache compressed_certs_cache_;
scoped_ptr<QuicSimpleServerSession> session_;
scoped_ptr<CryptoHandshakeMessage> handshake_message_;
QuicConnectionVisitorInterface* visitor_;
@@ -323,8 +330,8 @@ TEST_P(QuicSimpleServerSessionTest, CreateOutgoingDynamicStreamUptoLimit) {
EXPECT_EQ(0u, session_->GetNumOpenOutgoingStreams());
// Assume encryption already established.
- MockQuicCryptoServerStream* crypto_stream =
- new MockQuicCryptoServerStream(&crypto_config_, session_.get());
+ MockQuicCryptoServerStream* crypto_stream = new MockQuicCryptoServerStream(
+ &crypto_config_, &compressed_certs_cache_, session_.get());
crypto_stream->set_encryption_established(true);
QuicSimpleServerSessionPeer::SetCryptoStream(session_.get(), crypto_stream);
@@ -398,7 +405,8 @@ class QuicSimpleServerSessionServerPushTest
connection_ = new StrictMock<MockConnectionWithSendStreamData>(
&helper_, Perspective::IS_SERVER, SupportedVersions(GetParam()));
session_.reset(new QuicSimpleServerSession(config_, connection_, &owner_,
- &crypto_config_));
+ &crypto_config_,
+ &compressed_certs_cache_));
session_->Initialize();
// Needed to make new session flow control window work.
session_->OnConfigNegotiated();
@@ -408,8 +416,8 @@ class QuicSimpleServerSessionServerPushTest
QuicSpdySessionPeer::SetHeadersStream(session_.get(), headers_stream_);
// Assume encryption already established.
- MockQuicCryptoServerStream* crypto_stream =
- new MockQuicCryptoServerStream(&crypto_config_, session_.get());
+ MockQuicCryptoServerStream* crypto_stream = new MockQuicCryptoServerStream(
+ &crypto_config_, &compressed_certs_cache_, session_.get());
crypto_stream->set_encryption_established(true);
QuicSimpleServerSessionPeer::SetCryptoStream(session_.get(), crypto_stream);
}
@@ -455,7 +463,7 @@ class QuicSimpleServerSessionServerPushTest
// Since flow control window is smaller than response body, not the
// whole body will be sent.
EXPECT_CALL(*connection_,
- SendStreamData(stream_id, _, 0, false, _, nullptr))
+ SendStreamData(stream_id, _, 0, false, nullptr))
.WillOnce(
Return(QuicConsumedData(kStreamFlowControlWindowSize, false)));
EXPECT_CALL(*connection_, SendBlocked(stream_id));
@@ -492,7 +500,7 @@ TEST_P(QuicSimpleServerSessionServerPushTest,
EXPECT_CALL(*headers_stream_, WriteHeaders(next_out_going_stream_id, _, false,
kDefaultPriority, nullptr));
EXPECT_CALL(*connection_,
- SendStreamData(next_out_going_stream_id, _, 0, false, _, nullptr))
+ SendStreamData(next_out_going_stream_id, _, 0, false, nullptr))
.WillOnce(Return(QuicConsumedData(kStreamFlowControlWindowSize, false)));
EXPECT_CALL(*connection_, SendBlocked(next_out_going_stream_id));
session_->StreamDraining(2);
@@ -526,7 +534,7 @@ TEST_P(QuicSimpleServerSessionServerPushTest,
EXPECT_CALL(*headers_stream_, WriteHeaders(stream_not_reset, _, false,
kDefaultPriority, nullptr));
EXPECT_CALL(*connection_,
- SendStreamData(stream_not_reset, _, 0, false, _, nullptr))
+ SendStreamData(stream_not_reset, _, 0, false, nullptr))
.WillOnce(Return(QuicConsumedData(kStreamFlowControlWindowSize, false)));
EXPECT_CALL(*connection_, SendBlocked(stream_not_reset));
EXPECT_CALL(*headers_stream_, WriteHeaders(stream_got_reset, _, false,
@@ -553,7 +561,7 @@ TEST_P(QuicSimpleServerSessionServerPushTest,
EXPECT_CALL(*headers_stream_, WriteHeaders(stream_to_open, _, false,
kDefaultPriority, nullptr));
EXPECT_CALL(*connection_,
- SendStreamData(stream_to_open, _, 0, false, _, nullptr))
+ SendStreamData(stream_to_open, _, 0, false, nullptr))
.WillOnce(Return(QuicConsumedData(kStreamFlowControlWindowSize, false)));
EXPECT_CALL(*connection_, SendBlocked(stream_to_open));
diff --git a/net/tools/quic/quic_simple_server_stream_test.cc b/net/tools/quic/quic_simple_server_stream_test.cc
index 91b8ada..594e34c 100644
--- a/net/tools/quic/quic_simple_server_stream_test.cc
+++ b/net/tools/quic/quic_simple_server_stream_test.cc
@@ -84,16 +84,19 @@ class MockQuicSimpleServerSession : public QuicSimpleServerSession {
public:
const size_t kMaxStreamsForTest = 100;
- explicit MockQuicSimpleServerSession(QuicConnection* connection,
- MockQuicServerSessionVisitor* owner,
- QuicCryptoServerConfig* crypto_config)
- : QuicSimpleServerSession(::net::test::DefaultQuicConfig(),
+ explicit MockQuicSimpleServerSession(
+ QuicConnection* connection,
+ MockQuicServerSessionVisitor* owner,
+ QuicCryptoServerConfig* crypto_config,
+ QuicCompressedCertsCache* compressed_certs_cache)
+ : QuicSimpleServerSession(DefaultQuicConfig(),
connection,
owner,
- crypto_config) {
+ crypto_config,
+ compressed_certs_cache) {
set_max_open_incoming_streams(kMaxStreamsForTest);
set_max_open_outgoing_streams(kMaxStreamsForTest);
- ON_CALL(*this, WritevData(_, _, _, _, _, _))
+ ON_CALL(*this, WritevData(_, _, _, _, _))
.WillByDefault(testing::Return(QuicConsumedData(0, false)));
}
@@ -102,12 +105,11 @@ class MockQuicSimpleServerSession : public QuicSimpleServerSession {
MOCK_METHOD2(OnConnectionClosed,
void(QuicErrorCode error, ConnectionCloseSource source));
MOCK_METHOD1(CreateIncomingDynamicStream, QuicSpdyStream*(QuicStreamId id));
- MOCK_METHOD6(WritevData,
+ MOCK_METHOD5(WritevData,
QuicConsumedData(QuicStreamId id,
QuicIOVector data,
QuicStreamOffset offset,
bool fin,
- FecProtection fec_protection,
QuicAckListenerInterface*));
MOCK_METHOD2(OnStreamHeaders,
void(QuicStreamId stream_id, StringPiece headers_data));
@@ -153,7 +155,12 @@ class QuicSimpleServerStreamTest
QuicCryptoServerConfig::TESTING,
QuicRandom::GetInstance(),
::net::test::CryptoTestUtils::ProofSourceForTesting())),
- session_(connection_, session_owner_, crypto_config_.get()),
+ compressed_certs_cache_(
+ QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
+ session_(connection_,
+ session_owner_,
+ crypto_config_.get(),
+ &compressed_certs_cache_),
body_("hello world") {
FLAGS_quic_always_log_bugs_for_tests = true;
SpdyHeaderBlock request_headers;
@@ -198,6 +205,7 @@ class QuicSimpleServerStreamTest
StrictMock<MockConnection>* connection_;
StrictMock<MockQuicServerSessionVisitor>* session_owner_;
std::unique_ptr<QuicCryptoServerConfig> crypto_config_;
+ QuicCompressedCertsCache compressed_certs_cache_;
StrictMock<MockQuicSimpleServerSession> session_;
QuicSimpleServerStreamPeer* stream_; // Owned by session_.
string headers_string_;
@@ -209,7 +217,7 @@ INSTANTIATE_TEST_CASE_P(Tests,
::testing::ValuesIn(QuicSupportedVersions()));
TEST_P(QuicSimpleServerStreamTest, TestFraming) {
- EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
+ EXPECT_CALL(session_, WritevData(_, _, _, _, _))
.Times(AnyNumber())
.WillRepeatedly(Invoke(MockQuicSpdySession::ConsumeAllData));
stream_->OnStreamHeaders(headers_string_);
@@ -223,7 +231,7 @@ TEST_P(QuicSimpleServerStreamTest, TestFraming) {
}
TEST_P(QuicSimpleServerStreamTest, TestFramingOnePacket) {
- EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
+ EXPECT_CALL(session_, WritevData(_, _, _, _, _))
.Times(AnyNumber())
.WillRepeatedly(Invoke(MockQuicSpdySession::ConsumeAllData));
@@ -238,7 +246,7 @@ TEST_P(QuicSimpleServerStreamTest, TestFramingOnePacket) {
}
TEST_P(QuicSimpleServerStreamTest, SendQuicRstStreamNoErrorInStopReading) {
- EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
+ EXPECT_CALL(session_, WritevData(_, _, _, _, _))
.Times(AnyNumber())
.WillRepeatedly(Invoke(MockQuicSpdySession::ConsumeAllData));
@@ -261,7 +269,7 @@ TEST_P(QuicSimpleServerStreamTest, TestFramingExtraData) {
// We'll automatically write out an error (headers + body)
EXPECT_CALL(session_, WriteHeaders(_, _, _, _, _));
- EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
+ EXPECT_CALL(session_, WritevData(_, _, _, _, _))
.WillOnce(Invoke(MockQuicSpdySession::ConsumeAllData));
EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0);
@@ -298,7 +306,7 @@ TEST_P(QuicSimpleServerStreamTest, SendResponseWithIllegalResponseStatus) {
InSequence s;
EXPECT_CALL(session_, WriteHeaders(stream_->id(), _, false, _, nullptr));
- EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
+ EXPECT_CALL(session_, WritevData(_, _, _, _, _))
.Times(1)
.WillOnce(Return(QuicConsumedData(
strlen(QuicSimpleServerStream::kErrorResponseBody), true)));
@@ -355,7 +363,7 @@ TEST_P(QuicSimpleServerStreamTest, SendResponseWithValidHeaders) {
InSequence s;
EXPECT_CALL(session_, WriteHeaders(stream_->id(), _, false, _, nullptr));
- EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
+ EXPECT_CALL(session_, WritevData(_, _, _, _, _))
.Times(1)
.WillOnce(Return(QuicConsumedData(body.length(), true)));
@@ -394,7 +402,7 @@ TEST_P(QuicSimpleServerStreamTest, SendReponseWithPushResources) {
::net::test::kClientDataStreamId1,
*request_headers));
EXPECT_CALL(session_, WriteHeaders(stream_->id(), _, false, _, nullptr));
- EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
+ EXPECT_CALL(session_, WritevData(_, _, _, _, _))
.Times(1)
.WillOnce(Return(QuicConsumedData(body.length(), true)));
QuicSimpleServerStreamPeer::SendResponse(stream_);
@@ -440,7 +448,7 @@ TEST_P(QuicSimpleServerStreamTest, PushResponseOnServerInitiatedStream) {
EXPECT_CALL(session_,
WriteHeaders(kServerInitiatedStreamId, _, false,
server_initiated_stream->priority(), nullptr));
- EXPECT_CALL(session_, WritevData(kServerInitiatedStreamId, _, _, _, _, _))
+ EXPECT_CALL(session_, WritevData(kServerInitiatedStreamId, _, _, _, _))
.Times(1)
.WillOnce(Return(QuicConsumedData(kBody.size(), true)));
server_initiated_stream->PushResponse(headers);
@@ -462,7 +470,7 @@ TEST_P(QuicSimpleServerStreamTest, TestSendErrorResponse) {
InSequence s;
EXPECT_CALL(session_, WriteHeaders(_, _, _, _, _));
- EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
+ EXPECT_CALL(session_, WritevData(_, _, _, _, _))
.Times(1)
.WillOnce(Return(QuicConsumedData(3, true)));
@@ -482,7 +490,7 @@ TEST_P(QuicSimpleServerStreamTest, InvalidMultipleContentLength) {
headers_string_ = SpdyUtils::SerializeUncompressedHeaders(request_headers);
EXPECT_CALL(session_, WriteHeaders(_, _, _, _, _));
- EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
+ EXPECT_CALL(session_, WritevData(_, _, _, _, _))
.Times(AnyNumber())
.WillRepeatedly(Invoke(MockQuicSpdySession::ConsumeAllData));
stream_->OnStreamHeaders(headers_string_);
@@ -503,7 +511,7 @@ TEST_P(QuicSimpleServerStreamTest, InvalidLeadingNullContentLength) {
headers_string_ = SpdyUtils::SerializeUncompressedHeaders(request_headers);
EXPECT_CALL(session_, WriteHeaders(_, _, _, _, _));
- EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
+ EXPECT_CALL(session_, WritevData(_, _, _, _, _))
.Times(AnyNumber())
.WillRepeatedly(Invoke(MockQuicSpdySession::ConsumeAllData));
stream_->OnStreamHeaders(headers_string_);
@@ -537,7 +545,7 @@ TEST_P(QuicSimpleServerStreamTest, SendQuicRstStreamNoErrorWithEarlyResponse) {
InSequence s;
EXPECT_CALL(session_, WriteHeaders(stream_->id(), _, _, _, _));
- EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
+ EXPECT_CALL(session_, WritevData(_, _, _, _, _))
.Times(1)
.WillOnce(Return(QuicConsumedData(3, true)));
if (GetParam() > QUIC_VERSION_28) {
diff --git a/net/tools/quic/quic_socket_utils.cc b/net/tools/quic/quic_socket_utils.cc
index 42141df..9c8cac7 100644
--- a/net/tools/quic/quic_socket_utils.cc
+++ b/net/tools/quic/quic_socket_utils.cc
@@ -213,7 +213,10 @@ WriteResult QuicSocketUtils::WritePacket(int fd,
hdr.msg_controllen = cmsg->cmsg_len;
}
- int rc = sendmsg(fd, &hdr, 0);
+ int rc;
+ do {
+ rc = sendmsg(fd, &hdr, 0);
+ } while (rc < 0 && errno == EINTR);
if (rc >= 0) {
return WriteResult(WRITE_STATUS_OK, rc);
}
diff --git a/net/tools/quic/quic_time_wait_list_manager.cc b/net/tools/quic/quic_time_wait_list_manager.cc
index 64ff05e..91c48d0 100644
--- a/net/tools/quic/quic_time_wait_list_manager.cc
+++ b/net/tools/quic/quic_time_wait_list_manager.cc
@@ -34,10 +34,8 @@ class ConnectionIdCleanUpAlarm : public QuicAlarm::Delegate {
QuicTimeWaitListManager* time_wait_list_manager)
: time_wait_list_manager_(time_wait_list_manager) {}
- QuicTime OnAlarm() override {
+ void OnAlarm() override {
time_wait_list_manager_->CleanUpOldConnectionIds();
- // Let the time wait manager register the alarm at appropriate time.
- return QuicTime::Zero();
}
private:
diff --git a/net/tools/quic/test_tools/packet_dropping_test_writer.cc b/net/tools/quic/test_tools/packet_dropping_test_writer.cc
index ed46a07..3858b78 100644
--- a/net/tools/quic/test_tools/packet_dropping_test_writer.cc
+++ b/net/tools/quic/test_tools/packet_dropping_test_writer.cc
@@ -20,10 +20,9 @@ class WriteUnblockedAlarm : public QuicAlarm::Delegate {
explicit WriteUnblockedAlarm(PacketDroppingTestWriter* writer)
: writer_(writer) {}
- QuicTime OnAlarm() override {
+ void OnAlarm() override {
DVLOG(1) << "Unblocking socket.";
writer_->OnCanWrite();
- return QuicTime::Zero();
}
private:
@@ -36,7 +35,12 @@ class DelayAlarm : public QuicAlarm::Delegate {
public:
explicit DelayAlarm(PacketDroppingTestWriter* writer) : writer_(writer) {}
- QuicTime OnAlarm() override { return writer_->ReleaseOldPackets(); }
+ void OnAlarm() override {
+ QuicTime new_deadline = writer_->ReleaseOldPackets();
+ if (new_deadline.IsInitialized()) {
+ writer_->SetDelayAlarm(new_deadline);
+ }
+ }
private:
PacketDroppingTestWriter* writer_;
@@ -203,6 +207,10 @@ QuicTime PacketDroppingTestWriter::ReleaseOldPackets() {
return QuicTime::Zero();
}
+void PacketDroppingTestWriter::SetDelayAlarm(QuicTime new_deadline) {
+ delay_alarm_->Set(new_deadline);
+}
+
void PacketDroppingTestWriter::OnCanWrite() {
on_can_write_->OnCanWrite();
}
diff --git a/net/tools/quic/test_tools/packet_dropping_test_writer.h b/net/tools/quic/test_tools/packet_dropping_test_writer.h
index be948f6..20d2c27 100644
--- a/net/tools/quic/test_tools/packet_dropping_test_writer.h
+++ b/net/tools/quic/test_tools/packet_dropping_test_writer.h
@@ -63,6 +63,9 @@ class PacketDroppingTestWriter : public QuicPacketWriterWrapper {
// for the next delayed packet to be written.
QuicTime ReleaseOldPackets();
+ // Sets |delay_alarm_| to fire at |new_deadline|.
+ void SetDelayAlarm(QuicTime new_deadline);
+
void OnCanWrite();
// The percent of time a packet is simulated as being lost.
diff --git a/net/tools/quic/test_tools/quic_dispatcher_peer.cc b/net/tools/quic/test_tools/quic_dispatcher_peer.cc
index 03e8e46..232043f 100644
--- a/net/tools/quic/test_tools/quic_dispatcher_peer.cc
+++ b/net/tools/quic/test_tools/quic_dispatcher_peer.cc
@@ -30,6 +30,12 @@ QuicPacketWriter* QuicDispatcherPeer::GetWriter(QuicDispatcher* dispatcher) {
}
// static
+QuicCompressedCertsCache* QuicDispatcherPeer::GetCache(
+ QuicDispatcher* dispatcher) {
+ return dispatcher->compressed_certs_cache();
+}
+
+// static
QuicConnectionHelperInterface* QuicDispatcherPeer::GetHelper(
QuicDispatcher* dispatcher) {
return dispatcher->helper_.get();
diff --git a/net/tools/quic/test_tools/quic_dispatcher_peer.h b/net/tools/quic/test_tools/quic_dispatcher_peer.h
index 7c3536f..cbd60e2 100644
--- a/net/tools/quic/test_tools/quic_dispatcher_peer.h
+++ b/net/tools/quic/test_tools/quic_dispatcher_peer.h
@@ -28,6 +28,8 @@ class QuicDispatcherPeer {
static QuicPacketWriter* GetWriter(QuicDispatcher* dispatcher);
+ static QuicCompressedCertsCache* GetCache(QuicDispatcher* dispatcher);
+
static QuicConnectionHelperInterface* GetHelper(QuicDispatcher* dispatcher);
static QuicDispatcher::WriteBlockedList* GetWriteBlockedList(
diff --git a/net/tools/quic/test_tools/quic_test_client.cc b/net/tools/quic/test_tools/quic_test_client.cc
index cf1abec..e926279a 100644
--- a/net/tools/quic/test_tools/quic_test_client.cc
+++ b/net/tools/quic/test_tools/quic_test_client.cc
@@ -201,7 +201,6 @@ void QuicTestClient::Initialize() {
connect_attempted_ = false;
auto_reconnect_ = false;
buffer_body_ = true;
- fec_policy_ = FEC_PROTECT_OPTIONAL;
ClearPerRequestState();
// As chrome will generally do this, we want it to be the default when it's
// not overridden.
@@ -394,8 +393,6 @@ QuicSpdyClientStream* QuicTestClient::GetOrCreateStream() {
QuicSpdyClientStream* cs = reinterpret_cast<QuicSpdyClientStream*>(stream_);
cs->SetPriority(priority_);
cs->set_allow_bidirectional_data(allow_bidirectional_data_);
- // Set FEC policy on stream.
- ReliableQuicStreamPeer::SetFecPolicy(stream_, fec_policy_);
}
return stream_;
@@ -651,15 +648,6 @@ void QuicTestClient::WaitForWriteToFlush() {
}
}
-void QuicTestClient::SetFecPolicy(FecPolicy fec_policy) {
- fec_policy_ = fec_policy;
- // Set policy for headers and crypto streams.
- ReliableQuicStreamPeer::SetFecPolicy(
- QuicSpdySessionPeer::GetHeadersStream(client()->session()), fec_policy);
- ReliableQuicStreamPeer::SetFecPolicy(client()->session()->GetCryptoStream(),
- fec_policy);
-}
-
void QuicTestClient::TestClientDataToResend::Resend() {
test_client_->GetOrCreateStreamAndSendRequest(headers_, body_, fin_,
delegate_);
diff --git a/net/tools/quic/test_tools/quic_test_client.h b/net/tools/quic/test_tools/quic_test_client.h
index 6dc3ea5..93cc385 100644
--- a/net/tools/quic/test_tools/quic_test_client.h
+++ b/net/tools/quic/test_tools/quic_test_client.h
@@ -185,10 +185,6 @@ class QuicTestClient : public test::SimpleClient,
void set_priority(SpdyPriority priority) { priority_ = priority; }
- // Sets client's FEC policy. This policy applies to the data stream(s), and
- // also to the headers and crypto streams.
- void SetFecPolicy(FecPolicy fec_policy);
-
void WaitForWriteToFlush();
EpollServer* epoll_server() { return &epoll_server_; }
@@ -265,8 +261,6 @@ class QuicTestClient : public test::SimpleClient,
bool auto_reconnect_;
// Should we buffer the response body? Defaults to true.
bool buffer_body_;
- // FEC policy for data sent by this client.
- FecPolicy fec_policy_;
// When true allows the sending of a request to continue while the response is
// arriving.
bool allow_bidirectional_data_;
diff --git a/net/tools/quic/test_tools/quic_test_server.cc b/net/tools/quic/test_tools/quic_test_server.cc
index 31ddef8..d513a69 100644
--- a/net/tools/quic/test_tools/quic_test_server.cc
+++ b/net/tools/quic/test_tools/quic_test_server.cc
@@ -33,9 +33,14 @@ class CustomStreamSession : public QuicSimpleServerSession {
QuicConnection* connection,
QuicServerSessionVisitor* visitor,
const QuicCryptoServerConfig* crypto_config,
+ QuicCompressedCertsCache* compressed_certs_cache,
QuicTestServer::StreamFactory* factory,
QuicTestServer::CryptoStreamFactory* crypto_stream_factory)
- : QuicSimpleServerSession(config, connection, visitor, crypto_config),
+ : QuicSimpleServerSession(config,
+ connection,
+ visitor,
+ crypto_config,
+ compressed_certs_cache),
stream_factory_(factory),
crypto_stream_factory_(crypto_stream_factory) {}
@@ -52,11 +57,13 @@ class CustomStreamSession : public QuicSimpleServerSession {
}
QuicCryptoServerStreamBase* CreateQuicCryptoServerStream(
- const QuicCryptoServerConfig* crypto_config) override {
+ const QuicCryptoServerConfig* crypto_config,
+ QuicCompressedCertsCache* compressed_certs_cache) override {
if (crypto_stream_factory_) {
return crypto_stream_factory_->CreateCryptoStream(crypto_config, this);
}
- return QuicSimpleServerSession::CreateQuicCryptoServerStream(crypto_config);
+ return QuicSimpleServerSession::CreateQuicCryptoServerStream(
+ crypto_config, compressed_certs_cache);
}
private:
@@ -88,12 +95,13 @@ class QuicTestDispatcher : public QuicDispatcher {
QuicServerSessionBase* session = nullptr;
if (stream_factory_ != nullptr || crypto_stream_factory_ != nullptr) {
- session =
- new CustomStreamSession(config(), connection, this, crypto_config(),
- stream_factory_, crypto_stream_factory_);
+ session = new CustomStreamSession(
+ config(), connection, this, crypto_config(), compressed_certs_cache(),
+ stream_factory_, crypto_stream_factory_);
} else {
session = session_factory_->CreateSession(config(), connection, this,
- crypto_config());
+ crypto_config(),
+ compressed_certs_cache());
}
session->Initialize();
return session;
@@ -165,8 +173,13 @@ ImmediateGoAwaySession::ImmediateGoAwaySession(
const QuicConfig& config,
QuicConnection* connection,
QuicServerSessionVisitor* visitor,
- const QuicCryptoServerConfig* crypto_config)
- : QuicSimpleServerSession(config, connection, visitor, crypto_config) {
+ const QuicCryptoServerConfig* crypto_config,
+ QuicCompressedCertsCache* compressed_certs_cache)
+ : QuicSimpleServerSession(config,
+ connection,
+ visitor,
+ crypto_config,
+ compressed_certs_cache) {
SendGoAway(QUIC_PEER_GOING_AWAY, "");
}
diff --git a/net/tools/quic/test_tools/quic_test_server.h b/net/tools/quic/test_tools/quic_test_server.h
index ac02682..7af5f51 100644
--- a/net/tools/quic/test_tools/quic_test_server.h
+++ b/net/tools/quic/test_tools/quic_test_server.h
@@ -35,7 +35,8 @@ class QuicTestServer : public QuicServer {
const QuicConfig& config,
QuicConnection* connection,
QuicServerSessionVisitor* visitor,
- const QuicCryptoServerConfig* crypto_config) = 0;
+ const QuicCryptoServerConfig* crypto_config,
+ QuicCompressedCertsCache* compressed_certs_cache) = 0;
};
// Factory for creating QuicSimpleServerStreams.
@@ -89,7 +90,8 @@ class ImmediateGoAwaySession : public QuicSimpleServerSession {
ImmediateGoAwaySession(const QuicConfig& config,
QuicConnection* connection,
QuicServerSessionVisitor* visitor,
- const QuicCryptoServerConfig* crypto_config);
+ const QuicCryptoServerConfig* crypto_config,
+ QuicCompressedCertsCache* compressed_certs_cache);
};
} // namespace test