Add text outputter for IETF stream types Adds an overloaded << operator to pretty-print IETF stream types. gfe-relnote: N/A just for debug/logging, IETF QUIC/V99 only. PiperOrigin-RevId: 263749354 Change-Id: Ifdc257910bdfe066842948d8090636e7f31991fe
diff --git a/quic/core/frames/quic_connection_close_frame.cc b/quic/core/frames/quic_connection_close_frame.cc index d436499..3e37073 100644 --- a/quic/core/frames/quic_connection_close_frame.cc +++ b/quic/core/frames/quic_connection_close_frame.cc
@@ -6,6 +6,8 @@ #include <memory> +#include "net/third_party/quiche/src/quic/platform/api/quic_str_cat.h" + namespace quic { QuicConnectionCloseFrame::QuicConnectionCloseFrame() @@ -49,21 +51,28 @@ std::ostream& os, const QuicConnectionCloseFrame& connection_close_frame) { os << "{ Close type: " << connection_close_frame.close_type - << ", error_code: " - << ((connection_close_frame.close_type == - IETF_QUIC_TRANSPORT_CONNECTION_CLOSE) - ? static_cast<uint16_t>( - connection_close_frame.transport_error_code) - : ((connection_close_frame.close_type == - IETF_QUIC_APPLICATION_CONNECTION_CLOSE) - ? connection_close_frame.application_error_code - : static_cast<uint16_t>( - connection_close_frame.quic_error_code))) - << ", extracted_error_code: " - << connection_close_frame.extracted_error_code << ", error_details: '" - << connection_close_frame.error_details - << "', frame_type: " << connection_close_frame.transport_close_frame_type - << "}\n"; + << ", error_code: "; + switch (connection_close_frame.close_type) { + case IETF_QUIC_TRANSPORT_CONNECTION_CLOSE: + os << connection_close_frame.transport_error_code; + break; + case IETF_QUIC_APPLICATION_CONNECTION_CLOSE: + os << connection_close_frame.application_error_code; + break; + case GOOGLE_QUIC_CONNECTION_CLOSE: + os << connection_close_frame.quic_error_code; + break; + } + os << ", extracted_error_code: " + << QuicErrorCodeToString(connection_close_frame.extracted_error_code) + << ", error_details: '" << connection_close_frame.error_details << "'"; + if (connection_close_frame.close_type == + IETF_QUIC_TRANSPORT_CONNECTION_CLOSE) { + os << ", frame_type: " + << static_cast<QuicIetfFrameType>( + connection_close_frame.transport_close_frame_type); + } + os << "}\n"; return os; }
diff --git a/quic/core/frames/quic_frames_test.cc b/quic/core/frames/quic_frames_test.cc index 3467c78..b1030ee 100644 --- a/quic/core/frames/quic_frames_test.cc +++ b/quic/core/frames/quic_frames_test.cc
@@ -148,10 +148,31 @@ // underlying frame. EXPECT_EQ( "{ Close type: GOOGLE_QUIC_CONNECTION_CLOSE, error_code: 25, " - "extracted_error_code: 122, " + "extracted_error_code: QUIC_IETF_GQUIC_ERROR_MISSING, " + "error_details: 'No recent " + "network activity.'" + "}\n", + stream.str()); + QuicFrame quic_frame(&frame); + EXPECT_FALSE(IsControlFrame(quic_frame.type)); +} + +TEST_F(QuicFramesTest, TransportConnectionCloseFrameToString) { + QuicConnectionCloseFrame frame; + frame.close_type = IETF_QUIC_TRANSPORT_CONNECTION_CLOSE; + frame.transport_error_code = FINAL_SIZE_ERROR; + frame.extracted_error_code = QUIC_NETWORK_IDLE_TIMEOUT; + frame.error_details = "No recent network activity."; + frame.transport_close_frame_type = IETF_STREAM; + std::ostringstream stream; + stream << frame; + EXPECT_EQ( + "{ Close type: IETF_QUIC_TRANSPORT_CONNECTION_CLOSE, error_code: " + "FINAL_SIZE_ERROR, " + "extracted_error_code: QUIC_NETWORK_IDLE_TIMEOUT, " "error_details: 'No recent " "network activity.', " - "frame_type: 0" + "frame_type: IETF_STREAM" "}\n", stream.str()); QuicFrame quic_frame(&frame);
diff --git a/quic/core/quic_types.cc b/quic/core/quic_types.cc index 38572f1..2fe951b 100644 --- a/quic/core/quic_types.cc +++ b/quic/core/quic_types.cc
@@ -4,6 +4,8 @@ #include "net/third_party/quiche/src/quic/core/quic_types.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_str_cat.h" + namespace quic { QuicConsumedData::QuicConsumedData(size_t bytes_consumed, bool fin_consumed) @@ -75,52 +77,35 @@ MessageResult::MessageResult(MessageStatus status, QuicMessageId message_id) : status(status), message_id(message_id) {} -std::ostream& operator<<(std::ostream& os, - const QuicIetfTransportErrorCodes& c) { +#define RETURN_STRING_LITERAL(x) \ + case x: \ + return #x; + +std::string QuicIetfTransportErrorCodeString(QuicIetfTransportErrorCodes c) { if (static_cast<uint16_t>(c) >= 0xff00u) { - os << "Private value: " << c; - return os; + return QuicStrCat("Private value: ", c); } switch (c) { - case NO_IETF_QUIC_ERROR: - os << "NO_IETF_QUIC_ERROR"; - break; - case INTERNAL_ERROR: - os << "INTERNAL_ERROR"; - break; - case SERVER_BUSY_ERROR: - os << "SERVER_BUSY_ERROR"; - break; - case FLOW_CONTROL_ERROR: - os << "FLOW_CONTROL_ERROR"; - break; - case STREAM_LIMIT_ERROR: - os << "STREAM_LIMIT_ERROR"; - break; - case STREAM_STATE_ERROR: - os << "STREAM_STATE_ERROR"; - break; - case FINAL_SIZE_ERROR: - os << "FINAL_SIZE_ERROR"; - break; - case FRAME_ENCODING_ERROR: - os << "FRAME_ENCODING_ERROR"; - break; - case TRANSPORT_PARAMETER_ERROR: - os << "TRANSPORT_PARAMETER_ERROR"; - break; - case VERSION_NEGOTIATION_ERROR: - os << "VERSION_NEGOTIATION_ERROR"; - break; - case PROTOCOL_VIOLATION: - os << "PROTOCOL_VIOLATION"; - break; - case INVALID_MIGRATION: - os << "INVALID_MIGRATION"; - break; - // No default -- compiler will catch any adds/changes then. + RETURN_STRING_LITERAL(NO_IETF_QUIC_ERROR); + RETURN_STRING_LITERAL(INTERNAL_ERROR); + RETURN_STRING_LITERAL(SERVER_BUSY_ERROR); + RETURN_STRING_LITERAL(FLOW_CONTROL_ERROR); + RETURN_STRING_LITERAL(STREAM_LIMIT_ERROR); + RETURN_STRING_LITERAL(STREAM_STATE_ERROR); + RETURN_STRING_LITERAL(FINAL_SIZE_ERROR); + RETURN_STRING_LITERAL(FRAME_ENCODING_ERROR); + RETURN_STRING_LITERAL(TRANSPORT_PARAMETER_ERROR); + RETURN_STRING_LITERAL(VERSION_NEGOTIATION_ERROR); + RETURN_STRING_LITERAL(PROTOCOL_VIOLATION); + RETURN_STRING_LITERAL(INVALID_MIGRATION); + // No default -- compiler will catch any adds/changes then. } +} + +std::ostream& operator<<(std::ostream& os, + const QuicIetfTransportErrorCodes& c) { + os << QuicIetfTransportErrorCodeString(c); return os; } @@ -429,4 +414,43 @@ return {false, {NO_IETF_QUIC_ERROR}}; } +std::string QuicIetfFrameTypeString(QuicIetfFrameType t) { + if (IS_IETF_STREAM_FRAME(t)) { + return "IETF_STREAM"; + } + + switch (t) { + RETURN_STRING_LITERAL(IETF_PADDING); + RETURN_STRING_LITERAL(IETF_PING); + RETURN_STRING_LITERAL(IETF_ACK); + RETURN_STRING_LITERAL(IETF_ACK_ECN); + RETURN_STRING_LITERAL(IETF_RST_STREAM); + RETURN_STRING_LITERAL(IETF_STOP_SENDING); + RETURN_STRING_LITERAL(IETF_CRYPTO); + RETURN_STRING_LITERAL(IETF_NEW_TOKEN); + RETURN_STRING_LITERAL(IETF_MAX_DATA); + RETURN_STRING_LITERAL(IETF_MAX_STREAM_DATA); + RETURN_STRING_LITERAL(IETF_MAX_STREAMS_BIDIRECTIONAL); + RETURN_STRING_LITERAL(IETF_MAX_STREAMS_UNIDIRECTIONAL); + RETURN_STRING_LITERAL(IETF_BLOCKED); + RETURN_STRING_LITERAL(IETF_STREAM_BLOCKED); + RETURN_STRING_LITERAL(IETF_STREAMS_BLOCKED_BIDIRECTIONAL); + RETURN_STRING_LITERAL(IETF_STREAMS_BLOCKED_UNIDIRECTIONAL); + RETURN_STRING_LITERAL(IETF_NEW_CONNECTION_ID); + RETURN_STRING_LITERAL(IETF_RETIRE_CONNECTION_ID); + RETURN_STRING_LITERAL(IETF_PATH_CHALLENGE); + RETURN_STRING_LITERAL(IETF_PATH_RESPONSE); + RETURN_STRING_LITERAL(IETF_CONNECTION_CLOSE); + RETURN_STRING_LITERAL(IETF_APPLICATION_CLOSE); + RETURN_STRING_LITERAL(IETF_EXTENSION_MESSAGE_NO_LENGTH); + RETURN_STRING_LITERAL(IETF_EXTENSION_MESSAGE); + default: + return QuicStrCat("Private value (", t, ")"); + } +} +std::ostream& operator<<(std::ostream& os, const QuicIetfFrameType& c) { + os << QuicIetfFrameTypeString(c); + return os; +} + } // namespace quic
diff --git a/quic/core/quic_types.h b/quic/core/quic_types.h index 8a5434e..524d5ec 100644 --- a/quic/core/quic_types.h +++ b/quic/core/quic_types.h
@@ -267,6 +267,10 @@ IETF_EXTENSION_MESSAGE_NO_LENGTH = 0x20, IETF_EXTENSION_MESSAGE = 0x21, }; +QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, + const QuicIetfFrameType& c); +QUIC_EXPORT_PRIVATE std::string QuicIetfFrameTypeString(QuicIetfFrameType t); + // Masks for the bits that indicate the frame is a Stream frame vs the // bits used as flags. #define IETF_STREAM_FRAME_TYPE_MASK 0xfffffffffffffff8 @@ -519,6 +523,9 @@ PROTOCOL_VIOLATION = 0xA, INVALID_MIGRATION = 0xC, }; +QUIC_EXPORT_PRIVATE std::string QuicIetfTransportErrorCodeString( + QuicIetfTransportErrorCodes c); + QUIC_EXPORT_PRIVATE std::ostream& operator<<( std::ostream& os, const QuicIetfTransportErrorCodes& c);