Index: net/quic/core/quic_connection.cc |
diff --git a/net/quic/core/quic_connection.cc b/net/quic/core/quic_connection.cc |
index 7d23d90991239e0c3a727d27da61cd93edf682a5..c39a601770435c6a39d0972a8096fea11cffc412 100644 |
--- a/net/quic/core/quic_connection.cc |
+++ b/net/quic/core/quic_connection.cc |
@@ -690,8 +690,7 @@ bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) { |
// packet. |
if (active_peer_migration_type_ == NO_CHANGE && |
peer_migration_type != NO_CHANGE && |
- (!FLAGS_quic_do_not_migrate_on_old_packet || |
- header.packet_number > received_packet_manager_.GetLargestObserved())) { |
+ header.packet_number > received_packet_manager_.GetLargestObserved()) { |
StartPeerMigration(header.path_id, peer_migration_type); |
} |
@@ -1168,7 +1167,6 @@ void QuicConnection::MaybeSendInResponseToPacket() { |
} |
void QuicConnection::SendVersionNegotiationPacket() { |
- // TODO(alyssar): implement zero server state negotiation. |
pending_version_negotiation_packet_ = true; |
if (writer_->IsWriteBlocked()) { |
visitor_->OnWriteBlocked(); |
@@ -2307,6 +2305,28 @@ QuicConnection::ScopedPacketBundler::~ScopedPacketBundler() { |
if (!already_in_batch_mode_) { |
DVLOG(2) << "Leaving Batch Mode."; |
connection_->packet_generator_.FinishBatchOperations(); |
+ |
+ // Once all transmissions are done, check if there is any outstanding data |
+ // to send and notify the congestion controller if not. |
+ // |
+ // Note that this means that the application limited check will happen as |
+ // soon as the last bundler gets destroyed, which is typically after a |
+ // single stream write is finished. This means that if all the data from a |
+ // single write goes through the connection, the application-limited signal |
+ // will fire even if the caller does a write operation immediately after. |
+ // There are two important approaches to remedy this situation: |
+ // (1) Instantiate ScopedPacketBundler before performing multiple subsequent |
+ // writes, thus deferring this check until all writes are done. |
+ // (2) Write data in chunks sufficiently large so that they cause the |
+ // connection to be limited by the congestion control. Typically, this |
+ // would mean writing chunks larger than the product of the current |
+ // pacing rate and the pacer granularity. So, for instance, if the |
+ // pacing rate of the connection is 1 Gbps, and the pacer granularity is |
+ // 1 ms, the caller should send at least 125k bytes in order to not |
+ // be marked as application-limited. |
+ if (FLAGS_quic_enable_app_limited_check) { |
+ connection_->CheckIfApplicationLimited(); |
+ } |
} |
DCHECK_EQ(already_in_batch_mode_, |
connection_->packet_generator_.InBatchMode()); |
@@ -2523,4 +2543,12 @@ const QuicTime::Delta QuicConnection::DelayedAckTime() { |
min(kMaxDelayedAckTimeMs, kMinRetransmissionTimeMs / 2)); |
} |
+void QuicConnection::CheckIfApplicationLimited() { |
+ if (queued_packets_.empty() && |
+ !sent_packet_manager_->HasPendingRetransmissions() && |
+ !visitor_->WillingAndAbleToWrite()) { |
+ sent_packet_manager_->OnApplicationLimited(); |
+ } |
+} |
+ |
} // namespace net |