idnits 2.17.1 draft-ietf-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 (10 June 2021) is 1050 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: '120' on line 1522 == Unused Reference: 'QUIC-TRANSPORT' is defined on line 1366, but no explicit reference was found in the text == Outdated reference: A later version (-07) exists of draft-ietf-quic-qlog-h3-events-00 == Outdated reference: A later version (-08) exists of draft-ietf-quic-qlog-main-schema-00 Summary: 2 errors (**), 0 flaws (~~), 4 warnings (==), 2 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: 12 December 2021 Facebook 6 M. Seemann, Ed. 7 Protocol Labs 8 10 June 2021 10 QUIC event definitions for qlog 11 draft-ietf-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 12 December 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 (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 Simplified BSD License text 47 as described in Section 4.e of the Trust Legal Provisions and are 48 provided without warranty as described in the Simplified BSD License. 50 Table of Contents 52 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 53 1.1. Notational Conventions . . . . . . . . . . . . . . . . . 4 54 2. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . 4 55 2.1. Links to the main schema . . . . . . . . . . . . . . . . 4 56 2.1.1. Raw packet and frame information . . . . . . . . . . 5 57 2.1.2. Events not belonging to a single connection . . . . . 5 58 3. QUIC event definitions . . . . . . . . . . . . . . . . . . . 6 59 3.1. connectivity . . . . . . . . . . . . . . . . . . . . . . 6 60 3.1.1. server_listening . . . . . . . . . . . . . . . . . . 6 61 3.1.2. connection_started . . . . . . . . . . . . . . . . . 7 62 3.1.3. connection_closed . . . . . . . . . . . . . . . . . . 7 63 3.1.4. connection_id_updated . . . . . . . . . . . . . . . . 8 64 3.1.5. spin_bit_updated . . . . . . . . . . . . . . . . . . 8 65 3.1.6. connection_retried . . . . . . . . . . . . . . . . . 9 66 3.1.7. connection_state_updated . . . . . . . . . . . . . . 9 67 3.1.8. MIGRATION-related events . . . . . . . . . . . . . . 11 68 3.2. security . . . . . . . . . . . . . . . . . . . . . . . . 11 69 3.2.1. key_updated . . . . . . . . . . . . . . . . . . . . . 11 70 3.2.2. key_retired . . . . . . . . . . . . . . . . . . . . . 12 71 3.3. transport . . . . . . . . . . . . . . . . . . . . . . . . 12 72 3.3.1. version_information . . . . . . . . . . . . . . . . . 12 73 3.3.2. alpn_information . . . . . . . . . . . . . . . . . . 13 74 3.3.3. parameters_set . . . . . . . . . . . . . . . . . . . 14 75 3.3.4. parameters_restored . . . . . . . . . . . . . . . . . 16 76 3.3.5. packet_sent . . . . . . . . . . . . . . . . . . . . . 16 77 3.3.6. packet_received . . . . . . . . . . . . . . . . . . . 17 78 3.3.7. packet_dropped . . . . . . . . . . . . . . . . . . . 18 79 3.3.8. packet_buffered . . . . . . . . . . . . . . . . . . . 19 80 3.3.9. packets_acked . . . . . . . . . . . . . . . . . . . . 20 81 3.3.10. datagrams_sent . . . . . . . . . . . . . . . . . . . 20 82 3.3.11. datagrams_received . . . . . . . . . . . . . . . . . 21 83 3.3.12. datagram_dropped . . . . . . . . . . . . . . . . . . 21 84 3.3.13. stream_state_updated . . . . . . . . . . . . . . . . 22 85 3.3.14. frames_processed . . . . . . . . . . . . . . . . . . 23 86 3.3.15. data_moved . . . . . . . . . . . . . . . . . . . . . 24 87 3.4. recovery . . . . . . . . . . . . . . . . . . . . . . . . 25 88 3.4.1. parameters_set . . . . . . . . . . . . . . . . . . . 26 89 3.4.2. metrics_updated . . . . . . . . . . . . . . . . . . . 26 90 3.4.3. congestion_state_updated . . . . . . . . . . . . . . 27 91 3.4.4. loss_timer_updated . . . . . . . . . . . . . . . . . 28 92 3.4.5. packet_lost . . . . . . . . . . . . . . . . . . . . . 29 93 3.4.6. marked_for_retransmit . . . . . . . . . . . . . . . . 29 94 4. Security Considerations . . . . . . . . . . . . . . . . . . . 30 95 5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 30 96 6. References . . . . . . . . . . . . . . . . . . . . . . . . . 30 97 6.1. Normative References . . . . . . . . . . . . . . . . . . 30 98 6.2. Informative References . . . . . . . . . . . . . . . . . 31 99 Appendix A. QUIC data field definitions . . . . . . . . . . . . 31 100 A.1. IPAddress . . . . . . . . . . . . . . . . . . . . . . . . 31 101 A.2. PacketType . . . . . . . . . . . . . . . . . . . . . . . 31 102 A.3. PacketNumberSpace . . . . . . . . . . . . . . . . . . . . 31 103 A.4. PacketHeader . . . . . . . . . . . . . . . . . . . . . . 31 104 A.5. Token . . . . . . . . . . . . . . . . . . . . . . . . . . 32 105 A.6. KeyType . . . . . . . . . . . . . . . . . . . . . . . . . 32 106 A.7. QUIC Frames . . . . . . . . . . . . . . . . . . . . . . . 33 107 A.7.1. PaddingFrame . . . . . . . . . . . . . . . . . . . . 33 108 A.7.2. PingFrame . . . . . . . . . . . . . . . . . . . . . . 33 109 A.7.3. AckFrame . . . . . . . . . . . . . . . . . . . . . . 33 110 A.7.4. ResetStreamFrame . . . . . . . . . . . . . . . . . . 34 111 A.7.5. StopSendingFrame . . . . . . . . . . . . . . . . . . 34 112 A.7.6. CryptoFrame . . . . . . . . . . . . . . . . . . . . . 35 113 A.7.7. NewTokenFrame . . . . . . . . . . . . . . . . . . . . 35 114 A.7.8. StreamFrame . . . . . . . . . . . . . . . . . . . . . 35 115 A.7.9. MaxDataFrame . . . . . . . . . . . . . . . . . . . . 36 116 A.7.10. MaxStreamDataFrame . . . . . . . . . . . . . . . . . 36 117 A.7.11. MaxStreamsFrame . . . . . . . . . . . . . . . . . . . 36 118 A.7.12. DataBlockedFrame . . . . . . . . . . . . . . . . . . 36 119 A.7.13. StreamDataBlockedFrame . . . . . . . . . . . . . . . 36 120 A.7.14. StreamsBlockedFrame . . . . . . . . . . . . . . . . . 36 121 A.7.15. NewConnectionIDFrame . . . . . . . . . . . . . . . . 37 122 A.7.16. RetireConnectionIDFrame . . . . . . . . . . . . . . . 37 123 A.7.17. PathChallengeFrame . . . . . . . . . . . . . . . . . 37 124 A.7.18. PathResponseFrame . . . . . . . . . . . . . . . . . . 37 125 A.7.19. ConnectionCloseFrame . . . . . . . . . . . . . . . . 38 126 A.7.20. HandshakeDoneFrame . . . . . . . . . . . . . . . . . 38 127 A.7.21. UnknownFrame . . . . . . . . . . . . . . . . . . . . 38 128 A.7.22. TransportError . . . . . . . . . . . . . . . . . . . 38 129 A.7.23. CryptoError . . . . . . . . . . . . . . . . . . . . . 39 130 Appendix B. Change Log . . . . . . . . . . . . . . . . . . . . . 39 131 B.1. Since draft-marx-qlog-event-definitions-quic-h3-02: . . . 39 132 B.2. Since draft-marx-qlog-event-definitions-quic-h3-01: . . . 40 133 B.3. Since draft-marx-qlog-event-definitions-quic-h3-00: . . . 41 134 Appendix C. Design Variations . . . . . . . . . . . . . . . . . 41 135 Appendix D. Acknowledgements . . . . . . . . . . . . . . . . . . 42 136 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 42 138 1. Introduction 140 This document describes the values of the qlog name ("category" + 141 "event") and "data" fields and their semantics for the QUIC protocol. 142 This document is based on draft-34 of the QUIC I-Ds QUIC-TRANSPORT 143 [QUIC-RECOVERY] [QUIC-TLS]. HTTP/3 and QPACK events are defined in a 144 separate document [QLOG-H3]. 146 Feedback and discussion are welcome at https://github.com/quicwg/qlog 147 (https://github.com/quicwg/qlog). Readers are advised to refer to 148 the "editor's draft" at that URL for an up-to-date version of this 149 document. 151 Concrete examples of integrations of this schema in various 152 programming languages can be found at https://github.com/quiclog/ 153 qlog/ (https://github.com/quiclog/qlog/). 155 1.1. Notational Conventions 157 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 158 "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this 159 document are to be interpreted as described in [RFC2119]. 161 The examples and data definitions in ths document are expressed in a 162 custom data definition language, inspired by JSON and TypeScript, and 163 described in [QLOG-MAIN]. 165 2. Overview 167 This document describes the values of the qlog "name" ("category" + 168 "event") and "data" fields and their semantics for the QUIC protocol. 170 This document assumes the usage of the encompassing main qlog schema 171 defined in [QLOG-MAIN]. Each subsection below defines a separate 172 category (for example connectivity, transport, recovery) and each 173 subsubsection is an event type (for example "packet_received"). 175 For each event type, its importance and data definition is laid out, 176 often accompanied by possible values for the optional "trigger" 177 field. For the definition and semantics of "importance" and 178 "trigger", see the main schema document. 180 Most of the complex datastructures, enums and re-usable definitions 181 are grouped together on the bottom of this document for clarity. 183 2.1. Links to the main schema 185 This document re-uses all the fields defined in the main qlog schema 186 (e.g., name, category, type, data, group_id, protocol_type, the time- 187 related fields, importance, RawInfo, etc.). 189 One entry in the "protocol_type" qlog array field MUST be "QUIC" if 190 events from this document are included in a qlog trace. 192 When the qlog "group_id" field is used, it is recommended to use 193 QUIC's Original Destination Connection ID (ODCID, the CID chosen by 194 the client when first contacting the server), as this is the only 195 value that does not change over the course of the connection and can 196 be used to link more advanced QUIC packets (e.g., Retry, Version 197 Negotiation) to a given connection. Similarly, the ODCID should be 198 used as the qlog filename or file identifier, potentially suffixed by 199 the vantagepoint type (For example, abcd1234_server.qlog would 200 contain the server-side trace of the connection with ODCID abcd1234). 202 2.1.1. Raw packet and frame information 204 This document re-uses the definition of the RawInfo data class from 205 [QLOG-MAIN]. 207 Note: QUIC packets always include an AEAD authentication tag 208 ("trailer") at the end. As this tag is always the same size for a 209 given connection (it depends on the used TLS cipher), this 210 document does not define a separate "RawInfo:aead_tag_length" 211 field here. Instead, this field is reflected in 212 "transport:parameters_set" and can be logged only once. 214 Note: As QUIC uses trailers in packets, packet header_lengths can be 215 calculated as: 217 header_length = length - payload_length - aead_tag_length 219 For UDP datagrams, the calulation is simpler: 221 header_length = length - payload_length 223 Note: In some cases, the length fields are also explicitly reflected 224 inside of packet headers. For example, the QUIC STREAM frame has 225 a "length" field indicating its payload size. Similarly, the QUIC 226 Long Header has a "length" field which is equal to the payload 227 length plus the packet number length. In these cases, those 228 fields are intentionally preserved in the event definitions. Even 229 though this can lead to duplicate data when the full RawInfo is 230 logged, it allows a more direct mapping of the QUIC specifications 231 to qlog, making it easier for users to interpret. 233 2.1.2. Events not belonging to a single connection 235 For several types of events, it is sometimes impossible to tie them 236 to a specific conceptual QUIC connection (e.g., a packet_dropped 237 event triggered because the packet has an unknown connection_id in 238 the header). Since qlog events in a trace are typically associated 239 with a single connection, it is unclear how to log these events. 241 Ideally, implementers SHOULD create a separate, individual "endpoint- 242 level" trace file (or group_id value), not associated with a specific 243 connection (for example a "server.qlog" or group_id = "client"), and 244 log all events that do not belong to a single connection to this 245 grouping trace. However, this is not always practical, depending on 246 the implementation. Because the semantics of most of these events 247 are well-defined in the protocols and because they are difficult to 248 mis-interpret as belonging to a connection, implementers MAY choose 249 to log events not belonging to a particular connection in any other 250 trace, even those strongly associated with a single connection. 252 Note that this can make it difficult to match logs from different 253 vantage points with each other. For example, from the client side, 254 it is easy to log connections with version negotiation or retry in 255 the same trace, while on the server they would most likely be logged 256 in separate traces. Servers can take extra efforts (and keep 257 additional state) to keep these events combined in a single trace 258 however (for example by also matching connections on their four-tuple 259 instead of just the connection ID). 261 3. QUIC event definitions 263 Each subheading in this section is a qlog event category, while each 264 sub-subheading is a qlog event type. Concretely, for the following 265 two items, we have the category "connectivity" and event type 266 "server_listening", resulting in a concatenated qlog "name" field 267 value of "connectivity:server_listening". 269 3.1. connectivity 271 3.1.1. server_listening 273 Importance: Extra 275 Emitted when the server starts accepting connections. 277 Data: 279 { 280 ip_v4?: IPAddress, 281 ip_v6?: IPAddress, 282 port_v4?: uint32, 283 port_v6?: uint32, 285 retry_required?:boolean // the server will always answer client initials with a retry (no 1-RTT connection setups by choice) 286 } 287 Note: some QUIC stacks do not handle sockets directly and are thus 288 unable to log IP and/or port information. 290 3.1.2. connection_started 292 Importance: Base 294 Used for both attempting (client-perspective) and accepting (server- 295 perspective) new connections. Note that this event has overlap with 296 connection_state_updated and this is a separate event mainly because 297 of all the additional data that should be logged. 299 Data: 301 { 302 ip_version?: "v4" | "v6", 303 src_ip?: IPAddress, 304 dst_ip?: IPAddress, 306 protocol?: string, // transport layer protocol (default "QUIC") 307 src_port?: uint32, 308 dst_port?: uint32, 310 src_cid?: bytes, 311 dst_cid?: bytes, 313 } 315 Note: some QUIC stacks do not handle sockets directly and are thus 316 unable to log IP and/or port information. 318 3.1.3. connection_closed 320 Importance: Base 322 Used for logging when a connection was closed, typically when an 323 error or timeout occurred. Note that this event has overlap with 324 connectivity:connection_state_updated, as well as the 325 CONNECTION_CLOSE frame. However, in practice, when analyzing large 326 deployments, it can be useful to have a single event representing a 327 connection_closed event, which also includes an additional reason 328 field to provide additional information. Additionally, it is useful 329 to log closures due to timeouts, which are difficult to reflect using 330 the other options. 332 In QUIC there are two main connection-closing error categories: 333 connection and application errors. They have well-defined error 334 codes and semantics. Next to these however, there can be internal 335 errors that occur that may or may not get mapped to the official 336 error codes in implementation-specific ways. As such, multiple error 337 codes can be set on the same event to reflect this. 339 { 340 owner?:"local"|"remote", // which side closed the connection 342 connection_code?:TransportError | CryptoError | uint32, 343 application_code?:ApplicationError | uint32, 344 internal_code?:uint32, 346 reason?:string 347 } 349 Triggers: * clean * handshake_timeout * idle_timeout * error // this 350 is called the "immediate close" in the QUIC specification * 351 stateless_reset * version_mismatch * application // for example 352 HTTP/3's GOAWAY frame 354 3.1.4. connection_id_updated 356 Importance: Base 358 This event is emitted when either party updates their current 359 Connection ID. As this typically happens only sparingly over the 360 course of a connection, this event allows loggers to be more 361 efficient than logging the observed CID with each packet in the 362 .header field of the "packet_sent" or "packet_received" events. 364 This is viewed from the perspective of the one applying the new id. 365 As such, if we receive a new connection id from our peer, we will see 366 the dst_ fields are set. If we update our own connection id (e.g., 367 NEW_CONNECTION_ID frame), we log the src_ fields. 369 Data: 371 { 372 owner: "local" | "remote", 374 old?:bytes, 375 new?:bytes, 376 } 378 3.1.5. spin_bit_updated 380 Importance: Base 381 To be emitted when the spin bit changes value. It SHOULD NOT be 382 emitted if the spin bit is set without changing its value. 384 Data: 386 { 387 state: boolean 388 } 390 3.1.6. connection_retried 392 TODO 394 3.1.7. connection_state_updated 396 Importance: Base 398 This event is used to track progress through QUIC's complex handshake 399 and connection close procedures. It is intended to provide 400 exhaustive options to log each state individually, but also provides 401 a more basic, simpler set for implementations less interested in 402 tracking each smaller state transition. As such, users should not 403 expect to see -all- these states reflected in all qlogs and 404 implementers should focus on support for the SimpleConnectionState 405 set. 407 Data: ~~~ { old?: ConnectionState | SimpleConnectionState, new: 408 ConnectionState | SimpleConnectionState } 410 enum ConnectionState { attempted, // initial sent/received 411 peer_validated, // peer address validated by: client sent Handshake 412 packet OR client used CONNID chosen by the server. transport-draft- 413 32, section-8.1 handshake_started, early_write, // 1 RTT can be sent, 414 but handshake isn't done yet handshake_complete, // TLS handshake 415 complete: Finished received and sent. tls-draft-32, section-4.1.1 416 handshake_confirmed, // HANDSHAKE_DONE sent/received (connection is 417 now "active", 1RTT can be sent). tls-draft-32, section-4.1.2 closing, 418 draining, // connection_close sent/received closed // draining period 419 done, connection state discarded } 421 enum SimpleConnectionState { attempted, handshake_started, 422 handshake_confirmed, closed } ~~~ 424 These states correspond to the following transitions for both client 425 and server: 427 *Client:* 428 * send initial 430 - state = attempted 432 * get initial 434 - state = validated _(not really "needed" at the client, but 435 somewhat useful to indicate progress nonetheless)_ 437 * get first Handshake packet 439 - state = handshake_started 441 * get Handshake packet containing ServerFinished 443 - state = handshake_complete 445 * send ClientFinished 447 - state = early_write (1RTT can now be sent) 449 * get HANDSHAKE_DONE 451 - state = handshake_confirmed 453 *Server:* 455 * get initial 457 - state = attempted 459 * send initial _(don't think this needs a separate state, since some 460 handshake will always be sent in the same flight as this?)_ 462 * send handshake EE, CERT, CV, ... 464 - state = handshake_started 466 * send ServerFinished 468 - state = early_write (1RTT can now be sent) 470 * get first handshake packet / something using a server-issued CID 471 of min length 473 - state = validated 475 * get handshake packet containing ClientFinished 476 - state = handshake_complete 478 * send HANDSHAKE_DONE 480 - state = handshake_confirmed 482 Note: connection_state_changed with a new state of "attempted" is 483 the same conceptual event as the connection_started event above 484 from the client's perspective. Similarly, a state of "closing" or 485 "draining" corresponds to the connection_closed event. 487 3.1.8. MIGRATION-related events 489 e.g., path_updated 491 TODO: read up on the draft how migration works and whether to best 492 fit this here or in TRANSPORT TODO: integrate 493 https://tools.ietf.org/html/draft-deconinck-quic-multipath-02 495 For now, infer from other connectivity events and path_challenge/ 496 path_response frames 498 3.2. security 500 3.2.1. key_updated 502 Importance: Base 504 Note: secret_updated would be more correct, but in the draft it's 505 called KEY_UPDATE, so stick with that for consistency 507 Data: 509 { 510 key_type:KeyType, 511 old?:bytes, 512 new:bytes, 513 generation?:uint32 // needed for 1RTT key updates 514 } 516 Triggers: 518 * "tls" // (e.g., initial, handshake and 0-RTT keys are generated by 519 TLS) 521 * "remote_update" 523 * "local_update" 525 3.2.2. key_retired 527 Importance: Base 529 Data: 531 { 532 key_type:KeyType, 533 key?:bytes, 534 generation?:uint32 // needed for 1RTT key updates 535 } 537 Triggers: 539 * "tls" // (e.g., initial, handshake and 0-RTT keys are dropped 540 implicitly) 542 * "remote_update" 544 * "local_update" 546 3.3. transport 548 3.3.1. version_information 550 Importance: Core 552 QUIC endpoints each have their own list of of QUIC versions they 553 support. The client uses the most likely version in their first 554 initial. If the server does support that version, it replies with a 555 version_negotiation packet, containing supported versions. From 556 this, the client selects a version. This event aggregates all this 557 information in a single event type. It also allows logging of 558 supported versions at an endpoint without actual version negotiation 559 needing to happen. 561 Data: 563 { 564 server_versions?:Array, 565 client_versions?:Array, 566 chosen_version?:bytes 567 } 569 Intended use: 571 * When sending an initial, the client logs this event with 572 client_versions and chosen_version set 574 * Upon receiving a client initial with a supported version, the 575 server logs this event with server_versions and chosen_version set 577 * Upon receiving a client initial with an unsupported version, the 578 server logs this event with server_versions set and 579 client_versions to the single-element array containing the 580 client's attempted version. The absence of chosen_version implies 581 no overlap was found. 583 * Upon receiving a version negotiation packet from the server, the 584 client logs this event with client_versions set and 585 server_versions to the versions in the version negotiation packet 586 and chosen_version to the version it will use for the next initial 587 packet 589 3.3.2. alpn_information 591 Importance: Core 593 QUIC implementations each have their own list of application level 594 protocols and versions thereof they support. The client includes a 595 list of their supported options in its first initial as part of the 596 TLS Application Layer Protocol Negotiation (alpn) extension. If 597 there are common option(s), the server chooses the most optimal one 598 and communicates this back to the client. If not, the connection is 599 closed. 601 Data: 603 { 604 server_alpns?:Array, 605 client_alpns?:Array, 606 chosen_alpn?:string 607 } 609 Intended use: 611 * When sending an initial, the client logs this event with 612 client_alpns set 614 * When receiving an initial with a supported alpn, the server logs 615 this event with server_alpns set, client_alpns equalling the 616 client-provided list, and chosen_alpn to the value it will send 617 back to the client. 619 * When receiving an initial with an alpn, the client logs this event 620 with chosen_alpn to the received value. 622 * Alternatively, a client can choose to not log the first event, but 623 wait for the receipt of the server initial to log this event with 624 both client_alpns and chosen_alpn set. 626 3.3.3. parameters_set 628 Importance: Core 630 This event groups settings from several different sources (transport 631 parameters, TLS ciphers, etc.) into a single event. This is done to 632 minimize the amount of events and to decouple conceptual setting 633 impacts from their underlying mechanism for easier high-level 634 reasoning. 636 All these settings are typically set once and never change. However, 637 they are typically set at different times during the connection, so 638 there will typically be several instances of this event with 639 different fields set. 641 Note that some settings have two variations (one set locally, one 642 requested by the remote peer). This is reflected in the "owner" 643 field. As such, this field MUST be correct for all settings included 644 a single event instance. If you need to log settings from two sides, 645 you MUST emit two separate event instances. 647 In the case of connection resumption and 0-RTT, some of the server's 648 parameters are stored up-front at the client and used for the initial 649 connection startup. They are later updated with the server's reply. 650 In these cases, utilize the separate "parameters_restored" event to 651 indicate the initial values, and this event to indicate the updated 652 values, as normal. 654 Data: 656 { 657 owner?:"local" | "remote", 659 resumption_allowed?:boolean, // valid session ticket was received 660 early_data_enabled?:boolean, // early data extension was enabled on the TLS layer 661 tls_cipher?:string, // (e.g., "AES_128_GCM_SHA256") 662 aead_tag_length?:uint8, // depends on the TLS cipher, but it's easier to be explicit. Default value is 16 664 // transport parameters from the TLS layer: 665 original_destination_connection_id?:bytes, 666 initial_source_connection_id?:bytes, 667 retry_source_connection_id?:bytes, 668 stateless_reset_token?:Token, 669 disable_active_migration?:boolean, 671 max_idle_timeout?:uint64, 672 max_udp_payload_size?:uint32, 673 ack_delay_exponent?:uint16, 674 max_ack_delay?:uint16, 675 active_connection_id_limit?:uint32, 677 initial_max_data?:uint64, 678 initial_max_stream_data_bidi_local?:uint64, 679 initial_max_stream_data_bidi_remote?:uint64, 680 initial_max_stream_data_uni?:uint64, 681 initial_max_streams_bidi?:uint64, 682 initial_max_streams_uni?:uint64, 684 preferred_address?:PreferredAddress 685 } 687 interface PreferredAddress { 688 ip_v4:IPAddress, 689 ip_v6:IPAddress, 691 port_v4:uint16, 692 port_v6:uint16, 694 connection_id:bytes, 695 stateless_reset_token:Token 696 } 698 Additionally, this event can contain any number of unspecified 699 fields. This is to reflect setting of for example unknown (greased) 700 transport parameters or employed (proprietary) extensions. 702 3.3.4. parameters_restored 704 Importance: Base 706 When using QUIC 0-RTT, clients are expected to remember and restore 707 the server's transport parameters from the previous connection. This 708 event is used to indicate which parameters were restored and to which 709 values when utilizing 0-RTT. Note that not all transport parameters 710 should be restored (many are even prohibited from being re-utilized). 711 The ones listed here are the ones expected to be useful for correct 712 0-RTT usage. 714 Data: 716 { 717 disable_active_migration?:boolean, 719 max_idle_timeout?:uint64, 720 max_udp_payload_size?:uint32, 721 active_connection_id_limit?:uint32, 723 initial_max_data?:uint64, 724 initial_max_stream_data_bidi_local?:uint64, 725 initial_max_stream_data_bidi_remote?:uint64, 726 initial_max_stream_data_uni?:uint64, 727 initial_max_streams_bidi?:uint64, 728 initial_max_streams_uni?:uint64, 729 } 731 Note that, like parameters_set above, this event can contain any 732 number of unspecified fields to allow for additional/custom 733 parameters. 735 3.3.5. packet_sent 737 Importance: Core 739 Data: 741 { 742 header:PacketHeader, 744 frames?:Array, // see appendix for the definitions 746 is_coalesced?:boolean, // default value is false 748 retry_token?:Token, // only if header.packet_type === retry 750 stateless_reset_token?:bytes, // only if header.packet_type === stateless_reset. Is always 128 bits in length. 752 supported_versions:Array, // only if header.packet_type === version_negotiation 754 raw?:RawInfo, 755 datagram_id?:uint32 756 } 758 Note: We do not explicitly log the encryption_level or 759 packet_number_space: the header.packet_type specifies this by 760 inference (assuming correct implementation) 762 Triggers: 764 * "retransmit_reordered" // draft-23 5.1.1 766 * "retransmit_timeout" // draft-23 5.1.2 768 * "pto_probe" // draft-23 5.3.1 770 * "retransmit_crypto" // draft-19 6.2 772 * "cc_bandwidth_probe" // needed for some CCs to figure out 773 bandwidth allocations when there are no normal sends 775 Note: for more details on "datagram_id", see Section 3.3.10. It is 776 only needed when keeping track of packet coalescing. 778 3.3.6. packet_received 780 Importance: Core 782 Data: 784 { 785 header:PacketHeader, 787 frames?:Array, // see appendix for the definitions 789 is_coalesced?:boolean, 791 retry_token?:Token, // only if header.packet_type === retry 793 stateless_reset_token?:bytes, // only if header.packet_type === stateless_reset. Is always 128 bits in length. 795 supported_versions:Array, // only if header.packet_type === version_negotiation 797 raw?:RawInfo, 798 datagram_id?:uint32 799 } 801 Note: We do not explicitly log the encryption_level or 802 packet_number_space: the header.packet_type specifies this by 803 inference (assuming correct implementation) 805 Triggers: 807 * "keys_available" // if packet was buffered because it couldn't be 808 decrypted before 810 Note: for more details on "datagram_id", see Section 3.3.10. It is 811 only needed when keeping track of packet coalescing. 813 3.3.7. packet_dropped 815 Importance: Base 817 This event indicates a QUIC-level packet was dropped after partial or 818 no parsing. 820 Data: 822 { 823 header?:PacketHeader, // primarily packet_type should be filled here, as other fields might not be parseable 825 raw?:RawInfo, 826 datagram_id?:uint32 827 } 829 For this event, the "trigger" field SHOULD be set (for example to one 830 of the values below), as this helps tremendously in debugging. 832 Triggers: 834 * "key_unavailable" 836 * "unknown_connection_id" 838 * "header_parse_error" 840 * "payload_decrypt_error" 842 * "protocol_violation" 844 * "dos_prevention" 846 * "unsupported_version" 848 * "unexpected_packet" 850 * "unexpected_source_connection_id" 852 * "unexpected_version" 854 * "duplicate" 856 * "invalid_initial" 858 Note: sometimes packets are dropped before they can be associated 859 with a particular connection (e.g., in case of 860 "unsupported_version"). This situation is discussed more in 861 Section 2.1.2. 863 Note: for more details on "datagram_id", see Section 3.3.10. It is 864 only needed when keeping track of packet coalescing. 866 3.3.8. packet_buffered 868 Importance: Base 870 This event is emitted when a packet is buffered because it cannot be 871 processed yet. Typically, this is because the packet cannot be 872 parsed yet, and thus we only log the full packet contents when it was 873 parsed in a packet_received event. 875 Data: 877 { 878 header?:PacketHeader, // primarily packet_type and possible packet_number should be filled here, as other elements might not be available yet 880 raw?:RawInfo, 881 datagram_id?:uint32 882 } 884 Note: for more details on "datagram_id", see Section 3.3.10. It is 885 only needed when keeping track of packet coalescing. 887 Triggers: 889 * "backpressure" // indicates the parser cannot keep up, temporarily 890 buffers packet for later processing 892 * "keys_unavailable" // if packet cannot be decrypted because the 893 proper keys were not yet available 895 3.3.9. packets_acked 897 Importance: Extra 899 This event is emitted when a (group of) sent packet(s) is 900 acknowledged by the remote peer _for the first time_. This 901 information could also be deduced from the contents of received ACK 902 frames. However, ACK frames require additional processing logic to 903 determine when a given packet is acknowledged for the first time, as 904 QUIC uses ACK ranges which can include repeated ACKs. Additionally, 905 this event can be used by implementations that do not log frame 906 contents. 908 Data: ~~~ { packet_number_space?:PacketNumberSpace, 910 packet_numbers?:Array } ~~~ 912 Note: if packet_number_space is omitted, it assumes the default value 913 of PacketNumberSpace.application_data, as this is by far the most 914 prevalent packet number space a typical QUIC connection will use. 916 3.3.10. datagrams_sent 918 Importance: Extra 920 When we pass one or more UDP-level datagrams to the socket. This is 921 useful for determining how QUIC packet buffers are drained to the OS. 923 Data: 925 { 926 count?:uint16, // to support passing multiple at once 927 raw?:Array, // RawInfo:length field indicates total length of the datagrams, including UDP header length 929 datagram_ids?:Array 930 } 932 Note: QUIC itself does not have a concept of a "datagram_id". This 933 field is a purely qlog-specific construct to allow tracking how 934 multiple QUIC packets are coalesced inside of a single UDP datagram, 935 which is an important optimization during the QUIC handshake. For 936 this, implementations assign a (per-endpoint) unique ID to each 937 datagram and keep track of which packets were coalesced into the same 938 datagram. As packet coalescing typically only happens during the 939 handshake (as it requires at least one long header packet), this can 940 be done without much overhead. 942 3.3.11. datagrams_received 944 Importance: Extra 946 When we receive one or more UDP-level datagrams from the socket. 947 This is useful for determining how datagrams are passed to the user 948 space stack from the OS. 950 Data: 952 { 953 count?:uint16, // to support passing multiple at once 954 raw?:Array, // RawInfo:length field indicates total length of the datagrams, including UDP header length 956 datagram_ids?:Array 957 } 959 Note: for more details on "datagram_ids", see Section 3.3.10. 961 3.3.12. datagram_dropped 963 Importance: Extra 965 When we drop a UDP-level datagram. This is typically if it does not 966 contain a valid QUIC packet (in that case, use packet_dropped 967 instead). 969 Data: 971 { 972 raw?:RawInfo 973 } 975 3.3.13. stream_state_updated 977 Importance: Base 979 This event is emitted whenever the internal state of a QUIC stream is 980 updated, as described in QUIC transport draft-23 section 3. Most of 981 this can be inferred from several types of frames going over the 982 wire, but it's much easier to have explicit signals for these state 983 changes. 985 Data: 987 { 988 stream_id:uint64, 989 stream_type?:"unidirectional"|"bidirectional", // mainly useful when opening the stream 991 old?:StreamState, 992 new:StreamState, 994 stream_side?:"sending"|"receiving" 995 } 997 enum StreamState { 998 // bidirectional stream states, draft-23 3.4. 999 idle, 1000 open, 1001 half_closed_local, 1002 half_closed_remote, 1003 closed, 1005 // sending-side stream states, draft-23 3.1. 1006 ready, 1007 send, 1008 data_sent, 1009 reset_sent, 1010 reset_received, 1012 // receive-side stream states, draft-23 3.2. 1013 receive, 1014 size_known, 1015 data_read, 1016 reset_read, 1018 // both-side states 1019 data_received, 1021 // qlog-defined 1022 destroyed // memory actually freed 1023 } 1025 Note: QUIC implementations SHOULD mainly log the simplified 1026 bidirectional (HTTP/2-alike) stream states (e.g., idle, open, closed) 1027 instead of the more finegrained stream states (e.g., data_sent, 1028 reset_received). These latter ones are mainly for more in-depth 1029 debugging. Tools SHOULD be able to deal with both types equally. 1031 3.3.14. frames_processed 1033 Importance: Extra 1034 This event's main goal is to prevent a large proliferation of 1035 specific purpose events (e.g., packets_acknowledged, 1036 flow_control_updated, stream_data_received). We want to give 1037 implementations the opportunity to (selectively) log this type of 1038 signal without having to log packet-level details (e.g., in 1039 packet_received). Since for almost all cases, the effects of 1040 applying a frame to the internal state of an implementation can be 1041 inferred from that frame's contents, we aggregate these events in 1042 this single "frames_processed" event. 1044 Note: This event can be used to signal internal state change not 1045 resulting directly from the actual "parsing" of a frame (e.g., the 1046 frame could have been parsed, data put into a buffer, then later 1047 processed, then logged with this event). 1049 Note: Implementations logging "packet_received" and which include all 1050 of the packet's constituent frames therein, are not expected to emit 1051 this "frames_processed" event. Rather, implementations not wishing 1052 to log full packets or that wish to explicitly convey extra 1053 information about when frames are processed (if not directly tied to 1054 their reception) can use this event. 1056 Note: for some events, this approach will lose some information 1057 (e.g., for which encryption level are packets being acknowledged?). 1058 If this information is important, please use the packet_received 1059 event instead. 1061 Note: in some implementations, it can be difficult to log frames 1062 directly, even when using packet_sent and packet_received events. 1063 For these cases, this event also contains the direct packet_number 1064 field, which can be used to more explicitly link this event to the 1065 packet_sent/received events. 1067 Data: 1069 { 1070 frames:Array, // see appendix for the definitions 1072 packet_number?:uint64 1073 } 1075 3.3.15. data_moved 1077 Importance: Base 1079 Used to indicate when data moves between the different layers (for 1080 example passing from the application protocol (e.g., HTTP) to QUIC 1081 stream buffers and vice versa) or between the application protocol 1082 (e.g., HTTP) and the actual user application on top (for example a 1083 browser engine). This helps make clear the flow of data, how long 1084 data remains in various buffers and the overheads introduced by 1085 individual layers. 1087 For example, this helps make clear whether received data on a QUIC 1088 stream is moved to the application protocol immediately (for example 1089 per received packet) or in larger batches (for example, all QUIC 1090 packets are processed first and afterwards the application layer 1091 reads from the streams with newly available data). This in turn can 1092 help identify bottlenecks or scheduling problems. 1094 Data: 1096 { 1097 stream_id?:uint64, 1098 offset?:uint64, 1099 length?:uint64, // byte length of the moved data 1101 from?:string, // typically: use either of "user","application","transport","network" 1102 to?:string, // typically: use either of "user","application","transport","network" 1104 data?:bytes // raw bytes that were transferred 1105 } 1107 Note: we do not for example use a "direction" field (with values "up" 1108 and "down") to specify the data flow. This is because in some 1109 optimized implementations, data might skip some individual layers. 1110 Additionally, using explicit "from" and "to" fields is more flexible 1111 and allows the definition of other conceptual "layers" (for example 1112 to indicate data from QUIC CRYPTO frames being passed to a TLS 1113 library ("security") or from HTTP/3 to QPACK ("qpack")). 1115 Note: this event type is part of the "transport" category, but really 1116 spans all the different layers. This means we have a few leaky 1117 abstractions here (for example, the stream_id or stream offset might 1118 not be available at some logging points, or the raw data might not be 1119 in a byte-array form). In these situations, implementers can decide 1120 to define new, in-context fields to aid in manual debugging. 1122 3.4. recovery 1124 Note: most of the events in this category are kept generic to support 1125 different recovery approaches and various congestion control 1126 algorithms. Tool creators SHOULD make an effort to support and 1127 visualize even unknown data in these events (e.g., plot unknown 1128 congestion states by name on a timeline visualization). 1130 3.4.1. parameters_set 1132 Importance: Base 1134 This event groups initial parameters from both loss detection and 1135 congestion control into a single event. All these settings are 1136 typically set once and never change. Implementation that do, for 1137 some reason, change these parameters during execution, MAY emit the 1138 parameters_set event twice. 1140 Data: 1142 { 1143 // Loss detection, see recovery draft-23, Appendix A.2 1144 reordering_threshold?:uint16, // in amount of packets 1145 time_threshold?:float, // as RTT multiplier 1146 timer_granularity?:uint16, // in ms 1147 initial_rtt?:float, // in ms 1149 // congestion control, Appendix B.1. 1150 max_datagram_size?:uint32, // in bytes // Note: this could be updated after pmtud 1151 initial_congestion_window?:uint64, // in bytes 1152 minimum_congestion_window?:uint32, // in bytes // Note: this could change when max_datagram_size changes 1153 loss_reduction_factor?:float, 1154 persistent_congestion_threshold?:uint16 // as PTO multiplier 1155 } 1157 Additionally, this event can contain any number of unspecified fields 1158 to support different recovery approaches. 1160 3.4.2. metrics_updated 1162 Importance: Core 1164 This event is emitted when one or more of the observable recovery 1165 metrics changes value. This event SHOULD group all possible metric 1166 updates that happen at or around the same time in a single event 1167 (e.g., if min_rtt and smoothed_rtt change at the same time, they 1168 should be bundled in a single metrics_updated entry, rather than 1169 split out into two). Consequently, a metrics_updated event is only 1170 guaranteed to contain at least one of the listed metrics. 1172 Data: 1174 { 1175 // Loss detection, see recovery draft-23, Appendix A.3 1176 min_rtt?:float, // in ms or us, depending on the overarching qlog's configuration 1177 smoothed_rtt?:float, // in ms or us, depending on the overarching qlog's configuration 1178 latest_rtt?:float, // in ms or us, depending on the overarching qlog's configuration 1179 rtt_variance?:float, // in ms or us, depending on the overarching qlog's configuration 1181 pto_count?:uint16, 1183 // Congestion control, Appendix B.2. 1184 congestion_window?:uint64, // in bytes 1185 bytes_in_flight?:uint64, 1187 ssthresh?:uint64, // in bytes 1189 // qlog defined 1190 packets_in_flight?:uint64, // sum of all packet number spaces 1192 pacing_rate?:uint64 // in bps 1193 } 1195 Note: to make logging easier, implementations MAY log values even if 1196 they are the same as previously reported values (e.g., two subsequent 1197 METRIC_UPDATE entries can both report the exact same value for 1198 min_rtt). However, applications SHOULD try to log only actual 1199 updates to values. 1201 Additionally, this event can contain any number of unspecified fields 1202 to support different recovery approaches. 1204 3.4.3. congestion_state_updated 1206 Importance: Base 1208 This event signifies when the congestion controller enters a 1209 significant new state and changes its behaviour. This event's 1210 definition is kept generic to support different Congestion Control 1211 algorithms. For example, for the algorithm defined in the Recovery 1212 draft ("enhanced" New Reno), the following states are defined: 1214 * slow_start 1216 * congestion_avoidance 1218 * application_limited 1220 * recovery 1221 Data: 1223 { 1224 old?:string, 1225 new:string 1226 } 1228 The "trigger" field SHOULD be logged if there are multiple ways in 1229 which a state change can occur but MAY be omitted if a given state 1230 can only be due to a single event occuring (e.g., slow start is 1231 exited only when ssthresh is exceeded). 1233 Some triggers for ("enhanced" New Reno): 1235 * persistent_congestion 1237 * ECN 1239 3.4.4. loss_timer_updated 1241 Importance: Extra 1243 This event is emitted when a recovery loss timer changes state. The 1244 three main event types are: 1246 * set: the timer is set with a delta timeout for when it will 1247 trigger next 1249 * expired: when the timer effectively expires after the delta 1250 timeout 1252 * cancelled: when a timer is cancelled (e.g., all outstanding 1253 packets are acknowledged, start idle period) 1255 Note: to indicate an active timer's timeout update, a new "set" event 1256 is used. 1258 Data: 1260 { 1261 timer_type?:"ack"|"pto", // called "mode" in draft-23 A.9. 1262 packet_number_space?: PacketNumberSpace, 1264 event_type:"set"|"expired"|"cancelled", 1266 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 1267 } 1268 TODO: how about CC algo's that use multiple timers? How generic do 1269 these events need to be? Just support QUIC-style recovery from the 1270 spec or broader? 1272 TODO: read up on the loss detection logic in draft-27 onward and see 1273 if this suffices 1275 3.4.5. packet_lost 1277 Importance: Core 1279 This event is emitted when a packet is deemed lost by loss detection. 1281 Data: 1283 { 1284 header?:PacketHeader, // should include at least the packet_type and packet_number 1286 // not all implementations will keep track of full packets, so these are optional 1287 frames?:Array // see appendix for the definitions 1288 } 1290 For this event, the "trigger" field SHOULD be set (for example to one 1291 of the values below), as this helps tremendously in debugging. 1293 Triggers: 1295 * "reordering_threshold", 1297 * "time_threshold" 1299 * "pto_expired" // draft-23 section 5.3.1, MAY 1301 3.4.6. marked_for_retransmit 1303 Importance: Extra 1305 This event indicates which data was marked for retransmit upon 1306 detecing a packet loss (see packet_lost). Similar to our reasoning 1307 for the "frames_processed" event, in order to keep the amount of 1308 different events low, we group this signal for all types of 1309 retransmittable data in a single event based on existing QUIC frame 1310 definitions. 1312 Implementations retransmitting full packets or frames directly can 1313 just log the consituent frames of the lost packet here (or do away 1314 with this event and use the contents of the packet_lost event 1315 instead). Conversely, implementations that have more complex logic 1316 (e.g., marking ranges in a stream's data buffer as in-flight), or 1317 that do not track sent frames in full (e.g., only stream offset + 1318 length), can translate their internal behaviour into the appropriate 1319 frame instance here even if that frame was never or will never be put 1320 on the wire. 1322 Note: much of this data can be inferred if implementations log 1323 packet_sent events (e.g., looking at overlapping stream data offsets 1324 and length, one can determine when data was retransmitted). 1326 Data: 1328 { 1329 frames:Array, // see appendix for the definitions 1330 } 1332 4. Security Considerations 1334 TBD 1336 5. IANA Considerations 1338 TBD 1340 6. References 1342 6.1. Normative References 1344 [QLOG-H3] Marx, R., Ed., Niccolini, L., Ed., and M. Seemann, Ed., 1345 "HTTP/3 and QPACK event definitions for qlog", Work in 1346 Progress, Internet-Draft, draft-ietf-quic-qlog-h3-events- 1347 00, . 1350 [QLOG-MAIN] 1351 Marx, R., Ed., Niccolini, L., Ed., and M. Seemann, Ed., 1352 "Main logging schema for qlog", Work in Progress, 1353 Internet-Draft, draft-ietf-quic-qlog-main-schema-00, 1354 . 1357 [QUIC-RECOVERY] 1358 Iyengar, J., Ed. and I. Swett, Ed., "QUIC Loss Detection 1359 and Congestion Control", RFC 9002, DOI 10.17487/RFC9002, 1360 May 2021, . 1362 [QUIC-TLS] Thomson, M., Ed. and S. Turner, Ed., "Using TLS to Secure 1363 QUIC", RFC 9001, DOI 10.17487/RFC9001, May 2021, 1364 . 1366 [QUIC-TRANSPORT] 1367 Iyengar, J., Ed. and M. Thomson, Ed., "QUIC: A UDP-Based 1368 Multiplexed and Secure Transport", RFC 9000, 1369 DOI 10.17487/RFC9000, May 2021, 1370 . 1372 6.2. Informative References 1374 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 1375 Requirement Levels", BCP 14, RFC 2119, 1376 DOI 10.17487/RFC2119, March 1997, 1377 . 1379 Appendix A. QUIC data field definitions 1381 A.1. IPAddress 1383 class IPAddress : string | bytes; 1385 // 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) 1387 A.2. PacketType 1389 enum PacketType { 1390 initial, 1391 handshake, 1392 zerortt = "0RTT", 1393 onertt = "1RTT", 1394 retry, 1395 version_negotiation, 1396 stateless_reset, 1397 unknown 1398 } 1400 A.3. PacketNumberSpace 1402 enum PacketNumberSpace { 1403 initial, 1404 handshake, 1405 application_data 1406 } 1408 A.4. PacketHeader 1409 class PacketHeader { 1410 // Note: short vs long header is implicit through PacketType 1412 packet_type: PacketType; 1413 packet_number: uint64; 1415 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 1417 token?:Token; // only if packet_type == initial 1419 length?: uint16, // only if packet_type == initial || handshake || 0RTT. Signifies length of the packet_number plus the payload. 1421 // only if present in the header 1422 // if correctly using transport:connection_id_updated events, 1423 // dcid can be skipped for 1RTT packets 1424 version?: bytes; // e.g., "ff00001d" for draft-29 1425 scil?: uint8; 1426 dcil?: uint8; 1427 scid?: bytes; 1428 dcid?: bytes; 1429 } 1431 A.5. Token 1433 class Token { 1434 type?:"retry"|"resumption"|"stateless_reset"; 1436 length?:uint32; // byte length of the token 1437 data?:bytes; // raw byte value of the token 1439 details?:any; // decoded fields included in the token (typically: peer's IP address, creation time) 1440 } 1442 The token carried in an Initial packet can either be a retry token 1443 from a Retry packet, a stateless reset token from a Stateless Reset 1444 packet or one originally provided by the server in a NEW_TOKEN frame 1445 used when resuming a connection (e.g., for address validation 1446 purposes). Retry and resumption tokens typically contain encoded 1447 metadata to check the token's validity when it is used, but this 1448 metadata and its format is implementation specific. For that, this 1449 field includes a general-purpose "details" field. 1451 A.6. KeyType 1452 enum KeyType { 1453 server_initial_secret, 1454 client_initial_secret, 1456 server_handshake_secret, 1457 client_handshake_secret, 1459 server_0rtt_secret, 1460 client_0rtt_secret, 1462 server_1rtt_secret, 1463 client_1rtt_secret 1464 } 1466 A.7. QUIC Frames 1468 type QuicFrame = PaddingFrame | PingFrame | AckFrame | ResetStreamFrame | StopSendingFrame | CryptoFrame | NewTokenFrame | StreamFrame | MaxDataFrame | MaxStreamDataFrame | MaxStreamsFrame | DataBlockedFrame | StreamDataBlockedFrame | StreamsBlockedFrame | NewConnectionIDFrame | RetireConnectionIDFrame | PathChallengeFrame | PathResponseFrame | ConnectionCloseFrame | HandshakeDoneFrame | UnknownFrame; 1470 A.7.1. PaddingFrame 1472 In QUIC, PADDING frames are simply identified as a single byte of 1473 value 0. As such, each padding byte could be theoretically 1474 interpreted and logged as an individual PaddingFrame. 1476 However, as this leads to heavy logging overhead, implementations 1477 SHOULD instead emit just a single PaddingFrame and set the 1478 payload_length property to the amount of PADDING bytes/frames 1479 included in the packet. 1481 class PaddingFrame{ 1482 frame_type:string = "padding"; 1484 length?:uint32; // total frame length, including frame header 1485 payload_length?:uint32; 1486 } 1488 A.7.2. PingFrame 1490 class PingFrame{ 1491 frame_type:string = "ping"; 1493 length?:uint32; // total frame length, including frame header 1494 payload_length?:uint32; 1495 } 1497 A.7.3. AckFrame 1498 class AckFrame{ 1499 frame_type:string = "ack"; 1501 ack_delay?:float; // in ms 1503 // first number is "from": lowest packet number in interval 1504 // second number is "to": up to and including // highest packet number in interval 1505 // e.g., looks like [[1,2],[4,5]] 1506 acked_ranges?:Array<[uint64, uint64]|[uint64]>; 1508 // ECN (explicit congestion notification) related fields (not always present) 1509 ect1?:uint64; 1510 ect0?:uint64; 1511 ce?:uint64; 1513 length?:uint32; // total frame length, including frame header 1514 payload_length?:uint32; 1515 } 1517 Note: the packet ranges in AckFrame.acked_ranges do not necessarily 1518 have to be ordered (e.g., [[5,9],[1,4]] is a valid value). 1520 Note: the two numbers in the packet range can be the same (e.g., 1521 [120,120] means that packet with number 120 was ACKed). However, in 1522 that case, implementers SHOULD log [120] instead and tools MUST be 1523 able to deal with both notations. 1525 A.7.4. ResetStreamFrame 1527 class ResetStreamFrame{ 1528 frame_type:string = "reset_stream"; 1530 stream_id:uint64; 1531 error_code:ApplicationError | uint32; 1532 final_size:uint64; // in bytes 1534 length?:uint32; // total frame length, including frame header 1535 payload_length?:uint32; 1536 } 1538 A.7.5. StopSendingFrame 1539 class StopSendingFrame{ 1540 frame_type:string = "stop_sending"; 1542 stream_id:uint64; 1543 error_code:ApplicationError | uint32; 1545 length?:uint32; // total frame length, including frame header 1546 payload_length?:uint32; 1547 } 1549 A.7.6. CryptoFrame 1551 class CryptoFrame{ 1552 frame_type:string = "crypto"; 1554 offset:uint64; 1555 length:uint64; 1557 payload_length?:uint32; 1558 } 1560 A.7.7. NewTokenFrame 1562 class NewTokenFrame{ 1563 frame_type:string = "new_token"; 1565 token:Token 1566 } 1568 A.7.8. StreamFrame 1570 class StreamFrame{ 1571 frame_type:string = "stream"; 1573 stream_id:uint64; 1575 // These two MUST always be set 1576 // If not present in the Frame type, log their default values 1577 offset:uint64; 1578 length:uint64; 1580 // this MAY be set any time, but MUST only be set if the value is "true" 1581 // if absent, the value MUST be assumed to be "false" 1582 fin?:boolean; 1584 raw?:bytes; 1585 } 1586 A.7.9. MaxDataFrame 1588 class MaxDataFrame{ 1589 frame_type:string = "max_data"; 1591 maximum:uint64; 1592 } 1594 A.7.10. MaxStreamDataFrame 1596 class MaxStreamDataFrame{ 1597 frame_type:string = "max_stream_data"; 1599 stream_id:uint64; 1600 maximum:uint64; 1601 } 1603 A.7.11. MaxStreamsFrame 1605 class MaxStreamsFrame{ 1606 frame_type:string = "max_streams"; 1608 stream_type:string = "bidirectional" | "unidirectional"; 1609 maximum:uint64; 1610 } 1612 A.7.12. DataBlockedFrame 1614 class DataBlockedFrame{ 1615 frame_type:string = "data_blocked"; 1617 limit:uint64; 1618 } 1620 A.7.13. StreamDataBlockedFrame 1622 class StreamDataBlockedFrame{ 1623 frame_type:string = "stream_data_blocked"; 1625 stream_id:uint64; 1626 limit:uint64; 1627 } 1629 A.7.14. StreamsBlockedFrame 1630 class StreamsBlockedFrame{ 1631 frame_type:string = "streams_blocked"; 1633 stream_type:string = "bidirectional" | "unidirectional"; 1634 limit:uint64; 1635 } 1637 A.7.15. NewConnectionIDFrame 1639 class NewConnectionIDFrame{ 1640 frame_type:string = "new_connection_id"; 1642 sequence_number:uint32; 1643 retire_prior_to:uint32; 1645 connection_id_length?:uint8; 1646 connection_id:bytes; 1648 stateless_reset_token?:Token; 1649 } 1651 A.7.16. RetireConnectionIDFrame 1653 class RetireConnectionIDFrame{ 1654 frame_type:string = "retire_connection_id"; 1656 sequence_number:uint32; 1657 } 1659 A.7.17. PathChallengeFrame 1661 class PathChallengeFrame{ 1662 frame_type:string = "path_challenge"; 1664 data?:bytes; // always 64-bit 1665 } 1667 A.7.18. PathResponseFrame 1669 class PathResponseFrame{ 1670 frame_type:string = "path_response"; 1672 data?:bytes; // always 64-bit 1673 } 1675 A.7.19. ConnectionCloseFrame 1677 raw_error_code is the actual, numerical code. This is useful because 1678 some error types are spread out over a range of codes (e.g., QUIC's 1679 crypto_error). 1681 type ErrorSpace = "transport" | "application"; 1683 class ConnectionCloseFrame{ 1684 frame_type:string = "connection_close"; 1686 error_space?:ErrorSpace; 1687 error_code?:TransportError | ApplicationError | uint32; 1688 raw_error_code?:uint32; 1689 reason?:string; 1691 trigger_frame_type?:uint64 | string; // For known frame types, the appropriate "frame_type" string. For unknown frame types, the hex encoded identifier value 1692 } 1694 A.7.20. HandshakeDoneFrame 1696 class HandshakeDoneFrame{ 1697 frame_type:string = "handshake_done"; 1698 } 1700 A.7.21. UnknownFrame 1702 class UnknownFrame{ 1703 frame_type:string = "unknown"; 1704 raw_frame_type:uint64; 1706 raw_length?:uint32; 1707 raw?:bytes; 1708 } 1710 A.7.22. TransportError 1711 enum TransportError { 1712 no_error, 1713 internal_error, 1714 connection_refused, 1715 flow_control_error, 1716 stream_limit_error, 1717 stream_state_error, 1718 final_size_error, 1719 frame_encoding_error, 1720 transport_parameter_error, 1721 connection_id_limit_error, 1722 protocol_violation, 1723 invalid_token, 1724 application_error, 1725 crypto_buffer_exceeded 1726 } 1728 A.7.23. CryptoError 1730 These errors are defined in the TLS document as "A TLS alert is 1731 turned into a QUIC connection error by converting the one-byte alert 1732 description into a QUIC error code. The alert description is added 1733 to 0x100 to produce a QUIC error code from the range reserved for 1734 CRYPTO_ERROR." 1736 This approach maps badly to a pre-defined enum. As such, we define 1737 the crypto_error string as having a dynamic component here, which 1738 should include the hex-encoded value of the TLS alert description. 1740 enum CryptoError { 1741 crypto_error_{TLS_ALERT} 1742 } 1744 Appendix B. Change Log 1746 B.1. Since draft-marx-qlog-event-definitions-quic-h3-02: 1748 * These changes were done in preparation of the adoption of the 1749 drafts by the QUIC working group (#137) 1751 * Split QUIC and HTTP/3 events into two separate documents 1753 * Moved RawInfo, Importance, Generic events and Simulation events to 1754 the main schema document. 1756 * Changed to/from value options of the "data_moved" event 1758 B.2. Since draft-marx-qlog-event-definitions-quic-h3-01: 1760 Major changes: 1762 * Moved data_moved from http to transport. Also made the "from" and 1763 "to" fields flexible strings instead of an enum (#111,#65) 1765 * Moved packet_type fields to PacketHeader. Moved packet_size field 1766 out of PacketHeader to RawInfo:length (#40) 1768 * Made events that need to log packet_type and packet_number use a 1769 header field instead of logging these fields individually 1771 * Added support for logging retry, stateless reset and initial 1772 tokens (#94,#86,#117) 1774 * Moved separate general event categories into a single category 1775 "generic" (#47) 1777 * Added "transport:connection_closed" event (#43,#85,#78,#49) 1779 * Added version_information and alpn_information events 1780 (#85,#75,#28) 1782 * Added parameters_restored events to help clarify 0-RTT behaviour 1783 (#88) 1785 Smaller changes: 1787 * Merged loss_timer events into one loss_timer_updated event 1789 * Field data types are now strongly defined (#10,#39,#36,#115) 1791 * Renamed qpack instruction_received and instruction_sent to 1792 instruction_created and instruction_parsed (#114) 1794 * Updated qpack:dynamic_table_updated.update_type. It now has the 1795 value "inserted" instead of "added" (#113) 1797 * Updated qpack:dynamic_table_updated. It now has an "owner" field 1798 to differentiate encoder vs decoder state (#112) 1800 * Removed push_allowed from http:parameters_set (#110) 1802 * Removed explicit trigger field indications from events, since this 1803 was moved to be a generic property of the "data" field (#80) 1805 * Updated transport:connection_id_updated to be more in line with 1806 other similar events. Also dropped importance from Core to Base 1807 (#45) 1809 * Added length property to PaddingFrame (#34) 1811 * Added packet_number field to transport:frames_processed (#74) 1813 * Added a way to generically log packet header flags (first 8 bits) 1814 to PacketHeader 1816 * Added additional guidance on which events to log in which 1817 situations (#53) 1819 * Added "simulation:scenario" event to help indicate simulation 1820 details 1822 * Added "packets_acked" event (#107) 1824 * Added "datagram_ids" to the datagram_X and packet_X events to 1825 allow tracking of coalesced QUIC packets (#91) 1827 * Extended connection_state_updated with more fine-grained states 1828 (#49) 1830 B.3. Since draft-marx-qlog-event-definitions-quic-h3-00: 1832 * Event and category names are now all lowercase 1834 * Added many new events and their definitions 1836 * "type" fields have been made more specific (especially important 1837 for PacketType fields, which are now called packet_type instead of 1838 type) 1840 * Events are given an importance indicator (issue #22) 1842 * Event names are more consistent and use past tense (issue #21) 1844 * Triggers have been redefined as properties of the "data" field and 1845 updated for most events (issue #23) 1847 Appendix C. Design Variations 1849 TBD 1851 Appendix D. Acknowledgements 1853 Much of the initial work by Robin Marx was done at Hasselt 1854 University. 1856 Thanks to Marten Seemann, Jana Iyengar, Brian Trammell, Dmitri 1857 Tikhonov, Stephen Petrides, Jari Arkko, Marcus Ihlar, Victor 1858 Vasiliev, Mirja Kuehlewind, Jeremy Laine, Kazu Yamamoto, Christian 1859 Huitema, and Lucas Pardue for their feedback and suggestions. 1861 Authors' Addresses 1863 Robin Marx 1864 KU Leuven 1866 Email: robin.marx@kuleuven.be 1868 Luca Niccolini (editor) 1869 Facebook 1871 Email: lniccolini@fb.com 1873 Marten Seemann (editor) 1874 Protocol Labs 1876 Email: marten@protocol.ai