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(NUM_FRAME_TYPES)
161 }
162 return absl::StrCat("Unknown(", static_cast<int>(t), ")");
163 }
164
operator <<(std::ostream & os,const QuicFrameType & t)165 std::ostream& operator<<(std::ostream& os, const QuicFrameType& t) {
166 os << QuicFrameTypeToString(t);
167 return os;
168 }
169
QuicIetfFrameTypeString(QuicIetfFrameType t)170 std::string QuicIetfFrameTypeString(QuicIetfFrameType t) {
171 if (IS_IETF_STREAM_FRAME(t)) {
172 return "IETF_STREAM";
173 }
174
175 switch (t) {
176 RETURN_STRING_LITERAL(IETF_PADDING);
177 RETURN_STRING_LITERAL(IETF_PING);
178 RETURN_STRING_LITERAL(IETF_ACK);
179 RETURN_STRING_LITERAL(IETF_ACK_ECN);
180 RETURN_STRING_LITERAL(IETF_RST_STREAM);
181 RETURN_STRING_LITERAL(IETF_STOP_SENDING);
182 RETURN_STRING_LITERAL(IETF_CRYPTO);
183 RETURN_STRING_LITERAL(IETF_NEW_TOKEN);
184 RETURN_STRING_LITERAL(IETF_MAX_DATA);
185 RETURN_STRING_LITERAL(IETF_MAX_STREAM_DATA);
186 RETURN_STRING_LITERAL(IETF_MAX_STREAMS_BIDIRECTIONAL);
187 RETURN_STRING_LITERAL(IETF_MAX_STREAMS_UNIDIRECTIONAL);
188 RETURN_STRING_LITERAL(IETF_DATA_BLOCKED);
189 RETURN_STRING_LITERAL(IETF_STREAM_DATA_BLOCKED);
190 RETURN_STRING_LITERAL(IETF_STREAMS_BLOCKED_BIDIRECTIONAL);
191 RETURN_STRING_LITERAL(IETF_STREAMS_BLOCKED_UNIDIRECTIONAL);
192 RETURN_STRING_LITERAL(IETF_NEW_CONNECTION_ID);
193 RETURN_STRING_LITERAL(IETF_RETIRE_CONNECTION_ID);
194 RETURN_STRING_LITERAL(IETF_PATH_CHALLENGE);
195 RETURN_STRING_LITERAL(IETF_PATH_RESPONSE);
196 RETURN_STRING_LITERAL(IETF_CONNECTION_CLOSE);
197 RETURN_STRING_LITERAL(IETF_APPLICATION_CLOSE);
198 RETURN_STRING_LITERAL(IETF_EXTENSION_MESSAGE_NO_LENGTH);
199 RETURN_STRING_LITERAL(IETF_EXTENSION_MESSAGE);
200 RETURN_STRING_LITERAL(IETF_EXTENSION_MESSAGE_NO_LENGTH_V99);
201 RETURN_STRING_LITERAL(IETF_EXTENSION_MESSAGE_V99);
202 default:
203 return absl::StrCat("Private value (", t, ")");
204 }
205 }
operator <<(std::ostream & os,const QuicIetfFrameType & c)206 std::ostream& operator<<(std::ostream& os, const QuicIetfFrameType& c) {
207 os << QuicIetfFrameTypeString(c);
208 return os;
209 }
210
TransmissionTypeToString(TransmissionType transmission_type)211 std::string TransmissionTypeToString(TransmissionType transmission_type) {
212 switch (transmission_type) {
213 RETURN_STRING_LITERAL(NOT_RETRANSMISSION);
214 RETURN_STRING_LITERAL(HANDSHAKE_RETRANSMISSION);
215 RETURN_STRING_LITERAL(ALL_ZERO_RTT_RETRANSMISSION);
216 RETURN_STRING_LITERAL(LOSS_RETRANSMISSION);
217 RETURN_STRING_LITERAL(PTO_RETRANSMISSION);
218 RETURN_STRING_LITERAL(PATH_RETRANSMISSION);
219 RETURN_STRING_LITERAL(ALL_INITIAL_RETRANSMISSION);
220 default:
221 // Some varz rely on this behavior for statistic collection.
222 if (transmission_type == LAST_TRANSMISSION_TYPE + 1) {
223 return "INVALID_TRANSMISSION_TYPE";
224 }
225 return absl::StrCat("Unknown(", static_cast<int>(transmission_type), ")");
226 }
227 }
228
operator <<(std::ostream & os,TransmissionType transmission_type)229 std::ostream& operator<<(std::ostream& os, TransmissionType transmission_type) {
230 os << TransmissionTypeToString(transmission_type);
231 return os;
232 }
233
PacketHeaderFormatToString(PacketHeaderFormat format)234 std::string PacketHeaderFormatToString(PacketHeaderFormat format) {
235 switch (format) {
236 RETURN_STRING_LITERAL(IETF_QUIC_LONG_HEADER_PACKET);
237 RETURN_STRING_LITERAL(IETF_QUIC_SHORT_HEADER_PACKET);
238 RETURN_STRING_LITERAL(GOOGLE_QUIC_PACKET);
239 default:
240 return absl::StrCat("Unknown (", static_cast<int>(format), ")");
241 }
242 }
243
QuicLongHeaderTypeToString(QuicLongHeaderType type)244 std::string QuicLongHeaderTypeToString(QuicLongHeaderType type) {
245 switch (type) {
246 RETURN_STRING_LITERAL(VERSION_NEGOTIATION);
247 RETURN_STRING_LITERAL(INITIAL);
248 RETURN_STRING_LITERAL(ZERO_RTT_PROTECTED);
249 RETURN_STRING_LITERAL(HANDSHAKE);
250 RETURN_STRING_LITERAL(RETRY);
251 RETURN_STRING_LITERAL(INVALID_PACKET_TYPE);
252 default:
253 return absl::StrCat("Unknown (", static_cast<int>(type), ")");
254 }
255 }
256
MessageStatusToString(MessageStatus message_status)257 std::string MessageStatusToString(MessageStatus message_status) {
258 switch (message_status) {
259 RETURN_STRING_LITERAL(MESSAGE_STATUS_SUCCESS);
260 RETURN_STRING_LITERAL(MESSAGE_STATUS_ENCRYPTION_NOT_ESTABLISHED);
261 RETURN_STRING_LITERAL(MESSAGE_STATUS_UNSUPPORTED);
262 RETURN_STRING_LITERAL(MESSAGE_STATUS_BLOCKED);
263 RETURN_STRING_LITERAL(MESSAGE_STATUS_TOO_LARGE);
264 RETURN_STRING_LITERAL(MESSAGE_STATUS_INTERNAL_ERROR);
265 default:
266 return absl::StrCat("Unknown(", static_cast<int>(message_status), ")");
267 }
268 }
269
MessageResultToString(MessageResult message_result)270 std::string MessageResultToString(MessageResult message_result) {
271 if (message_result.status != MESSAGE_STATUS_SUCCESS) {
272 return absl::StrCat("{", MessageStatusToString(message_result.status), "}");
273 }
274 return absl::StrCat("{MESSAGE_STATUS_SUCCESS,id=", message_result.message_id,
275 "}");
276 }
277
operator <<(std::ostream & os,const MessageResult & mr)278 std::ostream& operator<<(std::ostream& os, const MessageResult& mr) {
279 os << MessageResultToString(mr);
280 return os;
281 }
282
PacketNumberSpaceToString(PacketNumberSpace packet_number_space)283 std::string PacketNumberSpaceToString(PacketNumberSpace packet_number_space) {
284 switch (packet_number_space) {
285 RETURN_STRING_LITERAL(INITIAL_DATA);
286 RETURN_STRING_LITERAL(HANDSHAKE_DATA);
287 RETURN_STRING_LITERAL(APPLICATION_DATA);
288 default:
289 return absl::StrCat("Unknown(", static_cast<int>(packet_number_space),
290 ")");
291 }
292 }
293
SerializedPacketFateToString(SerializedPacketFate fate)294 std::string SerializedPacketFateToString(SerializedPacketFate fate) {
295 switch (fate) {
296 RETURN_STRING_LITERAL(DISCARD);
297 RETURN_STRING_LITERAL(COALESCE);
298 RETURN_STRING_LITERAL(BUFFER);
299 RETURN_STRING_LITERAL(SEND_TO_WRITER);
300 }
301 return absl::StrCat("Unknown(", static_cast<int>(fate), ")");
302 }
303
operator <<(std::ostream & os,SerializedPacketFate fate)304 std::ostream& operator<<(std::ostream& os, SerializedPacketFate fate) {
305 os << SerializedPacketFateToString(fate);
306 return os;
307 }
308
CongestionControlTypeToString(CongestionControlType cc_type)309 std::string CongestionControlTypeToString(CongestionControlType cc_type) {
310 switch (cc_type) {
311 case kCubicBytes:
312 return "CUBIC_BYTES";
313 case kRenoBytes:
314 return "RENO_BYTES";
315 case kBBR:
316 return "BBR";
317 case kBBRv2:
318 return "BBRv2";
319 case kPCC:
320 return "PCC";
321 case kGoogCC:
322 return "GoogCC";
323 }
324 return absl::StrCat("Unknown(", static_cast<int>(cc_type), ")");
325 }
326
EncryptionLevelToString(EncryptionLevel level)327 std::string EncryptionLevelToString(EncryptionLevel level) {
328 switch (level) {
329 RETURN_STRING_LITERAL(ENCRYPTION_INITIAL);
330 RETURN_STRING_LITERAL(ENCRYPTION_HANDSHAKE);
331 RETURN_STRING_LITERAL(ENCRYPTION_ZERO_RTT);
332 RETURN_STRING_LITERAL(ENCRYPTION_FORWARD_SECURE);
333 default:
334 return absl::StrCat("Unknown(", static_cast<int>(level), ")");
335 }
336 }
337
operator <<(std::ostream & os,EncryptionLevel level)338 std::ostream& operator<<(std::ostream& os, EncryptionLevel level) {
339 os << EncryptionLevelToString(level);
340 return os;
341 }
342
ClientCertModeToString(ClientCertMode mode)343 absl::string_view ClientCertModeToString(ClientCertMode mode) {
344 #define RETURN_REASON_LITERAL(x) \
345 case ClientCertMode::x: \
346 return #x
347 switch (mode) {
348 RETURN_REASON_LITERAL(kNone);
349 RETURN_REASON_LITERAL(kRequest);
350 RETURN_REASON_LITERAL(kRequire);
351 default:
352 return "<invalid>";
353 }
354 #undef RETURN_REASON_LITERAL
355 }
356
operator <<(std::ostream & os,ClientCertMode mode)357 std::ostream& operator<<(std::ostream& os, ClientCertMode mode) {
358 os << ClientCertModeToString(mode);
359 return os;
360 }
361
QuicConnectionCloseTypeString(QuicConnectionCloseType type)362 std::string QuicConnectionCloseTypeString(QuicConnectionCloseType type) {
363 switch (type) {
364 RETURN_STRING_LITERAL(GOOGLE_QUIC_CONNECTION_CLOSE);
365 RETURN_STRING_LITERAL(IETF_QUIC_TRANSPORT_CONNECTION_CLOSE);
366 RETURN_STRING_LITERAL(IETF_QUIC_APPLICATION_CONNECTION_CLOSE);
367 default:
368 return absl::StrCat("Unknown(", static_cast<int>(type), ")");
369 }
370 }
371
operator <<(std::ostream & os,const QuicConnectionCloseType type)372 std::ostream& operator<<(std::ostream& os, const QuicConnectionCloseType type) {
373 os << QuicConnectionCloseTypeString(type);
374 return os;
375 }
376
AddressChangeTypeToString(AddressChangeType type)377 std::string AddressChangeTypeToString(AddressChangeType type) {
378 using IntType = typename std::underlying_type<AddressChangeType>::type;
379 switch (type) {
380 RETURN_STRING_LITERAL(NO_CHANGE);
381 RETURN_STRING_LITERAL(PORT_CHANGE);
382 RETURN_STRING_LITERAL(IPV4_SUBNET_CHANGE);
383 RETURN_STRING_LITERAL(IPV4_TO_IPV4_CHANGE);
384 RETURN_STRING_LITERAL(IPV4_TO_IPV6_CHANGE);
385 RETURN_STRING_LITERAL(IPV6_TO_IPV4_CHANGE);
386 RETURN_STRING_LITERAL(IPV6_TO_IPV6_CHANGE);
387 default:
388 return absl::StrCat("Unknown(", static_cast<IntType>(type), ")");
389 }
390 }
391
operator <<(std::ostream & os,AddressChangeType type)392 std::ostream& operator<<(std::ostream& os, AddressChangeType type) {
393 os << AddressChangeTypeToString(type);
394 return os;
395 }
396
KeyUpdateReasonString(KeyUpdateReason reason)397 std::string KeyUpdateReasonString(KeyUpdateReason reason) {
398 #define RETURN_REASON_LITERAL(x) \
399 case KeyUpdateReason::x: \
400 return #x
401 switch (reason) {
402 RETURN_REASON_LITERAL(kInvalid);
403 RETURN_REASON_LITERAL(kRemote);
404 RETURN_REASON_LITERAL(kLocalForTests);
405 RETURN_REASON_LITERAL(kLocalForInteropRunner);
406 RETURN_REASON_LITERAL(kLocalAeadConfidentialityLimit);
407 RETURN_REASON_LITERAL(kLocalKeyUpdateLimitOverride);
408 default:
409 return absl::StrCat("Unknown(", static_cast<int>(reason), ")");
410 }
411 #undef RETURN_REASON_LITERAL
412 }
413
operator <<(std::ostream & os,const KeyUpdateReason reason)414 std::ostream& operator<<(std::ostream& os, const KeyUpdateReason reason) {
415 os << KeyUpdateReasonString(reason);
416 return os;
417 }
418
operator ==(const ParsedClientHello & a,const ParsedClientHello & b)419 bool operator==(const ParsedClientHello& a, const ParsedClientHello& b) {
420 return a.sni == b.sni && a.uaid == b.uaid && a.alpns == b.alpns &&
421 a.retry_token == b.retry_token &&
422 a.resumption_attempted == b.resumption_attempted &&
423 a.early_data_attempted == b.early_data_attempted;
424 }
425
operator <<(std::ostream & os,const ParsedClientHello & parsed_chlo)426 std::ostream& operator<<(std::ostream& os,
427 const ParsedClientHello& parsed_chlo) {
428 os << "{ sni:" << parsed_chlo.sni << ", uaid:" << parsed_chlo.uaid
429 << ", alpns:" << quiche::PrintElements(parsed_chlo.alpns)
430 << ", len(retry_token):" << parsed_chlo.retry_token.size() << " }";
431 return os;
432 }
433
QuicPriorityTypeToString(QuicPriorityType type)434 QUICHE_EXPORT std::string QuicPriorityTypeToString(QuicPriorityType type) {
435 switch (type) {
436 case quic::QuicPriorityType::kHttp:
437 return "HTTP (RFC 9218)";
438 case quic::QuicPriorityType::kWebTransport:
439 return "WebTransport (W3C API)";
440 }
441 return "(unknown)";
442 }
operator <<(std::ostream & os,QuicPriorityType type)443 QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
444 QuicPriorityType type) {
445 os << QuicPriorityTypeToString(type);
446 return os;
447 }
448
EcnCodepointToString(QuicEcnCodepoint ecn)449 std::string EcnCodepointToString(QuicEcnCodepoint ecn) {
450 switch (ecn) {
451 case ECN_NOT_ECT:
452 return "Not-ECT";
453 case ECN_ECT0:
454 return "ECT(0)";
455 case ECN_ECT1:
456 return "ECT(1)";
457 case ECN_CE:
458 return "CE";
459 }
460 return ""; // Handle compilation on windows for invalid enums
461 }
462
463 #undef RETURN_STRING_LITERAL // undef for jumbo builds
464
465 } // namespace quic
466