Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(180)

Side by Side Diff: net/quic/quic_connection.cc

Issue 1814483002: Change QuicConnection's ScopedPacketBundler to use SEND_QUEUED_ACK instead of NO_ACK, to ensure a q… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@116589902
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/quic/quic_connection.h ('k') | net/quic/quic_session.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/quic/quic_connection.h" 5 #include "net/quic/quic_connection.h"
6 6
7 #include <string.h> 7 #include <string.h>
8 #include <sys/types.h> 8 #include <sys/types.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
(...skipping 1087 matching lines...) Expand 10 before | Expand all | Expand 10 after
1098 // SHLO from the server, leading to two different decrypters at the server.) 1098 // SHLO from the server, leading to two different decrypters at the server.)
1099 // 1099 //
1100 // TODO(jri): Note that ConsumeData may cause a response packet to be sent. 1100 // TODO(jri): Note that ConsumeData may cause a response packet to be sent.
1101 // We may end up sending stale ack information if there are undecryptable 1101 // We may end up sending stale ack information if there are undecryptable
1102 // packets hanging around and/or there are revivable packets which may get 1102 // packets hanging around and/or there are revivable packets which may get
1103 // handled after this packet is sent. Change ScopedPacketBundler to do the 1103 // handled after this packet is sent. Change ScopedPacketBundler to do the
1104 // right thing: check ack_queued_, and then check undecryptable packets and 1104 // right thing: check ack_queued_, and then check undecryptable packets and
1105 // also if there is possibility of revival. Only bundle an ack if there's no 1105 // also if there is possibility of revival. Only bundle an ack if there's no
1106 // processing left that may cause received_info_ to change. 1106 // processing left that may cause received_info_ to change.
1107 ScopedRetransmissionScheduler alarm_delayer(this); 1107 ScopedRetransmissionScheduler alarm_delayer(this);
1108 ScopedPacketBundler ack_bundler(this, BUNDLE_PENDING_ACK); 1108 ScopedPacketBundler ack_bundler(this, SEND_ACK_IF_PENDING);
1109 return packet_generator_.ConsumeData(id, iov, offset, fin, listener); 1109 return packet_generator_.ConsumeData(id, iov, offset, fin, listener);
1110 } 1110 }
1111 1111
1112 void QuicConnection::SendRstStream(QuicStreamId id, 1112 void QuicConnection::SendRstStream(QuicStreamId id,
1113 QuicRstStreamErrorCode error, 1113 QuicRstStreamErrorCode error,
1114 QuicStreamOffset bytes_written) { 1114 QuicStreamOffset bytes_written) {
1115 // Opportunistically bundle an ack with this outgoing packet. 1115 // Opportunistically bundle an ack with this outgoing packet.
1116 ScopedPacketBundler ack_bundler(this, BUNDLE_PENDING_ACK); 1116 ScopedPacketBundler ack_bundler(this, SEND_ACK_IF_PENDING);
1117 packet_generator_.AddControlFrame(QuicFrame(new QuicRstStreamFrame( 1117 packet_generator_.AddControlFrame(QuicFrame(new QuicRstStreamFrame(
1118 id, AdjustErrorForVersion(error, version()), bytes_written))); 1118 id, AdjustErrorForVersion(error, version()), bytes_written)));
1119 1119
1120 if (error == QUIC_STREAM_NO_ERROR && version() > QUIC_VERSION_28) { 1120 if (error == QUIC_STREAM_NO_ERROR && version() > QUIC_VERSION_28) {
1121 // All data for streams which are reset with QUIC_STREAM_NO_ERROR must 1121 // All data for streams which are reset with QUIC_STREAM_NO_ERROR must
1122 // be received by the peer. 1122 // be received by the peer.
1123 return; 1123 return;
1124 } 1124 }
1125 1125
1126 sent_packet_manager_.CancelRetransmissionsForStream(id); 1126 sent_packet_manager_.CancelRetransmissionsForStream(id);
(...skipping 13 matching lines...) Expand all
1140 } 1140 }
1141 delete[] packet_iterator->encrypted_buffer; 1141 delete[] packet_iterator->encrypted_buffer;
1142 QuicUtils::ClearSerializedPacket(&(*packet_iterator)); 1142 QuicUtils::ClearSerializedPacket(&(*packet_iterator));
1143 packet_iterator = queued_packets_.erase(packet_iterator); 1143 packet_iterator = queued_packets_.erase(packet_iterator);
1144 } 1144 }
1145 } 1145 }
1146 1146
1147 void QuicConnection::SendWindowUpdate(QuicStreamId id, 1147 void QuicConnection::SendWindowUpdate(QuicStreamId id,
1148 QuicStreamOffset byte_offset) { 1148 QuicStreamOffset byte_offset) {
1149 // Opportunistically bundle an ack with this outgoing packet. 1149 // Opportunistically bundle an ack with this outgoing packet.
1150 ScopedPacketBundler ack_bundler(this, BUNDLE_PENDING_ACK); 1150 ScopedPacketBundler ack_bundler(this, SEND_ACK_IF_PENDING);
1151 packet_generator_.AddControlFrame( 1151 packet_generator_.AddControlFrame(
1152 QuicFrame(new QuicWindowUpdateFrame(id, byte_offset))); 1152 QuicFrame(new QuicWindowUpdateFrame(id, byte_offset)));
1153 } 1153 }
1154 1154
1155 void QuicConnection::SendBlocked(QuicStreamId id) { 1155 void QuicConnection::SendBlocked(QuicStreamId id) {
1156 // Opportunistically bundle an ack with this outgoing packet. 1156 // Opportunistically bundle an ack with this outgoing packet.
1157 ScopedPacketBundler ack_bundler(this, BUNDLE_PENDING_ACK); 1157 ScopedPacketBundler ack_bundler(this, SEND_ACK_IF_PENDING);
1158 packet_generator_.AddControlFrame(QuicFrame(new QuicBlockedFrame(id))); 1158 packet_generator_.AddControlFrame(QuicFrame(new QuicBlockedFrame(id)));
1159 } 1159 }
1160 1160
1161 void QuicConnection::SendPathClose(QuicPathId path_id) { 1161 void QuicConnection::SendPathClose(QuicPathId path_id) {
1162 // Opportunistically bundle an ack with this outgoing packet. 1162 // Opportunistically bundle an ack with this outgoing packet.
1163 ScopedPacketBundler ack_bundler(this, BUNDLE_PENDING_ACK); 1163 ScopedPacketBundler ack_bundler(this, SEND_ACK_IF_PENDING);
1164 packet_generator_.AddControlFrame(QuicFrame(new QuicPathCloseFrame(path_id))); 1164 packet_generator_.AddControlFrame(QuicFrame(new QuicPathCloseFrame(path_id)));
1165 OnPathClosed(path_id); 1165 OnPathClosed(path_id);
1166 } 1166 }
1167 1167
1168 const QuicConnectionStats& QuicConnection::GetStats() { 1168 const QuicConnectionStats& QuicConnection::GetStats() {
1169 const RttStats* rtt_stats = sent_packet_manager_.GetRttStats(); 1169 const RttStats* rtt_stats = sent_packet_manager_.GetRttStats();
1170 1170
1171 // Update rtt and estimated bandwidth. 1171 // Update rtt and estimated bandwidth.
1172 QuicTime::Delta min_rtt = rtt_stats->min_rtt(); 1172 QuicTime::Delta min_rtt = rtt_stats->min_rtt();
1173 if (min_rtt.IsZero()) { 1173 if (min_rtt.IsZero()) {
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1278 WritePendingRetransmissions(); 1278 WritePendingRetransmissions();
1279 1279
1280 // Sending queued packets may have caused the socket to become write blocked, 1280 // Sending queued packets may have caused the socket to become write blocked,
1281 // or the congestion manager to prohibit sending. If we've sent everything 1281 // or the congestion manager to prohibit sending. If we've sent everything
1282 // we had queued and we're still not blocked, let the visitor know it can 1282 // we had queued and we're still not blocked, let the visitor know it can
1283 // write more. 1283 // write more.
1284 if (!CanWrite(HAS_RETRANSMITTABLE_DATA)) { 1284 if (!CanWrite(HAS_RETRANSMITTABLE_DATA)) {
1285 return; 1285 return;
1286 } 1286 }
1287 1287
1288 { // Limit the scope of the bundler. ACK inclusion happens elsewhere. 1288 {
1289 ScopedPacketBundler bundler(this, NO_ACK); 1289 ScopedPacketBundler bundler(this, SEND_ACK_IF_QUEUED);
1290 visitor_->OnCanWrite(); 1290 visitor_->OnCanWrite();
1291 visitor_->PostProcessAfterData(); 1291 visitor_->PostProcessAfterData();
1292 } 1292 }
1293 1293
1294 // After the visitor writes, it may have caused the socket to become write 1294 // After the visitor writes, it may have caused the socket to become write
1295 // blocked or the congestion manager to prohibit sending, so check again. 1295 // blocked or the congestion manager to prohibit sending, so check again.
1296 if (visitor_->WillingAndAbleToWrite() && !resume_writes_alarm_->IsSet() && 1296 if (visitor_->WillingAndAbleToWrite() && !resume_writes_alarm_->IsSet() &&
1297 CanWrite(HAS_RETRANSMITTABLE_DATA)) { 1297 CanWrite(HAS_RETRANSMITTABLE_DATA)) {
1298 // We're not write blocked, but some stream didn't write out all of its 1298 // We're not write blocked, but some stream didn't write out all of its
1299 // bytes. Register for 'immediate' resumption so we'll keep writing after 1299 // bytes. Register for 'immediate' resumption so we'll keep writing after
1300 // other connections and events have had a chance to use the thread. 1300 // other connections and events have had a chance to use the thread.
1301 resume_writes_alarm_->Set(clock_->ApproximateNow()); 1301 resume_writes_alarm_->Set(clock_->ApproximateNow());
1302 } 1302 }
1303 } 1303 }
1304 1304
1305 void QuicConnection::WriteIfNotBlocked() { 1305 void QuicConnection::WriteIfNotBlocked() {
1306 if (!writer_->IsWriteBlocked()) { 1306 if (!writer_->IsWriteBlocked()) {
1307 OnCanWrite(); 1307 OnCanWrite();
1308 } 1308 }
1309 } 1309 }
1310 1310
1311 void QuicConnection::WriteAndBundleAcksIfNotBlocked() { 1311 void QuicConnection::WriteAndBundleAcksIfNotBlocked() {
1312 if (!writer_->IsWriteBlocked()) { 1312 if (!writer_->IsWriteBlocked()) {
1313 ScopedPacketBundler bundler(this, ack_queued_ ? SEND_ACK : NO_ACK); 1313 ScopedPacketBundler bundler(this, SEND_ACK_IF_QUEUED);
1314 OnCanWrite(); 1314 OnCanWrite();
1315 } 1315 }
1316 } 1316 }
1317 1317
1318 bool QuicConnection::ProcessValidatedPacket(const QuicPacketHeader& header) { 1318 bool QuicConnection::ProcessValidatedPacket(const QuicPacketHeader& header) {
1319 if (header.fec_flag) { 1319 if (header.fec_flag) {
1320 // Drop any FEC packet. 1320 // Drop any FEC packet.
1321 return false; 1321 return false;
1322 } 1322 }
1323 1323
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after
1753 } 1753 }
1754 } 1754 }
1755 1755
1756 void QuicConnection::OnPingTimeout() { 1756 void QuicConnection::OnPingTimeout() {
1757 if (!retransmission_alarm_->IsSet()) { 1757 if (!retransmission_alarm_->IsSet()) {
1758 SendPing(); 1758 SendPing();
1759 } 1759 }
1760 } 1760 }
1761 1761
1762 void QuicConnection::SendPing() { 1762 void QuicConnection::SendPing() {
1763 ScopedPacketBundler bundler(this, ack_queued_ ? SEND_ACK : NO_ACK); 1763 ScopedPacketBundler bundler(this, SEND_ACK_IF_QUEUED);
1764 packet_generator_.AddControlFrame(QuicFrame(QuicPingFrame())); 1764 packet_generator_.AddControlFrame(QuicFrame(QuicPingFrame()));
1765 // Send PING frame immediately, without checking for congestion window bounds. 1765 // Send PING frame immediately, without checking for congestion window bounds.
1766 packet_generator_.FlushAllQueuedFrames(); 1766 packet_generator_.FlushAllQueuedFrames();
1767 } 1767 }
1768 1768
1769 void QuicConnection::SendAck() { 1769 void QuicConnection::SendAck() {
1770 ack_alarm_->Cancel(); 1770 ack_alarm_->Cancel();
1771 ack_queued_ = false; 1771 ack_queued_ = false;
1772 stop_waiting_count_ = 0; 1772 stop_waiting_count_ = 0;
1773 num_retransmittable_packets_received_since_last_ack_sent_ = 0; 1773 num_retransmittable_packets_received_since_last_ack_sent_ = 0;
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
1949 const string& reason) { 1949 const string& reason) {
1950 if (goaway_sent_) { 1950 if (goaway_sent_) {
1951 return; 1951 return;
1952 } 1952 }
1953 goaway_sent_ = true; 1953 goaway_sent_ = true;
1954 1954
1955 DVLOG(1) << ENDPOINT << "Going away with error " 1955 DVLOG(1) << ENDPOINT << "Going away with error "
1956 << QuicUtils::ErrorToString(error) << " (" << error << ")"; 1956 << QuicUtils::ErrorToString(error) << " (" << error << ")";
1957 1957
1958 // Opportunistically bundle an ack with this outgoing packet. 1958 // Opportunistically bundle an ack with this outgoing packet.
1959 ScopedPacketBundler ack_bundler(this, BUNDLE_PENDING_ACK); 1959 ScopedPacketBundler ack_bundler(this, SEND_ACK_IF_PENDING);
1960 packet_generator_.AddControlFrame( 1960 packet_generator_.AddControlFrame(
1961 QuicFrame(new QuicGoAwayFrame(error, last_good_stream_id, reason))); 1961 QuicFrame(new QuicGoAwayFrame(error, last_good_stream_id, reason)));
1962 } 1962 }
1963 1963
1964 QuicByteCount QuicConnection::max_packet_length() const { 1964 QuicByteCount QuicConnection::max_packet_length() const {
1965 return packet_generator_.GetCurrentMaxPacketLength(); 1965 return packet_generator_.GetCurrentMaxPacketLength();
1966 } 1966 }
1967 1967
1968 void QuicConnection::SetMaxPacketLength(QuicByteCount length) { 1968 void QuicConnection::SetMaxPacketLength(QuicByteCount length) {
1969 return packet_generator_.SetMaxPacketLength(LimitMaxPacketSize(length)); 1969 return packet_generator_.SetMaxPacketLength(LimitMaxPacketSize(length));
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
2114 2114
2115 if (packet_number_of_last_sent_packet_ >= next_mtu_probe_at_) { 2115 if (packet_number_of_last_sent_packet_ >= next_mtu_probe_at_) {
2116 // Use an alarm to send the MTU probe to ensure that no ScopedPacketBundlers 2116 // Use an alarm to send the MTU probe to ensure that no ScopedPacketBundlers
2117 // are active. 2117 // are active.
2118 mtu_discovery_alarm_->Set(clock_->ApproximateNow()); 2118 mtu_discovery_alarm_->Set(clock_->ApproximateNow());
2119 } 2119 }
2120 } 2120 }
2121 2121
2122 QuicConnection::ScopedPacketBundler::ScopedPacketBundler( 2122 QuicConnection::ScopedPacketBundler::ScopedPacketBundler(
2123 QuicConnection* connection, 2123 QuicConnection* connection,
2124 AckBundling send_ack) 2124 AckBundling ack_mode)
2125 : connection_(connection), 2125 : connection_(connection),
2126 already_in_batch_mode_(connection != nullptr && 2126 already_in_batch_mode_(connection != nullptr &&
2127 connection->packet_generator_.InBatchMode()) { 2127 connection->packet_generator_.InBatchMode()) {
2128 if (connection_ == nullptr) { 2128 if (connection_ == nullptr) {
2129 return; 2129 return;
2130 } 2130 }
2131 // Move generator into batch mode. If caller wants us to include an ack, 2131 // Move generator into batch mode. If caller wants us to include an ack,
2132 // check the delayed-ack timer to see if there's ack info to be sent. 2132 // check the delayed-ack timer to see if there's ack info to be sent.
2133 if (!already_in_batch_mode_) { 2133 if (!already_in_batch_mode_) {
2134 DVLOG(1) << "Entering Batch Mode."; 2134 DVLOG(1) << "Entering Batch Mode.";
2135 connection_->packet_generator_.StartBatchOperations(); 2135 connection_->packet_generator_.StartBatchOperations();
2136 } 2136 }
2137 // Bundle an ack if the alarm is set or with every second packet if we need to 2137 if (ShouldSendAck(ack_mode)) {
2138 // raise the peer's least unacked.
2139 bool ack_pending =
2140 connection_->ack_alarm_->IsSet() || connection_->stop_waiting_count_ > 1;
2141 if (send_ack == SEND_ACK || (send_ack == BUNDLE_PENDING_ACK && ack_pending)) {
2142 DVLOG(1) << "Bundling ack with outgoing packet."; 2138 DVLOG(1) << "Bundling ack with outgoing packet.";
2143 DCHECK(send_ack == SEND_ACK || connection_->ack_frame_updated() || 2139 DCHECK(ack_mode == SEND_ACK || connection_->ack_frame_updated() ||
2144 connection_->stop_waiting_count_ > 1); 2140 connection_->stop_waiting_count_ > 1);
2145 connection_->SendAck(); 2141 connection_->SendAck();
2146 } 2142 }
2147 } 2143 }
2148 2144
2145 bool QuicConnection::ScopedPacketBundler::ShouldSendAck(
2146 AckBundling ack_mode) const {
2147 switch (ack_mode) {
2148 case SEND_ACK:
2149 return true;
2150 case SEND_ACK_IF_QUEUED:
2151 return connection_->ack_queued();
2152 case SEND_ACK_IF_PENDING:
2153 return connection_->ack_alarm_->IsSet() ||
2154 connection_->stop_waiting_count_ > 1;
2155 }
2156 }
2157
2149 QuicConnection::ScopedPacketBundler::~ScopedPacketBundler() { 2158 QuicConnection::ScopedPacketBundler::~ScopedPacketBundler() {
2150 if (connection_ == nullptr) { 2159 if (connection_ == nullptr) {
2151 return; 2160 return;
2152 } 2161 }
2153 // If we changed the generator's batch state, restore original batch state. 2162 // If we changed the generator's batch state, restore original batch state.
2154 if (!already_in_batch_mode_) { 2163 if (!already_in_batch_mode_) {
2155 DVLOG(1) << "Leaving Batch Mode."; 2164 DVLOG(1) << "Leaving Batch Mode.";
2156 connection_->packet_generator_.FinishBatchOperations(); 2165 connection_->packet_generator_.FinishBatchOperations();
2157 } 2166 }
2158 DCHECK_EQ(already_in_batch_mode_, 2167 DCHECK_EQ(already_in_batch_mode_,
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
2327 } 2336 }
2328 2337
2329 StringPiece QuicConnection::GetCurrentPacket() { 2338 StringPiece QuicConnection::GetCurrentPacket() {
2330 if (current_packet_data_ == nullptr) { 2339 if (current_packet_data_ == nullptr) {
2331 return StringPiece(); 2340 return StringPiece();
2332 } 2341 }
2333 return StringPiece(current_packet_data_, last_size_); 2342 return StringPiece(current_packet_data_, last_size_);
2334 } 2343 }
2335 2344
2336 } // namespace net 2345 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/quic_connection.h ('k') | net/quic/quic_session.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698