summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/quic/crypto/aes_128_gcm_12_encrypter.h3
-rw-r--r--net/quic/crypto/aes_128_gcm_12_encrypter_nss.cc8
-rw-r--r--net/quic/crypto/aes_128_gcm_12_encrypter_openssl.cc3
-rw-r--r--net/quic/crypto/aes_128_gcm_12_encrypter_test.cc5
-rw-r--r--net/quic/crypto/crypto_handshake_test.cc5
-rw-r--r--net/quic/quic_client_session_test.cc20
-rw-r--r--net/quic/quic_connection.cc52
-rw-r--r--net/quic/quic_connection.h3
-rw-r--r--net/quic/quic_connection_stats.cc22
-rw-r--r--net/quic/quic_connection_stats.h19
-rw-r--r--net/quic/quic_connection_test.cc75
-rw-r--r--net/quic/quic_crypto_client_stream_test.cc30
-rw-r--r--net/quic/quic_crypto_server_stream_test.cc35
-rw-r--r--net/quic/quic_framer.cc267
-rw-r--r--net/quic/quic_framer_test.cc120
-rw-r--r--net/quic/quic_http_stream_test.cc4
-rw-r--r--net/quic/quic_network_transaction_unittest.cc7
-rw-r--r--net/quic/quic_protocol.cc3
-rw-r--r--net/quic/quic_protocol.h7
-rw-r--r--net/quic/quic_protocol_test.cc4
-rw-r--r--net/tools/quic/end_to_end_test.cc36
-rw-r--r--net/tools/quic/quic_client.cc7
-rw-r--r--net/tools/quic/quic_client.h1
-rw-r--r--net/tools/quic/quic_client_session_test.cc13
-rw-r--r--net/tools/quic/quic_dispatcher.cc8
-rw-r--r--net/tools/quic/quic_dispatcher.h6
-rw-r--r--net/tools/quic/quic_dispatcher_test.cc18
-rw-r--r--net/tools/quic/test_tools/packet_dropping_test_writer.cc83
-rw-r--r--net/tools/quic/test_tools/packet_dropping_test_writer.h48
-rw-r--r--net/tools/quic/test_tools/quic_test_client.cc29
-rw-r--r--net/tools/quic/test_tools/quic_test_client.h14
31 files changed, 422 insertions, 533 deletions
diff --git a/net/quic/crypto/aes_128_gcm_12_encrypter.h b/net/quic/crypto/aes_128_gcm_12_encrypter.h
index abea8ac2..a2d1dc9 100644
--- a/net/quic/crypto/aes_128_gcm_12_encrypter.h
+++ b/net/quic/crypto/aes_128_gcm_12_encrypter.h
@@ -36,9 +36,6 @@ class NET_EXPORT_PRIVATE Aes128Gcm12Encrypter : public QuicEncrypter {
Aes128Gcm12Encrypter();
virtual ~Aes128Gcm12Encrypter();
- // Returns true if the underlying crypto library supports AES GCM.
- static bool IsSupported();
-
// QuicEncrypter implementation
virtual bool SetKey(base::StringPiece key) OVERRIDE;
virtual bool SetNoncePrefix(base::StringPiece nonce_prefix) OVERRIDE;
diff --git a/net/quic/crypto/aes_128_gcm_12_encrypter_nss.cc b/net/quic/crypto/aes_128_gcm_12_encrypter_nss.cc
index ae6adab..e100edee 100644
--- a/net/quic/crypto/aes_128_gcm_12_encrypter_nss.cc
+++ b/net/quic/crypto/aes_128_gcm_12_encrypter_nss.cc
@@ -256,14 +256,6 @@ Aes128Gcm12Encrypter::Aes128Gcm12Encrypter() {
Aes128Gcm12Encrypter::~Aes128Gcm12Encrypter() {}
-// static
-bool Aes128Gcm12Encrypter::IsSupported() {
- // NSS 3.15 supports CKM_AES_GCM directly.
- // NSS 3.14 supports CKM_AES_CTR, which can be used to emulate CKM_AES_GCM.
- // Versions earlier than NSS 3.14 are not supported.
- return NSS_VersionCheck("3.14") != PR_FALSE;
-}
-
bool Aes128Gcm12Encrypter::SetKey(StringPiece key) {
DCHECK_EQ(key.size(), sizeof(key_));
if (key.size() != sizeof(key_)) {
diff --git a/net/quic/crypto/aes_128_gcm_12_encrypter_openssl.cc b/net/quic/crypto/aes_128_gcm_12_encrypter_openssl.cc
index 166fd55..cc9bf35 100644
--- a/net/quic/crypto/aes_128_gcm_12_encrypter_openssl.cc
+++ b/net/quic/crypto/aes_128_gcm_12_encrypter_openssl.cc
@@ -25,9 +25,6 @@ Aes128Gcm12Encrypter::Aes128Gcm12Encrypter() {}
Aes128Gcm12Encrypter::~Aes128Gcm12Encrypter() {}
-// static
-bool Aes128Gcm12Encrypter::IsSupported() { return true; }
-
bool Aes128Gcm12Encrypter::SetKey(StringPiece key) {
DCHECK_EQ(key.size(), sizeof(key_));
if (key.size() != sizeof(key_)) {
diff --git a/net/quic/crypto/aes_128_gcm_12_encrypter_test.cc b/net/quic/crypto/aes_128_gcm_12_encrypter_test.cc
index 0c9928b..bb641d6 100644
--- a/net/quic/crypto/aes_128_gcm_12_encrypter_test.cc
+++ b/net/quic/crypto/aes_128_gcm_12_encrypter_test.cc
@@ -261,11 +261,6 @@ QuicData* EncryptWithNonce(Aes128Gcm12Encrypter* encrypter,
}
TEST(Aes128Gcm12EncrypterTest, Encrypt) {
- if (!Aes128Gcm12Encrypter::IsSupported()) {
- LOG(INFO) << "AES GCM not supported. Test skipped.";
- return;
- }
-
char key[1024];
size_t key_len;
char iv[1024];
diff --git a/net/quic/crypto/crypto_handshake_test.cc b/net/quic/crypto/crypto_handshake_test.cc
index 3ad50bb..dcde964 100644
--- a/net/quic/crypto/crypto_handshake_test.cc
+++ b/net/quic/crypto/crypto_handshake_test.cc
@@ -155,11 +155,6 @@ TEST(QuicCryptoServerConfigTest, ServerConfig) {
}
TEST(QuicCryptoServerConfigTest, SourceAddressTokens) {
- if (!Aes128Gcm12Encrypter::IsSupported()) {
- LOG(INFO) << "AES GCM not supported. Test skipped.";
- return;
- }
-
QuicRandom* rand = QuicRandom::GetInstance();
QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand);
IPAddressNumber ip;
diff --git a/net/quic/quic_client_session_test.cc b/net/quic/quic_client_session_test.cc
index 7874273..8298ff2 100644
--- a/net/quic/quic_client_session_test.cc
+++ b/net/quic/quic_client_session_test.cc
@@ -108,20 +108,10 @@ class QuicClientSessionTest : public ::testing::Test {
};
TEST_F(QuicClientSessionTest, CryptoConnect) {
- if (!Aes128Gcm12Encrypter::IsSupported()) {
- LOG(INFO) << "AES GCM not supported. Test skipped.";
- return;
- }
-
CompleteCryptoHandshake();
}
TEST_F(QuicClientSessionTest, MaxNumStreams) {
- if (!Aes128Gcm12Encrypter::IsSupported()) {
- LOG(INFO) << "AES GCM not supported. Test skipped.";
- return;
- }
-
CompleteCryptoHandshake();
std::vector<QuicReliableClientStream*> streams;
@@ -138,11 +128,6 @@ TEST_F(QuicClientSessionTest, MaxNumStreams) {
}
TEST_F(QuicClientSessionTest, MaxNumStreamsViaRequest) {
- if (!Aes128Gcm12Encrypter::IsSupported()) {
- LOG(INFO) << "AES GCM not supported. Test skipped.";
- return;
- }
-
CompleteCryptoHandshake();
std::vector<QuicReliableClientStream*> streams;
@@ -167,11 +152,6 @@ TEST_F(QuicClientSessionTest, MaxNumStreamsViaRequest) {
}
TEST_F(QuicClientSessionTest, GoAwayReceived) {
- if (!Aes128Gcm12Encrypter::IsSupported()) {
- LOG(INFO) << "AES GCM not supported. Test skipped.";
- return;
- }
-
CompleteCryptoHandshake();
// After receiving a GoAway, I should no longer be able to create outgoing
diff --git a/net/quic/quic_connection.cc b/net/quic/quic_connection.cc
index 914f8ae..28a7b0d 100644
--- a/net/quic/quic_connection.cc
+++ b/net/quic/quic_connection.cc
@@ -55,8 +55,7 @@ const QuicPacketSequenceNumber kMaxPacketGap = 5000;
// initial congestion window(RFC 6928).
const size_t kMaxRetransmissionsPerAck = 10;
-// TCP retransmits after 2 nacks. We allow for a third in case of out-of-order
-// delivery.
+// TCP retransmits after 3 nacks.
// TODO(ianswett): Change to match TCP's rule of retransmitting once an ack
// at least 3 sequence numbers larger arrives.
const size_t kNumberOfNacksBeforeRetransmission = 3;
@@ -189,14 +188,6 @@ net::IsHandshake HasCryptoHandshake(
} // namespace
-// TODO(rch): Remove this.
-// Because of a bug in the interaction between the TcpCubicSender and
-// QuicConnection, acks currently count against the congestion window.
-// This means that if acks are not acked, and data is only flowing in
-// one direction, then the connection will deadlock.
-// static
-bool QuicConnection::g_acks_do_not_instigate_acks = true;
-
#define ENDPOINT (is_server_ ? "Server: " : " Client: ")
QuicConnection::QuicConnection(QuicGuid guid,
@@ -241,7 +232,6 @@ QuicConnection::QuicConnection(QuicGuid guid,
is_server_(is_server),
connected_(true),
received_truncated_ack_(false),
- send_ack_in_response_to_packet_(false),
address_migrating_(false) {
timeout_alarm_->Set(clock_->ApproximateNow().Add(idle_network_timeout_));
framer_.set_visitor(this);
@@ -718,10 +708,15 @@ void QuicConnection::OnPacketComplete() {
bool send_ack_immediately =
received_packet_manager_.GetNumMissingPackets() != 0;
+ // Ensure the visitor can process the stream frames before recording and
+ // processing the rest of the packet.
if (last_stream_frames_.empty() ||
visitor_->OnStreamFrames(last_stream_frames_)) {
received_packet_manager_.RecordPacketReceived(
last_header_, time_of_last_received_packet_);
+ for (size_t i = 0; i < last_stream_frames_.size(); ++i) {
+ stats_.stream_bytes_received += last_stream_frames_[i].data.length();
+ }
}
// Process stream resets, then acks, then congestion feedback.
@@ -794,26 +789,17 @@ void QuicConnection::MaybeSendInResponseToPacket(
// |include_ack| is false since we decide about ack bundling below.
ScopedPacketBundler bundler(this, false);
- if (send_ack_immediately) {
- send_ack_in_response_to_packet_ = true;
- }
-
- // TODO(rch): remove last_packet_should_instigate_ack when we remove
- // g_acks_do_not_instigate_acks.
- if (last_packet_should_instigate_ack ||
- !g_acks_do_not_instigate_acks) {
- if (send_ack_in_response_to_packet_) {
+ if (last_packet_should_instigate_ack) {
+ // In general, we ack every second packet. When we don't ack the first
+ // packet, we set the delayed ack alarm. Thus, if the ack alarm is set
+ // then we know this is the second packet, and we should send an ack.
+ if (send_ack_immediately || ack_alarm_->IsSet()) {
SendAck();
- DCHECK(!send_ack_in_response_to_packet_);
+ DCHECK(!ack_alarm_->IsSet());
} else {
- send_ack_in_response_to_packet_ = true;
- DVLOG(1) << "Next received packet will trigger ACK.";
- if (last_packet_should_instigate_ack && !ack_alarm_->IsSet()) {
- // Set the ack alarm for when any retransmittable frame is received.
- ack_alarm_->Set(clock_->ApproximateNow().Add(
- congestion_manager_.DelayedAckTime()));
- DVLOG(1) << "Ack timer set; next packet or timer will trigger ACK.";
- }
+ ack_alarm_->Set(clock_->ApproximateNow().Add(
+ congestion_manager_.DelayedAckTime()));
+ DVLOG(1) << "Ack timer set; next packet or timer will trigger ACK.";
}
}
@@ -907,6 +893,7 @@ QuicConsumedData QuicConnection::SendvStreamDataInner(
fin_consumed = consumed_data.fin_consumed;
}
+ stats_.stream_bytes_sent += bytes_written;
return QuicConsumedData(bytes_written, fin_consumed);
}
@@ -1237,8 +1224,6 @@ void QuicConnection::SetupRetransmission(
sent_packet_manager_.GetNumUnackedPackets(), consecutive_rto_count_);
retransmission_alarm_->Set(
clock_->ApproximateNow().Add(retransmission_delay));
- // TODO(satyamshekhar): restore packet reordering with Ian's TODO in
- // SendStreamData().
}
void QuicConnection::SetupAbandonFecTimer(
@@ -1525,7 +1510,6 @@ void QuicConnection::UpdateSentPacketInfo(SentPacketInfo* sent_info) {
void QuicConnection::SendAck() {
ack_alarm_->Cancel();
- send_ack_in_response_to_packet_ = false;
// TODO(rch): delay this until the CreateFeedbackFrame
// method is invoked. This requires changes SetShouldSendAck
// to be a no-arg method, and re-jiggering its implementation.
@@ -1555,6 +1539,8 @@ void QuicConnection::OnRetransmissionTimeout() {
// packets will be queued for future sending.
SequenceNumberSet unacked_packets =
sent_packet_manager_.GetUnackedPackets();
+ DLOG(INFO) << "OnRetransmissionTimeout() fired with "
+ << unacked_packets.size() << " unacked packets.";
// Abandon all unacked packets to ensure the congestion window
// opens up before we attempt to retransmit the packet.
@@ -1882,9 +1868,7 @@ QuicConnection::ScopedPacketBundler::ScopedPacketBundler(
if (FLAGS_bundle_ack_with_outgoing_packet &&
include_ack && connection_->ack_alarm_->IsSet()) {
DVLOG(1) << "Bundling ack with outgoing packet.";
- DCHECK(connection_->send_ack_in_response_to_packet_);
connection_->SendAck();
- DCHECK(!connection_->send_ack_in_response_to_packet_);
}
}
diff --git a/net/quic/quic_connection.h b/net/quic/quic_connection.h
index 92f9f88..583962c 100644
--- a/net/quic/quic_connection.h
+++ b/net/quic/quic_connection.h
@@ -401,8 +401,6 @@ class NET_EXPORT_PRIVATE QuicConnection
bool is_server() const { return is_server_; }
- static bool g_acks_do_not_instigate_acks;
-
protected:
// Send a packet to the peer using encryption |level|. If |sequence_number|
// is present in the |retransmission_map_|, then contents of this packet will
@@ -772,7 +770,6 @@ class NET_EXPORT_PRIVATE QuicConnection
// True if the last ack received from the peer may have been truncated. False
// otherwise.
bool received_truncated_ack_;
- bool send_ack_in_response_to_packet_;
// Set to true if the udp packet headers have a new self or peer address.
// This is checked later on validating a data or version negotiation packet.
diff --git a/net/quic/quic_connection_stats.cc b/net/quic/quic_connection_stats.cc
index f66a5cb..500b5f3 100644
--- a/net/quic/quic_connection_stats.cc
+++ b/net/quic/quic_connection_stats.cc
@@ -4,13 +4,17 @@
#include "net/quic/quic_connection_stats.h"
+using std::ostream;
+
namespace net {
QuicConnectionStats::QuicConnectionStats()
: bytes_sent(0),
packets_sent(0),
+ stream_bytes_sent(0),
bytes_received(0),
packets_received(0),
+ stream_bytes_received(0),
bytes_retransmitted(0),
packets_retransmitted(0),
packets_revived(0),
@@ -22,4 +26,22 @@ QuicConnectionStats::QuicConnectionStats()
QuicConnectionStats::~QuicConnectionStats() {}
+ostream& operator<<(ostream& os, const QuicConnectionStats& s) {
+ os << "{ bytes sent: " << s.bytes_sent
+ << ", packets sent:" << s.packets_sent
+ << ", stream bytes sent: " << s.stream_bytes_sent
+ << ", bytes received: " << s.bytes_received
+ << ", packets received: " << s.packets_received
+ << ", stream bytes received: " << s.stream_bytes_received
+ << ", bytes retransmitted: " << s.bytes_retransmitted
+ << ", packets retransmitted: " << s.packets_retransmitted
+ << ", packets revived: " << s.packets_revived
+ << ", packets dropped:" << s.packets_dropped
+ << ", rto count: " << s.rto_count
+ << ", rtt(us): " << s.rtt
+ << ", estimated_bandwidth: " << s.estimated_bandwidth
+ << "}\n";
+ return os;
+}
+
} // namespace net
diff --git a/net/quic/quic_connection_stats.h b/net/quic/quic_connection_stats.h
index f933662..b0761d9 100644
--- a/net/quic/quic_connection_stats.h
+++ b/net/quic/quic_connection_stats.h
@@ -5,6 +5,8 @@
#ifndef NET_QUIC_QUIC_CONNECTION_STATS_H_
#define NET_QUIC_QUIC_CONNECTION_STATS_H_
+#include <ostream>
+
#include "base/basictypes.h"
#include "net/base/net_export.h"
@@ -15,23 +17,26 @@ namespace net {
// 3. CHLO sent to SHLO received time.
// 4. Number of migrations.
// 5. Number of out of order packets.
-// 6. Avg packet size.
-// 7. Number of connections that require more that 1-RTT.
-// 8. Avg number of streams / session.
-// 9. Number of duplicates received.
-// 10. Fraction of traffic sent/received that was not data (protocol overhead).
-// 11. Fraction of data transferred that was padding.
+// 6. Number of connections that require more that 1-RTT.
+// 7. Avg number of streams / session.
+// 8. Number of duplicates received.
+// 9. Fraction of data transferred that was padding.
// Structure to hold stats for a QuicConnection.
struct NET_EXPORT_PRIVATE QuicConnectionStats {
QuicConnectionStats();
~QuicConnectionStats();
+ NET_EXPORT_PRIVATE friend std::ostream& operator<<(
+ std::ostream& os, const QuicConnectionStats& s);
+
uint64 bytes_sent; // includes retransmissions, fec.
uint32 packets_sent;
+ uint64 stream_bytes_sent; // non-retransmitted bytes sent in a stream frame.
uint64 bytes_received; // includes duplicate data for a stream, fec.
uint32 packets_received; // includes dropped packets
+ uint64 stream_bytes_received; // bytes received in a stream frame.
uint64 bytes_retransmitted;
uint32 packets_retransmitted;
@@ -40,7 +45,7 @@ struct NET_EXPORT_PRIVATE QuicConnectionStats {
uint32 packets_dropped; // duplicate or less than least unacked.
uint32 rto_count;
- uint32 rtt;
+ uint32 rtt; // In microseconds
uint64 estimated_bandwidth;
// TODO(satyamshekhar): Add window_size, mss and mtu.
};
diff --git a/net/quic/quic_connection_test.cc b/net/quic/quic_connection_test.cc
index 37a8e9b..c5e33e2 100644
--- a/net/quic/quic_connection_test.cc
+++ b/net/quic/quic_connection_test.cc
@@ -526,7 +526,6 @@ class QuicConnectionTest : public ::testing::TestWithParam<bool> {
frame2_(1, false, 3, data2),
accept_packet_(true) {
// TODO(rtenneti): remove g_* flags.
- QuicConnection::g_acks_do_not_instigate_acks = true;
FLAGS_track_retransmission_history = true;
connection_.set_visitor(&visitor_);
connection_.SetSendAlgorithm(send_algorithm_);
@@ -552,11 +551,6 @@ class QuicConnectionTest : public ::testing::TestWithParam<bool> {
Return(true));
}
- ~QuicConnectionTest() {
- // TODO(rch): remove this.
- QuicConnection::g_acks_do_not_instigate_acks = false;
- }
-
void SetUp() {
FLAGS_bundle_ack_with_outgoing_packet = GetParam();
}
@@ -701,8 +695,10 @@ class QuicConnectionTest : public ::testing::TestWithParam<bool> {
return encrypted->length();
}
- QuicByteCount SendStreamDataToPeer(QuicStreamId id, StringPiece data,
- QuicStreamOffset offset, bool fin,
+ QuicByteCount SendStreamDataToPeer(QuicStreamId id,
+ StringPiece data,
+ QuicStreamOffset offset,
+ bool fin,
QuicPacketSequenceNumber* last_packet) {
QuicByteCount packet_size;
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
@@ -1488,6 +1484,45 @@ TEST_P(QuicConnectionTest, FramePackingFEC) {
EXPECT_EQ(0u, writer_->frame_count());
}
+TEST_P(QuicConnectionTest, FramePackingAckResponse) {
+ if (!GetParam()) {
+ // This test depends on BundleAckWithPacket being true.
+ return;
+ }
+ EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+ // Process a data packet to queue up a pending ack.
+ EXPECT_CALL(visitor_, OnStreamFrames(_)).WillOnce(Return(true));
+ ProcessDataPacket(1, 1, kEntropyFlag);
+
+ EXPECT_CALL(visitor_, OnCanWrite()).WillOnce(DoAll(
+ IgnoreResult(InvokeWithoutArgs(&connection_,
+ &TestConnection::SendStreamData3)),
+ IgnoreResult(InvokeWithoutArgs(&connection_,
+ &TestConnection::SendStreamData5)),
+ Return(true)));
+
+ EXPECT_CALL(*send_algorithm_,
+ OnPacketSent(_, _, _, NOT_RETRANSMISSION, _))
+ .Times(1);
+
+ // Process an ack to cause the visitor's OnCanWrite to be invoked.
+ creator_.set_sequence_number(2);
+ QuicAckFrame ack_one(0, QuicTime::Zero(), 0);
+ ProcessAckPacket(&ack_one);
+
+ EXPECT_EQ(0u, connection_.NumQueuedPackets());
+ EXPECT_FALSE(connection_.HasQueuedData());
+
+ // Parse the last packet and ensure it's an ack and two stream frames from
+ // two different streams.
+ EXPECT_EQ(3u, writer_->frame_count());
+ EXPECT_TRUE(writer_->ack());
+ ASSERT_EQ(2u, writer_->stream_frames()->size());
+ EXPECT_EQ(kStreamId3, (*writer_->stream_frames())[0].stream_id);
+ EXPECT_EQ(kStreamId5, (*writer_->stream_frames())[1].stream_id);
+}
+
TEST_P(QuicConnectionTest, FramePackingSendv) {
// Send two stream frames in 1 packet by using writev.
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, NOT_RETRANSMISSION, _));
@@ -1724,18 +1759,6 @@ TEST_P(QuicConnectionTest, QueueAfterTwoRTOs) {
connection_.OnCanWrite();
}
-TEST_P(QuicConnectionTest, ResumptionAlarmThenWriteBlocked) {
- // Set the send and resumption alarm, then block the connection.
- connection_.GetResumeWritesAlarm()->Set(clock_.ApproximateNow());
- connection_.GetSendAlarm()->Set(clock_.ApproximateNow());
- QuicConnectionPeer::SetIsWriteBlocked(&connection_, true);
-
- // Fire the alarms and ensure the connection is still write blocked.
- connection_.GetResumeWritesAlarm()->Fire();
- connection_.GetSendAlarm()->Fire();
- EXPECT_TRUE(QuicConnectionPeer::IsWriteBlocked(&connection_));
-}
-
TEST_P(QuicConnectionTest, WriteBlockedThenSent) {
writer_->set_blocked(true);
@@ -1748,6 +1771,18 @@ TEST_P(QuicConnectionTest, WriteBlockedThenSent) {
EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
}
+TEST_P(QuicConnectionTest, ResumptionAlarmThenWriteBlocked) {
+ // Set the send and resumption alarm, then block the connection.
+ connection_.GetResumeWritesAlarm()->Set(clock_.ApproximateNow());
+ connection_.GetSendAlarm()->Set(clock_.ApproximateNow());
+ QuicConnectionPeer::SetIsWriteBlocked(&connection_, true);
+
+ // Fire the alarms and ensure the connection is still write blocked.
+ connection_.GetResumeWritesAlarm()->Fire();
+ connection_.GetSendAlarm()->Fire();
+ EXPECT_TRUE(QuicConnectionPeer::IsWriteBlocked(&connection_));
+}
+
TEST_P(QuicConnectionTest, LimitPacketsPerNack) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
EXPECT_CALL(*send_algorithm_, OnIncomingAck(12, _, _)).Times(1);
diff --git a/net/quic/quic_crypto_client_stream_test.cc b/net/quic/quic_crypto_client_stream_test.cc
index 2ad9a3a2..e07ad46 100644
--- a/net/quic/quic_crypto_client_stream_test.cc
+++ b/net/quic/quic_crypto_client_stream_test.cc
@@ -53,32 +53,17 @@ class QuicCryptoClientStreamTest : public ::testing::Test {
};
TEST_F(QuicCryptoClientStreamTest, NotInitiallyConected) {
- if (!Aes128Gcm12Encrypter::IsSupported()) {
- LOG(INFO) << "AES GCM not supported. Test skipped.";
- return;
- }
-
EXPECT_FALSE(stream_->encryption_established());
EXPECT_FALSE(stream_->handshake_confirmed());
}
TEST_F(QuicCryptoClientStreamTest, ConnectedAfterSHLO) {
- if (!Aes128Gcm12Encrypter::IsSupported()) {
- LOG(INFO) << "AES GCM not supported. Test skipped.";
- return;
- }
-
CompleteCryptoHandshake();
EXPECT_TRUE(stream_->encryption_established());
EXPECT_TRUE(stream_->handshake_confirmed());
}
TEST_F(QuicCryptoClientStreamTest, MessageAfterHandshake) {
- if (!Aes128Gcm12Encrypter::IsSupported()) {
- LOG(INFO) << "AES GCM not supported. Test skipped.";
- return;
- }
-
CompleteCryptoHandshake();
EXPECT_CALL(*connection_, SendConnectionClose(
@@ -89,11 +74,6 @@ TEST_F(QuicCryptoClientStreamTest, MessageAfterHandshake) {
}
TEST_F(QuicCryptoClientStreamTest, BadMessageType) {
- if (!Aes128Gcm12Encrypter::IsSupported()) {
- LOG(INFO) << "AES GCM not supported. Test skipped.";
- return;
- }
-
EXPECT_TRUE(stream_->CryptoConnect());
message_.set_tag(kCHLO);
@@ -105,11 +85,6 @@ TEST_F(QuicCryptoClientStreamTest, BadMessageType) {
}
TEST_F(QuicCryptoClientStreamTest, NegotiatedParameters) {
- if (!Aes128Gcm12Encrypter::IsSupported()) {
- LOG(INFO) << "AES GCM not supported. Test skipped.";
- return;
- }
-
CompleteCryptoHandshake();
const QuicConfig* config = session_->config();
@@ -127,11 +102,6 @@ TEST_F(QuicCryptoClientStreamTest, NegotiatedParameters) {
}
TEST_F(QuicCryptoClientStreamTest, InvalidHostname) {
- if (!Aes128Gcm12Encrypter::IsSupported()) {
- LOG(INFO) << "AES GCM not supported. Test skipped.";
- return;
- }
-
stream_.reset(new QuicCryptoClientStream("invalid", session_.get(),
&crypto_config_));
session_->SetCryptoStream(stream_.get());
diff --git a/net/quic/quic_crypto_server_stream_test.cc b/net/quic/quic_crypto_server_stream_test.cc
index 9e92b2b..bfea221 100644
--- a/net/quic/quic_crypto_server_stream_test.cc
+++ b/net/quic/quic_crypto_server_stream_test.cc
@@ -86,21 +86,11 @@ class QuicCryptoServerStreamTest : public ::testing::Test {
};
TEST_F(QuicCryptoServerStreamTest, NotInitiallyConected) {
- if (!Aes128Gcm12Encrypter::IsSupported()) {
- LOG(INFO) << "AES GCM not supported. Test skipped.";
- return;
- }
-
EXPECT_FALSE(stream_.encryption_established());
EXPECT_FALSE(stream_.handshake_confirmed());
}
TEST_F(QuicCryptoServerStreamTest, ConnectedAfterCHLO) {
- if (!Aes128Gcm12Encrypter::IsSupported()) {
- LOG(INFO) << "AES GCM not supported. Test skipped.";
- return;
- }
-
// CompleteCryptoHandshake returns the number of client hellos sent. This
// test should send:
// * One to get a source-address token and certificates.
@@ -111,11 +101,6 @@ TEST_F(QuicCryptoServerStreamTest, ConnectedAfterCHLO) {
}
TEST_F(QuicCryptoServerStreamTest, ZeroRTT) {
- if (!Aes128Gcm12Encrypter::IsSupported()) {
- LOG(INFO) << "AES GCM not supported. Test skipped.";
- return;
- }
-
QuicGuid guid(1);
IPAddressNumber ip;
ParseIPLiteralToNumber("127.0.0.1", &ip);
@@ -184,11 +169,6 @@ TEST_F(QuicCryptoServerStreamTest, ZeroRTT) {
}
TEST_F(QuicCryptoServerStreamTest, MessageAfterHandshake) {
- if (!Aes128Gcm12Encrypter::IsSupported()) {
- LOG(INFO) << "AES GCM not supported. Test skipped.";
- return;
- }
-
CompleteCryptoHandshake();
EXPECT_CALL(*connection_, SendConnectionClose(
QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE));
@@ -198,11 +178,6 @@ TEST_F(QuicCryptoServerStreamTest, MessageAfterHandshake) {
}
TEST_F(QuicCryptoServerStreamTest, BadMessageType) {
- if (!Aes128Gcm12Encrypter::IsSupported()) {
- LOG(INFO) << "AES GCM not supported. Test skipped.";
- return;
- }
-
message_.set_tag(kSHLO);
ConstructHandshakeMessage();
EXPECT_CALL(*connection_, SendConnectionClose(
@@ -211,11 +186,6 @@ TEST_F(QuicCryptoServerStreamTest, BadMessageType) {
}
TEST_F(QuicCryptoServerStreamTest, WithoutCertificates) {
- if (!Aes128Gcm12Encrypter::IsSupported()) {
- LOG(INFO) << "AES GCM not supported. Test skipped.";
- return;
- }
-
crypto_config_.SetProofSource(NULL);
client_options_.dont_verify_certs = true;
@@ -227,11 +197,6 @@ TEST_F(QuicCryptoServerStreamTest, WithoutCertificates) {
}
TEST_F(QuicCryptoServerStreamTest, ChannelID) {
- if (!Aes128Gcm12Encrypter::IsSupported()) {
- LOG(INFO) << "AES GCM not supported. Test skipped.";
- return;
- }
-
client_options_.channel_id_enabled = true;
// TODO(rtenneti): Enable testing of ProofVerifier.
// CompleteCryptoHandshake verifies
diff --git a/net/quic/quic_framer.cc b/net/quic/quic_framer.cc
index 24bde81..02ca896 100644
--- a/net/quic/quic_framer.cc
+++ b/net/quic/quic_framer.cc
@@ -72,16 +72,6 @@ const uint8 kQuicFrameTypeStreamMask = 0x80;
const uint8 kQuicFrameTypeAckMask = 0x40;
const uint8 kQuicFrameTypeCongestionFeedbackMask = 0x20;
-// Mask to determine if it's a special frame type(Stream, Ack, or
-// Congestion Control) by checking if the first bit is 0, then shifting right.
-// TODO(jri): Remove kQuicFrameType0BitMask constant from v. 10 onwards.
-// Replaced by kQuicFrameTypeStream defined above.
-const uint8 kQuicFrameType0BitMask = 0x01;
-
-// Default frame type shift and mask.
-const uint8 kQuicDefaultFrameTypeShift = 3;
-const uint8 kQuicDefaultFrameTypeMask = 0x07;
-
// Stream frame relative shifts and masks for interpreting the stream flags.
// StreamID may be 1, 2, 3, or 4 bytes.
const uint8 kQuicStreamIdShift = 2;
@@ -936,11 +926,9 @@ bool QuicFramer::ProcessFrameData() {
return RaiseError(QUIC_INVALID_FRAME_DATA);
}
- // TODO(jri): Remove this entire if block when support for
- // QUIC version < 10 removed.
- if (version() < QUIC_VERSION_10) {
- // Special frame type processing for QUIC version < 10.
- if ((frame_type & kQuicFrameType0BitMask) == 0) {
+ if (frame_type & kQuicFrameTypeSpecialMask) {
+ // Stream Frame
+ if (frame_type & kQuicFrameTypeStreamMask) {
QuicStreamFrame frame;
if (!ProcessStreamFrame(frame_type, &frame)) {
return RaiseError(QUIC_INVALID_STREAM_DATA);
@@ -953,8 +941,8 @@ bool QuicFramer::ProcessFrameData() {
continue;
}
- frame_type >>= 1;
- if ((frame_type & kQuicFrameType0BitMask) == 0) {
+ // Ack Frame
+ if (frame_type & kQuicFrameTypeAckMask) {
QuicAckFrame frame;
if (!ProcessAckFrame(&frame)) {
return RaiseError(QUIC_INVALID_ACK_DATA);
@@ -967,8 +955,8 @@ bool QuicFramer::ProcessFrameData() {
continue;
}
- frame_type >>= 1;
- if ((frame_type & kQuicFrameType0BitMask) == 0) {
+ // Congestion Feedback Frame
+ if (frame_type & kQuicFrameTypeCongestionFeedbackMask) {
QuicCongestionFeedbackFrame frame;
if (!ProcessQuicCongestionFeedbackFrame(&frame)) {
return RaiseError(QUIC_INVALID_CONGESTION_FEEDBACK_DATA);
@@ -981,178 +969,70 @@ bool QuicFramer::ProcessFrameData() {
continue;
}
- frame_type >>= 1;
- switch (frame_type) {
- // STREAM_FRAME, ACK_FRAME, and CONGESTION_FEEDBACK_FRAME are handled
- // above.
- case PADDING_FRAME_OLD:
- // We're done with the packet.
- return true;
-
- case RST_STREAM_FRAME_OLD: {
- QuicRstStreamFrame frame;
- if (!ProcessRstStreamFrame(&frame)) {
- return RaiseError(QUIC_INVALID_RST_STREAM_DATA);
- }
- if (!visitor_->OnRstStreamFrame(frame)) {
- DLOG(INFO) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- continue;
- }
-
- case CONNECTION_CLOSE_FRAME_OLD: {
- QuicConnectionCloseFrame frame;
- if (!ProcessConnectionCloseFrame(&frame)) {
- return RaiseError(QUIC_INVALID_CONNECTION_CLOSE_DATA);
- }
+ // This was a special frame type that did not match any
+ // of the known ones. Error.
+ set_detailed_error("Illegal frame type.");
+ DLOG(WARNING) << "Illegal frame type: "
+ << static_cast<int>(frame_type);
+ return RaiseError(QUIC_INVALID_FRAME_DATA);
+ }
- if (!visitor_->OnAckFrame(frame.ack_frame)) {
- DLOG(INFO) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
+ switch (frame_type) {
+ case PADDING_FRAME:
+ // We're done with the packet.
+ return true;
- if (!visitor_->OnConnectionCloseFrame(frame)) {
- DLOG(INFO) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- continue;
+ case RST_STREAM_FRAME: {
+ QuicRstStreamFrame frame;
+ if (!ProcessRstStreamFrame(&frame)) {
+ return RaiseError(QUIC_INVALID_RST_STREAM_DATA);
}
-
- case GOAWAY_FRAME_OLD: {
- QuicGoAwayFrame goaway_frame;
- if (!ProcessGoAwayFrame(&goaway_frame)) {
- return RaiseError(QUIC_INVALID_GOAWAY_DATA);
- }
- if (!visitor_->OnGoAwayFrame(goaway_frame)) {
- DLOG(INFO) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- continue;
+ if (!visitor_->OnRstStreamFrame(frame)) {
+ DLOG(INFO) << "Visitor asked to stop further processing.";
+ // Returning true since there was no parsing error.
+ return true;
}
-
- set_detailed_error("Illegal frame type.");
- DLOG(WARNING) << "Illegal frame type: "
- << static_cast<int>(frame_type);
- return RaiseError(QUIC_INVALID_FRAME_DATA);
+ continue;
}
- } else {
- // TODO(jri): Retain this else block when support for
- // QUIC version < 10 removed. Remove above if block.
-
- // Special frame type processing for QUIC version >= 10.
- if (frame_type & kQuicFrameTypeSpecialMask) {
- // Stream Frame
- if (frame_type & kQuicFrameTypeStreamMask) {
- QuicStreamFrame frame;
- if (!ProcessStreamFrame(frame_type, &frame)) {
- return RaiseError(QUIC_INVALID_STREAM_DATA);
- }
- if (!visitor_->OnStreamFrame(frame)) {
- DLOG(INFO) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- continue;
- }
- // Ack Frame
- if (frame_type & kQuicFrameTypeAckMask) {
- QuicAckFrame frame;
- if (!ProcessAckFrame(&frame)) {
- return RaiseError(QUIC_INVALID_ACK_DATA);
- }
- if (!visitor_->OnAckFrame(frame)) {
- DLOG(INFO) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- continue;
+ case CONNECTION_CLOSE_FRAME: {
+ QuicConnectionCloseFrame frame;
+ if (!ProcessConnectionCloseFrame(&frame)) {
+ return RaiseError(QUIC_INVALID_CONNECTION_CLOSE_DATA);
}
- // Congestion Feedback Frame
- if (frame_type & kQuicFrameTypeCongestionFeedbackMask) {
- QuicCongestionFeedbackFrame frame;
- if (!ProcessQuicCongestionFeedbackFrame(&frame)) {
- return RaiseError(QUIC_INVALID_CONGESTION_FEEDBACK_DATA);
- }
- if (!visitor_->OnCongestionFeedbackFrame(frame)) {
- DLOG(INFO) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- continue;
+ if (!visitor_->OnAckFrame(frame.ack_frame)) {
+ DLOG(INFO) << "Visitor asked to stop further processing.";
+ // Returning true since there was no parsing error.
+ return true;
}
- // This was a special frame type that did not match any
- // of the known ones. Error.
- set_detailed_error("Illegal frame type.");
- DLOG(WARNING) << "Illegal frame type: "
- << static_cast<int>(frame_type);
- return RaiseError(QUIC_INVALID_FRAME_DATA);
- }
-
- switch (frame_type) {
- case PADDING_FRAME:
- // We're done with the packet.
+ if (!visitor_->OnConnectionCloseFrame(frame)) {
+ DLOG(INFO) << "Visitor asked to stop further processing.";
+ // Returning true since there was no parsing error.
return true;
-
- case RST_STREAM_FRAME: {
- QuicRstStreamFrame frame;
- if (!ProcessRstStreamFrame(&frame)) {
- return RaiseError(QUIC_INVALID_RST_STREAM_DATA);
- }
- if (!visitor_->OnRstStreamFrame(frame)) {
- DLOG(INFO) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- continue;
}
+ continue;
+ }
- case CONNECTION_CLOSE_FRAME: {
- QuicConnectionCloseFrame frame;
- if (!ProcessConnectionCloseFrame(&frame)) {
- return RaiseError(QUIC_INVALID_CONNECTION_CLOSE_DATA);
- }
-
- if (!visitor_->OnAckFrame(frame.ack_frame)) {
- DLOG(INFO) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
-
- if (!visitor_->OnConnectionCloseFrame(frame)) {
- DLOG(INFO) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- continue;
+ case GOAWAY_FRAME: {
+ QuicGoAwayFrame goaway_frame;
+ if (!ProcessGoAwayFrame(&goaway_frame)) {
+ return RaiseError(QUIC_INVALID_GOAWAY_DATA);
}
-
- case GOAWAY_FRAME: {
- QuicGoAwayFrame goaway_frame;
- if (!ProcessGoAwayFrame(&goaway_frame)) {
- return RaiseError(QUIC_INVALID_GOAWAY_DATA);
- }
- if (!visitor_->OnGoAwayFrame(goaway_frame)) {
- DLOG(INFO) << "Visitor asked to stop further processing.";
- // Returning true since there was no parsing error.
- return true;
- }
- continue;
+ if (!visitor_->OnGoAwayFrame(goaway_frame)) {
+ DLOG(INFO) << "Visitor asked to stop further processing.";
+ // Returning true since there was no parsing error.
+ return true;
}
-
- default:
- set_detailed_error("Illegal frame type.");
- DLOG(WARNING) << "Illegal frame type: "
- << static_cast<int>(frame_type);
- return RaiseError(QUIC_INVALID_FRAME_DATA);
+ continue;
}
+
+ default:
+ set_detailed_error("Illegal frame type.");
+ DLOG(WARNING) << "Illegal frame type: "
+ << static_cast<int>(frame_type);
+ return RaiseError(QUIC_INVALID_FRAME_DATA);
}
}
@@ -1163,12 +1043,7 @@ bool QuicFramer::ProcessStreamFrame(uint8 frame_type,
QuicStreamFrame* frame) {
uint8 stream_flags = frame_type;
- // TODO(jri): Remove if block after support for ver. < 10 removed.
- if (version() < QUIC_VERSION_10) {
- stream_flags >>= 1;
- } else {
- stream_flags &= ~kQuicFrameTypeStreamMask;
- }
+ stream_flags &= ~kQuicFrameTypeStreamMask;
// Read from right to left: StreamID, Offset, Data Length, Fin.
const uint8 stream_id_length = (stream_flags & kQuicStreamIDLengthMask) + 1;
@@ -1716,45 +1591,21 @@ bool QuicFramer::AppendTypeByte(const QuicFrame& frame,
// stream id 2 bits.
type_byte <<= kQuicStreamIdShift;
type_byte |= GetStreamIdSize(frame.stream_frame->stream_id) - 1;
-
- // TODO(jri): Remove if block when support for QUIC ver. < 10 removed.
- if (version() < QUIC_VERSION_10) {
- type_byte <<= 1; // Leaves the last bit as a 0.
- } else {
- type_byte |= kQuicFrameTypeStreamMask; // Set Stream Frame Type to 1.
- }
+ type_byte |= kQuicFrameTypeStreamMask; // Set Stream Frame Type to 1.
break;
}
case ACK_FRAME: {
// TODO(ianswett): Use extra 5 bits in the ack framing.
- // TODO(jri): Remove if block when support for QUIC ver. < 10 removed.
- if (version() < QUIC_VERSION_10) {
- type_byte = 0x01;
- } else {
- type_byte = kQuicFrameTypeAckMask;
- }
+ type_byte = kQuicFrameTypeAckMask;
break;
}
case CONGESTION_FEEDBACK_FRAME: {
// TODO(ianswett): Use extra 5 bits in the congestion feedback framing.
- // TODO(jri): Remove if block when support for QUIC ver. < 10 removed.
- if (version() < QUIC_VERSION_10) {
- type_byte = 0x03;
- } else {
- type_byte = kQuicFrameTypeCongestionFeedbackMask;
- }
+ type_byte = kQuicFrameTypeCongestionFeedbackMask;
break;
}
default:
type_byte = frame.type;
- // TODO(jri): Remove if block when support for QUIC ver. < 10 removed.
- if (version() < QUIC_VERSION_10) {
- if (type_byte > 0) {
- type_byte += 3;
- }
- type_byte = (type_byte << kQuicDefaultFrameTypeShift) |
- kQuicDefaultFrameTypeMask;
- }
break;
}
diff --git a/net/quic/quic_framer_test.cc b/net/quic/quic_framer_test.cc
index a0352de..f679b81 100644
--- a/net/quic/quic_framer_test.cc
+++ b/net/quic/quic_framer_test.cc
@@ -1038,8 +1038,7 @@ TEST_P(QuicFramerTest, InvalidPublicFlag) {
0x00,
// frame type (padding)
- static_cast<unsigned char>(
- GetParam() < QUIC_VERSION_10 ? 0x07 : 0x00),
+ 0x00,
0x00, 0x00, 0x00, 0x00
};
CheckProcessingFails(packet,
@@ -1064,8 +1063,7 @@ TEST_P(QuicFramerTest, InvalidPublicFlagWithMatchingVersions) {
0x00,
// frame type (padding)
- static_cast<unsigned char>(
- GetParam() < QUIC_VERSION_10 ? 0x07 : 0x00),
+ 0x00,
0x00, 0x00, 0x00, 0x00
};
CheckProcessingFails(packet,
@@ -1090,8 +1088,7 @@ TEST_P(QuicFramerTest, LargePublicFlagWithMismatchedVersions) {
0x00,
// frame type (padding frame)
- static_cast<unsigned char>(
- GetParam() < QUIC_VERSION_10 ? 0x07 : 0x00),
+ 0x00,
0x00, 0x00, 0x00, 0x00
};
QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
@@ -1116,8 +1113,7 @@ TEST_P(QuicFramerTest, InvalidPrivateFlag) {
0x10,
// frame type (padding)
- static_cast<unsigned char>(
- GetParam() < QUIC_VERSION_10 ? 0x07 : 0x00),
+ 0x00,
0x00, 0x00, 0x00, 0x00
};
CheckProcessingFails(packet,
@@ -1162,12 +1158,10 @@ TEST_P(QuicFramerTest, PaddingFrame) {
0x00,
// frame type (padding frame)
- static_cast<unsigned char>(
- GetParam() < QUIC_VERSION_10 ? 0x07 : 0x00),
+ 0x00,
// Ignored data (which in this case is a stream frame)
// frame type (stream frame with fin)
- static_cast<unsigned char>(
- GetParam() < QUIC_VERSION_10 ? 0xFE : 0xFF),
+ 0xFF,
// stream id
0x04, 0x03, 0x02, 0x01,
// offset
@@ -1211,8 +1205,7 @@ TEST_P(QuicFramerTest, StreamFrame) {
0x00,
// frame type (stream frame with fin)
- static_cast<unsigned char>(
- GetParam() < QUIC_VERSION_10 ? 0xFE : 0xFF),
+ 0xFF,
// stream id
0x04, 0x03, 0x02, 0x01,
// offset
@@ -1260,8 +1253,7 @@ TEST_P(QuicFramerTest, StreamFrame3ByteStreamId) {
0x00,
// frame type (stream frame with fin)
- static_cast<unsigned char>(
- GetParam() < QUIC_VERSION_10 ? 0xFC : 0xFE),
+ 0xFE,
// stream id
0x04, 0x03, 0x02,
// offset
@@ -1310,8 +1302,7 @@ TEST_P(QuicFramerTest, StreamFrame2ByteStreamId) {
0x00,
// frame type (stream frame with fin)
- static_cast<unsigned char>(
- GetParam() < QUIC_VERSION_10 ? 0xFA : 0xFD),
+ 0xFD,
// stream id
0x04, 0x03,
// offset
@@ -1360,8 +1351,7 @@ TEST_P(QuicFramerTest, StreamFrame1ByteStreamId) {
0x00,
// frame type (stream frame with fin)
- static_cast<unsigned char>(
- GetParam() < QUIC_VERSION_10 ? 0xF8 : 0xFC),
+ 0xFC,
// stream id
0x04,
// offset
@@ -1412,8 +1402,7 @@ TEST_P(QuicFramerTest, StreamFrameWithVersion) {
0x00,
// frame type (stream frame with fin)
- static_cast<unsigned char>(
- GetParam() < QUIC_VERSION_10 ? 0xFE : 0xFF),
+ 0xFF,
// stream id
0x04, 0x03, 0x02, 0x01,
// offset
@@ -1465,8 +1454,7 @@ TEST_P(QuicFramerTest, RejectPacket) {
0x00,
// frame type (stream frame with fin)
- static_cast<unsigned char>(
- GetParam() < QUIC_VERSION_10 ? 0xFE : 0xFF),
+ 0xFF,
// stream id
0x04, 0x03, 0x02, 0x01,
// offset
@@ -1494,8 +1482,7 @@ TEST_P(QuicFramerTest, RejectPacket) {
TEST_P(QuicFramerTest, RevivedStreamFrame) {
unsigned char payload[] = {
// frame type (stream frame with fin)
- static_cast<unsigned char>(
- GetParam() < QUIC_VERSION_10 ? 0xFE : 0xFF),
+ 0xFF,
// stream id
0x04, 0x03, 0x02, 0x01,
// offset
@@ -1564,8 +1551,7 @@ TEST_P(QuicFramerTest, StreamFrameInFecGroup) {
0x02,
// frame type (stream frame with fin)
- static_cast<unsigned char>(
- GetParam() < QUIC_VERSION_10 ? 0xFE : 0xFF),
+ 0xFF,
// stream id
0x04, 0x03, 0x02, 0x01,
// offset
@@ -1617,8 +1603,7 @@ TEST_P(QuicFramerTest, AckFrame) {
0x00,
// frame type (ack frame)
- static_cast<unsigned char>(
- GetParam() < QUIC_VERSION_10 ? 0x01 : 0x40),
+ 0x40,
// entropy hash of sent packets till least awaiting - 1.
0xAB,
// least packet sequence number awaiting an ack
@@ -1711,8 +1696,7 @@ TEST_P(QuicFramerTest, CongestionFeedbackFrameTCP) {
0x00,
// frame type (congestion feedback frame)
- static_cast<unsigned char>(
- GetParam() < QUIC_VERSION_10 ? 0x03 : 0x20),
+ 0x20,
// congestion feedback type (tcp)
0x00,
// ack_frame.feedback.tcp.accumulated_number_of_lost_packets
@@ -1769,8 +1753,7 @@ TEST_P(QuicFramerTest, CongestionFeedbackFrameInterArrival) {
0x00,
// frame type (congestion feedback frame)
- static_cast<unsigned char>(
- GetParam() < QUIC_VERSION_10 ? 0x03 : 0x20),
+ 0x20,
// congestion feedback type (inter arrival)
0x01,
// accumulated_number_of_lost_packets
@@ -1866,8 +1849,7 @@ TEST_P(QuicFramerTest, CongestionFeedbackFrameFixRate) {
0x00,
// frame type (congestion feedback frame)
- static_cast<unsigned char>(
- GetParam() < QUIC_VERSION_10 ? 0x03 : 0x20),
+ 0x20,
// congestion feedback type (fix rate)
0x02,
// bitrate_in_bytes_per_second;
@@ -1919,8 +1901,7 @@ TEST_P(QuicFramerTest, CongestionFeedbackFrameInvalidFeedback) {
0x00,
// frame type (congestion feedback frame)
- static_cast<unsigned char>(
- GetParam() < QUIC_VERSION_10 ? 0x03 : 0x20),
+ 0x20,
// congestion feedback type (invalid)
0x03,
};
@@ -1945,8 +1926,7 @@ TEST_P(QuicFramerTest, RstStreamFrame) {
0x00,
// frame type (rst stream frame)
- static_cast<unsigned char>(
- GetParam() < QUIC_VERSION_10 ? 0x27 : 0x01),
+ 0x01,
// stream id
0x04, 0x03, 0x02, 0x01,
// error code
@@ -2005,8 +1985,7 @@ TEST_P(QuicFramerTest, ConnectionCloseFrame) {
0x00,
// frame type (connection close frame)
- static_cast<unsigned char>(
- GetParam() < QUIC_VERSION_10 ? 0x2F : 0x02),
+ 0x02,
// error code
0x11, 0x00, 0x00, 0x00,
@@ -2093,8 +2072,7 @@ TEST_P(QuicFramerTest, GoAwayFrame) {
0x00,
// frame type (go away frame)
- static_cast<unsigned char>(
- GetParam() < QUIC_VERSION_10 ? 0x37 : 0x03),
+ 0x03,
// error code
0x09, 0x00, 0x00, 0x00,
// stream id
@@ -2294,8 +2272,7 @@ TEST_P(QuicFramerTest, BuildPaddingFramePacket) {
0x00,
// frame type (padding frame)
- static_cast<unsigned char>(
- GetParam() < QUIC_VERSION_10 ? 0x07 : 0x00),
+ 0x00,
0x00, 0x00, 0x00, 0x00
};
@@ -2341,8 +2318,7 @@ TEST_P(QuicFramerTest, Build4ByteSequenceNumberPaddingFramePacket) {
0x00,
// frame type (padding frame)
- static_cast<unsigned char>(
- GetParam() < QUIC_VERSION_10 ? 0x07 : 0x00),
+ 0x00,
0x00, 0x00, 0x00, 0x00
};
@@ -2388,8 +2364,7 @@ TEST_P(QuicFramerTest, Build2ByteSequenceNumberPaddingFramePacket) {
0x00,
// frame type (padding frame)
- static_cast<unsigned char>(
- GetParam() < QUIC_VERSION_10 ? 0x07 : 0x00),
+ 0x00,
0x00, 0x00, 0x00, 0x00
};
@@ -2435,8 +2410,7 @@ TEST_P(QuicFramerTest, Build1ByteSequenceNumberPaddingFramePacket) {
0x00,
// frame type (padding frame)
- static_cast<unsigned char>(
- GetParam() < QUIC_VERSION_10 ? 0x07 : 0x00),
+ 0x00,
0x00, 0x00, 0x00, 0x00
};
@@ -2486,8 +2460,7 @@ TEST_P(QuicFramerTest, BuildStreamFramePacket) {
0x01,
// frame type (stream frame with fin and no length)
- static_cast<unsigned char>(
- GetParam() < QUIC_VERSION_10 ? 0xBE : 0xDF),
+ 0xDF,
// stream id
0x04, 0x03, 0x02, 0x01,
// offset
@@ -2542,8 +2515,7 @@ TEST_P(QuicFramerTest, BuildStreamFramePacketWithVersionFlag) {
0x01,
// frame type (stream frame with fin and no length)
- static_cast<unsigned char>(
- GetParam() < QUIC_VERSION_10 ? 0xBE : 0xDF),
+ 0xDF,
// stream id
0x04, 0x03, 0x02, 0x01,
// offset
@@ -2626,8 +2598,7 @@ TEST_P(QuicFramerTest, BuildAckFramePacket) {
0x01,
// frame type (ack frame)
- static_cast<unsigned char>(
- GetParam() < QUIC_VERSION_10 ? 0x01 : 0x40),
+ 0x40,
// entropy hash of sent packets till least awaiting - 1.
0x14,
// least packet sequence number awaiting an ack
@@ -2687,8 +2658,7 @@ TEST_P(QuicFramerTest, BuildCongestionFeedbackFramePacketTCP) {
0x00,
// frame type (congestion feedback frame)
- static_cast<unsigned char>(
- GetParam() < QUIC_VERSION_10 ? 0x03 : 0x20),
+ 0x20,
// congestion feedback type (TCP)
0x00,
// accumulated number of lost packets
@@ -2747,8 +2717,7 @@ TEST_P(QuicFramerTest, BuildCongestionFeedbackFramePacketInterArrival) {
0x00,
// frame type (congestion feedback frame)
- static_cast<unsigned char>(
- GetParam() < QUIC_VERSION_10 ? 0x03 : 0x20),
+ 0x20,
// congestion feedback type (inter arrival)
0x01,
// accumulated_number_of_lost_packets
@@ -2811,8 +2780,7 @@ TEST_P(QuicFramerTest, BuildCongestionFeedbackFramePacketFixRate) {
0x00,
// frame type (congestion feedback frame)
- static_cast<unsigned char>(
- GetParam() < QUIC_VERSION_10 ? 0x03 : 0x20),
+ 0x20,
// congestion feedback type (fix rate)
0x02,
// bitrate_in_bytes_per_second;
@@ -2878,8 +2846,7 @@ TEST_P(QuicFramerTest, BuildRstFramePacket) {
0x00,
// frame type (rst stream frame)
- static_cast<unsigned char>(
- GetParam() < QUIC_VERSION_10 ? 0x27 : 0x01),
+ 0x01,
// stream id
0x04, 0x03, 0x02, 0x01,
// error code
@@ -2942,8 +2909,7 @@ TEST_P(QuicFramerTest, BuildCloseFramePacket) {
0x01,
// frame type (connection close frame)
- static_cast<unsigned char>(
- GetParam() < QUIC_VERSION_10 ? 0x2F : 0x02),
+ 0x02,
// error code
0x08, 0x07, 0x06, 0x05,
// error details length
@@ -3014,8 +2980,7 @@ TEST_P(QuicFramerTest, BuildGoAwayPacket) {
0x01,
// frame type (go away frame)
- static_cast<unsigned char>(
- GetParam() < QUIC_VERSION_10 ? 0x37 : 0x03),
+ 0x03,
// error code
0x08, 0x07, 0x06, 0x05,
// stream id
@@ -3356,8 +3321,7 @@ TEST_P(QuicFramerTest, EntropyFlagTest) {
0x01,
// frame type (stream frame with fin and no length)
- static_cast<unsigned char>(
- GetParam() < QUIC_VERSION_10 ? 0xBE : 0xDF),
+ 0xDF,
// stream id
0x04, 0x03, 0x02, 0x01,
// offset
@@ -3394,8 +3358,7 @@ TEST_P(QuicFramerTest, FecEntropyTest) {
0xFF,
// frame type (stream frame with fin and no length)
- static_cast<unsigned char>(
- GetParam() < QUIC_VERSION_10 ? 0xBE : 0xDF),
+ 0xDF,
// stream id
0x04, 0x03, 0x02, 0x01,
// offset
@@ -3430,8 +3393,7 @@ TEST_P(QuicFramerTest, StopPacketProcessing) {
0x01,
// frame type (stream frame with fin)
- static_cast<unsigned char>(
- GetParam() < QUIC_VERSION_10 ? 0xFE : 0xFF),
+ 0xFF,
// stream id
0x04, 0x03, 0x02, 0x01,
// offset
@@ -3445,8 +3407,7 @@ TEST_P(QuicFramerTest, StopPacketProcessing) {
'r', 'l', 'd', '!',
// frame type (ack frame)
- static_cast<unsigned char>(
- GetParam() < QUIC_VERSION_10 ? 0x01 : 0x40),
+ 0x40,
// entropy hash of sent packets till least awaiting - 1.
0x14,
// least packet sequence number awaiting an ack
@@ -3491,8 +3452,7 @@ TEST_P(QuicFramerTest, ConnectionCloseWithInvalidAck) {
0x00,
// frame type (connection close frame)
- static_cast<unsigned char>(
- GetParam() < QUIC_VERSION_10 ? 0x2F : 0x02),
+ 0x02,
// error code
0x11, 0x00, 0x00, 0x00,
// error details length
diff --git a/net/quic/quic_http_stream_test.cc b/net/quic/quic_http_stream_test.cc
index b7c0522..5995c44 100644
--- a/net/quic/quic_http_stream_test.cc
+++ b/net/quic/quic_http_stream_test.cc
@@ -140,8 +140,6 @@ class QuicHttpStreamTest : public ::testing::TestWithParam<bool> {
CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip));
peer_addr_ = IPEndPoint(ip, 443);
self_addr_ = IPEndPoint(ip, 8435);
- // TODO(rch): remove this.
- QuicConnection::g_acks_do_not_instigate_acks = true;
}
~QuicHttpStreamTest() {
@@ -149,8 +147,6 @@ class QuicHttpStreamTest : public ::testing::TestWithParam<bool> {
for (size_t i = 0; i < writes_.size(); i++) {
delete writes_[i].packet;
}
- // TODO(rch): remove this.
- QuicConnection::g_acks_do_not_instigate_acks = false;
}
// Adds a packet to the list of expected writes.
diff --git a/net/quic/quic_network_transaction_unittest.cc b/net/quic/quic_network_transaction_unittest.cc
index 526cb68..efd0139 100644
--- a/net/quic/quic_network_transaction_unittest.cc
+++ b/net/quic/quic_network_transaction_unittest.cc
@@ -178,11 +178,8 @@ class QuicNetworkTransactionTest : public PlatformTest {
std::string SerializeHeaderBlock(const SpdyHeaderBlock& headers) {
QuicSpdyCompressor compressor;
- if (QuicVersionMax() >= QUIC_VERSION_9) {
- return compressor.CompressHeadersWithPriority(
- ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY), headers);
- }
- return compressor.CompressHeaders(headers);
+ return compressor.CompressHeadersWithPriority(
+ ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY), headers);
}
// Returns a newly created packet to send kData on stream 1.
diff --git a/net/quic/quic_protocol.cc b/net/quic/quic_protocol.cc
index 72843ef..c586d29 100644
--- a/net/quic/quic_protocol.cc
+++ b/net/quic/quic_protocol.cc
@@ -121,8 +121,6 @@ QuicVersion QuicVersionMin() {
QuicTag QuicVersionToQuicTag(const QuicVersion version) {
switch (version) {
- case QUIC_VERSION_9:
- return MakeQuicTag('Q', '0', '0', '9');
case QUIC_VERSION_10:
return MakeQuicTag('Q', '0', '1', '0');
case QUIC_VERSION_11:
@@ -153,7 +151,6 @@ return #x
string QuicVersionToString(const QuicVersion version) {
switch (version) {
- RETURN_STRING_LITERAL(QUIC_VERSION_9);
RETURN_STRING_LITERAL(QUIC_VERSION_10);
RETURN_STRING_LITERAL(QUIC_VERSION_11);
default:
diff --git a/net/quic/quic_protocol.h b/net/quic/quic_protocol.h
index 8b3c1e9..c2ccc07 100644
--- a/net/quic/quic_protocol.h
+++ b/net/quic/quic_protocol.h
@@ -190,7 +190,6 @@ enum QuicVersion {
// Special case to indicate unknown/unsupported QUIC version.
QUIC_VERSION_UNSUPPORTED = 0,
- QUIC_VERSION_9 = 9,
QUIC_VERSION_10 = 10,
QUIC_VERSION_11 = 11, // Current version.
};
@@ -200,7 +199,7 @@ enum QuicVersion {
// element, with subsequent elements in descending order (versions can be
// skipped as necessary).
static const QuicVersion kSupportedQuicVersions[] =
- {QUIC_VERSION_10, QUIC_VERSION_9};
+ {QUIC_VERSION_10};
typedef std::vector<QuicVersion> QuicVersionVector;
@@ -220,10 +219,6 @@ NET_EXPORT_PRIVATE QuicTag QuicVersionToQuicTag(const QuicVersion version);
// Returns QUIC_VERSION_UNSUPPORTED if version_tag cannot be understood.
NET_EXPORT_PRIVATE QuicVersion QuicTagToQuicVersion(const QuicTag version_tag);
-// Returns the appropriate QuicTag for a properly formed version string
-// (e.g. Q010).
-NET_EXPORT_PRIVATE QuicTag StringToQuicTag(std::string version);
-
// Helper function which translates from a QuicVersion to a string.
// Returns strings corresponding to enum names (e.g. QUIC_VERSION_6).
NET_EXPORT_PRIVATE std::string QuicVersionToString(const QuicVersion version);
diff --git a/net/quic/quic_protocol_test.cc b/net/quic/quic_protocol_test.cc
index 0b96e4d..0dcfcc6 100644
--- a/net/quic/quic_protocol_test.cc
+++ b/net/quic/quic_protocol_test.cc
@@ -135,8 +135,8 @@ TEST(QuicProtocolTest, QuicVersionToString) {
EXPECT_EQ("QUIC_VERSION_10,",
QuicVersionArrayToString(single_version,
arraysize(single_version)));
- QuicVersion multiple_versions[] = {QUIC_VERSION_10, QUIC_VERSION_9};
- EXPECT_EQ("QUIC_VERSION_10,QUIC_VERSION_9,",
+ QuicVersion multiple_versions[] = {QUIC_VERSION_11, QUIC_VERSION_10};
+ EXPECT_EQ("QUIC_VERSION_11,QUIC_VERSION_10,",
QuicVersionArrayToString(multiple_versions,
arraysize(multiple_versions)));
diff --git a/net/tools/quic/end_to_end_test.cc b/net/tools/quic/end_to_end_test.cc
index f29989a..96ea50b 100644
--- a/net/tools/quic/end_to_end_test.cc
+++ b/net/tools/quic/end_to_end_test.cc
@@ -74,7 +74,6 @@ class EndToEndTest : public ::testing::TestWithParam<QuicVersion> {
net::IPAddressNumber ip;
CHECK(net::ParseIPLiteralToNumber("127.0.0.1", &ip));
server_address_ = IPEndPoint(ip, 0);
- QuicConnection::g_acks_do_not_instigate_acks = true;
FLAGS_track_retransmission_history = true;
client_config_.SetDefaults();
server_config_.SetDefaults();
@@ -166,6 +165,23 @@ class EndToEndTest : public ::testing::TestWithParam<QuicVersion> {
// server_writer_->set_fake_packet_loss_percentage(loss);
}
+ void SetRTT(QuicTime::Delta rtt) {
+ // TODO(ianswett): For now, the RTT is entirely simulated on the client
+ // side, because the server's writer does not have a ConnectionHelper.
+ // TODO(rtenneti): enable when we can do random packet loss tests in
+ // chrome's tree.
+ // client_writer_->set_fake_packet_delay(rtt);
+ }
+
+ void SetReorderPercentage(int32 reorder) {
+ // TODO(ianswett): For now, the reordering is entirely simulated on the
+ // client side, because the server's writer does not have a
+ // ConnectionHelper.
+ // TODO(rtenneti): enable when we can do random packet loss tests in
+ // chrome's tree.
+ // client_writer_->set_fake_reorder_percentage(reorder);
+ }
+
IPEndPoint server_address_;
string server_hostname_;
scoped_ptr<ServerThread> server_thread_;
@@ -373,6 +389,24 @@ TEST_P(EndToEndTest, LargePostWithPacketLoss) {
EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request));
}
+TEST_P(EndToEndTest, LargePostNoPacketLossWithDelayAndReordering) {
+ ASSERT_TRUE(Initialize());
+ SetRTT(QuicTime::Delta::FromMilliseconds(2));
+ SetReorderPercentage(30);
+
+ client_->client()->WaitForCryptoHandshakeConfirmed();
+
+ // 1 Mb body.
+ string body;
+ GenerateBody(&body, 1024 * 1024);
+
+ HTTPMessage request(HttpConstants::HTTP_1_1,
+ HttpConstants::POST, "/foo");
+ request.AddBody(body, true);
+
+ EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request));
+}
+
TEST_P(EndToEndTest, LargePostWithPacketLossAndBlocketSocket) {
// Connect with lower fake packet loss than we'd like to test. Until
// b/10126687 is fixed, losing handshake packets is pretty brutal.
diff --git a/net/tools/quic/quic_client.cc b/net/tools/quic/quic_client.cc
index 6cef711..a01e3c7 100644
--- a/net/tools/quic/quic_client.cc
+++ b/net/tools/quic/quic_client.cc
@@ -153,14 +153,13 @@ bool QuicClient::Connect() {
bool QuicClient::StartConnect() {
DCHECK(!connected() && initialized_);
- QuicGuid guid = QuicRandom::GetInstance()->RandUint64();
if (!writer_.get()) {
writer_.reset(CreateQuicPacketWriter());
}
session_.reset(new QuicClientSession(
server_hostname_,
config_,
- new QuicConnection(guid, server_address_,
+ new QuicConnection(GenerateGuid(), server_address_,
CreateQuicConnectionHelper(),
writer_.get(), false, version_),
&crypto_config_));
@@ -271,6 +270,10 @@ bool QuicClient::connected() const {
session_->connection()->connected();
}
+QuicGuid QuicClient::GenerateGuid() {
+ return QuicRandom::GetInstance()->RandUint64();
+}
+
QuicEpollConnectionHelper* QuicClient::CreateQuicConnectionHelper() {
return new QuicEpollConnectionHelper(&epoll_server_);
}
diff --git a/net/tools/quic/quic_client.h b/net/tools/quic/quic_client.h
index b4b8ceb..5637736 100644
--- a/net/tools/quic/quic_client.h
+++ b/net/tools/quic/quic_client.h
@@ -144,6 +144,7 @@ class QuicClient : public EpollCallbackInterface,
}
protected:
+ virtual QuicGuid GenerateGuid();
virtual QuicEpollConnectionHelper* CreateQuicConnectionHelper();
virtual QuicPacketWriter* CreateQuicPacketWriter();
diff --git a/net/tools/quic/quic_client_session_test.cc b/net/tools/quic/quic_client_session_test.cc
index 1b1ece6..d5b63a8 100644
--- a/net/tools/quic/quic_client_session_test.cc
+++ b/net/tools/quic/quic_client_session_test.cc
@@ -48,19 +48,11 @@ class ToolsQuicClientSessionTest : public ::testing::Test {
};
TEST_F(ToolsQuicClientSessionTest, CryptoConnect) {
- if (!Aes128Gcm12Encrypter::IsSupported()) {
- LOG(INFO) << "AES GCM not supported. Test skipped.";
- return;
- }
CompleteCryptoHandshake();
}
TEST_F(ToolsQuicClientSessionTest, MaxNumStreams) {
session_->config()->set_max_streams_per_connection(1, 1);
- if (!Aes128Gcm12Encrypter::IsSupported()) {
- LOG(INFO) << "AES GCM not supported. Test skipped.";
- return;
- }
// FLAGS_max_streams_per_connection = 1;
// Initialize crypto before the client session will create a stream.
CompleteCryptoHandshake();
@@ -77,11 +69,6 @@ TEST_F(ToolsQuicClientSessionTest, MaxNumStreams) {
}
TEST_F(ToolsQuicClientSessionTest, GoAwayReceived) {
- if (!Aes128Gcm12Encrypter::IsSupported()) {
- LOG(INFO) << "AES GCM not supported. Test skipped.";
- return;
- }
-
CompleteCryptoHandshake();
// After receiving a GoAway, I should no longer be able to create outgoing
diff --git a/net/tools/quic/quic_dispatcher.cc b/net/tools/quic/quic_dispatcher.cc
index b0930b0..72b14de 100644
--- a/net/tools/quic/quic_dispatcher.cc
+++ b/net/tools/quic/quic_dispatcher.cc
@@ -97,7 +97,7 @@ void QuicDispatcher::ProcessPacket(const IPEndPoint& server_address,
packet);
return;
}
- session = CreateQuicSession(guid, client_address, fd_, epoll_server_);
+ session = CreateQuicSession(guid, client_address);
if (session == NULL) {
DLOG(INFO) << "Failed to create session for " << guid;
@@ -198,11 +198,9 @@ void QuicDispatcher::OnConnectionClose(QuicGuid guid, QuicErrorCode error) {
QuicSession* QuicDispatcher::CreateQuicSession(
QuicGuid guid,
- const IPEndPoint& client_address,
- int /* fd */,
- EpollServer* epoll_server) {
+ const IPEndPoint& client_address) {
QuicConnectionHelperInterface* helper =
- new QuicEpollConnectionHelper(epoll_server);
+ new QuicEpollConnectionHelper(epoll_server_);
QuicServerSession* session = new QuicServerSession(
config_, new QuicConnection(guid, client_address, helper, this,
true, QuicVersionMax()), this);
diff --git a/net/tools/quic/quic_dispatcher.h b/net/tools/quic/quic_dispatcher.h
index a5ce3e8..ddc98df 100644
--- a/net/tools/quic/quic_dispatcher.h
+++ b/net/tools/quic/quic_dispatcher.h
@@ -91,9 +91,7 @@ class QuicDispatcher : public QuicPacketWriter, public QuicSessionOwner {
virtual QuicSession* CreateQuicSession(
QuicGuid guid,
- const IPEndPoint& client_address,
- int fd,
- EpollServer* epoll_server);
+ const IPEndPoint& client_address);
// Deletes all sessions on the closed session list and clears the list.
void DeleteSessions();
@@ -114,6 +112,8 @@ class QuicDispatcher : public QuicPacketWriter, public QuicSessionOwner {
return time_wait_list_manager_.get();
}
+ EpollServer* epoll_server() { return epoll_server_; }
+
private:
friend class net::tools::test::QuicDispatcherPeer;
diff --git a/net/tools/quic/quic_dispatcher_test.cc b/net/tools/quic/quic_dispatcher_test.cc
index 0d7407a..651f224 100644
--- a/net/tools/quic/quic_dispatcher_test.cc
+++ b/net/tools/quic/quic_dispatcher_test.cc
@@ -43,11 +43,9 @@ class TestDispatcher : public QuicDispatcher {
EpollServer* eps)
: QuicDispatcher(config, crypto_config, 1, eps) {}
- MOCK_METHOD4(CreateQuicSession, QuicSession*(
+ MOCK_METHOD2(CreateQuicSession, QuicSession*(
QuicGuid guid,
- const IPEndPoint& client_address,
- int fd,
- EpollServer* eps));
+ const IPEndPoint& client_address));
using QuicDispatcher::write_blocked_list;
};
@@ -139,12 +137,12 @@ class QuicDispatcherTest : public ::testing::Test {
TEST_F(QuicDispatcherTest, ProcessPackets) {
IPEndPoint addr(Loopback4(), 1);
- EXPECT_CALL(dispatcher_, CreateQuicSession(1, addr, _, &eps_))
+ EXPECT_CALL(dispatcher_, CreateQuicSession(1, addr))
.WillOnce(testing::Return(CreateSession(
&dispatcher_, 1, addr, &session1_, &eps_)));
ProcessPacket(addr, 1, "foo");
- EXPECT_CALL(dispatcher_, CreateQuicSession(2, addr, _, &eps_))
+ EXPECT_CALL(dispatcher_, CreateQuicSession(2, addr))
.WillOnce(testing::Return(CreateSession(
&dispatcher_, 2, addr, &session2_, &eps_)));
ProcessPacket(addr, 2, "bar");
@@ -160,7 +158,7 @@ TEST_F(QuicDispatcherTest, ProcessPackets) {
TEST_F(QuicDispatcherTest, Shutdown) {
IPEndPoint addr(Loopback4(), 1);
- EXPECT_CALL(dispatcher_, CreateQuicSession(_, addr, _, &eps_))
+ EXPECT_CALL(dispatcher_, CreateQuicSession(_, addr))
.WillOnce(testing::Return(CreateSession(
&dispatcher_, 1, addr, &session1_, &eps_)));
@@ -195,7 +193,7 @@ TEST_F(QuicDispatcherTest, TimeWaitListManager) {
// Create a new session.
IPEndPoint addr(Loopback4(), 1);
QuicGuid guid = 1;
- EXPECT_CALL(dispatcher_, CreateQuicSession(guid, addr, _, &eps_))
+ EXPECT_CALL(dispatcher_, CreateQuicSession(guid, addr))
.WillOnce(testing::Return(CreateSession(
&dispatcher_, guid, addr, &session1_, &eps_)));
ProcessPacket(addr, guid, "foo");
@@ -232,12 +230,12 @@ class QuicWriteBlockedListTest : public QuicDispatcherTest {
virtual void SetUp() {
IPEndPoint addr(Loopback4(), 1);
- EXPECT_CALL(dispatcher_, CreateQuicSession(_, addr, _, &eps_))
+ EXPECT_CALL(dispatcher_, CreateQuicSession(_, addr))
.WillOnce(testing::Return(CreateSession(
&dispatcher_, 1, addr, &session1_, &eps_)));
ProcessPacket(addr, 1, "foo");
- EXPECT_CALL(dispatcher_, CreateQuicSession(_, addr, _, &eps_))
+ EXPECT_CALL(dispatcher_, CreateQuicSession(_, addr))
.WillOnce(testing::Return(CreateSession(
&dispatcher_, 2, addr, &session2_, &eps_)));
ProcessPacket(addr, 2, "bar");
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 65f9fd7..8ea2992 100644
--- a/net/tools/quic/test_tools/packet_dropping_test_writer.cc
+++ b/net/tools/quic/test_tools/packet_dropping_test_writer.cc
@@ -31,11 +31,28 @@ class WriteUnblockedAlarm : public QuicAlarm::Delegate {
PacketDroppingTestWriter* writer_;
};
+// An alarm that is scheduled every time a new packet is to be written at a
+// later point.
+class DelayAlarm : public QuicAlarm::Delegate {
+ public:
+ explicit DelayAlarm(PacketDroppingTestWriter* writer)
+ : writer_(writer) { }
+
+ virtual QuicTime OnAlarm() OVERRIDE {
+ return writer_->ReleaseNextPacket();
+ }
+
+ private:
+ PacketDroppingTestWriter* writer_;
+};
+
PacketDroppingTestWriter::PacketDroppingTestWriter()
: clock_(NULL),
blocked_writer_(NULL),
fake_packet_loss_percentage_(0),
- fake_blocked_socket_percentage_(0) {
+ fake_blocked_socket_percentage_(0),
+ fake_packet_reorder_percentage_(0),
+ fake_packet_delay_(QuicTime::Delta::Zero()) {
int64 seed = base::RandUint64();
LOG(INFO) << "Seeding packet loss with " << seed;
simple_random_.set_seed(seed);
@@ -48,6 +65,8 @@ void PacketDroppingTestWriter::SetConnectionHelper(
clock_ = helper->GetClock();
write_unblocked_alarm_.reset(
helper->CreateAlarm(new WriteUnblockedAlarm(this)));
+ delay_alarm_.reset(
+ helper->CreateAlarm(new DelayAlarm(this)));
}
WriteResult PacketDroppingTestWriter::WritePacket(
@@ -56,12 +75,14 @@ WriteResult PacketDroppingTestWriter::WritePacket(
const net::IPEndPoint& peer_address,
QuicBlockedWriterInterface* blocked_writer) {
if (fake_packet_loss_percentage_ > 0 &&
- simple_random_.RandUint64() % 100 < fake_packet_loss_percentage_) {
+ simple_random_.RandUint64() % 100 <
+ static_cast<uint64>(fake_packet_loss_percentage_)) {
DLOG(INFO) << "Dropping packet.";
return WriteResult(WRITE_STATUS_OK, buf_len);
}
if (fake_blocked_socket_percentage_ > 0 &&
- simple_random_.RandUint64() % 100 < fake_blocked_socket_percentage_) {
+ simple_random_.RandUint64() % 100 <
+ static_cast<uint64>(fake_blocked_socket_percentage_)) {
DLOG(INFO) << "Blocking socket.";
if (!write_unblocked_alarm_->IsSet()) {
blocked_writer_ = blocked_writer;
@@ -73,6 +94,19 @@ WriteResult PacketDroppingTestWriter::WritePacket(
return WriteResult(WRITE_STATUS_BLOCKED, EAGAIN);
}
+ if (!fake_packet_delay_.IsZero()) {
+ // Queue it to be sent.
+ QuicTime send_time = clock_->ApproximateNow().Add(fake_packet_delay_);
+ delayed_packets_.push_back(DelayedWrite(buffer, buf_len, self_address,
+ peer_address, send_time));
+ // Set the alarm if it's not yet set.
+ if (!delay_alarm_->IsSet()) {
+ delay_alarm_->Set(send_time);
+ }
+
+ return WriteResult(WRITE_STATUS_OK, buf_len);
+ }
+
return writer()->WritePacket(buffer, buf_len, self_address, peer_address,
blocked_writer);
}
@@ -81,6 +115,49 @@ bool PacketDroppingTestWriter::IsWriteBlockedDataBuffered() const {
return false;
}
+QuicTime PacketDroppingTestWriter::ReleaseNextPacket() {
+ if (delayed_packets_.empty()) {
+ return QuicTime::Zero();
+ }
+ DelayedPacketList::iterator iter = delayed_packets_.begin();
+ // Determine if we should re-order.
+ if (delayed_packets_.size() > 1 && fake_packet_reorder_percentage_ > 0 &&
+ simple_random_.RandUint64() % 100 <
+ static_cast<uint64>(fake_packet_reorder_percentage_)) {
+ DLOG(INFO) << "Reordering packets.";
+ ++iter;
+ // Swap the send times when re-ordering packets.
+ delayed_packets_.begin()->send_time = iter->send_time;
+ }
+
+ DLOG(INFO) << "Releasing packet. " << (delayed_packets_.size() - 1)
+ << " remaining.";
+ // Grab the next one off the queue and send it.
+ writer()->WritePacket(iter->buffer.data(), iter->buffer.length(),
+ iter->self_address, iter->peer_address, NULL);
+ delayed_packets_.erase(iter);
+
+ // If there are others, find the time for the next to be sent.
+ if (delayed_packets_.empty()) {
+ return QuicTime::Zero();
+ }
+ return delayed_packets_.begin()->send_time;
+}
+
+PacketDroppingTestWriter::DelayedWrite::DelayedWrite(
+ const char* buffer,
+ size_t buf_len,
+ const net::IPAddressNumber& self_address,
+ const net::IPEndPoint& peer_address,
+ QuicTime send_time)
+ : buffer(buffer, buf_len),
+ self_address(self_address),
+ peer_address(peer_address),
+ send_time(send_time) {
+}
+
+PacketDroppingTestWriter::DelayedWrite::~DelayedWrite() {}
+
} // namespace test
} // namespace tools
} // namespace net
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 6ee533b..4067ea9 100644
--- a/net/tools/quic/test_tools/packet_dropping_test_writer.h
+++ b/net/tools/quic/test_tools/packet_dropping_test_writer.h
@@ -5,6 +5,8 @@
#ifndef NET_TOOLS_QUIC_TEST_TOOLS_PACKET_DROPPING_TEST_WRITER_H_
#define NET_TOOLS_QUIC_TEST_TOOLS_PACKET_DROPPING_TEST_WRITER_H_
+#include <list>
+
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "net/quic/quic_alarm.h"
@@ -20,7 +22,8 @@ namespace tools {
namespace test {
// Simulates a connection that drops packets a configured percentage of the time
-// and has a blocked socket a configured percentage of the time.
+// and has a blocked socket a configured percentage of the time. Also provides
+// the options to delay packets and reorder packets if delay is enabled.
class PacketDroppingTestWriter : public net::test::QuicTestWriter {
public:
PacketDroppingTestWriter();
@@ -38,6 +41,10 @@ class PacketDroppingTestWriter : public net::test::QuicTestWriter {
virtual bool IsWriteBlockedDataBuffered() const OVERRIDE;
+ // Writes out the next packet to the contained writer and returns the time
+ // for the next delayed packet to be written.
+ QuicTime ReleaseNextPacket();
+
QuicBlockedWriterInterface* blocked_writer() { return blocked_writer_; }
// The percent of time a packet is simulated as being lost.
@@ -53,13 +60,48 @@ class PacketDroppingTestWriter : public net::test::QuicTestWriter {
fake_blocked_socket_percentage_ = fake_blocked_socket_percentage;
}
+ // The percent of time a packet is simulated as being reordered.
+ void set_fake_reorder_percentage(int32 fake_packet_reorder_percentage) {
+ DCHECK(clock_);
+ fake_packet_reorder_percentage_ = fake_packet_reorder_percentage;
+ }
+
+ // The percent of time WritePacket will block and set WriteResult's status
+ // to WRITE_BLOCKED.
+ void set_fake_packet_delay(QuicTime::Delta fake_packet_delay) {
+ DCHECK(clock_);
+ fake_packet_delay_ = fake_packet_delay;
+ }
+
private:
+ // A single packet which will be sent at the supplied send_time.
+ class DelayedWrite {
+ public:
+ DelayedWrite(const char* buffer,
+ size_t buf_len,
+ const IPAddressNumber& self_address,
+ const IPEndPoint& peer_address,
+ QuicTime send_time);
+ ~DelayedWrite();
+
+ string buffer;
+ const IPAddressNumber self_address;
+ const IPEndPoint peer_address;
+ QuicTime send_time;
+ };
+
+ typedef std::list<DelayedWrite> DelayedPacketList;
+
const QuicClock* clock_;
scoped_ptr<QuicAlarm> write_unblocked_alarm_;
+ scoped_ptr<QuicAlarm> delay_alarm_;
QuicBlockedWriterInterface* blocked_writer_;
- uint32 fake_packet_loss_percentage_;
- uint32 fake_blocked_socket_percentage_;
+ int32 fake_packet_loss_percentage_;
+ int32 fake_blocked_socket_percentage_;
+ int32 fake_packet_reorder_percentage_;
+ QuicTime::Delta fake_packet_delay_;
SimpleRandom simple_random_;
+ DelayedPacketList delayed_packets_;
DISALLOW_COPY_AND_ASSIGN(PacketDroppingTestWriter);
};
diff --git a/net/tools/quic/test_tools/quic_test_client.cc b/net/tools/quic/test_tools/quic_test_client.cc
index 701ca3d..c320b82 100644
--- a/net/tools/quic/test_tools/quic_test_client.cc
+++ b/net/tools/quic/test_tools/quic_test_client.cc
@@ -100,7 +100,7 @@ class QuicEpollClient : public QuicClient {
const string& server_hostname,
const QuicVersion version)
: Super(server_address, server_hostname, version, false),
- test_writer_(NULL) {
+ override_guid_(0), test_writer_(NULL) {
}
QuicEpollClient(IPEndPoint server_address,
@@ -108,7 +108,7 @@ class QuicEpollClient : public QuicClient {
const QuicConfig& config,
const QuicVersion version)
: Super(server_address, server_hostname, config, version),
- test_writer_(NULL) {
+ override_guid_(0), test_writer_(NULL) {
}
virtual ~QuicEpollClient() {
@@ -126,10 +126,19 @@ class QuicEpollClient : public QuicClient {
return test_writer_;
}
+ virtual QuicGuid GenerateGuid() OVERRIDE {
+ return override_guid_ ? override_guid_ : Super::GenerateGuid();
+ }
+
// Takes ownership of writer.
void UseWriter(QuicTestWriter* writer) { test_writer_ = writer; }
+ void UseGuid(QuicGuid guid) {
+ override_guid_ = guid;
+ }
+
private:
+ QuicGuid override_guid_; // GUID to use, if nonzero
QuicTestWriter* test_writer_;
};
@@ -165,7 +174,7 @@ void QuicTestClient::Initialize(IPEndPoint address,
priority_ = 3;
bytes_read_ = 0;
bytes_written_= 0;
- never_connected_ = true;
+ connect_attempted_ = false;
secure_ = secure;
auto_reconnect_ = false;
proof_verifier_ = NULL;
@@ -239,7 +248,7 @@ string QuicTestClient::SendSynchronousRequest(const string& uri) {
}
QuicReliableClientStream* QuicTestClient::GetOrCreateStream() {
- if (never_connected_ == true || auto_reconnect_) {
+ if (!connect_attempted_ || auto_reconnect_) {
if (!connected()) {
Connect();
}
@@ -278,9 +287,11 @@ void QuicTestClient::WaitForResponse() {
void QuicTestClient::Connect() {
DCHECK(!connected());
- client_->Initialize();
+ if (!connect_attempted_) {
+ client_->Initialize();
+ }
client_->Connect();
- never_connected_ = false;
+ connect_attempted_ = true;
}
void QuicTestClient::ResetConnection() {
@@ -290,6 +301,7 @@ void QuicTestClient::ResetConnection() {
void QuicTestClient::Disconnect() {
client_->Disconnect();
+ connect_attempted_ = false;
}
IPEndPoint QuicTestClient::LocalSocketAddress() const {
@@ -344,6 +356,11 @@ void QuicTestClient::UseWriter(QuicTestWriter* writer) {
reinterpret_cast<QuicEpollClient*>(client_.get())->UseWriter(writer);
}
+void QuicTestClient::UseGuid(QuicGuid guid) {
+ DCHECK(!connected());
+ reinterpret_cast<QuicEpollClient*>(client_.get())->UseGuid(guid);
+}
+
} // namespace test
} // namespace tools
} // namespace net
diff --git a/net/tools/quic/test_tools/quic_test_client.h b/net/tools/quic/test_tools/quic_test_client.h
index 9640505..4f52cfb 100644
--- a/net/tools/quic/test_tools/quic_test_client.h
+++ b/net/tools/quic/test_tools/quic_test_client.h
@@ -81,6 +81,9 @@ class QuicTestClient : public ReliableQuicStream::Visitor {
// Configures client_ to take ownership of and use the writer.
// Must be called before initial connect.
void UseWriter(net::test::QuicTestWriter* writer);
+ // If the given GUID is nonzero, configures client_ to use a specific GUID
+ // instead of a random one.
+ void UseGuid(QuicGuid guid);
// Returns NULL if the maximum number of streams have already been created.
QuicReliableClientStream* GetOrCreateStream();
@@ -117,13 +120,12 @@ class QuicTestClient : public ReliableQuicStream::Visitor {
string response_;
uint64 bytes_read_;
uint64 bytes_written_;
- // True if the client has never connected before. The client will
- // auto-connect exactly once before sending data. If something causes a
- // connection reset, it will not automatically reconnect.
- bool never_connected_;
+ // True if we tried to connect already since the last call to Disconnect().
+ bool connect_attempted_;
bool secure_;
- // If true, the client will always reconnect if necessary before creating a
- // stream.
+ // The client will auto-connect exactly once before sending data. If
+ // something causes a connection reset, it will not automatically reconnect
+ // unless auto_reconnect_ is true.
bool auto_reconnect_;
// proof_verifier_ points to a RecordingProofVerifier that is owned by