1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "quiche/quic/core/quic_types.h"
6
7 #include <cstdint>
8
9 #include "absl/strings/str_cat.h"
10 #include "quiche/quic/core/quic_error_codes.h"
11 #include "quiche/common/print_elements.h"
12
13 namespace quic {
14
15 static_assert(sizeof(StatelessResetToken) == kStatelessResetTokenLength,
16 "bad size");
17
operator <<(std::ostream & os,const QuicConsumedData & s)18 std::ostream& operator<<(std::ostream& os, const QuicConsumedData& s) {
19 os << "bytes_consumed: " << s.bytes_consumed
20 << " fin_consumed: " << s.fin_consumed;
21 return os;
22 }
23
PerspectiveToString(Perspective perspective)24 std::string PerspectiveToString(Perspective perspective) {
25 if (perspective == Perspective::IS_SERVER) {
26 return "IS_SERVER";
27 }
28 if (perspective == Perspective::IS_CLIENT) {
29 return "IS_CLIENT";
30 }
31 return absl::StrCat("Unknown(", static_cast<int>(perspective), ")");
32 }
33
operator <<(std::ostream & os,const Perspective & perspective)34 std::ostream& operator<<(std::ostream& os, const Perspective& perspective) {
35 os << PerspectiveToString(perspective);
36 return os;
37 }
38
ConnectionCloseSourceToString(ConnectionCloseSource connection_close_source)39 std::string ConnectionCloseSourceToString(
40 ConnectionCloseSource connection_close_source) {
41 if (connection_close_source == ConnectionCloseSource::FROM_PEER) {
42 return "FROM_PEER";
43 }
44 if (connection_close_source == ConnectionCloseSource::FROM_SELF) {
45 return "FROM_SELF";
46 }
47 return absl::StrCat("Unknown(", static_cast<int>(connection_close_source),
48 ")");
49 }
50
operator <<(std::ostream & os,const ConnectionCloseSource & connection_close_source)51 std::ostream& operator<<(std::ostream& os,
52 const ConnectionCloseSource& connection_close_source) {
53 os << ConnectionCloseSourceToString(connection_close_source);
54 return os;
55 }
56
ConnectionCloseBehaviorToString(ConnectionCloseBehavior connection_close_behavior)57 std::string ConnectionCloseBehaviorToString(
58 ConnectionCloseBehavior connection_close_behavior) {
59 if (connection_close_behavior == ConnectionCloseBehavior::SILENT_CLOSE) {
60 return "SILENT_CLOSE";
61 }
62 if (connection_close_behavior ==
63 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET) {
64 return "SEND_CONNECTION_CLOSE_PACKET";
65 }
66 return absl::StrCat("Unknown(", static_cast<int>(connection_close_behavior),
67 ")");
68 }
69
operator <<(std::ostream & os,const ConnectionCloseBehavior & connection_close_behavior)70 std::ostream& operator<<(
71 std::ostream& os,
72 const ConnectionCloseBehavior& connection_close_behavior) {
73 os << ConnectionCloseBehaviorToString(connection_close_behavior);
74 return os;
75 }
76
operator <<(std::ostream & os,const AckedPacket & acked_packet)77 std::ostream& operator<<(std::ostream& os, const AckedPacket& acked_packet) {
78 os << "{ packet_number: " << acked_packet.packet_number
79 << ", bytes_acked: " << acked_packet.bytes_acked << ", receive_timestamp: "
80 << acked_packet.receive_timestamp.ToDebuggingValue() << "} ";
81 return os;
82 }
83
operator <<(std::ostream & os,const LostPacket & lost_packet)84 std::ostream& operator<<(std::ostream& os, const LostPacket& lost_packet) {
85 os << "{ packet_number: " << lost_packet.packet_number
86 << ", bytes_lost: " << lost_packet.bytes_lost << "} ";
87 return os;
88 }
89
HistogramEnumString(WriteStatus enum_value)90 std::string HistogramEnumString(WriteStatus enum_value) {
91 switch (enum_value) {
92 case WRITE_STATUS_OK:
93 return "OK";
94 case WRITE_STATUS_BLOCKED:
95 return "BLOCKED";
96 case WRITE_STATUS_BLOCKED_DATA_BUFFERED:
97 return "BLOCKED_DATA_BUFFERED";
98 case WRITE_STATUS_ERROR:
99 return "ERROR";
100 case WRITE_STATUS_MSG_TOO_BIG:
101 return "MSG_TOO_BIG";
102 case WRITE_STATUS_FAILED_TO_COALESCE_PACKET:
103 return "WRITE_STATUS_FAILED_TO_COALESCE_PACKET";
104 case WRITE_STATUS_NUM_VALUES:
105 return "NUM_VALUES";
106 }
107 QUIC_DLOG(ERROR) << "Invalid WriteStatus value: "
108 << static_cast<int16_t>(enum_value);
109 return "<invalid>";
110 }
111
operator <<(std::ostream & os,const WriteStatus & status)112 std::ostream& operator<<(std::ostream& os, const WriteStatus& status) {
113 os << HistogramEnumString(status);
114 return os;
115 }
116
operator <<(std::ostream & os,const WriteResult & s)117 std::ostream& operator<<(std::ostream& os, const WriteResult& s) {
118 os << "{ status: " << s.status;
119 if (s.status == WRITE_STATUS_OK) {
120 os << ", bytes_written: " << s.bytes_written;
121 } else {
122 os << ", error_code: " << s.error_code;
123 }
124 os << " }";
125 return os;
126 }
127
MessageResult(MessageStatus status,QuicMessageId message_id)128 MessageResult::MessageResult(MessageStatus status, QuicMessageId message_id)
129 : status(status), message_id(message_id) {}
130
131 #define RETURN_STRING_LITERAL(x) \
132 case x: \
133 return #x;
134
QuicFrameTypeToString(QuicFrameType t)135 std::string QuicFrameTypeToString(QuicFrameType t) {
136 switch (t) {
137 RETURN_STRING_LITERAL(PADDING_FRAME)
138 RETURN_STRING_LITERAL(RST_STREAM_FRAME)
139 RETURN_STRING_LITERAL(CONNECTION_CLOSE_FRAME)
140 RETURN_STRING_LITERAL(GOAWAY_FRAME)
141 RETURN_STRING_LITERAL(WINDOW_UPDATE_FRAME)
142 RETURN_STRING_LITERAL(BLOCKED_FRAME)
143 RETURN_STRING_LITERAL(STOP_WAITING_FRAME)
144 RETURN_STRING_LITERAL(PING_FRAME)
145 RETURN_STRING_LITERAL(CRYPTO_FRAME)
146 RETURN_STRING_LITERAL(HANDSHAKE_DONE_FRAME)
147 RETURN_STRING_LITERAL(STREAM_FRAME)
148 RETURN_STRING_LITERAL(ACK_FRAME)
149 RETURN_STRING_LITERAL(MTU_DISCOVERY_FRAME)
150 RETURN_STRING_LITERAL(NEW_CONNECTION_ID_FRAME)
151 RETURN_STRING_LITERAL(MAX_STREAMS_FRAME)
152 RETURN_STRING_LITERAL(STREAMS_BLOCKED_FRAME)
153 RETURN_STRING_LITERAL(PATH_RESPONSE_FRAME)
154 RETURN_STRING_LITERAL(PATH_CHALLENGE_FRAME)
155 RETURN_STRING_LITERAL(STOP_SENDING_FRAME)
156 RETURN_STRING_LITERAL(MESSAGE_FRAME)
157 RETURN_STRING_LITERAL(NEW_TOKEN_FRAME)
158 RETURN_STRING_LITERAL(RETIRE_CONNECTION_ID_FRAME)
159 RETURN_STRING_LITERAL(ACK_FREQUENCY_FRAME)
160 RETURN_STRING_LITERAL(RESET_STREAM_AT_FRAME)
161 RETURN_STRING_LITERAL(NUM_FRAME_TYPES)
162 }
163 return absl::StrCat("Unknown(", static_cast<int>(t), ")");
164 }
165
operator <<(std::ostream & os,const QuicFrameType & t)166 std::ostream& operator<<(std::ostream& os, const QuicFrameType& t) {
167 os << QuicFrameTypeToString(t);
168 return os;
169 }
170
QuicIetfFrameTypeString(QuicIetfFrameType t)171 std::string QuicIetfFrameTypeString(QuicIetfFrameType t) {
172 if (IS_IETF_STREAM_FRAME(t)) {
173 return "IETF_STREAM";
174 }
175
176 switch (t) {
177 RETURN_STRING_LITERAL(IETF_PADDING);
178 RETURN_STRING_LITERAL(IETF_PING);
179 RETURN_STRING_LITERAL(IETF_ACK);
180 RETURN_STRING_LITERAL(IETF_ACK_ECN);
181 RETURN_STRING_LITERAL(IETF_RST_STREAM);
182 RETURN_STRING_LITERAL(IETF_STOP_SENDING);
183 RETURN_STRING_LITERAL(IETF_CRYPTO);
184 RETURN_STRING_LITERAL(IETF_NEW_TOKEN);
185 RETURN_STRING_LITERAL(IETF_MAX_DATA);
186 RETURN_STRING_LITERAL(IETF_MAX_STREAM_DATA);
187 RETURN_STRING_LITERAL(IETF_MAX_STREAMS_BIDIRECTIONAL);
188 RETURN_STRING_LITERAL(IETF_MAX_STREAMS_UNIDIRECTIONAL);
189 RETURN_STRING_LITERAL(IETF_DATA_BLOCKED);
190 RETURN_STRING_LITERAL(IETF_STREAM_DATA_BLOCKED);
191 RETURN_STRING_LITERAL(IETF_STREAMS_BLOCKED_BIDIRECTIONAL);
192 RETURN_STRING_LITERAL(IETF_STREAMS_BLOCKED_UNIDIRECTIONAL);
193 RETURN_STRING_LITERAL(IETF_NEW_CONNECTION_ID);
194 RETURN_STRING_LITERAL(IETF_RETIRE_CONNECTION_ID);
195 RETURN_STRING_LITERAL(IETF_PATH_CHALLENGE);
196 RETURN_STRING_LITERAL(IETF_PATH_RESPONSE);
197 RETURN_STRING_LITERAL(IETF_CONNECTION_CLOSE);
198 RETURN_STRING_LITERAL(IETF_APPLICATION_CLOSE);
199 RETURN_STRING_LITERAL(IETF_EXTENSION_MESSAGE_NO_LENGTH);
200 RETURN_STRING_LITERAL(IETF_EXTENSION_MESSAGE);
201 RETURN_STRING_LITERAL(IETF_EXTENSION_MESSAGE_NO_LENGTH_V99);
202 RETURN_STRING_LITERAL(IETF_EXTENSION_MESSAGE_V99);
203 default:
204 return absl::StrCat("Private value (", t, ")");
205 }
206 }
operator <<(std::ostream & os,const QuicIetfFrameType & c)207 std::ostream& operator<<(std::ostream& os, const QuicIetfFrameType& c) {
208 os << QuicIetfFrameTypeString(c);
209 return os;
210 }
211
TransmissionTypeToString(TransmissionType transmission_type)212 std::string TransmissionTypeToString(TransmissionType transmission_type) {
213 switch (transmission_type) {
214 RETURN_STRING_LITERAL(NOT_RETRANSMISSION);
215 RETURN_STRING_LITERAL(HANDSHAKE_RETRANSMISSION);
216 RETURN_STRING_LITERAL(ALL_ZERO_RTT_RETRANSMISSION);
217 RETURN_STRING_LITERAL(LOSS_RETRANSMISSION);
218 RETURN_STRING_LITERAL(PTO_RETRANSMISSION);
219 RETURN_STRING_LITERAL(PATH_RETRANSMISSION);
220 RETURN_STRING_LITERAL(ALL_INITIAL_RETRANSMISSION);
221 default:
222 // Some varz rely on this behavior for statistic collection.
223 if (transmission_type == LAST_TRANSMISSION_TYPE + 1) {
224 return "INVALID_TRANSMISSION_TYPE";
225 }
226 return absl::StrCat("Unknown(", static_cast<int>(transmission_type), ")");
227 }
228 }
229
operator <<(std::ostream & os,TransmissionType transmission_type)230 std::ostream& operator<<(std::ostream& os, TransmissionType transmission_type) {
231 os << TransmissionTypeToString(transmission_type);
232 return os;
233 }
234
PacketHeaderFormatToString(PacketHeaderFormat format)235 std::string PacketHeaderFormatToString(PacketHeaderFormat format) {
236 switch (format) {
237 RETURN_STRING_LITERAL(IETF_QUIC_LONG_HEADER_PACKET);
238 RETURN_STRING_LITERAL(IETF_QUIC_SHORT_HEADER_PACKET);
239 RETURN_STRING_LITERAL(GOOGLE_QUIC_PACKET);
240 default:
241 return absl::StrCat("Unknown (", static_cast<int>(format), ")");
242 }
243 }
244
QuicLongHeaderTypeToString(QuicLongHeaderType type)245 std::string QuicLongHeaderTypeToString(QuicLongHeaderType type) {
246 switch (type) {
247 RETURN_STRING_LITERAL(VERSION_NEGOTIATION);
248 RETURN_STRING_LITERAL(INITIAL);
249 RETURN_STRING_LITERAL(ZERO_RTT_PROTECTED);
250 RETURN_STRING_LITERAL(HANDSHAKE);
251 RETURN_STRING_LITERAL(RETRY);
252 RETURN_STRING_LITERAL(INVALID_PACKET_TYPE);
253 default:
254 return absl::StrCat("Unknown (", static_cast<int>(type), ")");
255 }
256 }
257
MessageStatusToString(MessageStatus message_status)258 std::string MessageStatusToString(MessageStatus message_status) {
259 switch (message_status) {
260 RETURN_STRING_LITERAL(MESSAGE_STATUS_SUCCESS);
261 RETURN_STRING_LITERAL(MESSAGE_STATUS_ENCRYPTION_NOT_ESTABLISHED);
262 RETURN_STRING_LITERAL(MESSAGE_STATUS_UNSUPPORTED);
263 RETURN_STRING_LITERAL(MESSAGE_STATUS_BLOCKED);
264 RETURN_STRING_LITERAL(MESSAGE_STATUS_TOO_LARGE);
265 RETURN_STRING_LITERAL(MESSAGE_STATUS_INTERNAL_ERROR);
266 default:
267 return absl::StrCat("Unknown(", static_cast<int>(message_status), ")");
268 }
269 }
270
MessageResultToString(MessageResult message_result)271 std::string MessageResultToString(MessageResult message_result) {
272 if (message_result.status != MESSAGE_STATUS_SUCCESS) {
273 return absl::StrCat("{", MessageStatusToString(message_result.status), "}");
274 }
275 return absl::StrCat("{MESSAGE_STATUS_SUCCESS,id=", message_result.message_id,
276 "}");
277 }
278
operator <<(std::ostream & os,const MessageResult & mr)279 std::ostream& operator<<(std::ostream& os, const MessageResult& mr) {
280 os << MessageResultToString(mr);
281 return os;
282 }
283
PacketNumberSpaceToString(PacketNumberSpace packet_number_space)284 std::string PacketNumberSpaceToString(PacketNumberSpace packet_number_space) {
285 switch (packet_number_space) {
286 RETURN_STRING_LITERAL(INITIAL_DATA);
287 RETURN_STRING_LITERAL(HANDSHAKE_DATA);
288 RETURN_STRING_LITERAL(APPLICATION_DATA);
289 default:
290 return absl::StrCat("Unknown(", static_cast<int>(packet_number_space),
291 ")");
292 }
293 }
294
SerializedPacketFateToString(SerializedPacketFate fate)295 std::string SerializedPacketFateToString(SerializedPacketFate fate) {
296 switch (fate) {
297 RETURN_STRING_LITERAL(DISCARD);
298 RETURN_STRING_LITERAL(COALESCE);
299 RETURN_STRING_LITERAL(BUFFER);
300 RETURN_STRING_LITERAL(SEND_TO_WRITER);
301 }
302 return absl::StrCat("Unknown(", static_cast<int>(fate), ")");
303 }
304
operator <<(std::ostream & os,SerializedPacketFate fate)305 std::ostream& operator<<(std::ostream& os, SerializedPacketFate fate) {
306 os << SerializedPacketFateToString(fate);
307 return os;
308 }
309
CongestionControlTypeToString(CongestionControlType cc_type)310 std::string CongestionControlTypeToString(CongestionControlType cc_type) {
311 switch (cc_type) {
312 case kCubicBytes:
313 return "CUBIC_BYTES";
314 case kRenoBytes:
315 return "RENO_BYTES";
316 case kBBR:
317 return "BBR";
318 case kBBRv2:
319 return "BBRv2";
320 case kPCC:
321 return "PCC";
322 case kGoogCC:
323 return "GoogCC";
324 }
325 return absl::StrCat("Unknown(", static_cast<int>(cc_type), ")");
326 }
327
EncryptionLevelToString(EncryptionLevel level)328 std::string EncryptionLevelToString(EncryptionLevel level) {
329 switch (level) {
330 RETURN_STRING_LITERAL(ENCRYPTION_INITIAL);
331 RETURN_STRING_LITERAL(ENCRYPTION_HANDSHAKE);
332 RETURN_STRING_LITERAL(ENCRYPTION_ZERO_RTT);
333 RETURN_STRING_LITERAL(ENCRYPTION_FORWARD_SECURE);
334 default:
335 return absl::StrCat("Unknown(", static_cast<int>(level), ")");
336 }
337 }
338
operator <<(std::ostream & os,EncryptionLevel level)339 std::ostream& operator<<(std::ostream& os, EncryptionLevel level) {
340 os << EncryptionLevelToString(level);
341 return os;
342 }
343
ClientCertModeToString(ClientCertMode mode)344 absl::string_view ClientCertModeToString(ClientCertMode mode) {
345 #define RETURN_REASON_LITERAL(x) \
346 case ClientCertMode::x: \
347 return #x
348 switch (mode) {
349 RETURN_REASON_LITERAL(kNone);
350 RETURN_REASON_LITERAL(kRequest);
351 RETURN_REASON_LITERAL(kRequire);
352 default:
353 return "<invalid>";
354 }
355 #undef RETURN_REASON_LITERAL
356 }
357
operator <<(std::ostream & os,ClientCertMode mode)358 std::ostream& operator<<(std::ostream& os, ClientCertMode mode) {
359 os << ClientCertModeToString(mode);
360 return os;
361 }
362
QuicConnectionCloseTypeString(QuicConnectionCloseType type)363 std::string QuicConnectionCloseTypeString(QuicConnectionCloseType type) {
364 switch (type) {
365 RETURN_STRING_LITERAL(GOOGLE_QUIC_CONNECTION_CLOSE);
366 RETURN_STRING_LITERAL(IETF_QUIC_TRANSPORT_CONNECTION_CLOSE);
367 RETURN_STRING_LITERAL(IETF_QUIC_APPLICATION_CONNECTION_CLOSE);
368 default:
369 return absl::StrCat("Unknown(", static_cast<int>(type), ")");
370 }
371 }
372
operator <<(std::ostream & os,const QuicConnectionCloseType type)373 std::ostream& operator<<(std::ostream& os, const QuicConnectionCloseType type) {
374 os << QuicConnectionCloseTypeString(type);
375 return os;
376 }
377
AddressChangeTypeToString(AddressChangeType type)378 std::string AddressChangeTypeToString(AddressChangeType type) {
379 using IntType = typename std::underlying_type<AddressChangeType>::type;
380 switch (type) {
381 RETURN_STRING_LITERAL(NO_CHANGE);
382 RETURN_STRING_LITERAL(PORT_CHANGE);
383 RETURN_STRING_LITERAL(IPV4_SUBNET_CHANGE);
384 RETURN_STRING_LITERAL(IPV4_TO_IPV4_CHANGE);
385 RETURN_STRING_LITERAL(IPV4_TO_IPV6_CHANGE);
386 RETURN_STRING_LITERAL(IPV6_TO_IPV4_CHANGE);
387 RETURN_STRING_LITERAL(IPV6_TO_IPV6_CHANGE);
388 default:
389 return absl::StrCat("Unknown(", static_cast<IntType>(type), ")");
390 }
391 }
392
operator <<(std::ostream & os,AddressChangeType type)393 std::ostream& operator<<(std::ostream& os, AddressChangeType type) {
394 os << AddressChangeTypeToString(type);
395 return os;
396 }
397
KeyUpdateReasonString(KeyUpdateReason reason)398 std::string KeyUpdateReasonString(KeyUpdateReason reason) {
399 #define RETURN_REASON_LITERAL(x) \
400 case KeyUpdateReason::x: \
401 return #x
402 switch (reason) {
403 RETURN_REASON_LITERAL(kInvalid);
404 RETURN_REASON_LITERAL(kRemote);
405 RETURN_REASON_LITERAL(kLocalForTests);
406 RETURN_REASON_LITERAL(kLocalForInteropRunner);
407 RETURN_REASON_LITERAL(kLocalAeadConfidentialityLimit);
408 RETURN_REASON_LITERAL(kLocalKeyUpdateLimitOverride);
409 default:
410 return absl::StrCat("Unknown(", static_cast<int>(reason), ")");
411 }
412 #undef RETURN_REASON_LITERAL
413 }
414
operator <<(std::ostream & os,const KeyUpdateReason reason)415 std::ostream& operator<<(std::ostream& os, const KeyUpdateReason reason) {
416 os << KeyUpdateReasonString(reason);
417 return os;
418 }
419
operator ==(const ParsedClientHello & a,const ParsedClientHello & b)420 bool operator==(const ParsedClientHello& a, const ParsedClientHello& b) {
421 return a.sni == b.sni && a.uaid == b.uaid &&
422 a.supported_groups == b.supported_groups && a.alpns == b.alpns &&
423 a.retry_token == b.retry_token &&
424 a.resumption_attempted == b.resumption_attempted &&
425 a.early_data_attempted == b.early_data_attempted;
426 }
427
operator <<(std::ostream & os,const ParsedClientHello & parsed_chlo)428 std::ostream& operator<<(std::ostream& os,
429 const ParsedClientHello& parsed_chlo) {
430 os << "{ sni:" << parsed_chlo.sni << ", uaid:" << parsed_chlo.uaid
431 << ", alpns:" << quiche::PrintElements(parsed_chlo.alpns)
432 << ", supported_groups:"
433 << quiche::PrintElements(parsed_chlo.supported_groups)
434 << ", resumption_attempted:" << parsed_chlo.resumption_attempted
435 << ", early_data_attempted:" << parsed_chlo.early_data_attempted
436 << ", len(retry_token):" << parsed_chlo.retry_token.size() << " }";
437 return os;
438 }
439
QuicPriorityTypeToString(QuicPriorityType type)440 QUICHE_EXPORT std::string QuicPriorityTypeToString(QuicPriorityType type) {
441 switch (type) {
442 case quic::QuicPriorityType::kHttp:
443 return "HTTP (RFC 9218)";
444 case quic::QuicPriorityType::kWebTransport:
445 return "WebTransport (W3C API)";
446 }
447 return "(unknown)";
448 }
operator <<(std::ostream & os,QuicPriorityType type)449 QUICHE_EXPORT std::ostream& operator<<(std::ostream& os,
450 QuicPriorityType type) {
451 os << QuicPriorityTypeToString(type);
452 return os;
453 }
454
EcnCodepointToString(QuicEcnCodepoint ecn)455 std::string EcnCodepointToString(QuicEcnCodepoint ecn) {
456 switch (ecn) {
457 case ECN_NOT_ECT:
458 return "Not-ECT";
459 case ECN_ECT0:
460 return "ECT(0)";
461 case ECN_ECT1:
462 return "ECT(1)";
463 case ECN_CE:
464 return "CE";
465 }
466 return ""; // Handle compilation on windows for invalid enums
467 }
468
469 #undef RETURN_STRING_LITERAL // undef for jumbo builds
470
471 } // namespace quic
472