idnits 2.17.1 draft-marx-quic-qlog-quic-events-00.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 : ---------------------------------------------------------------------------- ** There are 32 instances of too long lines in the document, the longest one being 332 characters in excess of 72. ** 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 (May 17, 2021) is 1074 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 1383 -- Looks like a reference, but probably isn't: '2' on line 1385 -- Looks like a reference, but probably isn't: '120' on line 1531 == Unused Reference: 'QUIC-TRANSPORT' is defined on line 1369, but no explicit reference was found in the text -- No information found for draft-ietf-quic-recovery-latest - is the name correct? -- Possible downref: Normative reference to a draft: ref. 'QUIC-RECOVERY' -- No information found for draft-ietf-quic-tls-latest - is the name correct? -- Possible downref: Normative reference to a draft: ref. 'QUIC-TLS' -- No information found for draft-ietf-quic-transport-latest - is the name correct? -- Possible downref: Normative reference to a draft: ref. 'QUIC-TRANSPORT' Summary: 2 errors (**), 0 flaws (~~), 2 warnings (==), 10 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: November 18, 2021 Facebook 6 M. Seemann, Ed. 7 Protocol Labs 8 May 17, 2021 10 QUIC event definitions for qlog 11 draft-marx-quic-qlog-quic-events-00 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 November 18, 2021. 36 Copyright Notice 38 Copyright (c) 2021 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 43 (https://trustee.ietf.org/license-info) in effect on the date of 44 publication of this document. Please review these documents 45 carefully, as they describe your rights and restrictions with respect 46 to this document. Code Components extracted from this document must 47 include Simplified BSD License text as described in Section 4.e of 48 the Trust Legal Provisions and are provided without warranty as 49 described in the Simplified BSD License. 51 Table of Contents 53 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 4 54 1.1. Notational Conventions . . . . . . . . . . . . . . . . . 4 55 2. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . 4 56 2.1. Links to the main schema . . . . . . . . . . . . . . . . 5 57 2.1.1. Raw packet and frame information . . . . . . . . . . 5 58 2.1.2. Events not belonging to a single connection . . . . . 6 59 3. QUIC event definitions . . . . . . . . . . . . . . . . . . . 6 60 3.1. connectivity . . . . . . . . . . . . . . . . . . . . . . 6 61 3.1.1. server_listening . . . . . . . . . . . . . . . . . . 6 62 3.1.2. connection_started . . . . . . . . . . . . . . . . . 7 63 3.1.3. connection_closed . . . . . . . . . . . . . . . . . . 7 64 3.1.4. connection_id_updated . . . . . . . . . . . . . . . . 8 65 3.1.5. spin_bit_updated . . . . . . . . . . . . . . . . . . 9 66 3.1.6. connection_retried . . . . . . . . . . . . . . . . . 9 67 3.1.7. connection_state_updated . . . . . . . . . . . . . . 9 68 3.1.8. MIGRATION-related events . . . . . . . . . . . . . . 11 69 3.2. security . . . . . . . . . . . . . . . . . . . . . . . . 11 70 3.2.1. key_updated . . . . . . . . . . . . . . . . . . . . . 11 71 3.2.2. key_retired . . . . . . . . . . . . . . . . . . . . . 12 72 3.3. transport . . . . . . . . . . . . . . . . . . . . . . . . 12 73 3.3.1. version_information . . . . . . . . . . . . . . . . . 12 74 3.3.2. alpn_information . . . . . . . . . . . . . . . . . . 13 75 3.3.3. parameters_set . . . . . . . . . . . . . . . . . . . 14 76 3.3.4. parameters_restored . . . . . . . . . . . . . . . . . 16 77 3.3.5. packet_sent . . . . . . . . . . . . . . . . . . . . . 16 78 3.3.6. packet_received . . . . . . . . . . . . . . . . . . . 17 79 3.3.7. packet_dropped . . . . . . . . . . . . . . . . . . . 18 80 3.3.8. packet_buffered . . . . . . . . . . . . . . . . . . . 19 81 3.3.9. packets_acked . . . . . . . . . . . . . . . . . . . . 20 82 3.3.10. datagrams_sent . . . . . . . . . . . . . . . . . . . 20 83 3.3.11. datagrams_received . . . . . . . . . . . . . . . . . 21 84 3.3.12. datagram_dropped . . . . . . . . . . . . . . . . . . 21 85 3.3.13. stream_state_updated . . . . . . . . . . . . . . . . 22 86 3.3.14. frames_processed . . . . . . . . . . . . . . . . . . 24 87 3.3.15. data_moved . . . . . . . . . . . . . . . . . . . . . 25 88 3.4. recovery . . . . . . . . . . . . . . . . . . . . . . . . 26 89 3.4.1. parameters_set . . . . . . . . . . . . . . . . . . . 26 90 3.4.2. metrics_updated . . . . . . . . . . . . . . . . . . . 26 91 3.4.3. congestion_state_updated . . . . . . . . . . . . . . 27 92 3.4.4. loss_timer_updated . . . . . . . . . . . . . . . . . 28 93 3.4.5. packet_lost . . . . . . . . . . . . . . . . . . . . . 29 94 3.4.6. marked_for_retransmit . . . . . . . . . . . . . . . . 29 95 4. Security Considerations . . . . . . . . . . . . . . . . . . . 30 96 5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 30 97 6. References . . . . . . . . . . . . . . . . . . . . . . . . . 30 98 6.1. Normative References . . . . . . . . . . . . . . . . . . 30 99 6.2. Informative References . . . . . . . . . . . . . . . . . 31 100 6.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 31 101 Appendix A. QUIC data field definitions . . . . . . . . . . . . 31 102 A.1. IPAddress . . . . . . . . . . . . . . . . . . . . . . . . 31 103 A.2. PacketType . . . . . . . . . . . . . . . . . . . . . . . 31 104 A.3. PacketNumberSpace . . . . . . . . . . . . . . . . . . . . 32 105 A.4. PacketHeader . . . . . . . . . . . . . . . . . . . . . . 32 106 A.5. Token . . . . . . . . . . . . . . . . . . . . . . . . . . 32 107 A.6. KeyType . . . . . . . . . . . . . . . . . . . . . . . . . 33 108 A.7. QUIC Frames . . . . . . . . . . . . . . . . . . . . . . . 33 109 A.7.1. PaddingFrame . . . . . . . . . . . . . . . . . . . . 33 110 A.7.2. PingFrame . . . . . . . . . . . . . . . . . . . . . . 34 111 A.7.3. AckFrame . . . . . . . . . . . . . . . . . . . . . . 34 112 A.7.4. ResetStreamFrame . . . . . . . . . . . . . . . . . . 35 113 A.7.5. StopSendingFrame . . . . . . . . . . . . . . . . . . 35 114 A.7.6. CryptoFrame . . . . . . . . . . . . . . . . . . . . . 35 115 A.7.7. NewTokenFrame . . . . . . . . . . . . . . . . . . . . 35 116 A.7.8. StreamFrame . . . . . . . . . . . . . . . . . . . . . 36 117 A.7.9. MaxDataFrame . . . . . . . . . . . . . . . . . . . . 36 118 A.7.10. MaxStreamDataFrame . . . . . . . . . . . . . . . . . 36 119 A.7.11. MaxStreamsFrame . . . . . . . . . . . . . . . . . . . 36 120 A.7.12. DataBlockedFrame . . . . . . . . . . . . . . . . . . 37 121 A.7.13. StreamDataBlockedFrame . . . . . . . . . . . . . . . 37 122 A.7.14. StreamsBlockedFrame . . . . . . . . . . . . . . . . . 37 123 A.7.15. NewConnectionIDFrame . . . . . . . . . . . . . . . . 37 124 A.7.16. RetireConnectionIDFrame . . . . . . . . . . . . . . . 37 125 A.7.17. PathChallengeFrame . . . . . . . . . . . . . . . . . 38 126 A.7.18. PathResponseFrame . . . . . . . . . . . . . . . . . . 38 127 A.7.19. ConnectionCloseFrame . . . . . . . . . . . . . . . . 38 128 A.7.20. HandshakeDoneFrame . . . . . . . . . . . . . . . . . 38 129 A.7.21. UnknownFrame . . . . . . . . . . . . . . . . . . . . 38 130 A.7.22. TransportError . . . . . . . . . . . . . . . . . . . 39 131 A.7.23. CryptoError . . . . . . . . . . . . . . . . . . . . . 39 132 Appendix B. Change Log . . . . . . . . . . . . . . . . . . . . . 39 133 B.1. Since draft-marx-qlog-event-definitions-quic-h3-02: . . . 40 134 B.2. Since draft-marx-qlog-event-definitions-quic-h3-01: . . . 40 135 B.3. Since draft-marx-qlog-event-definitions-quic-h3-00: . . . 41 136 Appendix C. Design Variations . . . . . . . . . . . . . . . . . 42 137 Appendix D. Acknowledgements . . . . . . . . . . . . . . . . . . 42 138 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 42 140 1. Introduction 142 This document describes the values of the qlog name ("category" + 143 "event") and "data" fields and their semantics for the QUIC protocol. 144 This document is based on draft-34 of the QUIC I-Ds QUIC-TRANSPORT 145 [QUIC-RECOVERY] [QUIC-TLS]. HTTP/3 and QPACK events are defined in a 146 separate document [QLOG-H3]. 148 Feedback and discussion are welcome at https://github.com/quiclog/ 149 internet-drafts [1]. Readers are advised to refer to the "editor's 150 draft" at that URL for an up-to-date version of this document. 152 Concrete examples of integrations of this schema in various 153 programming languages can be found at https://github.com/quiclog/ 154 qlog/ [2]. 156 1.1. Notational Conventions 158 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 159 "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this 160 document are to be interpreted as described in [RFC2119]. 162 The examples and data definitions in ths document are expressed in a 163 custom data definition language, inspired by JSON and TypeScript, and 164 described in [QLOG-MAIN]. 166 2. Overview 168 This document describes the values of the qlog "name" ("category" + 169 "event") and "data" fields and their semantics for the QUIC protocol. 171 This document assumes the usage of the encompassing main qlog schema 172 defined in [QLOG-MAIN]. Each subsection below defines a separate 173 category (for example connectivity, transport, recovery) and each 174 subsubsection is an event type (for example "packet_received"). 176 For each event type, its importance and data definition is laid out, 177 often accompanied by possible values for the optional "trigger" 178 field. For the definition and semantics of "importance" and 179 "trigger", see the main schema document. 181 Most of the complex datastructures, enums and re-usable definitions 182 are grouped together on the bottom of this document for clarity. 184 2.1. Links to the main schema 186 This document re-uses all the fields defined in the main qlog schema 187 (e.g., name, category, type, data, group_id, protocol_type, the time- 188 related fields, importance, RawInfo, etc.). 190 One entry in the "protocol_type" qlog array field MUST be "QUIC" if 191 events from this document are included in a qlog trace. 193 When the qlog "group_id" field is used, it is recommended to use 194 QUIC's Original Destination Connection ID (ODCID, the CID chosen by 195 the client when first contacting the server), as this is the only 196 value that does not change over the course of the connection and can 197 be used to link more advanced QUIC packets (e.g., Retry, Version 198 Negotiation) to a given connection. Similarly, the ODCID should be 199 used as the qlog filename or file identifier, potentially suffixed by 200 the vantagepoint type (For example, abcd1234_server.qlog would 201 contain the server-side trace of the connection with ODCID abcd1234). 203 2.1.1. Raw packet and frame information 205 This document re-uses the definition of the RawInfo data class from 206 [QLOG-MAIN]. 208 Note: QUIC packets always include an AEAD authentication tag 209 ("trailer") at the end. As this tag is always the same size for a 210 given connection (it depends on the used TLS cipher), this 211 document does not define a separate "RawInfo:aead_tag_length" 212 field here. Instead, this field is reflected in 213 "transport:parameters_set" and can be logged only once. 215 Note: As QUIC uses trailers in packets, packet header_lengths can be 216 calculated as: 218 header_length = length - payload_length - aead_tag_length 220 For UDP datagrams, the calulation is simpler: 222 header_length = length - payload_length 224 Note: In some cases, the length fields are also explicitly reflected 225 inside of packet headers. For example, the QUIC STREAM frame has 226 a "length" field indicating its payload size. Similarly, the QUIC 227 Long Header has a "length" field which is equal to the payload 228 length plus the packet number length. In these cases, those 229 fields are intentionally preserved in the event definitions. Even 230 though this can lead to duplicate data when the full RawInfo is 231 logged, it allows a more direct mapping of the QUIC specifications 232 to qlog, making it easier for users to interpret. 234 2.1.2. Events not belonging to a single connection 236 For several types of events, it is sometimes impossible to tie them 237 to a specific conceptual QUIC connection (e.g., a packet_dropped 238 event triggered because the packet has an unknown connection_id in 239 the header). Since qlog events in a trace are typically associated 240 with a single connection, it is unclear how to log these events. 242 Ideally, implementers SHOULD create a separate, individual "endpoint- 243 level" trace file (or group_id value), not associated with a specific 244 connection (for example a "server.qlog" or group_id = "client"), and 245 log all events that do not belong to a single connection to this 246 grouping trace. However, this is not always practical, depending on 247 the implementation. Because the semantics of most of these events 248 are well-defined in the protocols and because they are difficult to 249 mis-interpret as belonging to a connection, implementers MAY choose 250 to log events not belonging to a particular connection in any other 251 trace, even those strongly associated with a single connection. 253 Note that this can make it difficult to match logs from different 254 vantage points with each other. For example, from the client side, 255 it is easy to log connections with version negotiation or retry in 256 the same trace, while on the server they would most likely be logged 257 in separate traces. Servers can take extra efforts (and keep 258 additional state) to keep these events combined in a single trace 259 however (for example by also matching connections on their four-tuple 260 instead of just the connection ID). 262 3. QUIC event definitions 264 Each subheading in this section is a qlog event category, while each 265 sub-subheading is a qlog event type. Concretely, for the following 266 two items, we have the category "connectivity" and event type 267 "server_listening", resulting in a concatenated qlog "name" field 268 value of "connectivity:server_listening". 270 3.1. connectivity 272 3.1.1. server_listening 274 Importance: Extra 276 Emitted when the server starts accepting connections. 278 Data: 280 { 281 ip_v4?: IPAddress, 282 ip_v6?: IPAddress, 283 port_v4?: uint32, 284 port_v6?: uint32, 286 retry_required?:boolean // the server will always answer client initials with a retry (no 1-RTT connection setups by choice) 287 } 289 Note: some QUIC stacks do not handle sockets directly and are thus 290 unable to log IP and/or port information. 292 3.1.2. connection_started 294 Importance: Base 296 Used for both attempting (client-perspective) and accepting (server- 297 perspective) new connections. Note that this event has overlap with 298 connection_state_updated and this is a separate event mainly because 299 of all the additional data that should be logged. 301 Data: 303 { 304 ip_version?: "v4" | "v6", 305 src_ip?: IPAddress, 306 dst_ip?: IPAddress, 308 protocol?: string, // transport layer protocol (default "QUIC") 309 src_port?: uint32, 310 dst_port?: uint32, 312 src_cid?: bytes, 313 dst_cid?: bytes, 315 } 317 Note: some QUIC stacks do not handle sockets directly and are thus 318 unable to log IP and/or port information. 320 3.1.3. connection_closed 322 Importance: Base 324 Used for logging when a connection was closed, typically when an 325 error or timeout occurred. Note that this event has overlap with 326 connectivity:connection_state_updated, as well as the 327 CONNECTION_CLOSE frame. However, in practice, when analyzing large 328 deployments, it can be useful to have a single event representing a 329 connection_closed event, which also includes an additional reason 330 field to provide additional information. Additionally, it is useful 331 to log closures due to timeouts, which are difficult to reflect using 332 the other options. 334 In QUIC there are two main connection-closing error categories: 335 connection and application errors. They have well-defined error 336 codes and semantics. Next to these however, there can be internal 337 errors that occur that may or may not get mapped to the official 338 error codes in implementation-specific ways. As such, multiple error 339 codes can be set on the same event to reflect this. 341 { 342 owner?:"local"|"remote", // which side closed the connection 344 connection_code?:TransportError | CryptoError | uint32, 345 application_code?:ApplicationError | uint32, 346 internal_code?:uint32, 348 reason?:string 349 } 351 Triggers: * clean * handshake_timeout * idle_timeout * error // this 352 is called the "immediate close" in the QUIC specification * 353 stateless_reset * version_mismatch * application // for example 354 HTTP/3's GOAWAY frame 356 3.1.4. connection_id_updated 358 Importance: Base 360 This event is emitted when either party updates their current 361 Connection ID. As this typically happens only sparingly over the 362 course of a connection, this event allows loggers to be more 363 efficient than logging the observed CID with each packet in the 364 .header field of the "packet_sent" or "packet_received" events. 366 This is viewed from the perspective of the one applying the new id. 367 As such, if we receive a new connection id from our peer, we will see 368 the dst_ fields are set. If we update our own connection id (e.g., 369 NEW_CONNECTION_ID frame), we log the src_ fields. 371 Data: 373 { 374 owner: "local" | "remote", 376 old?:bytes, 377 new?:bytes, 378 } 380 3.1.5. spin_bit_updated 382 Importance: Base 384 To be emitted when the spin bit changes value. It SHOULD NOT be 385 emitted if the spin bit is set without changing its value. 387 Data: 389 { 390 state: boolean 391 } 393 3.1.6. connection_retried 395 TODO 397 3.1.7. connection_state_updated 399 Importance: Base 401 This event is used to track progress through QUIC's complex handshake 402 and connection close procedures. It is intended to provide 403 exhaustive options to log each state individually, but also provides 404 a more basic, simpler set for implementations less interested in 405 tracking each smaller state transition. As such, users should not 406 expect to see -all- these states reflected in all qlogs and 407 implementers should focus on support for the SimpleConnectionState 408 set. 410 Data: ~~~ { old?: ConnectionState | SimpleConnectionState, new: 411 ConnectionState | SimpleConnectionState } 413 enum ConnectionState { attempted, // initial sent/received 414 peer_validated, // peer address validated by: client sent Handshake 415 packet OR client used CONNID chosen by the server. transport-draft- 416 32, section-8.1 handshake_started, early_write, // 1 RTT can be sent, 417 but handshake isn't done yet handshake_complete, // TLS handshake 418 complete: Finished received and sent. tls-draft-32, section-4.1.1 419 handshake_confirmed, // HANDSHAKE_DONE sent/received (connection is 420 now "active", 1RTT can be sent). tls-draft-32, section-4.1.2 closing, 421 draining, // connection_close sent/received closed // draining period 422 done, connection state discarded } 424 enum SimpleConnectionState { attempted, handshake_started, 425 handshake_confirmed, closed } ~~~ 427 These states correspond to the following transitions for both client 428 and server: 430 *Client:* 432 o send initial 434 * state = attempted 436 o get initial 438 * state = validated _(not really "needed" at the client, but 439 somewhat useful to indicate progress nonetheless)_ 441 o get first Handshake packet 443 * state = handshake_started 445 o get Handshake packet containing ServerFinished 447 * state = handshake_complete 449 o send ClientFinished 451 * state = early_write (1RTT can now be sent) 453 o get HANDSHAKE_DONE 455 * state = handshake_confirmed 457 *Server:* 459 o get initial 461 * state = attempted 463 o send initial _(don't think this needs a separate state, since some 464 handshake will always be sent in the same flight as this?)_ 466 o send handshake EE, CERT, CV, ... 468 * state = handshake_started 470 o send ServerFinished 472 * state = early_write (1RTT can now be sent) 474 o get first handshake packet / something using a server-issued CID 475 of min length 477 * state = validated 479 o get handshake packet containing ClientFinished 481 * state = handshake_complete 483 o send HANDSHAKE_DONE 485 * state = handshake_confirmed 487 Note: connection_state_changed with a new state of "attempted" is 488 the same conceptual event as the connection_started event above 489 from the client's perspective. Similarly, a state of "closing" or 490 "draining" corresponds to the connection_closed event. 492 3.1.8. MIGRATION-related events 494 e.g., path_updated 496 TODO: read up on the draft how migration works and whether to best 497 fit this here or in TRANSPORT TODO: integrate 498 https://tools.ietf.org/html/draft-deconinck-quic-multipath-02 500 For now, infer from other connectivity events and path_challenge/ 501 path_response frames 503 3.2. security 505 3.2.1. key_updated 507 Importance: Base 509 Note: secret_updated would be more correct, but in the draft it's 510 called KEY_UPDATE, so stick with that for consistency 512 Data: 514 { 515 key_type:KeyType, 516 old?:bytes, 517 new:bytes, 518 generation?:uint32 // needed for 1RTT key updates 519 } 521 Triggers: 523 o "tls" // (e.g., initial, handshake and 0-RTT keys are generated by 524 TLS) 526 o "remote_update" 528 o "local_update" 530 3.2.2. key_retired 532 Importance: Base 534 Data: 536 { 537 key_type:KeyType, 538 key?:bytes, 539 generation?:uint32 // needed for 1RTT key updates 540 } 542 Triggers: 544 o "tls" // (e.g., initial, handshake and 0-RTT keys are dropped 545 implicitly) 547 o "remote_update" 549 o "local_update" 551 3.3. transport 553 3.3.1. version_information 555 Importance: Core 557 QUIC endpoints each have their own list of of QUIC versions they 558 support. The client uses the most likely version in their first 559 initial. If the server does support that version, it replies with a 560 version_negotiation packet, containing supported versions. From 561 this, the client selects a version. This event aggregates all this 562 information in a single event type. It also allows logging of 563 supported versions at an endpoint without actual version negotiation 564 needing to happen. 566 Data: 568 { 569 server_versions?:Array, 570 client_versions?:Array, 571 chosen_version?:bytes 572 } 574 Intended use: 576 o When sending an initial, the client logs this event with 577 client_versions and chosen_version set 579 o Upon receiving a client initial with a supported version, the 580 server logs this event with server_versions and chosen_version set 582 o Upon receiving a client initial with an unsupported version, the 583 server logs this event with server_versions set and 584 client_versions to the single-element array containing the 585 client's attempted version. The absence of chosen_version implies 586 no overlap was found. 588 o Upon receiving a version negotiation packet from the server, the 589 client logs this event with client_versions set and 590 server_versions to the versions in the version negotiation packet 591 and chosen_version to the version it will use for the next initial 592 packet 594 3.3.2. alpn_information 596 Importance: Core 598 QUIC implementations each have their own list of application level 599 protocols and versions thereof they support. The client includes a 600 list of their supported options in its first initial as part of the 601 TLS Application Layer Protocol Negotiation (alpn) extension. If 602 there are common option(s), the server chooses the most optimal one 603 and communicates this back to the client. If not, the connection is 604 closed. 606 Data: 608 { 609 server_alpns?:Array, 610 client_alpns?:Array, 611 chosen_alpn?:string 612 } 614 Intended use: 616 o When sending an initial, the client logs this event with 617 client_alpns set 619 o When receiving an initial with a supported alpn, the server logs 620 this event with server_alpns set, client_alpns equalling the 621 client-provided list, and chosen_alpn to the value it will send 622 back to the client. 624 o When receiving an initial with an alpn, the client logs this event 625 with chosen_alpn to the received value. 627 o Alternatively, a client can choose to not log the first event, but 628 wait for the receipt of the server initial to log this event with 629 both client_alpns and chosen_alpn set. 631 3.3.3. parameters_set 633 Importance: Core 635 This event groups settings from several different sources (transport 636 parameters, TLS ciphers, etc.) into a single event. This is done to 637 minimize the amount of events and to decouple conceptual setting 638 impacts from their underlying mechanism for easier high-level 639 reasoning. 641 All these settings are typically set once and never change. However, 642 they are typically set at different times during the connection, so 643 there will typically be several instances of this event with 644 different fields set. 646 Note that some settings have two variations (one set locally, one 647 requested by the remote peer). This is reflected in the "owner" 648 field. As such, this field MUST be correct for all settings included 649 a single event instance. If you need to log settings from two sides, 650 you MUST emit two separate event instances. 652 In the case of connection resumption and 0-RTT, some of the server's 653 parameters are stored up-front at the client and used for the initial 654 connection startup. They are later updated with the server's reply. 655 In these cases, utilize the separate "parameters_restored" event to 656 indicate the initial values, and this event to indicate the updated 657 values, as normal. 659 Data: 661 { 662 owner?:"local" | "remote", 664 resumption_allowed?:boolean, // valid session ticket was received 665 early_data_enabled?:boolean, // early data extension was enabled on the TLS layer 666 tls_cipher?:string, // (e.g., "AES_128_GCM_SHA256") 667 aead_tag_length?:uint8, // depends on the TLS cipher, but it's easier to be explicit. Default value is 16 669 // transport parameters from the TLS layer: 670 original_destination_connection_id?:bytes, 671 initial_source_connection_id?:bytes, 672 retry_source_connection_id?:bytes, 673 stateless_reset_token?:Token, 674 disable_active_migration?:boolean, 676 max_idle_timeout?:uint64, 677 max_udp_payload_size?:uint32, 678 ack_delay_exponent?:uint16, 679 max_ack_delay?:uint16, 680 active_connection_id_limit?:uint32, 682 initial_max_data?:uint64, 683 initial_max_stream_data_bidi_local?:uint64, 684 initial_max_stream_data_bidi_remote?:uint64, 685 initial_max_stream_data_uni?:uint64, 686 initial_max_streams_bidi?:uint64, 687 initial_max_streams_uni?:uint64, 689 preferred_address?:PreferredAddress 690 } 692 interface PreferredAddress { 693 ip_v4:IPAddress, 694 ip_v6:IPAddress, 696 port_v4:uint16, 697 port_v6:uint16, 699 connection_id:bytes, 700 stateless_reset_token:Token 701 } 702 Additionally, this event can contain any number of unspecified 703 fields. This is to reflect setting of for example unknown (greased) 704 transport parameters or employed (proprietary) extensions. 706 3.3.4. parameters_restored 708 Importance: Base 710 When using QUIC 0-RTT, clients are expected to remember and restore 711 the server's transport parameters from the previous connection. This 712 event is used to indicate which parameters were restored and to which 713 values when utilizing 0-RTT. Note that not all transport parameters 714 should be restored (many are even prohibited from being re-utilized). 715 The ones listed here are the ones expected to be useful for correct 716 0-RTT usage. 718 Data: 720 { 721 disable_active_migration?:boolean, 723 max_idle_timeout?:uint64, 724 max_udp_payload_size?:uint32, 725 active_connection_id_limit?:uint32, 727 initial_max_data?:uint64, 728 initial_max_stream_data_bidi_local?:uint64, 729 initial_max_stream_data_bidi_remote?:uint64, 730 initial_max_stream_data_uni?:uint64, 731 initial_max_streams_bidi?:uint64, 732 initial_max_streams_uni?:uint64, 733 } 735 Note that, like parameters_set above, this event can contain any 736 number of unspecified fields to allow for additional/custom 737 parameters. 739 3.3.5. packet_sent 741 Importance: Core 743 Data: 745 { 746 header:PacketHeader, 748 frames?:Array, // see appendix for the definitions 750 is_coalesced?:boolean, // default value is false 752 retry_token?:Token, // only if header.packet_type === retry 754 stateless_reset_token?:bytes, // only if header.packet_type === stateless_reset. Is always 128 bits in length. 756 supported_versions:Array, // only if header.packet_type === version_negotiation 758 raw?:RawInfo, 759 datagram_id?:uint32 760 } 762 Note: We do not explicitly log the encryption_level or 763 packet_number_space: the header.packet_type specifies this by 764 inference (assuming correct implementation) 766 Triggers: 768 o "retransmit_reordered" // draft-23 5.1.1 770 o "retransmit_timeout" // draft-23 5.1.2 772 o "pto_probe" // draft-23 5.3.1 774 o "retransmit_crypto" // draft-19 6.2 776 o "cc_bandwidth_probe" // needed for some CCs to figure out 777 bandwidth allocations when there are no normal sends 779 Note: for more details on "datagram_id", see Section 3.3.10. It is 780 only needed when keeping track of packet coalescing. 782 3.3.6. packet_received 784 Importance: Core 786 Data: 788 { 789 header:PacketHeader, 791 frames?:Array, // see appendix for the definitions 793 is_coalesced?:boolean, 795 retry_token?:Token, // only if header.packet_type === retry 797 stateless_reset_token?:bytes, // only if header.packet_type === stateless_reset. Is always 128 bits in length. 799 supported_versions:Array, // only if header.packet_type === version_negotiation 801 raw?:RawInfo, 802 datagram_id?:uint32 803 } 805 Note: We do not explicitly log the encryption_level or 806 packet_number_space: the header.packet_type specifies this by 807 inference (assuming correct implementation) 809 Triggers: 811 o "keys_available" // if packet was buffered because it couldn't be 812 decrypted before 814 Note: for more details on "datagram_id", see Section 3.3.10. It is 815 only needed when keeping track of packet coalescing. 817 3.3.7. packet_dropped 819 Importance: Base 821 This event indicates a QUIC-level packet was dropped after partial or 822 no parsing. 824 Data: 826 { 827 header?:PacketHeader, // primarily packet_type should be filled here, as other fields might not be parseable 829 raw?:RawInfo, 830 datagram_id?:uint32 831 } 833 For this event, the "trigger" field SHOULD be set (for example to one 834 of the values below), as this helps tremendously in debugging. 836 Triggers: 838 o "key_unavailable" 840 o "unknown_connection_id" 842 o "header_parse_error" 844 o "payload_decrypt_error" 846 o "protocol_violation" 848 o "dos_prevention" 850 o "unsupported_version" 852 o "unexpected_packet" 854 o "unexpected_source_connection_id" 856 o "unexpected_version" 858 o "duplicate" 860 o "invalid_initial" 862 Note: sometimes packets are dropped before they can be associated 863 with a particular connection (e.g., in case of 864 "unsupported_version"). This situation is discussed more in 865 Section 2.1.2. 867 Note: for more details on "datagram_id", see Section 3.3.10. It is 868 only needed when keeping track of packet coalescing. 870 3.3.8. packet_buffered 872 Importance: Base 874 This event is emitted when a packet is buffered because it cannot be 875 processed yet. Typically, this is because the packet cannot be 876 parsed yet, and thus we only log the full packet contents when it was 877 parsed in a packet_received event. 879 Data: 881 { 882 header?:PacketHeader, // primarily packet_type and possible packet_number should be filled here, as other elements might not be available yet 884 raw?:RawInfo, 885 datagram_id?:uint32 886 } 888 Note: for more details on "datagram_id", see Section 3.3.10. It is 889 only needed when keeping track of packet coalescing. 891 Triggers: 893 o "backpressure" // indicates the parser cannot keep up, temporarily 894 buffers packet for later processing 896 o "keys_unavailable" // if packet cannot be decrypted because the 897 proper keys were not yet available 899 3.3.9. packets_acked 901 Importance: Extra 903 This event is emitted when a (group of) sent packet(s) is 904 acknowledged by the remote peer _for the first time_. This 905 information could also be deduced from the contents of received ACK 906 frames. However, ACK frames require additional processing logic to 907 determine when a given packet is acknowledged for the first time, as 908 QUIC uses ACK ranges which can include repeated ACKs. Additionally, 909 this event can be used by implementations that do not log frame 910 contents. 912 Data: ~~~ { packet_number_space?:PacketNumberSpace, 914 packet_numbers?:Array } ~~~ 916 Note: if packet_number_space is omitted, it assumes the default value 917 of PacketNumberSpace.application_data, as this is by far the most 918 prevalent packet number space a typical QUIC connection will use. 920 3.3.10. datagrams_sent 922 Importance: Extra 924 When we pass one or more UDP-level datagrams to the socket. This is 925 useful for determining how QUIC packet buffers are drained to the OS. 927 Data: 929 { 930 count?:uint16, // to support passing multiple at once 931 raw?:Array, // RawInfo:length field indicates total length of the datagrams, including UDP header length 933 datagram_ids?:Array 934 } 936 Note: QUIC itself does not have a concept of a "datagram_id". This 937 field is a purely qlog-specific construct to allow tracking how 938 multiple QUIC packets are coalesced inside of a single UDP datagram, 939 which is an important optimization during the QUIC handshake. For 940 this, implementations assign a (per-endpoint) unique ID to each 941 datagram and keep track of which packets were coalesced into the same 942 datagram. As packet coalescing typically only happens during the 943 handshake (as it requires at least one long header packet), this can 944 be done without much overhead. 946 3.3.11. datagrams_received 948 Importance: Extra 950 When we receive one or more UDP-level datagrams from the socket. 951 This is useful for determining how datagrams are passed to the user 952 space stack from the OS. 954 Data: 956 { 957 count?:uint16, // to support passing multiple at once 958 raw?:Array, // RawInfo:length field indicates total length of the datagrams, including UDP header length 960 datagram_ids?:Array 961 } 963 Note: for more details on "datagram_ids", see Section 3.3.10. 965 3.3.12. datagram_dropped 967 Importance: Extra 969 When we drop a UDP-level datagram. This is typically if it does not 970 contain a valid QUIC packet (in that case, use packet_dropped 971 instead). 973 Data: 975 { 976 raw?:RawInfo 977 } 979 3.3.13. stream_state_updated 981 Importance: Base 983 This event is emitted whenever the internal state of a QUIC stream is 984 updated, as described in QUIC transport draft-23 section 3. Most of 985 this can be inferred from several types of frames going over the 986 wire, but it's much easier to have explicit signals for these state 987 changes. 989 Data: 991 { 992 stream_id:uint64, 993 stream_type?:"unidirectional"|"bidirectional", // mainly useful when opening the stream 995 old?:StreamState, 996 new:StreamState, 998 stream_side?:"sending"|"receiving" 999 } 1001 enum StreamState { 1002 // bidirectional stream states, draft-23 3.4. 1003 idle, 1004 open, 1005 half_closed_local, 1006 half_closed_remote, 1007 closed, 1009 // sending-side stream states, draft-23 3.1. 1010 ready, 1011 send, 1012 data_sent, 1013 reset_sent, 1014 reset_received, 1016 // receive-side stream states, draft-23 3.2. 1017 receive, 1018 size_known, 1019 data_read, 1020 reset_read, 1022 // both-side states 1023 data_received, 1025 // qlog-defined 1026 destroyed // memory actually freed 1027 } 1029 Note: QUIC implementations SHOULD mainly log the simplified 1030 bidirectional (HTTP/2-alike) stream states (e.g., idle, open, closed) 1031 instead of the more finegrained stream states (e.g., data_sent, 1032 reset_received). These latter ones are mainly for more in-depth 1033 debugging. Tools SHOULD be able to deal with both types equally. 1035 3.3.14. frames_processed 1037 Importance: Extra 1039 This event's main goal is to prevent a large proliferation of 1040 specific purpose events (e.g., packets_acknowledged, 1041 flow_control_updated, stream_data_received). We want to give 1042 implementations the opportunity to (selectively) log this type of 1043 signal without having to log packet-level details (e.g., in 1044 packet_received). Since for almost all cases, the effects of 1045 applying a frame to the internal state of an implementation can be 1046 inferred from that frame's contents, we aggregate these events in 1047 this single "frames_processed" event. 1049 Note: This event can be used to signal internal state change not 1050 resulting directly from the actual "parsing" of a frame (e.g., the 1051 frame could have been parsed, data put into a buffer, then later 1052 processed, then logged with this event). 1054 Note: Implementations logging "packet_received" and which include all 1055 of the packet's constituent frames therein, are not expected to emit 1056 this "frames_processed" event. Rather, implementations not wishing 1057 to log full packets or that wish to explicitly convey extra 1058 information about when frames are processed (if not directly tied to 1059 their reception) can use this event. 1061 Note: for some events, this approach will lose some information 1062 (e.g., for which encryption level are packets being acknowledged?). 1063 If this information is important, please use the packet_received 1064 event instead. 1066 Note: in some implementations, it can be difficult to log frames 1067 directly, even when using packet_sent and packet_received events. 1068 For these cases, this event also contains the direct packet_number 1069 field, which can be used to more explicitly link this event to the 1070 packet_sent/received events. 1072 Data: 1074 { 1075 frames:Array, // see appendix for the definitions 1077 packet_number?:uint64 1078 } 1080 3.3.15. data_moved 1082 Importance: Base 1084 Used to indicate when data moves between the different layers (for 1085 example passing from the application protocol (e.g., HTTP) to QUIC 1086 stream buffers and vice versa) or between the application protocol 1087 (e.g., HTTP) and the actual user application on top (for example a 1088 browser engine). This helps make clear the flow of data, how long 1089 data remains in various buffers and the overheads introduced by 1090 individual layers. 1092 For example, this helps make clear whether received data on a QUIC 1093 stream is moved to the application protocol immediately (for example 1094 per received packet) or in larger batches (for example, all QUIC 1095 packets are processed first and afterwards the application layer 1096 reads from the streams with newly available data). This in turn can 1097 help identify bottlenecks or scheduling problems. 1099 Data: 1101 { 1102 stream_id?:uint64, 1103 offset?:uint64, 1104 length?:uint64, // byte length of the moved data 1106 from?:string, // typically: use either of "user","application","transport","network" 1107 to?:string, // typically: use either of "user","application","transport","network" 1109 data?:bytes // raw bytes that were transferred 1110 } 1112 Note: we do not for example use a "direction" field (with values "up" 1113 and "down") to specify the data flow. This is because in some 1114 optimized implementations, data might skip some individual layers. 1115 Additionally, using explicit "from" and "to" fields is more flexible 1116 and allows the definition of other conceptual "layers" (for example 1117 to indicate data from QUIC CRYPTO frames being passed to a TLS 1118 library ("security") or from HTTP/3 to QPACK ("qpack")). 1120 Note: this event type is part of the "transport" category, but really 1121 spans all the different layers. This means we have a few leaky 1122 abstractions here (for example, the stream_id or stream offset might 1123 not be available at some logging points, or the raw data might not be 1124 in a byte-array form). In these situations, implementers can decide 1125 to define new, in-context fields to aid in manual debugging. 1127 3.4. recovery 1129 Note: most of the events in this category are kept generic to support 1130 different recovery approaches and various congestion control 1131 algorithms. Tool creators SHOULD make an effort to support and 1132 visualize even unknown data in these events (e.g., plot unknown 1133 congestion states by name on a timeline visualization). 1135 3.4.1. parameters_set 1137 Importance: Base 1139 This event groups initial parameters from both loss detection and 1140 congestion control into a single event. All these settings are 1141 typically set once and never change. Implementation that do, for 1142 some reason, change these parameters during execution, MAY emit the 1143 parameters_set event twice. 1145 Data: 1147 { 1148 // Loss detection, see recovery draft-23, Appendix A.2 1149 reordering_threshold?:uint16, // in amount of packets 1150 time_threshold?:float, // as RTT multiplier 1151 timer_granularity?:uint16, // in ms 1152 initial_rtt?:float, // in ms 1154 // congestion control, Appendix B.1. 1155 max_datagram_size?:uint32, // in bytes // Note: this could be updated after pmtud 1156 initial_congestion_window?:uint64, // in bytes 1157 minimum_congestion_window?:uint32, // in bytes // Note: this could change when max_datagram_size changes 1158 loss_reduction_factor?:float, 1159 persistent_congestion_threshold?:uint16 // as PTO multiplier 1160 } 1162 Additionally, this event can contain any number of unspecified fields 1163 to support different recovery approaches. 1165 3.4.2. metrics_updated 1167 Importance: Core 1169 This event is emitted when one or more of the observable recovery 1170 metrics changes value. This event SHOULD group all possible metric 1171 updates that happen at or around the same time in a single event 1172 (e.g., if min_rtt and smoothed_rtt change at the same time, they 1173 should be bundled in a single metrics_updated entry, rather than 1174 split out into two). Consequently, a metrics_updated event is only 1175 guaranteed to contain at least one of the listed metrics. 1177 Data: 1179 { 1180 // Loss detection, see recovery draft-23, Appendix A.3 1181 min_rtt?:float, // in ms or us, depending on the overarching qlog's configuration 1182 smoothed_rtt?:float, // in ms or us, depending on the overarching qlog's configuration 1183 latest_rtt?:float, // in ms or us, depending on the overarching qlog's configuration 1184 rtt_variance?:float, // in ms or us, depending on the overarching qlog's configuration 1186 pto_count?:uint16, 1188 // Congestion control, Appendix B.2. 1189 congestion_window?:uint64, // in bytes 1190 bytes_in_flight?:uint64, 1192 ssthresh?:uint64, // in bytes 1194 // qlog defined 1195 packets_in_flight?:uint64, // sum of all packet number spaces 1197 pacing_rate?:uint64 // in bps 1198 } 1200 Note: to make logging easier, implementations MAY log values even if 1201 they are the same as previously reported values (e.g., two subsequent 1202 METRIC_UPDATE entries can both report the exact same value for 1203 min_rtt). However, applications SHOULD try to log only actual 1204 updates to values. 1206 Additionally, this event can contain any number of unspecified fields 1207 to support different recovery approaches. 1209 3.4.3. congestion_state_updated 1211 Importance: Base 1213 This event signifies when the congestion controller enters a 1214 significant new state and changes its behaviour. This event's 1215 definition is kept generic to support different Congestion Control 1216 algorithms. For example, for the algorithm defined in the Recovery 1217 draft ("enhanced" New Reno), the following states are defined: 1219 o slow_start 1221 o congestion_avoidance 1222 o application_limited 1224 o recovery 1226 Data: 1228 { 1229 old?:string, 1230 new:string 1231 } 1233 The "trigger" field SHOULD be logged if there are multiple ways in 1234 which a state change can occur but MAY be omitted if a given state 1235 can only be due to a single event occuring (e.g., slow start is 1236 exited only when ssthresh is exceeded). 1238 Some triggers for ("enhanced" New Reno): 1240 o persistent_congestion 1242 o ECN 1244 3.4.4. loss_timer_updated 1246 Importance: Extra 1248 This event is emitted when a recovery loss timer changes state. The 1249 three main event types are: 1251 o set: the timer is set with a delta timeout for when it will 1252 trigger next 1254 o expired: when the timer effectively expires after the delta 1255 timeout 1257 o cancelled: when a timer is cancelled (e.g., all outstanding 1258 packets are acknowledged, start idle period) 1260 Note: to indicate an active timer's timeout update, a new "set" event 1261 is used. 1263 Data: 1265 { 1266 timer_type?:"ack"|"pto", // called "mode" in draft-23 A.9. 1267 packet_number_space?: PacketNumberSpace, 1269 event_type:"set"|"expired"|"cancelled", 1271 delta?:float // if event_type === "set": delta time in ms or us (see configuration) from this event's timestamp until when the timer will trigger 1272 } 1274 TODO: how about CC algo's that use multiple timers? How generic do 1275 these events need to be? Just support QUIC-style recovery from the 1276 spec or broader? 1278 TODO: read up on the loss detection logic in draft-27 onward and see 1279 if this suffices 1281 3.4.5. packet_lost 1283 Importance: Core 1285 This event is emitted when a packet is deemed lost by loss detection. 1287 Data: 1289 { 1290 header?:PacketHeader, // should include at least the packet_type and packet_number 1292 // not all implementations will keep track of full packets, so these are optional 1293 frames?:Array // see appendix for the definitions 1294 } 1296 For this event, the "trigger" field SHOULD be set (for example to one 1297 of the values below), as this helps tremendously in debugging. 1299 Triggers: 1301 o "reordering_threshold", 1303 o "time_threshold" 1305 o "pto_expired" // draft-23 section 5.3.1, MAY 1307 3.4.6. marked_for_retransmit 1309 Importance: Extra 1311 This event indicates which data was marked for retransmit upon 1312 detecing a packet loss (see packet_lost). Similar to our reasoning 1313 for the "frames_processed" event, in order to keep the amount of 1314 different events low, we group this signal for all types of 1315 retransmittable data in a single event based on existing QUIC frame 1316 definitions. 1318 Implementations retransmitting full packets or frames directly can 1319 just log the consituent frames of the lost packet here (or do away 1320 with this event and use the contents of the packet_lost event 1321 instead). Conversely, implementations that have more complex logic 1322 (e.g., marking ranges in a stream's data buffer as in-flight), or 1323 that do not track sent frames in full (e.g., only stream offset + 1324 length), can translate their internal behaviour into the appropriate 1325 frame instance here even if that frame was never or will never be put 1326 on the wire. 1328 Note: much of this data can be inferred if implementations log 1329 packet_sent events (e.g., looking at overlapping stream data offsets 1330 and length, one can determine when data was retransmitted). 1332 Data: 1334 { 1335 frames:Array, // see appendix for the definitions 1336 } 1338 4. Security Considerations 1340 TBD 1342 5. IANA Considerations 1344 TBD 1346 6. References 1348 6.1. Normative References 1350 [QLOG-H3] Marx, R., Ed., Niccolini, L., Ed., and M. Seemann, Ed., 1351 "HTTP/3 and QPACK event definitions for qlog", draft-marx- 1352 quic-qlog-h3-events-00 (work in progress). 1354 [QLOG-MAIN] 1355 Marx, R., Ed., Niccolini, L., Ed., and M. Seemann, Ed., 1356 "Main logging schema for qlog", draft-marx-qlog-main- 1357 schema-03 (work in progress). 1359 [QUIC-RECOVERY] 1360 Iyengar, J., Ed. and I. Swett, Ed., "QUIC Loss Detection 1361 and Congestion Control", draft-ietf-quic-recovery-latest 1362 (work in progress). 1364 [QUIC-TLS] 1365 Thomson, M., Ed. and S. Turner, Ed., "Using Transport 1366 Layer Security (TLS) to Secure QUIC", draft-ietf-quic-tls- 1367 latest (work in progress). 1369 [QUIC-TRANSPORT] 1370 Iyengar, J., Ed. and M. Thomson, Ed., "QUIC: A UDP-Based 1371 Multiplexed and Secure Transport", draft-ietf-quic- 1372 transport-latest (work in progress). 1374 6.2. Informative References 1376 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 1377 Requirement Levels", BCP 14, RFC 2119, 1378 DOI 10.17487/RFC2119, March 1997, 1379 . 1381 6.3. URIs 1383 [1] https://github.com/quiclog/internet-drafts 1385 [2] https://github.com/quiclog/qlog/ 1387 Appendix A. QUIC data field definitions 1389 A.1. IPAddress 1391 class IPAddress : string | bytes; 1393 // an IPAddress can either be a "human readable" form (e.g., "127.0.0.1" for v4 or "2001:0db8:85a3:0000:0000:8a2e:0370:7334" for v6) or use a raw byte-form (as the string forms can be ambiguous) 1395 A.2. PacketType 1396 enum PacketType { 1397 initial, 1398 handshake, 1399 zerortt = "0RTT", 1400 onertt = "1RTT", 1401 retry, 1402 version_negotiation, 1403 stateless_reset, 1404 unknown 1405 } 1407 A.3. PacketNumberSpace 1409 enum PacketNumberSpace { 1410 initial, 1411 handshake, 1412 application_data 1413 } 1415 A.4. PacketHeader 1417 class PacketHeader { 1418 // Note: short vs long header is implicit through PacketType 1420 packet_type: PacketType; 1421 packet_number: uint64; 1423 flags?: uint8; // the bit flags of the packet headers (spin bit, key update bit, etc. up to and including the packet number length bits if present) interpreted as a single 8-bit integer 1425 token?:Token; // only if packet_type == initial 1427 length?: uint16, // only if packet_type == initial || handshake || 0RTT. Signifies length of the packet_number plus the payload. 1429 // only if present in the header 1430 // if correctly using transport:connection_id_updated events, 1431 // dcid can be skipped for 1RTT packets 1432 version?: bytes; // e.g., "ff00001d" for draft-29 1433 scil?: uint8; 1434 dcil?: uint8; 1435 scid?: bytes; 1436 dcid?: bytes; 1437 } 1439 A.5. Token 1440 class Token { 1441 type?:"retry"|"resumption"|"stateless_reset"; 1443 length?:uint32; // byte length of the token 1444 data?:bytes; // raw byte value of the token 1446 details?:any; // decoded fields included in the token (typically: peer's IP address, creation time) 1447 } 1449 The token carried in an Initial packet can either be a retry token 1450 from a Retry packet, a stateless reset token from a Stateless Reset 1451 packet or one originally provided by the server in a NEW_TOKEN frame 1452 used when resuming a connection (e.g., for address validation 1453 purposes). Retry and resumption tokens typically contain encoded 1454 metadata to check the token's validity when it is used, but this 1455 metadata and its format is implementation specific. For that, this 1456 field includes a general-purpose "details" field. 1458 A.6. KeyType 1460 enum KeyType { 1461 server_initial_secret, 1462 client_initial_secret, 1464 server_handshake_secret, 1465 client_handshake_secret, 1467 server_0rtt_secret, 1468 client_0rtt_secret, 1470 server_1rtt_secret, 1471 client_1rtt_secret 1472 } 1474 A.7. QUIC Frames 1476 type QuicFrame = PaddingFrame | PingFrame | AckFrame | ResetStreamFrame | StopSendingFrame | CryptoFrame | NewTokenFrame | StreamFrame | MaxDataFrame | MaxStreamDataFrame | MaxStreamsFrame | DataBlockedFrame | StreamDataBlockedFrame | StreamsBlockedFrame | NewConnectionIDFrame | RetireConnectionIDFrame | PathChallengeFrame | PathResponseFrame | ConnectionCloseFrame | HandshakeDoneFrame | UnknownFrame; 1478 A.7.1. PaddingFrame 1480 In QUIC, PADDING frames are simply identified as a single byte of 1481 value 0. As such, each padding byte could be theoretically 1482 interpreted and logged as an individual PaddingFrame. 1484 However, as this leads to heavy logging overhead, implementations 1485 SHOULD instead emit just a single PaddingFrame and set the 1486 payload_length property to the amount of PADDING bytes/frames 1487 included in the packet. 1489 class PaddingFrame{ 1490 frame_type:string = "padding"; 1492 length?:uint32; // total frame length, including frame header 1493 payload_length?:uint32; 1494 } 1496 A.7.2. PingFrame 1498 class PingFrame{ 1499 frame_type:string = "ping"; 1501 length?:uint32; // total frame length, including frame header 1502 payload_length?:uint32; 1503 } 1505 A.7.3. AckFrame 1507 class AckFrame{ 1508 frame_type:string = "ack"; 1510 ack_delay?:float; // in ms 1512 // first number is "from": lowest packet number in interval 1513 // second number is "to": up to and including // highest packet number in interval 1514 // e.g., looks like [[1,2],[4,5]] 1515 acked_ranges?:Array<[uint64, uint64]|[uint64]>; 1517 // ECN (explicit congestion notification) related fields (not always present) 1518 ect1?:uint64; 1519 ect0?:uint64; 1520 ce?:uint64; 1522 length?:uint32; // total frame length, including frame header 1523 payload_length?:uint32; 1524 } 1526 Note: the packet ranges in AckFrame.acked_ranges do not necessarily 1527 have to be ordered (e.g., [[5,9],[1,4]] is a valid value). 1529 Note: the two numbers in the packet range can be the same (e.g., 1530 [120,120] means that packet with number 120 was ACKed). However, in 1531 that case, implementers SHOULD log [120] instead and tools MUST be 1532 able to deal with both notations. 1534 A.7.4. ResetStreamFrame 1536 class ResetStreamFrame{ 1537 frame_type:string = "reset_stream"; 1539 stream_id:uint64; 1540 error_code:ApplicationError | uint32; 1541 final_size:uint64; // in bytes 1543 length?:uint32; // total frame length, including frame header 1544 payload_length?:uint32; 1545 } 1547 A.7.5. StopSendingFrame 1549 class StopSendingFrame{ 1550 frame_type:string = "stop_sending"; 1552 stream_id:uint64; 1553 error_code:ApplicationError | uint32; 1555 length?:uint32; // total frame length, including frame header 1556 payload_length?:uint32; 1557 } 1559 A.7.6. CryptoFrame 1561 class CryptoFrame{ 1562 frame_type:string = "crypto"; 1564 offset:uint64; 1565 length:uint64; 1567 payload_length?:uint32; 1568 } 1570 A.7.7. NewTokenFrame 1572 class NewTokenFrame{ 1573 frame_type:string = "new_token"; 1575 token:Token 1576 } 1578 A.7.8. StreamFrame 1580 class StreamFrame{ 1581 frame_type:string = "stream"; 1583 stream_id:uint64; 1585 // These two MUST always be set 1586 // If not present in the Frame type, log their default values 1587 offset:uint64; 1588 length:uint64; 1590 // this MAY be set any time, but MUST only be set if the value is "true" 1591 // if absent, the value MUST be assumed to be "false" 1592 fin?:boolean; 1594 raw?:bytes; 1595 } 1597 A.7.9. MaxDataFrame 1599 class MaxDataFrame{ 1600 frame_type:string = "max_data"; 1602 maximum:uint64; 1603 } 1605 A.7.10. MaxStreamDataFrame 1607 class MaxStreamDataFrame{ 1608 frame_type:string = "max_stream_data"; 1610 stream_id:uint64; 1611 maximum:uint64; 1612 } 1614 A.7.11. MaxStreamsFrame 1616 class MaxStreamsFrame{ 1617 frame_type:string = "max_streams"; 1619 stream_type:string = "bidirectional" | "unidirectional"; 1620 maximum:uint64; 1621 } 1623 A.7.12. DataBlockedFrame 1625 class DataBlockedFrame{ 1626 frame_type:string = "data_blocked"; 1628 limit:uint64; 1629 } 1631 A.7.13. StreamDataBlockedFrame 1633 class StreamDataBlockedFrame{ 1634 frame_type:string = "stream_data_blocked"; 1636 stream_id:uint64; 1637 limit:uint64; 1638 } 1640 A.7.14. StreamsBlockedFrame 1642 class StreamsBlockedFrame{ 1643 frame_type:string = "streams_blocked"; 1645 stream_type:string = "bidirectional" | "unidirectional"; 1646 limit:uint64; 1647 } 1649 A.7.15. NewConnectionIDFrame 1651 class NewConnectionIDFrame{ 1652 frame_type:string = "new_connection_id"; 1654 sequence_number:uint32; 1655 retire_prior_to:uint32; 1657 connection_id_length?:uint8; 1658 connection_id:bytes; 1660 stateless_reset_token?:Token; 1661 } 1663 A.7.16. RetireConnectionIDFrame 1665 class RetireConnectionIDFrame{ 1666 frame_type:string = "retire_connection_id"; 1668 sequence_number:uint32; 1669 } 1671 A.7.17. PathChallengeFrame 1673 class PathChallengeFrame{ 1674 frame_type:string = "path_challenge"; 1676 data?:bytes; // always 64-bit 1677 } 1679 A.7.18. PathResponseFrame 1681 class PathResponseFrame{ 1682 frame_type:string = "path_response"; 1684 data?:bytes; // always 64-bit 1685 } 1687 A.7.19. ConnectionCloseFrame 1689 raw_error_code is the actual, numerical code. This is useful because 1690 some error types are spread out over a range of codes (e.g., QUIC's 1691 crypto_error). 1693 type ErrorSpace = "transport" | "application"; 1695 class ConnectionCloseFrame{ 1696 frame_type:string = "connection_close"; 1698 error_space?:ErrorSpace; 1699 error_code?:TransportError | ApplicationError | uint32; 1700 raw_error_code?:uint32; 1701 reason?:string; 1703 trigger_frame_type?:uint64 | string; // For known frame types, the appropriate "frame_type" string. For unknown frame types, the hex encoded identifier value 1704 } 1706 A.7.20. HandshakeDoneFrame 1708 class HandshakeDoneFrame{ 1709 frame_type:string = "handshake_done"; 1710 } 1712 A.7.21. UnknownFrame 1713 class UnknownFrame{ 1714 frame_type:string = "unknown"; 1715 raw_frame_type:uint64; 1717 raw_length?:uint32; 1718 raw?:bytes; 1719 } 1721 A.7.22. TransportError 1723 enum TransportError { 1724 no_error, 1725 internal_error, 1726 connection_refused, 1727 flow_control_error, 1728 stream_limit_error, 1729 stream_state_error, 1730 final_size_error, 1731 frame_encoding_error, 1732 transport_parameter_error, 1733 connection_id_limit_error, 1734 protocol_violation, 1735 invalid_token, 1736 application_error, 1737 crypto_buffer_exceeded 1738 } 1740 A.7.23. CryptoError 1742 These errors are defined in the TLS document as "A TLS alert is 1743 turned into a QUIC connection error by converting the one-byte alert 1744 description into a QUIC error code. The alert description is added 1745 to 0x100 to produce a QUIC error code from the range reserved for 1746 CRYPTO_ERROR." 1748 This approach maps badly to a pre-defined enum. As such, we define 1749 the crypto_error string as having a dynamic component here, which 1750 should include the hex-encoded value of the TLS alert description. 1752 enum CryptoError { 1753 crypto_error_{TLS_ALERT} 1754 } 1756 Appendix B. Change Log 1757 B.1. Since draft-marx-qlog-event-definitions-quic-h3-02: 1759 o These changes were done in preparation of the adoption of the 1760 drafts by the QUIC working group (#137) 1762 o Split QUIC and HTTP/3 events into two separate documents 1764 o Moved RawInfo, Importance, Generic events and Simulation events to 1765 the main schema document. 1767 o Changed to/from value options of the "data_moved" event 1769 B.2. Since draft-marx-qlog-event-definitions-quic-h3-01: 1771 Major changes: 1773 o Moved data_moved from http to transport. Also made the "from" and 1774 "to" fields flexible strings instead of an enum (#111,#65) 1776 o Moved packet_type fields to PacketHeader. Moved packet_size field 1777 out of PacketHeader to RawInfo:length (#40) 1779 o Made events that need to log packet_type and packet_number use a 1780 header field instead of logging these fields individually 1782 o Added support for logging retry, stateless reset and initial 1783 tokens (#94,#86,#117) 1785 o Moved separate general event categories into a single category 1786 "generic" (#47) 1788 o Added "transport:connection_closed" event (#43,#85,#78,#49) 1790 o Added version_information and alpn_information events 1791 (#85,#75,#28) 1793 o Added parameters_restored events to help clarify 0-RTT behaviour 1794 (#88) 1796 Smaller changes: 1798 o Merged loss_timer events into one loss_timer_updated event 1800 o Field data types are now strongly defined (#10,#39,#36,#115) 1802 o Renamed qpack instruction_received and instruction_sent to 1803 instruction_created and instruction_parsed (#114) 1805 o Updated qpack:dynamic_table_updated.update_type. It now has the 1806 value "inserted" instead of "added" (#113) 1808 o Updated qpack:dynamic_table_updated. It now has an "owner" field 1809 to differentiate encoder vs decoder state (#112) 1811 o Removed push_allowed from http:parameters_set (#110) 1813 o Removed explicit trigger field indications from events, since this 1814 was moved to be a generic property of the "data" field (#80) 1816 o Updated transport:connection_id_updated to be more in line with 1817 other similar events. Also dropped importance from Core to Base 1818 (#45) 1820 o Added length property to PaddingFrame (#34) 1822 o Added packet_number field to transport:frames_processed (#74) 1824 o Added a way to generically log packet header flags (first 8 bits) 1825 to PacketHeader 1827 o Added additional guidance on which events to log in which 1828 situations (#53) 1830 o Added "simulation:scenario" event to help indicate simulation 1831 details 1833 o Added "packets_acked" event (#107) 1835 o Added "datagram_ids" to the datagram_X and packet_X events to 1836 allow tracking of coalesced QUIC packets (#91) 1838 o Extended connection_state_updated with more fine-grained states 1839 (#49) 1841 B.3. Since draft-marx-qlog-event-definitions-quic-h3-00: 1843 o Event and category names are now all lowercase 1845 o Added many new events and their definitions 1847 o "type" fields have been made more specific (especially important 1848 for PacketType fields, which are now called packet_type instead of 1849 type) 1851 o Events are given an importance indicator (issue #22) 1852 o Event names are more consistent and use past tense (issue #21) 1854 o Triggers have been redefined as properties of the "data" field and 1855 updated for most events (issue #23) 1857 Appendix C. Design Variations 1859 TBD 1861 Appendix D. Acknowledgements 1863 Much of the initial work by Robin Marx was done at Hasselt 1864 University. 1866 Thanks to Marten Seemann, Jana Iyengar, Brian Trammell, Dmitri 1867 Tikhonov, Stephen Petrides, Jari Arkko, Marcus Ihlar, Victor 1868 Vasiliev, Mirja Kuehlewind, Jeremy Laine, Kazu Yamamoto, Christian 1869 Huitema, and Lucas Pardue for their feedback and suggestions. 1871 Authors' Addresses 1873 Robin Marx 1874 KU Leuven 1876 Email: robin.marx@kuleuven.be 1878 Luca Niccolini (editor) 1879 Facebook 1881 Email: lniccolini@fb.com 1883 Marten Seemann (editor) 1884 Protocol Labs 1886 Email: marten@protocol.ai