idnits 2.17.1 draft-ietf-quic-qlog-quic-events-01.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- ** The abstract seems to contain references ([QLOG-MAIN]), which it shouldn't. Please replace those with straight textual mentions of the documents in question. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year -- The document date (7 March 2022) is 771 days in the past. Is this intentional? Checking references for intended status: Proposed Standard ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) -- Looks like a reference, but probably isn't: '1' on line 1733 -- Looks like a reference, but probably isn't: '2' on line 1733 -- Looks like a reference, but probably isn't: '4' on line 1733 -- Looks like a reference, but probably isn't: '5' on line 1733 -- Looks like a reference, but probably isn't: '7' on line 1733 -- Looks like a reference, but probably isn't: '10' on line 1733 -- Looks like a reference, but probably isn't: '22' on line 1733 -- Looks like a reference, but probably isn't: '120' on line 1754 == Missing Reference: '0-9' is mentioned on line 2027, but not defined == Outdated reference: A later version (-07) exists of draft-ietf-quic-qlog-h3-events-01 == Outdated reference: A later version (-08) exists of draft-ietf-quic-qlog-main-schema-03 Summary: 1 error (**), 0 flaws (~~), 4 warnings (==), 9 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 QUIC R. Marx 3 Internet-Draft KU Leuven 4 Intended status: Standards Track L. Niccolini, Ed. 5 Expires: 8 September 2022 Facebook 6 M. Seemann, Ed. 7 Protocol Labs 8 7 March 2022 10 QUIC event definitions for qlog 11 draft-ietf-quic-qlog-quic-events-01 13 Abstract 15 This document describes concrete qlog event definitions and their 16 metadata for QUIC events. These events can then be embedded in the 17 higher level schema defined in [QLOG-MAIN]. 19 Status of This Memo 21 This Internet-Draft is submitted in full conformance with the 22 provisions of BCP 78 and BCP 79. 24 Internet-Drafts are working documents of the Internet Engineering 25 Task Force (IETF). Note that other groups may also distribute 26 working documents as Internet-Drafts. The list of current Internet- 27 Drafts is at https://datatracker.ietf.org/drafts/current/. 29 Internet-Drafts are draft documents valid for a maximum of six months 30 and may be updated, replaced, or obsoleted by other documents at any 31 time. It is inappropriate to use Internet-Drafts as reference 32 material or to cite them other than as "work in progress." 34 This Internet-Draft will expire on 8 September 2022. 36 Copyright Notice 38 Copyright (c) 2022 IETF Trust and the persons identified as the 39 document authors. All rights reserved. 41 This document is subject to BCP 78 and the IETF Trust's Legal 42 Provisions Relating to IETF Documents (https://trustee.ietf.org/ 43 license-info) in effect on the date of publication of this document. 44 Please review these documents carefully, as they describe your rights 45 and restrictions with respect to this document. Code Components 46 extracted from this document must include Revised BSD License text as 47 described in Section 4.e of the Trust Legal Provisions and are 48 provided without warranty as described in the Revised BSD License. 50 Table of Contents 52 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 4 53 1.1. Notational Conventions . . . . . . . . . . . . . . . . . 4 54 2. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . 4 55 2.1. Links to the main schema . . . . . . . . . . . . . . . . 5 56 2.1.1. Raw packet and frame information . . . . . . . . . . 5 57 2.1.2. Events not belonging to a single connection . . . . . 6 58 3. QUIC event definitions . . . . . . . . . . . . . . . . . . . 6 59 3.1. connectivity . . . . . . . . . . . . . . . . . . . . . . 7 60 3.1.1. server_listening . . . . . . . . . . . . . . . . . . 7 61 3.1.2. connection_started . . . . . . . . . . . . . . . . . 7 62 3.1.3. connection_closed . . . . . . . . . . . . . . . . . . 8 63 3.1.4. connection_id_updated . . . . . . . . . . . . . . . . 9 64 3.1.5. spin_bit_updated . . . . . . . . . . . . . . . . . . 10 65 3.1.6. connection_retried . . . . . . . . . . . . . . . . . 10 66 3.1.7. connection_state_updated . . . . . . . . . . . . . . 10 67 3.1.8. MIGRATION-related events . . . . . . . . . . . . . . 13 68 3.2. security . . . . . . . . . . . . . . . . . . . . . . . . 13 69 3.2.1. key_updated . . . . . . . . . . . . . . . . . . . . . 13 70 3.2.2. key_retired . . . . . . . . . . . . . . . . . . . . . 14 71 3.3. transport . . . . . . . . . . . . . . . . . . . . . . . . 14 72 3.3.1. version_information . . . . . . . . . . . . . . . . . 14 73 3.3.2. alpn_information . . . . . . . . . . . . . . . . . . 15 74 3.3.3. parameters_set . . . . . . . . . . . . . . . . . . . 16 75 3.3.4. parameters_restored . . . . . . . . . . . . . . . . . 18 76 3.3.5. packet_sent . . . . . . . . . . . . . . . . . . . . . 18 77 3.3.6. packet_received . . . . . . . . . . . . . . . . . . . 19 78 3.3.7. packet_dropped . . . . . . . . . . . . . . . . . . . 20 79 3.3.8. packet_buffered . . . . . . . . . . . . . . . . . . . 21 80 3.3.9. packets_acked . . . . . . . . . . . . . . . . . . . . 22 81 3.3.10. datagrams_sent . . . . . . . . . . . . . . . . . . . 23 82 3.3.11. datagrams_received . . . . . . . . . . . . . . . . . 23 83 3.3.12. datagram_dropped . . . . . . . . . . . . . . . . . . 24 84 3.3.13. stream_state_updated . . . . . . . . . . . . . . . . 24 85 3.3.14. frames_processed . . . . . . . . . . . . . . . . . . 26 86 3.3.15. data_moved . . . . . . . . . . . . . . . . . . . . . 27 87 3.4. recovery . . . . . . . . . . . . . . . . . . . . . . . . 28 88 3.4.1. parameters_set . . . . . . . . . . . . . . . . . . . 28 89 3.4.2. metrics_updated . . . . . . . . . . . . . . . . . . . 29 90 3.4.3. congestion_state_updated . . . . . . . . . . . . . . 30 91 3.4.4. loss_timer_updated . . . . . . . . . . . . . . . . . 31 92 3.4.5. packet_lost . . . . . . . . . . . . . . . . . . . . . 32 93 3.4.6. marked_for_retransmit . . . . . . . . . . . . . . . . 33 94 4. Security Considerations . . . . . . . . . . . . . . . . . . . 33 95 5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 33 96 6. References . . . . . . . . . . . . . . . . . . . . . . . . . 33 97 6.1. Normative References . . . . . . . . . . . . . . . . . . 33 98 6.2. Informative References . . . . . . . . . . . . . . . . . 34 99 Appendix A. QUIC data field definitions . . . . . . . . . . . . 34 100 A.1. ProtocolEventBody extension . . . . . . . . . . . . . . . 34 101 A.2. QuicVersion . . . . . . . . . . . . . . . . . . . . . . . 35 102 A.3. ConnectionID . . . . . . . . . . . . . . . . . . . . . . 35 103 A.4. Owner . . . . . . . . . . . . . . . . . . . . . . . . . . 35 104 A.5. IPAddress and IPVersion . . . . . . . . . . . . . . . . . 35 105 A.6. PacketType . . . . . . . . . . . . . . . . . . . . . . . 36 106 A.7. PacketNumberSpace . . . . . . . . . . . . . . . . . . . . 36 107 A.8. PacketHeader . . . . . . . . . . . . . . . . . . . . . . 36 108 A.9. Token . . . . . . . . . . . . . . . . . . . . . . . . . . 37 109 A.10. KeyType . . . . . . . . . . . . . . . . . . . . . . . . . 37 110 A.11. QUIC Frames . . . . . . . . . . . . . . . . . . . . . . . 37 111 A.11.1. PaddingFrame . . . . . . . . . . . . . . . . . . . . 38 112 A.11.2. PingFrame . . . . . . . . . . . . . . . . . . . . . 38 113 A.11.3. AckFrame . . . . . . . . . . . . . . . . . . . . . . 38 114 A.11.4. ResetStreamFrame . . . . . . . . . . . . . . . . . . 39 115 A.11.5. StopSendingFrame . . . . . . . . . . . . . . . . . . 40 116 A.11.6. CryptoFrame . . . . . . . . . . . . . . . . . . . . 40 117 A.11.7. NewTokenFrame . . . . . . . . . . . . . . . . . . . 40 118 A.11.8. StreamFrame . . . . . . . . . . . . . . . . . . . . 41 119 A.11.9. MaxDataFrame . . . . . . . . . . . . . . . . . . . . 41 120 A.11.10. MaxStreamDataFrame . . . . . . . . . . . . . . . . . 41 121 A.11.11. MaxStreamsFrame . . . . . . . . . . . . . . . . . . 42 122 A.11.12. DataBlockedFrame . . . . . . . . . . . . . . . . . . 42 123 A.11.13. StreamDataBlockedFrame . . . . . . . . . . . . . . . 42 124 A.11.14. StreamsBlockedFrame . . . . . . . . . . . . . . . . 42 125 A.11.15. NewConnectionIDFrame . . . . . . . . . . . . . . . . 42 126 A.11.16. RetireConnectionIDFrame . . . . . . . . . . . . . . 43 127 A.11.17. PathChallengeFrame . . . . . . . . . . . . . . . . . 43 128 A.11.18. PathResponseFrame . . . . . . . . . . . . . . . . . 43 129 A.11.19. ConnectionCloseFrame . . . . . . . . . . . . . . . . 44 130 A.11.20. HandshakeDoneFrame . . . . . . . . . . . . . . . . . 44 131 A.11.21. UnknownFrame . . . . . . . . . . . . . . . . . . . . 44 132 A.11.22. TransportError . . . . . . . . . . . . . . . . . . . 44 133 A.11.23. ApplicationError . . . . . . . . . . . . . . . . . . 45 134 A.11.24. CryptoError . . . . . . . . . . . . . . . . . . . . 45 135 Appendix B. Change Log . . . . . . . . . . . . . . . . . . . . . 45 136 B.1. Since draft-ietf-qlog-quic-events-00: . . . . . . . . . . 45 137 B.2. Since draft-marx-qlog-event-definitions-quic-h3-02: . . . 46 138 B.3. Since draft-marx-qlog-event-definitions-quic-h3-01: . . . 46 139 B.4. Since draft-marx-qlog-event-definitions-quic-h3-00: . . . 47 140 Appendix C. Design Variations . . . . . . . . . . . . . . . . . 48 141 Appendix D. Acknowledgements . . . . . . . . . . . . . . . . . . 48 142 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 48 144 1. Introduction 146 This document describes the values of the qlog name ("category" + 147 "event") and "data" fields and their semantics for the QUIC protocol. 148 This document is based on draft-34 of the QUIC I-Ds [QUIC-TRANSPORT], 149 [QUIC-RECOVERY], and [QUIC-TLS]. HTTP/3 and QPACK events are defined 150 in a separate document [QLOG-H3]. 152 Feedback and discussion are welcome at https://github.com/quicwg/qlog 153 (https://github.com/quicwg/qlog). Readers are advised to refer to 154 the "editor's draft" at that URL for an up-to-date version of this 155 document. 157 Concrete examples of integrations of this schema in various 158 programming languages can be found at https://github.com/quiclog/ 159 qlog/ (https://github.com/quiclog/qlog/). 161 1.1. Notational Conventions 163 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 164 "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this 165 document are to be interpreted as described in [RFC2119]. 167 The event and data structure definitions in ths document are 168 expressed in the Concise Data Definition Language [CDDL] and its 169 extensions described in [QLOG-MAIN]. 171 2. Overview 173 This document describes the values of the qlog "name" ("category" + 174 "event") and "data" fields and their semantics for the QUIC protocol. 176 This document assumes the usage of the encompassing main qlog schema 177 defined in [QLOG-MAIN]. Each subsection below defines a separate 178 category (for example connectivity, transport, recovery) and each 179 subsubsection is an event type (for example packet_received). 181 For each event type, its importance and data definition is laid out, 182 often accompanied by possible values for the optional "trigger" 183 field. For the definition and semantics of "importance" and 184 "trigger", see the main schema document. 186 Most of the complex datastructures, enums and re-usable definitions 187 are grouped together on the bottom of this document for clarity. 189 2.1. Links to the main schema 191 This document re-uses all the fields defined in the main qlog schema 192 (e.g., name, category, type, data, group_id, protocol_type, the time- 193 related fields, importance, RawInfo, etc.). 195 One entry in the "protocol_type" qlog array field MUST be "QUIC" if 196 events from this document are included in a qlog trace. 198 When the qlog "group_id" field is used, it is recommended to use 199 QUIC's Original Destination Connection ID (ODCID, the CID chosen by 200 the client when first contacting the server), as this is the only 201 value that does not change over the course of the connection and can 202 be used to link more advanced QUIC packets (e.g., Retry, Version 203 Negotiation) to a given connection. Similarly, the ODCID should be 204 used as the qlog filename or file identifier, potentially suffixed by 205 the vantagepoint type (For example, abcd1234_server.qlog would 206 contain the server-side trace of the connection with ODCID abcd1234). 208 2.1.1. Raw packet and frame information 210 This document re-uses the definition of the RawInfo data class from 211 [QLOG-MAIN]. 213 Note: QUIC packets always include an AEAD authentication tag 214 ("trailer") at the end. As this tag is always the same size for a 215 given connection (it depends on the used TLS cipher), this 216 document does not define a separate "RawInfo:aead_tag_length" 217 field here. Instead, this field is reflected in 218 "transport:parameters_set" and can be logged only once. 220 Note: As QUIC uses trailers in packets, packet header_lengths can be 221 calculated as: 223 header_length = length - payload_length - aead_tag_length 225 For UDP datagrams, the calulation is simpler: 227 header_length = length - payload_length 229 Note: In some cases, the length fields are also explicitly reflected 230 inside of packet headers. For example, the QUIC STREAM frame has 231 a "length" field indicating its payload size. Similarly, the QUIC 232 Long Header has a "length" field which is equal to the payload 233 length plus the packet number length. In these cases, those 234 fields are intentionally preserved in the event definitions. Even 235 though this can lead to duplicate data when the full RawInfo is 236 logged, it allows a more direct mapping of the QUIC specifications 237 to qlog, making it easier for users to interpret. 239 2.1.2. Events not belonging to a single connection 241 For several types of events, it is sometimes impossible to tie them 242 to a specific conceptual QUIC connection (e.g., a packet_dropped 243 event triggered because the packet has an unknown connection_id in 244 the header). Since qlog events in a trace are typically associated 245 with a single connection, it is unclear how to log these events. 247 Ideally, implementers SHOULD create a separate, individual "endpoint- 248 level" trace file (or group_id value), not associated with a specific 249 connection (for example a "server.qlog" or group_id = "client"), and 250 log all events that do not belong to a single connection to this 251 grouping trace. However, this is not always practical, depending on 252 the implementation. Because the semantics of most of these events 253 are well-defined in the protocols and because they are difficult to 254 mis-interpret as belonging to a connection, implementers MAY choose 255 to log events not belonging to a particular connection in any other 256 trace, even those strongly associated with a single connection. 258 Note that this can make it difficult to match logs from different 259 vantage points with each other. For example, from the client side, 260 it is easy to log connections with version negotiation or retry in 261 the same trace, while on the server they would most likely be logged 262 in separate traces. Servers can take extra efforts (and keep 263 additional state) to keep these events combined in a single trace 264 however (for example by also matching connections on their four-tuple 265 instead of just the connection ID). 267 3. QUIC event definitions 269 Each subheading in this section is a qlog event category, while each 270 sub-subheading is a qlog event type. Concretely, for the following 271 two items, we have the category "connectivity" and event type 272 "server_listening", resulting in a concatenated qlog "name" field 273 value of "connectivity:server_listening". 275 3.1. connectivity 277 3.1.1. server_listening 279 Importance: Extra 281 Emitted when the server starts accepting connections. 283 Definition: 285 ConnectivityServerListening = { 286 ? ip_v4: IPAddress 287 ? ip_v6: IPAddress 288 ? port_v4: uint16 289 ? port_v6: uint16 291 ; the server will always answer client initials with a retry 292 ; (no 1-RTT connection setups by choice) 293 ? retry_required: bool 294 } 296 Figure 1: ConnectivityServerListening definition 298 Note: some QUIC stacks do not handle sockets directly and are thus 299 unable to log IP and/or port information. 301 3.1.2. connection_started 303 Importance: Base 305 Used for both attempting (client-perspective) and accepting (server- 306 perspective) new connections. Note that this event has overlap with 307 connection_state_updated and this is a separate event mainly because 308 of all the additional data that should be logged. 310 Definition: 312 ConnectivityConnectionStarted = { 313 ? ip_version: IPVersion 314 src_ip: IPAddress 315 dst_ip: IPAddress 317 ; transport layer protocol 318 ? protocol: text .default "QUIC" 319 ? src_port: uint16 320 ? dst_port: uint16 322 ? src_cid: ConnectionID 323 ? dst_cid: ConnectionID 324 } 326 Figure 2: ConnectivityConnectionStarted definition 328 Note: some QUIC stacks do not handle sockets directly and are thus 329 unable to log IP and/or port information. 331 3.1.3. connection_closed 333 Importance: Base 335 Used for logging when a connection was closed, typically when an 336 error or timeout occurred. Note that this event has overlap with 337 connectivity:connection_state_updated, as well as the 338 CONNECTION_CLOSE frame. However, in practice, when analyzing large 339 deployments, it can be useful to have a single event representing a 340 connection_closed event, which also includes an additional reason 341 field to provide additional information. Additionally, it is useful 342 to log closures due to timeouts, which are difficult to reflect using 343 the other options. 345 In QUIC there are two main connection-closing error categories: 346 connection and application errors. They have well-defined error 347 codes and semantics. Next to these however, there can be internal 348 errors that occur that may or may not get mapped to the official 349 error codes in implementation-specific ways. As such, multiple error 350 codes can be set on the same event to reflect this. 352 Definition: 354 ConnectivityConnectionClosed = { 355 ; which side closed the connection 356 ? owner: Owner 358 ? connection_code: TransportError / CryptoError / uint32 359 ? application_code: $ApplicationError / uint32 360 ? internal_code: uint32 362 ? reason: text 363 ? trigger: 364 "clean" / 365 "handshake_timeout" / 366 "idle_timeout" / 367 ; this is called the "immediate close" in the QUIC RFC 368 "error" / 369 "stateless_reset" / 370 "version_mismatch" / 371 ; for example HTTP/3's GOAWAY frame 372 "application" 373 } 375 Figure 3: ConnectivityConnectionClosed definition 377 3.1.4. connection_id_updated 379 Importance: Base 381 This event is emitted when either party updates their current 382 Connection ID. As this typically happens only sparingly over the 383 course of a connection, this event allows loggers to be more 384 efficient than logging the observed CID with each packet in the 385 .header field of the "packet_sent" or "packet_received" events. 387 This is viewed from the perspective of the one applying the new id. 388 As such, if we receive a new connection id from our peer, we will see 389 the dst_ fields are set. If we update our own connection id (e.g., 390 NEW_CONNECTION_ID frame), we log the src_ fields. 392 Definition: 394 ConnectivityConnectionIDUpdated = { 395 owner: Owner 397 ? old: ConnectionID 398 ? new: ConnectionID 399 } 401 Figure 4: ConnectivityConnectionIDUpdated definition 403 3.1.5. spin_bit_updated 405 Importance: Base 407 To be emitted when the spin bit changes value. It SHOULD NOT be 408 emitted if the spin bit is set without changing its value. 410 Definition: 412 ConnectivitySpinBitUpdated = { 413 state: bool 414 } 416 Figure 5: ConnectivitySpinBitUpdated definition 418 3.1.6. connection_retried 420 TODO 422 3.1.7. connection_state_updated 424 Importance: Base 426 This event is used to track progress through QUIC's complex handshake 427 and connection close procedures. It is intended to provide 428 exhaustive options to log each state individually, but also provides 429 a more basic, simpler set for implementations less interested in 430 tracking each smaller state transition. As such, users should not 431 expect to see -all- these states reflected in all qlogs and 432 implementers should focus on support for the SimpleConnectionState 433 set. 435 Definition: 437 ConnectivityConnectionStateUpdated = { 438 ? old: ConnectionState / SimpleConnectionState 439 new: ConnectionState / SimpleConnectionState 440 } 442 ConnectionState = 443 ; initial sent/received 444 "attempted" / 445 ; peer address validated by: client sent Handshake packet OR 446 ; client used CONNID chosen by the server. 447 ; transport-draft-32, section-8.1 448 "peer_validated" / 449 "handshake_started" / 450 ; 1 RTT can be sent, but handshake isn't done yet 451 "early_write" / 452 ; TLS handshake complete: Finished received and sent 453 ; tls-draft-32, section-4.1.1 454 "handshake_complete" / 455 ; HANDSHAKE_DONE sent/received (connection is now "active", 1RTT 456 ; can be sent). tls-draft-32, section-4.1.2 457 "handshake_confirmed" / 458 "closing" / 459 ; connection_close sent/received 460 "draining" / 461 ; draining period done, connection state discarded 462 "closed" 464 SimpleConnectionState = 465 "attempted" / 466 "handshake_started" / 467 "handshake_confirmed" / 468 "closed" 470 Figure 6: ConnectivityConnectionStateUpdated definition 472 These states correspond to the following transitions for both client 473 and server: 475 *Client:* 477 * send initial 479 - state = attempted 481 * get initial 483 - state = validated _(not really "needed" at the client, but 484 somewhat useful to indicate progress nonetheless)_ 486 * get first Handshake packet 488 - state = handshake_started 490 * get Handshake packet containing ServerFinished 492 - state = handshake_complete 494 * send ClientFinished 496 - state = early_write (1RTT can now be sent) 498 * get HANDSHAKE_DONE 500 - state = handshake_confirmed 502 *Server:* 504 * get initial 506 - state = attempted 508 * send initial _(TODO don't think this needs a separate state, since 509 some handshake will always be sent in the same flight as this?)_ 511 * send handshake EE, CERT, CV, ... 513 - state = handshake_started 515 * send ServerFinished 517 - state = early_write (1RTT can now be sent) 519 * get first handshake packet / something using a server-issued CID 520 of min length 522 - state = validated 524 * get handshake packet containing ClientFinished 526 - state = handshake_complete 528 * send HANDSHAKE_DONE 530 - state = handshake_confirmed 532 Note: connection_state_changed with a new state of "attempted" is 533 the same conceptual event as the connection_started event above 534 from the client's perspective. Similarly, a state of "closing" or 535 "draining" corresponds to the connection_closed event. 537 3.1.8. MIGRATION-related events 539 e.g., path_updated 541 TODO: read up on the draft how migration works and whether to best 542 fit this here or in TRANSPORT TODO: integrate 543 https://tools.ietf.org/html/draft-deconinck-quic-multipath-02 545 For now, infer from other connectivity events and path_challenge/ 546 path_response frames 548 3.2. security 550 3.2.1. key_updated 552 Importance: Base 554 Note: secret_updated would be more correct, but in the draft it's 555 called KEY_UPDATE, so stick with that for consistency 557 Definition: 559 SecurityKeyUpdated = { 560 key_type: KeyType 562 ? old: hexstring 563 new: hexstring 565 ; needed for 1RTT key updates 566 ? generation: uint32 568 ? trigger: 569 ; (e.g., initial, handshake and 0-RTT keys 570 ; are generated by TLS) 571 "tls" / 572 "remote_update" / 573 "local_update" 574 } 576 Figure 7: SecurityKeyUpdated definition 578 3.2.2. key_retired 580 Importance: Base 582 Definition: 584 SecurityKeyRetired = { 585 key_type: KeyType 586 ? key: hexstring 588 ; needed for 1RTT key updates 589 ? generation: uint32 591 ? trigger: 592 ; (e.g., initial, handshake and 0-RTT keys 593 ; are generated by TLS) 594 "tls" / 595 "remote_update" / 596 "local_update" 597 } 599 Figure 8: SecurityKeyRetired definition 601 3.3. transport 603 3.3.1. version_information 605 Importance: Core 607 QUIC endpoints each have their own list of of QUIC versions they 608 support. The client uses the most likely version in their first 609 initial. If the server does support that version, it replies with a 610 version_negotiation packet, containing supported versions. From 611 this, the client selects a version. This event aggregates all this 612 information in a single event type. It also allows logging of 613 supported versions at an endpoint without actual version negotiation 614 needing to happen. 616 Definition: 618 TransportVersionInformation = { 619 ? server_versions: [+ QuicVersion] 620 ? client_versions: [+ QuicVersion] 621 ? chosen_version: QuicVersion 622 } 624 Figure 9: TransportVersionInformation definition 626 Intended use: 628 * When sending an initial, the client logs this event with 629 client_versions and chosen_version set 631 * Upon receiving a client initial with a supported version, the 632 server logs this event with server_versions and chosen_version set 634 * Upon receiving a client initial with an unsupported version, the 635 server logs this event with server_versions set and 636 client_versions to the single-element array containing the 637 client's attempted version. The absence of chosen_version implies 638 no overlap was found. 640 * Upon receiving a version negotiation packet from the server, the 641 client logs this event with client_versions set and 642 server_versions to the versions in the version negotiation packet 643 and chosen_version to the version it will use for the next initial 644 packet 646 3.3.2. alpn_information 648 Importance: Core 650 QUIC implementations each have their own list of application level 651 protocols and versions thereof they support. The client includes a 652 list of their supported options in its first initial as part of the 653 TLS Application Layer Protocol Negotiation (alpn) extension. If 654 there are common option(s), the server chooses the most optimal one 655 and communicates this back to the client. If not, the connection is 656 closed. 658 Definition: 660 TransportALPNInformation = { 661 ? server_alpns: [* text] 662 ? client_alpns: [* text] 663 ? chosen_alpn: text 664 } 666 Figure 10: TransportALPNInformation definition 668 Intended use: 670 * When sending an initial, the client logs this event with 671 client_alpns set 673 * When receiving an initial with a supported alpn, the server logs 674 this event with server_alpns set, client_alpns equalling the 675 client-provided list, and chosen_alpn to the value it will send 676 back to the client. 678 * When receiving an initial with an alpn, the client logs this event 679 with chosen_alpn to the received value. 681 * Alternatively, a client can choose to not log the first event, but 682 wait for the receipt of the server initial to log this event with 683 both client_alpns and chosen_alpn set. 685 3.3.3. parameters_set 687 Importance: Core 689 This event groups settings from several different sources (transport 690 parameters, TLS ciphers, etc.) into a single event. This is done to 691 minimize the amount of events and to decouple conceptual setting 692 impacts from their underlying mechanism for easier high-level 693 reasoning. 695 All these settings are typically set once and never change. However, 696 they are typically set at different times during the connection, so 697 there will typically be several instances of this event with 698 different fields set. 700 Note that some settings have two variations (one set locally, one 701 requested by the remote peer). This is reflected in the "owner" 702 field. As such, this field MUST be correct for all settings included 703 a single event instance. If you need to log settings from two sides, 704 you MUST emit two separate event instances. 706 In the case of connection resumption and 0-RTT, some of the server's 707 parameters are stored up-front at the client and used for the initial 708 connection startup. They are later updated with the server's reply. 709 In these cases, utilize the separate parameters_restored event to 710 indicate the initial values, and this event to indicate the updated 711 values, as normal. 713 Definition: 715 TransportParametersSet = { 716 ? owner: Owner 718 ; true if valid session ticket was received 719 ? resumption_allowed: bool 720 ; true if early data extension was enabled on the TLS layer 721 ? early_data_enabled: bool 723 ; e.g., "AES_128_GCM_SHA256" 724 ? tls_cipher: text 726 ; depends on the TLS cipher, but it's easier to be explicit. 727 ; in bytes 728 ? aead_tag_length: uint8 .default 16 730 ; transport parameters from the TLS layer: 731 ? original_destination_connection_id: ConnectionID 732 ? initial_source_connection_id: ConnectionID 733 ? retry_source_connection_id: ConnectionID 734 ? stateless_reset_token: Token 735 ? disable_active_migration: bool 737 ? max_idle_timeout: uint64 738 ? max_udp_payload_size: uint32 739 ? ack_delay_exponent: uint16 740 ? max_ack_delay: uint16 741 ? active_connection_id_limit: uint32 743 ? initial_max_data: uint64 744 ? initial_max_stream_data_bidi_local: uint64 745 ? initial_max_stream_data_bidi_remote: uint64 746 ? initial_max_stream_data_uni: uint64 747 ? initial_max_streams_bidi: uint64 748 ? initial_max_streams_uni: uint64 750 ? preferred_address: PreferredAddress 751 } 753 PreferredAddress = { 754 ip_v4: IPAddress 755 ip_v6: IPAddress 757 port_v4: uint16 758 port_v6: uint16 760 connection_id: ConnectionID 761 stateless_reset_token: Token 762 } 764 Figure 11: TransportParametersSet definition 766 Additionally, this event can contain any number of unspecified 767 fields. This is to reflect setting of for example unknown (greased) 768 transport parameters or employed (proprietary) extensions. 770 3.3.4. parameters_restored 772 Importance: Base 774 When using QUIC 0-RTT, clients are expected to remember and restore 775 the server's transport parameters from the previous connection. This 776 event is used to indicate which parameters were restored and to which 777 values when utilizing 0-RTT. Note that not all transport parameters 778 should be restored (many are even prohibited from being re-utilized). 779 The ones listed here are the ones expected to be useful for correct 780 0-RTT usage. 782 Definition: 784 TransportParametersRestored = { 785 ? disable_active_migration: bool 787 ? max_idle_timeout: uint64 788 ? max_udp_payload_size: uint32 789 ? active_connection_id_limit: uint32 791 ? initial_max_data: uint64 792 ? initial_max_stream_data_bidi_local: uint64 793 ? initial_max_stream_data_bidi_remote: uint64, 794 ? initial_max_stream_data_uni: uint64 795 ? initial_max_streams_bidi: uint64 796 ? initial_max_streams_uni: uint64 797 } 799 Figure 12: TransportParametersRestored definition 801 Note that, like parameters_set above, this event can contain any 802 number of unspecified fields to allow for additional/custom 803 parameters. 805 3.3.5. packet_sent 807 Importance: Core 809 Definition: 811 TransportPacketSent = { 812 header: PacketHeader 814 ; see appendix for the QuicFrame definitions 815 ? frames: [* QuicFrame] 817 ? is_coalesced: bool .default false 819 ; only if header.packet_type === "retry" 820 ? retry_token: Token 822 ; only if header.packet_type === "stateless_reset" 823 ; is always 128 bits in length. 824 ? stateless_reset_token: hexstring .size 16 826 ; only if header.packet_type === "version_negotiation" 827 ? supported_versions: [+ QuicVersion] 829 ? raw: RawInfo 830 ? datagram_id: uint32 832 ? trigger: 833 ; draft-23 5.1.1 834 "retransmit_reordered" / 835 ; draft-23 5.1.2 836 "retransmit_timeout" / 837 ; draft-23 5.3.1 838 "pto_probe" / 839 ; draft-19 6.2 840 "retransmit_crypto" / 841 ; needed for some CCs to figure out bandwidth allocations 842 ; when there are no normal sends 843 "cc_bandwidth_probe" 844 } 846 Figure 13: TransportPacketSent definition 848 Note: We do not explicitly log the encryption_level or 849 packet_number_space: the header.packet_type specifies this by 850 inference (assuming correct implementation) 852 Note: for more details on "datagram_id", see Section 3.3.10. It is 853 only needed when keeping track of packet coalescing. 855 3.3.6. packet_received 857 Importance: Core 858 Definition: 860 TransportPacketReceived = { 861 header: PacketHeader 863 ; see appendix for the definitions 864 ? frames: [* QuicFrame] 866 ? is_coalesced: bool .default false 868 ; only if header.packet_type === "retry" 869 ? retry_token: Token 871 ; only if header.packet_type === "stateless_reset" 872 ; Is always 128 bits in length. 873 ? stateless_reset_token: hexstring .size 16 875 ; only if header.packet_type === "version_negotiation" 876 ? supported_versions: [+ QuicVersion] 878 ? raw: RawInfo 879 ? datagram_id: uint32 881 ? trigger: 882 ; if packet was buffered because 883 ; it couldn't be decrypted before 884 "keys_available" 885 } 887 Figure 14: TransportPacketReceived definition 889 Note: We do not explicitly log the encryption_level or 890 packet_number_space: the header.packet_type specifies this by 891 inference (assuming correct implementation) 893 Note: for more details on "datagram_id", see Section 3.3.10. It is 894 only needed when keeping track of packet coalescing. 896 3.3.7. packet_dropped 898 Importance: Base 900 This event indicates a QUIC-level packet was dropped after partial or 901 no parsing. 903 Definition: 905 TransportPacketDropped = { 906 ; primarily packet_type should be filled here, 907 ; as other fields might not be parseable 908 ? header: PacketHeader 910 ? raw: RawInfo 911 ? datagram_id: uint32 913 ? trigger: 914 "key_unavailable" / 915 "unknown_connection_id" / 916 "header_parse_error" / 917 "payload_decrypt_error" / 918 "protocol_violation" / 919 "dos_prevention" / 920 "unsupported_version" / 921 "unexpected_packet" / 922 "unexpected_source_connection_id" / 923 "unexpected_version" / 924 "duplicate" / 925 "invalid_initial" 926 } 928 Figure 15: TransportPacketDropped definition 930 Note: sometimes packets are dropped before they can be associated 931 with a particular connection (e.g., in case of 932 "unsupported_version"). This situation is discussed more in 933 Section 2.1.2. 935 Note: for more details on "datagram_id", see Section 3.3.10. It is 936 only needed when keeping track of packet coalescing. 938 3.3.8. packet_buffered 940 Importance: Base 942 This event is emitted when a packet is buffered because it cannot be 943 processed yet. Typically, this is because the packet cannot be 944 parsed yet, and thus we only log the full packet contents when it was 945 parsed in a packet_received event. 947 Definition: 949 TransportPacketBuffered = { 950 ; primarily packet_type and possible packet_number should be 951 ; filled here as other elements might not be available yet 952 ? header: PacketHeader 954 ? raw: RawInfo 955 ? datagram_id: uint32 957 ? trigger: 958 ; indicates the parser cannot keep up, temporarily buffers 959 ; packet for later processing 960 "backpressure" / 961 ; if packet cannot be decrypted because the proper keys were 962 ; not yet available 963 "keys_unavailable" 964 } 966 Figure 16: TransportPacketBuffered definition 968 Note: for more details on "datagram_id", see Section 3.3.10. It is 969 only needed when keeping track of packet coalescing. 971 3.3.9. packets_acked 973 Importance: Extra 975 This event is emitted when a (group of) sent packet(s) is 976 acknowledged by the remote peer _for the first time_. This 977 information could also be deduced from the contents of received ACK 978 frames. However, ACK frames require additional processing logic to 979 determine when a given packet is acknowledged for the first time, as 980 QUIC uses ACK ranges which can include repeated ACKs. Additionally, 981 this event can be used by implementations that do not log frame 982 contents. 984 Definition: 986 TransportPacketsAcked = { 987 ? packet_number_space: PacketNumberSpace 989 ? packet_numbers: [+ uint64] 990 } 992 Figure 17: TransportPacketsAcked definition 994 Note: if packet_number_space is omitted, it assumes the default value 995 of PacketNumberSpace.application_data, as this is by far the most 996 prevalent packet number space a typical QUIC connection will use. 998 3.3.10. datagrams_sent 1000 Importance: Extra 1002 When we pass one or more UDP-level datagrams to the socket. This is 1003 useful for determining how QUIC packet buffers are drained to the OS. 1005 Definition: 1007 TransportDatagramsSent = { 1008 ; to support passing multiple at once 1009 ? count: uint16 1011 ; RawInfo:length field indicates total length of the datagrams 1012 ; including UDP header length 1013 ? raw: [+ RawInfo] 1015 ? datagram_ids: [+ uint32] 1016 } 1018 Figure 18: TransportDatagramsSent definition 1020 Note: QUIC itself does not have a concept of a "datagram_id". This 1021 field is a purely qlog-specific construct to allow tracking how 1022 multiple QUIC packets are coalesced inside of a single UDP datagram, 1023 which is an important optimization during the QUIC handshake. For 1024 this, implementations assign a (per-endpoint) unique ID to each 1025 datagram and keep track of which packets were coalesced into the same 1026 datagram. As packet coalescing typically only happens during the 1027 handshake (as it requires at least one long header packet), this can 1028 be done without much overhead. 1030 3.3.11. datagrams_received 1032 Importance: Extra 1034 When we receive one or more UDP-level datagrams from the socket. 1035 This is useful for determining how datagrams are passed to the user 1036 space stack from the OS. 1038 Definition: 1040 TransportDatagramsReceived = { 1041 ; to support passing multiple at once 1042 ? count: uint16 1044 ; RawInfo:length field indicates total length of the datagrams 1045 ; including UDP header length 1046 ? raw: [+ RawInfo] 1048 ? datagram_ids: [+ uint32] 1049 } 1051 Figure 19: TransportDatagramsReceived definition 1053 Note: for more details on "datagram_ids", see Section 3.3.10. 1055 3.3.12. datagram_dropped 1057 Importance: Extra 1059 When we drop a UDP-level datagram. This is typically if it does not 1060 contain a valid QUIC packet (in that case, use packet_dropped 1061 instead). 1063 Definition: 1065 TransportDatagramDropped = { 1066 ? raw: RawInfo 1067 } 1069 Figure 20: TransportDatagramDropped definition 1071 3.3.13. stream_state_updated 1073 Importance: Base 1075 This event is emitted whenever the internal state of a QUIC stream is 1076 updated, as described in QUIC transport draft-23 section 3. Most of 1077 this can be inferred from several types of frames going over the 1078 wire, but it's much easier to have explicit signals for these state 1079 changes. 1081 Definition: 1083 StreamType = "unidirectional" / "bidirectional" 1085 TransportStreamStateUpdated = { 1086 stream_id: uint64 1088 ; mainly useful when opening the stream 1089 ? stream_type: StreamType 1091 ? old: StreamState 1092 new: StreamState 1094 ? stream_side: "sending" / "receiving" 1095 } 1097 StreamState = 1098 ; bidirectional stream states, draft-23 3.4. 1099 "idle" / 1100 "open" / 1101 "half_closed_local" / 1102 "half_closed_remote" / 1103 "closed" / 1105 ; sending-side stream states, draft-23 3.1. 1106 "ready" / 1107 "send" / 1108 "data_sent" / 1109 "reset_sent" / 1110 "reset_received" / 1112 ; receive-side stream states, draft-23 3.2. 1113 "receive" / 1114 "size_known" / 1115 "data_read" / 1116 "reset_read" / 1118 ; both-side states 1119 "data_received" / 1121 ; qlog-defined: 1122 ; memory actually freed 1123 "destroyed" 1125 Figure 21: TransportStreamStateUpdated definition 1127 Note: QUIC implementations SHOULD mainly log the simplified 1128 bidirectional (HTTP/2-alike) stream states (e.g., idle, open, closed) 1129 instead of the more finegrained stream states (e.g., data_sent, 1130 reset_received). These latter ones are mainly for more in-depth 1131 debugging. Tools SHOULD be able to deal with both types equally. 1133 3.3.14. frames_processed 1135 Importance: Extra 1137 This event's main goal is to prevent a large proliferation of 1138 specific purpose events (e.g., packets_acknowledged, 1139 flow_control_updated, stream_data_received). We want to give 1140 implementations the opportunity to (selectively) log this type of 1141 signal without having to log packet-level details (e.g., in 1142 packet_received). Since for almost all cases, the effects of 1143 applying a frame to the internal state of an implementation can be 1144 inferred from that frame's contents, we aggregate these events in 1145 this single "frames_processed" event. 1147 Note: This event can be used to signal internal state change not 1148 resulting directly from the actual "parsing" of a frame (e.g., the 1149 frame could have been parsed, data put into a buffer, then later 1150 processed, then logged with this event). 1152 Note: Implementations logging "packet_received" and which include all 1153 of the packet's constituent frames therein, are not expected to emit 1154 this "frames_processed" event. Rather, implementations not wishing 1155 to log full packets or that wish to explicitly convey extra 1156 information about when frames are processed (if not directly tied to 1157 their reception) can use this event. 1159 Note: for some events, this approach will lose some information 1160 (e.g., for which encryption level are packets being acknowledged?). 1161 If this information is important, please use the packet_received 1162 event instead. 1164 Note: in some implementations, it can be difficult to log frames 1165 directly, even when using packet_sent and packet_received events. 1166 For these cases, this event also contains the direct packet_number 1167 field, which can be used to more explicitly link this event to the 1168 packet_sent/received events. 1170 Definition: 1172 TransportFramesProcessed = { 1173 ; see appendix for the QuicFrame definitions 1174 frames: [* QuicFrame] 1176 ? packet_number: uint64 1177 } 1179 Figure 22: TransportFramesProcessed definition 1181 3.3.15. data_moved 1183 Importance: Base 1185 Used to indicate when data moves between the different layers (for 1186 example passing from the application protocol (e.g., HTTP) to QUIC 1187 stream buffers and vice versa) or between the application protocol 1188 (e.g., HTTP) and the actual user application on top (for example a 1189 browser engine). This helps make clear the flow of data, how long 1190 data remains in various buffers and the overheads introduced by 1191 individual layers. 1193 For example, this helps make clear whether received data on a QUIC 1194 stream is moved to the application protocol immediately (for example 1195 per received packet) or in larger batches (for example, all QUIC 1196 packets are processed first and afterwards the application layer 1197 reads from the streams with newly available data). This in turn can 1198 help identify bottlenecks or scheduling problems. 1200 Definition: 1202 TransportDataMoved = { 1203 ? stream_id: uint64 1204 ? offset: uint64 1206 ; byte length of the moved data 1207 ? length: uint64 1209 ? from: "user" / "application" / "transport" / "network" / text 1210 ? to: "user" / "application" / "transport" / "network" / text 1212 ; raw bytes that were transferred 1213 ? data: hexstring 1214 } 1216 Figure 23: TransportDataMoved definition 1218 Note: we do not for example use a "direction" field (with values "up" 1219 and "down") to specify the data flow. This is because in some 1220 optimized implementations, data might skip some individual layers. 1221 Additionally, using explicit "from" and "to" fields is more flexible 1222 and allows the definition of other conceptual "layers" (for example 1223 to indicate data from QUIC CRYPTO frames being passed to a TLS 1224 library ("security") or from HTTP/3 to QPACK ("qpack")). 1226 Note: this event type is part of the "transport" category, but really 1227 spans all the different layers. This means we have a few leaky 1228 abstractions here (for example, the stream_id or stream offset might 1229 not be available at some logging points, or the raw data might not be 1230 in a byte-array form). In these situations, implementers can decide 1231 to define new, in-context fields to aid in manual debugging. 1233 3.4. recovery 1235 Note: most of the events in this category are kept generic to support 1236 different recovery approaches and various congestion control 1237 algorithms. Tool creators SHOULD make an effort to support and 1238 visualize even unknown data in these events (e.g., plot unknown 1239 congestion states by name on a timeline visualization). 1241 3.4.1. parameters_set 1243 Importance: Base 1245 This event groups initial parameters from both loss detection and 1246 congestion control into a single event. All these settings are 1247 typically set once and never change. Implementation that do, for 1248 some reason, change these parameters during execution, MAY emit the 1249 parameters_set event twice. 1251 Definition: 1253 RecoveryParametersSet = { 1254 ; Loss detection, see recovery draft-23, Appendix A.2 1255 ; in amount of packets 1256 ? reordering_threshold: uint16 1258 ; as RTT multiplier 1259 ? time_threshold: float32 1261 ; in ms 1262 timer_granularity: uint16 1264 ; in ms 1265 ? initial_rtt:float32 1267 ; congestion control, Appendix B.1. 1268 ; in bytes. Note: this could be updated after pmtud 1269 ? max_datagram_size: uint32 1271 ; in bytes 1272 ? initial_congestion_window: uint64 1274 ; Note: this could change when max_datagram_size changes 1275 ; in bytes 1276 ? minimum_congestion_window: uint32 1277 ? loss_reduction_factor: float32 1279 ; as PTO multiplier 1280 ? persistent_congestion_threshold: uint16 1281 } 1283 Figure 24: RecoveryParametersSet definition 1285 Additionally, this event can contain any number of unspecified fields 1286 to support different recovery approaches. 1288 3.4.2. metrics_updated 1290 Importance: Core 1292 This event is emitted when one or more of the observable recovery 1293 metrics changes value. This event SHOULD group all possible metric 1294 updates that happen at or around the same time in a single event 1295 (e.g., if min_rtt and smoothed_rtt change at the same time, they 1296 should be bundled in a single metrics_updated entry, rather than 1297 split out into two). Consequently, a metrics_updated event is only 1298 guaranteed to contain at least one of the listed metrics. 1300 Definition: 1302 RecoveryMetricsUpdated = { 1303 ; Loss detection, see recovery draft-23, Appendix A.3 1304 ; all following rtt fields are expressed in ms 1305 ? min_rtt: float32 1306 ? smoothed_rtt: float32 1307 ? latest_rtt: float32 1308 ? rtt_variance: float32 1310 ? pto_count: uint16 1312 ; Congestion control, Appendix B.2. 1313 ; in bytes 1314 ? congestion_window: uint64 1315 ? bytes_in_flight: uint64 1317 ; in bytes 1318 ? ssthresh: uint64 1320 ; qlog defined 1321 ; sum of all packet number spaces 1322 ? packets_in_flight: uint64 1324 ; in bits per second 1325 ? pacing_rate: uint64 1326 } 1328 Figure 25: RecoveryMetricsUpdated definition 1330 Note: to make logging easier, implementations MAY log values even if 1331 they are the same as previously reported values (e.g., two subsequent 1332 RecoveryMetricsUpdated entries can both report the exact same value 1333 for min_rtt). However, applications SHOULD try to log only actual 1334 updates to values. 1336 Additionally, this event can contain any number of unspecified fields 1337 to support different recovery approaches. 1339 3.4.3. congestion_state_updated 1341 Importance: Base 1343 This event signifies when the congestion controller enters a 1344 significant new state and changes its behaviour. This event's 1345 definition is kept generic to support different Congestion Control 1346 algorithms. For example, for the algorithm defined in the Recovery 1347 draft ("enhanced" New Reno), the following states are defined: 1349 * slow_start 1350 * congestion_avoidance 1352 * application_limited 1354 * recovery 1356 Definition: 1358 RecoveryCongestionStateUpdated = { 1359 ? old: text 1360 new: text 1362 ? trigger: 1363 "persistent_congestion" / 1364 "ECN" 1365 } 1367 Figure 26: RecoveryCongestionStateUpdated definition 1369 The "trigger" field SHOULD be logged if there are multiple ways in 1370 which a state change can occur but MAY be omitted if a given state 1371 can only be due to a single event occuring (e.g., slow start is 1372 exited only when ssthresh is exceeded). 1374 3.4.4. loss_timer_updated 1376 Importance: Extra 1378 This event is emitted when a recovery loss timer changes state. The 1379 three main event types are: 1381 * set: the timer is set with a delta timeout for when it will 1382 trigger next 1384 * expired: when the timer effectively expires after the delta 1385 timeout 1387 * cancelled: when a timer is cancelled (e.g., all outstanding 1388 packets are acknowledged, start idle period) 1390 Note: to indicate an active timer's timeout update, a new "set" event 1391 is used. 1393 Definition: 1395 RecoveryLossTimerUpdated = { 1396 ; called "mode" in draft-23 A.9. 1397 ? timer_type: "ack" / "pto" 1398 ? packet_number_space: PacketNumberSpace 1400 event_type: "set" / "expired" / "cancelled" 1402 ; if event_type === "set": delta time is in ms from 1403 ; this event's timestamp until when the timer will trigger 1404 ? delta: float32 1405 } 1407 Figure 27: RecoveryLossTimerUpdated definition 1409 TODO: how about CC algo's that use multiple timers? How generic do 1410 these events need to be? Just support QUIC-style recovery from the 1411 spec or broader? 1413 TODO: read up on the loss detection logic in draft-27 onward and see 1414 if this suffices 1416 3.4.5. packet_lost 1418 Importance: Core 1420 This event is emitted when a packet is deemed lost by loss detection. 1422 Definition: 1424 RecoveryPacketLost = { 1425 ; should include at least the packet_type and packet_number 1426 ? header: PacketHeader 1428 ; not all implementations will keep track of full 1429 ; packets, so these are optional 1430 ; see appendix for the QuicFrame definitions 1431 ? frames: [* QuicFrame] 1433 ? trigger: 1434 "reordering_threshold" / 1435 "time_threshold" / 1436 ; draft-23 section 5.3.1, MAY 1437 "pto_expired" 1438 } 1440 Figure 28: RecoveryPacketLost definition 1442 For this event, the "trigger" field SHOULD be set (for example to one 1443 of the values below), as this helps tremendously in debugging. 1445 3.4.6. marked_for_retransmit 1447 Importance: Extra 1449 This event indicates which data was marked for retransmit upon 1450 detecing a packet loss (see packet_lost). Similar to our reasoning 1451 for the "frames_processed" event, in order to keep the amount of 1452 different events low, we group this signal for all types of 1453 retransmittable data in a single event based on existing QUIC frame 1454 definitions. 1456 Implementations retransmitting full packets or frames directly can 1457 just log the consituent frames of the lost packet here (or do away 1458 with this event and use the contents of the packet_lost event 1459 instead). Conversely, implementations that have more complex logic 1460 (e.g., marking ranges in a stream's data buffer as in-flight), or 1461 that do not track sent frames in full (e.g., only stream offset + 1462 length), can translate their internal behaviour into the appropriate 1463 frame instance here even if that frame was never or will never be put 1464 on the wire. 1466 Note: much of this data can be inferred if implementations log 1467 packet_sent events (e.g., looking at overlapping stream data offsets 1468 and length, one can determine when data was retransmitted). 1470 Definition: 1472 RecoveryMarkedForRetransmit = { 1473 ; see appendix for the QuicFrame definitions 1474 frames: [+ QuicFrame] 1475 } 1477 Figure 29: RecoveryMarkedForRetransmit definition 1479 4. Security Considerations 1481 TBD 1483 5. IANA Considerations 1485 TBD 1487 6. References 1489 6.1. Normative References 1491 [CDDL] Birkholz, H., Vigano, C., and C. Bormann, "Concise Data 1492 Definition Language (CDDL): A Notational Convention to 1493 Express Concise Binary Object Representation (CBOR) and 1494 JSON Data Structures", RFC 8610, DOI 10.17487/RFC8610, 1495 June 2019, . 1497 [QLOG-H3] Marx, R., Ed., Niccolini, L., Ed., and M. Seemann, Ed., 1498 "HTTP/3 and QPACK event definitions for qlog", Work in 1499 Progress, Internet-Draft, draft-ietf-quic-qlog-h3-events- 1500 01, . 1503 [QLOG-MAIN] 1504 Marx, R., Ed., Niccolini, L., Ed., and M. Seemann, Ed., 1505 "Main logging schema for qlog", Work in Progress, 1506 Internet-Draft, draft-ietf-quic-qlog-main-schema-03, 1507 . 1510 [QUIC-RECOVERY] 1511 Iyengar, J., Ed. and I. Swett, Ed., "QUIC Loss Detection 1512 and Congestion Control", RFC 9002, DOI 10.17487/RFC9002, 1513 May 2021, . 1515 [QUIC-TLS] Thomson, M., Ed. and S. Turner, Ed., "Using TLS to Secure 1516 QUIC", RFC 9001, DOI 10.17487/RFC9001, May 2021, 1517 . 1519 [QUIC-TRANSPORT] 1520 Iyengar, J., Ed. and M. Thomson, Ed., "QUIC: A UDP-Based 1521 Multiplexed and Secure Transport", RFC 9000, 1522 DOI 10.17487/RFC9000, May 2021, 1523 . 1525 6.2. Informative References 1527 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 1528 Requirement Levels", BCP 14, RFC 2119, 1529 DOI 10.17487/RFC2119, March 1997, 1530 . 1532 Appendix A. QUIC data field definitions 1534 A.1. ProtocolEventBody extension 1536 We extend the $ProtocolEventBody extension point defined in 1537 [QLOG-MAIN] with the QUIC protocol events defined in this document. 1539 QuicEvents = ConnectivityServerListening / 1540 ConnectivityConnectionStarted / 1541 ConnectivityConnectionClosed / 1542 ConnectivityConnectionIDUpdated / 1543 ConnectivitySpinBitUpdated / 1544 ConnectivityConnectionStateUpdated / 1545 SecurityKeyUpdated / SecurityKeyRetired / 1546 TransportVersionInformation / TransportALPNInformation / 1547 TransportParametersSet / TransportParametersRestored / 1548 TransportPacketSent / TransportPacketReceived / 1549 TransportPacketDropped / TransportPacketBuffered / 1550 TransportPacketsAcked / TransportDatagramsSent / 1551 TransportDatagramsReceived / TransportDatagramDropped / 1552 TransportStreamStateUpdated / TransportFramesProcessed / 1553 TransportDataMoved / 1554 RecoveryParametersSet / RecoveryMetricsUpdated / 1555 RecoveryCongestionStateUpdated / 1556 RecoveryLossTimerUpdated / 1557 RecoveryPacketLost 1559 $ProtocolEventBody /= QuicEvents 1561 A.2. QuicVersion 1563 QuicVersion = hexstring 1565 Figure 30: QuicVersion definition 1567 A.3. ConnectionID 1569 ConnectionID = hexstring 1571 Figure 31: ConnectionID definition 1573 A.4. Owner 1575 Owner = "local" / "remote" 1577 Figure 32: Owner definition 1579 A.5. IPAddress and IPVersion 1581 ; an IPAddress can either be a "human readable" form 1582 ; (e.g., "127.0.0.1" for v4 or 1583 ; "2001:0db8:85a3:0000:0000:8a2e:0370:7334" for v6) or 1584 ; use a raw byte-form (as the string forms can be ambiguous) 1585 IPAddress = text / hexstring 1586 Figure 33: IPAddress definition 1588 IPVersion = "v4" / "v6" 1590 Figure 34: IPVersion definition 1592 A.6. PacketType 1594 PacketType = "initial" / "handshake" / "0RTT" / "1RTT" / "retry" / 1595 "version_negotiation" / "stateless_reset" / "unknown" 1597 Figure 35: PacketType definition 1599 A.7. PacketNumberSpace 1601 PacketNumberSpace = "initial" / "handshake" / "application_data" 1603 Figure 36: PacketNumberSpace definition 1605 A.8. PacketHeader 1607 PacketHeader = { 1608 packet_type: PacketType 1609 packet_number: uint64 1611 ; the bit flags of the packet headers (spin bit, key update bit, 1612 ; etc. up to and including the packet number length bits 1613 ; if present 1614 ? flags: uint8 1616 ; only if packet_type === "initial" 1617 ? token: Token 1619 ; only if packet_type === "initial" || "handshake" || "0RTT" 1620 ; Signifies length of the packet_number plus the payload 1621 ? length: uint16 1623 ; only if present in the header 1624 ; if correctly using transport:connection_id_updated events, 1625 ; dcid can be skipped for 1RTT packets 1626 ? version: QuicVersion 1627 ? scil: uint8 1628 ? dcil: uint8 1629 ? scid: ConnectionID 1630 ? dcid: ConnectionID 1631 } 1633 Figure 37: PacketHeader definition 1635 A.9. Token 1637 Token = { 1638 ? type: "retry" / "resumption" / "stateless_reset" 1640 ; byte length of the token 1641 ? length: uint32 1643 ; raw byte value of the token 1644 ? data: hexstring 1646 ; decoded fields included in the token 1647 ; (typically: peer's IP address, creation time) 1648 ? details: { 1649 * text => any 1650 } 1651 } 1653 Figure 38: Token definition 1655 The token carried in an Initial packet can either be a retry token 1656 from a Retry packet, a stateless reset token from a Stateless Reset 1657 packet or one originally provided by the server in a NEW_TOKEN frame 1658 used when resuming a connection (e.g., for address validation 1659 purposes). Retry and resumption tokens typically contain encoded 1660 metadata to check the token's validity when it is used, but this 1661 metadata and its format is implementation specific. For that, this 1662 field includes a general-purpose "details" field. 1664 A.10. KeyType 1666 KeyType = 1667 "server_initial_secret" / "client_initial_secret" / 1668 "server_handshake_secret" / "client_handshake_secret" / 1669 "server_0rtt_secret" / "client_0rtt_secret" / 1670 "server_1rtt_secret" / "client_1rtt_secret" 1672 Figure 39: KeyType definition 1674 A.11. QUIC Frames 1675 QuicFrame = 1676 PaddingFrame / PingFrame / AckFrame / ResetStreamFrame / 1677 StopSendingFrame / CryptoFrame / NewTokenFrame / StreamFrame / 1678 MaxDataFrame / MaxStreamDataFrame / MaxStreamsFrame / 1679 DataBlockedFrame / StreamDataBlockedFrame / StreamsBlockedFrame / 1680 NewConnectionIDFrame / RetireConnectionIDFrame / 1681 PathChallengeFrame / PathResponseFrame / ConnectionCloseFrame / 1682 HandshakeDoneFrame / UnknownFrame 1684 Figure 40: QuicFrame definition 1686 A.11.1. PaddingFrame 1688 In QUIC, PADDING frames are simply identified as a single byte of 1689 value 0. As such, each padding byte could be theoretically 1690 interpreted and logged as an individual PaddingFrame. 1692 However, as this leads to heavy logging overhead, implementations 1693 SHOULD instead emit just a single PaddingFrame and set the 1694 payload_length property to the amount of PADDING bytes/frames 1695 included in the packet. 1697 PaddingFrame = { 1698 frame_type: "padding" 1700 ; total frame length, including frame header 1701 ? length: uint32 1702 payload_length: uint32 1703 } 1705 Figure 41: PaddingFrame definition 1707 A.11.2. PingFrame 1709 PingFrame = { 1710 frame_type: "ping" 1712 ; total frame length, including frame header 1713 ? length: uint32 1714 ? payload_length: uint32 1715 } 1717 Figure 42: PingFrame definition 1719 A.11.3. AckFrame 1720 ; either a single number (e.g., [1]) or two numbers (e.g., [1,2]). 1721 ; For two numbers: 1722 ; the first number is "from": lowest packet number in interval 1723 ; the second number is "to": up to and including the highest 1724 ; packet number in the interval 1725 AckRange = [1*2 uint64] 1727 AckFrame = { 1728 frame_type: "ack" 1730 ; in ms 1731 ? ack_delay: float32 1733 ; e.g., looks like [[1,2],[4,5], [7], [10,22]] serialized 1734 ? acked_ranges: [+ AckRange] 1736 ; ECN (explicit congestion notification) related fields 1737 ; (not always present) 1738 ? ect1: uint64 1739 ? ect0:uint64 1740 ? ce: uint64 1742 ; total frame length, including frame header 1743 ? length: uint32 1744 ? payload_length: uint32 1745 } 1747 Figure 43: AckFrame definition 1749 Note: the packet ranges in AckFrame.acked_ranges do not necessarily 1750 have to be ordered (e.g., [[5,9],[1,4]] is a valid value). 1752 Note: the two numbers in the packet range can be the same (e.g., 1753 [120,120] means that packet with number 120 was ACKed). However, in 1754 that case, implementers SHOULD log [120] instead and tools MUST be 1755 able to deal with both notations. 1757 A.11.4. ResetStreamFrame 1758 ResetStreamFrame = { 1759 frame_type: "reset_stream" 1761 stream_id: uint64 1762 error_code: $ApplicationError / uint32 1764 ; in bytes 1765 final_size: uint64 1767 ; total frame length, including frame header 1768 ? length: uint32 1769 ? payload_length: uint32 1770 } 1772 Figure 44: ResetStreamFrame definition 1774 A.11.5. StopSendingFrame 1776 StopSendingFrame = { 1777 frame_type: "stop_sending" 1779 stream_id: uint64 1780 error_code: $ApplicationError / uint32 1782 ; total frame length, including frame header 1783 ? length: uint32 1784 ? payload_length: uint32 1785 } 1787 Figure 45: StopSendingFrame definition 1789 A.11.6. CryptoFrame 1791 CryptoFrame = { 1792 frame_type: "crypto" 1794 offset: uint64 1795 length: uint64 1797 ? payload_length: uint32 1798 } 1800 Figure 46: CryptoFrame definition 1802 A.11.7. NewTokenFrame 1803 NewTokenFrame = { 1804 frame_type: "new_token" 1806 token: Token 1807 } 1809 Figure 47: NewTokenFrame definition 1811 A.11.8. StreamFrame 1813 StreamFrame = { 1814 frame_type: "stream" 1816 stream_id: uint64 1818 ; These two MUST always be set 1819 ; If not present in the Frame type, log their default values 1820 offset: uint64 1821 length: uint64 1823 ; this MAY be set any time, 1824 ; but MUST only be set if the value is true 1825 ; if absent, the value MUST be assumed to be false 1826 ? fin: bool .default false 1828 ? raw: hexstring 1829 } 1831 Figure 48: StreamFrame definition 1833 A.11.9. MaxDataFrame 1835 MaxDataFrame = { 1836 frame_type: "max_data" 1838 maximum: uint64 1839 } 1841 Figure 49: MaxDataFrame definition 1843 A.11.10. MaxStreamDataFrame 1845 MaxStreamDataFrame = { 1846 frame_type: "max_stream_data" 1848 stream_id: uint64 1849 maximum: uint64 1850 } 1851 Figure 50: MaxStreamDataFrame definition 1853 A.11.11. MaxStreamsFrame 1855 MaxStreamsFrame = { 1856 frame_type: "max_streams" 1858 stream_type: StreamType 1859 maximum: uint64 1860 } 1862 Figure 51: MaxStreamsFrame definition 1864 A.11.12. DataBlockedFrame 1866 DataBlockedFrame = { 1867 frame_type: "data_blocked" 1869 limit: uint64 1870 } 1872 Figure 52: DataBlockedFrame definition 1874 A.11.13. StreamDataBlockedFrame 1876 StreamDataBlockedFrame = { 1877 frame_type: "stream_data_blocked" 1879 stream_id: uint64 1880 limit: uint64 1881 } 1883 Figure 53: StreamDataBlockedFrame definition 1885 A.11.14. StreamsBlockedFrame 1887 StreamsBlockedFrame = { 1888 frame_type: "streams_blocked" 1890 stream_type: StreamType 1891 limit: uint64 1892 } 1894 Figure 54: StreamsBlockedFrame definition 1896 A.11.15. NewConnectionIDFrame 1897 NewConnectionIDFrame = { 1898 frame_type: "new_connection_id" 1900 sequence_number: uint32 1901 retire_prior_to: uint32 1903 ; mainly used if e.g., for privacy reasons the full 1904 ; connection_id cannot be logged 1905 ? connection_id_length: uint8 1906 connection_id: ConnectionID 1908 ? stateless_reset_token: Token 1909 } 1911 Figure 55: NewConnectionIDFrame definition 1913 A.11.16. RetireConnectionIDFrame 1915 RetireConnectionIDFrame = { 1916 frame_type: "retire_connection_id" 1918 sequence_number: uint32 1919 } 1921 Figure 56: RetireConnectionIDFrame definition 1923 A.11.17. PathChallengeFrame 1925 PathChallengeFrame = { 1926 frame_type: "path_challenge" 1928 ; always 64-bit 1929 ? data: hexstring 1930 } 1932 Figure 57: PathChallengeFrame definition 1934 A.11.18. PathResponseFrame 1936 PathResponseFrame = { 1937 frame_type: "path_response" 1939 ; always 64-bit 1940 ? data: hexstring 1941 } 1943 Figure 58: PathResponseFrame definition 1945 A.11.19. ConnectionCloseFrame 1947 raw_error_code is the actual, numerical code. This is useful because 1948 some error types are spread out over a range of codes (e.g., QUIC's 1949 crypto_error). 1951 ErrorSpace = "transport" / "application" 1953 ConnectionCloseFrame = { 1954 frame_type: "connection_close" 1956 ? error_space: ErrorSpace 1957 ? error_code: TransportError / $ApplicationError / uint32 1958 ? raw_error_code: uint32 1959 ? reason: text 1961 ; For known frame types, the appropriate "frame_type" string 1962 ; For unknown frame types, the hex encoded identifier value 1963 ? trigger_frame_type: uint64 / text 1964 } 1966 Figure 59: ConnectionCloseFrame definition 1968 A.11.20. HandshakeDoneFrame 1970 HandshakeDoneFrame = { 1971 frame_type: "handshake_done"; 1972 } 1974 Figure 60: HandshakeDoneFrame definition 1976 A.11.21. UnknownFrame 1978 UnknownFrame = { 1979 frame_type: "unknown" 1980 raw_frame_type: uint64 1982 ? raw_length: uint32 1983 ? raw: hexstring 1984 } 1986 Figure 61: UnknownFrame definition 1988 A.11.22. TransportError 1989 TransportError = "no_error" / "internal_error" / 1990 "connection_refused" / "flow_control_error" / 1991 "stream_limit_error" / "stream_state_error" / 1992 "final_size_error" / "frame_encoding_error" / 1993 "transport_parameter_error" / "connection_id_limit_error" / 1994 "protocol_violation" / "invalid_token" / "application_error" / 1995 "crypto_buffer_exceeded" 1997 Figure 62: TransportError definition 1999 A.11.23. ApplicationError 2001 By definition, an application error is defined by the application- 2002 level protocol running on top of QUIC (e.g., HTTP/3). 2004 As such, we cannot define it here directly. Though we provide an 2005 extension point through the use of the CDDL "socket" mechanism. 2007 Application-level qlog definitions that wish to define new 2008 ApplicationError strings MUST do so by extending the 2009 $ApplicationError socket as such: 2011 $ApplicationError /= "new_error_name" / "another_new_error_name" 2013 A.11.24. CryptoError 2015 These errors are defined in the TLS document as "A TLS alert is 2016 turned into a QUIC connection error by converting the one-byte alert 2017 description into a QUIC error code. The alert description is added 2018 to 0x100 to produce a QUIC error code from the range reserved for 2019 CRYPTO_ERROR." 2021 This approach maps badly to a pre-defined enum. As such, we define 2022 the crypto_error string as having a dynamic component here, which 2023 should include the hex-encoded and zero-padded value of the TLS alert 2024 description. 2026 ; all strings from "crypto_error_0x100" to "crypto_error_0x199" 2027 CryptoError = text .regexp "crypto_error_0x1[0-9][0-9]" 2029 Figure 63: CryptoError definition 2031 Appendix B. Change Log 2033 B.1. Since draft-ietf-qlog-quic-events-00: 2035 * Change the data definition language from TypeScript to CDDL (#143) 2037 B.2. Since draft-marx-qlog-event-definitions-quic-h3-02: 2039 * These changes were done in preparation of the adoption of the 2040 drafts by the QUIC working group (#137) 2042 * Split QUIC and HTTP/3 events into two separate documents 2044 * Moved RawInfo, Importance, Generic events and Simulation events to 2045 the main schema document. 2047 * Changed to/from value options of the data_moved event 2049 B.3. Since draft-marx-qlog-event-definitions-quic-h3-01: 2051 Major changes: 2053 * Moved data_moved from http to transport. Also made the "from" and 2054 "to" fields flexible strings instead of an enum (#111,#65) 2056 * Moved packet_type fields to PacketHeader. Moved packet_size field 2057 out of PacketHeader to RawInfo:length (#40) 2059 * Made events that need to log packet_type and packet_number use a 2060 header field instead of logging these fields individually 2062 * Added support for logging retry, stateless reset and initial 2063 tokens (#94,#86,#117) 2065 * Moved separate general event categories into a single category 2066 "generic" (#47) 2068 * Added "transport:connection_closed" event (#43,#85,#78,#49) 2070 * Added version_information and alpn_information events 2071 (#85,#75,#28) 2073 * Added parameters_restored events to help clarify 0-RTT behaviour 2074 (#88) 2076 Smaller changes: 2078 * Merged loss_timer events into one loss_timer_updated event 2080 * Field data types are now strongly defined (#10,#39,#36,#115) 2082 * Renamed qpack instruction_received and instruction_sent to 2083 instruction_created and instruction_parsed (#114) 2085 * Updated qpack:dynamic_table_updated.update_type. It now has the 2086 value "inserted" instead of "added" (#113) 2088 * Updated qpack:dynamic_table_updated. It now has an "owner" field 2089 to differentiate encoder vs decoder state (#112) 2091 * Removed push_allowed from http:parameters_set (#110) 2093 * Removed explicit trigger field indications from events, since this 2094 was moved to be a generic property of the "data" field (#80) 2096 * Updated transport:connection_id_updated to be more in line with 2097 other similar events. Also dropped importance from Core to Base 2098 (#45) 2100 * Added length property to PaddingFrame (#34) 2102 * Added packet_number field to transport:frames_processed (#74) 2104 * Added a way to generically log packet header flags (first 8 bits) 2105 to PacketHeader 2107 * Added additional guidance on which events to log in which 2108 situations (#53) 2110 * Added "simulation:scenario" event to help indicate simulation 2111 details 2113 * Added "packets_acked" event (#107) 2115 * Added "datagram_ids" to the datagram_X and packet_X events to 2116 allow tracking of coalesced QUIC packets (#91) 2118 * Extended connection_state_updated with more fine-grained states 2119 (#49) 2121 B.4. Since draft-marx-qlog-event-definitions-quic-h3-00: 2123 * Event and category names are now all lowercase 2125 * Added many new events and their definitions 2127 * "type" fields have been made more specific (especially important 2128 for PacketType fields, which are now called packet_type instead of 2129 type) 2131 * Events are given an importance indicator (issue #22) 2132 * Event names are more consistent and use past tense (issue #21) 2134 * Triggers have been redefined as properties of the "data" field and 2135 updated for most events (issue #23) 2137 Appendix C. Design Variations 2139 TBD 2141 Appendix D. Acknowledgements 2143 Much of the initial work by Robin Marx was done at Hasselt 2144 University. 2146 Thanks to Marten Seemann, Jana Iyengar, Brian Trammell, Dmitri 2147 Tikhonov, Stephen Petrides, Jari Arkko, Marcus Ihlar, Victor 2148 Vasiliev, Mirja Kuehlewind, Jeremy Laine, Kazu Yamamoto, Christian 2149 Huitema, and Lucas Pardue for their feedback and suggestions. 2151 Authors' Addresses 2153 Robin Marx 2154 KU Leuven 2155 Email: robin.marx@kuleuven.be 2157 Luca Niccolini (editor) 2158 Facebook 2159 Email: lniccolini@fb.com 2161 Marten Seemann (editor) 2162 Protocol Labs 2163 Email: marten@protocol.ai