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;
}