Record detailed location of FAIL_TO_SERIALIZE_PACKET error in UMA histogram. PiperOrigin-RevId: 332882395 Change-Id: If948bd43a46f2c0abf948bc4de4509e8a429a8b2
diff --git a/quic/core/quic_error_codes.cc b/quic/core/quic_error_codes.cc index cf153e3..f37ac84 100644 --- a/quic/core/quic_error_codes.cc +++ b/quic/core/quic_error_codes.cc
@@ -7,6 +7,7 @@ #include "third_party/boringssl/src/include/openssl/ssl.h" #include "net/third_party/quiche/src/quic/core/quic_error_codes.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_client_stats.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" @@ -763,6 +764,13 @@ return QUIC_STREAM_UNKNOWN_APPLICATION_ERROR_CODE; } +void RecordFailToSerializePacketLocation( + QuicFailToSerializePacketLocation location) { + QUIC_CLIENT_HISTOGRAM_ENUM("QuicSession.FailToSerializePacketLocation", + location, QUIC_FAIL_LOCATION_MAX, + "The reason why a packet fails to serialize"); +} + #undef RETURN_STRING_LITERAL // undef for jumbo builds } // namespace quic
diff --git a/quic/core/quic_error_codes.h b/quic/core/quic_error_codes.h index 78b5614..7bd4e14 100644 --- a/quic/core/quic_error_codes.h +++ b/quic/core/quic_error_codes.h
@@ -598,6 +598,36 @@ return "cause"; } +enum QuicFailToSerializePacketLocation { + kQuicFailToAppendPacketHeaderFastPath = 0, + kQuicFailToAppendTypeFastPath = 1, + kQuicFailToAppendStreamFrameFastPath = 2, + kQuicFailToAddPaddingFastPath = 3, + kQuicFailToWriteIetfLongHeaderLengthFastPath = 4, + kQuicFailToEncryptPacketFastPath = 5, + kQuicSerializePacketNonEmptyBuffer = 6, + kQuicMissingInitialKey = 7, + kQuicMissingHandshakeKey = 8, + kQuicMissingZeroRttKey = 9, + kQuicMissingOneRttKey = 10, + kQuicFailToBuildPacketWithPaddingInitial = 11, + kQuicFailToBuildPacketInitial = 12, + kQuicFailToBuildPacketWithPaddingHandshake = 13, + kQuicFailToBuildPacketHandshake = 14, + kQuicFailToBuildPacketWithPaddingZeroRtt = 15, + kQuicFailToBuildPacketZeroRtt = 16, + kQuicFailToBuildPacketWithPaddingOneRtt = 17, + kQuicFailToBuildPacketOneRtt = 18, + kQuicFailToEncryptInitial = 19, + kQuicFailToEncryptHandshake = 20, + kQuicFailToEncryptZeroRtt = 21, + kQuicFailToEncryptOneRtt = 22, + kMaxValue = kQuicFailToEncryptOneRtt +}; + +QUIC_EXPORT_PRIVATE void RecordFailToSerializePacketLocation( + QuicFailToSerializePacketLocation location); + } // namespace quic #endif // QUICHE_QUIC_CORE_QUIC_ERROR_CODES_H_
diff --git a/quic/core/quic_packet_creator.cc b/quic/core/quic_packet_creator.cc index a3e2bf9..3160b67 100644 --- a/quic/core/quic_packet_creator.cc +++ b/quic/core/quic_packet_creator.cc
@@ -18,6 +18,7 @@ #include "net/third_party/quiche/src/quic/core/quic_connection_id.h" #include "net/third_party/quiche/src/quic/core/quic_constants.h" #include "net/third_party/quiche/src/quic/core/quic_data_writer.h" +#include "net/third_party/quiche/src/quic/core/quic_error_codes.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/core/quic_versions.h" @@ -599,6 +600,7 @@ size_t length_field_offset = 0; if (!framer_->AppendPacketHeader(header, &writer, &length_field_offset)) { QUIC_BUG << "AppendPacketHeader failed"; + RecordFailToSerializePacketLocation(kQuicFailToAppendPacketHeaderFastPath); return; } @@ -640,10 +642,12 @@ bool omit_frame_length = !needs_padding; if (!framer_->AppendTypeByte(QuicFrame(frame), omit_frame_length, &writer)) { QUIC_BUG << "AppendTypeByte failed"; + RecordFailToSerializePacketLocation(kQuicFailToAppendTypeFastPath); return; } if (!framer_->AppendStreamFrame(frame, omit_frame_length, &writer)) { QUIC_BUG << "AppendStreamFrame failed"; + RecordFailToSerializePacketLocation(kQuicFailToAppendStreamFrameFastPath); return; } if (needs_padding && @@ -651,11 +655,14 @@ !writer.WritePaddingBytes(MinPlaintextPacketSize(framer_->version()) - plaintext_bytes_written)) { QUIC_BUG << "Unable to add padding bytes"; + RecordFailToSerializePacketLocation(kQuicFailToAddPaddingFastPath); return; } if (!framer_->WriteIetfLongHeaderLength(header, &writer, length_field_offset, packet_.encryption_level)) { + RecordFailToSerializePacketLocation( + kQuicFailToWriteIetfLongHeaderLengthFastPath); return; } @@ -670,6 +677,7 @@ writer.length(), kMaxOutgoingPacketSize, encrypted_buffer); if (encrypted_length == 0) { QUIC_BUG << "Failed to encrypt packet number " << header.packet_number; + RecordFailToSerializePacketLocation(kQuicFailToEncryptPacketFastPath); return; } // TODO(ianswett): Optimize the storage so RetransmitableFrames can be @@ -754,6 +762,7 @@ size_t encrypted_buffer_len) { if (close_connection_on_serialization_failure_ && packet_.encrypted_buffer != nullptr) { + RecordFailToSerializePacketLocation(kQuicSerializePacketNonEmptyBuffer); const std::string error_details = "Packet's encrypted buffer is not empty before serialization"; QUIC_BUG << error_details; @@ -795,6 +804,22 @@ << QuicFramesToString(queued_frames_) << " at missing encryption_level " << packet_.encryption_level << " using " << framer_->version(); + switch (packet_.encryption_level) { + case ENCRYPTION_INITIAL: + RecordFailToSerializePacketLocation(kQuicMissingInitialKey); + break; + case ENCRYPTION_HANDSHAKE: + RecordFailToSerializePacketLocation(kQuicMissingHandshakeKey); + break; + case ENCRYPTION_ZERO_RTT: + RecordFailToSerializePacketLocation(kQuicMissingZeroRttKey); + break; + case ENCRYPTION_FORWARD_SECURE: + RecordFailToSerializePacketLocation(kQuicMissingOneRttKey); + break; + default: + break; + } return false; } @@ -813,6 +838,42 @@ << latched_hard_max_packet_length_ << ", max_packet_length_: " << max_packet_length_ << ", header: " << header; + switch (packet_.encryption_level) { + case ENCRYPTION_INITIAL: + if (QuicUtils::ContainsFrameType(queued_frames_, PADDING_FRAME)) { + RecordFailToSerializePacketLocation( + kQuicFailToBuildPacketWithPaddingInitial); + } else { + RecordFailToSerializePacketLocation(kQuicFailToBuildPacketInitial); + } + break; + case ENCRYPTION_HANDSHAKE: + if (QuicUtils::ContainsFrameType(queued_frames_, PADDING_FRAME)) { + RecordFailToSerializePacketLocation( + kQuicFailToBuildPacketWithPaddingHandshake); + } else { + RecordFailToSerializePacketLocation(kQuicFailToBuildPacketHandshake); + } + break; + case ENCRYPTION_ZERO_RTT: + if (QuicUtils::ContainsFrameType(queued_frames_, PADDING_FRAME)) { + RecordFailToSerializePacketLocation( + kQuicFailToBuildPacketWithPaddingZeroRtt); + } else { + RecordFailToSerializePacketLocation(kQuicFailToBuildPacketZeroRtt); + } + break; + case ENCRYPTION_FORWARD_SECURE: + if (QuicUtils::ContainsFrameType(queued_frames_, PADDING_FRAME)) { + RecordFailToSerializePacketLocation( + kQuicFailToBuildPacketWithPaddingOneRtt); + } else { + RecordFailToSerializePacketLocation(kQuicFailToBuildPacketOneRtt); + } + break; + default: + break; + } return false; } @@ -834,6 +895,22 @@ encrypted_buffer_len, encrypted_buffer.buffer); if (encrypted_length == 0) { QUIC_BUG << "Failed to encrypt packet number " << packet_.packet_number; + switch (packet_.encryption_level) { + case ENCRYPTION_INITIAL: + RecordFailToSerializePacketLocation(kQuicFailToEncryptInitial); + break; + case ENCRYPTION_HANDSHAKE: + RecordFailToSerializePacketLocation(kQuicFailToEncryptHandshake); + break; + case ENCRYPTION_ZERO_RTT: + RecordFailToSerializePacketLocation(kQuicFailToEncryptZeroRtt); + break; + case ENCRYPTION_FORWARD_SECURE: + RecordFailToSerializePacketLocation(kQuicFailToEncryptOneRtt); + break; + default: + break; + } return false; }