summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/net.gyp4
-rw-r--r--net/quic/blocked_list.h91
-rw-r--r--net/quic/blocked_list_test.cc83
-rw-r--r--net/quic/congestion_control/hybrid_slow_start.cc5
-rw-r--r--net/quic/congestion_control/hybrid_slow_start.h2
-rw-r--r--net/quic/congestion_control/inter_arrival_overuse_detector.cc4
-rw-r--r--net/quic/congestion_control/tcp_cubic_sender_test.cc1
-rw-r--r--net/quic/crypto/crypto_framer.h2
-rw-r--r--net/quic/crypto/crypto_handshake.cc8
-rw-r--r--net/quic/crypto/crypto_handshake.h4
-rw-r--r--net/quic/crypto/crypto_protocol.h1
-rw-r--r--net/quic/crypto/strike_register.cc15
-rw-r--r--net/quic/crypto/strike_register.h6
-rw-r--r--net/quic/quic_connection.cc52
-rw-r--r--net/quic/quic_connection.h2
-rw-r--r--net/quic/quic_connection_test.cc118
-rw-r--r--net/quic/quic_crypto_client_stream_test.cc25
-rw-r--r--net/quic/quic_crypto_server_stream.h2
-rw-r--r--net/quic/quic_crypto_server_stream_test.cc19
-rw-r--r--net/quic/quic_data_writer.cc4
-rw-r--r--net/quic/quic_data_writer.h4
-rw-r--r--net/quic/quic_framer_test.cc9
-rw-r--r--net/quic/quic_packet_creator_test.cc2
-rw-r--r--net/quic/quic_packet_generator.cc22
-rw-r--r--net/quic/quic_packet_generator.h7
-rw-r--r--net/quic/quic_packet_generator_test.cc13
-rw-r--r--net/quic/quic_protocol.h6
-rw-r--r--net/quic/quic_sent_entropy_manager.h4
-rw-r--r--net/quic/quic_session.cc15
-rw-r--r--net/quic/quic_session.h4
-rw-r--r--net/quic/quic_session_test.cc6
-rw-r--r--net/quic/quic_stream_sequencer.h2
-rw-r--r--net/quic/quic_stream_sequencer_test.cc3
-rw-r--r--net/quic/quic_time_test.cc30
-rw-r--r--net/quic/quic_utils.cc8
-rw-r--r--net/quic/quic_utils.h3
-rw-r--r--net/quic/reliable_quic_stream.h1
-rw-r--r--net/quic/reliable_quic_stream_test.cc16
-rw-r--r--net/quic/test_tools/quic_framer_peer.cc4
-rw-r--r--net/quic/test_tools/quic_framer_peer.h1
-rw-r--r--net/quic/test_tools/quic_session_peer.cc8
-rw-r--r--net/quic/test_tools/quic_session_peer.h6
-rw-r--r--net/quic/test_tools/quic_test_utils.cc10
-rw-r--r--net/quic/test_tools/quic_test_utils.h6
-rw-r--r--net/spdy/write_blocked_list.h86
-rw-r--r--net/spdy/write_blocked_list_test.cc76
-rw-r--r--net/tools/quic/quic_client.h4
-rw-r--r--net/tools/quic/quic_dispatcher.cc18
-rw-r--r--net/tools/quic/quic_dispatcher.h6
-rw-r--r--net/tools/quic/quic_dispatcher_test.cc69
-rw-r--r--net/tools/quic/test_tools/quic_client_peer.cc7
-rw-r--r--net/tools/quic/test_tools/quic_client_peer.h1
-rw-r--r--net/tools/quic/test_tools/quic_test_utils.h2
53 files changed, 402 insertions, 505 deletions
diff --git a/net/net.gyp b/net/net.gyp
index e7b73b9..445bf3d 100644
--- a/net/net.gyp
+++ b/net/net.gyp
@@ -684,7 +684,6 @@
'proxy/proxy_server_mac.cc',
'proxy/proxy_service.cc',
'proxy/proxy_service.h',
- 'quic/blocked_list.h',
'quic/congestion_control/available_channel_estimator.cc',
'quic/congestion_control/available_channel_estimator.h',
'quic/congestion_control/channel_estimator.cc',
@@ -963,6 +962,7 @@
'spdy/spdy_websocket_stream.h',
'spdy/spdy_write_queue.cc',
'spdy/spdy_write_queue.h',
+ 'spdy/write_blocked_list.h',
'ssl/client_cert_store.h',
'ssl/client_cert_store_impl.h',
'ssl/client_cert_store_impl_mac.cc',
@@ -1667,7 +1667,6 @@
'proxy/proxy_script_fetcher_impl_unittest.cc',
'proxy/proxy_server_unittest.cc',
'proxy/proxy_service_unittest.cc',
- 'quic/blocked_list_test.cc',
'quic/congestion_control/available_channel_estimator_test.cc',
'quic/congestion_control/channel_estimator_test.cc',
'quic/congestion_control/cube_root_test.cc',
@@ -1819,6 +1818,7 @@
'spdy/spdy_websocket_test_util.cc',
'spdy/spdy_websocket_test_util.h',
'spdy/spdy_write_queue_unittest.cc',
+ 'spdy/write_blocked_list_test.cc',
'ssl/client_cert_store_impl_unittest.cc',
'ssl/default_server_bound_cert_store_unittest.cc',
'ssl/openssl_client_key_store_unittest.cc',
diff --git a/net/quic/blocked_list.h b/net/quic/blocked_list.h
deleted file mode 100644
index 3a7f989..0000000
--- a/net/quic/blocked_list.h
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// A combined list/hash set for read or write-blocked entities.
-
-#ifndef NET_QUIC_BLOCKED_LIST_H_
-#define NET_QUIC_BLOCKED_LIST_H_
-
-#include <list>
-
-#include "base/containers/hash_tables.h"
-#include "base/logging.h"
-
-namespace net {
-
-template <typename Object>
-class BlockedList {
- public:
- // Called to add an object to the blocked list. This indicates
- // the object should be notified when it can use the socket again.
- //
- // If this object is already on the list, it will not be added again.
- void AddBlockedObject(Object object) {
- // Only add the object to the list if we successfully add it to the set.
- if (object_set_.insert(object).second) {
- object_list_.push_back(object);
- }
- }
-
- // Called to remove an object from a blocked list. This should be
- // called in the event the object is being deleted before the list is.
- void RemoveBlockedObject(Object object) {
- // Remove the object from the set. We'll check the set before calling
- // OnCanWrite on a object from the list.
- //
- // There is potentially ordering unfairness should a session be removed and
- // then readded (as it keeps its position in the list) but it's not worth
- // the overhead to walk the list and remove it.
- object_set_.erase(object);
- }
-
- // Called when the socket is usable and some objects can access it. Returns
- // the first object and removes it from the list.
- Object GetNextBlockedObject() {
- DCHECK(!IsEmpty());
-
- // Walk the list to find the first object which was not removed from the
- // set.
- while (!object_list_.empty()) {
- Object object = *object_list_.begin();
- object_list_.pop_front();
- int removed = object_set_.erase(object);
- if (removed > 0) {
- return object;
- }
- }
-
- // This is a bit of a hack: It's illegal to call GetNextBlockedObject() if
- // the list is empty (see DCHECK above) but we must return something. This
- // compiles for ints (returns 0) and pointers in the case that someone has a
- // bug in their call site.
- return 0;
- };
-
- // Returns the number of objects in the blocked list.
- int NumObjects() {
- return object_set_.size();
- };
-
- // Returns true if there are no objects in the list, false otherwise.
- bool IsEmpty() {
- return object_set_.empty();
- };
-
- private:
- // A set tracking the objects. This is the authoritative container for
- // determining if an object is blocked. Objects in the list will always
- // be in the set.
- base::hash_set<Object> object_set_;
- // A list tracking the order in which objects were added to the list.
- // Objects are added to the back and pulled off the front, but only get
- // resumption calls if they're still in the set.
- // It's possible to be in the list twice, but only the first entry will get an
- // OnCanWrite call.
- std::list<Object> object_list_;
-};
-
-} // namespace net
-
-#endif // NET_QUIC_BLOCKED_LIST_H_
diff --git a/net/quic/blocked_list_test.cc b/net/quic/blocked_list_test.cc
deleted file mode 100644
index 074b6f5..0000000
--- a/net/quic/blocked_list_test.cc
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "net/quic/blocked_list.h"
-#include "net/quic/quic_connection.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-#if defined(COMPILER_GCC)
-namespace BASE_HASH_NAMESPACE {
-template<>
-struct hash<const int*> {
- std::size_t operator()(const int* ptr) const {
- return hash<size_t>()(reinterpret_cast<size_t>(ptr));
- }
-};
-}
-#endif
-
-namespace net {
-namespace test {
-namespace {
-
-class BlockedListTest : public ::testing::Test {
- protected:
- BlockedListTest() :
- item1_(0),
- item2_(0),
- item3_(0) {
- }
-
- BlockedList<const int*> list_;
- const int item1_;
- const int item2_;
- const int item3_;
-};
-
-TEST_F(BlockedListTest, BasicAdd) {
- list_.AddBlockedObject(&item1_);
- list_.AddBlockedObject(&item3_);
- list_.AddBlockedObject(&item2_);
- ASSERT_EQ(3, list_.NumObjects());
- ASSERT_FALSE(list_.IsEmpty());
-
- EXPECT_EQ(&item1_, list_.GetNextBlockedObject());
- EXPECT_EQ(&item3_, list_.GetNextBlockedObject());
- EXPECT_EQ(&item2_, list_.GetNextBlockedObject());
-}
-
-TEST_F(BlockedListTest, AddAndRemove) {
- list_.AddBlockedObject(&item1_);
- list_.AddBlockedObject(&item3_);
- list_.AddBlockedObject(&item2_);
- ASSERT_EQ(3, list_.NumObjects());
-
- list_.RemoveBlockedObject(&item3_);
- ASSERT_EQ(2, list_.NumObjects());
-
- EXPECT_EQ(&item1_, list_.GetNextBlockedObject());
- EXPECT_EQ(&item2_, list_.GetNextBlockedObject());
-}
-
-TEST_F(BlockedListTest, DuplicateAdd) {
- list_.AddBlockedObject(&item1_);
- list_.AddBlockedObject(&item3_);
- list_.AddBlockedObject(&item2_);
-
- list_.AddBlockedObject(&item3_);
- list_.AddBlockedObject(&item2_);
- list_.AddBlockedObject(&item1_);
-
- ASSERT_EQ(3, list_.NumObjects());
- ASSERT_FALSE(list_.IsEmpty());
-
- // Call in the original insert order.
- EXPECT_EQ(&item1_, list_.GetNextBlockedObject());
- EXPECT_EQ(&item3_, list_.GetNextBlockedObject());
- EXPECT_EQ(&item2_, list_.GetNextBlockedObject());
-}
-
-} // namespace
-} // namespace test
-} // namespace net
diff --git a/net/quic/congestion_control/hybrid_slow_start.cc b/net/quic/congestion_control/hybrid_slow_start.cc
index 8968dc9..eee96ad 100644
--- a/net/quic/congestion_control/hybrid_slow_start.cc
+++ b/net/quic/congestion_control/hybrid_slow_start.cc
@@ -104,9 +104,4 @@ bool HybridSlowStart::Exit() {
return false;
}
-QuicTime::Delta HybridSlowStart::SmoothedRtt() {
- // TODO(satyamshekhar): Calculate and return smooth average of rtt over time.
- return current_rtt_;
-}
-
} // namespace net
diff --git a/net/quic/congestion_control/hybrid_slow_start.h b/net/quic/congestion_control/hybrid_slow_start.h
index b0e4248..cee9c73 100644
--- a/net/quic/congestion_control/hybrid_slow_start.h
+++ b/net/quic/congestion_control/hybrid_slow_start.h
@@ -46,8 +46,6 @@ class NET_EXPORT_PRIVATE HybridSlowStart {
bool started() { return started_; }
- QuicTime::Delta SmoothedRtt();
-
private:
const QuicClock* clock_;
bool started_;
diff --git a/net/quic/congestion_control/inter_arrival_overuse_detector.cc b/net/quic/congestion_control/inter_arrival_overuse_detector.cc
index 73e005d..ea1c3af 100644
--- a/net/quic/congestion_control/inter_arrival_overuse_detector.cc
+++ b/net/quic/congestion_control/inter_arrival_overuse_detector.cc
@@ -16,10 +16,6 @@ static const int kMinVarianceDelta = 10000;
// Threshold for accumulated delta.
static const int kThresholdAccumulatedDeltasUs = 1000;
-// The higher the beta parameter, the lower is the effect of the input and the
-// more damping of the noise. And the longer time for a detection.
-static const float kBeta = 0.98f;
-
// Same as above, described as numerator and denominator.
static const int kBetaNumerator = 49;
static const int kBetaDenominator = 50;
diff --git a/net/quic/congestion_control/tcp_cubic_sender_test.cc b/net/quic/congestion_control/tcp_cubic_sender_test.cc
index e9f8893..c62ef83 100644
--- a/net/quic/congestion_control/tcp_cubic_sender_test.cc
+++ b/net/quic/congestion_control/tcp_cubic_sender_test.cc
@@ -13,7 +13,6 @@ namespace net {
namespace test {
const uint32 kDefaultWindowTCP = 10 * kMaxPacketSize;
-const QuicByteCount kNoNBytesInFlight = 0;
class TcpCubicSenderPeer : public TcpCubicSender {
public:
diff --git a/net/quic/crypto/crypto_framer.h b/net/quic/crypto/crypto_framer.h
index b070c66..ea69f3a 100644
--- a/net/quic/crypto/crypto_framer.h
+++ b/net/quic/crypto/crypto_framer.h
@@ -84,8 +84,6 @@ class NET_EXPORT_PRIVATE CryptoFramer {
size_t pad_length,
uint32* end_offset);
- void set_error(QuicErrorCode error) { error_ = error; }
-
// Represents the current state of the parsing state machine.
enum CryptoFramerState {
STATE_READING_TAG,
diff --git a/net/quic/crypto/crypto_handshake.cc b/net/quic/crypto/crypto_handshake.cc
index 2110d18..1a30f435 100644
--- a/net/quic/crypto/crypto_handshake.cc
+++ b/net/quic/crypto/crypto_handshake.cc
@@ -84,11 +84,6 @@ void CryptoHandshakeMessage::MarkDirty() {
serialized_.reset();
}
-void CryptoHandshakeMessage::Insert(QuicTagValueMap::const_iterator begin,
- QuicTagValueMap::const_iterator end) {
- tag_value_map_.insert(begin, end);
-}
-
void CryptoHandshakeMessage::SetTaglist(QuicTag tag, ...) {
// Warning, if sizeof(QuicTag) > sizeof(int) then this function will break
// because the terminating 0 will only be promoted to int.
@@ -326,8 +321,7 @@ string CryptoHandshakeMessage::DebugStringInternal(size_t indent) const {
}
QuicCryptoNegotiatedParameters::QuicCryptoNegotiatedParameters()
- : version(0),
- key_exchange(0),
+ : key_exchange(0),
aead(0) {
}
diff --git a/net/quic/crypto/crypto_handshake.h b/net/quic/crypto/crypto_handshake.h
index 8d954b6..e2fd38b 100644
--- a/net/quic/crypto/crypto_handshake.h
+++ b/net/quic/crypto/crypto_handshake.h
@@ -73,9 +73,6 @@ class NET_EXPORT_PRIVATE CryptoHandshakeMessage {
const QuicTagValueMap& tag_value_map() const { return tag_value_map_; }
- void Insert(QuicTagValueMap::const_iterator begin,
- QuicTagValueMap::const_iterator end);
-
// SetTaglist sets an element with the given tag to contain a list of tags,
// passed as varargs. The argument list must be terminated with a 0 element.
void SetTaglist(QuicTag tag, ...);
@@ -160,7 +157,6 @@ struct NET_EXPORT_PRIVATE QuicCryptoNegotiatedParameters {
QuicCryptoNegotiatedParameters();
~QuicCryptoNegotiatedParameters();
- uint16 version;
QuicTag key_exchange;
QuicTag aead;
std::string initial_premaster_secret;
diff --git a/net/quic/crypto/crypto_protocol.h b/net/quic/crypto/crypto_protocol.h
index 586569a..4580fce 100644
--- a/net/quic/crypto/crypto_protocol.h
+++ b/net/quic/crypto/crypto_protocol.h
@@ -59,7 +59,6 @@ const QuicTag kCHID = TAG('C', 'H', 'I', 'D'); // Channel ID.
// Client hello tags
const QuicTag kVERS = TAG('V', 'E', 'R', 'S'); // Version
const QuicTag kNONC = TAG('N', 'O', 'N', 'C'); // The client's nonce
-const QuicTag kSSID = TAG('S', 'S', 'I', 'D'); // Session ID
const QuicTag kKEXS = TAG('K', 'E', 'X', 'S'); // Key exchange methods
const QuicTag kAEAD = TAG('A', 'E', 'A', 'D'); // Authenticated
// encryption algorithms
diff --git a/net/quic/crypto/strike_register.cc b/net/quic/crypto/strike_register.cc
index 97aca18..f45bfab 100644
--- a/net/quic/crypto/strike_register.cc
+++ b/net/quic/crypto/strike_register.cc
@@ -56,8 +56,8 @@ class StrikeRegister::InternalNode {
};
// kCreationTimeFromInternalEpoch contains the number of seconds between the
-// start of the internal epoch and |creation_time_external_|. This allows us
-// to consider times that are before |creation_time_external_|.
+// start of the internal epoch and the creation time. This allows us
+// to consider times that are before the creation time.
static const uint32 kCreationTimeFromInternalEpoch = 63115200.0; // 2 years.
StrikeRegister::StrikeRegister(unsigned max_entries,
@@ -67,22 +67,17 @@ StrikeRegister::StrikeRegister(unsigned max_entries,
StartupType startup)
: max_entries_(max_entries),
window_secs_(window_secs),
+ internal_epoch_(current_time > kCreationTimeFromInternalEpoch
+ ? current_time - kCreationTimeFromInternalEpoch
+ : 0),
// The horizon is initially set |window_secs| into the future because, if
// we just crashed, then we may have accepted nonces in the span
// [current_time...current_time+window_secs) and so we conservatively
// reject the whole timespan unless |startup| tells us otherwise.
- creation_time_external_(current_time),
- internal_epoch_(current_time > kCreationTimeFromInternalEpoch
- ? current_time - kCreationTimeFromInternalEpoch
- : 0),
horizon_(ExternalTimeToInternal(current_time) + window_secs),
horizon_valid_(startup == DENY_REQUESTS_AT_STARTUP) {
memcpy(orbit_, orbit, sizeof(orbit_));
- // TODO(rtenneti): Remove the following check, Added the following to silence
- // "is not used" error.
- CHECK_GE(creation_time_external_, 0u);
-
// We only have 23 bits of index available.
CHECK_LT(max_entries, 1u << 23);
CHECK_GT(max_entries, 1u); // There must be at least two entries.
diff --git a/net/quic/crypto/strike_register.h b/net/quic/crypto/strike_register.h
index 98bc04c..fda62a8 100644
--- a/net/quic/crypto/strike_register.h
+++ b/net/quic/crypto/strike_register.h
@@ -129,7 +129,7 @@ class NET_EXPORT_PRIVATE StrikeRegister {
static uint32 TimeFromBytes(const uint8 d[4]);
// ExternalTimeToInternal converts an external time value into an internal
- // time value using |creation_time_external_|.
+ // time value using |internal_epoch_|.
uint32 ExternalTimeToInternal(uint32 external_time);
// BestMatch returns either kNil, or an external node index which could
@@ -164,10 +164,6 @@ class NET_EXPORT_PRIVATE StrikeRegister {
const uint32 max_entries_;
const uint32 window_secs_;
- // creation_time_external_ contains the uint32, external time when this
- // object was created (i.e. the value passed to the constructor). This is
- // used to translate external times to internal times.
- const uint32 creation_time_external_;
// internal_epoch_ contains the external time value of the start of internal
// time.
const uint32 internal_epoch_;
diff --git a/net/quic/quic_connection.cc b/net/quic/quic_connection.cc
index 718b788..fe0f2fa 100644
--- a/net/quic/quic_connection.cc
+++ b/net/quic/quic_connection.cc
@@ -40,11 +40,6 @@ const int kMaxRetransmissionsPerAck = 10;
// at least 3 sequence numbers larger arrives.
const size_t kNumberOfNacksBeforeRetransmission = 3;
-// The maxiumum number of packets we'd like to queue. We may end up queueing
-// more in the case of many control frames.
-// 6 is arbitrary.
-const int kMaxPacketsToSerializeAtOnce = 6;
-
// Limit the number of packets we send per retransmission-alarm so we
// eventually cede. 10 is arbitrary.
const size_t kMaxPacketsPerRetransmissionAlarm = 10;
@@ -516,7 +511,7 @@ bool QuicConnection::ValidateAckFrame(const QuicAckFrame& incoming_ack) {
incoming_ack.received_info.largest_observed) {
DLOG(ERROR) << ENDPOINT << "Peer sent missing packet: "
<< *incoming_ack.received_info.missing_packets.rbegin()
- << " greater than largest observed: "
+ << " which is greater than largest observed: "
<< incoming_ack.received_info.largest_observed;
return false;
}
@@ -526,7 +521,7 @@ bool QuicConnection::ValidateAckFrame(const QuicAckFrame& incoming_ack) {
received_packet_manager_.least_packet_awaited_by_peer()) {
DLOG(ERROR) << ENDPOINT << "Peer sent missing packet: "
<< *incoming_ack.received_info.missing_packets.begin()
- << "smaller than least_packet_awaited_by_peer_: "
+ << " which is smaller than least_packet_awaited_by_peer_: "
<< received_packet_manager_.least_packet_awaited_by_peer();
return false;
}
@@ -750,8 +745,21 @@ bool QuicConnection::ShouldLastPacketInstigateAck() {
void QuicConnection::MaybeSendInResponseToPacket(
bool last_packet_should_instigate_ack) {
- // TODO(ianswett): Better merge these two blocks to queue up an ack if
- // necessary, then either only send the ack or bundle it with other data.
+ packet_generator_.StartBatchOperations();
+
+ if (last_packet_should_instigate_ack) {
+ if (send_ack_in_response_to_packet_) {
+ SendAck();
+ } else if (last_packet_should_instigate_ack) {
+ // Set the ack alarm for when any retransmittable frame is received.
+ if (!ack_alarm_->IsSet()) {
+ ack_alarm_->Set(clock_->ApproximateNow().Add(
+ congestion_manager_.DefaultRetransmissionTime()));
+ }
+ }
+ send_ack_in_response_to_packet_ = !send_ack_in_response_to_packet_;
+ }
+
if (!last_ack_frames_.empty()) {
// Now the we have received an ack, we might be able to send packets which
// are queued locally, or drain streams which are blocked.
@@ -766,22 +774,7 @@ void QuicConnection::MaybeSendInResponseToPacket(
send_alarm_->Set(time_of_last_received_packet_.Add(delay));
}
}
-
- if (!last_packet_should_instigate_ack) {
- return;
- }
-
- if (send_ack_in_response_to_packet_) {
- SendAck();
- } else if (!last_stream_frames_.empty()) {
- // TODO(alyssar) this case should really be "if the packet contained any
- // non-ack frame", rather than "if the packet contained a stream frame"
- if (!ack_alarm_->IsSet()) {
- ack_alarm_->Set(clock_->ApproximateNow().Add(
- congestion_manager_.DefaultRetransmissionTime()));
- }
- }
- send_ack_in_response_to_packet_ = !send_ack_in_response_to_packet_;
+ packet_generator_.FinishBatchOperations();
}
void QuicConnection::SendVersionNegotiationPacket() {
@@ -884,9 +877,14 @@ bool QuicConnection::DoWrite() {
// write more.
if (CanWrite(NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA,
NOT_HANDSHAKE)) {
- packet_generator_.StartBatchOperations();
+ const bool in_batch_mode = packet_generator_.InBatchMode();
+ if (!in_batch_mode) {
+ packet_generator_.StartBatchOperations();
+ }
bool all_bytes_written = visitor_->OnCanWrite();
- packet_generator_.FinishBatchOperations();
+ if (!in_batch_mode) {
+ packet_generator_.FinishBatchOperations();
+ }
// After the visitor writes, it may have caused the socket to become write
// blocked or the congestion manager to prohibit sending, so check again.
diff --git a/net/quic/quic_connection.h b/net/quic/quic_connection.h
index 2e9b6db..05c70ec 100644
--- a/net/quic/quic_connection.h
+++ b/net/quic/quic_connection.h
@@ -204,8 +204,6 @@ class NET_EXPORT_PRIVATE QuicConnection
QuicVersion version);
virtual ~QuicConnection();
- static void DeleteEnclosedFrame(QuicFrame* frame);
-
// Send the data payload to the peer.
// Returns a pair with the number of bytes consumed from data, and a boolean
// indicating if the fin bit was consumed. This does not indicate the data
diff --git a/net/quic/quic_connection_test.cc b/net/quic/quic_connection_test.cc
index bd698c3..f2731ef 100644
--- a/net/quic/quic_connection_test.cc
+++ b/net/quic/quic_connection_test.cc
@@ -29,14 +29,14 @@ using std::map;
using std::vector;
using testing::_;
using testing::AnyNumber;
-using testing::Between;
using testing::ContainerEq;
using testing::DoAll;
using testing::InSequence;
using testing::InvokeWithoutArgs;
+using testing::Ref;
using testing::Return;
-using testing::StrictMock;
using testing::SaveArg;
+using testing::StrictMock;
namespace net {
namespace test {
@@ -50,6 +50,8 @@ const bool kEntropyFlag = true;
const QuicPacketEntropyHash kTestEntropyHash = 76;
+const int kDefaultRetransmissionTimeMs = 500;
+
class TestReceiveAlgorithm : public ReceiveAlgorithmInterface {
public:
explicit TestReceiveAlgorithm(QuicCongestionFeedbackFrame* feedback)
@@ -505,18 +507,6 @@ class QuicConnectionTest : public ::testing::Test {
return serialized_packet.entropy_hash;
}
- size_t ProcessFecProtectedPacket(QuicPacketSequenceNumber number,
- bool expect_revival) {
- if (expect_revival) {
- EXPECT_CALL(visitor_, OnPacket(_, _, _, _)).Times(2).WillRepeatedly(
- Return(accept_packet_));
- } else {
- EXPECT_CALL(visitor_, OnPacket(_, _, _, _)).WillOnce(
- Return(accept_packet_));
- }
- return ProcessDataPacket(number, 1, !kEntropyFlag);
- }
-
size_t ProcessDataPacket(QuicPacketSequenceNumber number,
QuicFecGroupNumber fec_group,
bool entropy_flag) {
@@ -689,6 +679,10 @@ class QuicConnectionTest : public ::testing::Test {
connection_.SetReceiveAlgorithm(receive_algorithm_);
}
+ QuicTime::Delta DefaultRetransmissionTime() {
+ return QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs);
+ }
+
QuicGuid guid_;
QuicFramer framer_;
QuicPacketCreator creator_;
@@ -699,7 +693,7 @@ class QuicConnectionTest : public ::testing::Test {
MockRandom random_generator_;
TestConnectionHelper* helper_;
TestConnection connection_;
- testing::StrictMock<MockConnectionVisitor> visitor_;
+ StrictMock<MockConnectionVisitor> visitor_;
QuicPacketHeader header_;
QuicPacketHeader revived_header_;
@@ -1100,9 +1094,7 @@ TEST_F(QuicConnectionTest, DontAbandonAckedFEC) {
ProcessAckPacket(&ack_fec, true);
- const QuicTime::Delta kDefaultRetransmissionTime =
- QuicTime::Delta::FromMilliseconds(5000);
- clock_.AdvanceTime(kDefaultRetransmissionTime);
+ clock_.AdvanceTime(DefaultRetransmissionTime());
// Abandon only data packet, FEC has been acked.
EXPECT_CALL(*send_algorithm_, AbandoningPacket(sequence_number, _)).Times(1);
@@ -1283,16 +1275,14 @@ TEST_F(QuicConnectionTest, RetransmitNackedPacketsOnTruncatedAck) {
EXPECT_TRUE(QuicConnectionPeer::GetReceivedTruncatedAck(&connection_));
QuicConnectionPeer::SetMaxPacketsPerRetransmissionAlarm(&connection_, 200);
- const QuicTime::Delta kDefaultRetransmissionTime =
- QuicTime::Delta::FromMilliseconds(500);
- clock_.AdvanceTime(kDefaultRetransmissionTime);
+ clock_.AdvanceTime(DefaultRetransmissionTime());
// Only packets that are less than largest observed should be retransmitted.
EXPECT_CALL(*send_algorithm_, AbandoningPacket(_, _)).Times(191);
EXPECT_CALL(*send_algorithm_, SentPacket(_, _, _, _)).Times(191);
connection_.OnRetransmissionTimeout();
clock_.AdvanceTime(QuicTime::Delta::FromMicroseconds(
- 2 * kDefaultRetransmissionTime.ToMicroseconds()));
+ 2 * DefaultRetransmissionTime().ToMicroseconds()));
// Retransmit already retransmitted packets event though the sequence number
// greater than the largest observed.
EXPECT_CALL(*send_algorithm_, AbandoningPacket(_, _)).Times(191);
@@ -1458,11 +1448,8 @@ TEST_F(QuicConnectionTest, ReviveMissingPacketAfterDataPackets) {
}
TEST_F(QuicConnectionTest, TestRetransmit) {
- const QuicTime::Delta kDefaultRetransmissionTime =
- QuicTime::Delta::FromMilliseconds(500);
-
QuicTime default_retransmission_time = clock_.ApproximateNow().Add(
- kDefaultRetransmissionTime);
+ DefaultRetransmissionTime());
SendStreamDataToPeer(1, "foo", 0, !kFin, NULL);
EXPECT_EQ(1u, outgoing_ack()->sent_info.least_unacked);
@@ -1470,7 +1457,7 @@ TEST_F(QuicConnectionTest, TestRetransmit) {
EXPECT_EQ(default_retransmission_time,
connection_.GetRetransmissionAlarm()->deadline());
// Simulate the retransimission alarm firing
- clock_.AdvanceTime(kDefaultRetransmissionTime);
+ clock_.AdvanceTime(DefaultRetransmissionTime());
EXPECT_CALL(*send_algorithm_, SentPacket(_, _, _, _));
EXPECT_CALL(*send_algorithm_, AbandoningPacket(1, _)).Times(1);
connection_.RetransmitPacket(1);
@@ -1479,11 +1466,8 @@ TEST_F(QuicConnectionTest, TestRetransmit) {
}
TEST_F(QuicConnectionTest, RetransmitWithSameEncryptionLevel) {
- const QuicTime::Delta kDefaultRetransmissionTime =
- QuicTime::Delta::FromMilliseconds(500);
-
QuicTime default_retransmission_time = clock_.ApproximateNow().Add(
- kDefaultRetransmissionTime);
+ DefaultRetransmissionTime());
use_tagging_decrypter();
// A TaggingEncrypter puts kTagSize copies of the given byte (0x01 here) at
@@ -1500,7 +1484,7 @@ TEST_F(QuicConnectionTest, RetransmitWithSameEncryptionLevel) {
EXPECT_EQ(default_retransmission_time,
connection_.GetRetransmissionAlarm()->deadline());
// Simulate the retransimission alarm firing
- clock_.AdvanceTime(kDefaultRetransmissionTime);
+ clock_.AdvanceTime(DefaultRetransmissionTime());
EXPECT_CALL(*send_algorithm_, AbandoningPacket(_, _)).Times(2);
EXPECT_CALL(*send_algorithm_, SentPacket(_, _, _, _));
@@ -1528,15 +1512,13 @@ TEST_F(QuicConnectionTest,
EXPECT_CALL(*send_algorithm_, SentPacket(_, _, _, _)).Times(0);
EXPECT_CALL(*send_algorithm_, AbandoningPacket(sequence_number, _)).Times(1);
- const QuicTime::Delta kDefaultRetransmissionTime =
- QuicTime::Delta::FromMilliseconds(500);
QuicTime default_retransmission_time = clock_.ApproximateNow().Add(
- kDefaultRetransmissionTime);
+ DefaultRetransmissionTime());
EXPECT_EQ(default_retransmission_time,
connection_.GetRetransmissionAlarm()->deadline());
// Simulate the retransimission alarm firing
- clock_.AdvanceTime(kDefaultRetransmissionTime);
+ clock_.AdvanceTime(DefaultRetransmissionTime());
connection_.OnRetransmissionTimeout();
}
@@ -2065,7 +2047,7 @@ TEST_F(QuicConnectionTest, UpdateEntropyForReceivedPackets) {
QuicPacketEntropyHash six_packet_entropy_hash = 0;
if (ProcessAckPacket(&ack, true)) {
six_packet_entropy_hash = 1 << 6;
- };
+ }
EXPECT_EQ((kRandomEntropyHash + (1 << 5) + six_packet_entropy_hash),
outgoing_ack()->received_info.entropy_hash);
@@ -2440,6 +2422,68 @@ TEST_F(QuicConnectionTest, ConnectionCloseWhenNothingPending) {
EXPECT_EQ(1u, helper_->packets_write_attempts());
}
+class MockQuicConnectionDebugVisitor
+ : public QuicConnectionDebugVisitorInterface {
+ public:
+ MOCK_METHOD1(OnFrameAddedToPacket,
+ void(const QuicFrame&));
+
+ MOCK_METHOD4(OnPacketSent,
+ void(QuicPacketSequenceNumber,
+ EncryptionLevel,
+ const QuicEncryptedPacket&,
+ int));
+
+ MOCK_METHOD2(OnPacketRetransmitted,
+ void(QuicPacketSequenceNumber,
+ QuicPacketSequenceNumber));
+
+ MOCK_METHOD3(OnPacketReceived,
+ void(const IPEndPoint&,
+ const IPEndPoint&,
+ const QuicEncryptedPacket&));
+
+ MOCK_METHOD1(OnProtocolVersionMismatch,
+ void(QuicVersion));
+
+ MOCK_METHOD1(OnPacketHeader,
+ void(const QuicPacketHeader& header));
+
+ MOCK_METHOD1(OnStreamFrame,
+ void(const QuicStreamFrame&));
+
+ MOCK_METHOD1(OnAckFrame,
+ void(const QuicAckFrame& frame));
+
+ MOCK_METHOD1(OnCongestionFeedbackFrame,
+ void(const QuicCongestionFeedbackFrame&));
+
+ MOCK_METHOD1(OnRstStreamFrame,
+ void(const QuicRstStreamFrame&));
+
+ MOCK_METHOD1(OnConnectionCloseFrame,
+ void(const QuicConnectionCloseFrame&));
+
+ MOCK_METHOD1(OnPublicResetPacket,
+ void(const QuicPublicResetPacket&));
+
+ MOCK_METHOD1(OnVersionNegotiationPacket,
+ void(const QuicVersionNegotiationPacket&));
+
+ MOCK_METHOD2(OnRevivedPacket,
+ void(const QuicPacketHeader&, StringPiece payload));
+};
+
+TEST_F(QuicConnectionTest, OnPacketHeaderDebugVisitor) {
+ QuicPacketHeader header;
+
+ scoped_ptr<MockQuicConnectionDebugVisitor>
+ debug_visitor(new StrictMock<MockQuicConnectionDebugVisitor>);
+ connection_.set_debug_visitor(debug_visitor.get());
+ EXPECT_CALL(*debug_visitor, OnPacketHeader(Ref(header))).Times(1);
+ connection_.OnPacketHeader(header);
+}
+
} // namespace
} // namespace test
} // namespace net
diff --git a/net/quic/quic_crypto_client_stream_test.cc b/net/quic/quic_crypto_client_stream_test.cc
index 9f9e7f7..2ad9a3a2 100644
--- a/net/quic/quic_crypto_client_stream_test.cc
+++ b/net/quic/quic_crypto_client_stream_test.cc
@@ -21,31 +21,6 @@ namespace {
const char kServerHostname[] = "example.com";
-class TestQuicVisitor : public NoOpFramerVisitor {
- public:
- TestQuicVisitor()
- : frame_valid_(false) {
- }
-
- // NoOpFramerVisitor
- virtual bool OnStreamFrame(const QuicStreamFrame& frame) OVERRIDE {
- frame_ = frame;
- frame_valid_ = true;
- return true;
- }
-
- bool frame_valid() const {
- return frame_valid_;
- }
- QuicStreamFrame* frame() { return &frame_; }
-
- private:
- QuicStreamFrame frame_;
- bool frame_valid_;
-
- DISALLOW_COPY_AND_ASSIGN(TestQuicVisitor);
-};
-
class QuicCryptoClientStreamTest : public ::testing::Test {
public:
QuicCryptoClientStreamTest()
diff --git a/net/quic/quic_crypto_server_stream.h b/net/quic/quic_crypto_server_stream.h
index f1e30cb..b4967d8 100644
--- a/net/quic/quic_crypto_server_stream.h
+++ b/net/quic/quic_crypto_server_stream.h
@@ -43,8 +43,6 @@ class NET_EXPORT_PRIVATE QuicCryptoServerStream : public QuicCryptoStream {
CryptoHandshakeMessage* reply,
std::string* error_details);
- const QuicCryptoServerConfig* crypto_config() { return &crypto_config_; }
-
private:
friend class test::CryptoTestUtils;
diff --git a/net/quic/quic_crypto_server_stream_test.cc b/net/quic/quic_crypto_server_stream_test.cc
index 3bb2593..9e92b2b 100644
--- a/net/quic/quic_crypto_server_stream_test.cc
+++ b/net/quic/quic_crypto_server_stream_test.cc
@@ -36,25 +36,6 @@ namespace net {
namespace test {
namespace {
-// TODO(agl): Use rch's utility class for parsing a message when committed.
-class TestQuicVisitor : public NoOpFramerVisitor {
- public:
- TestQuicVisitor() {}
-
- // NoOpFramerVisitor
- virtual bool OnStreamFrame(const QuicStreamFrame& frame) OVERRIDE {
- frame_ = frame;
- return true;
- }
-
- QuicStreamFrame* frame() { return &frame_; }
-
- private:
- QuicStreamFrame frame_;
-
- DISALLOW_COPY_AND_ASSIGN(TestQuicVisitor);
-};
-
class QuicCryptoServerStreamTest : public ::testing::Test {
public:
QuicCryptoServerStreamTest()
diff --git a/net/quic/quic_data_writer.cc b/net/quic/quic_data_writer.cc
index e52cd03..61e7292 100644
--- a/net/quic/quic_data_writer.cc
+++ b/net/quic/quic_data_writer.cc
@@ -56,10 +56,6 @@ bool QuicDataWriter::WriteUInt64(uint64 value) {
return WriteBytes(&value, sizeof(value));
}
-bool QuicDataWriter::WriteUInt128(uint128 value) {
- return WriteUInt64(Uint128Low64(value)) && WriteUInt64(Uint128High64(value));
-}
-
bool QuicDataWriter::WriteStringPiece16(StringPiece val) {
if (val.length() > numeric_limits<uint16>::max()) {
return false;
diff --git a/net/quic/quic_data_writer.h b/net/quic/quic_data_writer.h
index f3408d1..b18121d 100644
--- a/net/quic/quic_data_writer.h
+++ b/net/quic/quic_data_writer.h
@@ -43,7 +43,6 @@ class NET_EXPORT_PRIVATE QuicDataWriter {
bool WriteUInt32(uint32 value);
bool WriteUInt48(uint64 value);
bool WriteUInt64(uint64 value);
- bool WriteUInt128(uint128 value);
bool WriteStringPiece16(base::StringPiece val);
bool WriteBytes(const void* data, size_t data_len);
bool WriteRepeatedByte(uint8 byte, size_t count);
@@ -61,9 +60,6 @@ class NET_EXPORT_PRIVATE QuicDataWriter {
return capacity_;
}
- protected:
- const char* end_of_payload() const { return buffer_ + length_; }
-
private:
// Returns the location that the data should be written at, or NULL if there
// is not enough room. Call EndWrite with the returned offset and the given
diff --git a/net/quic/quic_framer_test.cc b/net/quic/quic_framer_test.cc
index e4148fe..4f37f12 100644
--- a/net/quic/quic_framer_test.cc
+++ b/net/quic/quic_framer_test.cc
@@ -36,8 +36,6 @@ namespace test {
const QuicPacketSequenceNumber kEpoch = GG_UINT64_C(1) << 48;
const QuicPacketSequenceNumber kMask = kEpoch - 1;
-// Index into the flags offset in the header.
-const size_t kPublicFlagsOffset = 0;
// Index into the guid offset in the header.
const size_t kGuidOffset = kPublicFlagsSize;
// Index into the version string in the header. (if present).
@@ -390,13 +388,6 @@ class QuicFramerTest : public ::testing::TestWithParam<QuicVersion> {
EXPECT_EQ(error_code, framer_.error()) << "len: " << len;
}
- void ValidateTruncatedAck(const QuicAckFrame* ack, size_t keys) {
- for (size_t i = 1; i < keys; ++i) {
- EXPECT_TRUE(ContainsKey(ack->received_info.missing_packets, i)) << i;
- }
- EXPECT_EQ(keys, ack->received_info.largest_observed);
- }
-
void CheckCalculatePacketSequenceNumber(
QuicPacketSequenceNumber expected_sequence_number,
QuicPacketSequenceNumber last_sequence_number) {
diff --git a/net/quic/quic_packet_creator_test.cc b/net/quic/quic_packet_creator_test.cc
index 1d793d2..030066f 100644
--- a/net/quic/quic_packet_creator_test.cc
+++ b/net/quic/quic_packet_creator_test.cc
@@ -32,7 +32,6 @@ class QuicPacketCreatorTest : public ::testing::TestWithParam<bool> {
QuicPacketCreatorTest()
: server_framer_(QuicVersionMax(), QuicTime::Zero(), true),
client_framer_(QuicVersionMax(), QuicTime::Zero(), false),
- id_(1),
sequence_number_(0),
guid_(2),
data_("foo"),
@@ -64,7 +63,6 @@ class QuicPacketCreatorTest : public ::testing::TestWithParam<bool> {
QuicFramer server_framer_;
QuicFramer client_framer_;
testing::StrictMock<MockFramerVisitor> framer_visitor_;
- QuicStreamId id_;
QuicPacketSequenceNumber sequence_number_;
QuicGuid guid_;
string data_;
diff --git a/net/quic/quic_packet_generator.cc b/net/quic/quic_packet_generator.cc
index 7600010..493a6dd 100644
--- a/net/quic/quic_packet_generator.cc
+++ b/net/quic/quic_packet_generator.cc
@@ -18,7 +18,7 @@ QuicPacketGenerator::QuicPacketGenerator(DelegateInterface* delegate,
: delegate_(delegate),
debug_delegate_(debug_delegate),
packet_creator_(creator),
- should_flush_(true),
+ batch_mode_(false),
should_send_ack_(false),
should_send_feedback_(false) {
}
@@ -89,7 +89,7 @@ QuicConsumedData QuicPacketGenerator::ConsumeData(QuicStreamId id,
DCHECK(data.empty() || packet_creator_->BytesFree() == 0u);
// TODO(ianswett): Restore packet reordering.
- if (should_flush_ || !packet_creator_->HasRoomForStreamFrame(id, offset)) {
+ if (!InBatchMode() || !packet_creator_->HasRoomForStreamFrame(id, offset)) {
SerializeAndSendPacket();
}
@@ -101,15 +101,15 @@ QuicConsumedData QuicPacketGenerator::ConsumeData(QuicStreamId id,
}
}
- // Ensure the FEC group is closed at the end of this method unless other
- // writes are pending.
- if (should_flush_ && packet_creator_->ShouldSendFec(true)) {
+ // Ensure the FEC group is closed at the end of this method if not in batch
+ // mode.
+ if (!InBatchMode() && packet_creator_->ShouldSendFec(true)) {
SerializedPacket serialized_fec = packet_creator_->SerializeFec();
DCHECK(serialized_fec.packet);
delegate_->OnSerializedPacket(serialized_fec);
}
- DCHECK(!should_flush_ || !packet_creator_->HasPendingFrames());
+ DCHECK(InBatchMode() || !packet_creator_->HasPendingFrames());
return QuicConsumedData(total_bytes_consumed, fin_consumed);
}
@@ -135,7 +135,7 @@ void QuicPacketGenerator::SendQueuedFrames() {
}
}
- if (should_flush_) {
+ if (!InBatchMode()) {
if (packet_creator_->HasPendingFrames()) {
SerializeAndSendPacket();
}
@@ -151,12 +151,16 @@ void QuicPacketGenerator::SendQueuedFrames() {
}
}
+bool QuicPacketGenerator::InBatchMode() {
+ return batch_mode_;
+}
+
void QuicPacketGenerator::StartBatchOperations() {
- should_flush_ = false;
+ batch_mode_ = true;
}
void QuicPacketGenerator::FinishBatchOperations() {
- should_flush_ = true;
+ batch_mode_ = false;
SendQueuedFrames();
}
diff --git a/net/quic/quic_packet_generator.h b/net/quic/quic_packet_generator.h
index e8b09e6..f61e6e4 100644
--- a/net/quic/quic_packet_generator.h
+++ b/net/quic/quic_packet_generator.h
@@ -95,6 +95,8 @@ class NET_EXPORT_PRIVATE QuicPacketGenerator {
QuicStreamOffset offset,
bool fin);
+ // Indicates whether batch mode is currently enabled.
+ bool InBatchMode();
// Disables flushing.
void StartBatchOperations();
// Enables flushing and flushes queued data.
@@ -126,7 +128,10 @@ class NET_EXPORT_PRIVATE QuicPacketGenerator {
QuicPacketCreator* packet_creator_;
QuicFrames queued_control_frames_;
- bool should_flush_;
+
+ // True if batch mode is currently enabled.
+ bool batch_mode_;
+
// Flags to indicate the need for just-in-time construction of a frame.
bool should_send_ack_;
bool should_send_feedback_;
diff --git a/net/quic/quic_packet_generator_test.cc b/net/quic/quic_packet_generator_test.cc
index 45556f1..5f7c7b6 100644
--- a/net/quic/quic_packet_generator_test.cc
+++ b/net/quic/quic_packet_generator_test.cc
@@ -21,6 +21,7 @@ using std::string;
using testing::InSequence;
using testing::Return;
using testing::SaveArg;
+using testing::StrictMock;
using testing::_;
namespace net {
@@ -198,7 +199,7 @@ class QuicPacketGeneratorTest : public ::testing::Test {
QuicFramer framer_;
MockRandom random_;
QuicPacketCreator creator_;
- testing::StrictMock<MockDelegate> delegate_;
+ StrictMock<MockDelegate> delegate_;
QuicPacketGenerator generator_;
SimpleQuicFramer simple_framer_;
SerializedPacket packet_;
@@ -211,6 +212,12 @@ class QuicPacketGeneratorTest : public ::testing::Test {
scoped_ptr<char[]> data_array_;
};
+class MockDebugDelegate : public QuicPacketGenerator::DebugDelegateInterface {
+ public:
+ MOCK_METHOD1(OnFrameAddedToPacket,
+ void(const QuicFrame&));
+};
+
TEST_F(QuicPacketGeneratorTest, ShouldSendAck_NotWritable) {
delegate_.SetCanNotWrite();
@@ -219,10 +226,14 @@ TEST_F(QuicPacketGeneratorTest, ShouldSendAck_NotWritable) {
}
TEST_F(QuicPacketGeneratorTest, ShouldSendAck_WritableAndShouldNotFlush) {
+ StrictMock<MockDebugDelegate> debug_delegate;
+
+ generator_.set_debug_delegate(&debug_delegate);
delegate_.SetCanWriteOnlyNonRetransmittable();
generator_.StartBatchOperations();
EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame()));
+ EXPECT_CALL(debug_delegate, OnFrameAddedToPacket(_)).Times(1);
generator_.SetShouldSendAck(false);
EXPECT_TRUE(generator_.HasQueuedFrames());
diff --git a/net/quic/quic_protocol.h b/net/quic/quic_protocol.h
index 737bb16..28abe3c 100644
--- a/net/quic/quic_protocol.h
+++ b/net/quic/quic_protocol.h
@@ -675,10 +675,6 @@ struct NET_EXPORT_PRIVATE QuicFecData {
base::StringPiece redundancy;
};
-struct NET_EXPORT_PRIVATE QuicPacketData {
- std::string data;
-};
-
class NET_EXPORT_PRIVATE QuicData {
public:
QuicData(const char* buffer, size_t length)
@@ -739,8 +735,6 @@ class NET_EXPORT_PRIVATE QuicPacket : public QuicData {
bool is_fec_packet() const { return is_fec_packet_; }
- bool includes_version() const { return includes_version_; }
-
char* mutable_data() { return buffer_; }
private:
diff --git a/net/quic/quic_sent_entropy_manager.h b/net/quic/quic_sent_entropy_manager.h
index 4f684fc..a101e73 100644
--- a/net/quic/quic_sent_entropy_manager.h
+++ b/net/quic/quic_sent_entropy_manager.h
@@ -40,10 +40,6 @@ class NET_EXPORT_PRIVATE QuicSentEntropyManager {
// |sequence_number|.
void ClearEntropyBefore(QuicPacketSequenceNumber sequence_number);
- QuicPacketEntropyHash packets_entropy_hash() const {
- return packets_entropy_hash_;
- }
-
private:
typedef linked_hash_map<QuicPacketSequenceNumber,
std::pair<QuicPacketEntropyHash,
diff --git a/net/quic/quic_session.cc b/net/quic/quic_session.cc
index 5abf305..aa83ab0 100644
--- a/net/quic/quic_session.cc
+++ b/net/quic/quic_session.cc
@@ -190,13 +190,16 @@ void QuicSession::ConnectionClose(QuicErrorCode error, bool from_peer) {
bool QuicSession::OnCanWrite() {
// We latch this here rather than doing a traditional loop, because streams
// may be modifying the list as we loop.
- int remaining_writes = write_blocked_streams_.NumObjects();
+ int remaining_writes = write_blocked_streams_.NumBlockedStreams();
while (!connection_->HasQueuedData() &&
remaining_writes > 0) {
- DCHECK(!write_blocked_streams_.IsEmpty());
- ReliableQuicStream* stream =
- GetStream(write_blocked_streams_.GetNextBlockedObject());
+ DCHECK(write_blocked_streams_.HasWriteBlockedStreams());
+ ReliableQuicStream* stream = NULL;
+ int index = write_blocked_streams_.GetHighestPriorityWriteBlockedList();
+ if (index != -1) {
+ stream = GetStream(write_blocked_streams_.PopFront(index));
+ }
if (stream != NULL) {
// If the stream can't write all bytes, it'll re-add itself to the blocked
// list.
@@ -205,7 +208,7 @@ bool QuicSession::OnCanWrite() {
--remaining_writes;
}
- return write_blocked_streams_.IsEmpty();
+ return !write_blocked_streams_.HasWriteBlockedStreams();
}
QuicConsumedData QuicSession::WriteData(QuicStreamId id,
@@ -393,7 +396,7 @@ size_t QuicSession::GetNumOpenStreams() const {
}
void QuicSession::MarkWriteBlocked(QuicStreamId id) {
- write_blocked_streams_.AddBlockedObject(id);
+ write_blocked_streams_.PushBack(id, 0);
}
void QuicSession::MarkDecompressionBlocked(QuicHeaderId header_id,
diff --git a/net/quic/quic_session.h b/net/quic/quic_session.h
index 24a6deb..75c3ea0 100644
--- a/net/quic/quic_session.h
+++ b/net/quic/quic_session.h
@@ -13,7 +13,6 @@
#include "base/containers/hash_tables.h"
#include "net/base/ip_endpoint.h"
#include "net/base/linked_hash_map.h"
-#include "net/quic/blocked_list.h"
#include "net/quic/quic_connection.h"
#include "net/quic/quic_crypto_stream.h"
#include "net/quic/quic_packet_creator.h"
@@ -21,6 +20,7 @@
#include "net/quic/quic_spdy_compressor.h"
#include "net/quic/quic_spdy_decompressor.h"
#include "net/quic/reliable_quic_stream.h"
+#include "net/spdy/write_blocked_list.h"
namespace net {
@@ -242,7 +242,7 @@ class NET_EXPORT_PRIVATE QuicSession : public QuicConnectionVisitorInterface {
base::hash_set<QuicStreamId> implicitly_created_streams_;
// A list of streams which need to write more data.
- BlockedList<QuicStreamId> write_blocked_streams_;
+ WriteBlockedList<QuicStreamId> write_blocked_streams_;
// A map of headers waiting to be compressed, and the streams
// they are associated with.
diff --git a/net/quic/quic_session_test.cc b/net/quic/quic_session_test.cc
index e417c43..4df7222 100644
--- a/net/quic/quic_session_test.cc
+++ b/net/quic/quic_session_test.cc
@@ -125,11 +125,13 @@ class QuicSessionTest : public ::testing::Test {
QuicGuid guid_;
MockConnection* connection_;
TestSession session_;
- QuicConnectionVisitorInterface* visitor_;
- hash_map<QuicStreamId, ReliableQuicStream*>* streams_;
set<QuicStreamId> closed_streams_;
};
+TEST_F(QuicSessionTest, PeerAddress) {
+ EXPECT_EQ(IPEndPoint(), session_.peer_address());
+}
+
TEST_F(QuicSessionTest, IsCryptoHandshakeConfirmed) {
EXPECT_FALSE(session_.IsCryptoHandshakeConfirmed());
CryptoHandshakeMessage message;
diff --git a/net/quic/quic_stream_sequencer.h b/net/quic/quic_stream_sequencer.h
index fe9fba5..a450bef 100644
--- a/net/quic/quic_stream_sequencer.h
+++ b/net/quic/quic_stream_sequencer.h
@@ -29,8 +29,6 @@ class ReliableQuicStream;
// TOOD(alyssar) add some checks for overflow attempts [1, 256,] [2, 256]
class NET_EXPORT_PRIVATE QuicStreamSequencer {
public:
- static size_t kMaxUdpPacketSize;
-
explicit QuicStreamSequencer(ReliableQuicStream* quic_stream);
QuicStreamSequencer(size_t max_frame_memory,
ReliableQuicStream* quic_stream);
diff --git a/net/quic/quic_stream_sequencer_test.cc b/net/quic/quic_stream_sequencer_test.cc
index 0d40db9..878585b 100644
--- a/net/quic/quic_stream_sequencer_test.cc
+++ b/net/quic/quic_stream_sequencer_test.cc
@@ -58,11 +58,8 @@ class QuicStreamSequencerPeer : public QuicStreamSequencer {
void SetMemoryLimit(size_t limit) {
max_frame_memory_ = limit;
}
-
- const ReliableQuicStream* stream() const { return stream_; }
uint64 num_bytes_consumed() const { return num_bytes_consumed_; }
const FrameMap* frames() const { return &frames_; }
- int32 max_frame_memory() const { return max_frame_memory_; }
QuicStreamOffset close_offset() const { return close_offset_; }
};
diff --git a/net/quic/quic_time_test.cc b/net/quic/quic_time_test.cc
index c4ea0e2..18b1de4 100644
--- a/net/quic/quic_time_test.cc
+++ b/net/quic/quic_time_test.cc
@@ -9,23 +9,19 @@
namespace net {
namespace test {
-class QuicTimeDeltaTest : public ::testing::Test {
- protected:
-};
-
-TEST_F(QuicTimeDeltaTest, Zero) {
+TEST(QuicTimeDeltaTest, Zero) {
EXPECT_TRUE(QuicTime::Delta::Zero().IsZero());
EXPECT_FALSE(QuicTime::Delta::Zero().IsInfinite());
EXPECT_FALSE(QuicTime::Delta::FromMilliseconds(1).IsZero());
}
-TEST_F(QuicTimeDeltaTest, Infinite) {
+TEST(QuicTimeDeltaTest, Infinite) {
EXPECT_TRUE(QuicTime::Delta::Infinite().IsInfinite());
EXPECT_FALSE(QuicTime::Delta::Zero().IsInfinite());
EXPECT_FALSE(QuicTime::Delta::FromMilliseconds(1).IsInfinite());
}
-TEST_F(QuicTimeDeltaTest, FromTo) {
+TEST(QuicTimeDeltaTest, FromTo) {
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(1),
QuicTime::Delta::FromMicroseconds(1000));
EXPECT_EQ(QuicTime::Delta::FromSeconds(1),
@@ -41,17 +37,24 @@ TEST_F(QuicTimeDeltaTest, FromTo) {
QuicTime::Delta::FromSeconds(2).ToMicroseconds());
}
-TEST_F(QuicTimeDeltaTest, Add) {
+TEST(QuicTimeDeltaTest, Add) {
EXPECT_EQ(QuicTime::Delta::FromMicroseconds(2000),
QuicTime::Delta::Zero().Add(QuicTime::Delta::FromMilliseconds(2)));
}
-TEST_F(QuicTimeDeltaTest, Subtract) {
+TEST(QuicTimeDeltaTest, Subtract) {
EXPECT_EQ(QuicTime::Delta::FromMicroseconds(1000),
QuicTime::Delta::FromMilliseconds(2).Subtract(
QuicTime::Delta::FromMilliseconds(1)));
}
+TEST(QuicTimeDeltaTest, NotEqual) {
+ EXPECT_TRUE(QuicTime::Delta::FromSeconds(0) !=
+ QuicTime::Delta::FromSeconds(1));
+ EXPECT_FALSE(QuicTime::Delta::FromSeconds(0) !=
+ QuicTime::Delta::FromSeconds(0));
+}
+
class QuicTimeTest : public ::testing::Test {
protected:
MockClock clock_;
@@ -109,5 +112,14 @@ TEST_F(QuicTimeTest, MockClock) {
EXPECT_EQ(now, time);
}
+TEST_F(QuicTimeTest, LE) {
+ const QuicTime zero = QuicTime::Zero();
+ const QuicTime one = zero.Add(QuicTime::Delta::FromSeconds(1));
+ EXPECT_TRUE(zero <= zero);
+ EXPECT_TRUE(zero <= one);
+ EXPECT_TRUE(one <= one);
+ EXPECT_FALSE(one <= zero);
+}
+
} // namespace test
} // namespace net
diff --git a/net/quic/quic_utils.cc b/net/quic/quic_utils.cc
index 1795744..dc8c667 100644
--- a/net/quic/quic_utils.cc
+++ b/net/quic/quic_utils.cc
@@ -111,14 +111,6 @@ void QuicUtils::SerializeUint128(uint128 v, uint8* out) {
memcpy(out + sizeof(lo), &hi, sizeof(hi));
}
-// static
-uint128 QuicUtils::ParseUint128(const uint8* in) {
- uint64 lo, hi;
- memcpy(&lo, in, sizeof(lo));
- memcpy(&hi, in + sizeof(lo), sizeof(hi));
- return uint128(hi, lo);
-}
-
#define RETURN_STRING_LITERAL(x) \
case x: \
return #x;
diff --git a/net/quic/quic_utils.h b/net/quic/quic_utils.h
index 6650dbf..37eb9d2 100644
--- a/net/quic/quic_utils.h
+++ b/net/quic/quic_utils.h
@@ -46,9 +46,6 @@ class NET_EXPORT_PRIVATE QuicUtils {
// SerializeUint128 writes |v| in little-endian form to |out|.
static void SerializeUint128(uint128 v, uint8* out);
- // ParseUint128 parses a little-endian uint128 from |in| and returns it.
- static uint128 ParseUint128(const uint8* in);
-
// Returns the name of the QuicRstStreamErrorCode as a char*
static const char* StreamErrorToString(QuicRstStreamErrorCode error);
diff --git a/net/quic/reliable_quic_stream.h b/net/quic/reliable_quic_stream.h
index 352325d..166ca61f 100644
--- a/net/quic/reliable_quic_stream.h
+++ b/net/quic/reliable_quic_stream.h
@@ -108,7 +108,6 @@ class NET_EXPORT_PRIVATE ReliableQuicStream : public
const IPEndPoint& GetPeerAddress() const;
- Visitor* visitor() { return visitor_; }
void set_visitor(Visitor* visitor) { visitor_ = visitor; }
QuicSpdyCompressor* compressor();
diff --git a/net/quic/reliable_quic_stream_test.cc b/net/quic/reliable_quic_stream_test.cc
index 7167a22..e8ba52a 100644
--- a/net/quic/reliable_quic_stream_test.cc
+++ b/net/quic/reliable_quic_stream_test.cc
@@ -116,7 +116,7 @@ class ReliableQuicStreamTest : public ::testing::TestWithParam<bool> {
scoped_ptr<QuicSpdyCompressor> compressor_;
scoped_ptr<QuicSpdyDecompressor> decompressor_;
SpdyHeaderBlock headers_;
- BlockedList<QuicStreamId>* write_blocked_list_;
+ WriteBlockedList<QuicStreamId>* write_blocked_list_;
};
TEST_F(ReliableQuicStreamTest, WriteAllData) {
@@ -131,7 +131,7 @@ TEST_F(ReliableQuicStreamTest, WriteAllData) {
EXPECT_CALL(*session_, WriteData(kStreamId, _, _, _)).WillOnce(
Return(QuicConsumedData(kDataLen, true)));
EXPECT_EQ(kDataLen, stream_->WriteData(kData1, false).bytes_consumed);
- EXPECT_TRUE(write_blocked_list_->IsEmpty());
+ EXPECT_FALSE(write_blocked_list_->HasWriteBlockedStreams());
}
// TODO(rtenneti): Death tests crash on OS_ANDROID.
@@ -145,7 +145,7 @@ TEST_F(ReliableQuicStreamTest, NoBlockingIfNoDataOrFin) {
EXPECT_CALL(*session_, WriteData(kStreamId, _, _, _)).WillOnce(
Return(QuicConsumedData(0, false)));
stream_->WriteData(StringPiece(), false);
- EXPECT_TRUE(write_blocked_list_->IsEmpty());
+ EXPECT_FALSE(write_blocked_list_->HasWriteBlockedStreams());
}, "");
}
#endif // GTEST_HAS_DEATH_TEST && !defined(NDEBUG) && !defined(OS_ANDROID)
@@ -158,7 +158,7 @@ TEST_F(ReliableQuicStreamTest, BlockIfOnlySomeDataConsumed) {
EXPECT_CALL(*session_, WriteData(kStreamId, _, _, _)).WillOnce(
Return(QuicConsumedData(1, false)));
stream_->WriteData(StringPiece(kData1, 2), false);
- ASSERT_EQ(1, write_blocked_list_->NumObjects());
+ ASSERT_EQ(1, write_blocked_list_->NumBlockedStreams());
}
@@ -172,7 +172,7 @@ TEST_F(ReliableQuicStreamTest, BlockIfFinNotConsumedWithData) {
EXPECT_CALL(*session_, WriteData(kStreamId, _, _, _)).WillOnce(
Return(QuicConsumedData(2, false)));
stream_->WriteData(StringPiece(kData1, 2), true);
- ASSERT_EQ(1, write_blocked_list_->NumObjects());
+ ASSERT_EQ(1, write_blocked_list_->NumBlockedStreams());
}
TEST_F(ReliableQuicStreamTest, BlockIfSoloFinNotConsumed) {
@@ -183,13 +183,13 @@ TEST_F(ReliableQuicStreamTest, BlockIfSoloFinNotConsumed) {
EXPECT_CALL(*session_, WriteData(kStreamId, _, _, _)).WillOnce(
Return(QuicConsumedData(0, false)));
stream_->WriteData(StringPiece(), true);
- ASSERT_EQ(1, write_blocked_list_->NumObjects());
+ ASSERT_EQ(1, write_blocked_list_->NumBlockedStreams());
}
TEST_F(ReliableQuicStreamTest, WriteData) {
Initialize(kShouldProcessData);
- EXPECT_TRUE(write_blocked_list_->IsEmpty());
+ EXPECT_FALSE(write_blocked_list_->HasWriteBlockedStreams());
connection_->options()->max_packet_length =
1 + QuicPacketCreator::StreamFramePacketOverhead(
connection_->version(), PACKET_8BYTE_GUID, !kIncludeVersion,
@@ -200,7 +200,7 @@ TEST_F(ReliableQuicStreamTest, WriteData) {
Return(QuicConsumedData(kDataLen - 1, false)));
// The return will be kDataLen, because the last byte gets buffered.
EXPECT_EQ(kDataLen, stream_->WriteData(kData1, false).bytes_consumed);
- EXPECT_FALSE(write_blocked_list_->IsEmpty());
+ EXPECT_TRUE(write_blocked_list_->HasWriteBlockedStreams());
// Queue a bytes_consumed write.
EXPECT_EQ(kDataLen, stream_->WriteData(kData2, false).bytes_consumed);
diff --git a/net/quic/test_tools/quic_framer_peer.cc b/net/quic/test_tools/quic_framer_peer.cc
index 5ec52dc..e8d43cd 100644
--- a/net/quic/test_tools/quic_framer_peer.cc
+++ b/net/quic/test_tools/quic_framer_peer.cc
@@ -34,9 +34,5 @@ void QuicFramerPeer::SetIsServer(QuicFramer* framer, bool is_server) {
framer->is_server_ = is_server;
}
-void QuicFramerPeer::SetVersion(QuicFramer* framer, QuicVersion version) {
- framer->quic_version_ = version;
-}
-
} // namespace test
} // namespace net
diff --git a/net/quic/test_tools/quic_framer_peer.h b/net/quic/test_tools/quic_framer_peer.h
index 0508f5c..acb45ec 100644
--- a/net/quic/test_tools/quic_framer_peer.h
+++ b/net/quic/test_tools/quic_framer_peer.h
@@ -24,7 +24,6 @@ class QuicFramerPeer {
QuicFramer* framer,
QuicPacketSequenceNumber packet_sequence_number);
static void SetIsServer(QuicFramer* framer, bool is_server);
- static void SetVersion(QuicFramer* framer, QuicVersion version);
private:
DISALLOW_COPY_AND_ASSIGN(QuicFramerPeer);
diff --git a/net/quic/test_tools/quic_session_peer.cc b/net/quic/test_tools/quic_session_peer.cc
index 66caa15..c25b42f 100644
--- a/net/quic/test_tools/quic_session_peer.cc
+++ b/net/quic/test_tools/quic_session_peer.cc
@@ -22,13 +22,7 @@ void QuicSessionPeer::SetMaxOpenStreams(QuicSession* session,
}
// static
-ReliableQuicStream* QuicSessionPeer::CreateIncomingReliableStream(
- QuicSession* session, QuicStreamId id) {
- return session->CreateIncomingReliableStream(id);
-}
-
-// static
-BlockedList<QuicStreamId>* QuicSessionPeer::GetWriteblockedStreams(
+WriteBlockedList<QuicStreamId>* QuicSessionPeer::GetWriteblockedStreams(
QuicSession* session) {
return &session->write_blocked_streams_;
}
diff --git a/net/quic/test_tools/quic_session_peer.h b/net/quic/test_tools/quic_session_peer.h
index 6f9a8f3..fb4529c 100644
--- a/net/quic/test_tools/quic_session_peer.h
+++ b/net/quic/test_tools/quic_session_peer.h
@@ -5,8 +5,8 @@
#ifndef NET_QUIC_TEST_TOOLS_QUIC_SESSION_PEER_H_
#define NET_QUIC_TEST_TOOLS_QUIC_SESSION_PEER_H_
-#include "net/quic/blocked_list.h"
#include "net/quic/quic_protocol.h"
+#include "net/spdy/write_blocked_list.h"
namespace net {
@@ -19,9 +19,7 @@ class QuicSessionPeer {
public:
static void SetNextStreamId(QuicSession* session, QuicStreamId id);
static void SetMaxOpenStreams(QuicSession* session, uint32 max_streams);
- static ReliableQuicStream* CreateIncomingReliableStream(QuicSession* session,
- QuicStreamId id);
- static BlockedList<QuicStreamId>* GetWriteblockedStreams(
+ static WriteBlockedList<QuicStreamId>* GetWriteblockedStreams(
QuicSession* session);
private:
diff --git a/net/quic/test_tools/quic_test_utils.cc b/net/quic/test_tools/quic_test_utils.cc
index 2562b07..8699473 100644
--- a/net/quic/test_tools/quic_test_utils.cc
+++ b/net/quic/test_tools/quic_test_utils.cc
@@ -356,16 +356,6 @@ void CompareCharArraysWithHexError(
<< HexDumpWithMarks(actual, actual_len, marks.get(), max_len);
}
-void CompareQuicDataWithHexError(
- const string& description,
- QuicData* actual,
- QuicData* expected) {
- CompareCharArraysWithHexError(
- description,
- actual->data(), actual->length(),
- expected->data(), expected->length());
-}
-
static QuicPacket* ConstructPacketFromHandshakeMessage(
QuicGuid guid,
const CryptoHandshakeMessage& message,
diff --git a/net/quic/test_tools/quic_test_utils.h b/net/quic/test_tools/quic_test_utils.h
index 65fba73..b51c785 100644
--- a/net/quic/test_tools/quic_test_utils.h
+++ b/net/quic/test_tools/quic_test_utils.h
@@ -31,10 +31,6 @@ void CompareCharArraysWithHexError(const std::string& description,
const char* expected,
const int expected_len);
-void CompareQuicDataWithHexError(const std::string& description,
- QuicData* actual,
- QuicData* expected);
-
// Returns the length of a QuicPacket that is capable of holding either a
// stream frame or a minimal ack frame. Sets |*payload_length| to the number
// of bytes of stream data that will fit in such a packet.
@@ -47,8 +43,6 @@ size_t GetPacketLengthForOneStream(QuicVersion version,
// offset and the last frame in a packet.
size_t GetMinStreamFrameSize(QuicVersion version);
-string SerializeUncompressedHeaders(const SpdyHeaderBlock& headers);
-
// Returns QuicConfig set to default values.
QuicConfig DefaultQuicConfig();
diff --git a/net/spdy/write_blocked_list.h b/net/spdy/write_blocked_list.h
new file mode 100644
index 0000000..fe5668f
--- /dev/null
+++ b/net/spdy/write_blocked_list.h
@@ -0,0 +1,86 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_SPDY_WRITE_BLOCKED_LIST_H_
+#define NET_SPDY_WRITE_BLOCKED_LIST_H_
+
+#include <algorithm>
+#include <deque>
+
+#include "base/logging.h"
+
+namespace net {
+
+const int kHighestPriority = 0;
+const int kLowestPriority = 7;
+
+template <typename IdType>
+class WriteBlockedList {
+ public:
+ // 0(1) size lookup. 0(1) insert at front or back.
+ typedef std::deque<IdType> BlockedList;
+ typedef typename BlockedList::iterator iterator;
+
+ // Returns the priority of the highest priority list with sessions on it, or
+ // -1 if none of the lists have pending sessions.
+ int GetHighestPriorityWriteBlockedList() const {
+ for (int i = 0; i <= kLowestPriority; ++i) {
+ if (write_blocked_lists_[i].size() > 0)
+ return i;
+ }
+ return -1;
+ }
+
+ int PopFront(int priority) {
+ DCHECK(!write_blocked_lists_[priority].empty());
+ IdType stream_id = write_blocked_lists_[priority].front();
+ write_blocked_lists_[priority].pop_front();
+ return stream_id;
+ }
+
+ bool HasWriteBlockedStreamsGreaterThanPriority(int priority) const {
+ for (int i = kHighestPriority; i < priority; ++i) {
+ if (!write_blocked_lists_[i].empty()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool HasWriteBlockedStreams() const {
+ return HasWriteBlockedStreamsGreaterThanPriority(kLowestPriority + 1);
+ }
+
+ void PushBack(IdType stream_id, int priority) {
+ write_blocked_lists_[priority].push_back(stream_id);
+ }
+
+ void RemoveStreamFromWriteBlockedList(IdType stream_id, int priority) {
+ iterator it = std::find(write_blocked_lists_[priority].begin(),
+ write_blocked_lists_[priority].end(),
+ stream_id);
+ while (it != write_blocked_lists_[priority].end()) {
+ write_blocked_lists_[priority].erase(it);
+ it = std::find(write_blocked_lists_[priority].begin(),
+ write_blocked_lists_[priority].end(),
+ stream_id);
+ }
+ }
+
+ int NumBlockedStreams() {
+ int num_blocked_streams = 0;
+ for (int i = kHighestPriority; i <= kLowestPriority; ++i) {
+ num_blocked_streams += write_blocked_lists_[i].size();
+ }
+ return num_blocked_streams;
+ }
+
+ private:
+ // Priority ranges from 0 to 7
+ BlockedList write_blocked_lists_[8];
+};
+
+} // namespace net
+
+#endif // NET_SPDY_WRITE_BLOCKED_LIST_H_
diff --git a/net/spdy/write_blocked_list_test.cc b/net/spdy/write_blocked_list_test.cc
new file mode 100644
index 0000000..3bb49df
--- /dev/null
+++ b/net/spdy/write_blocked_list_test.cc
@@ -0,0 +1,76 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/spdy/write_blocked_list.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+
+namespace net {
+namespace test {
+namespace {
+
+typedef WriteBlockedList<int> IntWriteBlockedList;
+
+TEST(WriteBlockedListTest, GetHighestPriority) {
+ IntWriteBlockedList list;
+ EXPECT_EQ(-1, list.GetHighestPriorityWriteBlockedList());
+ list.PushBack(1, 1);
+ EXPECT_EQ(1, list.GetHighestPriorityWriteBlockedList());
+ list.PushBack(1, 0);
+ EXPECT_EQ(0, list.GetHighestPriorityWriteBlockedList());
+}
+
+TEST(WriteBlockedListTest, HasWriteBlockedStreamsOfGreaterThanPriority) {
+ IntWriteBlockedList list;
+ list.PushBack(1, 4);
+ EXPECT_TRUE(list.HasWriteBlockedStreamsGreaterThanPriority(5));
+ EXPECT_FALSE(list.HasWriteBlockedStreamsGreaterThanPriority(4));
+ list.PushBack(1, 2);
+ EXPECT_TRUE(list.HasWriteBlockedStreamsGreaterThanPriority(3));
+ EXPECT_FALSE(list.HasWriteBlockedStreamsGreaterThanPriority(2));
+}
+
+TEST(WriteBlockedListTest, RemoveStreamFromWriteBlockedList) {
+ IntWriteBlockedList list;
+
+ list.PushBack(1, 4);
+ EXPECT_TRUE(list.HasWriteBlockedStreams());
+
+ list.RemoveStreamFromWriteBlockedList(1, 5);
+ EXPECT_TRUE(list.HasWriteBlockedStreams());
+
+ list.PushBack(2, 4);
+ list.PushBack(1, 4);
+ list.RemoveStreamFromWriteBlockedList(1, 4);
+ list.RemoveStreamFromWriteBlockedList(2, 4);
+ EXPECT_FALSE(list.HasWriteBlockedStreams());
+
+ list.PushBack(1, 7);
+ EXPECT_TRUE(list.HasWriteBlockedStreams());
+}
+
+TEST(WriteBlockedListTest, PopFront) {
+ IntWriteBlockedList list;
+
+ list.PushBack(1, 4);
+ EXPECT_EQ(1, list.NumBlockedStreams());
+ list.PushBack(2, 4);
+ list.PushBack(1, 4);
+ list.PushBack(3, 4);
+ EXPECT_EQ(4, list.NumBlockedStreams());
+
+ EXPECT_EQ(1, list.PopFront(4));
+ EXPECT_EQ(2, list.PopFront(4));
+ EXPECT_EQ(1, list.PopFront(4));
+ EXPECT_EQ(1, list.NumBlockedStreams());
+ EXPECT_EQ(3, list.PopFront(4));
+}
+
+} // namespace
+} // namespace test
+} // namespace net
+
+
+
diff --git a/net/tools/quic/quic_client.h b/net/tools/quic/quic_client.h
index ca20a8d2..5e89601 100644
--- a/net/tools/quic/quic_client.h
+++ b/net/tools/quic/quic_client.h
@@ -102,8 +102,6 @@ class QuicClient : public EpollCallbackInterface {
bool connected() const;
- int packets_dropped() { return packets_dropped_; }
-
void set_bind_to_address(IPAddressNumber address) {
bind_to_address_ = address;
}
@@ -112,8 +110,6 @@ class QuicClient : public EpollCallbackInterface {
void set_local_port(int local_port) { local_port_ = local_port; }
- int local_port() { return local_port_; }
-
const IPEndPoint& server_address() const { return server_address_; }
const IPEndPoint& client_address() const { return client_address_; }
diff --git a/net/tools/quic/quic_dispatcher.cc b/net/tools/quic/quic_dispatcher.cc
index 68691f7..5253764 100644
--- a/net/tools/quic/quic_dispatcher.cc
+++ b/net/tools/quic/quic_dispatcher.cc
@@ -59,7 +59,7 @@ int QuicDispatcher::WritePacket(const char* buffer, size_t buf_len,
QuicBlockedWriterInterface* writer,
int* error) {
if (write_blocked_) {
- write_blocked_list_.AddBlockedObject(writer);
+ write_blocked_list_.insert(make_pair(writer, true));
*error = EAGAIN;
return -1;
}
@@ -68,7 +68,7 @@ int QuicDispatcher::WritePacket(const char* buffer, size_t buf_len,
self_address, peer_address,
error);
if (rc == -1 && (*error == EWOULDBLOCK || *error == EAGAIN)) {
- write_blocked_list_.AddBlockedObject(writer);
+ write_blocked_list_.insert(make_pair(writer, true));
write_blocked_ = true;
}
return rc;
@@ -114,7 +114,7 @@ void QuicDispatcher::ProcessPacket(const IPEndPoint& server_address,
void QuicDispatcher::CleanUpSession(SessionMap::iterator it) {
QuicSession* session = it->second;
- write_blocked_list_.RemoveBlockedObject(session->connection());
+ write_blocked_list_.erase(session->connection());
time_wait_list_manager_->AddGuidToTimeWait(it->first,
session->connection()->version());
session_map_.erase(it);
@@ -129,13 +129,13 @@ bool QuicDispatcher::OnCanWrite() {
write_blocked_ = false;
// Give each writer one attempt to write.
- int num_writers = write_blocked_list_.NumObjects();
+ int num_writers = write_blocked_list_.size();
for (int i = 0; i < num_writers; ++i) {
- if (write_blocked_list_.IsEmpty()) {
+ if (write_blocked_list_.empty()) {
break;
}
- QuicBlockedWriterInterface* writer =
- write_blocked_list_.GetNextBlockedObject();
+ QuicBlockedWriterInterface* writer = write_blocked_list_.begin()->first;
+ write_blocked_list_.erase(write_blocked_list_.begin());
bool can_write_more = writer->OnCanWrite();
if (write_blocked_) {
// We were unable to write. Wait for the next EPOLLOUT.
@@ -146,12 +146,12 @@ bool QuicDispatcher::OnCanWrite() {
// The socket is not blocked but the writer has ceded work. Add it to the
// end of the list.
if (can_write_more) {
- write_blocked_list_.AddBlockedObject(writer);
+ write_blocked_list_.insert(make_pair(writer, true));
}
}
// We're not write blocked. Return true if there's more work to do.
- return !write_blocked_list_.IsEmpty();
+ return !write_blocked_list_.empty();
}
void QuicDispatcher::Shutdown() {
diff --git a/net/tools/quic/quic_dispatcher.h b/net/tools/quic/quic_dispatcher.h
index bbf8d9b..aea76cb 100644
--- a/net/tools/quic/quic_dispatcher.h
+++ b/net/tools/quic/quic_dispatcher.h
@@ -12,7 +12,7 @@
#include "base/containers/hash_tables.h"
#include "net/base/ip_endpoint.h"
-#include "net/quic/blocked_list.h"
+#include "net/base/linked_hash_map.h"
#include "net/quic/quic_blocked_writer_interface.h"
#include "net/quic/quic_protocol.h"
#include "net/tools/flip_server/epoll_server.h"
@@ -48,7 +48,8 @@ class QuicDispatcherPeer;
class DeleteSessionsAlarm;
class QuicDispatcher : public QuicPacketWriter, public QuicSessionOwner {
public:
- typedef BlockedList<QuicBlockedWriterInterface*> WriteBlockedList;
+ // Ideally we'd have a linked_hash_set: the boolean is unused.
+ typedef linked_hash_map<QuicBlockedWriterInterface*, bool> WriteBlockedList;
// Due to the way delete_sessions_closure_ is registered, the Dispatcher
// must live until epoll_server Shutdown.
@@ -82,7 +83,6 @@ class QuicDispatcher : public QuicPacketWriter, public QuicSessionOwner {
// Ensure that the closed connection is cleaned up asynchronously.
virtual void OnConnectionClose(QuicGuid guid, QuicErrorCode error) OVERRIDE;
- int fd() { return fd_; }
void set_fd(int fd) { fd_ = fd; }
typedef base::hash_map<QuicGuid, QuicSession*> SessionMap;
diff --git a/net/tools/quic/quic_dispatcher_test.cc b/net/tools/quic/quic_dispatcher_test.cc
index 059d833..2e2c309 100644
--- a/net/tools/quic/quic_dispatcher_test.cc
+++ b/net/tools/quic/quic_dispatcher_test.cc
@@ -22,6 +22,7 @@ using base::StringPiece;
using net::EpollServer;
using net::test::MockSession;
using net::tools::test::MockConnection;
+using std::make_pair;
using testing::_;
using testing::DoAll;
using testing::Invoke;
@@ -237,7 +238,7 @@ TEST_F(QuicDispatcherTest, TimeWaitListManager) {
ProcessPacket(addr, guid, "foo");
}
-class WriteBlockedListTest : public QuicDispatcherTest {
+class QuicWriteBlockedListTest : public QuicDispatcherTest {
public:
virtual void SetUp() {
IPEndPoint addr(Loopback4(), 1);
@@ -270,12 +271,12 @@ class WriteBlockedListTest : public QuicDispatcherTest {
QuicDispatcher::WriteBlockedList* blocked_list_;
};
-TEST_F(WriteBlockedListTest, BasicOnCanWrite) {
+TEST_F(QuicWriteBlockedListTest, BasicOnCanWrite) {
// No OnCanWrite calls because no connections are blocked.
dispatcher_.OnCanWrite();
// Register connection 1 for events, and make sure it's nofitied.
- blocked_list_->AddBlockedObject(connection1());
+ blocked_list_->insert(make_pair(connection1(), true));
EXPECT_CALL(*connection1(), OnCanWrite());
dispatcher_.OnCanWrite();
@@ -284,67 +285,67 @@ TEST_F(WriteBlockedListTest, BasicOnCanWrite) {
EXPECT_FALSE(dispatcher_.OnCanWrite());
}
-TEST_F(WriteBlockedListTest, OnCanWriteOrder) {
+TEST_F(QuicWriteBlockedListTest, OnCanWriteOrder) {
// Make sure we handle events in order.
InSequence s;
- blocked_list_->AddBlockedObject(connection1());
- blocked_list_->AddBlockedObject(connection2());
+ blocked_list_->insert(make_pair(connection1(), true));
+ blocked_list_->insert(make_pair(connection2(), true));
EXPECT_CALL(*connection1(), OnCanWrite());
EXPECT_CALL(*connection2(), OnCanWrite());
dispatcher_.OnCanWrite();
// Check the other ordering.
- blocked_list_->AddBlockedObject(connection2());
- blocked_list_->AddBlockedObject(connection1());
+ blocked_list_->insert(make_pair(connection2(), true));
+ blocked_list_->insert(make_pair(connection1(), true));
EXPECT_CALL(*connection2(), OnCanWrite());
EXPECT_CALL(*connection1(), OnCanWrite());
dispatcher_.OnCanWrite();
}
-TEST_F(WriteBlockedListTest, OnCanWriteRemove) {
+TEST_F(QuicWriteBlockedListTest, OnCanWriteRemove) {
// Add and remove one connction.
- blocked_list_->AddBlockedObject(connection1());
- blocked_list_->RemoveBlockedObject(connection1());
+ blocked_list_->insert(make_pair(connection1(), true));
+ blocked_list_->erase(connection1());
EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
dispatcher_.OnCanWrite();
// Add and remove one connction and make sure it doesn't affect others.
- blocked_list_->AddBlockedObject(connection1());
- blocked_list_->AddBlockedObject(connection2());
- blocked_list_->RemoveBlockedObject(connection1());
+ blocked_list_->insert(make_pair(connection1(), true));
+ blocked_list_->insert(make_pair(connection2(), true));
+ blocked_list_->erase(connection1());
EXPECT_CALL(*connection2(), OnCanWrite());
dispatcher_.OnCanWrite();
// Add it, remove it, and add it back and make sure things are OK.
- blocked_list_->AddBlockedObject(connection1());
- blocked_list_->RemoveBlockedObject(connection1());
- blocked_list_->AddBlockedObject(connection1());
+ blocked_list_->insert(make_pair(connection1(), true));
+ blocked_list_->erase(connection1());
+ blocked_list_->insert(make_pair(connection1(), true));
EXPECT_CALL(*connection1(), OnCanWrite()).Times(1);
dispatcher_.OnCanWrite();
}
-TEST_F(WriteBlockedListTest, DoubleAdd) {
+TEST_F(QuicWriteBlockedListTest, DoubleAdd) {
// Make sure a double add does not necessitate a double remove.
- blocked_list_->AddBlockedObject(connection1());
- blocked_list_->AddBlockedObject(connection1());
- blocked_list_->RemoveBlockedObject(connection1());
+ blocked_list_->insert(make_pair(connection1(), true));
+ blocked_list_->insert(make_pair(connection1(), true));
+ blocked_list_->erase(connection1());
EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
dispatcher_.OnCanWrite();
// Make sure a double add does not result in two OnCanWrite calls.
- blocked_list_->AddBlockedObject(connection1());
- blocked_list_->AddBlockedObject(connection1());
+ blocked_list_->insert(make_pair(connection1(), true));
+ blocked_list_->insert(make_pair(connection1(), true));
EXPECT_CALL(*connection1(), OnCanWrite()).Times(1);
dispatcher_.OnCanWrite();
}
-TEST_F(WriteBlockedListTest, OnCanWriteHandleBlock) {
+TEST_F(QuicWriteBlockedListTest, OnCanWriteHandleBlock) {
// Finally make sure if we write block on a write call, we stop calling.
InSequence s;
- blocked_list_->AddBlockedObject(connection1());
- blocked_list_->AddBlockedObject(connection2());
+ blocked_list_->insert(make_pair(connection1(), true));
+ blocked_list_->insert(make_pair(connection2(), true));
EXPECT_CALL(*connection1(), OnCanWrite()).WillOnce(
- Invoke(this, &WriteBlockedListTest::SetBlocked));
+ Invoke(this, &QuicWriteBlockedListTest::SetBlocked));
EXPECT_CALL(*connection2(), OnCanWrite()).Times(0);
dispatcher_.OnCanWrite();
@@ -353,12 +354,12 @@ TEST_F(WriteBlockedListTest, OnCanWriteHandleBlock) {
dispatcher_.OnCanWrite();
}
-TEST_F(WriteBlockedListTest, LimitedWrites) {
+TEST_F(QuicWriteBlockedListTest, LimitedWrites) {
// Make sure we call both writers. The first will register for more writing
// but should not be immediately called due to limits.
InSequence s;
- blocked_list_->AddBlockedObject(connection1());
- blocked_list_->AddBlockedObject(connection2());
+ blocked_list_->insert(make_pair(connection1(), true));
+ blocked_list_->insert(make_pair(connection2(), true));
EXPECT_CALL(*connection1(), OnCanWrite()).WillOnce(Return(true));
EXPECT_CALL(*connection2(), OnCanWrite()).WillOnce(Return(false));
dispatcher_.OnCanWrite();
@@ -368,13 +369,13 @@ TEST_F(WriteBlockedListTest, LimitedWrites) {
dispatcher_.OnCanWrite();
}
-TEST_F(WriteBlockedListTest, TestWriteLimits) {
+TEST_F(QuicWriteBlockedListTest, TestWriteLimits) {
// Finally make sure if we write block on a write call, we stop calling.
InSequence s;
- blocked_list_->AddBlockedObject(connection1());
- blocked_list_->AddBlockedObject(connection2());
+ blocked_list_->insert(make_pair(connection1(), true));
+ blocked_list_->insert(make_pair(connection2(), true));
EXPECT_CALL(*connection1(), OnCanWrite()).WillOnce(
- Invoke(this, &WriteBlockedListTest::SetBlocked));
+ Invoke(this, &QuicWriteBlockedListTest::SetBlocked));
EXPECT_CALL(*connection2(), OnCanWrite()).Times(0);
dispatcher_.OnCanWrite();
diff --git a/net/tools/quic/test_tools/quic_client_peer.cc b/net/tools/quic/test_tools/quic_client_peer.cc
index 8583594..25fdb7e 100644
--- a/net/tools/quic/test_tools/quic_client_peer.cc
+++ b/net/tools/quic/test_tools/quic_client_peer.cc
@@ -11,13 +11,6 @@ namespace tools {
namespace test {
// static
-void QuicClientPeer::Reinitialize(QuicClient* client) {
- client->initialized_ = false;
- client->epoll_server_.UnregisterFD(client->fd_);
- client->Initialize();
-}
-
-// static
int QuicClientPeer::GetFd(QuicClient* client) {
return client->fd_;
}
diff --git a/net/tools/quic/test_tools/quic_client_peer.h b/net/tools/quic/test_tools/quic_client_peer.h
index 8eaa17e..016120a 100644
--- a/net/tools/quic/test_tools/quic_client_peer.h
+++ b/net/tools/quic/test_tools/quic_client_peer.h
@@ -14,7 +14,6 @@ namespace test {
class QuicClientPeer {
public:
- static void Reinitialize(QuicClient* client);
static int GetFd(QuicClient* client);
};
diff --git a/net/tools/quic/test_tools/quic_test_utils.h b/net/tools/quic/test_tools/quic_test_utils.h
index 31ea1815..d18556b 100644
--- a/net/tools/quic/test_tools/quic_test_utils.h
+++ b/net/tools/quic/test_tools/quic_test_utils.h
@@ -22,8 +22,6 @@ class IPEndPoint;
namespace tools {
namespace test {
-std::string SerializeUncompressedHeaders(const SpdyHeaderBlock& headers);
-
class MockConnection : public QuicConnection {
public:
// Uses a QuicConnectionHelper created with fd and eps.