gfe-relnote: In QUIC, add OnUndecryptablePacket and OnAttemptingToProcessUndecryptablePacket to QuicConnectionDebugVistor. No functional change expected, not protected. This will be used for net-log in chromium. PiperOrigin-RevId: 308247080 Change-Id: I03ccc02ae4138cbd0b3b68ce0dfa5091452eb004
diff --git a/quic/core/quic_connection.cc b/quic/core/quic_connection.cc index 5ac44fc..7a23582 100644 --- a/quic/core/quic_connection.cc +++ b/quic/core/quic_connection.cc
@@ -1733,9 +1733,12 @@ } if (should_enqueue) { - QueueUndecryptablePacket(packet); - } else if (debug_visitor_ != nullptr) { - debug_visitor_->OnUndecryptablePacket(); + QueueUndecryptablePacket(packet, decryption_level); + } + + if (debug_visitor_ != nullptr) { + debug_visitor_->OnUndecryptablePacket(decryption_level, + /*dropped=*/!should_enqueue); } } @@ -2835,16 +2838,17 @@ } void QuicConnection::QueueUndecryptablePacket( - const QuicEncryptedPacket& packet) { + const QuicEncryptedPacket& packet, + EncryptionLevel decryption_level) { for (const auto& saved_packet : undecryptable_packets_) { - if (packet.data() == saved_packet->data() && - packet.length() == saved_packet->length()) { + if (packet.data() == saved_packet.packet->data() && + packet.length() == saved_packet.packet->length()) { QUIC_DVLOG(1) << ENDPOINT << "Not queueing known undecryptable packet"; return; } } QUIC_DVLOG(1) << ENDPOINT << "Queueing undecryptable packet."; - undecryptable_packets_.push_back(packet.Clone()); + undecryptable_packets_.emplace_back(packet, decryption_level); } void QuicConnection::MaybeProcessUndecryptablePackets() { @@ -2863,8 +2867,12 @@ return; } QUIC_DVLOG(1) << ENDPOINT << "Attempting to process undecryptable packet"; - QuicEncryptedPacket* packet = undecryptable_packets_.front().get(); - if (!framer_.ProcessPacket(*packet) && + const auto& undecryptable_packet = undecryptable_packets_.front(); + if (debug_visitor_ != nullptr) { + debug_visitor_->OnAttemptingToProcessUndecryptablePacket( + undecryptable_packet.encryption_level); + } + if (!framer_.ProcessPacket(*undecryptable_packet.packet) && framer_.error() == QUIC_DECRYPTION_FAILURE) { QUIC_DVLOG(1) << ENDPOINT << "Unable to process undecryptable packet..."; break; @@ -2879,11 +2887,9 @@ // never be able to be decrypted. if (encryption_level_ == ENCRYPTION_FORWARD_SECURE) { if (debug_visitor_ != nullptr) { - // TODO(rtenneti): perhaps more efficient to pass the number of - // undecryptable packets as the argument to OnUndecryptablePacket so that - // we just need to call OnUndecryptablePacket once? - for (size_t i = 0; i < undecryptable_packets_.size(); ++i) { - debug_visitor_->OnUndecryptablePacket(); + for (const auto& undecryptable_packet : undecryptable_packets_) { + debug_visitor_->OnUndecryptablePacket( + undecryptable_packet.encryption_level, /*dropped=*/true); } } undecryptable_packets_.clear();
diff --git a/quic/core/quic_connection.h b/quic/core/quic_connection.h index a6be992..e653352 100644 --- a/quic/core/quic_connection.h +++ b/quic/core/quic_connection.h
@@ -217,8 +217,15 @@ // match the ID of this connection. virtual void OnIncorrectConnectionId(QuicConnectionId /*connection_id*/) {} - // Called when an undecryptable packet has been received. - virtual void OnUndecryptablePacket() {} + // Called when an undecryptable packet has been received. If |dropped| is + // true, the packet has been dropped. Otherwise, the packet will be queued and + // connection will attempt to process it later. + virtual void OnUndecryptablePacket(EncryptionLevel /*decryption_level*/, + bool /*dropped*/) {} + + // Called when attempting to process a previously undecryptable packet. + virtual void OnAttemptingToProcessUndecryptablePacket( + EncryptionLevel /*decryption_level*/) {} // Called when a duplicate packet has been received. virtual void OnDuplicatePacket(QuicPacketNumber /*packet_number*/) {} @@ -1053,6 +1060,19 @@ const QuicSocketAddress peer_address; }; + // UndecrytablePacket comprises a undecryptable packet and the its encryption + // level. + struct QUIC_EXPORT_PRIVATE UndecryptablePacket { + UndecryptablePacket(const QuicEncryptedPacket& packet, + EncryptionLevel encryption_level) + : packet(packet.Clone()), encryption_level(encryption_level) {} + + std::unique_ptr<QuicEncryptedPacket> packet; + // Currently, |encryption_level| is only used for logging and does not + // affect processing of the packet. + EncryptionLevel encryption_level; + }; + // Notifies the visitor of the close and marks the connection as disconnected. // Does not send a connection close frame to the peer. It should only be // called by CloseConnection or OnConnectionCloseFrame, OnPublicResetPacket, @@ -1102,7 +1122,8 @@ // Queues |packet| in the hopes that it can be decrypted in the // future, when a new key is installed. - void QueueUndecryptablePacket(const QuicEncryptedPacket& packet); + void QueueUndecryptablePacket(const QuicEncryptedPacket& packet, + EncryptionLevel decryption_level); // Sends any packets which are a response to the last packet, including both // acks and pending writes if an ack opened the congestion window. @@ -1331,8 +1352,7 @@ // established, but which could not be decrypted. We buffer these on // the assumption that they could not be processed because they were // sent with the INITIAL encryption and the CHLO message was lost. - QuicCircularDeque<std::unique_ptr<QuicEncryptedPacket>> - undecryptable_packets_; + QuicCircularDeque<UndecryptablePacket> undecryptable_packets_; // Collection of coalesced packets which were received while processing // the current packet.