| Internet-Draft | QUIC event definitions for qlog | November 2026 |
| Marx, et al. | Expires 6 May 2027 | [Page] |
- Workgroup:
- QUIC
- Internet-Draft:
- draft-ietf-quic-qlog-quic-events-14
- Published:
- Intended Status:
- Standards Track
- Expires:
QUIC event definitions for qlog
Abstract
This document describes a qlog event schema containing concrete qlog event definitions and their metadata for the core QUIC protocol and selected extensions.¶
Note to Readers
-
Note to RFC editor: Please remove this section before publication.¶
Feedback and discussion are welcome at https://github.com/quicwg/qlog. Readers are advised to refer to the "editor's draft" at that URL for an up-to-date version of this document.¶
Status of This Memo
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 6 May 2027.¶
Copyright Notice
Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
1. Introduction
This document defines a qlog event schema (Section 8 of [QLOG-MAIN]) containing concrete events for the core QUIC protocol (see [QUIC-TRANSPORT], [QUIC-RECOVERY], and [QUIC-TLS]) and some of its extensions (see [QUIC-DATAGRAM], [GREASEBIT], and [RESET-STREAM-AT]).¶
The event namespace with identifier quic is defined; see Section 2. In
this namespace multiple events derive from the qlog abstract Event class
(Section 7 of [QLOG-MAIN]), each extending the data field and defining their
name field values and semantics. The data types that the events use are
defined in Section 8.¶
1.1. Use of Group IDs
QUIC's Original Destination Connection ID (ODCID) can be used as the value of
the qlog group_id field. The ODCID is the connection ID that the client
chooses for its first Initial packet. It stays the same for the whole
connection, unlike the connection IDs that endpoints use, which can change. It
can also link packets such as Retry and Version Negotiation to the connection.¶
The ODCID can also be used as the qlog filename or file identifier, optionally suffixed by the vantage point type. For example, abcd1234_server.qlog would contain the server-side trace of the connection with ODCID abcd1234.¶
1.2. Raw Packet and Frame Information
Protected QUIC packets (Initial, 0-RTT, Handshake, and 1-RTT) end with an AEAD authentication tag. Every cipher suite that QUIC version 1 can use has a 16-byte tag; see Section 5.3 of [QUIC-TLS]. When calculating the lengths in RawInfo fields (Section 10 of [QLOG-MAIN]) for these packets, the tag is treated as a 16-byte trailer.¶
1.3. Events without a Known Connection
A qlog trace is typically associated with a single QUIC connection. However,
some events cannot be tied to a specific connection, especially on the server.
For example, a packet_dropped event (Section 5.7) with the trigger
"connection_unknown" is for a packet that matches no known connection.¶
There are various ways to handle these events, each with tradeoffs between file size overhead, flexibility, ease of use, and ease of implementation. Some options include:¶
- Log them in a separate endpoint-wide trace, or use a special
group_idvalue, not associated with a single connection.¶ - Log them in the most recently used trace.¶
- Use additional heuristics to identify the connection, for example the four-tuple in addition to the connection ID.¶
- Buffer events until they can be assigned to a connection, for example events about the Version Negotiation and Retry packets that a server sends before it creates connection state.¶
1.4. Notational Conventions
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.¶
The event and data structure definitions in this document are expressed in the Concise Data Definition Language [CDDL] and its extensions described in Section 1.2 of [QLOG-MAIN].¶
This document uses the following from [QLOG-MAIN]: the event namespace and event type concepts; the name, data, tuple, group_id, and time-related fields; and the RawInfo type.¶
Events are defined with an importance level as described in Section 8.3 of [QLOG-MAIN].¶
As is the case for [QLOG-MAIN], the qlog schema definitions in this document are intentionally agnostic to serialization formats. The choice of format is an implementation decision.¶
2. Event Schema Definition
This document describes how the core QUIC protocol and selected extensions can
be expressed in qlog using a newly defined event schema. Per the requirements in
Section 8 of [QLOG-MAIN], this document registers the quic namespace. The
event schema URI is urn:ietf:params:qlog:events:quic.¶
2.1. Draft Event Schema Identification
This section is to be removed before publishing as an RFC.¶
Only implementations of the final, published RFC can use the events belonging to
the event schema with the URI urn:ietf:params:qlog:events:quic. Until such an
RFC exists, implementations MUST NOT identify themselves using this URI.¶
Implementations of draft versions of the event schema MUST append the string
"-" and the corresponding draft number to the URI. For example, draft 07 of this
document is identified using the URI urn:ietf:params:qlog:events:quic-07.¶
The namespace identifier itself is not affected by this requirement.¶
3. QUIC Event Overview
Table 1 summarizes the name value of each event type that is defined in this specification.¶
| Name value | Importance | Definition |
|---|---|---|
| quic:server_listening | Extra | Section 4.1 |
| quic:connection_started | Base | Section 4.2 |
| quic:connection_closed | Base | Section 4.3 |
| quic:connection_id_updated | Base | Section 4.4 |
| quic:spin_bit_updated | Base | Section 4.5 |
| quic:connection_state_updated | Base | Section 4.6 |
| quic:tuple_assigned | Base | Section 4.7 |
| quic:mtu_updated | Extra | Section 4.8 |
| quic:version_information | Core | Section 5.1 |
| quic:alpn_information | Core | Section 5.2 |
| quic:parameters_set | Core | Section 5.3 |
| quic:parameters_restored | Base | Section 5.4 |
| quic:packet_sent | Core | Section 5.5 |
| quic:packet_received | Core | Section 5.6 |
| quic:packet_dropped | Base | Section 5.7 |
| quic:packet_buffered | Base | Section 5.8 |
| quic:packets_acked | Extra | Section 5.9 |
| quic:udp_datagrams_sent | Extra | Section 5.10 |
| quic:udp_datagrams_received | Extra | Section 5.11 |
| quic:udp_datagram_dropped | Extra | Section 5.12 |
| quic:stream_state_updated | Base | Section 5.13 |
| quic:frames_created | Extra | Section 5.14.1 |
| quic:frames_parsed | Extra | Section 5.14.2 |
| quic:stream_data_moved | Base | Section 5.15 |
| quic:datagram_data_moved | Base | Section 5.16 |
| quic:datagram_dropped | Base | Section 5.17 |
| quic:connection_data_blocked_updated | Extra | Section 5.18 |
| quic:stream_data_blocked_updated | Extra | Section 5.19 |
| quic:datagram_data_blocked_updated | Extra | Section 5.20 |
| quic:migration_state_updated | Extra | Section 5.21 |
| quic:timer_updated | Extra | Section 5.22 |
| quic:key_updated | Base | Section 6.1 |
| quic:key_discarded | Base | Section 6.2 |
| quic:recovery_parameters_set | Base | Section 7.1 |
| quic:recovery_metrics_updated | Core | Section 7.2 |
| quic:congestion_state_updated | Base | Section 7.3 |
| quic:packet_lost | Core | Section 7.4 |
| quic:marked_for_retransmit | Extra | Section 7.5 |
| quic:ecn_state_updated | Extra | Section 7.6 |
QUIC events extend the $ProtocolEventData extension point defined in
Section 8.2 of [QLOG-MAIN]. Additionally, they allow for direct extensibility by their use of
per-event extension points via the $$ CDDL "group socket" syntax, as also
described in Section 8.2 of [QLOG-MAIN].¶
QuicEventData = QUICServerListening /
QUICConnectionStarted /
QUICConnectionClosed /
QUICConnectionIDUpdated /
QUICSpinBitUpdated /
QUICConnectionStateUpdated /
QUICTupleAssigned /
QUICMTUUpdated /
QUICVersionInformation /
QUICALPNInformation /
QUICParametersSet /
QUICParametersRestored /
QUICPacketSent /
QUICPacketReceived /
QUICPacketDropped /
QUICPacketBuffered /
QUICPacketsAcked /
QUICUDPDatagramsSent /
QUICUDPDatagramsReceived /
QUICUDPDatagramDropped /
QUICStreamStateUpdated /
QUICFramesCreated /
QUICFramesParsed /
QUICStreamDataMoved /
QUICDatagramDataMoved /
QUICDatagramDropped /
QUICConnectionDataBlockedUpdated /
QUICStreamDataBlockedUpdated /
QUICDatagramDataBlockedUpdated /
QUICMigrationStateUpdated /
QUICTimerUpdated /
QUICKeyUpdated /
QUICKeyDiscarded /
QUICRecoveryParametersSet /
QUICRecoveryMetricsUpdated /
QUICCongestionStateUpdated /
QUICPacketLost /
QUICMarkedForRetransmit /
QUICECNStateUpdated
$ProtocolEventData /= QuicEventData
The concrete QUIC event types are further defined below, their type identifier is the heading name. The subdivisions in sections on Connectivity, Transport, Security, and Recovery are purely for readability.¶
4. Connectivity Events
4.1. server_listening
The server_listening event is emitted when the server starts accepting
connections. It has Extra importance level.¶
QUICServerListening = {
? address_v4: IPAddressPort
? address_v6: IPAddressPort
; the server will always answer client Initial packets with a Retry
; packet (no 1-RTT connection setups by choice)
? retry_required: bool
* $$quic-serverlistening-extension
}
Some QUIC stacks do not handle sockets directly, so they cannot log IP addresses or ports.¶
4.2. connection_started
The connection_started event is emitted when a client attempts a new
connection, or when a server accepts one. It overlaps with the
connection_state_updated event, but it also logs the local and remote
endpoint information. It has Base importance level.¶
QUICConnectionStarted = {
local: TupleEndpointInfo
remote: TupleEndpointInfo
* $$quic-connectionstarted-extension
}
Some QUIC stacks do not handle sockets directly, so they cannot log IP
addresses or ports. All fields of TupleEndpointInfo
(Figure 45) are optional, so such a stack can log local and
remote with only the fields it knows, such as connection_ids.¶
4.3. connection_closed
The connection_closed event is emitted when a connection closes, typically
because of an error or a timeout. It has Base importance level.¶
This event overlaps with the connection_state_updated event and the
CONNECTION_CLOSE frame. However, when analyzing large deployments, it can be
useful to have a single event for each closure, with a reason field for more
detail. This event can also log closures due to timeouts or explicit
application actions, such as racing several connections and aborting the
slowest, which the other events cannot easily capture.¶
The connection_closed event is logged when the local endpoint does one of the
following; see Section 10 of [QUIC-TRANSPORT]:¶
- silently discards the connection after an idle timeout;¶
- sends a CONNECTION_CLOSE frame, and enters the closing state;¶
- receives a CONNECTION_CLOSE frame, and enters the draining state; or¶
- receives a Stateless Reset, and enters the draining state.¶
Later changes, such as leaving the closing or draining state, are logged with
the connection_state_updated event.¶
QUIC has two kinds of connection error, transport errors and application
errors, each with defined codes and semantics; see Section 20 of [QUIC-TRANSPORT]. An implementation can also have internal errors, which it
might or might not map to these codes. So this event can carry two levels of
error: connection_error or application_error for the QUIC error, and
internal_code for a more specific internal error.¶
If an error code has no known string, connection_error or application_error
can be "unknown", and error_code then holds the numerical value without
variable-length integer encoding.¶
QUICConnectionClosed = {
; which side closed the connection
? initiator: Initiator
? connection_error: $TransportError /
CryptoError
? application_error: $ApplicationError
; if connection_error or application_error === "unknown"
? error_code: uint64
? internal_code: uint64
? reason: text
? trigger:
"idle_timeout" /
"application" /
"error" /
"version_mismatch" /
; when received from peer
"stateless_reset" /
"aborted" /
; when it is unclear what triggered the CONNECTION_CLOSE
"unspecified"
* $$quic-connectionclosed-extension
}
Implementations SHOULD use the most descriptive trigger value that they can
determine. This is often clear at the endpoint that closes the connection, but
can be less clear at the endpoint that receives the CONNECTION_CLOSE frame.¶
4.4. connection_id_updated
The connection_id_updated event is emitted when either endpoint updates its
current connection ID. This typically happens rarely during a connection, so
logging this event is more efficient than logging the connection ID in every
packet_sent or packet_received event. It has Base importance level.¶
The connection_id_updated event is viewed from the perspective of the
endpoint applying the new ID. When the endpoint receives a new connection ID
from the peer, the initiator field is "remote". When the endpoint updates its
own connection ID, the initiator field is "local".¶
QUICConnectionIDUpdated = {
initiator: Initiator
? old: ConnectionID
? new: ConnectionID
* $$quic-connectionidupdated-extension
}
4.5. spin_bit_updated
The spin_bit_updated event is emitted when the value of the QUIC latency spin
bit changes; see Section 17.4 of [QUIC-TRANSPORT]. It SHOULD NOT be emitted
when the spin bit is set to the value it already has. It has Base importance
level.¶
QUICSpinBitUpdated = {
state: bool
* $$quic-spinbitupdated-extension
}
4.6. connection_state_updated
The connection_state_updated event is emitted when the connection changes
state, to track progress through the QUIC handshake and connection close. It
has Base importance level.¶
[QUIC-TRANSPORT] does not define a complete set of connection states or their transitions, though it names some, such as the closing and draining states. This document defines the states most likely to be useful for debugging QUIC connections; the list is not exhaustive.¶
QUIC implementations SHOULD log the BaseConnectionStates, and can add the GranularConnectionStates when more in-depth debugging is required. Tools SHOULD handle both kinds equally.¶
QUICConnectionStateUpdated = {
? old: $ConnectionState
new: $ConnectionState
* $$quic-connectionstateupdated-extension
}
BaseConnectionStates =
; Initial packet sent/received
"attempted" /
; Handshake packet sent/received
"handshake_started" /
; Both sent a TLS Finished message
; and verified the peer's TLS Finished message
; 1-RTT packets can be sent
; RFC 9001 Section 4.1.1
"handshake_complete" /
; CONNECTION_CLOSE sent/received,
; stateless reset received or idle timeout
"closed"
GranularConnectionStates =
; RFC 9000 Section 8.1
; client sent Handshake packet OR
; client used connection ID chosen by the server OR
; client used valid address validation token
"peer_validated" /
; 1-RTT data can be sent by the server,
; but handshake is not done yet
; (server has sent TLS Finished; sometimes called 0.5 RTT data)
"early_write" /
; HANDSHAKE_DONE sent/received.
; RFC 9001 Section 4.1.2
"handshake_confirmed" /
; CONNECTION_CLOSE sent
"closing" /
; CONNECTION_CLOSE or Stateless Reset received
"draining" /
; draining or closing period done, connection state discarded
"closed"
$ConnectionState /= BaseConnectionStates / GranularConnectionStates
The connection_state_updated event overlaps with the connection_closed and
connection_started events, and with the frames logged in events such as
packet_received. Still, it can be useful to log state transitions separately,
especially if they map to an internal state machine. Implementations can
therefore use other ConnectionState values that match their internal logic.
Tools SHOULD handle these custom states in a similar way to the states defined
in this document.¶
4.7. tuple_assigned
The tuple_assigned event associates a TupleID with the details of a network
tuple, such as its IP addresses, ports, and connection IDs. It has Base
importance level.¶
As described in Section 7.2 of [QLOG-MAIN], each qlog event can be linked to
a single network tuple by its top-level tuple field, whose value is a
TupleID. Encoding tuple details, such as IP addresses or connection IDs, into
the TupleID itself can be cumbersome. This event records them separately, so
TupleIDs can stay short, and their details can be updated as the connection
evolves.¶
QUICTupleAssigned = {
tuple_id: TupleID
; the information for traffic going towards the remote receiver
? tuple_remote: TupleEndpointInfo
; the information for traffic coming in at the local endpoint
? tuple_local: TupleEndpointInfo
* $$quic-tupleassigned-extension
}
Implementations choose their own tuple_id values. For example, a TupleID can
be an incrementing integer, the first Destination Connection ID associated with
the tuple (or its sequence number), or the two endpoint IP addresses or a hash
of them.¶
The empty string ("") is a valid TupleID, and it is the default for events that
do not set the tuple field. So the initial tuple of a QUIC connection, on
which the handshake occurs (see Section 4.2), is implicitly
associated with the TupleID "". Details for this default tuple can be logged
with a tuple_assigned event whose tuple_id is "".¶
Because a tuple's details can change during the connection, a TupleID can
appear in several tuple_assigned events, and the latest one holds its current
details. The first tuple_assigned event for a TupleID indicates that the
TupleID was created, and later ones indicate updates. An event with both
tuple_local and tuple_remote omitted indicates that the TupleID was
abandoned.¶
4.8. mtu_updated
The mtu_updated event indicates that the estimated Path MTU was updated. This
happens as part of Path MTU discovery; see Section 14 of [QUIC-TRANSPORT]. It
has Extra importance level.¶
QUICMTUUpdated = {
? old: uint32
new: uint32
; at some point, MTU discovery stops, as a "good enough"
; packet size has been found
? done: bool
* $$quic-mtuupdated-extension
}
The done field defaults to false.¶
5. Transport Events
5.1. version_information
The version_information event supports QUIC version negotiation; see Section 6 of [QUIC-TRANSPORT]. It has Core importance level.¶
Each QUIC endpoint supports one or more versions. The client sends its first Initial packet using one of them. A server that does not support that version can reply with a Version Negotiation packet, which lists the versions the server supports. This event records the versions that each endpoint supports, and the chosen version if there is one.¶
QUICVersionInformation = {
? server_versions: [+ QuicVersion]
? client_versions: [+ QuicVersion]
? chosen_version: QuicVersion
* $$quic-versioninformation-extension
}
A client logs this event when it sends its first Initial packet. The event
includes client_versions, and chosen_version holds the version used in that
packet.¶
If the client then processes a Version Negotiation packet, it logs this event
again with client_versions. The event also includes server_versions, which
holds the versions from that packet. If the client selects one of them,
chosen_version holds it; otherwise, chosen_version is absent.¶
A Version Negotiation packet can also list reserved versions, which an endpoint
adds to check that its peer ignores unknown versions; see Section 6.3 of [QUIC-TRANSPORT]. Because server_versions holds the versions from the packet,
it can include reserved versions.¶
A server logs this event when it receives a client's first Initial packet. The
event includes server_versions. If the server supports the client's version,
chosen_version holds the version that the server uses for the connection.
Otherwise, chosen_version is absent, and client_versions holds the version
the client used.¶
5.2. alpn_information
The alpn_information event supports Application-Layer Protocol Negotiation
(ALPN) over the QUIC transport; see [RFC7301] and Section 8.1 of [QUIC-TLS]. It has Core importance level.¶
QUIC endpoints are configured with a list of supported ALPN identifiers. During the TLS handshake, the client sends its list, and the server chooses one identifier from both lists and sends it back. If no match is found, the connection is closed.¶
ALPN identifiers are byte sequences, which are often valid UTF-8. The
ALPNIdentifier type can hold either form: byte_value holds the raw bytes,
and string_value holds the identifier as text. Implementations SHOULD log at
least one form and MAY log both.¶
QUICALPNInformation = {
? server_alpns: [* ALPNIdentifier]
? client_alpns: [* ALPNIdentifier]
? chosen_alpn: ALPNIdentifier
* $$quic-alpninformation-extension
}
ALPNIdentifier = {
? byte_value: hexstring
? string_value: text
}
A client usually logs this event twice: first with client_alpns when it
offers its list, then with chosen_alpn when it learns the server's choice. It
can instead log a single event with both fields once it learns the choice.¶
A server logs this event once, after it chooses, with client_alpns,
server_alpns, and chosen_alpn.¶
5.3. parameters_set
The parameters_set event groups settings from several sources, such as
transport parameters and the TLS cipher suite, into a single event. This keeps
the number of events low, and lets a reader reason about what the settings do
without needing to know which mechanism set each one. It has Core importance
level.¶
Most of these settings are set once and never change. However, they are often
set at different times during the connection, so a trace can contain several
parameters_set events with different fields set.¶
Some settings have two values: one set by the local endpoint, and one requested
by the peer. The initiator field says which side the settings in an event
come from, so it MUST be correct for every setting in that event. Local and
remote settings MUST be logged in separate events. If the local endpoint
changes its behavior based on the peer's settings, the outcome can be logged
with a new event type, or with fields added through
$$quic-parametersset-extension; see Section 8.2 of [QLOG-MAIN].¶
The initiator field is required. Settings that both endpoints negotiate, such
as tls_cipher, are logged in both the local and the remote event.¶
Each setting starts the connection with its default value, or with no value if
it has no default. A parameters_set event that includes a setting replaces
its previous value; settings that the event omits keep their values.¶
The grease_quic_bit and reset_stream_at settings are true if the transport
parameter is present, and default to false.¶
Implementations are not required to recognize, process, or support every
parameter that they receive. For example, QUIC implementations ignore
transport parameters that they do not support; see Section 7.4.2 of [QUIC-TRANSPORT]. The unknown_parameters field can log the raw values of such
parameters, for example reserved (GREASE) parameters, private extensions, or
experiments.¶
In the case of connection resumption and 0-RTT, some of the server's parameters
are stored up-front at the client and used for the initial connection startup.
They are later updated with the server's reply. In these cases, utilize the
separate parameters_restored event to indicate the initial values, and this
event to indicate the updated values, as normal.¶
QUICParametersSet = {
initiator: Initiator
; true if valid session ticket was received
? resumption_allowed: bool
; true if early data extension was enabled on the TLS layer
? early_data_enabled: bool
; e.g., "AES_128_GCM_SHA256"
? tls_cipher: text
; RFC9000
? original_destination_connection_id: ConnectionID
? initial_source_connection_id: ConnectionID
? retry_source_connection_id: ConnectionID
? stateless_reset_token: StatelessResetToken
? disable_active_migration: bool
? max_idle_timeout: uint64
? max_udp_payload_size: uint64
? ack_delay_exponent: uint64
? max_ack_delay: uint64
? active_connection_id_limit: uint64
? initial_max_data: uint64
? initial_max_stream_data_bidi_local: uint64
? initial_max_stream_data_bidi_remote: uint64
? initial_max_stream_data_uni: uint64
? initial_max_streams_bidi: uint64
? initial_max_streams_uni: uint64
? preferred_address: PreferredAddress
? unknown_parameters: [* UnknownParameter]
; RFC9221
? max_datagram_frame_size: uint64
; RFC9287
? grease_quic_bit: bool
; draft-ietf-quic-reliable-stream-reset
? reset_stream_at: bool
* $$quic-parametersset-extension
}
PreferredAddress = {
? address_v4: IPAddressPort
? address_v6: IPAddressPort
connection_id: ConnectionID
stateless_reset_token: StatelessResetToken
}
UnknownParameter = {
id: uint64
? value: hexstring
}
5.4. parameters_restored
When using QUIC 0-RTT, clients are expected to remember and restore the server's
transport parameters from the previous connection. The parameters_restored
event is used to indicate which parameters were restored and to which values
when utilizing 0-RTT. It has Base importance level.¶
Note that not all transport parameters should be restored (many are even prohibited from being re-utilized). The ones listed here are the ones expected to be useful for correct 0-RTT usage.¶
QUICParametersRestored = {
; RFC9000
? disable_active_migration: bool
? max_idle_timeout: uint64
? max_udp_payload_size: uint64
? active_connection_id_limit: uint64
? initial_max_data: uint64
? initial_max_stream_data_bidi_local: uint64
? initial_max_stream_data_bidi_remote: uint64
? initial_max_stream_data_uni: uint64
? initial_max_streams_bidi: uint64
? initial_max_streams_uni: uint64
; RFC9221
? max_datagram_frame_size: uint64
; RFC9287
; can only be restored at the client.
; servers MUST NOT restore this parameter!
? grease_quic_bit: bool
* $$quic-parametersrestored-extension
}
5.5. packet_sent
The packet_sent event indicates that a QUIC packet was sent. It has Core
importance level.¶
QUICPacketSent = {
header: PacketHeader
? frames: [* $QuicFrame]
; only if header.packet_type === "stateless_reset"
? stateless_reset_token: StatelessResetToken
; only if header.packet_type === "version_negotiation"
? supported_versions: [+ QuicVersion]
? raw: RawInfo
? datagram_payload_checksum: uint32
? is_mtu_probe_packet: bool
? trigger:
; RFC 9002 Section 6.1.1
"retransmit_reordered" /
; RFC 9002 Section 6.1.2
"retransmit_timeout" /
; RFC 9002 Section 6.2.4
"pto_probe" /
; RFC 9002 6.2.3
"retransmit_crypto" /
; needed for some CCs to figure out bandwidth allocations
; when there are no normal sends
"cc_bandwidth_probe"
* $$quic-packetsent-extension
}
The encryption level and packet number space are not logged explicitly,
because header.packet_type implies them for the packet types that have them.¶
The datagram_payload_checksum field is described in Section 9.¶
The is_mtu_probe_packet field defaults to false.¶
5.6. packet_received
The packet_received event indicates that a QUIC packet was received. It has
Core importance level.¶
QUICPacketReceived = {
header: PacketHeader
? frames: [* $QuicFrame]
; only if header.packet_type === "stateless_reset"
? stateless_reset_token: StatelessResetToken
; only if header.packet_type === "version_negotiation"
? supported_versions: [+ QuicVersion]
? raw: RawInfo
? datagram_payload_checksum: uint32
? trigger:
; if packet was buffered because it couldn't be
; decrypted before
"keys_available"
* $$quic-packetreceived-extension
}
The encryption level and packet number space are not logged explicitly,
because header.packet_type implies them for the packet types that have them.¶
The datagram_payload_checksum field is described in Section 9.¶
5.7. packet_dropped
The packet_dropped event indicates that a QUIC packet was dropped. It has
Base importance level.¶
QUICPacketDropped = {
; Primarily packet_type should be filled here,
; as other fields might not be decryptable or parsable
? header: PacketHeader
? raw: RawInfo
? datagram_payload_checksum: uint32
? details: {* text => any}
? trigger:
"internal_error" /
"rejected" /
"unsupported" /
"invalid" /
"duplicate" /
"connection_unknown" /
"decryption_failure" /
"keys_unavailable" /
"general"
* $$quic-packetdropped-extension
}
The trigger field gives a general reason for dropping the packet, and the
details field can hold additional implementation-specific information. Some
example situations for each trigger value include:¶
- "internal_error": not initialized, out of memory¶
- "rejected": limits reached, DDoS protection, unwilling to track more paths¶
- "unsupported": unknown or unsupported version¶
- "invalid": packet parsing or validation error¶
- "duplicate": duplicate packet¶
- "connection_unknown": packet does not relate to a known connection or connection ID¶
- "decryption_failure": decryption failed¶
- "keys_unavailable": decryption keys were unavailable¶
- "general": situations not clearly covered in the other categories¶
Packets dropped as "unsupported" or "connection_unknown" often cannot be tied to a connection; see Section 1.3.¶
The datagram_payload_checksum field is described in Section 9.¶
5.8. packet_buffered
The packet_buffered event is emitted when a packet is buffered because it
cannot be processed yet, for example because the keys to decrypt it are not
yet available. Its full contents can be logged later, in a packet_received
event, once it is processed. It has Base importance level.¶
QUICPacketBuffered = {
; primarily packet_type should be filled here as other elements
; might not be available yet
? header: PacketHeader
? raw: RawInfo
? datagram_payload_checksum: uint32
? trigger:
; indicates the parser cannot keep up, temporarily buffers
; packet for later processing
"backpressure" /
; if packet cannot be decrypted because the proper keys were
; not yet available
"keys_unavailable"
* $$quic-packetbuffered-extension
}
The datagram_payload_checksum field is described in Section 9.¶
5.9. packets_acked
The packets_acked event is emitted when one or more sent packets are
acknowledged by the peer for the first time. It has Extra importance level.¶
Successive ACK frames can acknowledge the same packet, but this event is emitted only for the first acknowledgment of each packet. This information can also be deduced from received ACK frames, though finding the first acknowledgment needs extra processing. Implementations that do not log frame contents can use this event instead.¶
QUICPacketsAcked = {
? packet_number_space: $PacketNumberSpace
? packet_numbers: [+ uint64]
* $$quic-packetsacked-extension
}
The packet_number_space field defaults to "application_data", the
packet number space that most packets in a typical QUIC connection use.¶
5.10. udp_datagrams_sent
The udp_datagrams_sent event indicates that one or more UDP datagrams were
passed to the network socket. It can show how QUIC packet buffers are drained
to the operating system. It has Extra importance level.¶
QUICUDPDatagramsSent = {
; to support passing multiple at once
? count: uint16
; The RawInfo fields do not include the UDP headers,
; only the UDP payload
? raw: [+ RawInfo]
; ECN bits in the IP header
? ecn: [+ ECN]
? datagram_payload_checksums: [+ uint32]
* $$quic-udpdatagramssent-extension
}
The RawInfo fields exclude UDP headers, because QUIC implementations do not always handle UDP directly.¶
If an event omits the ecn field, the ECN bits are the same as on the last
udp_datagrams_sent event.¶
The datagram_payload_checksums field is described in Section 9.¶
5.11. udp_datagrams_received
The udp_datagrams_received event indicates that one or more UDP datagrams
were received from the network socket. It can show how the operating system
passes datagrams to the user-space stack. It has Extra importance level.¶
QUICUDPDatagramsReceived = {
; to support passing multiple at once
? count: uint16
; The RawInfo fields do not include the UDP headers,
; only the UDP payload
? raw: [+ RawInfo]
; ECN bits in the IP header
? ecn: [+ ECN]
? datagram_payload_checksums: [+ uint32]
* $$quic-udpdatagramsreceived-extension
}
If an event omits the ecn field, the ECN bits are the same as on the last
udp_datagrams_received event.¶
The datagram_payload_checksums field is described in Section 9.¶
5.12. udp_datagram_dropped
The udp_datagram_dropped event indicates that a UDP datagram was dropped,
typically because it does not contain a valid QUIC packet. If the datagram
contains a valid QUIC packet that is dropped for another reason, the
packet_dropped event (Section 5.7) is used instead. It has Extra
importance level.¶
QUICUDPDatagramDropped = {
; The RawInfo fields do not include the UDP headers,
; only the UDP payload
? raw: RawInfo
* $$quic-udpdatagramdropped-extension
}
5.13. stream_state_updated
The stream_state_updated event is emitted when the state of a QUIC stream
changes; see Section 3 of [QUIC-TRANSPORT]. Most state changes can be
inferred from the frames that are sent and received, but an explicit event can
be easier to use. It has Base importance level.¶
QUIC stream IDs encode whether a stream is unidirectional or bidirectional
(see Section 2.1 of [QUIC-TRANSPORT]), but the optional stream_type field
states it directly.¶
Section 3 of [QUIC-TRANSPORT] describes the sending and receiving parts of a
stream, each with its own state machine. The stream_side field says which
part's state changed. If both parts change state at the same time, for example
when both become "closed", two events with different stream_side values
SHOULD be logged.¶
StreamType = "unidirectional" /
"bidirectional"
QUICStreamStateUpdated = {
stream_id: uint64
? stream_type: StreamType
? old: $StreamState
new: $StreamState
stream_side: "sending" /
"receiving"
? trigger:
; stream state change was initiated by a local action
"local" /
; stream state change was initiated by a remote action
"remote"
* $$quic-streamstateupdated-extension
}
BaseStreamStates = "idle" /
"open" /
"closed"
GranularStreamStates =
; bidirectional stream states, RFC 9000 Section 3.4.
"half_closed_local" /
"half_closed_remote" /
; sending-side stream states, RFC 9000 Section 3.1.
"ready" /
"send" /
"data_sent" /
"reset_sent" /
; receive-side stream states, RFC 9000 Section 3.2.
"receive" /
"size_known" /
"data_read" /
"reset_read" /
; both-side states
"data_received" /
"reset_received" /
; qlog-defined: memory actually freed
"destroyed"
$StreamState /= BaseStreamStates / GranularStreamStates
QUIC implementations SHOULD log the BaseStreamStates, and can add the GranularStreamStates when more in-depth debugging is required. Tools SHOULD handle both kinds equally.¶
The trigger field can show which endpoint initiated a state change, for
example when a stream is closed because of a RESET_STREAM or STOP_SENDING
frame.¶
5.15. stream_data_moved
The stream_data_moved event indicates that QUIC stream data moved between
layers. It has Base importance level.¶
For example, data can move from an application protocol such as HTTP/3 to QUIC stream buffers, or the other way. Logging these moves can show the flow of data, how long data stays in each buffer, and the overhead introduced by each layer.¶
This event can also show whether received stream data is passed to the application protocol immediately or in batches. Data can be passed, for example, once per received packet, or in a batch after all received packets are processed. This can help identify bottlenecks, flow control issues, or scheduling problems.¶
The raw.length field gives the number of bytes moved. Because this event
covers stream data only, there are no packet or frame headers, and
raw.length MUST reflect that.¶
The additional_info field can log information about the stream state. For
example, an application that moves data into the transport and ends the stream
at the same time can log "fin_set". A transport that has received an
instruction to reset a stream can tell the application with "stream_reset". In
both cases, raw.length can be omitted or be zero.¶
This event covers only data in QUIC streams. For data in QUIC datagrams, see
the datagram_data_moved event (Section 5.16).¶
QUICStreamDataMoved = {
? stream_id: uint64
? offset: uint64
? from: $DataLocation
? to: $DataLocation
? additional_info: $DataMovedAdditionalInfo
? raw: RawInfo
* $$quic-streamdatamoved-extension
}
$DataLocation /= "application" /
"transport" /
"network"
$DataMovedAdditionalInfo /= "fin_set" /
"stream_reset"
5.16. datagram_data_moved
The datagram_data_moved event indicates that QUIC datagram data (see
[QUIC-DATAGRAM]) moved between layers. It has Base importance level.¶
For example, data can move from an application protocol such as WebTransport to QUIC buffers, or the other way. Logging these moves can show the flow of data, how long data stays in each buffer, and the overhead introduced by each layer.¶
This event can also show whether received datagram data is passed to the application protocol immediately or in batches. Data can be passed, for example, once per received packet, or in a batch after all received packets are processed. This can help identify bottlenecks or scheduling problems.¶
The raw.length field gives the number of bytes moved. Because this event
covers datagram data only, there are no packet or frame headers, and
raw.length MUST reflect that.¶
This event covers only data in QUIC datagrams. For data in QUIC streams, see
the stream_data_moved event (Section 5.15).¶
QUICDatagramDataMoved = {
? from: $DataLocation
? to: $DataLocation
? raw: RawInfo
* $$quic-datagramdatamoved-extension
}
5.17. datagram_dropped
The datagram_dropped event indicates that QUIC DATAGRAM data (see
[RFC9221]) was discarded locally, before sending or after reception. It has
Base importance level.¶
The direction field identifies the sending or receiving side, and trigger
indicates the reason for discarding the data. The raw.length field MUST count
discarded payload bytes, excluding packet and frame headers.¶
Received DATAGRAM data can be discarded while its packet is still acknowledged.
For drops of entire QUIC packets, use packet_dropped (Section 5.7).¶
QUICDatagramDropped = {
? direction: "sending" /
"receiving"
? raw: RawInfo
? trigger:
; insufficient space in a send or receive buffer
"buffer_full" /
; datagram data exceeds the maximum payload size
"too_large" /
text
* $$quic-datagramdropped-extension
}
5.18. connection_data_blocked_updated
The connection_data_blocked_updated event indicates that the QUIC connection
became blocked or unblocked for sending data. It has Extra importance level.¶
Depending on the reason, a blocked connection cannot send stream data, datagram
data, or both, until that reason is resolved. The stream_data_blocked_updated
and datagram_data_blocked_updated events give more detail for each type of
data.¶
QUICConnectionDataBlockedUpdated = {
? old: $BlockedState
new: $BlockedState
? reason: $BlockedReason
* $$quic-connectiondatablockedupdated-extension
}
$BlockedState /= "blocked" /
"unblocked"
$BlockedReason /= "scheduling" /
"pacing" /
"amplification_protection" /
"congestion_control" /
"connection_flow_control" /
"stream_flow_control" /
"stream_id" /
"application"
5.19. stream_data_blocked_updated
The stream_data_blocked_updated event indicates that a QUIC stream became
blocked or unblocked for sending. It has Extra importance level.¶
QUICStreamDataBlockedUpdated = {
? old: $BlockedState
new: $BlockedState
stream_id: uint64
? reason: $BlockedReason
* $$quic-streamdatablockedupdated-extension
}
5.20. datagram_data_blocked_updated
The datagram_data_blocked_updated event indicates that QUIC datagrams became
blocked or unblocked for sending. It has Extra importance level.¶
QUICDatagramDataBlockedUpdated = {
? old: $BlockedState
new: $BlockedState
? reason: $BlockedReason
* $$quic-datagramdatablockedupdated-extension
}
5.21. migration_state_updated
The migration_state_updated event logs the progress of a connection migration
by a client; see Section 9 of [QUIC-TRANSPORT]. It has Extra importance level.¶
Most details of a migration can be inferred from PATH_CHALLENGE and
PATH_RESPONSE frames, together with tuple_assigned events. However, it can
be useful to log the progress of the migration, and any decisions made, in a
single event.¶
The MigrationState values follow the steps in Section 9 of [QUIC-TRANSPORT]:
the probing_* values cover probing a new path (Section 9.1 of [QUIC-TRANSPORT]), and the migration_* values cover migrating the connection
(Section 9.2 of [QUIC-TRANSPORT]).¶
Implementations that log per-path information in migration_state_updated
events SHOULD also emit tuple_assigned events, to serve as the ground truth
for tuple information.¶
QUICMigrationStateUpdated = {
? old: MigrationState
new: MigrationState
? tuple_id: TupleID
; the information for traffic going towards the remote receiver
? tuple_remote: TupleEndpointInfo
; the information for traffic coming in at the local endpoint
? tuple_local: TupleEndpointInfo
* $$quic-migrationstateupdated-extension
}
; Note that MigrationState does not describe a full state machine
; These entries are not necessarily chronological,
; nor will they always all appear during
; a connection migration attempt.
MigrationState =
; probing packets are sent, migration not initiated yet
"probing_started" /
; did not get reply to probing packets,
; discarding path as an option
"probing_abandoned" /
; received reply to probing packets, path is migration candidate
"probing_successful" /
; non-probing packets are sent, attempting migration
"migration_started" /
; something went wrong during the migration, abandoning attempt
"migration_abandoned" /
; new path is now fully used, old path is discarded
"migration_complete"
5.22. timer_updated
The timer_updated event is emitted when a timer changes state. It has Extra
importance level.¶
The event_type field takes one of three values:¶
- "set": the timer is set, and
deltagives the time until it triggers¶ - "expired": the timer expired¶
- "cancelled": the timer was cancelled¶
An update to an active timer's timeout is logged as a new "set" event.¶
The recovery timer types correspond to timers in Section 6 of [QUIC-RECOVERY] and Appendix A.8 of [QUIC-RECOVERY]:¶
- "ack": the time threshold loss detection timeout¶
- "pto": the probe timeout¶
- "loss_timeout": the single, multi-modal loss detection timer that covers both¶
QUIC uses a variety of timers, and how they are used can depend on the
implementation. Implementers can add fields to this event through
$$quic-timerupdated-extension, or add timer types through $TimerType.¶
; a non-exhaustive list of typically employed timers
$TimerType /= "ack" /
"pto" /
"loss_timeout" /
"path_validation" /
"handshake_timeout" /
"idle_timeout"
QUICTimerUpdated = {
? timer_type: $TimerType
; to disambiguate in case there are multiple timers
; of the same type
? timer_id: uint64
; if used for recovery timers, this can be useful information
? packet_number_space: $PacketNumberSpace
event_type: "set" /
"expired" /
"cancelled"
; if event_type === "set": delta time is in ms from
; this event's timestamp until when the timer should trigger
? delta: float32
* $$quic-timerupdated-extension
}
6. Security Events
6.1. key_updated
The key_updated event indicates that a key was installed or updated. It has
Base importance level.¶
This happens when TLS provides new keys during the handshake, and at each 1-RTT key update; see Section 6 of [QUIC-TLS].¶
QUICKeyUpdated = {
key_type: $KeyType
? old: hexstring
? new: hexstring
; needed for 1RTT key updates
? key_phase: uint64
? trigger:
; (e.g., initial, handshake and 0-RTT keys
; are generated by TLS)
"tls" /
"remote_update" /
"local_update"
* $$quic-keyupdated-extension
}
The key_phase field holds the full key phase, which identifies the
generation of keys; it corresponds to @M and @N in Figure 9 of Section 6 of [QUIC-TLS]. The Key Phase bit in the packet header is the least significant
bit of this value.¶
6.2. key_discarded
The key_discarded event indicates that a key was discarded. It has Base
importance level.¶
Keys are discarded, for example, when the connection moves to a new encryption level during the handshake, or after a key update; see Section 4.9 of [QUIC-TLS].¶
QUICKeyDiscarded = {
key_type: $KeyType
? key: hexstring
; needed for 1RTT key updates
? key_phase: uint64
? trigger:
; (e.g., initial, handshake and 0-RTT keys
; are generated by TLS)
"tls" /
"remote_update" /
"local_update"
* $$quic-keydiscarded-extension
}
7. Recovery Events
Most of the events in this section are kept generic to support different
recovery approaches and congestion control algorithms. The old, new, and
trigger fields of congestion_state_updated, for instance, are free text, so
their values depend on the algorithm.¶
Tools that process these events SHOULD try to handle such values even when they
don't recognize them. For example, a tool that plots congestion states on a
timeline can label an unknown state with the value of the new field.¶
7.1. recovery_parameters_set
The recovery_parameters_set event groups initial parameters from both loss
detection and congestion control into a single event. It has Base importance
level.¶
These parameters are typically set once and never change. Implementations that
change them during the connection MAY emit the recovery_parameters_set event
more than once.¶
The reordering_threshold field contains the packet threshold for loss detection,
or "disabled" if packet-threshold loss detection is disabled.¶
QUICRecoveryParametersSet = {
; Loss detection, see RFC 9002 Appendix A.2
; in amount of packets
? reordering_threshold: uint16 / "disabled"
; as RTT multiplier
? time_threshold: float32
; in ms
timer_granularity: uint16
; in ms
? initial_rtt:float32
; congestion control, see RFC 9002 Appendix B.2
; in bytes. Note that this could be updated after pmtud
? max_datagram_size: uint32
; in bytes
? initial_congestion_window: uint64
; Note that this could change when max_datagram_size changes
; in bytes
? minimum_congestion_window: uint64
? loss_reduction_factor: float32
; as PTO multiplier
? persistent_congestion_threshold: uint16
* $$quic-recoveryparametersset-extension
}
Parameters that this document does not define, such as those of other loss
detection and recovery algorithms, can be added through
$$quic-recoveryparametersset-extension.¶
7.2. recovery_metrics_updated
The recovery_metrics_updated event is emitted when one or more of the
observable recovery metrics change value. It has Core importance level.¶
Implementations SHOULD group all metric updates that happen at or around the
same time into a single recovery_metrics_updated event. For example, if
min_rtt and smoothed_rtt change at the same time, they are logged in one
event, not two. Each event is only guaranteed to contain at least one of the
listed metrics.¶
QUICRecoveryMetricsUpdated = {
; Loss detection, see RFC 9002 Appendix A.3
; all following rtt fields are expressed in ms
? min_rtt: float32
? smoothed_rtt: float32
? latest_rtt: float32
? rtt_variance: float32
? pto_count: uint16
; Congestion control, see RFC 9002 Appendix B.2.
; in bytes
? congestion_window: uint64
? bytes_in_flight: uint64
; in bytes
? ssthresh: uint64
; qlog defined
; sum of all packet number spaces
? packets_in_flight: uint64
; in bits per second
? pacing_rate: uint64
* $$quic-recoverymetricsupdated-extension
}
To make logging easier, implementations MAY log values that are the same as
previously reported values; for example, two consecutive
recovery_metrics_updated events can report the same min_rtt. However,
implementations SHOULD try to log only values that changed.¶
Metrics that this document does not define, such as those of other loss
detection and recovery algorithms, can be added through
$$quic-recoverymetricsupdated-extension.¶
7.3. congestion_state_updated
The congestion_state_updated event indicates when the congestion controller
enters a new state that changes its behavior. It has Base importance level.¶
This document does not define values for the event's fields. Congestion control algorithms have different states and different causes for moving between them, and stacks can implement the same algorithm differently. For example, the NewReno controller in Section 7.3 of [QUIC-RECOVERY] has three states: slow start, recovery, and congestion avoidance.¶
QUICCongestionStateUpdated = {
? old: text
new: text
? trigger: text
* $$quic-congestionstateupdated-extension
}
The trigger field SHOULD be logged if a state change can have more than one
cause. For example, NewReno enters recovery when it detects packet loss or
when the ECN-CE count increases, so the trigger field shows which of the two
caused the change.¶
7.4. packet_lost
The packet_lost event is emitted when loss detection declares a packet lost.
It has Core importance level.¶
QUICPacketLost = {
; should include at least the packet_type and packet_number
? header: PacketHeader
? frames: [* $QuicFrame]
? is_mtu_probe_packet: bool
? trigger:
"reordering_threshold" /
"time_threshold" /
"pto_expired"
* $$quic-packetlost-extension
}
The frames field lists the frames that the lost packet carried. It is
optional, because not all implementations keep sent packets in full. The data
that is then marked for retransmission can be logged with the
marked_for_retransmit event (Section 7.5).¶
The is_mtu_probe_packet field marks a packet that was sent as a Path MTU
probe. The loss of such a packet is not a reliable sign of congestion; see
Section 14.4 of [QUIC-TRANSPORT]. It defaults to false.¶
The trigger field SHOULD be logged. Its value shows how loss detection
declared the packet lost:¶
-
reordering_threshold: the packet threshold was exceeded; see Section 6.1.1 of [QUIC-RECOVERY].¶ -
time_threshold: the time threshold was exceeded; see Section 6.1.2 of [QUIC-RECOVERY].¶ -
pto_expired: the probe timeout expired, and the sender declared the packet lost instead of sending a probe; see Section 6.2.4 of [QUIC-RECOVERY].¶
7.5. marked_for_retransmit
The marked_for_retransmit event indicates which data was marked for
retransmission after packet loss was detected. It has Extra importance level.¶
This single event covers all types of retransmittable data, which it logs using the existing QUIC frame definitions.¶
A packet_lost event (Section 7.4) records that a packet was declared
lost, and can list the frames it carried. A marked_for_retransmit event
records what the implementation then marks for retransmission. The two can
differ, because not every frame is retransmitted (ACK and PADDING frames never
are), and retransmitted data need not be sent in the same frames; see
Section 13.3 of [QUIC-TRANSPORT].¶
An implementation that retransmits the frames of a lost packet unchanged can
log them here, or skip this event and use the frames in the packet_lost event
instead. An implementation with more complex logic, such as one that marks
ranges of a stream's send buffer as in flight, or one that does not keep sent
frames in full, can log frames that describe the data it marked for
retransmission. These frames need not match any frame that was sent or will be
sent.¶
If an implementation logs packet_sent events, tools can infer much of this
data from them. For example, overlapping stream offsets and lengths show when
data was retransmitted.¶
QUICMarkedForRetransmit = {
frames: [+ $QuicFrame]
* $$quic-markedforretransmit-extension
}
7.6. ecn_state_updated
The ecn_state_updated event indicates a progression in the ECN state machine
as described in Appendix A.4 of [QUIC-TRANSPORT]. It has Extra importance
level.¶
QUICECNStateUpdated = {
? old: ECNState
new: ECNState
? trigger: text
* $$quic-ecnstateupdated-extension
}
ECNState =
; ECN testing in progress
"testing" /
; ECN state unknown, waiting for acknowledgements
; for testing packets
"unknown" /
; ECN testing failed
"failed" /
; testing was successful
"capable"
The trigger field can be used to log why the state changed, for example which
ECN validation check in Section 13.4.2 of [QUIC-TRANSPORT] failed.¶
8. QUIC Data Type Definitions
8.1. QuicVersion
QuicVersion = hexstring
8.2. ConnectionID
ConnectionID = hexstring
8.3. Initiator
Initiator = "local" /
"remote"
8.4. IPAddressPort
; an IP address 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).
; Additionally, the IP address and port pair can be logged as an
; application-defined redacted string for privacy or security reasons.
IPAddressPort = {
ip: text / hexstring
port: uint16
} / text
8.5. TupleEndpointInfo
TupleEndpointInfo describes one half, or direction, of a four-tuple. A full tuple has two halves: the server sends to the client's IP address and port, and the client sends to the server's IP address and port. Each direction uses its own destination connection ID.¶
Structures that log tuple information SHOULD therefore include two TupleEndpointInfo instances, one for each half of the tuple.¶
TupleEndpointInfo = {
? address_v4: IPAddressPort
? address_v6: IPAddressPort
; Even though usually only a single ConnectionID
; is associated with a given tuple/path at a time,
; there are situations where there can be an overlap
; or a need to keep track of previous ConnectionIDs
? connection_ids: [+ ConnectionID]
* $$quic-tupleendpointinfo-extension
}
8.6. PacketType
$PacketType /= "initial" /
"handshake" /
"0RTT" /
"1RTT" /
"retry" /
"version_negotiation" /
"stateless_reset" /
"unknown"
8.7. PacketNumberSpace
$PacketNumberSpace /= "initial" /
"handshake" /
"application_data"
8.8. PacketHeader
If a packet type has no known $PacketType string, packet_type can be
"unknown", and packet_type_bytes then holds the numerical value without
variable-length integer encoding.¶
PacketHeader omits the fixed bit and the reserved bits because QUIC version 1
gives them fixed values; see Section 17 of [QUIC-TRANSPORT]. Their values can
be logged in the raw.data field of the event that logs the PacketHeader.¶
QUIC extensions that use these bits, such as the QUIC Bit greasing extension
([GREASEBIT]), can log that use with new events, similar to
spin_bit_updated, or with fields added to PacketHeader through
$$quic-packetheader-extension.¶
For long header packets of type initial, handshake, and 0RTT, the length field
of the packet header is logged in the qlog raw.length field, and the value
signifies the length of the packet number plus the payload.¶
PacketHeader = {
packet_type: $PacketType
; only if packet_type === "unknown"
? packet_type_bytes: uint64
; only if packet_type === "1RTT"
? spin_bit: bool
; only if packet_type === "1RTT", and if the key phase was
; determined from the key_phase_bit
? key_phase: uint64
; only if packet_type === "1RTT", and if key_phase is not set
? key_phase_bit: bool
; only if packet_type === "initial" || "handshake" || "0RTT" ||
; "1RTT"
? packet_number_length: uint8
; only if packet_type === "initial" || "handshake" || "0RTT" ||
; "1RTT"
? packet_number: uint64
; only if packet_type === "initial" || "retry"
? token: Token
; only if present in the header.
; if correctly using connection_id_updated events,
; dcid can be skipped for 1RTT packets
? version: QuicVersion
? scil: uint8
? dcil: uint8
? scid: ConnectionID
? dcid: ConnectionID
* $$quic-packetheader-extension
}
8.9. Token
Token = {
? type: $TokenType
; decoded fields included in the token
; (typically: peer's IP address, creation time)
? details: {
* text => any
}
? raw: RawInfo
* $$quic-token-extension
}
$TokenType /= "retry" /
"resumption"
The token carried in an Initial packet is either a token from a Retry packet,
or one that the server provided earlier in a NEW_TOKEN frame, for address
validation in a later connection; see Section 8.1.3 of [QUIC-TRANSPORT].
Both kinds typically encode metadata that the server uses to check the token,
but the metadata and its format are implementation-specific. The details
field can log that metadata.¶
8.10. StatelessResetToken
; always 16 bytes StatelessResetToken = hexstring
The stateless reset token is defined in Section 10.3 of [QUIC-TRANSPORT].¶
8.11. KeyType
$KeyType /= "server_initial_secret" /
"client_initial_secret" /
"server_handshake_secret" /
"client_handshake_secret" /
"server_0rtt_secret" /
"client_0rtt_secret" /
"server_1rtt_secret" /
"client_1rtt_secret"
8.12. ECN
ECN holds the ECN codepoint carried in the IP header; see Section 13.4 of [QUIC-TRANSPORT].¶
ECN = "Not-ECT" / "ECT(1)" / "ECT(0)" / "CE"
8.13. QUIC Frames
The generic $QuicFrame is defined here as a CDDL "type socket" extension
point. It can be extended to support additional QUIC frame types.¶
; The QuicFrame is any key-value map (e.g., JSON object)
$QuicFrame /= {
* text => any
}
The QUIC frame types defined in this document are as follows:¶
QuicBaseFrames = PaddingFrame /
PingFrame /
AckFrame /
ResetStreamFrame /
ResetStreamAtFrame /
StopSendingFrame /
CryptoFrame /
NewTokenFrame /
StreamFrame /
MaxDataFrame /
MaxStreamDataFrame /
MaxStreamsFrame /
DataBlockedFrame /
StreamDataBlockedFrame /
StreamsBlockedFrame /
NewConnectionIDFrame /
RetireConnectionIDFrame /
PathChallengeFrame /
PathResponseFrame /
ConnectionCloseFrame /
HandshakeDoneFrame /
UnknownFrame /
DatagramFrame
$QuicFrame /= QuicBaseFrames
8.13.1. PaddingFrame
A PADDING frame is a single byte with the value 0, so each padding byte is its
own frame; see Section 19.1 of [QUIC-TRANSPORT]. Logging each one as a
separate PaddingFrame could add hundreds of entries to a single packet event,
for example when a client pads an Initial packet to 1200 bytes. Implementations
SHOULD instead log a single PaddingFrame for the packet, and set its
raw.payload_length field to the number of PADDING frames in the packet.¶
PaddingFrame = {
frame_type: "padding"
? raw: RawInfo
}
8.13.2. PingFrame
PingFrame = {
frame_type: "ping"
? raw: RawInfo
}
8.13.3. AckFrame
; either a single number (e.g., [1]) or two numbers (e.g., [1,2]).
; For two numbers:
; the first number is "from": lowest packet number in interval
; the second number is "to": up to and including the highest
; packet number in the interval
AckRange = [1*2 uint64]
AckFrame = {
frame_type: "ack"
; in ms
? ack_delay: float32
; e.g., looks like [[1,2],[4,5], [7], [10,22]] serialized
? acked_ranges: [+ AckRange]
; ECN (explicit congestion notification) related fields
; (not always present)
? ect1: uint64
? ect0: uint64
? ce: uint64
? raw: RawInfo
}
The ranges in acked_ranges do not have to be in order; for example,
[[5,9],[1,4]] is valid.¶
The two numbers in a range can be equal; for example, [120,120] means that
packet 120 was acknowledged. In that case, implementations SHOULD log [120]
instead, and tools MUST handle both forms.¶
8.13.4. ResetStreamFrame
If an error code has no known ApplicationError string, error can be
"unknown", and error_code then holds the numerical value without
variable-length integer encoding.¶
ResetStreamFrame = {
frame_type: "reset_stream"
stream_id: uint64
error: $ApplicationError
; if error === "unknown"
? error_code: uint64
; in bytes
final_size: uint64
? raw: RawInfo
}
8.13.5. ResetStreamAtFrame
The RESET_STREAM_AT frame is defined in Section 4 of [RESET-STREAM-AT].¶
If an error code has no known ApplicationError string, error can be
"unknown", and error_code then holds the numerical value without
variable-length integer encoding.¶
ResetStreamAtFrame = {
frame_type: "reset_stream_at"
stream_id: uint64
error: $ApplicationError
; if error === "unknown"
? error_code: uint64
; in bytes
final_size: uint64
; in bytes
reliable_size: uint64
? raw: RawInfo
}
8.13.6. StopSendingFrame
If an error code has no known ApplicationError string, error can be
"unknown", and error_code then holds the numerical value without
variable-length integer encoding.¶
StopSendingFrame = {
frame_type: "stop_sending"
stream_id: uint64
error: $ApplicationError
; if error === "unknown"
? error_code: uint64
? raw: RawInfo
}
8.13.7. CryptoFrame
The length field of the CRYPTO frame MUST be logged in the qlog raw.length
field. The other sub-fields of the raw field are optional.¶
CryptoFrame = {
frame_type: "crypto"
offset: uint64
raw: RawInfo
}
8.13.8. NewTokenFrame
NewTokenFrame = {
frame_type: "new_token"
token: Token
? raw: RawInfo
}
8.13.9. StreamFrame
If the STREAM frame contains a length field, it MUST be logged in the qlog
raw.length field. If it does not, the implementation MAY calculate the actual
frame byte length itself and log that in raw.length if necessary.¶
The offset field defaults to 0, and the fin field defaults to false.¶
StreamFrame = {
frame_type: "stream"
stream_id: uint64
? offset: uint64
? fin: bool
? raw: RawInfo
}
8.13.10. MaxDataFrame
MaxDataFrame = {
frame_type: "max_data"
maximum: uint64
? raw: RawInfo
}
8.13.11. MaxStreamDataFrame
MaxStreamDataFrame = {
frame_type: "max_stream_data"
stream_id: uint64
maximum: uint64
? raw: RawInfo
}
8.13.12. MaxStreamsFrame
MaxStreamsFrame = {
frame_type: "max_streams"
stream_type: StreamType
maximum: uint64
? raw: RawInfo
}
8.13.13. DataBlockedFrame
DataBlockedFrame = {
frame_type: "data_blocked"
limit: uint64
? raw: RawInfo
}
8.13.14. StreamDataBlockedFrame
StreamDataBlockedFrame = {
frame_type: "stream_data_blocked"
stream_id: uint64
limit: uint64
? raw: RawInfo
}
8.13.15. StreamsBlockedFrame
StreamsBlockedFrame = {
frame_type: "streams_blocked"
stream_type: StreamType
limit: uint64
? raw: RawInfo
}
8.13.16. NewConnectionIDFrame
NewConnectionIDFrame = {
frame_type: "new_connection_id"
sequence_number: uint64
retire_prior_to: uint64
; mainly used if e.g., for privacy reasons the full
; connection_id cannot be logged
? connection_id_length: uint8
connection_id: ConnectionID
? stateless_reset_token: StatelessResetToken
? raw: RawInfo
}
8.13.17. RetireConnectionIDFrame
RetireConnectionIDFrame = {
frame_type: "retire_connection_id"
sequence_number: uint64
? raw: RawInfo
}
8.13.18. PathChallengeFrame
PathChallengeFrame = {
frame_type: "path_challenge"
; always 8 bytes
? data: hexstring
? raw: RawInfo
}
8.13.19. PathResponseFrame
PathResponseFrame = {
frame_type: "path_response"
; always 8 bytes
? data: hexstring
? raw: RawInfo
}
8.13.20. ConnectionCloseFrame
If an error code has no known string, error can be "unknown", and
error_code then holds the numerical value without variable-length integer
encoding.¶
The trigger_frame_type field logs the Frame Type field, which only the
transport variant of CONNECTION_CLOSE (type 0x1c) carries; see Section 19.19 of [QUIC-TRANSPORT]. A known frame type is logged as its frame type string,
such as "stream". An unknown frame type is logged as the numerical value
without variable-length integer encoding.¶
The reason phrase in a CONNECTION_CLOSE frame is a byte sequence, which RFC
9000 recommends be UTF-8; see Section 19.19 of [QUIC-TRANSPORT]. The reason
field holds the reason phrase as text, and reason_bytes holds the raw bytes,
for example when the value is not UTF-8 or when an endpoint does not want to
decode it. Implementations SHOULD log at least one form and MAY log both.¶
ErrorSpace = "transport" /
"application"
ConnectionCloseFrame = {
frame_type: "connection_close"
? error_space: ErrorSpace
? error: $TransportError / CryptoError /
$ApplicationError
; if error === "unknown"
? error_code: uint64
? reason: text
? reason_bytes: hexstring
; when error_space === "transport"
? trigger_frame_type: uint64 /
text
? raw: RawInfo
}
8.13.21. HandshakeDoneFrame
HandshakeDoneFrame = {
frame_type: "handshake_done"
? raw: RawInfo
}
8.13.22. UnknownFrame
The frame_type_bytes field holds the numerical value of the frame type
without variable-length integer encoding.¶
UnknownFrame = {
frame_type: "unknown"
frame_type_bytes: uint64
? raw: RawInfo
}
8.13.23. DatagramFrame
The QUIC DATAGRAM frame is defined in Section 4 of [QUIC-DATAGRAM].¶
If the DATAGRAM frame contains a length field, it MUST be logged in the qlog
raw.length field. If it does not, the implementation MAY calculate the actual
datagram byte length itself and log that in raw.length if necessary.¶
DatagramFrame = {
frame_type: "datagram"
? raw: RawInfo
}
8.14. TransportError
The generic $TransportError is defined here as a CDDL "type socket" extension
point. It can be extended to support additional transport errors.¶
$TransportError /= "no_error" /
"internal_error" /
"connection_refused" /
"flow_control_error" /
"stream_limit_error" /
"stream_state_error" /
"final_size_error" /
"frame_encoding_error" /
"transport_parameter_error" /
"connection_id_limit_error" /
"protocol_violation" /
"invalid_token" /
"application_error" /
"crypto_buffer_exceeded" /
"key_update_error" /
"aead_limit_reached" /
"no_viable_path" /
"unknown"
; there is no value to reflect CRYPTO_ERROR
; use the CryptoError type instead
8.15. ApplicationError
Application errors are defined by the application protocol that runs on top of
QUIC, such as HTTP/3, so this document cannot list them. $ApplicationError is
instead defined as a CDDL "type socket" extension point, with a single
"unknown" value.¶
$ApplicationError /= "unknown"
Event schemas for application protocols MUST add their error strings by
extending the $ApplicationError socket; see Section 8.2 of [QLOG-MAIN].¶
8.16. CryptoError
RFC 9001 converts a TLS alert into a QUIC error code by adding the alert's AlertDescription value to 0x0100; see Section 4.8 of [QUIC-TLS].¶
A fixed list of strings does not fit this range well, so a CryptoError value
is crypto_error_ followed by the resulting QUIC error code in lowercase
hexadecimal, from crypto_error_0x100 to crypto_error_0x1ff. For example, a
handshake_failure alert, which is 0x0128 in QUIC, is logged as
crypto_error_0x128.¶
; all strings from "crypto_error_0x100" to "crypto_error_0x1ff" CryptoError = text .regexp "crypto_error_0x1[0-9a-f][0-9a-f]"
9. Handling Packet Coalescing
Multiple QUIC packets can be coalesced into a single UDP datagram, especially during the handshake; see Section 12.2 of [QUIC-TRANSPORT]. Neither QUIC nor UDP provides a way to tell which packets shared a datagram.¶
To let tools match QUIC packet events to UDP datagram events, the optional
datagram_payload_checksum field carries a 32-bit CRC32c of the UDP payload,
calculated as described in Section 11.3 of [RFC9868]. The UDP datagram
events carry one checksum per datagram, in their datagram_payload_checksums
field.¶
10. Security and Privacy Considerations
The security and privacy considerations discussed in Section 14 of [QLOG-MAIN] apply to this document as well.¶
11. IANA Considerations
This document registers a new entry in the "qlog event schema URIs" registry, which was created in Section 15 of [QLOG-MAIN]:¶
- Event schema URI:
-
urn:ietf:params:qlog:events:quic¶
- Namespace:
-
quic¶
- Event Types:
-
server_listening, connection_started, connection_closed, connection_id_updated, spin_bit_updated, connection_state_updated, tuple_assigned, mtu_updated, version_information, alpn_information, parameters_set, parameters_restored, packet_sent, packet_received, packet_dropped, packet_buffered, packets_acked, udp_datagrams_sent, udp_datagrams_received, udp_datagram_dropped, stream_state_updated, frames_created, frames_parsed, stream_data_moved, datagram_data_moved, datagram_dropped, connection_data_blocked_updated, stream_data_blocked_updated, datagram_data_blocked_updated, migration_state_updated, timer_updated, key_updated, key_discarded, recovery_parameters_set, recovery_metrics_updated, congestion_state_updated, packet_lost, marked_for_retransmit, ecn_state_updated¶
- Description:
-
Event definitions related to the QUIC transport protocol.¶
- Reference:
-
This document¶
12. References
12.1. Normative References
- [CDDL]
- Birkholz, H., Vigano, C., and C. Bormann, "Concise Data Definition Language (CDDL): A Notational Convention to Express Concise Binary Object Representation (CBOR) and JSON Data Structures", RFC 8610, DOI 10.17487/RFC8610, , <https://www.rfc-editor.org/rfc/rfc8610>.
- [GREASEBIT]
- Thomson, M., "Greasing the QUIC Bit", RFC 9287, DOI 10.17487/RFC9287, , <https://www.rfc-editor.org/rfc/rfc9287>.
- [QLOG-MAIN]
- Marx, R., Niccolini, L., Seemann, M., and L. Pardue, "qlog: Structured Logging for Network Protocols", Work in Progress, Internet-Draft, draft-ietf-quic-qlog-main-schema-14, , <https://datatracker.ietf.org/doc/html/draft-ietf-quic-qlog-main-schema-14>.
- [QUIC-DATAGRAM]
- Pauly, T., Kinnear, E., and D. Schinazi, "An Unreliable Datagram Extension to QUIC", RFC 9221, DOI 10.17487/RFC9221, , <https://www.rfc-editor.org/rfc/rfc9221>.
- [QUIC-RECOVERY]
- Iyengar, J., Ed. and I. Swett, Ed., "QUIC Loss Detection and Congestion Control", RFC 9002, DOI 10.17487/RFC9002, , <https://www.rfc-editor.org/rfc/rfc9002>.
- [QUIC-TLS]
- Thomson, M., Ed. and S. Turner, Ed., "Using TLS to Secure QUIC", RFC 9001, DOI 10.17487/RFC9001, , <https://www.rfc-editor.org/rfc/rfc9001>.
- [QUIC-TRANSPORT]
- Iyengar, J., Ed. and M. Thomson, Ed., "QUIC: A UDP-Based Multiplexed and Secure Transport", RFC 9000, DOI 10.17487/RFC9000, , <https://www.rfc-editor.org/rfc/rfc9000>.
- [RESET-STREAM-AT]
- Seemann, M. and K. Oku, "QUIC Stream Resets with Partial Delivery", Work in Progress, Internet-Draft, draft-ietf-quic-reliable-stream-reset-11, , <https://datatracker.ietf.org/doc/html/draft-ietf-quic-reliable-stream-reset-11>.
- [RFC2119]
- Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, , <https://www.rfc-editor.org/rfc/rfc2119>.
- [RFC8174]
- Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, , <https://www.rfc-editor.org/rfc/rfc8174>.
- [RFC9221]
- Pauly, T., Kinnear, E., and D. Schinazi, "An Unreliable Datagram Extension to QUIC", RFC 9221, DOI 10.17487/RFC9221, , <https://www.rfc-editor.org/rfc/rfc9221>.
- [RFC9868]
- Touch, J. and C. Heard, Ed., "Transport Options for UDP", RFC 9868, DOI 10.17487/RFC9868, , <https://www.rfc-editor.org/rfc/rfc9868>.
12.2. Informative References
- [RFC7301]
- Friedl, S., Popov, A., Langley, A., and E. Stephan, "Transport Layer Security (TLS) Application-Layer Protocol Negotiation Extension", RFC 7301, DOI 10.17487/RFC7301, , <https://www.rfc-editor.org/rfc/rfc7301>.
Acknowledgements
Much of the initial work by Robin Marx was done at the Hasselt and KU Leuven Universities.¶
Thanks to Jana Iyengar, Brian Trammell, Dmitri Tikhonov, Stephen Petrides, Jari Arkko, Marcus Ihlar, Victor Vasiliev, Mirja Kuehlewind, Jeremy Laine, Kazu Yamamoto, Christian Huitema, Hugo Landau, Will Hawkins, Mathis Engelbart, Kazuho Oku, and Jonathan Lennox for their feedback and suggestions.¶
Change Log
This section is to be removed before publishing as an RFC.¶
Since draft-ietf-qlog-quic-events-11:
- Updated several fields to be uint64 per QUIC spec¶
- Renamed error and error_code fields and logic (#473)¶
- Clarified parameters_set usage (#493)¶
- Replaced all length fields with raw.length (#495)¶
- Change loss_timer_updated to timer_updated (#496)¶
- Renamed path_assigned to tuple_assigned (#491)¶
- Reworked stream_state_updated (#497)¶
- Renamed owner to initiator (#498)¶
- Split up flags in PacketHeader (#478)¶
Since draft-ietf-qlog-quic-events-08:
- Removed individual categories and put every event in the single
quicevent schema namespace. Major change (#439)¶ - Renamed
recovery:metrics_updatedtoquic:recovery_metrics_updatedandrecovery:parameters_settoquic:recovery_parameters_set(#439)¶ - Added
unknown_parametersfield toparameters_set(#438)¶ - Added extra parameters to
parameters_restored(#441)¶
Since draft-ietf-qlog-quic-events-07:
- TODO (we forgot...)¶
Since draft-ietf-qlog-quic-events-06:
- Added PathAssigned and MigrationStateUpdated events (#336)¶
- Added extension points to parameters_set and parameters_restored (#400)¶
- Removed error_code_value from connection_closed (#386, #392)¶
- Renamed generation to key_phase for key_updated and key_discarded (#390)¶
- Removed retry_token from packet_sent and packet_received (#389)¶
- Updated ALPN handling (#385)¶
- Added key_unavailable trigger to packet_dropped (#381)¶
- Updated several uint32 to uint64¶
- ProtocolEventBody is now called ProtocolEventData (#352)¶
- Editorial changes (#402, #404, #394, #393)¶
Since draft-ietf-qlog-quic-events-04:
- Updated guidance on logging events across connections (#279)¶
- Renamed 'transport' category to 'quic' (#302)¶
- Added support for multiple packet numbers in 'quic:frames_processed' (#307)¶
- Added definitions for RFC9287 (QUIC GREASE Bit extension) (#311)¶
- Added definitions for RFC9221 (QUIC Datagram Frame extension) (#310)¶
- (Temporarily) removed definitions for connection migration events (#317)¶
- Editorial and formatting changes (#298, #299, #304, #306, #327)¶
Since draft-ietf-qlog-quic-events-03:
- Ensured consistent use of RawInfo to indicate raw wire bytes (#243)¶
- Renamed UnknownFrame:raw_frame_type to :frame_type_value (#54)¶
- Renamed ConnectionCloseFrame:raw_error_code to :error_code_value (#54)¶
- Changed triggers for packet_dropped (#278)¶
- Added entries to TransportError enum (#285)¶
- Changed minimum_congestion_window to uint64 (#288)¶
Since draft-ietf-qlog-quic-events-02:
- Renamed key_retired to key_discarded (#185)¶
- Added fields and events for DPLPMTUD (#135)¶
- Made packet_number optional in PacketHeader (#244)¶
- Removed connection_retried event placeholder (#255)¶
- Changed QuicFrame to a CDDL plug type (#257)¶
- Moved data definitions out of the appendix into separate sections¶
- Added overview Table of Contents¶
Since draft-ietf-qlog-quic-events-01:
- Added Stateless Reset Token type (#122)¶
Since draft-ietf-qlog-quic-events-00:
- Change the data definition language from TypeScript to CDDL (#143)¶
Since draft-marx-qlog-event-definitions-quic-h3-02:
- These changes were done in preparation of the adoption of the drafts by the QUIC working group (#137)¶
- Split QUIC and HTTP/3 events into two separate documents¶
- Moved RawInfo, Importance, Generic events and Simulation events to the main schema document.¶
- Changed to/from value options of the
data_movedevent¶
Since draft-marx-qlog-event-definitions-quic-h3-01:
Major changes:¶
- Moved data_moved from http to transport. Also made the "from" and "to" fields flexible strings instead of an enum (#111,#65)¶
- Moved packet_type fields to PacketHeader. Moved packet_size field out of PacketHeader to RawInfo:length (#40)¶
- Made events that need to log packet_type and packet_number use a header field instead of logging these fields individually¶
- Added support for logging retry, stateless reset and initial tokens (#94,#86,#117)¶
- Moved separate general event categories into a single category "generic" (#47)¶
- Added "transport:connection_closed" event (#43,#85,#78,#49)¶
- Added version_information and alpn_information events (#85,#75,#28)¶
- Added parameters_restored events to help clarify 0-RTT behaviour (#88)¶
Smaller changes:¶
- Merged loss_timer events into one loss_timer_updated event¶
- Field data types are now strongly defined (#10,#39,#36,#115)¶
- Renamed qpack instruction_received and instruction_sent to instruction_created and instruction_parsed (#114)¶
- Updated qpack:dynamic_table_updated.update_type. It now has the value "inserted" instead of "added" (#113)¶
- Updated qpack:dynamic_table_updated. It now has an "owner" field to differentiate encoder vs decoder state (#112)¶
- Removed push_allowed from http:parameters_set (#110)¶
- Removed explicit trigger field indications from events, since this was moved to be a generic property of the "data" field (#80)¶
- Updated transport:connection_id_updated to be more in line with other similar events. Also dropped importance from Core to Base (#45)¶
- Added length property to PaddingFrame (#34)¶
- Added packet_number field to transport:frames_processed (#74)¶
- Added a way to generically log packet header flags (first 8 bits) to PacketHeader¶
- Added additional guidance on which events to log in which situations (#53)¶
- Added "simulation:scenario" event to help indicate simulation details¶
- Added "packets_acked" event (#107)¶
- Added "datagram_ids" to the datagram_X and packet_X events to allow tracking of coalesced QUIC packets (#91)¶
- Extended connection_state_updated with more fine-grained states (#49)¶
Since draft-marx-qlog-event-definitions-quic-h3-00:
- Event and category names are now all lowercase¶
- Added many new events and their definitions¶
- "type" fields have been made more specific (especially important for PacketType fields, which are now called packet_type instead of type)¶
- Events are given an importance indicator (issue #22)¶
- Event names are more consistent and use past tense (issue #21)¶
- Triggers have been redefined as properties of the "data" field and updated for most events (issue #23)¶