| Index: net/quic/quic_connection.cc
|
| diff --git a/net/quic/quic_connection.cc b/net/quic/quic_connection.cc
|
| index b2a27d96e19ffde5a758763c5b18a5844d1aa310..332918fdb675c7c9dc9c215c12789860e0783fcc 100644
|
| --- a/net/quic/quic_connection.cc
|
| +++ b/net/quic/quic_connection.cc
|
| @@ -305,6 +305,7 @@ QuicConnection::QuicConnection(QuicConnectionId connection_id,
|
| packet_number_of_last_sent_packet_(0),
|
| sent_packet_manager_(
|
| perspective,
|
| + kDefaultPathId,
|
| clock_,
|
| &stats_,
|
| FLAGS_quic_use_bbr_congestion_control ? kBBR : kCubic,
|
| @@ -614,7 +615,8 @@ bool QuicConnection::OnUnauthenticatedHeader(const QuicPacketHeader& header) {
|
|
|
| // If this packet has already been seen, or the sender has told us that it
|
| // will not be retransmitted, then stop processing the packet.
|
| - if (!received_packet_manager_.IsAwaitingPacket(header.packet_number)) {
|
| + if (FLAGS_quic_drop_non_awaited_packets &&
|
| + !received_packet_manager_.IsAwaitingPacket(header.packet_number)) {
|
| DVLOG(1) << ENDPOINT << "Packet " << header.packet_number
|
| << " no longer being waited for. Discarding.";
|
| if (debug_visitor_ != nullptr) {
|
| @@ -675,7 +677,8 @@ bool QuicConnection::OnStreamFrame(const QuicStreamFrame& frame) {
|
| last_decrypted_packet_level_ == ENCRYPTION_NONE) {
|
| DLOG(WARNING) << ENDPOINT
|
| << "Received an unencrypted data frame: closing connection";
|
| - SendConnectionClose(QUIC_UNENCRYPTED_STREAM_DATA);
|
| + SendConnectionCloseWithDetails(QUIC_UNENCRYPTED_STREAM_DATA,
|
| + "Unencrypted stream data seen");
|
| return false;
|
| }
|
| visitor_->OnStreamFrame(frame);
|
| @@ -696,8 +699,9 @@ bool QuicConnection::OnAckFrame(const QuicAckFrame& incoming_ack) {
|
| return true;
|
| }
|
|
|
| - if (!ValidateAckFrame(incoming_ack)) {
|
| - SendConnectionClose(QUIC_INVALID_ACK_DATA);
|
| + const char* error = ValidateAckFrame(incoming_ack);
|
| + if (error != nullptr) {
|
| + SendConnectionCloseWithDetails(QUIC_INVALID_ACK_DATA, error);
|
| return false;
|
| }
|
|
|
| @@ -748,8 +752,9 @@ bool QuicConnection::OnStopWaitingFrame(const QuicStopWaitingFrame& frame) {
|
| return true;
|
| }
|
|
|
| - if (!ValidateStopWaitingFrame(frame)) {
|
| - SendConnectionClose(QUIC_INVALID_STOP_WAITING_DATA);
|
| + const char* error = ValidateStopWaitingFrame(frame);
|
| + if (error != nullptr) {
|
| + SendConnectionCloseWithDetails(QUIC_INVALID_STOP_WAITING_DATA, error);
|
| return false;
|
| }
|
|
|
| @@ -770,13 +775,13 @@ bool QuicConnection::OnPingFrame(const QuicPingFrame& frame) {
|
| return true;
|
| }
|
|
|
| -bool QuicConnection::ValidateAckFrame(const QuicAckFrame& incoming_ack) {
|
| +const char* QuicConnection::ValidateAckFrame(const QuicAckFrame& incoming_ack) {
|
| if (incoming_ack.largest_observed > packet_generator_.packet_number()) {
|
| LOG(WARNING) << ENDPOINT << "Peer's observed unsent packet:"
|
| << incoming_ack.largest_observed << " vs "
|
| << packet_generator_.packet_number();
|
| // We got an error for data we have not sent. Error out.
|
| - return false;
|
| + return "Largest observed too high";
|
| }
|
|
|
| if (incoming_ack.largest_observed < sent_packet_manager_.largest_observed()) {
|
| @@ -785,7 +790,7 @@ bool QuicConnection::ValidateAckFrame(const QuicAckFrame& incoming_ack) {
|
| << sent_packet_manager_.largest_observed();
|
| // A new ack has a diminished largest_observed value. Error out.
|
| // If this was an old packet, we wouldn't even have checked.
|
| - return false;
|
| + return "Largest observed too low";
|
| }
|
|
|
| if (!incoming_ack.missing_packets.Empty() &&
|
| @@ -794,7 +799,7 @@ bool QuicConnection::ValidateAckFrame(const QuicAckFrame& incoming_ack) {
|
| << incoming_ack.missing_packets.Max()
|
| << " which is greater than largest observed: "
|
| << incoming_ack.largest_observed;
|
| - return false;
|
| + return "Missing packet higher than largest observed";
|
| }
|
|
|
| if (!incoming_ack.missing_packets.Empty() &&
|
| @@ -804,14 +809,14 @@ bool QuicConnection::ValidateAckFrame(const QuicAckFrame& incoming_ack) {
|
| << incoming_ack.missing_packets.Min()
|
| << " which is smaller than least_packet_awaited_by_peer_: "
|
| << sent_packet_manager_.least_packet_awaited_by_peer();
|
| - return false;
|
| + return "Missing packet smaller than least awaited";
|
| }
|
|
|
| if (!sent_entropy_manager_.IsValidEntropy(incoming_ack.largest_observed,
|
| incoming_ack.missing_packets,
|
| incoming_ack.entropy_hash)) {
|
| LOG(WARNING) << ENDPOINT << "Peer sent invalid entropy.";
|
| - return false;
|
| + return "Invalid entropy";
|
| }
|
|
|
| if (incoming_ack.latest_revived_packet != 0 &&
|
| @@ -819,12 +824,12 @@ bool QuicConnection::ValidateAckFrame(const QuicAckFrame& incoming_ack) {
|
| incoming_ack.latest_revived_packet)) {
|
| LOG(WARNING) << ENDPOINT
|
| << "Peer specified revived packet which was not missing.";
|
| - return false;
|
| + return "Invalid revived packet";
|
| }
|
| - return true;
|
| + return nullptr;
|
| }
|
|
|
| -bool QuicConnection::ValidateStopWaitingFrame(
|
| +const char* QuicConnection::ValidateStopWaitingFrame(
|
| const QuicStopWaitingFrame& stop_waiting) {
|
| if (stop_waiting.least_unacked <
|
| received_packet_manager_.peer_least_packet_awaiting_ack()) {
|
| @@ -832,7 +837,7 @@ bool QuicConnection::ValidateStopWaitingFrame(
|
| << 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;
|
| + return "Least unacked too small";
|
| }
|
|
|
| if (stop_waiting.least_unacked > last_header_.packet_number) {
|
| @@ -840,10 +845,10 @@ bool QuicConnection::ValidateStopWaitingFrame(
|
| << "Peer sent least_unacked:" << stop_waiting.least_unacked
|
| << " greater than the enclosing packet number:"
|
| << last_header_.packet_number;
|
| - return false;
|
| + return "Least unacked too large";
|
| }
|
|
|
| - return true;
|
| + return nullptr;
|
| }
|
|
|
| void QuicConnection::OnFecData(StringPiece redundancy) {
|
| @@ -1352,6 +1357,18 @@ bool QuicConnection::ProcessValidatedPacket(const QuicPacketHeader& header) {
|
| return false;
|
| }
|
|
|
| + // If this packet has already been seen, or the sender has told us that it
|
| + // will not be retransmitted, then stop processing the packet.
|
| + if (!FLAGS_quic_drop_non_awaited_packets &&
|
| + !received_packet_manager_.IsAwaitingPacket(header.packet_number)) {
|
| + DVLOG(1) << ENDPOINT << "Packet " << header.packet_number
|
| + << " no longer being waited for. Discarding.";
|
| + if (debug_visitor_ != nullptr) {
|
| + debug_visitor_->OnDuplicatePacket(header.packet_number);
|
| + }
|
| + return false;
|
| + }
|
| +
|
| if (version_negotiation_state_ != NEGOTIATED_VERSION) {
|
| if (perspective_ == Perspective::IS_SERVER) {
|
| if (!header.public_header.version_flag) {
|
| @@ -1717,6 +1734,7 @@ void QuicConnection::OnWriteError(int error_code) {
|
| }
|
|
|
| void QuicConnection::OnSerializedPacket(SerializedPacket* serialized_packet) {
|
| + DCHECK_NE(kInvalidPathId, serialized_packet->path_id);
|
| if (serialized_packet->packet == nullptr) {
|
| // We failed to serialize the packet, so close the connection.
|
| // CloseConnection does not send close packet, so no infinite loop here.
|
| @@ -1970,7 +1988,15 @@ void QuicConnection::MaybeProcessRevivedPacket() {
|
|
|
| QuicFecGroup* QuicConnection::GetFecGroup() {
|
| QuicFecGroupNumber fec_group_num = last_header_.fec_group;
|
| - if (fec_group_num == 0) {
|
| + if (fec_group_num == 0 ||
|
| + (FLAGS_quic_drop_non_awaited_packets &&
|
| + fec_group_num <
|
| + received_packet_manager_.peer_least_packet_awaiting_ack() &&
|
| + !ContainsKey(group_map_, fec_group_num))) {
|
| + // If the group number is below peer_least_packet_awaiting_ack and this
|
| + // group does not exist, which means this group has missing packets below
|
| + // |peer_least_packet_awaiting_ack| which we would never receive, so return
|
| + // nullptr.
|
| return nullptr;
|
| }
|
| if (!ContainsKey(group_map_, fec_group_num)) {
|
| @@ -2064,9 +2090,9 @@ void QuicConnection::SendGoAway(QuicErrorCode error,
|
| void QuicConnection::CloseFecGroupsBefore(QuicPacketNumber packet_number) {
|
| FecGroupMap::iterator it = group_map_.begin();
|
| while (it != group_map_.end()) {
|
| - // If this is the current group or the group doesn't protect this packet
|
| - // we can ignore it.
|
| - if (last_header_.fec_group == it->first ||
|
| + // If the group doesn't protect this packet we can ignore it.
|
| + if ((!FLAGS_quic_drop_non_awaited_packets &&
|
| + last_header_.fec_group == it->first) ||
|
| !it->second->IsWaitingForPacketBefore(packet_number)) {
|
| ++it;
|
| continue;
|
| @@ -2156,7 +2182,8 @@ void QuicConnection::CheckForTimeout() {
|
| << idle_network_timeout_.ToMicroseconds();
|
| if (idle_duration >= idle_network_timeout_) {
|
| DVLOG(1) << ENDPOINT << "Connection timedout due to no network activity.";
|
| - SendConnectionClose(QUIC_CONNECTION_TIMED_OUT);
|
| + SendConnectionCloseWithDetails(QUIC_CONNECTION_TIMED_OUT,
|
| + "No recent network activity");
|
| return;
|
| }
|
|
|
| @@ -2170,7 +2197,8 @@ void QuicConnection::CheckForTimeout() {
|
| if (connected_duration >= overall_connection_timeout_) {
|
| DVLOG(1) << ENDPOINT
|
| << "Connection timedout due to overall connection timeout.";
|
| - SendConnectionClose(QUIC_CONNECTION_OVERALL_TIMED_OUT);
|
| + SendConnectionCloseWithDetails(QUIC_CONNECTION_OVERALL_TIMED_OUT,
|
| + "Overall timeout expired");
|
| return;
|
| }
|
| }
|
|
|