Index: net/quic/core/quic_connection.cc |
diff --git a/net/quic/core/quic_connection.cc b/net/quic/core/quic_connection.cc |
index c93735b80839c2411087bb5f6bf6b2687a5b21ad..dadba8c67c7b3871d8b6459a9da4cd37c3b17408 100644 |
--- a/net/quic/core/quic_connection.cc |
+++ b/net/quic/core/quic_connection.cc |
@@ -210,6 +210,7 @@ QuicConnection::QuicConnection(QuicConnectionId connection_id, |
current_packet_data_(nullptr), |
last_decrypted_packet_level_(ENCRYPTION_NONE), |
should_last_packet_instigate_acks_(false), |
+ was_last_packet_missing_(false), |
largest_seen_packet_with_ack_(0), |
largest_seen_packet_with_stop_waiting_(0), |
max_undecryptable_packets_(0), |
@@ -289,7 +290,9 @@ QuicConnection::QuicConnection(QuicConnectionId connection_id, |
<< "Created connection with connection_id: " << connection_id; |
framer_.set_visitor(this); |
framer_.set_received_entropy_calculator(&received_packet_manager_); |
- last_stop_waiting_frame_.least_unacked = 0; |
+ if (!FLAGS_quic_receive_packet_once_decrypted) { |
+ last_stop_waiting_frame_.least_unacked = 0; |
+ } |
stats_.connection_creation_time = clock_->ApproximateNow(); |
if (FLAGS_quic_enable_multipath) { |
sent_packet_manager_.reset(new QuicMultipathSentPacketManager( |
@@ -661,6 +664,17 @@ bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) { |
--stats_.packets_dropped; |
DVLOG(1) << ENDPOINT << "Received packet header: " << header; |
last_header_ = header; |
+ if (FLAGS_quic_receive_packet_once_decrypted) { |
+ // An ack will be sent if a missing retransmittable packet was received; |
+ was_last_packet_missing_ = |
+ received_packet_manager_.IsMissing(last_header_.packet_number); |
+ |
+ // Record received to populate ack info correctly before processing stream |
+ // frames, since the processing may result in a response packet with a |
+ // bundled ack. |
+ received_packet_manager_.RecordPacketReceived( |
+ last_header_, time_of_last_received_packet_); |
+ } |
DCHECK(connected_); |
return true; |
} |
@@ -778,7 +792,11 @@ bool QuicConnection::OnStopWaitingFrame(const QuicStopWaitingFrame& frame) { |
debug_visitor_->OnStopWaitingFrame(frame); |
} |
- last_stop_waiting_frame_ = frame; |
+ if (FLAGS_quic_receive_packet_once_decrypted) { |
+ ProcessStopWaitingFrame(frame); |
+ } else { |
+ last_stop_waiting_frame_ = frame; |
+ } |
return connected_; |
} |
@@ -986,27 +1004,39 @@ void QuicConnection::OnPacketComplete() { |
DVLOG(1) << ENDPOINT << "Got packet " << last_header_.packet_number << " for " |
<< last_header_.public_header.connection_id; |
- // An ack will be sent if a missing retransmittable packet was received; |
- const bool was_missing = |
- should_last_packet_instigate_acks_ && |
- received_packet_manager_.IsMissing(last_header_.packet_number); |
- |
- // Record received to populate ack info correctly before processing stream |
- // frames, since the processing may result in a response packet with a bundled |
- // ack. |
- received_packet_manager_.RecordPacketReceived(last_size_, last_header_, |
- time_of_last_received_packet_); |
- |
- // Process stop waiting frames here, instead of inline, because the packet |
- // needs to be considered 'received' before the entropy can be updated. |
- if (last_stop_waiting_frame_.least_unacked > 0) { |
- ProcessStopWaitingFrame(last_stop_waiting_frame_); |
- if (!connected_) { |
- return; |
+ if (FLAGS_quic_receive_packet_once_decrypted) { |
+ // An ack will be sent if a missing retransmittable packet was received; |
+ const bool was_missing = |
+ should_last_packet_instigate_acks_ && was_last_packet_missing_; |
+ |
+ // It's possible the ack frame was sent along with response data, so it |
+ // no longer needs to be sent. |
+ if (ack_frame_updated()) { |
+ MaybeQueueAck(was_missing); |
+ } |
+ } else { |
+ // An ack will be sent if a missing retransmittable packet was received; |
+ const bool was_missing = |
+ should_last_packet_instigate_acks_ && |
+ received_packet_manager_.IsMissing(last_header_.packet_number); |
+ |
+ // Record received to populate ack info correctly before processing stream |
+ // frames, since the processing may result in a response packet with a |
+ // bundled ack. |
+ received_packet_manager_.RecordPacketReceived( |
+ last_header_, time_of_last_received_packet_); |
+ |
+ // Process stop waiting frames here, instead of inline, because the packet |
+ // needs to be considered 'received' before the entropy can be updated. |
+ if (last_stop_waiting_frame_.least_unacked > 0) { |
+ ProcessStopWaitingFrame(last_stop_waiting_frame_); |
+ if (!connected_) { |
+ return; |
+ } |
} |
- } |
- MaybeQueueAck(was_missing); |
+ MaybeQueueAck(was_missing); |
+ } |
ClearLastFrames(); |
MaybeCloseIfTooManyOutstandingPackets(); |
@@ -1078,7 +1108,9 @@ void QuicConnection::MaybeQueueAck(bool was_missing) { |
void QuicConnection::ClearLastFrames() { |
should_last_packet_instigate_acks_ = false; |
- last_stop_waiting_frame_.least_unacked = 0; |
+ if (!FLAGS_quic_receive_packet_once_decrypted) { |
+ last_stop_waiting_frame_.least_unacked = 0; |
+ } |
} |
void QuicConnection::MaybeCloseIfTooManyOutstandingPackets() { |
@@ -1712,22 +1744,14 @@ bool QuicConnection::WritePacket(SerializedPacket* packet) { |
} |
if (packet->transmission_type == NOT_RETRANSMISSION) { |
time_of_last_sent_new_packet_ = packet_send_time; |
- if (!FLAGS_quic_better_last_send_for_timeout) { |
- if (IsRetransmittable(*packet) == HAS_RETRANSMITTABLE_DATA && |
- last_send_for_timeout_ <= time_of_last_received_packet_) { |
- last_send_for_timeout_ = packet_send_time; |
- } |
- } |
} |
- if (FLAGS_quic_better_last_send_for_timeout) { |
- // Only adjust the last sent time (for the purpose of tracking the idle |
- // timeout) if this is the first retransmittable packet sent after a |
- // packet is received. If it were updated on every sent packet, then |
- // sending into a black hole might never timeout. |
- if (IsRetransmittable(*packet) == HAS_RETRANSMITTABLE_DATA && |
- last_send_for_timeout_ <= time_of_last_received_packet_) { |
- last_send_for_timeout_ = packet_send_time; |
- } |
+ // Only adjust the last sent time (for the purpose of tracking the idle |
+ // timeout) if this is the first retransmittable packet sent after a |
+ // packet is received. If it were updated on every sent packet, then |
+ // sending into a black hole might never timeout. |
+ if (IsRetransmittable(*packet) == HAS_RETRANSMITTABLE_DATA && |
+ last_send_for_timeout_ <= time_of_last_received_packet_) { |
+ last_send_for_timeout_ = packet_send_time; |
} |
SetPingAlarm(); |
MaybeSetMtuAlarm(); |
@@ -2236,10 +2260,8 @@ void QuicConnection::CheckForTimeout() { |
void QuicConnection::SetTimeoutAlarm() { |
QuicTime time_of_last_packet = |
max(time_of_last_received_packet_, time_of_last_sent_new_packet_); |
- if (FLAGS_quic_better_last_send_for_timeout) { |
- time_of_last_packet = |
- max(time_of_last_received_packet_, last_send_for_timeout_); |
- } |
+ time_of_last_packet = |
+ max(time_of_last_received_packet_, last_send_for_timeout_); |
QuicTime deadline = time_of_last_packet + idle_network_timeout_; |
if (!handshake_timeout_.IsInfinite()) { |