| Index: net/quic/quic_connection.cc
|
| diff --git a/net/quic/quic_connection.cc b/net/quic/quic_connection.cc
|
| index 75dfd19ace6520127dec0dd88d08d77941afe267..c5035985ea0501be28eb7e7703e81536a82857f2 100644
|
| --- a/net/quic/quic_connection.cc
|
| +++ b/net/quic/quic_connection.cc
|
| @@ -179,6 +179,7 @@ QuicConnection::QuicConnection(QuicGuid guid,
|
| guid_(guid),
|
| peer_address_(address),
|
| largest_seen_packet_with_ack_(0),
|
| + largest_seen_packet_with_stop_waiting_(0),
|
| pending_version_negotiation_packet_(false),
|
| received_packet_manager_(kTCP),
|
| ack_queued_(false),
|
| @@ -262,7 +263,8 @@ void QuicConnection::OnPacket() {
|
| last_window_update_frames_.empty() &&
|
| last_rst_frames_.empty() &&
|
| last_ack_frames_.empty() &&
|
| - last_congestion_frames_.empty());
|
| + last_congestion_frames_.empty() &&
|
| + last_stop_waiting_frames_.empty());
|
| }
|
|
|
| void QuicConnection::OnPublicResetPacket(
|
| @@ -493,13 +495,11 @@ bool QuicConnection::OnAckFrame(const QuicAckFrame& incoming_ack) {
|
|
|
| void QuicConnection::ProcessAckFrame(const QuicAckFrame& incoming_ack) {
|
| largest_seen_packet_with_ack_ = last_header_.packet_sequence_number;
|
| -
|
| received_packet_manager_.UpdatePacketInformationReceivedByPeer(
|
| incoming_ack.received_info);
|
| - received_packet_manager_.UpdatePacketInformationSentByPeer(
|
| - incoming_ack.sent_info);
|
| - // Possibly close any FecGroups which are now irrelevant.
|
| - CloseFecGroupsBefore(incoming_ack.sent_info.least_unacked + 1);
|
| + if (version() <= QUIC_VERSION_15) {
|
| + ProcessStopWaitingFrame(incoming_ack.sent_info);
|
| + }
|
|
|
| sent_entropy_manager_.ClearEntropyBefore(
|
| received_packet_manager_.least_packet_awaited_by_peer() - 1);
|
| @@ -521,6 +521,14 @@ void QuicConnection::ProcessAckFrame(const QuicAckFrame& incoming_ack) {
|
| }
|
| }
|
|
|
| +void QuicConnection::ProcessStopWaitingFrame(
|
| + const QuicStopWaitingFrame& stop_waiting) {
|
| + largest_seen_packet_with_stop_waiting_ = last_header_.packet_sequence_number;
|
| + received_packet_manager_.UpdatePacketInformationSentByPeer(stop_waiting);
|
| + // Possibly close any FecGroups which are now irrelevant.
|
| + CloseFecGroupsBefore(stop_waiting.least_unacked + 1);
|
| +}
|
| +
|
| bool QuicConnection::OnCongestionFeedbackFrame(
|
| const QuicCongestionFeedbackFrame& feedback) {
|
| DCHECK(connected_);
|
| @@ -531,6 +539,28 @@ bool QuicConnection::OnCongestionFeedbackFrame(
|
| return connected_;
|
| }
|
|
|
| +bool QuicConnection::OnStopWaitingFrame(const QuicStopWaitingFrame& frame) {
|
| + DCHECK(connected_);
|
| +
|
| + if (last_header_.packet_sequence_number <=
|
| + largest_seen_packet_with_stop_waiting_) {
|
| + DVLOG(1) << ENDPOINT << "Received an old stop waiting frame: ignoring";
|
| + return true;
|
| + }
|
| +
|
| + if (!ValidateStopWaitingFrame(frame)) {
|
| + SendConnectionClose(QUIC_INVALID_STOP_WAITING_DATA);
|
| + return false;
|
| + }
|
| +
|
| + if (debug_visitor_) {
|
| + debug_visitor_->OnStopWaitingFrame(frame);
|
| + }
|
| +
|
| + last_stop_waiting_frames_.push_back(frame);
|
| + return connected_;
|
| +}
|
| +
|
| bool QuicConnection::ValidateAckFrame(const QuicAckFrame& incoming_ack) {
|
| if (incoming_ack.received_info.largest_observed >
|
| packet_creator_.sequence_number()) {
|
| @@ -551,22 +581,10 @@ bool QuicConnection::ValidateAckFrame(const QuicAckFrame& incoming_ack) {
|
| return false;
|
| }
|
|
|
| - if (incoming_ack.sent_info.least_unacked <
|
| - received_packet_manager_.peer_least_packet_awaiting_ack()) {
|
| - DLOG(ERROR) << ENDPOINT << "Peer's sent low least_unacked: "
|
| - << incoming_ack.sent_info.least_unacked << " vs "
|
| - << received_packet_manager_.peer_least_packet_awaiting_ack();
|
| - // We never process old ack frames, so this number should only increase.
|
| - return false;
|
| - }
|
| -
|
| - if (incoming_ack.sent_info.least_unacked >
|
| - last_header_.packet_sequence_number) {
|
| - DLOG(ERROR) << ENDPOINT << "Peer sent least_unacked:"
|
| - << incoming_ack.sent_info.least_unacked
|
| - << " greater than the enclosing packet sequence number:"
|
| - << last_header_.packet_sequence_number;
|
| - return false;
|
| + if (version() <= QUIC_VERSION_15) {
|
| + if (!ValidateStopWaitingFrame(incoming_ack.sent_info)) {
|
| + return false;
|
| + }
|
| }
|
|
|
| if (!incoming_ack.received_info.missing_packets.empty() &&
|
| @@ -609,6 +627,29 @@ bool QuicConnection::ValidateAckFrame(const QuicAckFrame& incoming_ack) {
|
| return true;
|
| }
|
|
|
| +bool QuicConnection::ValidateStopWaitingFrame(
|
| + const QuicStopWaitingFrame& stop_waiting) {
|
| + if (stop_waiting.least_unacked <
|
| + received_packet_manager_.peer_least_packet_awaiting_ack()) {
|
| + DLOG(ERROR) << ENDPOINT << "Peer's sent low least_unacked: "
|
| + << stop_waiting.least_unacked << " vs "
|
| + << received_packet_manager_.peer_least_packet_awaiting_ack();
|
| + // We never process old ack frames, so this number should only increase.
|
| + return false;
|
| + }
|
| +
|
| + if (stop_waiting.least_unacked >
|
| + last_header_.packet_sequence_number) {
|
| + DLOG(ERROR) << ENDPOINT << "Peer sent least_unacked:"
|
| + << stop_waiting.least_unacked
|
| + << " greater than the enclosing packet sequence number:"
|
| + << last_header_.packet_sequence_number;
|
| + return false;
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| void QuicConnection::OnFecData(const QuicFecData& fec) {
|
| DCHECK_EQ(IN_FEC_GROUP, last_header_.is_in_fec_group);
|
| DCHECK_NE(0u, last_header_.fec_group);
|
| @@ -678,9 +719,12 @@ void QuicConnection::OnPacketComplete() {
|
| << " packet " << last_header_.packet_sequence_number
|
| << " with " << last_ack_frames_.size() << " acks, "
|
| << last_congestion_frames_.size() << " congestions, "
|
| + << last_stop_waiting_frames_.size() << " stop_waiting, "
|
| << last_goaway_frames_.size() << " goaways, "
|
| << last_window_update_frames_.size() << " window updates, "
|
| << last_rst_frames_.size() << " rsts, "
|
| + << last_blocked_frames_.size() << " blocked, "
|
| + << last_rst_frames_.size() << " rsts, "
|
| << last_close_frames_.size() << " closes, "
|
| << last_stream_frames_.size()
|
| << " stream frames for " << last_header_.public_header.guid;
|
| @@ -726,6 +770,9 @@ void QuicConnection::OnPacketComplete() {
|
| sent_packet_manager_.OnIncomingQuicCongestionFeedbackFrame(
|
| last_congestion_frames_[i], time_of_last_received_packet_);
|
| }
|
| + for (size_t i = 0; i < last_stop_waiting_frames_.size(); ++i) {
|
| + ProcessStopWaitingFrame(last_stop_waiting_frames_[i]);
|
| + }
|
| if (!last_close_frames_.empty()) {
|
| CloseConnection(last_close_frames_[0].error_code, true);
|
| DCHECK(!connected_);
|
| @@ -768,6 +815,7 @@ void QuicConnection::ClearLastFrames() {
|
| last_window_update_frames_.clear();
|
| last_rst_frames_.clear();
|
| last_ack_frames_.clear();
|
| + last_stop_waiting_frames_.clear();
|
| last_congestion_frames_.clear();
|
| }
|
|
|
| @@ -775,7 +823,7 @@ QuicAckFrame* QuicConnection::CreateAckFrame() {
|
| QuicAckFrame* outgoing_ack = new QuicAckFrame();
|
| received_packet_manager_.UpdateReceivedPacketInfo(
|
| &(outgoing_ack->received_info), clock_->ApproximateNow());
|
| - UpdateSentPacketInfo(&(outgoing_ack->sent_info));
|
| + UpdateStopWaiting(&(outgoing_ack->sent_info));
|
| DVLOG(1) << ENDPOINT << "Creating ack frame: " << *outgoing_ack;
|
| return outgoing_ack;
|
| }
|
| @@ -784,6 +832,12 @@ QuicCongestionFeedbackFrame* QuicConnection::CreateFeedbackFrame() {
|
| return new QuicCongestionFeedbackFrame(outgoing_congestion_feedback_);
|
| }
|
|
|
| +QuicStopWaitingFrame* QuicConnection::CreateStopWaitingFrame() {
|
| + QuicStopWaitingFrame stop_waiting;
|
| + UpdateStopWaiting(&stop_waiting);
|
| + return new QuicStopWaitingFrame(stop_waiting);
|
| +}
|
| +
|
| bool QuicConnection::ShouldLastPacketInstigateAck() const {
|
| if (!last_stream_frames_.empty() ||
|
| !last_goaway_frames_.empty() ||
|
| @@ -795,7 +849,6 @@ bool QuicConnection::ShouldLastPacketInstigateAck() const {
|
| last_ack_frames_.back().received_info.is_truncated) {
|
| return true;
|
| }
|
| -
|
| return false;
|
| }
|
|
|
| @@ -1381,10 +1434,10 @@ bool QuicConnection::SendOrQueuePacket(EncryptionLevel level,
|
| return false;
|
| }
|
|
|
| -void QuicConnection::UpdateSentPacketInfo(SentPacketInfo* sent_info) {
|
| - sent_info->least_unacked = GetLeastUnacked();
|
| - sent_info->entropy_hash = sent_entropy_manager_.EntropyHash(
|
| - sent_info->least_unacked - 1);
|
| +void QuicConnection::UpdateStopWaiting(QuicStopWaitingFrame* stop_waiting) {
|
| + stop_waiting->least_unacked = GetLeastUnacked();
|
| + stop_waiting->entropy_hash = sent_entropy_manager_.EntropyHash(
|
| + stop_waiting->least_unacked - 1);
|
| }
|
|
|
| void QuicConnection::SendAck() {
|
| @@ -1401,7 +1454,8 @@ void QuicConnection::SendAck() {
|
| send_feedback = true;
|
| }
|
|
|
| - packet_generator_.SetShouldSendAck(send_feedback);
|
| + packet_generator_.SetShouldSendAck(send_feedback,
|
| + version() > QUIC_VERSION_15);
|
| }
|
|
|
| void QuicConnection::OnRetransmissionTimeout() {
|
|
|