idnits 2.17.1 draft-marx-qlog-event-definitions-quic-h3-02.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 50 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 (2 November 2020) is 1265 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 2133 == Unused Reference: 'QUIC-TRANSPORT' is defined on line 1976, but no explicit reference was found in the text == Outdated reference: A later version (-03) exists of draft-marx-qlog-main-schema-02 == Outdated reference: A later version (-34) exists of draft-ietf-quic-http-32 == Outdated reference: A later version (-21) exists of draft-ietf-quic-qpack-19 == Outdated reference: A later version (-34) exists of draft-ietf-quic-transport-32 Summary: 2 errors (**), 0 flaws (~~), 6 warnings (==), 2 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 QUIC R. Marx 3 Internet-Draft Hasselt University 4 Intended status: Standards Track 2 November 2020 5 Expires: 6 May 2021 7 QUIC and HTTP/3 event definitions for qlog 8 draft-marx-qlog-event-definitions-quic-h3-02 10 Abstract 12 This document describes concrete qlog event definitions and their 13 metadata for QUIC and HTTP/3-related events. These events can then 14 be embedded in the higher level schema defined in [QLOG-MAIN]. 16 Status of This Memo 18 This Internet-Draft is submitted in full conformance with the 19 provisions of BCP 78 and BCP 79. 21 Internet-Drafts are working documents of the Internet Engineering 22 Task Force (IETF). Note that other groups may also distribute 23 working documents as Internet-Drafts. The list of current Internet- 24 Drafts is at https://datatracker.ietf.org/drafts/current/. 26 Internet-Drafts are draft documents valid for a maximum of six months 27 and may be updated, replaced, or obsoleted by other documents at any 28 time. It is inappropriate to use Internet-Drafts as reference 29 material or to cite them other than as "work in progress." 31 This Internet-Draft will expire on 6 May 2021. 33 Copyright Notice 35 Copyright (c) 2020 IETF Trust and the persons identified as the 36 document authors. All rights reserved. 38 This document is subject to BCP 78 and the IETF Trust's Legal 39 Provisions Relating to IETF Documents (https://trustee.ietf.org/ 40 license-info) in effect on the date of publication of this document. 41 Please review these documents carefully, as they describe your rights 42 and restrictions with respect to this document. Code Components 43 extracted from this document must include Simplified BSD License text 44 as described in Section 4.e of the Trust Legal Provisions and are 45 provided without warranty as described in the Simplified BSD License. 47 Table of Contents 49 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 5 50 1.1. Notational Conventions . . . . . . . . . . . . . . . . . 5 51 2. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . 5 52 2.1. Importance . . . . . . . . . . . . . . . . . . . . . . . 6 53 2.2. Custom fields . . . . . . . . . . . . . . . . . . . . . . 7 54 3. Events not belonging to a single connection . . . . . . . . . 7 55 4. QUIC and HTTP/3 fields . . . . . . . . . . . . . . . . . . . 8 56 4.1. Raw packet and frame information . . . . . . . . . . . . 8 57 5. QUIC event definitions . . . . . . . . . . . . . . . . . . . 10 58 5.1. connectivity . . . . . . . . . . . . . . . . . . . . . . 10 59 5.1.1. server_listening . . . . . . . . . . . . . . . . . . 10 60 5.1.2. connection_started . . . . . . . . . . . . . . . . . 10 61 5.1.3. connection_closed . . . . . . . . . . . . . . . . . . 11 62 5.1.4. connection_id_updated . . . . . . . . . . . . . . . . 12 63 5.1.5. spin_bit_updated . . . . . . . . . . . . . . . . . . 12 64 5.1.6. connection_retried . . . . . . . . . . . . . . . . . 12 65 5.1.7. connection_state_updated . . . . . . . . . . . . . . 13 66 5.1.8. MIGRATION-related events . . . . . . . . . . . . . . 15 67 5.2. security . . . . . . . . . . . . . . . . . . . . . . . . 15 68 5.2.1. key_updated . . . . . . . . . . . . . . . . . . . . . 15 69 5.2.2. key_retired . . . . . . . . . . . . . . . . . . . . . 15 70 5.3. transport . . . . . . . . . . . . . . . . . . . . . . . . 16 71 5.3.1. version_information . . . . . . . . . . . . . . . . . 16 72 5.3.2. alpn_information . . . . . . . . . . . . . . . . . . 17 73 5.3.3. parameters_set . . . . . . . . . . . . . . . . . . . 18 74 5.3.4. parameters_restored . . . . . . . . . . . . . . . . . 20 75 5.3.5. packet_sent . . . . . . . . . . . . . . . . . . . . . 20 76 5.3.6. packet_received . . . . . . . . . . . . . . . . . . . 21 77 5.3.7. packet_dropped . . . . . . . . . . . . . . . . . . . 22 78 5.3.8. packet_buffered . . . . . . . . . . . . . . . . . . . 23 79 5.3.9. packets_acked . . . . . . . . . . . . . . . . . . . . 24 80 5.3.10. datagrams_sent . . . . . . . . . . . . . . . . . . . 24 81 5.3.11. datagrams_received . . . . . . . . . . . . . . . . . 25 82 5.3.12. datagram_dropped . . . . . . . . . . . . . . . . . . 25 83 5.3.13. stream_state_updated . . . . . . . . . . . . . . . . 26 84 5.3.14. frames_processed . . . . . . . . . . . . . . . . . . 27 85 5.3.15. data_moved . . . . . . . . . . . . . . . . . . . . . 28 86 5.4. recovery . . . . . . . . . . . . . . . . . . . . . . . . 30 87 5.4.1. parameters_set . . . . . . . . . . . . . . . . . . . 30 88 5.4.2. metrics_updated . . . . . . . . . . . . . . . . . . . 30 89 5.4.3. congestion_state_updated . . . . . . . . . . . . . . 31 90 5.4.4. loss_timer_updated . . . . . . . . . . . . . . . . . 32 91 5.4.5. packet_lost . . . . . . . . . . . . . . . . . . . . . 33 92 5.4.6. marked_for_retransmit . . . . . . . . . . . . . . . . 34 93 6. HTTP/3 event definitions . . . . . . . . . . . . . . . . . . 34 94 6.1. http . . . . . . . . . . . . . . . . . . . . . . . . . . 34 95 6.1.1. parameters_set . . . . . . . . . . . . . . . . . . . 34 96 6.1.2. parameters_restored . . . . . . . . . . . . . . . . . 35 97 6.1.3. stream_type_set . . . . . . . . . . . . . . . . . . . 36 98 6.1.4. frame_created . . . . . . . . . . . . . . . . . . . . 36 99 6.1.5. frame_parsed . . . . . . . . . . . . . . . . . . . . 37 100 6.1.6. push_resolved . . . . . . . . . . . . . . . . . . . . 37 101 6.2. qpack . . . . . . . . . . . . . . . . . . . . . . . . . . 38 102 6.2.1. state_updated . . . . . . . . . . . . . . . . . . . . 38 103 6.2.2. stream_state_updated . . . . . . . . . . . . . . . . 39 104 6.2.3. dynamic_table_updated . . . . . . . . . . . . . . . . 39 105 6.2.4. headers_encoded . . . . . . . . . . . . . . . . . . . 39 106 6.2.5. headers_decoded . . . . . . . . . . . . . . . . . . . 40 107 6.2.6. instruction_created . . . . . . . . . . . . . . . . . 40 108 6.2.7. instruction_parsed . . . . . . . . . . . . . . . . . 41 109 7. Generic events and Simulation indicators . . . . . . . . . . 41 110 7.1. generic . . . . . . . . . . . . . . . . . . . . . . . . . 41 111 7.1.1. error . . . . . . . . . . . . . . . . . . . . . . . . 42 112 7.1.2. warning . . . . . . . . . . . . . . . . . . . . . . . 42 113 7.1.3. info . . . . . . . . . . . . . . . . . . . . . . . . 42 114 7.1.4. debug . . . . . . . . . . . . . . . . . . . . . . . . 42 115 7.1.5. verbose . . . . . . . . . . . . . . . . . . . . . . . 43 116 7.2. simulation . . . . . . . . . . . . . . . . . . . . . . . 43 117 7.2.1. scenario . . . . . . . . . . . . . . . . . . . . . . 43 118 7.2.2. marker . . . . . . . . . . . . . . . . . . . . . . . 44 119 8. Security Considerations . . . . . . . . . . . . . . . . . . . 44 120 9. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 44 121 10. References . . . . . . . . . . . . . . . . . . . . . . . . . 44 122 10.1. Normative References . . . . . . . . . . . . . . . . . . 44 123 10.2. Informative References . . . . . . . . . . . . . . . . . 45 124 Appendix A. QUIC data field definitions . . . . . . . . . . . . 45 125 A.1. IPAddress . . . . . . . . . . . . . . . . . . . . . . . . 45 126 A.2. PacketType . . . . . . . . . . . . . . . . . . . . . . . 45 127 A.3. PacketNumberSpace . . . . . . . . . . . . . . . . . . . . 45 128 A.4. PacketHeader . . . . . . . . . . . . . . . . . . . . . . 45 129 A.5. Token . . . . . . . . . . . . . . . . . . . . . . . . . . 46 130 A.6. KeyType . . . . . . . . . . . . . . . . . . . . . . . . . 46 131 A.7. QUIC Frames . . . . . . . . . . . . . . . . . . . . . . . 47 132 A.7.1. PaddingFrame . . . . . . . . . . . . . . . . . . . . 47 133 A.7.2. PingFrame . . . . . . . . . . . . . . . . . . . . . . 47 134 A.7.3. AckFrame . . . . . . . . . . . . . . . . . . . . . . 47 135 A.7.4. ResetStreamFrame . . . . . . . . . . . . . . . . . . 48 136 A.7.5. StopSendingFrame . . . . . . . . . . . . . . . . . . 48 137 A.7.6. CryptoFrame . . . . . . . . . . . . . . . . . . . . . 49 138 A.7.7. NewTokenFrame . . . . . . . . . . . . . . . . . . . . 49 139 A.7.8. StreamFrame . . . . . . . . . . . . . . . . . . . . . 49 140 A.7.9. MaxDataFrame . . . . . . . . . . . . . . . . . . . . 50 141 A.7.10. MaxStreamDataFrame . . . . . . . . . . . . . . . . . 50 142 A.7.11. MaxStreamsFrame . . . . . . . . . . . . . . . . . . . 50 143 A.7.12. DataBlockedFrame . . . . . . . . . . . . . . . . . . 50 144 A.7.13. StreamDataBlockedFrame . . . . . . . . . . . . . . . 50 145 A.7.14. StreamsBlockedFrame . . . . . . . . . . . . . . . . . 50 146 A.7.15. NewConnectionIDFrame . . . . . . . . . . . . . . . . 51 147 A.7.16. RetireConnectionIDFrame . . . . . . . . . . . . . . . 51 148 A.7.17. PathChallengeFrame . . . . . . . . . . . . . . . . . 51 149 A.7.18. PathResponseFrame . . . . . . . . . . . . . . . . . . 51 150 A.7.19. ConnectionCloseFrame . . . . . . . . . . . . . . . . 52 151 A.7.20. HandshakeDoneFrame . . . . . . . . . . . . . . . . . 52 152 A.7.21. UnknownFrame . . . . . . . . . . . . . . . . . . . . 52 153 A.7.22. TransportError . . . . . . . . . . . . . . . . . . . 52 154 A.7.23. CryptoError . . . . . . . . . . . . . . . . . . . . . 53 155 Appendix B. HTTP/3 data field definitions . . . . . . . . . . . 53 156 B.1. HTTP/3 Frames . . . . . . . . . . . . . . . . . . . . . . 53 157 B.1.1. DataFrame . . . . . . . . . . . . . . . . . . . . . . 53 158 B.1.2. HeadersFrame . . . . . . . . . . . . . . . . . . . . 54 159 B.1.3. CancelPushFrame . . . . . . . . . . . . . . . . . . . 54 160 B.1.4. SettingsFrame . . . . . . . . . . . . . . . . . . . . 54 161 B.1.5. PushPromiseFrame . . . . . . . . . . . . . . . . . . 54 162 B.1.6. GoAwayFrame . . . . . . . . . . . . . . . . . . . . . 55 163 B.1.7. MaxPushIDFrame . . . . . . . . . . . . . . . . . . . 55 164 B.1.8. DuplicatePushFrame . . . . . . . . . . . . . . . . . 55 165 B.1.9. ReservedFrame . . . . . . . . . . . . . . . . . . . . 55 166 B.1.10. UnknownFrame . . . . . . . . . . . . . . . . . . . . 55 167 B.2. ApplicationError . . . . . . . . . . . . . . . . . . . . 55 168 Appendix C. QPACK DATA type definitions . . . . . . . . . . . . 56 169 C.1. QPACK Instructions . . . . . . . . . . . . . . . . . . . 56 170 C.1.1. SetDynamicTableCapacityInstruction . . . . . . . . . 56 171 C.1.2. InsertWithNameReferenceInstruction . . . . . . . . . 56 172 C.1.3. InsertWithoutNameReferenceInstruction . . . . . . . . 57 173 C.1.4. DuplicateInstruction . . . . . . . . . . . . . . . . 57 174 C.1.5. HeaderAcknowledgementInstruction . . . . . . . . . . 57 175 C.1.6. StreamCancellationInstruction . . . . . . . . . . . . 57 176 C.1.7. InsertCountIncrementInstruction . . . . . . . . . . . 58 177 C.2. QPACK Header compression . . . . . . . . . . . . . . . . 58 178 C.2.1. IndexedHeaderField . . . . . . . . . . . . . . . . . 58 179 C.2.2. LiteralHeaderFieldWithName . . . . . . . . . . . . . 58 180 C.2.3. LiteralHeaderFieldWithoutName . . . . . . . . . . . . 59 181 C.2.4. QPackHeaderBlockPrefix . . . . . . . . . . . . . . . 59 182 Appendix D. Change Log . . . . . . . . . . . . . . . . . . . . . 59 183 D.1. Since draft-01: . . . . . . . . . . . . . . . . . . . . . 59 184 D.2. Since draft-00: . . . . . . . . . . . . . . . . . . . . . 61 185 Appendix E. Design Variations . . . . . . . . . . . . . . . . . 61 186 Appendix F. Acknowledgements . . . . . . . . . . . . . . . . . . 61 187 Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 61 189 1. Introduction 191 This document describes the values of the qlog name ("category" + 192 "event") and "data" fields and their semantics for the QUIC and 193 HTTP/3 protocols. This document is based on draft-29 of the QUIC and 194 HTTP/3 I-Ds QUIC-TRANSPORT [QUIC-HTTP] and draft-16 of the QPACK I-D 195 [QUIC-QPACK]. 197 Feedback and discussion welcome at https://github.com/quiclog/ 198 internet-drafts (https://github.com/quiclog/internet-drafts). 199 Readers are advised to refer to the "editor's draft" at that URL for 200 an up-to-date version of this document. 202 Concrete examples of integrations of this schema in various 203 programming languages can be found at https://github.com/quiclog/ 204 qlog/ (https://github.com/quiclog/qlog/). 206 1.1. Notational Conventions 208 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 209 "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this 210 document are to be interpreted as described in [RFC2119]. 212 The examples and data definitions in ths document are expressed in a 213 custom data definition language, inspired by JSON and TypeScript, and 214 described in [QLOG-MAIN]. 216 2. Overview 218 This document describes the values of the qlog "name" ("category" + 219 "event") and "data" fields and their semantics for the QUIC and 220 HTTP/3 protocols. 222 This document assumes the usage of the encompassing main qlog schema 223 defined in [QLOG-MAIN]. Each subsection below defines a separate 224 category (for example connectivity, transport, http) and each 225 subsubsection is an event type (for example "packet_received"). 227 For each event type, its importance and data definition is laid out, 228 often accompanied by possible values for the optional "trigger" 229 field. For the definition and semantics of "trigger", see the main 230 schema document. 232 Most of the complex datastructures, enums and re-usable definitions 233 are grouped together on the bottom of this document for clarity. 235 2.1. Importance 237 Many of the events defined in this document map directly to concepts 238 seen in the QUIC and HTTP/3 documents, while others act as 239 aggregating events that combine data from several possible protocol 240 behaviours or code paths into one. This is done to reduce the amount 241 of unique event definitions, as reflecting each possible protocol 242 event as a separate qlog entity would cause an explosion of event 243 types. Similarly, we prevent logging duplicate packet data as much 244 as possible. As such, especially packet header value updates are 245 split out into separate events (for example spin_bit_updated, 246 connection_id_updated), as they are expected to change sparingly. 248 Consequently, many events that can be directly inferred from data on 249 the wire (for example flow control limit changes) if the 250 implementation is bug-free, are currently not explicitly defined as 251 stand-alone events. Exceptions can be made for common events that 252 benefit from being easily identifiable or individually logged (for 253 example the "packets_acked" event). This can in turn give rise to 254 separate events logging similar data, where it is not always clear 255 which event should be logged (for example the separate 256 "connection_started" event, whereas the more general 257 "connection_state_updated" event also allows indicating that a 258 connection was started). 260 To aid in this decision making, each event has an "importance 261 indicator" with one of three values, in decreasing order of 262 importance and exptected usage: 264 * Core 266 * Base 268 * Extra 270 The "Core" events are the events that SHOULD be present in all qlog 271 files. These are mostly tied to basic packet and frame parsing and 272 creation, as well as listing basic internal metrics. Tool 273 implementers SHOULD expect and add support for these events, though 274 SHOULD NOT expect all Core events to be present in each qlog trace. 276 The "Base" events add additional debugging options and CAN be present 277 in qlog files. Most of these can be implicitly inferred from data in 278 Core events (if those contain all their properties), but for many it 279 is better to log the events explicitly as well, making it clearer how 280 the implementation behaves. These events are for example tied to 281 passing data around in buffers, to how internal state machines change 282 and help show when decisions are actually made based on received 283 data. Tool implementers SHOULD at least add support for showing the 284 contents of these events, if they do not handle them explicitly. 286 The "Extra" events are considered mostly useful for low-level 287 debugging of the implementation, rather than the protocol. They 288 allow more fine-grained tracking of internal behaviour. As such, 289 they CAN be present in qlog files and tool implementers CAN add 290 support for these, but they are not required to. 292 Note that in some cases, implementers might not want to log for 293 example frame-level details in the "Core" events due to performance 294 or privacy considerations. In this case, they SHOULD use (a subset 295 of) relevant "Base" events instead to ensure usability of the qlog 296 output. As an example, implementations that do not log 297 "packet_received" events and thus also not which (if any) ACK frames 298 the packet contain, SHOULD log "packets_acked" events instead. 300 Finally, for event types who's data (partially) overlap with other 301 event types' definitions, where necessary this document includes 302 guidance on which to use in specific situations. 304 2.2. Custom fields 306 Note that implementers are free to define new category and event 307 types, as well as values for the "trigger" property within the "data" 308 field, or other member fields of the "data" field, as they see fit. 309 They SHOULD NOT however expect non-specialized tools to recognize or 310 visualize this custom data. However, tools SHOULD make an effort to 311 visualize even unknown data if possible in the specific tool's 312 context. 314 3. Events not belonging to a single connection 316 For several types of events, it is sometimes impossible to tie them 317 to a specific conceptual QUIC connection (e.g., a packet_dropped 318 event triggered because the packet has an unknown connection_id in 319 the header). Since qlog events in a trace are typically associated 320 with a single connection, it is unclear how to log these events. 322 Ideally, implementers SHOULD create a separate, individual "endpoint- 323 level" trace file (or group_id value), not associated with a specific 324 connection (for example a "server.qlog" or group_id = "client"), and 325 log all events that do not belong to a single connection to this 326 grouping trace. However, this is not always practical, depending on 327 the implementation. Because the semantics of most of these events 328 are well-defined in the protocols and because they are difficult to 329 mis-interpret as belonging to a connection, implementers MAY choose 330 to log events not belonging to a particular connection in any other 331 trace, even those strongly associated with a single connection. 333 Note that this can make it difficult to match logs from different 334 vantage points with each other. For example, from the client side, 335 it is easy to log connections with version negotiation or retry in 336 the same trace, while on the server they would most likely be logged 337 in separate traces. Servers can take extra efforts (and keep 338 additional state) to keep these events combined in a single trace 339 however (for example by also matching connections on their four-tuple 340 instead of just the connection ID). 342 4. QUIC and HTTP/3 fields 344 This document re-uses all the fields defined in the main qlog schema 345 (e.g., name, category, type, data, group_id, protocol_type, the time- 346 related fields, etc.). 348 The value of the "protocol_type" qlog field MUST be "QUIC_HTTP3". 350 When the qlog "group_id" field is used, it is recommended to use 351 QUIC's Original Destination Connection ID (ODCID, the CID chosen by 352 the client when first contacting the server), as this is the only 353 value that does not change over the course of the connection and can 354 be used to link more advanced QUIC packets (e.g., Retry, Version 355 Negotiation) to a given connection. Similarly, the ODCID should be 356 used as the qlog filename or file identifier, potentially suffixed by 357 the vantagepoint type (For example, abcd1234_server.qlog would 358 contain the server-side trace of the connection with ODCID abcd1234). 360 4.1. Raw packet and frame information 362 While qlog is a more high-level logging format, it also allows the 363 inclusion of most raw wire image information, such as byte lengths 364 and even raw byte values. This can be useful when for example 365 investigating or tuning packetization behaviour or determining 366 encoding/framing overheads. However, these fields are not always 367 necessary and can take up considerable space if logged for each 368 packet or frame. As such, they are grouped in a separate optional 369 field called "raw" of type RawInfo (where applicable). 371 class RawInfo { 372 length?:uint64; // full packet/frame length, including header and AEAD authentication tag lengths (where applicable) 373 payload_length?:uint64; // length of the packet/frame payload, excluding AEAD tag. For many control frames, this will have a value of zero 375 data?:bytes; // full packet/frame contents, including header and AEAD authentication tag (where applicable) 376 } 378 Note: QUIC packets always include an AEAD authentication tag at the 379 end. As this tag is always the same size for a given connection 380 (it depends on the used TLS cipher), we do not have a separate 381 "aead_tag_length" field here. Instead, this field is reflected in 382 "transport:parameters_set" and can be logged only once. 384 Note: There is intentionally no explicit header_length field in 385 RawInfo. QUIC and HTTP/3 use many Variable-Length Integer Encoded 386 (VLIE) values in their packet and frame headers, which are of a 387 dynamic length. Note too that because of this, we cannot 388 deterministally reconstruct the header encoding/length from qlog 389 data, as implementations might not necessarily employ the most 390 efficient VLIE scheme for all values. As such, it is typically 391 easier to log just the total packet/frame length and the payload 392 length. The header length can be calculated by tools as: 394 For QUIC packets: header_length = length - payload_length - 395 aead_tag_length 397 For QUIC and HTTP/3 frames: header_length = length - 398 payload_length 400 For UDP datagrams: header_length = length - payload_length 402 Note: In some cases, the length fields are also explicitly reflected 403 inside of frame/packet headers. For example, the QUIC STREAM 404 frame has a "length" field indicating its payload size. 405 Similarly, all HTTP/3 frames include their explicit payload 406 lengths in the frame header. Finally, the QUIC Long Header has a 407 "length" field which is equal to the payload length plus the 408 packet number length. In these cases, those fields are 409 intentionally preserved in the event definitions. Even though 410 this can lead to duplicate data when the full RawInfo is logged, 411 it allows a more direct mapping of the QUIC and HTTP/3 412 specifications to qlog, making it easier for users to interpret. 414 Note: as described in [QLOG-MAIN], the RawInfo:data field can be 415 truncated for privacy or security purposes (for example excluding 416 payload data). In this case, the length properties should still 417 indicate the non-truncated lengths. 419 5. QUIC event definitions 421 Each subheading in this section is a qlog event category, while each 422 sub-subheading is a qlog event type. Concretely, for the following 423 two items, we have the category "connectivity" and event type 424 "server_listening", resulting in a concatenated qlog "name" field 425 value of "connectivity:server_listening". 427 5.1. connectivity 429 5.1.1. server_listening 431 Importance: Extra 433 Emitted when the server starts accepting connections. 435 Data: 437 { 438 ip_v4?: IPAddress, 439 ip_v6?: IPAddress, 440 port_v4?: uint32, 441 port_v6?: uint32, 443 retry_required?:boolean // the server will always answer client initials with a retry (no 1-RTT connection setups by choice) 444 } 446 Note: some QUIC stacks do not handle sockets directly and are thus 447 unable to log IP and/or port information. 449 5.1.2. connection_started 451 Importance: Base 453 Used for both attempting (client-perspective) and accepting (server- 454 perspective) new connections. Note that this event has overlap with 455 connection_state_updated and this is a separate event mainly because 456 of all the additional data that should be logged. 458 Data: 460 { 461 ip_version?: "v4" | "v6", 462 src_ip?: IPAddress, 463 dst_ip?: IPAddress, 465 protocol?: string, // transport layer protocol (default "QUIC") 466 src_port?: uint32, 467 dst_port?: uint32, 469 src_cid?: bytes, 470 dst_cid?: bytes, 472 } 474 Note: some QUIC stacks do not handle sockets directly and are thus 475 unable to log IP and/or port information. 477 5.1.3. connection_closed 479 Importance: Base 481 Used for logging when a connection was closed, typically when an 482 error or timeout occurred. Note that this event has overlap with 483 connectivity:connection_state_updated, as well as the 484 CONNECTION_CLOSE frame. However, in practice, when analyzing large 485 deployments, it can be useful to have a single event representing a 486 connection_closed event, which also includes an additional reason 487 field to provide additional information. Additionally, it is useful 488 to log closures due to timeouts, which are difficult to reflect using 489 the other options. 491 In QUIC there are two main connection-closing error categories: 492 connection and application errors. They have well-defined error 493 codes and semantics. Next to these however, there can be internal 494 errors that occur that may or may not get mapped to the official 495 error codes in implementation-specific ways. As such, multiple error 496 codes can be set on the same event to reflect this. 498 { 499 owner?:"local"|"remote", // which side closed the connection 501 connection_code?:TransportError | CryptoError | uint32, 502 application_code?:ApplicationError | uint32, 503 internal_code?:uint32, 505 reason?:string 506 } 507 Triggers: * clean * handshake_timeout * idle_timeout * error // this 508 is called the "immediate close" in the QUIC specification * 509 stateless_reset * version_mismatch * application // for example 510 HTTP/3's GOAWAY frame 512 5.1.4. connection_id_updated 514 Importance: Base 516 This event is emitted when either party updates their current 517 Connection ID. As this typically happens only sparingly over the 518 course of a connection, this event allows loggers to be more 519 efficient than logging the observed CID with each packet in the 520 .header field of the "packet_sent" or "packet_received" events. 522 This is viewed from the perspective of the one applying the new id. 523 As such, if we receive a new connection id from our peer, we will see 524 the dst_ fields are set. If we update our own connection id (e.g., 525 NEW_CONNECTION_ID frame), we log the src_ fields. 527 Data: 529 { 530 owner: "local" | "remote", 532 old?:bytes, 533 new?:bytes, 534 } 536 5.1.5. spin_bit_updated 538 Importance: Base 540 To be emitted when the spin bit changes value. It SHOULD NOT be 541 emitted if the spin bit is set without changing its value. 543 Data: 545 { 546 state: boolean 547 } 549 5.1.6. connection_retried 551 TODO 553 5.1.7. connection_state_updated 555 Importance: Base 557 This event is used to track progress through QUIC's complex handshake 558 and connection close procedures. It is intended to provide 559 exhaustive options to log each state individually, but also provides 560 a more basic, simpler set for implementations less interested in 561 tracking each smaller state transition. As such, users should not 562 expect to see -all- these states reflected in all qlogs and 563 implementers should focus on support for the SimpleConnectionState 564 set. 566 Data: ~~~ { old?: ConnectionState | SimpleConnectionState, new: 567 ConnectionState | SimpleConnectionState } 569 enum ConnectionState { attempted, // initial sent/received 570 peer_validated, // peer address validated by: client sent Handshake 571 packet OR client used CONNID chosen by the server. transport-draft- 572 32, section-8.1 handshake_started, early_write, // 1 RTT can be sent, 573 but handshake isn't done yet handshake_complete, // TLS handshake 574 complete: Finished received and sent. tls-draft-32, section-4.1.1 575 handshake_confirmed, // HANDSHAKE_DONE sent/received (connection is 576 now "active", 1RTT can be sent). tls-draft-32, section-4.1.2 closing, 577 draining, // connection_close sent/received closed // draining period 578 done, connection state discarded } 580 enum SimpleConnectionState { attempted, handshake_started, 581 handshake_confirmed, closed } ~~~ 583 These states correspond to the following transitions for both client 584 and server: 586 *Client:* 588 * send initial 590 - state = attempted 592 * get initial 594 - state = validated _(not really "needed" at the client, but 595 somewhat useful to indicate progress nonetheless)_ 597 * get first Handshake packet 599 - state = handshake_started 601 * get Handshake packet containing ServerFinished 603 - state = handshake_complete 605 * send ClientFinished 607 - state = early_write (1RTT can now be sent) 609 * get HANDSHAKE_DONE 611 - state = handshake_confirmed 613 *Server:* 615 * get initial 617 - state = attempted 619 * send initial _(don't think this needs a separate state, since some 620 handshake will always be sent in the same flight as this?)_ 622 * send handshake EE, CERT, CV, ... 624 - state = handshake_started 626 * send ServerFinished 628 - state = early_write (1RTT can now be sent) 630 * get first handshake packet / something using a server-issued CID 631 of min length 633 - state = validated 635 * get handshake packet containing ClientFinished 637 - state = handshake_complete 639 * send HANDSHAKE_DONE 641 - state = handshake_confirmed 643 Note: connection_state_changed with a new state of "attempted" is 644 the same conceptual event as the connection_started event above 645 from the client's perspective. Similarly, a state of "closing" or 646 "draining" corresponds to the connection_closed event. 648 5.1.8. MIGRATION-related events 650 e.g., path_updated 652 TODO: read up on the draft how migration works and whether to best 653 fit this here or in TRANSPORT TODO: integrate 654 https://tools.ietf.org/html/draft-deconinck-quic-multipath-02 656 For now, infer from other connectivity events and path_challenge/ 657 path_response frames 659 5.2. security 661 5.2.1. key_updated 663 Importance: Base 665 Note: secret_updated would be more correct, but in the draft it's 666 called KEY_UPDATE, so stick with that for consistency 668 Data: 670 { 671 key_type:KeyType, 672 old?:bytes, 673 new:bytes, 674 generation?:uint32 // needed for 1RTT key updates 675 } 677 Triggers: 679 * "tls" // (e.g., initial, handshake and 0-RTT keys are generated by 680 TLS) 682 * "remote_update" 684 * "local_update" 686 5.2.2. key_retired 688 Importance: Base 690 Data: 692 { 693 key_type:KeyType, 694 key?:bytes, 695 generation?:uint32 // needed for 1RTT key updates 696 } 698 Triggers: 700 * "tls" // (e.g., initial, handshake and 0-RTT keys are dropped 701 implicitly) 703 * "remote_update" 705 * "local_update" 707 5.3. transport 709 5.3.1. version_information 711 Importance: Core 713 QUIC endpoints each have their own list of of QUIC versions they 714 support. The client uses the most likely version in their first 715 initial. If the server does support that version, it replies with a 716 version_negotiation packet, containing supported versions. From 717 this, the client selects a version. This event aggregates all this 718 information in a single event type. It also allows logging of 719 supported versions at an endpoint without actual version negotiation 720 needing to happen. 722 Data: 724 { 725 server_versions?:Array, 726 client_versions?:Array, 727 chosen_version?:bytes 728 } 730 Intended use: 732 * When sending an initial, the client logs this event with 733 client_versions and chosen_version set 735 * Upon receiving a client initial with a supported version, the 736 server logs this event with server_versions and chosen_version set 738 * Upon receiving a client initial with an unsupported version, the 739 server logs this event with server_versions set and 740 client_versions to the single-element array containing the 741 client's attempted version. The absence of chosen_version implies 742 no overlap was found. 744 * Upon receiving a version negotiation packet from the server, the 745 client logs this event with client_versions set and 746 server_versions to the versions in the version negotiation packet 747 and chosen_version to the version it will use for the next initial 748 packet 750 5.3.2. alpn_information 752 Importance: Core 754 QUIC implementations each have their own list of application level 755 protocols and versions thereof they support. The client includes a 756 list of their supported options in its first initial as part of the 757 TLS Application Layer Protocol Negotiation (alpn) extension. If 758 there are common option(s), the server chooses the most optimal one 759 and communicates this back to the client. If not, the connection is 760 closed. 762 Data: 764 { 765 server_alpns?:Array, 766 client_alpns?:Array, 767 chosen_alpn?:string 768 } 770 Intended use: 772 * When sending an initial, the client logs this event with 773 client_alpns set 775 * When receiving an initial with a supported alpn, the server logs 776 this event with server_alpns set, client_alpns equalling the 777 client-provided list, and chosen_alpn to the value it will send 778 back to the client. 780 * When receiving an initial with an alpn, the client logs this event 781 with chosen_alpn to the received value. 783 * Alternatively, a client can choose to not log the first event, but 784 wait for the receipt of the server initial to log this event with 785 both client_alpns and chosen_alpn set. 787 5.3.3. parameters_set 789 Importance: Core 791 This event groups settings from several different sources (transport 792 parameters, TLS ciphers, etc.) into a single event. This is done to 793 minimize the amount of events and to decouple conceptual setting 794 impacts from their underlying mechanism for easier high-level 795 reasoning. 797 All these settings are typically set once and never change. However, 798 they are typically set at different times during the connection, so 799 there will typically be several instances of this event with 800 different fields set. 802 Note that some settings have two variations (one set locally, one 803 requested by the remote peer). This is reflected in the "owner" 804 field. As such, this field MUST be correct for all settings included 805 a single event instance. If you need to log settings from two sides, 806 you MUST emit two separate event instances. 808 In the case of connection resumption and 0-RTT, some of the server's 809 parameters are stored up-front at the client and used for the initial 810 connection startup. They are later updated with the server's reply. 811 In these cases, utilize the separate "parameters_restored" event to 812 indicate the initial values, and this event to indicate the updated 813 values, as normal. 815 Data: 817 { 818 owner?:"local" | "remote", 820 resumption_allowed?:boolean, // valid session ticket was received 821 early_data_enabled?:boolean, // early data extension was enabled on the TLS layer 822 tls_cipher?:string, // (e.g., "AES_128_GCM_SHA256") 823 aead_tag_length?:uint8, // depends on the TLS cipher, but it's easier to be explicit. Default value is 16 825 // transport parameters from the TLS layer: 826 original_destination_connection_id?:bytes, 827 initial_source_connection_id?:bytes, 828 retry_source_connection_id?:bytes, 829 stateless_reset_token?:Token, 830 disable_active_migration?:boolean, 832 max_idle_timeout?:uint64, 833 max_udp_payload_size?:uint32, 834 ack_delay_exponent?:uint16, 835 max_ack_delay?:uint16, 836 active_connection_id_limit?:uint32, 838 initial_max_data?:uint64, 839 initial_max_stream_data_bidi_local?:uint64, 840 initial_max_stream_data_bidi_remote?:uint64, 841 initial_max_stream_data_uni?:uint64, 842 initial_max_streams_bidi?:uint64, 843 initial_max_streams_uni?:uint64, 845 preferred_address?:PreferredAddress 846 } 848 interface PreferredAddress { 849 ip_v4:IPAddress, 850 ip_v6:IPAddress, 852 port_v4:uint16, 853 port_v6:uint16, 855 connection_id:bytes, 856 stateless_reset_token:Token 857 } 859 Additionally, this event can contain any number of unspecified 860 fields. This is to reflect setting of for example unknown (greased) 861 transport parameters or employed (proprietary) extensions. 863 5.3.4. parameters_restored 865 Importance: Base 867 When using QUIC 0-RTT, clients are expected to remember and restore 868 the server's transport parameters from the previous connection. This 869 event is used to indicate which parameters were restored and to which 870 values when utilizing 0-RTT. Note that not all transport parameters 871 should be restored (many are even prohibited from being re-utilized). 872 The ones listed here are the ones expected to be useful for correct 873 0-RTT usage. 875 Data: 877 { 878 disable_active_migration?:boolean, 880 max_idle_timeout?:uint64, 881 max_udp_payload_size?:uint32, 882 active_connection_id_limit?:uint32, 884 initial_max_data?:uint64, 885 initial_max_stream_data_bidi_local?:uint64, 886 initial_max_stream_data_bidi_remote?:uint64, 887 initial_max_stream_data_uni?:uint64, 888 initial_max_streams_bidi?:uint64, 889 initial_max_streams_uni?:uint64, 890 } 892 Note that, like parameters_set above, this event can contain any 893 number of unspecified fields to allow for additional/custom 894 parameters. 896 5.3.5. packet_sent 898 Importance: Core 900 Data: 902 { 903 header:PacketHeader, 905 frames?:Array, // see appendix for the definitions 907 is_coalesced?:boolean, // default value is false 909 retry_token?:Token, // only if header.packet_type === retry 911 stateless_reset_token?:bytes, // only if header.packet_type === stateless_reset. Is always 128 bits in length. 913 supported_versions:Array, // only if header.packet_type === version_negotiation 915 raw?:RawInfo, 916 datagram_id?:uint32 917 } 919 Note: We do not explicitly log the encryption_level or 920 packet_number_space: the header.packet_type specifies this by 921 inference (assuming correct implementation) 923 Triggers: 925 * "retransmit_reordered" // draft-23 5.1.1 927 * "retransmit_timeout" // draft-23 5.1.2 929 * "pto_probe" // draft-23 5.3.1 931 * "retransmit_crypto" // draft-19 6.2 933 * "cc_bandwidth_probe" // needed for some CCs to figure out 934 bandwidth allocations when there are no normal sends 936 Note: for more details on "datagram_id", see Section 5.3.10. It is 937 only needed when keeping track of packet coalescing. 939 5.3.6. packet_received 941 Importance: Core 943 Data: 945 { 946 header:PacketHeader, 948 frames?:Array, // see appendix for the definitions 950 is_coalesced?:boolean, 952 retry_token?:Token, // only if header.packet_type === retry 954 stateless_reset_token?:bytes, // only if header.packet_type === stateless_reset. Is always 128 bits in length. 956 supported_versions:Array, // only if header.packet_type === version_negotiation 958 raw?:RawInfo, 959 datagram_id?:uint32 960 } 962 Note: We do not explicitly log the encryption_level or 963 packet_number_space: the header.packet_type specifies this by 964 inference (assuming correct implementation) 966 Triggers: 968 * "keys_available" // if packet was buffered because it couldn't be 969 decrypted before 971 Note: for more details on "datagram_id", see Section 5.3.10. It is 972 only needed when keeping track of packet coalescing. 974 5.3.7. packet_dropped 976 Importance: Base 978 This event indicates a QUIC-level packet was dropped after partial or 979 no parsing. 981 Data: 983 { 984 header?:PacketHeader, // primarily packet_type should be filled here, as other fields might not be parseable 986 raw?:RawInfo, 987 datagram_id?:uint32 988 } 990 For this event, the "trigger" field SHOULD be set (for example to one 991 of the values below), as this helps tremendously in debugging. 993 Triggers: 995 * "key_unavailable" 997 * "unknown_connection_id" 999 * "header_parse_error" 1001 * "payload_decrypt_error" 1003 * "protocol_violation" 1005 * "dos_prevention" 1007 * "unsupported_version" 1009 * "unexpected_packet" 1011 * "unexpected_source_connection_id" 1013 * "unexpected_version" 1015 * "duplicate" 1017 * "invalid_initial" 1019 Note: sometimes packets are dropped before they can be associated 1020 with a particular connection (e.g., in case of 1021 "unsupported_version"). This situation is discussed more in 1022 Section 3. 1024 Note: for more details on "datagram_id", see Section 5.3.10. It is 1025 only needed when keeping track of packet coalescing. 1027 5.3.8. packet_buffered 1029 Importance: Base 1031 This event is emitted when a packet is buffered because it cannot be 1032 processed yet. Typically, this is because the packet cannot be 1033 parsed yet, and thus we only log the full packet contents when it was 1034 parsed in a packet_received event. 1036 Data: 1038 { 1039 header?:PacketHeader, // primarily packet_type and possible packet_number should be filled here, as other elements might not be available yet 1041 raw?:RawInfo, 1042 datagram_id?:uint32 1043 } 1045 Note: for more details on "datagram_id", see Section 5.3.10. It is 1046 only needed when keeping track of packet coalescing. 1048 Triggers: 1050 * "backpressure" // indicates the parser cannot keep up, temporarily 1051 buffers packet for later processing 1053 * "keys_unavailable" // if packet cannot be decrypted because the 1054 proper keys were not yet available 1056 5.3.9. packets_acked 1058 Importance: Extra 1060 This event is emitted when a (group of) sent packet(s) is 1061 acknowledged by the remote peer _for the first time_. This 1062 information could also be deduced from the contents of received ACK 1063 frames. However, ACK frames require additional processing logic to 1064 determine when a given packet is acknowledged for the first time, as 1065 QUIC uses ACK ranges which can include repeated ACKs. Additionally, 1066 this event can be used by implementations that do not log frame 1067 contents. 1069 Data: ~~~ { packet_number_space?:PacketNumberSpace, 1071 packet_numbers?:Array } ~~~ 1073 Note: if packet_number_space is omitted, it assumes the default value 1074 of PacketNumberSpace.application_data, as this is by far the most 1075 prevalent packet number space a typical QUIC connection will use. 1077 5.3.10. datagrams_sent 1079 Importance: Extra 1081 When we pass one or more UDP-level datagrams to the socket. This is 1082 useful for determining how QUIC packet buffers are drained to the OS. 1084 Data: 1086 { 1087 count?:uint16, // to support passing multiple at once 1088 raw?:Array, // RawInfo:length field indicates total length of the datagrams, including UDP header length 1090 datagram_ids?:Array 1091 } 1093 Note: QUIC itself does not have a concept of a "datagram_id". This 1094 field is a purely qlog-specific construct to allow tracking how 1095 multiple QUIC packets are coalesced inside of a single UDP datagram, 1096 which is an important optimization during the QUIC handshake. For 1097 this, implementations assign a (per-endpoint) unique ID to each 1098 datagram and keep track of which packets were coalesced into the same 1099 datagram. As packet coalescing typically only happens during the 1100 handshake (as it requires at least one long header packet), this can 1101 be done without much overhead. 1103 5.3.11. datagrams_received 1105 Importance: Extra 1107 When we receive one or more UDP-level datagrams from the socket. 1108 This is useful for determining how datagrams are passed to the user 1109 space stack from the OS. 1111 Data: 1113 { 1114 count?:uint16, // to support passing multiple at once 1115 raw?:Array, // RawInfo:length field indicates total length of the datagrams, including UDP header length 1117 datagram_ids?:Array 1118 } 1120 Note: for more details on "datagram_ids", see Section 5.3.10. 1122 5.3.12. datagram_dropped 1124 Importance: Extra 1126 When we drop a UDP-level datagram. This is typically if it does not 1127 contain a valid QUIC packet (in that case, use packet_dropped 1128 instead). 1130 Data: 1132 { 1133 raw?:RawInfo 1134 } 1136 5.3.13. stream_state_updated 1138 Importance: Base 1140 This event is emitted whenever the internal state of a QUIC stream is 1141 updated, as described in QUIC transport draft-23 section 3. Most of 1142 this can be inferred from several types of frames going over the 1143 wire, but it's much easier to have explicit signals for these state 1144 changes. 1146 Data: 1148 { 1149 stream_id:uint64, 1150 stream_type?:"unidirectional"|"bidirectional", // mainly useful when opening the stream 1152 old?:StreamState, 1153 new:StreamState, 1155 stream_side?:"sending"|"receiving" 1156 } 1158 enum StreamState { 1159 // bidirectional stream states, draft-23 3.4. 1160 idle, 1161 open, 1162 half_closed_local, 1163 half_closed_remote, 1164 closed, 1166 // sending-side stream states, draft-23 3.1. 1167 ready, 1168 send, 1169 data_sent, 1170 reset_sent, 1171 reset_received, 1173 // receive-side stream states, draft-23 3.2. 1174 receive, 1175 size_known, 1176 data_read, 1177 reset_read, 1179 // both-side states 1180 data_received, 1182 // qlog-defined 1183 destroyed // memory actually freed 1184 } 1186 Note: QUIC implementations SHOULD mainly log the simplified 1187 bidirectional (HTTP/2-alike) stream states (e.g., idle, open, closed) 1188 instead of the more finegrained stream states (e.g., data_sent, 1189 reset_received). These latter ones are mainly for more in-depth 1190 debugging. Tools SHOULD be able to deal with both types equally. 1192 5.3.14. frames_processed 1194 Importance: Extra 1195 This event's main goal is to prevent a large proliferation of 1196 specific purpose events (e.g., packets_acknowledged, 1197 flow_control_updated, stream_data_received). We want to give 1198 implementations the opportunity to (selectively) log this type of 1199 signal without having to log packet-level details (e.g., in 1200 packet_received). Since for almost all cases, the effects of 1201 applying a frame to the internal state of an implementation can be 1202 inferred from that frame's contents, we aggregate these events in 1203 this single "frames_processed" event. 1205 Note: This event can be used to signal internal state change not 1206 resulting directly from the actual "parsing" of a frame (e.g., the 1207 frame could have been parsed, data put into a buffer, then later 1208 processed, then logged with this event). 1210 Note: Implementations logging "packet_received" and which include all 1211 of the packet's constituent frames therein, are not expected to emit 1212 this "frames_processed" event (contrary to the HTTP-level 1213 "frames_parsed" event). Rather, implementations not wishing to log 1214 full packets or that wish to explicitly convey extra information 1215 about when frames are processed (if not directly tied to their 1216 reception) can use this event. 1218 Note: for some events, this approach will lose some information 1219 (e.g., for which encryption level are packets being acknowledged?). 1220 If this information is important, please use the packet_received 1221 event instead. 1223 Note: in some implementations, it can be difficult to log frames 1224 directly, even when using packet_sent and packet_received events. 1225 For these cases, this event also contains the direct packet_number 1226 field, which can be used to more explicitly link this event to the 1227 packet_sent/received events. 1229 Data: 1231 { 1232 frames:Array, // see appendix for the definitions 1234 packet_number?:uint64 1235 } 1237 5.3.15. data_moved 1239 Importance: Base 1240 Used to indicate when data moves between the different layers (for 1241 example passing from HTTP/3 to QUIC stream buffers and vice versa) or 1242 between HTTP/3 and the actual user application on top (for example a 1243 browser engine). This helps make clear the flow of data, how long 1244 data remains in various buffers and the overheads introduced by 1245 individual layers. 1247 For example, this helps make clear whether received data on a QUIC 1248 stream is moved to the HTTP layer immediately (for example per 1249 received packet) or in larger batches (for example, all QUIC packets 1250 are processed first and afterwards the HTTP layer reads from the 1251 streams with newly available data). This in turn can help identify 1252 bottlenecks or scheduling problems. 1254 Data: 1256 { 1257 stream_id?:uint64, 1258 offset?:uint64, 1259 length?:uint64, // byte length of the moved data 1261 from?:string, // typically: use either of "application","http","transport" 1262 to?:string, // typically: use either of "application","http","transport" 1264 data?:bytes // raw bytes that were transferred 1265 } 1267 Note: we do not for example use a "direction" field (with values "up" 1268 and "down") to specify the data flow. This is because in some 1269 optimized implementations, data might skip some individual layers. 1270 Additionally, using explicit "from" and "to" fields is more flexible 1271 and allows the definition of other conceptual "layers" (for example 1272 to indicate data from QUIC CRYPTO frames being passed to a TLS 1273 library ("security") or from HTTP/3 to QPACK ("qpack")). 1275 Note: this event type is part of the "transport" category, but really 1276 spans all the different layers. This means we have a few leaky 1277 abstractions here (for example, the stream_id or stream offset might 1278 not be available at some logging points, or the raw data might not be 1279 in a byte-array form). In these situations, implementers can decide 1280 to define new, in-context fields to aid in manual debugging. 1282 5.4. recovery 1284 Note: most of the events in this category are kept generic to support 1285 different recovery approaches and various congestion control 1286 algorithms. Tool creators SHOULD make an effort to support and 1287 visualize even unknown data in these events (e.g., plot unknown 1288 congestion states by name on a timeline visualization). 1290 5.4.1. parameters_set 1292 Importance: Base 1294 This event groups initial parameters from both loss detection and 1295 congestion control into a single event. All these settings are 1296 typically set once and never change. Implementation that do, for 1297 some reason, change these parameters during execution, MAY emit the 1298 parameters_set event twice. 1300 Data: 1302 { 1303 // Loss detection, see recovery draft-23, Appendix A.2 1304 reordering_threshold?:uint16, // in amount of packets 1305 time_threshold?:float, // as RTT multiplier 1306 timer_granularity?:uint16, // in ms 1307 initial_rtt?:float, // in ms 1309 // congestion control, Appendix B.1. 1310 max_datagram_size?:uint32, // in bytes // Note: this could be updated after pmtud 1311 initial_congestion_window?:uint64, // in bytes 1312 minimum_congestion_window?:uint32, // in bytes // Note: this could change when max_datagram_size changes 1313 loss_reduction_factor?:float, 1314 persistent_congestion_threshold?:uint16 // as PTO multiplier 1315 } 1317 Additionally, this event can contain any number of unspecified fields 1318 to support different recovery approaches. 1320 5.4.2. metrics_updated 1322 Importance: Core 1323 This event is emitted when one or more of the observable recovery 1324 metrics changes value. This event SHOULD group all possible metric 1325 updates that happen at or around the same time in a single event 1326 (e.g., if min_rtt and smoothed_rtt change at the same time, they 1327 should be bundled in a single metrics_updated entry, rather than 1328 split out into two). Consequently, a metrics_updated event is only 1329 guaranteed to contain at least one of the listed metrics. 1331 Data: 1333 { 1334 // Loss detection, see recovery draft-23, Appendix A.3 1335 min_rtt?:float, // in ms or us, depending on the overarching qlog's configuration 1336 smoothed_rtt?:float, // in ms or us, depending on the overarching qlog's configuration 1337 latest_rtt?:float, // in ms or us, depending on the overarching qlog's configuration 1338 rtt_variance?:float, // in ms or us, depending on the overarching qlog's configuration 1340 pto_count?:uint16, 1342 // Congestion control, Appendix B.2. 1343 congestion_window?:uint64, // in bytes 1344 bytes_in_flight?:uint64, 1346 ssthresh?:uint64, // in bytes 1348 // qlog defined 1349 packets_in_flight?:uint64, // sum of all packet number spaces 1351 pacing_rate?:uint64 // in bps 1352 } 1354 Note: to make logging easier, implementations MAY log values even if 1355 they are the same as previously reported values (e.g., two subsequent 1356 METRIC_UPDATE entries can both report the exact same value for 1357 min_rtt). However, applications SHOULD try to log only actual 1358 updates to values. 1360 Additionally, this event can contain any number of unspecified fields 1361 to support different recovery approaches. 1363 5.4.3. congestion_state_updated 1365 Importance: Base 1366 This event signifies when the congestion controller enters a 1367 significant new state and changes its behaviour. This event's 1368 definition is kept generic to support different Congestion Control 1369 algorithms. For example, for the algorithm defined in the Recovery 1370 draft ("enhanced" New Reno), the following states are defined: 1372 * slow_start 1374 * congestion_avoidance 1376 * application_limited 1378 * recovery 1380 Data: 1382 { 1383 old?:string, 1384 new:string 1385 } 1387 The "trigger" field SHOULD be logged if there are multiple ways in 1388 which a state change can occur but MAY be omitted if a given state 1389 can only be due to a single event occuring (e.g., slow start is 1390 exited only when ssthresh is exceeded). 1392 Some triggers for ("enhanced" New Reno): 1394 * persistent_congestion 1396 * ECN 1398 5.4.4. loss_timer_updated 1400 Importance: Extra 1402 This event is emitted when a recovery loss timer changes state. The 1403 three main event types are: 1405 * set: the timer is set with a delta timeout for when it will 1406 trigger next 1408 * expired: when the timer effectively expires after the delta 1409 timeout 1411 * cancelled: when a timer is cancelled (e.g., all outstanding 1412 packets are acknowledged, start idle period) 1414 Note: to indicate an active timer's timeout update, a new "set" event 1415 is used. 1417 Data: 1419 { 1420 timer_type?:"ack"|"pto", // called "mode" in draft-23 A.9. 1421 packet_number_space?: PacketNumberSpace, 1423 event_type:"set"|"expired"|"cancelled", 1425 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 1426 } 1428 TODO: how about CC algo's that use multiple timers? How generic do 1429 these events need to be? Just support QUIC-style recovery from the 1430 spec or broader? 1432 TODO: read up on the loss detection logic in draft-27 onward and see 1433 if this suffices 1435 5.4.5. packet_lost 1437 Importance: Core 1439 This event is emitted when a packet is deemed lost by loss detection. 1441 Data: 1443 { 1444 header?:PacketHeader, // should include at least the packet_type and packet_number 1446 // not all implementations will keep track of full packets, so these are optional 1447 frames?:Array // see appendix for the definitions 1448 } 1450 For this event, the "trigger" field SHOULD be set (for example to one 1451 of the values below), as this helps tremendously in debugging. 1453 Triggers: 1455 * "reordering_threshold", 1457 * "time_threshold" 1459 * "pto_expired" // draft-23 section 5.3.1, MAY 1461 5.4.6. marked_for_retransmit 1463 Importance: Extra 1465 This event indicates which data was marked for retransmit upon 1466 detecing a packet loss (see packet_lost). Similar to our reasoning 1467 for the "frames_processed" event, in order to keep the amount of 1468 different events low, we group this signal for all types of 1469 retransmittable data in a single event based on existing QUIC frame 1470 definitions. 1472 Implementations retransmitting full packets or frames directly can 1473 just log the consituent frames of the lost packet here (or do away 1474 with this event and use the contents of the packet_lost event 1475 instead). Conversely, implementations that have more complex logic 1476 (e.g., marking ranges in a stream's data buffer as in-flight), or 1477 that do not track sent frames in full (e.g., only stream offset + 1478 length), can translate their internal behaviour into the appropriate 1479 frame instance here even if that frame was never or will never be put 1480 on the wire. 1482 Note: much of this data can be inferred if implementations log 1483 packet_sent events (e.g., looking at overlapping stream data offsets 1484 and length, one can determine when data was retransmitted). 1486 Data: 1488 { 1489 frames:Array, // see appendix for the definitions 1490 } 1492 6. HTTP/3 event definitions 1494 6.1. http 1496 Note: like all category values, the "http" category is written in 1497 lowercase. 1499 6.1.1. parameters_set 1501 Importance: Base 1503 This event contains HTTP/3 and QPACK-level settings, mostly those 1504 received from the HTTP/3 SETTINGS frame. All these parameters are 1505 typically set once and never change. However, they are typically set 1506 at different times during the connection, so there can be several 1507 instances of this event with different fields set. 1509 Note that some settings have two variations (one set locally, one 1510 requested by the remote peer). This is reflected in the "owner" 1511 field. As such, this field MUST be correct for all settings included 1512 a single event instance. If you need to log settings from two sides, 1513 you MUST emit two separate event instances. 1515 Data: 1517 { 1518 owner?:"local" | "remote", 1520 max_header_list_size?:uint64, // from SETTINGS_MAX_HEADER_LIST_SIZE 1521 max_table_capacity?:uint64, // from SETTINGS_QPACK_MAX_TABLE_CAPACITY 1522 blocked_streams_count?:uint64, // from SETTINGS_QPACK_BLOCKED_STREAMS 1524 // qlog-defined 1525 waits_for_settings?:boolean // indicates whether this implementation waits for a SETTINGS frame before processing requests 1526 } 1528 Note: enabling server push is not explicitly done in HTTP/3 by use of 1529 a setting or parameter. Instead, it is communicated by use of the 1530 MAX_PUSH_ID frame, which should be logged using the frame_created and 1531 frame_parsed events below. 1533 Additionally, this event can contain any number of unspecified 1534 fields. This is to reflect setting of for example unknown (greased) 1535 settings or parameters of (proprietary) extensions. 1537 6.1.2. parameters_restored 1539 Importance: Base 1541 When using QUIC 0-RTT, clients are expected to remember and reuse the 1542 server's SETTINGs from the previous connection. This event is used 1543 to indicate which settings were restored and to which values when 1544 utilizing 0-RTT. 1546 Data: 1548 { 1549 max_header_list_size?:uint64, 1550 max_table_capacity?:uint64, 1551 blocked_streams_count?:uint64 1552 } 1554 Note that, like for parameters_set above, this event can contain any 1555 number of unspecified fields to allow for additional and custom 1556 settings. 1558 6.1.3. stream_type_set 1560 Importance: Base 1562 Emitted when a stream's type becomes known. This is typically when a 1563 stream is opened and the stream's type indicator is sent or received. 1565 Note: most of this information can also be inferred by looking at a 1566 stream's id, since id's are strictly partitioned at the QUIC level. 1567 Even so, this event has a "Base" importance because it helps a lot in 1568 debugging to have this information clearly spelled out. 1570 Data: 1572 { 1573 stream_id:uint64, 1575 owner?:"local"|"remote" 1577 old?:StreamType, 1578 new:StreamType, 1580 associated_push_id?:uint64 // only when new == "push" 1581 } 1583 enum StreamType { 1584 data, // bidirectional request-response streams 1585 control, 1586 push, 1587 reserved, 1588 qpack_encode, 1589 qpack_decode 1590 } 1592 6.1.4. frame_created 1594 Importance: Core 1596 HTTP equivalent to the packet_sent event. This event is emitted when 1597 the HTTP/3 framing actually happens. Note: this is not necessarily 1598 the same as when the HTTP/3 data is passed on to the QUIC layer. For 1599 that, see the "data_moved" event. 1601 Data: 1603 { 1604 stream_id:uint64, 1605 length?:uint64, // payload byte length of the frame 1606 frame:HTTP3Frame, // see appendix for the definitions, 1608 raw?:RawInfo 1609 } 1611 Note: in HTTP/3, DATA frames can have arbitrarily large lengths to 1612 reduce frame header overhead. As such, DATA frames can span many 1613 QUIC packets and can be created in a streaming fashion. In this 1614 case, the frame_created event is emitted once for the frame header, 1615 and further streamed data is indicated using the data_moved event. 1617 6.1.5. frame_parsed 1619 Importance: Core 1621 HTTP equivalent to the packet_received event. This event is emitted 1622 when we actually parse the HTTP/3 frame. Note: this is not 1623 necessarily the same as when the HTTP/3 data is actually received on 1624 the QUIC layer. For that, see the "data_moved" event. 1626 Data: 1628 { 1629 stream_id:uint64, 1630 length?:uint64, // payload byte length of the frame 1631 frame:HTTP3Frame, // see appendix for the definitions, 1633 raw?:RawInfo 1634 } 1636 Note: in HTTP/3, DATA frames can have arbitrarily large lengths to 1637 reduce frame header overhead. As such, DATA frames can span many 1638 QUIC packets and can be processed in a streaming fashion. In this 1639 case, the frame_parsed event is emitted once for the frame header, 1640 and further streamed data is indicated using the data_moved event. 1642 6.1.6. push_resolved 1644 Importance: Extra 1646 This event is emitted when a pushed resource is successfully claimed 1647 (used) or, conversely, abandoned (rejected) by the application on top 1648 of HTTP/3 (e.g., the web browser). This event is added to help debug 1649 problems with unexpected PUSH behaviour, which is commonplace with 1650 HTTP/2. 1652 { 1653 push_id?:uint64, 1654 stream_id?:uint64, // in case this is logged from a place that does not have access to the push_id 1656 decision:"claimed"|"abandoned" 1657 } 1659 6.2. qpack 1661 Note: like all category values, the "qpack" category is written in 1662 lowercase. 1664 The QPACK events mainly serve as an aid to debug low-level QPACK 1665 issues. The higher-level, plaintext header values SHOULD (also) be 1666 logged in the http.frame_created and http.frame_parsed event data 1667 (instead). 1669 Note: qpack does not have its own parameters_set event. This was 1670 merged with http.parameters_set for brevity, since qpack is a 1671 required extension for HTTP/3 anyway. Other HTTP/3 extensions MAY 1672 also log their SETTINGS fields in http.parameters_set or MAY define 1673 their own events. 1675 6.2.1. state_updated 1677 Importance: Base 1679 This event is emitted when one or more of the internal QPACK 1680 variables changes value. Note that some variables have two 1681 variations (one set locally, one requested by the remote peer). This 1682 is reflected in the "owner" field. As such, this field MUST be 1683 correct for all variables included a single event instance. If you 1684 need to log settings from two sides, you MUST emit two separate event 1685 instances. 1687 Data: 1689 { 1690 owner:"local" | "remote", 1692 dynamic_table_capacity?:uint64, 1693 dynamic_table_size?:uint64, // effective current size, sum of all the entries 1695 known_received_count?:uint64, 1696 current_insert_count?:uint64 1697 } 1698 6.2.2. stream_state_updated 1700 Importance: Core 1702 This event is emitted when a stream becomes blocked or unblocked by 1703 header decoding requests or QPACK instructions. 1705 Note: This event is of "Core" importance, as it might have a large 1706 impact on HTTP/3's observed performance. 1708 Data: 1710 { 1711 stream_id:uint64, 1713 state:"blocked"|"unblocked" // streams are assumed to start "unblocked" until they become "blocked" 1714 } 1716 6.2.3. dynamic_table_updated 1718 Importance: Extra 1720 This event is emitted when one or more entries are inserted or 1721 evicted from QPACK's dynamic table. 1723 Data: 1725 { 1726 owner:"local" | "remote", // local = the encoder's dynamic table. remote = the decoder's dynamic table 1728 update_type:"inserted"|"evicted", 1730 entries:Array 1731 } 1733 class DynamicTableEntry { 1734 index:uint64; 1735 name?:string | bytes; 1736 value?:string | bytes; 1737 } 1739 6.2.4. headers_encoded 1741 Importance: Base 1743 This event is emitted when an uncompressed header block is encoded 1744 successfully. 1746 Note: this event has overlap with http.frame_created for the 1747 HeadersFrame type. When outputting both events, implementers MAY 1748 omit the "headers" field in this event. 1750 Data: 1752 { 1753 stream_id?:uint64, 1755 headers?:Array, 1757 block_prefix:QPackHeaderBlockPrefix, 1758 header_block:Array, 1760 length?:uint32, 1761 raw?:bytes 1762 } 1764 6.2.5. headers_decoded 1766 Importance: Base 1768 This event is emitted when a compressed header block is decoded 1769 successfully. 1771 Note: this event has overlap with http.frame_parsed for the 1772 HeadersFrame type. When outputting both events, implementers MAY 1773 omit the "headers" field in this event. 1775 Data: 1777 { 1778 stream_id?:uint64, 1780 headers?:Array, 1782 block_prefix:QPackHeaderBlockPrefix, 1783 header_block:Array, 1785 length?:uint32, 1786 raw?:bytes 1787 } 1789 6.2.6. instruction_created 1791 Importance: Base 1792 This event is emitted when a QPACK instruction (both decoder and 1793 encoder) is created and added to the encoder/decoder stream. 1795 Data: 1797 { 1798 instruction:QPackInstruction // see appendix for the definitions, 1800 length?:uint32, 1801 raw?:bytes 1802 } 1804 Note: encoder/decoder semantics and stream_id's are implicit in 1805 either the instruction types or can be logged via other events (e.g., 1806 http.stream_type_set) 1808 6.2.7. instruction_parsed 1810 Importance: Base 1812 This event is emitted when a QPACK instruction (both decoder and 1813 encoder) is read from the encoder/decoder stream. 1815 Data: 1817 { 1818 instruction:QPackInstruction // see appendix for the definitions, 1820 length?:uint32, 1821 raw?:bytes 1822 } 1824 Note: encoder/decoder semantics and stream_id's are implicit in 1825 either the instruction types or can be logged via other events (e.g., 1826 http.stream_type_set) 1828 7. Generic events and Simulation indicators 1830 7.1. generic 1832 The main goal of the events in this category is to allow 1833 implementations to fully replace their existing text-based logging by 1834 qlog. This is done by providing events to log generic strings for 1835 typical well-known logging levels (error, warning, info, debug, 1836 verbose). 1838 7.1.1. error 1840 Importance: Core 1842 Used to log details of an internal error. For errors that 1843 effectively lead to the closure of a QUIC connection, it is 1844 recommended to use transport:connection_closed instead. 1846 Data: 1848 { 1849 code?:uint32, 1850 message?:string 1851 } 1853 7.1.2. warning 1855 Importance: Base 1857 Used to log details of an internal warning that might not get 1858 reflected on the wire. 1860 Data: 1862 { 1863 code?:uint32, 1864 message?:string 1865 } 1867 7.1.3. info 1869 Importance: Extra 1871 Used mainly for implementations that want to use qlog as their one 1872 and only logging format but still want to support unstructured string 1873 messages. 1875 Data: 1877 { 1878 message:string 1879 } 1881 7.1.4. debug 1883 Importance: Extra 1884 Used mainly for implementations that want to use qlog as their one 1885 and only logging format but still want to support unstructured string 1886 messages. 1888 Data: 1890 { 1891 message:string 1892 } 1894 7.1.5. verbose 1896 Importance: Extra 1898 Used mainly for implementations that want to use qlog as their one 1899 and only logging format but still want to support unstructured string 1900 messages. 1902 Data: 1904 { 1905 message:string 1906 } 1908 7.2. simulation 1910 When evaluating a protocol evaluation, one typically sets up a series 1911 of interoperability or benchmarking tests, in which the test 1912 situations can change over time. For example, the network bandwidth 1913 or latency can vary during the test, or the network can be fully 1914 disable for a short time. In these setups, it is useful to know when 1915 exactly these conditions are triggered, to allow for proper 1916 correlation with other events. 1918 7.2.1. scenario 1920 Importance: Extra 1922 Used to specify which specific scenario is being tested at this 1923 particular instance. This could also be reflected in the top-level 1924 qlog's "summary" or "configuration" fields, but having a separate 1925 event allows easier aggregation of several simulations into one 1926 trace. 1928 { 1929 name?:string, 1930 details?:any 1931 } 1933 7.2.2. marker 1935 Importance: Extra 1937 Used to indicate when specific emulation conditions are triggered at 1938 set times (e.g., at 3 seconds in 2% packet loss is introduced, at 10s 1939 a NAT rebind is triggered). 1941 { 1942 type?:string, 1943 message?:string 1944 } 1946 8. Security Considerations 1948 TBD 1950 9. IANA Considerations 1952 TBD 1954 10. References 1956 10.1. Normative References 1958 [QLOG-MAIN] 1959 Marx, R., Ed., "Main logging schema for qlog", Work in 1960 Progress, Internet-Draft, draft-marx-qlog-main-schema-02, 1961 2 November 2020, . 1964 [QUIC-HTTP] 1965 Bishop, M., Ed., "Hypertext Transfer Protocol Version 3 1966 (HTTP/3)", Work in Progress, Internet-Draft, draft-ietf- 1967 quic-http-32, 1 October 2020, 1968 . 1970 [QUIC-QPACK] 1971 Frindell, A., Ed., "QPACK: Header Compression for HTTP/3", 1972 Work in Progress, Internet-Draft, draft-ietf-quic-qpack- 1973 19, 20 October 2020, 1974 . 1976 [QUIC-TRANSPORT] 1977 Iyengar, J., Ed. and M. Thomson, Ed., "QUIC: A UDP-Based 1978 Multiplexed and Secure Transport", Work in Progress, 1979 Internet-Draft, draft-ietf-quic-transport-32, 1 October 1980 2020, . 1983 10.2. Informative References 1985 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 1986 Requirement Levels", BCP 14, RFC 2119, 1987 DOI 10.17487/RFC2119, March 1997, 1988 . 1990 Appendix A. QUIC data field definitions 1992 A.1. IPAddress 1994 class IPAddress : string | bytes; 1996 // 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) 1998 A.2. PacketType 2000 enum PacketType { 2001 initial, 2002 handshake, 2003 zerortt = "0RTT", 2004 onertt = "1RTT", 2005 retry, 2006 version_negotiation, 2007 stateless_reset, 2008 unknown 2009 } 2011 A.3. PacketNumberSpace 2013 enum PacketNumberSpace { 2014 initial, 2015 handshake, 2016 application_data 2017 } 2019 A.4. PacketHeader 2020 class PacketHeader { 2021 // Note: short vs long header is implicit through PacketType 2023 packet_type: PacketType; 2024 packet_number: uint64; 2026 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 2028 token?:Token; // only if packet_type == initial 2030 length?: uint16, // only if packet_type == initial || handshake || 0RTT. Signifies length of the packet_number plus the payload. 2032 // only if present in the header 2033 // if correctly using transport:connection_id_updated events, 2034 // dcid can be skipped for 1RTT packets 2035 version?: bytes; // e.g., "ff00001d" for draft-29 2036 scil?: uint8; 2037 dcil?: uint8; 2038 scid?: bytes; 2039 dcid?: bytes; 2040 } 2042 A.5. Token 2044 class Token { 2045 type?:"retry"|"resumption"|"stateless_reset"; 2047 length?:uint32; // byte length of the token 2048 data?:bytes; // raw byte value of the token 2050 details?:any; // decoded fields included in the token (typically: peer's IP address, creation time) 2051 } 2053 The token carried in an Initial packet can either be a retry token 2054 from a Retry packet, a stateless reset token from a Stateless Reset 2055 packet or one originally provided by the server in a NEW_TOKEN frame 2056 used when resuming a connection (e.g., for address validation 2057 purposes). Retry and resumption tokens typically contain encoded 2058 metadata to check the token's validity when it is used, but this 2059 metadata and its format is implementation specific. For that, this 2060 field includes a general-purpose "details" field. 2062 A.6. KeyType 2063 enum KeyType { 2064 server_initial_secret, 2065 client_initial_secret, 2067 server_handshake_secret, 2068 client_handshake_secret, 2070 server_0rtt_secret, 2071 client_0rtt_secret, 2073 server_1rtt_secret, 2074 client_1rtt_secret 2075 } 2077 A.7. QUIC Frames 2079 type QuicFrame = PaddingFrame | PingFrame | AckFrame | ResetStreamFrame | StopSendingFrame | CryptoFrame | NewTokenFrame | StreamFrame | MaxDataFrame | MaxStreamDataFrame | MaxStreamsFrame | DataBlockedFrame | StreamDataBlockedFrame | StreamsBlockedFrame | NewConnectionIDFrame | RetireConnectionIDFrame | PathChallengeFrame | PathResponseFrame | ConnectionCloseFrame | HandshakeDoneFrame | UnknownFrame; 2081 A.7.1. PaddingFrame 2083 In QUIC, PADDING frames are simply identified as a single byte of 2084 value 0. As such, each padding byte could be theoretically 2085 interpreted and logged as an individual PaddingFrame. 2087 However, as this leads to heavy logging overhead, implementations 2088 SHOULD instead emit just a single PaddingFrame and set the 2089 payload_length property to the amount of PADDING bytes/frames 2090 included in the packet. 2092 class PaddingFrame{ 2093 frame_type:string = "padding"; 2095 length?:uint32; // total frame length, including frame header 2096 payload_length?:uint32; 2097 } 2099 A.7.2. PingFrame 2101 class PingFrame{ 2102 frame_type:string = "ping"; 2104 length?:uint32; // total frame length, including frame header 2105 payload_length?:uint32; 2106 } 2108 A.7.3. AckFrame 2109 class AckFrame{ 2110 frame_type:string = "ack"; 2112 ack_delay?:float; // in ms 2114 // first number is "from": lowest packet number in interval 2115 // second number is "to": up to and including // highest packet number in interval 2116 // e.g., looks like [[1,2],[4,5]] 2117 acked_ranges?:Array<[uint64, uint64]|[uint64]>; 2119 // ECN (explicit congestion notification) related fields (not always present) 2120 ect1?:uint64; 2121 ect0?:uint64; 2122 ce?:uint64; 2124 length?:uint32; // total frame length, including frame header 2125 payload_length?:uint32; 2126 } 2128 Note: the packet ranges in AckFrame.acked_ranges do not necessarily 2129 have to be ordered (e.g., [[5,9],[1,4]] is a valid value). 2131 Note: the two numbers in the packet range can be the same (e.g., 2132 [120,120] means that packet with number 120 was ACKed). However, in 2133 that case, implementers SHOULD log [120] instead and tools MUST be 2134 able to deal with both notations. 2136 A.7.4. ResetStreamFrame 2138 class ResetStreamFrame{ 2139 frame_type:string = "reset_stream"; 2141 stream_id:uint64; 2142 error_code:ApplicationError | uint32; 2143 final_size:uint64; // in bytes 2145 length?:uint32; // total frame length, including frame header 2146 payload_length?:uint32; 2147 } 2149 A.7.5. StopSendingFrame 2150 class StopSendingFrame{ 2151 frame_type:string = "stop_sending"; 2153 stream_id:uint64; 2154 error_code:ApplicationError | uint32; 2156 length?:uint32; // total frame length, including frame header 2157 payload_length?:uint32; 2158 } 2160 A.7.6. CryptoFrame 2162 class CryptoFrame{ 2163 frame_type:string = "crypto"; 2165 offset:uint64; 2166 length:uint64; 2168 payload_length?:uint32; 2169 } 2171 A.7.7. NewTokenFrame 2173 class NewTokenFrame{ 2174 frame_type:string = "new_token"; 2176 token:Token 2177 } 2179 A.7.8. StreamFrame 2181 class StreamFrame{ 2182 frame_type:string = "stream"; 2184 stream_id:uint64; 2186 // These two MUST always be set 2187 // If not present in the Frame type, log their default values 2188 offset:uint64; 2189 length:uint64; 2191 // this MAY be set any time, but MUST only be set if the value is "true" 2192 // if absent, the value MUST be assumed to be "false" 2193 fin?:boolean; 2195 raw?:bytes; 2196 } 2197 A.7.9. MaxDataFrame 2199 class MaxDataFrame{ 2200 frame_type:string = "max_data"; 2202 maximum:uint64; 2203 } 2205 A.7.10. MaxStreamDataFrame 2207 class MaxStreamDataFrame{ 2208 frame_type:string = "max_stream_data"; 2210 stream_id:uint64; 2211 maximum:uint64; 2212 } 2214 A.7.11. MaxStreamsFrame 2216 class MaxStreamsFrame{ 2217 frame_type:string = "max_streams"; 2219 stream_type:string = "bidirectional" | "unidirectional"; 2220 maximum:uint64; 2221 } 2223 A.7.12. DataBlockedFrame 2225 class DataBlockedFrame{ 2226 frame_type:string = "data_blocked"; 2228 limit:uint64; 2229 } 2231 A.7.13. StreamDataBlockedFrame 2233 class StreamDataBlockedFrame{ 2234 frame_type:string = "stream_data_blocked"; 2236 stream_id:uint64; 2237 limit:uint64; 2238 } 2240 A.7.14. StreamsBlockedFrame 2241 class StreamsBlockedFrame{ 2242 frame_type:string = "streams_blocked"; 2244 stream_type:string = "bidirectional" | "unidirectional"; 2245 limit:uint64; 2246 } 2248 A.7.15. NewConnectionIDFrame 2250 class NewConnectionIDFrame{ 2251 frame_type:string = "new_connection_id"; 2253 sequence_number:uint32; 2254 retire_prior_to:uint32; 2256 connection_id_length?:uint8; 2257 connection_id:bytes; 2259 stateless_reset_token?:Token; 2260 } 2262 A.7.16. RetireConnectionIDFrame 2264 class RetireConnectionIDFrame{ 2265 frame_type:string = "retire_connection_id"; 2267 sequence_number:uint32; 2268 } 2270 A.7.17. PathChallengeFrame 2272 class PathChallengeFrame{ 2273 frame_type:string = "path_challenge"; 2275 data?:bytes; // always 64-bit 2276 } 2278 A.7.18. PathResponseFrame 2280 class PathResponseFrame{ 2281 frame_type:string = "path_response"; 2283 data?:bytes; // always 64-bit 2284 } 2286 A.7.19. ConnectionCloseFrame 2288 raw_error_code is the actual, numerical code. This is useful because 2289 some error types are spread out over a range of codes (e.g., QUIC's 2290 crypto_error). 2292 type ErrorSpace = "transport" | "application"; 2294 class ConnectionCloseFrame{ 2295 frame_type:string = "connection_close"; 2297 error_space?:ErrorSpace; 2298 error_code?:TransportError | ApplicationError | uint32; 2299 raw_error_code?:uint32; 2300 reason?:string; 2302 trigger_frame_type?:uint64 | string; // For known frame types, the appropriate "frame_type" string. For unknown frame types, the hex encoded identifier value 2303 } 2305 A.7.20. HandshakeDoneFrame 2307 class HandshakeDoneFrame{ 2308 frame_type:string = "handshake_done"; 2309 } 2311 A.7.21. UnknownFrame 2313 class UnknownFrame{ 2314 frame_type:string = "unknown"; 2315 raw_frame_type:uint64; 2317 raw_length?:uint32; 2318 raw?:bytes; 2319 } 2321 A.7.22. TransportError 2322 enum TransportError { 2323 no_error, 2324 internal_error, 2325 connection_refused, 2326 flow_control_error, 2327 stream_limit_error, 2328 stream_state_error, 2329 final_size_error, 2330 frame_encoding_error, 2331 transport_parameter_error, 2332 connection_id_limit_error, 2333 protocol_violation, 2334 invalid_token, 2335 application_error, 2336 crypto_buffer_exceeded 2337 } 2339 A.7.23. CryptoError 2341 These errors are defined in the TLS document as "A TLS alert is 2342 turned into a QUIC connection error by converting the one-byte alert 2343 description into a QUIC error code. The alert description is added 2344 to 0x100 to produce a QUIC error code from the range reserved for 2345 CRYPTO_ERROR." 2347 This approach maps badly to a pre-defined enum. As such, we define 2348 the crypto_error string as having a dynamic component here, which 2349 should include the hex-encoded value of the TLS alert description. 2351 enum CryptoError { 2352 crypto_error_{TLS_ALERT} 2353 } 2355 Appendix B. HTTP/3 data field definitions 2357 B.1. HTTP/3 Frames 2359 type HTTP3Frame = DataFrame | HeadersFrame | PriorityFrame | CancelPushFrame | SettingsFrame | PushPromiseFrame | GoAwayFrame | MaxPushIDFrame | DuplicatePushFrame | ReservedFrame | UnknownFrame; 2361 B.1.1. DataFrame 2363 class DataFrame{ 2364 frame_type:string = "data"; 2366 raw?:bytes; 2367 } 2369 B.1.2. HeadersFrame 2371 This represents an _uncompressed_, plaintext HTTP Headers frame 2372 (e.g., no QPACK compression is applied). 2374 For example: 2376 headers: [{"name":":path","value":"/"},{"name":":method","value":"GET"},{"name":":authority","value":"127.0.0.1:4433"},{"name":":scheme","value":"https"}] 2378 class HeadersFrame{ 2379 frame_type:string = "header"; 2380 headers:Array; 2381 } 2383 class HTTPHeader { 2384 name:string; 2385 value:string; 2386 } 2388 B.1.3. CancelPushFrame 2390 class CancelPushFrame{ 2391 frame_type:string = "cancel_push"; 2392 push_id:uint64; 2393 } 2395 B.1.4. SettingsFrame 2397 class SettingsFrame{ 2398 frame_type:string = "settings"; 2399 settings:Array; 2400 } 2402 class Setting{ 2403 name:string; 2404 value:string; 2405 } 2407 B.1.5. PushPromiseFrame 2409 class PushPromiseFrame{ 2410 frame_type:string = "push_promise"; 2411 push_id:uint64; 2413 headers:Array; 2414 } 2416 B.1.6. GoAwayFrame 2418 class GoAwayFrame{ 2419 frame_type:string = "goaway"; 2420 stream_id:uint64; 2421 } 2423 B.1.7. MaxPushIDFrame 2425 class MaxPushIDFrame{ 2426 frame_type:string = "max_push_id"; 2427 push_id:uint64; 2428 } 2430 B.1.8. DuplicatePushFrame 2432 class DuplicatePushFrame{ 2433 frame_type:string = "duplicate_push"; 2434 push_id:uint64; 2435 } 2437 B.1.9. ReservedFrame 2439 class ReservedFrame{ 2440 frame_type:string = "reserved"; 2441 } 2443 B.1.10. UnknownFrame 2445 HTTP/3 re-uses QUIC's UnknownFrame definition, since their values and 2446 usage overlaps. 2448 B.2. ApplicationError 2449 enum ApplicationError{ 2450 http_no_error, 2451 http_general_protocol_error, 2452 http_internal_error, 2453 http_stream_creation_error, 2454 http_closed_critical_stream, 2455 http_frame_unexpected, 2456 http_frame_error, 2457 http_excessive_load, 2458 http_id_error, 2459 http_settings_error, 2460 http_missing_settings, 2461 http_request_rejected, 2462 http_request_cancelled, 2463 http_request_incomplete, 2464 http_early_response, 2465 http_connect_error, 2466 http_version_fallback 2467 } 2469 Appendix C. QPACK DATA type definitions 2471 C.1. QPACK Instructions 2473 Note: the instructions do not have explicit encoder/decoder types, 2474 since there is no overlap between the insturctions of both types in 2475 neither name nor function. 2477 type QPackInstruction = SetDynamicTableCapacityInstruction | InsertWithNameReferenceInstruction | InsertWithoutNameReferenceInstruction | DuplicateInstruction | HeaderAcknowledgementInstruction | StreamCancellationInstruction | InsertCountIncrementInstruction; 2479 C.1.1. SetDynamicTableCapacityInstruction 2481 class SetDynamicTableCapacityInstruction { 2482 instruction_type:string = "set_dynamic_table_capacity"; 2484 capacity:uint32; 2485 } 2487 C.1.2. InsertWithNameReferenceInstruction 2488 class InsertWithNameReferenceInstruction { 2489 instruction_type:string = "insert_with_name_reference"; 2491 table_type:"static"|"dynamic"; 2493 name_index:uint32; 2495 huffman_encoded_value:boolean; 2497 value_length?:uint32; 2498 value?:string; 2499 } 2501 C.1.3. InsertWithoutNameReferenceInstruction 2503 class InsertWithoutNameReferenceInstruction { 2504 instruction_type:string = "insert_without_name_reference"; 2506 huffman_encoded_name:boolean; 2508 name_length?:uint32; 2509 name?:string; 2511 huffman_encoded_value:boolean; 2513 value_length?:uint32; 2514 value?:string; 2515 } 2517 C.1.4. DuplicateInstruction 2519 class DuplicateInstruction { 2520 instruction_type:string = "duplicate"; 2522 index:uint32; 2523 } 2525 C.1.5. HeaderAcknowledgementInstruction 2527 class HeaderAcknowledgementInstruction { 2528 instruction_type:string = "header_acknowledgement"; 2530 stream_id:uint64; 2531 } 2533 C.1.6. StreamCancellationInstruction 2534 class StreamCancellationInstruction { 2535 instruction_type:string = "stream_cancellation"; 2537 stream_id:uint64; 2538 } 2540 C.1.7. InsertCountIncrementInstruction 2542 class InsertCountIncrementInstruction { 2543 instruction_type:string = "insert_count_increment"; 2545 increment:uint32; 2546 } 2548 C.2. QPACK Header compression 2550 type QPackHeaderBlockRepresentation = IndexedHeaderField | LiteralHeaderFieldWithName | LiteralHeaderFieldWithoutName; 2552 C.2.1. IndexedHeaderField 2554 Note: also used for "indexed header field with post-base index" 2556 class IndexedHeaderField { 2557 header_field_type:string = "indexed_header"; 2559 table_type:"static"|"dynamic"; // MUST be "dynamic" if is_post_base is true 2560 index:uint32; 2562 is_post_base:boolean = false; // to represent the "indexed header field with post-base index" header field type 2563 } 2565 C.2.2. LiteralHeaderFieldWithName 2567 Note: also used for "Literal header field with post-base name 2568 reference" 2570 class LiteralHeaderFieldWithName { 2571 header_field_type:string = "literal_with_name"; 2573 preserve_literal:boolean; // the 3rd "N" bit 2574 table_type:"static"|"dynamic"; // MUST be "dynamic" if is_post_base is true 2575 name_index:uint32; 2577 huffman_encoded_value:boolean; 2578 value_length?:uint32; 2579 value?:string; 2581 is_post_base:boolean = false; // to represent the "Literal header field with post-base name reference" header field type 2582 } 2584 C.2.3. LiteralHeaderFieldWithoutName 2586 class LiteralHeaderFieldWithoutName { 2587 header_field_type:string = "literal_without_name"; 2589 preserve_literal:boolean; // the 3rd "N" bit 2591 huffman_encoded_name:boolean; 2592 name_length?:uint32; 2593 name?:string; 2595 huffman_encoded_value:boolean; 2596 value_length?:uint32; 2597 value?:string; 2598 } 2600 C.2.4. QPackHeaderBlockPrefix 2602 class QPackHeaderBlockPrefix { 2603 required_insert_count:uint32; 2604 sign_bit:boolean; 2605 delta_base:uint32; 2606 } 2608 Appendix D. Change Log 2610 D.1. Since draft-01: 2612 Major changes: 2614 * Moved data_moved from http to transport. Also made the "from" and 2615 "to" fields flexible strings instead of an enum (#111,#65) 2617 * Moved packet_type fields to PacketHeader. Moved packet_size field 2618 out of PacketHeader to RawInfo:length (#40) 2620 * Made events that need to log packet_type and packet_number use a 2621 header field instead of logging these fields individually 2623 * Added support for logging retry, stateless reset and initial 2624 tokens (#94,#86,#117) 2626 * Moved separate general event categories into a single category 2627 "generic" (#47) 2629 * Added "transport:connection_closed" event (#43,#85,#78,#49) 2631 * Added version_information and alpn_information events 2632 (#85,#75,#28) 2634 * Added parameters_restored events to help clarify 0-RTT behaviour 2635 (#88) 2637 Smaller changes: 2639 * Merged loss_timer events into one loss_timer_updated event 2641 * Field data types are now strongly defined (#10,#39,#36,#115) 2643 * Renamed qpack instruction_received and instruction_sent to 2644 instruction_created and instruction_parsed (#114) 2646 * Updated qpack:dynamic_table_updated.update_type. It now has the 2647 value "inserted" instead of "added" (#113) 2649 * Updated qpack:dynamic_table_updated. It now has an "owner" field 2650 to differentiate encoder vs decoder state (#112) 2652 * Removed push_allowed from http:parameters_set (#110) 2654 * Removed explicit trigger field indications from events, since this 2655 was moved to be a generic property of the "data" field (#80) 2657 * Updated transport:connection_id_updated to be more in line with 2658 other similar events. Also dropped importance from Core to Base 2659 (#45) 2661 * Added length property to PaddingFrame (#34) 2663 * Added packet_number field to transport:frames_processed (#74) 2664 * Added a way to generically log packet header flags (first 8 bits) 2665 to PacketHeader 2667 * Added additional guidance on which events to log in which 2668 situations (#53) 2670 * Added "simulation:scenario" event to help indicate simulation 2671 details 2673 * Added "packets_acked" event (#107) 2675 * Added "datagram_ids" to the datagram_X and packet_X events to 2676 allow tracking of coalesced QUIC packets (#91) 2678 * Extended connection_state_updated with more fine-grained states 2679 (#49) 2681 D.2. Since draft-00: 2683 * Event and category names are now all lowercase 2685 * Added many new events and their definitions 2687 * "type" fields have been made more specific (especially important 2688 for PacketType fields, which are now called packet_type instead of 2689 type) 2691 * Events are given an importance indicator (issue #22) 2693 * Event names are more consistent and use past tense (issue #21) 2695 * Triggers have been redefined as properties of the "data" field and 2696 updated for most events (issue #23) 2698 Appendix E. Design Variations 2700 TBD 2702 Appendix F. Acknowledgements 2704 Thanks to Marten Seemann, Jana Iyengar, Brian Trammell, Dmitri 2705 Tikhonov, Stephen Petrides, Jari Arkko, Marcus Ihlar, Victor 2706 Vasiliev, Mirja Kuehlewind, Jeremy Laine, Kazu Yamamoto, Christian 2707 Huitema, and Lucas Pardue for their feedback and suggestions. 2709 Author's Address 2710 Robin Marx 2711 Hasselt University 2713 Email: robin.marx@uhasselt.be