summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorrtenneti <rtenneti@chromium.org>2015-10-15 14:54:30 -0700
committerCommit bot <commit-bot@chromium.org>2015-10-15 21:55:16 +0000
commit5ca6eeeb62cfe6d3d2f8fa1e00a8112949f26791 (patch)
tree61887923c823474d876e12bf79fa5c0b5e53a523 /net
parent631a99a61cbe3e7e03e372b3d37c6a37fa700392 (diff)
downloadchromium_src-5ca6eeeb62cfe6d3d2f8fa1e00a8112949f26791.zip
chromium_src-5ca6eeeb62cfe6d3d2f8fa1e00a8112949f26791.tar.gz
chromium_src-5ca6eeeb62cfe6d3d2f8fa1e00a8112949f26791.tar.bz2
Landing Recent QUIC changes until 9/30/2015 20:43 UTC.
This CL doesn't include "remove inscure QUIC support" CL. relnote: Inline all frames smaller than a pointer into QuicFrame. No functional change. Merge internal change: 104330302 https://codereview.chromium.org/1399893005/ relnote: Avoid redundant recvmmsg when the previous recvmmsg returned less than the requested number of packets. Guarded by FLAGS_quic_read_packets_full_recvmmsg. This has no measurable effect on the QUIC microbenchmark, though it should avoid an extra call to recvmmsg at a minimum. Merge internal change: 104327020 https://codereview.chromium.org/1404873003/ relnote: n/a (QUIC test tools). Cleanup: use C++11 delegate constructor in quic_test_client, and clang-format to Chromium style: clang-format -i --style="{BasedOnStyle: Chromium, Standard: Cpp11}" quic_test_client.cc Merge internal change: 104305494 https://codereview.chromium.org/1407473005/ relnote: n/a (standalone quic_server binary). Cleanup: Use C++11 delegate constructor in quic_server Merge internal change: 104305451 https://codereview.chromium.org/1405843003/ relnote: Reduce the size of QUIC's TransmissionInfo struct based on suggestions from ClassLayoutOptimizer. No functional change. Merge internal change: 104242241 https://codereview.chromium.org/1401053005/ relnote: add test cases to catch failure on uninitialized self_address_ on chromium side, always set the self_address_ when client creates a new session and connection. There's a corner case in quic_client, when it tries to write to the first packet, the write fails. Previously we did not set self_address_ immediately when we created a new quic_connection. This leads to a crash on chromium side when logging the uninitialized self_address. Merge internal change: 104130818 https://codereview.chromium.org/1395423009/ relnote: n/a (comment only). Add comment about |proof_source|, adds ownership comment about |server_nonce_entropy|. Merge internal change: 104108540 https://codereview.chromium.org/1403643005/ relnote: Cache-align the encryption buffer in QuicPacketCreator::SerializePacket. Merge internal change: 104095714 https://codereview.chromium.org/1402943004/ relnote: Disables strike register lookups when talking QUIC_VERSION_27 or higher (not yet used by Chrome). Merge internal change: 103965712 https://codereview.chromium.org/1404053002/ relnote: Remove unused supported_versions argument from QuicTimeWaitListManager. No behavior change. Merge internal change: 103964623 https://codereview.chromium.org/1404013002/ relnote: Check QUIC handshake reject_reasons to decide whether to send a REJ. No behavior change, not protected. Simplifies things a little in the server crypto code. Instead of storing both a reject_reason *and* a boolean indicating whether there was a problem, just store the reject reason and use the presence of any such reasons to decide to send a REJ. Merge internal change: 103949902 https://codereview.chromium.org/1404523004/ relnote: Create Quic version 28. The receiver refuses to create a stream if too many streams are open, rather than closing the connection. FIXED=22475509,22476505 Merge internal change: 103943396 https://codereview.chromium.org/1398403006/ R=rch@chromium.org Review URL: https://codereview.chromium.org/1406983002 Cr-Commit-Position: refs/heads/master@{#354371}
Diffstat (limited to 'net')
-rw-r--r--net/quic/crypto/crypto_server_test.cc37
-rw-r--r--net/quic/crypto/quic_crypto_server_config.cc46
-rw-r--r--net/quic/crypto/quic_crypto_server_config.h6
-rw-r--r--net/quic/quic_connection.cc6
-rw-r--r--net/quic/quic_connection_logger.cc3
-rw-r--r--net/quic/quic_connection_test.cc25
-rw-r--r--net/quic/quic_crypto_server_stream_test.cc3
-rw-r--r--net/quic/quic_flags.cc7
-rw-r--r--net/quic/quic_flags.h1
-rw-r--r--net/quic/quic_framer.cc3
-rw-r--r--net/quic/quic_framer_test.cc12
-rw-r--r--net/quic/quic_packet_creator.cc9
-rw-r--r--net/quic/quic_packet_creator_test.cc2
-rw-r--r--net/quic/quic_packet_generator.cc11
-rw-r--r--net/quic/quic_protocol.cc99
-rw-r--r--net/quic/quic_protocol.h49
-rw-r--r--net/quic/quic_protocol_test.cc2
-rw-r--r--net/quic/quic_session.cc7
-rw-r--r--net/quic/quic_unacked_packet_map.cc2
-rw-r--r--net/quic/quic_unacked_packet_map.h2
-rw-r--r--net/quic/quic_utils.cc1
-rw-r--r--net/quic/test_tools/crypto_test_utils_chromium.cc2
-rw-r--r--net/tools/quic/end_to_end_test.cc12
-rw-r--r--net/tools/quic/quic_dispatcher.cc2
-rw-r--r--net/tools/quic/quic_packet_reader.cc8
-rw-r--r--net/tools/quic/quic_packet_reader.h4
-rw-r--r--net/tools/quic/quic_server.cc20
-rw-r--r--net/tools/quic/quic_server_session_test.cc16
-rw-r--r--net/tools/quic/quic_time_wait_list_manager.cc3
-rw-r--r--net/tools/quic/quic_time_wait_list_manager.h3
-rw-r--r--net/tools/quic/quic_time_wait_list_manager_test.cc5
-rw-r--r--net/tools/quic/test_tools/mock_quic_time_wait_list_manager.cc5
-rw-r--r--net/tools/quic/test_tools/quic_test_client.cc44
33 files changed, 240 insertions, 217 deletions
diff --git a/net/quic/crypto/crypto_server_test.cc b/net/quic/crypto/crypto_server_test.cc
index a905597..5bcbc70 100644
--- a/net/quic/crypto/crypto_server_test.cc
+++ b/net/quic/crypto/crypto_server_test.cc
@@ -408,22 +408,18 @@ TEST_P(CryptoServerTest, BadSNI) {
}
}
-// TODO(rtenneti): Enable the DefaultCert test after implementing ProofSource.
-// See http://crbug.com/514472.
TEST_P(CryptoServerTest, DefaultCert) {
// Check that the server replies with a default certificate when no SNI is
- // specified.
+ // specified. The CHLO is constructed to generate a REJ with certs, so must
+ // not contain a valid STK, and must include PDMD.
// 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(),
"PDMD", "X509",
- "XLCT", XlctHexString().c_str(),
"VER\0", client_version_string_.c_str(),
"$padding", static_cast<int>(kClientHelloMinimumSize),
nullptr);
@@ -435,9 +431,15 @@ TEST_P(CryptoServerTest, DefaultCert) {
EXPECT_TRUE(out_.GetStringPiece(kPROF, &proof));
EXPECT_NE(0u, cert.size());
EXPECT_NE(0u, proof.size());
- const HandshakeFailureReason kRejectReasons[] = {
- CLIENT_NONCE_INVALID_TIME_FAILURE};
- CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
+ if (client_version_ <= QUIC_VERSION_26) {
+ const HandshakeFailureReason kRejectReasons[] = {
+ CLIENT_NONCE_INVALID_TIME_FAILURE};
+ CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
+ } else {
+ const HandshakeFailureReason kRejectReasons[] = {
+ SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
+ CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
+ }
}
TEST_P(CryptoServerTest, TooSmall) {
@@ -614,14 +616,23 @@ TEST_P(CryptoServerTest, CorruptMultipleTags) {
// clang-format on
ShouldSucceed(msg);
CheckRejectTag();
- const HandshakeFailureReason kRejectReasons[] = {
- SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE, CLIENT_NONCE_INVALID_FAILURE,
- SERVER_NONCE_DECRYPTION_FAILURE,
+
+ if (client_version_ <= QUIC_VERSION_26) {
+ const HandshakeFailureReason kRejectReasons[] = {
+ SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE, CLIENT_NONCE_INVALID_FAILURE,
+ SERVER_NONCE_DECRYPTION_FAILURE};
+ CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
+ } else {
+ const HandshakeFailureReason kRejectReasons[] = {
+ SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE, CLIENT_NONCE_INVALID_FAILURE};
+ CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
};
- CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
}
TEST_P(CryptoServerTest, ReplayProtection) {
+ if (client_version_ > QUIC_VERSION_26) {
+ return;
+ }
// This tests that disabling replay protection works.
// clang-format off
CryptoHandshakeMessage msg = CryptoTestUtils::Message(
diff --git a/net/quic/crypto/quic_crypto_server_config.cc b/net/quic/crypto/quic_crypto_server_config.cc
index 8481a0e..5371438 100644
--- a/net/quic/crypto/quic_crypto_server_config.cc
+++ b/net/quic/crypto/quic_crypto_server_config.cc
@@ -120,7 +120,6 @@ class VerifyNonceIsValidAndUniqueCallback
InsertStatus nonce_error) override {
DVLOG(1) << "Using client nonce, unique: " << nonce_is_valid_and_unique
<< " nonce_error: " << nonce_error;
- result_->info.unique = nonce_is_valid_and_unique;
if (!nonce_is_valid_and_unique) {
HandshakeFailureReason client_nonce_error;
switch (nonce_error) {
@@ -168,12 +167,7 @@ const char QuicCryptoServerConfig::TESTING[] = "secret string for testing";
ClientHelloInfo::ClientHelloInfo(const IPAddressNumber& in_client_ip,
QuicWallTime in_now)
- : client_ip(in_client_ip),
- now(in_now),
- valid_source_address_token(false),
- client_nonce_well_formed(false),
- unique(false) {
-}
+ : client_ip(in_client_ip), now(in_now), valid_source_address_token(false) {}
ClientHelloInfo::~ClientHelloInfo() {
}
@@ -617,10 +611,7 @@ QuicErrorCode QuicCryptoServerConfig::ProcessClientHello(
return QUIC_HANDSHAKE_FAILED;
}
- if (!info.valid_source_address_token ||
- !info.client_nonce_well_formed ||
- !info.unique ||
- !requested_config.get()) {
+ if (!info.reject_reasons.empty() || !requested_config.get()) {
BuildRejection(*primary_config, client_hello, info,
validate_chlo_result.cached_network_params,
use_stateless_rejects, server_designated_connection_id, rand,
@@ -1032,10 +1023,8 @@ void QuicCryptoServerConfig::EvaluateClientHello(
}
}
- if (client_hello.GetStringPiece(kNONC, &info->client_nonce) &&
- info->client_nonce.size() == kNonceSize) {
- info->client_nonce_well_formed = true;
- } else {
+ if (!client_hello.GetStringPiece(kNONC, &info->client_nonce) ||
+ info->client_nonce.size() != kNonceSize) {
info->reject_reasons.push_back(CLIENT_NONCE_INVALID_FAILURE);
// Invalid client nonce.
DVLOG(1) << "Invalid client nonce.";
@@ -1046,27 +1035,36 @@ void QuicCryptoServerConfig::EvaluateClientHello(
found_error = true;
}
- if (!replay_protection_) {
- if (!found_error) {
- info->unique = true;
+ // Server nonce is optional, and used for key derivation if present.
+ client_hello.GetStringPiece(kServerNonceTag, &info->server_nonce);
+
+ if (version > QUIC_VERSION_26) {
+ DVLOG(1) << "No 0-RTT replay protection in QUIC_VERSION_27 and higher.";
+ // If the server nonce is empty and we're requiring handshake confirmation
+ // for DoS reasons then we must reject the CHLO.
+ if (FLAGS_quic_require_handshake_confirmation &&
+ info->server_nonce.empty()) {
+ info->reject_reasons.push_back(SERVER_NONCE_REQUIRED_FAILURE);
}
+ helper.ValidationComplete(QUIC_NO_ERROR, "");
+ return;
+ }
+
+ if (!replay_protection_) {
DVLOG(1) << "No replay protection.";
helper.ValidationComplete(QUIC_NO_ERROR, "");
return;
}
- client_hello.GetStringPiece(kServerNonceTag, &info->server_nonce);
if (!info->server_nonce.empty()) {
// If the server nonce is present, use it to establish uniqueness.
HandshakeFailureReason server_nonce_error =
ValidateServerNonce(info->server_nonce, info->now);
- if (server_nonce_error == HANDSHAKE_OK) {
- info->unique = true;
- } else {
+ bool is_unique = server_nonce_error == HANDSHAKE_OK;
+ if (!is_unique) {
info->reject_reasons.push_back(server_nonce_error);
- info->unique = false;
}
- DVLOG(1) << "Using server nonce, unique: " << info->unique;
+ DVLOG(1) << "Using server nonce, unique: " << is_unique;
helper.ValidationComplete(QUIC_NO_ERROR, "");
return;
}
diff --git a/net/quic/crypto/quic_crypto_server_config.h b/net/quic/crypto/quic_crypto_server_config.h
index 4a5c83f..cb3f776 100644
--- a/net/quic/crypto/quic_crypto_server_config.h
+++ b/net/quic/crypto/quic_crypto_server_config.h
@@ -50,8 +50,6 @@ struct ClientHelloInfo {
// Outputs from EvaluateClientHello.
bool valid_source_address_token;
- bool client_nonce_well_formed;
- bool unique;
base::StringPiece sni;
base::StringPiece client_nonce;
base::StringPiece server_nonce;
@@ -145,7 +143,9 @@ class NET_EXPORT_PRIVATE QuicCryptoServerConfig {
// into a KDF before use. In tests, use TESTING.
// |server_nonce_entropy|: an entropy source used to generate the orbit and
// key for server nonces, which are always local to a given instance of a
- // server.
+ // server. Not owned.
+ // |proof_source|: provides certificate chains and signatures. This class
+ // takes ownership of |proof_source|.
QuicCryptoServerConfig(base::StringPiece source_address_token_secret,
QuicRandom* server_nonce_entropy);
~QuicCryptoServerConfig();
diff --git a/net/quic/quic_connection.cc b/net/quic/quic_connection.cc
index f639eb7..74a2626 100644
--- a/net/quic/quic_connection.cc
+++ b/net/quic/quic_connection.cc
@@ -1626,7 +1626,9 @@ bool QuicConnection::WritePacketInner(QueuedPacket* packet) {
OnWriteError(result.error_code);
DLOG(ERROR) << ENDPOINT << "failed writing " << encrypted->length()
<< " bytes "
- << " from host " << self_address().ToStringWithoutPort()
+ << " from host " << (self_address().address().empty()
+ ? " empty address "
+ : self_address().ToStringWithoutPort())
<< " to address " << peer_address().ToString();
return false;
}
@@ -1763,7 +1765,7 @@ void QuicConnection::SendPing() {
if (retransmission_alarm_->IsSet()) {
return;
}
- packet_generator_.AddControlFrame(QuicFrame(new QuicPingFrame));
+ packet_generator_.AddControlFrame(QuicFrame(QuicPingFrame()));
}
void QuicConnection::SendAck() {
diff --git a/net/quic/quic_connection_logger.cc b/net/quic/quic_connection_logger.cc
index 9be77b9..956138f 100644
--- a/net/quic/quic_connection_logger.cc
+++ b/net/quic/quic_connection_logger.cc
@@ -416,8 +416,7 @@ void QuicConnectionLogger::OnFrameAddedToPacket(const QuicFrame& frame) {
++num_blocked_frames_sent_;
net_log_.AddEvent(
NetLog::TYPE_QUIC_SESSION_BLOCKED_FRAME_SENT,
- base::Bind(&NetLogQuicBlockedFrameCallback,
- frame.blocked_frame));
+ base::Bind(&NetLogQuicBlockedFrameCallback, frame.blocked_frame));
break;
case STOP_WAITING_FRAME:
net_log_.AddEvent(
diff --git a/net/quic/quic_connection_test.cc b/net/quic/quic_connection_test.cc
index f60c84e..306f496 100644
--- a/net/quic/quic_connection_test.cc
+++ b/net/quic/quic_connection_test.cc
@@ -239,6 +239,7 @@ class TestPacketWriter : public QuicPacketWriter {
framer_(SupportedVersions(version_)),
last_packet_size_(0),
write_blocked_(false),
+ write_should_fail_(false),
block_on_next_write_(false),
is_write_blocked_data_buffered_(false),
final_bytes_of_last_packet_(0),
@@ -274,6 +275,11 @@ class TestPacketWriter : public QuicPacketWriter {
if (IsWriteBlocked()) {
return WriteResult(WRITE_STATUS_BLOCKED, -1);
}
+
+ if (ShouldWriteFail()) {
+ return WriteResult(WRITE_STATUS_ERROR, 0);
+ }
+
last_packet_size_ = packet.length();
if (!write_pause_time_delta_.IsZero()) {
@@ -286,10 +292,14 @@ class TestPacketWriter : public QuicPacketWriter {
return is_write_blocked_data_buffered_;
}
+ bool ShouldWriteFail() { return write_should_fail_; }
+
bool IsWriteBlocked() const override { return write_blocked_; }
void SetWritable() override { write_blocked_ = false; }
+ void SetShouldWriteFail() { write_should_fail_ = true; }
+
QuicByteCount GetMaxPacketSize(
const IPEndPoint& /*peer_address*/) const override {
return max_packet_size_;
@@ -383,6 +393,7 @@ class TestPacketWriter : public QuicPacketWriter {
SimpleQuicFramer framer_;
size_t last_packet_size_;
bool write_blocked_;
+ bool write_should_fail_;
bool block_on_next_write_;
bool is_write_blocked_data_buffered_;
uint32 final_bytes_of_last_packet_;
@@ -1076,7 +1087,7 @@ TEST_P(QuicConnectionTest, IncreaseServerMaxPacketSize) {
QuicFrames frames;
QuicPaddingFrame padding;
frames.push_back(QuicFrame(&frame1_));
- frames.push_back(QuicFrame(&padding));
+ frames.push_back(QuicFrame(padding));
scoped_ptr<QuicPacket> packet(ConstructPacket(header, frames));
char buffer[kMaxPacketSize];
scoped_ptr<QuicEncryptedPacket> encrypted(framer_.EncryptPayload(
@@ -1107,7 +1118,7 @@ TEST_P(QuicConnectionTest, IncreaseServerMaxPacketSizeWhileWriterLimited) {
QuicFrames frames;
QuicPaddingFrame padding;
frames.push_back(QuicFrame(&frame1_));
- frames.push_back(QuicFrame(&padding));
+ frames.push_back(QuicFrame(padding));
scoped_ptr<QuicPacket> packet(ConstructPacket(header, frames));
char buffer[kMaxPacketSize];
scoped_ptr<QuicEncryptedPacket> encrypted(framer_.EncryptPayload(
@@ -3650,6 +3661,16 @@ TEST_P(QuicConnectionTest, SendScheduler) {
EXPECT_EQ(0u, connection_.NumQueuedPackets());
}
+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(1, 0, !kEntropyFlag);
+ writer_->SetShouldWriteFail();
+ connection_.SendPacket(ENCRYPTION_NONE, 1, packet, kTestEntropyHash,
+ HAS_RETRANSMITTABLE_DATA, false, false);
+}
+
TEST_P(QuicConnectionTest, SendSchedulerEAGAIN) {
QuicPacket* packet = ConstructDataPacket(1, 0, !kEntropyFlag);
BlockOnNextWrite();
diff --git a/net/quic/quic_crypto_server_stream_test.cc b/net/quic/quic_crypto_server_stream_test.cc
index 5a999ed..88b6de2 100644
--- a/net/quic/quic_crypto_server_stream_test.cc
+++ b/net/quic/quic_crypto_server_stream_test.cc
@@ -141,6 +141,9 @@ class QuicCryptoServerStreamTest : public ::testing::TestWithParam<bool> {
}
bool AsyncStrikeRegisterVerification() {
+ if (server_connection_->version() > QUIC_VERSION_26) {
+ return false;
+ }
return GetParam();
}
diff --git a/net/quic/quic_flags.cc b/net/quic/quic_flags.cc
index d3e5a40..3feb646 100644
--- a/net/quic/quic_flags.cc
+++ b/net/quic/quic_flags.cc
@@ -51,7 +51,7 @@ bool FLAGS_quic_limit_max_cwnd = true;
// If true, require handshake confirmation for QUIC connections, functionally
// disabling 0-rtt handshakes.
-// TODO(rtenneti): Enable this flag after fixing tests.
+// TODO(rtenneti): Enable this flag after CryptoServerTest's are fixed.
bool FLAGS_quic_require_handshake_confirmation = false;
// Disables special treatment of truncated acks, since older retransmissions are
@@ -80,3 +80,8 @@ bool FLAGS_shift_quic_cubic_epoch_when_app_limited = true;
// If true, accounts for available (implicitly opened) streams under a separate
// quota from open streams, which is 10 times larger.
bool FLAGS_allow_many_available_streams = true;
+
+// If true, QuicPacketReader::ReadAndDispatchPackets will only return true if
+// recvmmsg fills all of the passed in messages. Otherwise, it will return true
+// if recvmmsg read any messages.
+bool FLAGS_quic_read_packets_full_recvmmsg = true;
diff --git a/net/quic/quic_flags.h b/net/quic/quic_flags.h
index e613ea6..bb66a23 100644
--- a/net/quic/quic_flags.h
+++ b/net/quic/quic_flags.h
@@ -28,5 +28,6 @@ NET_EXPORT_PRIVATE extern bool FLAGS_reset_cubic_epoch_when_app_limited;
NET_EXPORT_PRIVATE extern bool FLAGS_quic_packet_queue_use_interval_set;
NET_EXPORT_PRIVATE extern bool FLAGS_shift_quic_cubic_epoch_when_app_limited;
NET_EXPORT_PRIVATE extern bool FLAGS_allow_many_available_streams;
+NET_EXPORT_PRIVATE extern bool FLAGS_quic_read_packets_full_recvmmsg;
#endif // NET_QUIC_QUIC_FLAGS_H_
diff --git a/net/quic/quic_framer.cc b/net/quic/quic_framer.cc
index a04824a..9dd3d90 100644
--- a/net/quic/quic_framer.cc
+++ b/net/quic/quic_framer.cc
@@ -268,7 +268,8 @@ size_t QuicFramer::GetSerializedFrameLength(
InFecGroup is_in_fec_group,
QuicPacketNumberLength packet_number_length) {
// Prevent a rare crash reported in b/19458523.
- if (frame.stream_frame == nullptr) {
+ if ((frame.type == STREAM_FRAME || frame.type == ACK_FRAME) &&
+ frame.stream_frame == nullptr) {
LOG(DFATAL) << "Cannot compute the length of a null frame. "
<< "type:" << frame.type << "free_bytes:" << free_bytes
<< " first_frame:" << first_frame
diff --git a/net/quic/quic_framer_test.cc b/net/quic/quic_framer_test.cc
index 45710c1..5d3a7b7 100644
--- a/net/quic/quic_framer_test.cc
+++ b/net/quic/quic_framer_test.cc
@@ -2924,7 +2924,7 @@ TEST_P(QuicFramerTest, BuildPaddingFramePacket) {
QuicPaddingFrame padding_frame;
QuicFrames frames;
- frames.push_back(QuicFrame(&padding_frame));
+ frames.push_back(QuicFrame(padding_frame));
// clang-format off
unsigned char packet[kMaxPacketSize] = {
@@ -2973,7 +2973,7 @@ TEST_P(QuicFramerTest, Build4ByteSequenceNumberPaddingFramePacket) {
QuicPaddingFrame padding_frame;
QuicFrames frames;
- frames.push_back(QuicFrame(&padding_frame));
+ frames.push_back(QuicFrame(padding_frame));
// clang-format off
unsigned char packet[kMaxPacketSize] = {
@@ -3021,7 +3021,7 @@ TEST_P(QuicFramerTest, Build2ByteSequenceNumberPaddingFramePacket) {
QuicPaddingFrame padding_frame;
QuicFrames frames;
- frames.push_back(QuicFrame(&padding_frame));
+ frames.push_back(QuicFrame(padding_frame));
// clang-format off
unsigned char packet[kMaxPacketSize] = {
@@ -3069,7 +3069,7 @@ TEST_P(QuicFramerTest, Build1ByteSequenceNumberPaddingFramePacket) {
QuicPaddingFrame padding_frame;
QuicFrames frames;
- frames.push_back(QuicFrame(&padding_frame));
+ frames.push_back(QuicFrame(padding_frame));
// clang-format off
unsigned char packet[kMaxPacketSize] = {
@@ -3944,7 +3944,7 @@ TEST_P(QuicFramerTest, BuildPingPacket) {
QuicPingFrame ping_frame;
QuicFrames frames;
- frames.push_back(QuicFrame(&ping_frame));
+ frames.push_back(QuicFrame(ping_frame));
// clang-format off
unsigned char packet[] = {
@@ -3986,7 +3986,7 @@ TEST_P(QuicFramerTest, BuildMtuDiscoveryPacket) {
QuicMtuDiscoveryFrame mtu_discovery_frame;
QuicFrames frames;
- frames.push_back(QuicFrame(&mtu_discovery_frame));
+ frames.push_back(QuicFrame(mtu_discovery_frame));
// clang-format off
unsigned char packet[] = {
diff --git a/net/quic/quic_packet_creator.cc b/net/quic/quic_packet_creator.cc
index 18a719a..8e4f174 100644
--- a/net/quic/quic_packet_creator.cc
+++ b/net/quic/quic_packet_creator.cc
@@ -451,7 +451,11 @@ SerializedPacket QuicPacketCreator::SerializePacket(
bool possibly_truncated_by_length = packet_size_ == max_plaintext_size_ &&
queued_frames_.size() == 1 &&
queued_frames_.back().type == ACK_FRAME;
- char buffer[kMaxPacketSize];
+ // The optimized encryption algorithm implementations run faster when
+ // operating on aligned memory.
+ // TODO(rtenneti): Change the default 64 alignas value (used the default
+ // value from CACHELINE_SIZE).
+ ALIGNAS(64) char buffer[kMaxPacketSize];
scoped_ptr<QuicPacket> packet;
// Use the packet_size_ instead of the buffer size to ensure smaller
// packet sizes are properly used.
@@ -638,8 +642,7 @@ void QuicPacketCreator::MaybeAddPadding() {
return;
}
- QuicPaddingFrame padding;
- bool success = AddFrame(QuicFrame(&padding), false, false, nullptr);
+ bool success = AddFrame(QuicFrame(QuicPaddingFrame()), false, false, nullptr);
DCHECK(success);
}
diff --git a/net/quic/quic_packet_creator_test.cc b/net/quic/quic_packet_creator_test.cc
index c0565ed..4e73ba1 100644
--- a/net/quic/quic_packet_creator_test.cc
+++ b/net/quic/quic_packet_creator_test.cc
@@ -1006,7 +1006,7 @@ TEST_P(QuicPacketCreatorTest, AddFrameAndSerialize) {
EXPECT_TRUE(creator_.HasPendingFrames());
QuicPaddingFrame padding_frame;
- EXPECT_TRUE(creator_.AddSavedFrame(QuicFrame(&padding_frame)));
+ EXPECT_TRUE(creator_.AddSavedFrame(QuicFrame(padding_frame)));
EXPECT_TRUE(creator_.HasPendingFrames());
EXPECT_EQ(0u, creator_.BytesFree());
diff --git a/net/quic/quic_packet_generator.cc b/net/quic/quic_packet_generator.cc
index eed8ec7..a1a7dd2 100644
--- a/net/quic/quic_packet_generator.cc
+++ b/net/quic/quic_packet_generator.cc
@@ -57,7 +57,8 @@ QuicPacketGenerator::~QuicPacketGenerator() {
for (QuicFrame& frame : queued_control_frames_) {
switch (frame.type) {
case PADDING_FRAME:
- delete frame.padding_frame;
+ case MTU_DISCOVERY_FRAME:
+ case PING_FRAME:
break;
case STREAM_FRAME:
delete frame.stream_frame;
@@ -65,9 +66,6 @@ QuicPacketGenerator::~QuicPacketGenerator() {
case ACK_FRAME:
delete frame.ack_frame;
break;
- case MTU_DISCOVERY_FRAME:
- delete frame.mtu_discovery_frame;
- break;
case RST_STREAM_FRAME:
delete frame.rst_stream_frame;
break;
@@ -86,9 +84,6 @@ QuicPacketGenerator::~QuicPacketGenerator() {
case STOP_WAITING_FRAME:
delete frame.stop_waiting_frame;
break;
- case PING_FRAME:
- delete frame.ping_frame;
- break;
case NUM_FRAME_TYPES:
DCHECK(false) << "Cannot delete type: " << frame.type;
}
@@ -250,7 +245,7 @@ void QuicPacketGenerator::GenerateMtuDiscoveryPacket(
// The MTU discovery frame is allocated on the stack, since it is going to be
// serialized within this function.
QuicMtuDiscoveryFrame mtu_discovery_frame;
- QuicFrame frame(&mtu_discovery_frame);
+ QuicFrame frame(mtu_discovery_frame);
// Send the probe packet with the new length.
SetMaxPacketLength(target_mtu, /*force=*/true);
diff --git a/net/quic/quic_protocol.cc b/net/quic/quic_protocol.cc
index d281358..e04902f 100644
--- a/net/quic/quic_protocol.cc
+++ b/net/quic/quic_protocol.cc
@@ -142,6 +142,8 @@ QuicTag QuicVersionToQuicTag(const QuicVersion version) {
return MakeQuicTag('Q', '0', '2', '6');
case QUIC_VERSION_27:
return MakeQuicTag('Q', '0', '2', '7');
+ case QUIC_VERSION_28:
+ return MakeQuicTag('Q', '0', '2', '8');
default:
// This shold be an ERROR because we should never attempt to convert an
// invalid QuicVersion to be written to the wire.
@@ -172,6 +174,7 @@ string QuicVersionToString(const QuicVersion version) {
RETURN_STRING_LITERAL(QUIC_VERSION_25);
RETURN_STRING_LITERAL(QUIC_VERSION_26);
RETURN_STRING_LITERAL(QUIC_VERSION_27);
+ RETURN_STRING_LITERAL(QUIC_VERSION_28);
default:
return "QUIC_VERSION_UNSUPPORTED";
}
@@ -263,59 +266,37 @@ QuicConnectionCloseFrame::QuicConnectionCloseFrame()
QuicFrame::QuicFrame() {}
-QuicFrame::QuicFrame(QuicPaddingFrame* padding_frame)
- : type(PADDING_FRAME),
- padding_frame(padding_frame) {
-}
+QuicFrame::QuicFrame(QuicPaddingFrame padding_frame)
+ : type(PADDING_FRAME), padding_frame(padding_frame) {}
QuicFrame::QuicFrame(QuicStreamFrame* stream_frame)
- : type(STREAM_FRAME),
- stream_frame(stream_frame) {
-}
+ : type(STREAM_FRAME), stream_frame(stream_frame) {}
-QuicFrame::QuicFrame(QuicAckFrame* frame)
- : type(ACK_FRAME),
- ack_frame(frame) {
-}
+QuicFrame::QuicFrame(QuicAckFrame* frame) : type(ACK_FRAME), ack_frame(frame) {}
-QuicFrame::QuicFrame(QuicMtuDiscoveryFrame* frame)
- : type(MTU_DISCOVERY_FRAME), mtu_discovery_frame(frame) {
-}
+QuicFrame::QuicFrame(QuicMtuDiscoveryFrame frame)
+ : type(MTU_DISCOVERY_FRAME), mtu_discovery_frame(frame) {}
QuicFrame::QuicFrame(QuicStopWaitingFrame* frame)
- : type(STOP_WAITING_FRAME),
- stop_waiting_frame(frame) {
-}
+ : type(STOP_WAITING_FRAME), stop_waiting_frame(frame) {}
-QuicFrame::QuicFrame(QuicPingFrame* frame)
- : type(PING_FRAME),
- ping_frame(frame) {
-}
+QuicFrame::QuicFrame(QuicPingFrame frame)
+ : type(PING_FRAME), ping_frame(frame) {}
QuicFrame::QuicFrame(QuicRstStreamFrame* frame)
- : type(RST_STREAM_FRAME),
- rst_stream_frame(frame) {
-}
+ : type(RST_STREAM_FRAME), rst_stream_frame(frame) {}
QuicFrame::QuicFrame(QuicConnectionCloseFrame* frame)
- : type(CONNECTION_CLOSE_FRAME),
- connection_close_frame(frame) {
-}
+ : type(CONNECTION_CLOSE_FRAME), connection_close_frame(frame) {}
QuicFrame::QuicFrame(QuicGoAwayFrame* frame)
- : type(GOAWAY_FRAME),
- goaway_frame(frame) {
-}
+ : type(GOAWAY_FRAME), goaway_frame(frame) {}
QuicFrame::QuicFrame(QuicWindowUpdateFrame* frame)
- : type(WINDOW_UPDATE_FRAME),
- window_update_frame(frame) {
-}
+ : type(WINDOW_UPDATE_FRAME), window_update_frame(frame) {}
QuicFrame::QuicFrame(QuicBlockedFrame* frame)
- : type(BLOCKED_FRAME),
- blocked_frame(frame) {
-}
+ : type(BLOCKED_FRAME), blocked_frame(frame) {}
QuicFecData::QuicFecData() : fec_group(0) {}
@@ -785,43 +766,39 @@ RetransmittableFrames::RetransmittableFrames(EncryptionLevel level)
}
RetransmittableFrames::~RetransmittableFrames() {
- for (QuicFrames::iterator it = frames_.begin(); it != frames_.end(); ++it) {
- switch (it->type) {
+ for (QuicFrame& frame : frames_) {
+ switch (frame.type) {
+ // Frames smaller than a pointer are inlined, so don't need to be deleted.
case PADDING_FRAME:
- delete it->padding_frame;
+ case MTU_DISCOVERY_FRAME:
+ case PING_FRAME:
break;
case STREAM_FRAME:
- delete it->stream_frame;
+ delete frame.stream_frame;
break;
case ACK_FRAME:
- delete it->ack_frame;
- break;
- case MTU_DISCOVERY_FRAME:
- delete it->mtu_discovery_frame;
+ delete frame.ack_frame;
break;
case STOP_WAITING_FRAME:
- delete it->stop_waiting_frame;
- break;
- case PING_FRAME:
- delete it->ping_frame;
+ delete frame.stop_waiting_frame;
break;
case RST_STREAM_FRAME:
- delete it->rst_stream_frame;
+ delete frame.rst_stream_frame;
break;
case CONNECTION_CLOSE_FRAME:
- delete it->connection_close_frame;
+ delete frame.connection_close_frame;
break;
case GOAWAY_FRAME:
- delete it->goaway_frame;
+ delete frame.goaway_frame;
break;
case WINDOW_UPDATE_FRAME:
- delete it->window_update_frame;
+ delete frame.window_update_frame;
break;
case BLOCKED_FRAME:
- delete it->blocked_frame;
+ delete frame.blocked_frame;
break;
case NUM_FRAME_TYPES:
- DCHECK(false) << "Cannot delete type: " << it->type;
+ DCHECK(false) << "Cannot delete type: " << frame.type;
}
}
// TODO(rtenneti): Delete the for loop once chrome has c++11 library support
@@ -893,31 +870,31 @@ ostream& operator<<(ostream& os, const QuicEncryptedPacket& s) {
TransmissionInfo::TransmissionInfo()
: retransmittable_frames(nullptr),
packet_number_length(PACKET_1BYTE_PACKET_NUMBER),
- sent_time(QuicTime::Zero()),
bytes_sent(0),
nack_count(0),
+ sent_time(QuicTime::Zero()),
transmission_type(NOT_RETRANSMISSION),
- all_transmissions(nullptr),
in_flight(false),
is_unackable(false),
- is_fec_packet(false) {}
+ is_fec_packet(false),
+ all_transmissions(nullptr) {}
TransmissionInfo::TransmissionInfo(
RetransmittableFrames* retransmittable_frames,
QuicPacketNumberLength packet_number_length,
TransmissionType transmission_type,
QuicTime sent_time,
- QuicByteCount bytes_sent,
+ QuicPacketLength bytes_sent,
bool is_fec_packet)
: retransmittable_frames(retransmittable_frames),
packet_number_length(packet_number_length),
- sent_time(sent_time),
bytes_sent(bytes_sent),
nack_count(0),
+ sent_time(sent_time),
transmission_type(transmission_type),
- all_transmissions(nullptr),
in_flight(false),
is_unackable(false),
- is_fec_packet(is_fec_packet) {}
+ is_fec_packet(is_fec_packet),
+ all_transmissions(nullptr) {}
} // namespace net
diff --git a/net/quic/quic_protocol.h b/net/quic/quic_protocol.h
index c942b8d..9d4ad54 100644
--- a/net/quic/quic_protocol.h
+++ b/net/quic/quic_protocol.h
@@ -51,6 +51,7 @@ typedef std::map<QuicTag, std::string> QuicTagValueMap;
// TODO(rtenneti): Didn't use SpdyPriority because SpdyPriority is uint8 and
// QuicPriority is uint32. Use SpdyPriority when we change the QUIC_VERSION.
typedef uint32 QuicPriority;
+typedef uint16 QuicPacketLength;
// Default initial maximum size in bytes of a QUIC packet.
const QuicByteCount kDefaultMaxPacketSize = 1350;
@@ -346,6 +347,7 @@ enum QuicVersion {
// from QuicRstStreamFrame
QUIC_VERSION_26 = 26, // In CHLO, send XLCT tag containing hash of leaf cert
QUIC_VERSION_27 = 27, // Sends a nonce in the SHLO.
+ QUIC_VERSION_28 = 28, // Receiver can refuse to create a requested stream.
};
// This vector contains QUIC versions which we currently support.
@@ -356,7 +358,8 @@ enum QuicVersion {
// IMPORTANT: if you are adding to this list, follow the instructions at
// http://sites/quic/adding-and-removing-versions
static const QuicVersion kSupportedQuicVersions[] = {
- QUIC_VERSION_27, QUIC_VERSION_26, QUIC_VERSION_25, QUIC_VERSION_24};
+ QUIC_VERSION_28, QUIC_VERSION_27, QUIC_VERSION_26, QUIC_VERSION_25,
+ QUIC_VERSION_24};
typedef std::vector<QuicVersion> QuicVersionVector;
@@ -436,6 +439,10 @@ enum QuicRstStreamErrorCode {
// Closing stream locally, sending a RST to allow for proper flow control
// accounting. Sent in response to a RST from the peer.
QUIC_RST_ACKNOWLEDGEMENT,
+ // Receiver refused to create the stream (because its limit on open streams
+ // has been reached). The sender should retry the request later (using
+ // another stream).
+ QUIC_REFUSED_STREAM,
// No error. Used as bound while iterating.
QUIC_STREAM_LAST_ERROR,
@@ -685,13 +692,11 @@ enum QuicVersionNegotiationState {
typedef QuicPacketPublicHeader QuicVersionNegotiationPacket;
// A padding frame contains no payload.
-struct NET_EXPORT_PRIVATE QuicPaddingFrame {
-};
+struct NET_EXPORT_PRIVATE QuicPaddingFrame {};
// A ping frame contains no payload, though it is retransmittable,
// and ACK'd just like other normal frames.
-struct NET_EXPORT_PRIVATE QuicPingFrame {
-};
+struct NET_EXPORT_PRIVATE QuicPingFrame {};
// A path MTU discovery frame contains no payload and is serialized as a ping
// frame.
@@ -994,15 +999,15 @@ enum EncryptionLevel {
struct NET_EXPORT_PRIVATE QuicFrame {
QuicFrame();
- explicit QuicFrame(QuicPaddingFrame* padding_frame);
+ explicit QuicFrame(QuicPaddingFrame padding_frame);
+ explicit QuicFrame(QuicMtuDiscoveryFrame frame);
+ explicit QuicFrame(QuicPingFrame frame);
+
explicit QuicFrame(QuicStreamFrame* stream_frame);
explicit QuicFrame(QuicAckFrame* frame);
- explicit QuicFrame(QuicMtuDiscoveryFrame* frame);
-
explicit QuicFrame(QuicRstStreamFrame* frame);
explicit QuicFrame(QuicConnectionCloseFrame* frame);
explicit QuicFrame(QuicStopWaitingFrame* frame);
- explicit QuicFrame(QuicPingFrame* frame);
explicit QuicFrame(QuicGoAwayFrame* frame);
explicit QuicFrame(QuicWindowUpdateFrame* frame);
explicit QuicFrame(QuicBlockedFrame* frame);
@@ -1012,14 +1017,15 @@ struct NET_EXPORT_PRIVATE QuicFrame {
QuicFrameType type;
union {
- QuicPaddingFrame* padding_frame;
+ // Frames smaller than a pointer are inline.
+ QuicPaddingFrame padding_frame;
+ QuicMtuDiscoveryFrame mtu_discovery_frame;
+ QuicPingFrame ping_frame;
+
+ // Frames larger than a pointer.
QuicStreamFrame* stream_frame;
QuicAckFrame* ack_frame;
- QuicMtuDiscoveryFrame* mtu_discovery_frame;
-
QuicStopWaitingFrame* stop_waiting_frame;
-
- QuicPingFrame* ping_frame;
QuicRstStreamFrame* rst_stream_frame;
QuicConnectionCloseFrame* connection_close_frame;
QuicGoAwayFrame* goaway_frame;
@@ -1027,6 +1033,9 @@ struct NET_EXPORT_PRIVATE QuicFrame {
QuicBlockedFrame* blocked_frame;
};
};
+// QuicFrameType consumes 8 bytes with padding.
+static_assert(sizeof(QuicFrame) <= 16,
+ "Frames larger than 8 bytes should be referenced by pointer.");
typedef std::vector<QuicFrame> QuicFrames;
@@ -1180,25 +1189,25 @@ struct NET_EXPORT_PRIVATE TransmissionInfo {
QuicPacketNumberLength packet_number_length,
TransmissionType transmission_type,
QuicTime sent_time,
- QuicByteCount bytes_sent,
+ QuicPacketLength bytes_sent,
bool is_fec_packet);
RetransmittableFrames* retransmittable_frames;
QuicPacketNumberLength packet_number_length;
+ QuicPacketLength bytes_sent;
+ uint16 nack_count;
QuicTime sent_time;
- QuicByteCount bytes_sent;
- QuicPacketCount nack_count;
// Reason why this packet was transmitted.
TransmissionType transmission_type;
- // Stores the packet numbers of all transmissions of this packet.
- // Must always be nullptr or have multiple elements.
- PacketNumberList* all_transmissions;
// In flight packets have not been abandoned or lost.
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;
+ // Stores the packet numbers of all transmissions of this packet.
+ // Must always be nullptr or have multiple elements.
+ PacketNumberList* all_transmissions;
};
// Convenience wrapper to wrap an iovec array and the total length, which must
diff --git a/net/quic/quic_protocol_test.cc b/net/quic/quic_protocol_test.cc
index c74d3d1..fcadbe9 100644
--- a/net/quic/quic_protocol_test.cc
+++ b/net/quic/quic_protocol_test.cc
@@ -14,7 +14,7 @@ namespace test {
namespace {
TEST(QuicProtocolTest, AdjustErrorForVersion) {
- ASSERT_EQ(8, QUIC_STREAM_LAST_ERROR)
+ ASSERT_EQ(9, QUIC_STREAM_LAST_ERROR)
<< "Any additions to QuicRstStreamErrorCode require an addition to "
<< "AdjustErrorForVersion and this associated test.";
diff --git a/net/quic/quic_session.cc b/net/quic/quic_session.cc
index 7875bb8..12d1903 100644
--- a/net/quic/quic_session.cc
+++ b/net/quic/quic_session.cc
@@ -679,7 +679,12 @@ ReliableQuicStream* QuicSession::GetIncomingDynamicStream(
// Check if the new number of open streams would cause the number of
// open streams to exceed the limit.
if (GetNumOpenStreams() >= get_max_open_streams()) {
- CloseConnection(QUIC_TOO_MANY_OPEN_STREAMS);
+ if (connection()->version() <= QUIC_VERSION_27) {
+ CloseConnection(QUIC_TOO_MANY_OPEN_STREAMS);
+ } else {
+ // Refuse to open the stream.
+ SendRstStream(stream_id, QUIC_REFUSED_STREAM, 0);
+ }
return nullptr;
}
}
diff --git a/net/quic/quic_unacked_packet_map.cc b/net/quic/quic_unacked_packet_map.cc
index 71088ae..bbe7b3f 100644
--- a/net/quic/quic_unacked_packet_map.cc
+++ b/net/quic/quic_unacked_packet_map.cc
@@ -185,7 +185,7 @@ bool QuicUnackedPacketMap::HasRetransmittableFrames(
}
void QuicUnackedPacketMap::NackPacket(QuicPacketNumber packet_number,
- QuicPacketCount min_nacks) {
+ uint16 min_nacks) {
DCHECK_GE(packet_number, least_unacked_);
DCHECK_LT(packet_number, least_unacked_ + unacked_packets_.size());
unacked_packets_[packet_number - least_unacked_].nack_count = max(
diff --git a/net/quic/quic_unacked_packet_map.h b/net/quic/quic_unacked_packet_map.h
index 1926d31..358491d 100644
--- a/net/quic/quic_unacked_packet_map.h
+++ b/net/quic/quic_unacked_packet_map.h
@@ -42,7 +42,7 @@ class NET_EXPORT_PRIVATE QuicUnackedPacketMap {
bool IsUnacked(QuicPacketNumber packet_number) const;
// Sets the nack count to the max of the current nack count and |min_nacks|.
- void NackPacket(QuicPacketNumber packet_number, QuicPacketCount min_nacks);
+ void NackPacket(QuicPacketNumber packet_number, uint16 min_nacks);
// Marks |packet_number| as no longer in flight.
void RemoveFromInFlight(QuicPacketNumber packet_number);
diff --git a/net/quic/quic_utils.cc b/net/quic/quic_utils.cc
index 641818e..b336202 100644
--- a/net/quic/quic_utils.cc
+++ b/net/quic/quic_utils.cc
@@ -146,6 +146,7 @@ const char* QuicUtils::StreamErrorToString(QuicRstStreamErrorCode error) {
RETURN_STRING_LITERAL(QUIC_STREAM_PEER_GOING_AWAY);
RETURN_STRING_LITERAL(QUIC_STREAM_CANCELLED);
RETURN_STRING_LITERAL(QUIC_RST_ACKNOWLEDGEMENT);
+ RETURN_STRING_LITERAL(QUIC_REFUSED_STREAM);
RETURN_STRING_LITERAL(QUIC_STREAM_LAST_ERROR);
}
// Return a default value so that we return this when |error| doesn't match
diff --git a/net/quic/test_tools/crypto_test_utils_chromium.cc b/net/quic/test_tools/crypto_test_utils_chromium.cc
index 366dd5e..ffa1788 100644
--- a/net/quic/test_tools/crypto_test_utils_chromium.cc
+++ b/net/quic/test_tools/crypto_test_utils_chromium.cc
@@ -116,7 +116,7 @@ ProofSource* CryptoTestUtils::ProofSourceForTesting() {
ProofSourceChromium* source = new ProofSourceChromium();
base::FilePath certs_dir = GetTestCertsDirectory();
CHECK(source->Initialize(
- certs_dir.AppendASCII("quic_chain.crt"),
+ certs_dir.AppendASCII("quic_test.example.com.crt"),
certs_dir.AppendASCII("quic_test.example.com.key.pkcs8")));
return source;
}
diff --git a/net/tools/quic/end_to_end_test.cc b/net/tools/quic/end_to_end_test.cc
index 9f4ccaa..dd13bcb 100644
--- a/net/tools/quic/end_to_end_test.cc
+++ b/net/tools/quic/end_to_end_test.cc
@@ -1100,9 +1100,15 @@ TEST_P(EndToEndTest, NegotiateMaxOpenStreams) {
}
client_->WaitForResponse();
- EXPECT_FALSE(client_->connected());
- EXPECT_EQ(QUIC_STREAM_CONNECTION_ERROR, client_->stream_error());
- EXPECT_EQ(QUIC_TOO_MANY_OPEN_STREAMS, client_->connection_error());
+ if (negotiated_version_ <= QUIC_VERSION_27) {
+ EXPECT_FALSE(client_->connected());
+ EXPECT_EQ(QUIC_STREAM_CONNECTION_ERROR, client_->stream_error());
+ EXPECT_EQ(QUIC_TOO_MANY_OPEN_STREAMS, client_->connection_error());
+ } else {
+ EXPECT_TRUE(client_->connected());
+ EXPECT_EQ(QUIC_REFUSED_STREAM, client_->stream_error());
+ EXPECT_EQ(QUIC_NO_ERROR, client_->connection_error());
+ }
}
TEST_P(EndToEndTest, NegotiateCongestionControl) {
diff --git a/net/tools/quic/quic_dispatcher.cc b/net/tools/quic/quic_dispatcher.cc
index 0a103ac..31cc8e3 100644
--- a/net/tools/quic/quic_dispatcher.cc
+++ b/net/tools/quic/quic_dispatcher.cc
@@ -487,7 +487,7 @@ QuicTimeWaitListManager* QuicDispatcher::CreateQuicTimeWaitListManager() {
time_wait_list_writer_.reset(
packet_writer_factory_->Create(writer_.get(), nullptr));
return new QuicTimeWaitListManager(time_wait_list_writer_.get(), this,
- helper_.get(), supported_versions());
+ helper_.get());
}
bool QuicDispatcher::HandlePacketForTimeWait(
diff --git a/net/tools/quic/quic_packet_reader.cc b/net/tools/quic/quic_packet_reader.cc
index 1982269..1f368a6 100644
--- a/net/tools/quic/quic_packet_reader.cc
+++ b/net/tools/quic/quic_packet_reader.cc
@@ -14,6 +14,7 @@
#include "base/logging.h"
#include "net/base/ip_endpoint.h"
+#include "net/quic/quic_flags.h"
#include "net/tools/quic/quic_dispatcher.h"
#include "net/tools/quic/quic_socket_utils.h"
@@ -103,7 +104,12 @@ bool QuicPacketReader::ReadAndDispatchPackets(
packets_dropped);
}
- return true;
+ if (FLAGS_quic_read_packets_full_recvmmsg) {
+ // We may not have read all of the packets available on the socket.
+ return packets_read == kNumPacketsPerReadMmsgCall;
+ } else {
+ return true;
+ }
#else
LOG(FATAL) << "Unsupported";
return false;
diff --git a/net/tools/quic/quic_packet_reader.h b/net/tools/quic/quic_packet_reader.h
index 479fc6d..e667d59 100644
--- a/net/tools/quic/quic_packet_reader.h
+++ b/net/tools/quic/quic_packet_reader.h
@@ -37,8 +37,8 @@ class QuicPacketReader {
virtual ~QuicPacketReader();
// Reads a number of packets from the given fd, and then passes them off to
- // the PacketProcessInterface. Returns true if at least 1 packet is read,
- // false otherwise.
+ // the PacketProcessInterface. Returns true if there may be additional
+ // packets available on the socket.
// Populates |packets_dropped| if it is non-null and the socket is configured
// to track dropped packets and some packets are read.
virtual bool ReadAndDispatchPackets(int fd,
diff --git a/net/tools/quic/quic_server.cc b/net/tools/quic/quic_server.cc
index 392963d..e0cd873 100644
--- a/net/tools/quic/quic_server.cc
+++ b/net/tools/quic/quic_server.cc
@@ -47,17 +47,7 @@ const char kSourceAddressTokenSecret[] = "secret";
} // namespace
-QuicServer::QuicServer()
- : port_(0),
- fd_(-1),
- packets_dropped_(0),
- overflow_supported_(false),
- use_recvmmsg_(false),
- crypto_config_(kSourceAddressTokenSecret, QuicRandom::GetInstance()),
- supported_versions_(QuicSupportedVersions()),
- packet_reader_(new QuicPacketReader()) {
- Initialize();
-}
+QuicServer::QuicServer() : QuicServer(QuicConfig(), QuicSupportedVersions()) {}
QuicServer::QuicServer(const QuicConfig& config,
const QuicVersionVector& supported_versions)
@@ -215,14 +205,14 @@ void QuicServer::OnEvent(int fd, EpollEvent* event) {
if (event->in_events & EPOLLIN) {
DVLOG(1) << "EPOLLIN";
- bool read = true;
- while (read) {
+ bool more_to_read = true;
+ while (more_to_read) {
if (use_recvmmsg_) {
- read = packet_reader_->ReadAndDispatchPackets(
+ more_to_read = packet_reader_->ReadAndDispatchPackets(
fd_, port_, dispatcher_.get(),
overflow_supported_ ? &packets_dropped_ : nullptr);
} else {
- read = QuicPacketReader::ReadAndDispatchSinglePacket(
+ more_to_read = QuicPacketReader::ReadAndDispatchSinglePacket(
fd_, port_, dispatcher_.get(),
overflow_supported_ ? &packets_dropped_ : nullptr);
}
diff --git a/net/tools/quic/quic_server_session_test.cc b/net/tools/quic/quic_server_session_test.cc
index 7123496..d24b837 100644
--- a/net/tools/quic/quic_server_session_test.cc
+++ b/net/tools/quic/quic_server_session_test.cc
@@ -189,9 +189,9 @@ TEST_P(QuicServerSessionTest, AcceptClosedStream) {
}
TEST_P(QuicServerSessionTest, MaxOpenStreams) {
- // Test that the server closes the connection if a client attempts to open too
- // many data streams. The server accepts slightly more than the negotiated
- // stream limit to deal with rare cases where a client FIN/RST is lost.
+ // Test that the server refuses if a client attempts to open too many data
+ // streams. The server accepts slightly more than the negotiated stream limit
+ // to deal with rare cases where a client FIN/RST is lost.
// The slightly increased stream limit is set during config negotiation. It
// is either an increase of 10 over negotiated limit, or a fixed percentage
@@ -220,8 +220,14 @@ TEST_P(QuicServerSessionTest, MaxOpenStreams) {
// Now violate the server's internal stream limit.
stream_id += 2;
- EXPECT_CALL(*connection_, SendConnectionClose(QUIC_TOO_MANY_OPEN_STREAMS));
- EXPECT_CALL(*connection_, SendRstStream(_, _, _)).Times(0);
+ if (connection_->version() <= QUIC_VERSION_27) {
+ EXPECT_CALL(*connection_, SendConnectionClose(QUIC_TOO_MANY_OPEN_STREAMS));
+ EXPECT_CALL(*connection_, SendRstStream(_, _, _)).Times(0);
+ } else {
+ EXPECT_CALL(*connection_, SendConnectionClose(_)).Times(0);
+ EXPECT_CALL(*connection_, SendRstStream(stream_id, QUIC_REFUSED_STREAM, 0));
+ }
+ // Even if the connection remains open, the stream creation should fail.
EXPECT_FALSE(QuicServerSessionPeer::GetIncomingDynamicStream(session_.get(),
stream_id));
}
diff --git a/net/tools/quic/quic_time_wait_list_manager.cc b/net/tools/quic/quic_time_wait_list_manager.cc
index 68d1b9e..1e433e5 100644
--- a/net/tools/quic/quic_time_wait_list_manager.cc
+++ b/net/tools/quic/quic_time_wait_list_manager.cc
@@ -80,8 +80,7 @@ class QuicTimeWaitListManager::QueuedPacket {
QuicTimeWaitListManager::QuicTimeWaitListManager(
QuicPacketWriter* writer,
QuicServerSessionVisitor* visitor,
- QuicConnectionHelperInterface* helper,
- const QuicVersionVector& supported_versions)
+ QuicConnectionHelperInterface* helper)
: time_wait_period_(
QuicTime::Delta::FromSeconds(FLAGS_quic_time_wait_list_seconds)),
connection_id_clean_up_alarm_(
diff --git a/net/tools/quic/quic_time_wait_list_manager.h b/net/tools/quic/quic_time_wait_list_manager.h
index 9a9eccd..092f116 100644
--- a/net/tools/quic/quic_time_wait_list_manager.h
+++ b/net/tools/quic/quic_time_wait_list_manager.h
@@ -44,8 +44,7 @@ class QuicTimeWaitListManager : public QuicBlockedWriterInterface {
// helper - used to run clean up alarms. (Owned by the dispatcher)
QuicTimeWaitListManager(QuicPacketWriter* writer,
QuicServerSessionVisitor* visitor,
- QuicConnectionHelperInterface* helper,
- const QuicVersionVector& supported_versions);
+ QuicConnectionHelperInterface* helper);
~QuicTimeWaitListManager() override;
// Adds the given connection_id to time wait state for time_wait_period_.
diff --git a/net/tools/quic/quic_time_wait_list_manager_test.cc b/net/tools/quic/quic_time_wait_list_manager_test.cc
index e6baf7d..8f5fd89 100644
--- a/net/tools/quic/quic_time_wait_list_manager_test.cc
+++ b/net/tools/quic/quic_time_wait_list_manager_test.cc
@@ -96,10 +96,7 @@ class QuicTimeWaitListManagerTest : public ::testing::Test {
protected:
QuicTimeWaitListManagerTest()
: helper_(&epoll_server_),
- time_wait_list_manager_(&writer_,
- &visitor_,
- &helper_,
- QuicSupportedVersions()),
+ time_wait_list_manager_(&writer_, &visitor_, &helper_),
framer_(QuicSupportedVersions(),
QuicTime::Zero(),
Perspective::IS_SERVER),
diff --git a/net/tools/quic/test_tools/mock_quic_time_wait_list_manager.cc b/net/tools/quic/test_tools/mock_quic_time_wait_list_manager.cc
index 7801db5..8e972f3 100644
--- a/net/tools/quic/test_tools/mock_quic_time_wait_list_manager.cc
+++ b/net/tools/quic/test_tools/mock_quic_time_wait_list_manager.cc
@@ -16,10 +16,7 @@ MockTimeWaitListManager::MockTimeWaitListManager(
QuicPacketWriter* writer,
QuicServerSessionVisitor* visitor,
QuicConnectionHelperInterface* helper)
- : QuicTimeWaitListManager(writer,
- visitor,
- helper,
- QuicSupportedVersions()) {
+ : QuicTimeWaitListManager(writer, visitor, helper) {
// Though AddConnectionIdToTimeWait is mocked, we want to retain its
// functionality.
EXPECT_CALL(*this, AddConnectionIdToTimeWait(_, _, _, _))
diff --git a/net/tools/quic/test_tools/quic_test_client.cc b/net/tools/quic/test_tools/quic_test_client.cc
index 718f0cf..708b4f8 100644
--- a/net/tools/quic/test_tools/quic_test_client.cc
+++ b/net/tools/quic/test_tools/quic_test_client.cc
@@ -109,12 +109,11 @@ MockableQuicClient::MockableQuicClient(
const QuicServerId& server_id,
const QuicVersionVector& supported_versions,
EpollServer* epoll_server)
- : QuicClient(server_address,
- server_id,
- supported_versions,
- epoll_server),
- override_connection_id_(0),
- test_writer_(nullptr) {}
+ : MockableQuicClient(server_address,
+ server_id,
+ QuicConfig(),
+ supported_versions,
+ epoll_server) {}
MockableQuicClient::MockableQuicClient(
IPEndPoint server_address,
@@ -164,36 +163,29 @@ QuicTestClient::QuicTestClient(IPEndPoint server_address,
const string& server_hostname,
bool secure,
const QuicVersionVector& supported_versions)
+ : QuicTestClient(server_address,
+ server_hostname,
+ secure,
+ QuicConfig(),
+ supported_versions) {}
+
+QuicTestClient::QuicTestClient(IPEndPoint server_address,
+ const string& server_hostname,
+ bool secure,
+ const QuicConfig& config,
+ const QuicVersionVector& supported_versions)
: client_(new MockableQuicClient(server_address,
QuicServerId(server_hostname,
server_address.port(),
secure,
PRIVACY_MODE_DISABLED),
+ config,
supported_versions,
&epoll_server_)) {
Initialize(secure);
}
-QuicTestClient::QuicTestClient(
- IPEndPoint server_address,
- const string& server_hostname,
- bool secure,
- const QuicConfig& config,
- const QuicVersionVector& supported_versions)
- : client_(
- new MockableQuicClient(server_address,
- QuicServerId(server_hostname,
- server_address.port(),
- secure,
- PRIVACY_MODE_DISABLED),
- config,
- supported_versions,
- &epoll_server_)) {
- Initialize(secure);
-}
-
-QuicTestClient::QuicTestClient() {
-}
+QuicTestClient::QuicTestClient() {}
QuicTestClient::~QuicTestClient() {
if (stream_) {