QUIC | R. Marx |
Internet-Draft | Hasselt University |
Intended status: Standards Track | July 03, 2019 |
Expires: January 4, 2020 |
QUIC and HTTP/3 event definitions for qlog
draft-marx-qlog-event-definitions-quic-h3-00
This document describes concrete qlog event definitions and their metadata for QUIC and HTTP/3-related events. These events can then be embedded in the higher level schema defined in draft-marx-quic-logging-main-schema-latest.
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 January 4, 2020.
Copyright (c) 2019 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 Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License.
Feedback and discussion welcome at https://github.com/quiclog/internet-drafts
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in [RFC2119].
This document describes the values of the qlog CATEGORY, EVENT_TYPE, TRIGGER and DATA fields and their semantics for the QUIC and HTTP/3 protocols. The definitions included in this file are assumed to be used in qlog’s “trace” containers, where the trace’s “protocol_type” field MUST be set to “QUIC_HTTP3”.
This document is based on draft-20 of the QUIC and HTTP/3 I-Ds QUIC-TRANSPORT.
This document uses the “TypeScript” language to describe its schema in. We use TypeScript because it is less verbose than JSON-schema and almost as expressive. It also makes it easier to include these definitions directly into a web-based tool. The main conventions a reader should be aware of are:
TODO: specify how this works with happy eyeballs
TODO: mention that CIDs can be logged in hex
e.g., PATH_UPDATE
TODO: read up on the draft how migration works and whether to best fit this here or in TRANSPORT
{ mask, error }
{ key, error }
{ type = "Initial | handshake | 1RTT", value }
{ value } # initial encryption level is implicitly deleted
Triggers:
Data:
{ packet_type:PacketType, header:PacketHeader, frames:Array<QuicFrame> }
Notes:
Triggers:
Data:
{ packet_type:PacketType, header:PacketHeader, frames:Array<QuicFrame> }
Notes:
Can be due to several reasons * TODO: How does this relate to HEADER_DECRYPT_ERROR and PACKET_DECRYPT_ERROR? * TODO: if a packet is dropped because we don’t have a connection for it, how can we add it to a given trace in the overall qlog file? Need a sort of catch-call trace in each file? * TODO: differentiate between DATAGRAM_DROPPED and PACKET_DROPPED? Same with PACKET_RECEIVED and DATAGRAM_RECEIVED?
TODO: maybe name VERSION_SELECTED ?
TODO: should this be in HTTP?
{ alpn:string }
{ old:string, new:string }
Possible values:
TODO: do we need all of these? How do implementations actually handle this in practice?
TODO: check state machine in QUIC transport draft
{ old:string, new:string }
{ cwnd?: number; bytes_in_flight?:number; min_rtt?:number; smoothed_rtt?:number; latest_rtt?:number; max_ack_delay?:number; rtt_variance?:number; ssthresh?:number; pacing_rate?:number; }
This event SHOULD group all possible metric updates that happen at or around the same time in a single event (e.g., if min_rtt and smoothed_rtt change at the same time, they should be bundled in a single METRIC_UPDATE entry, rather than split out into two). Consequently, a METRIC_UPDATE is only guaranteed to contain at least one of the listed metrics.
Note: to make logging easier, implementations MAY log values even if they are the same as previously reported values (e.g., two subsequent METRIC_UPDATE entries can both report the exact same value for min_rtt). However, applications SHOULD try to log only actual updates to values.
Data:
{ packet_number:string }
Triggers:
TODO: must this be a separate event? can’t we get this from logged ACK frames? (however, explicitly indicating this and logging it in the ack handler is a better signal that the ACK actually had the intended effect than just logging its receipt)
TODO: only if a packet is retransmit in-full, which many stacks don’t do. Need something more flexible.
TBD
TBD
[QUIC-HTTP] | Bishop, M., "Hypertext Transfer Protocol Version 3 (HTTP/3)", Internet-Draft draft-ietf-quic-http-20, April 2019. |
[QUIC-TRANSPORT] | Iyengar, J. and M. Thomson, "QUIC: A UDP-Based Multiplexed and Secure Transport", Internet-Draft draft-ietf-quic-transport-20, April 2019. |
[RFC2119] | Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997. |
enum PacketType { INITIAL, HANDSHAKE, ZERORTT = "0RTT", ONERTT = "1RTT", RETRY, VERSION_NEGOTIATION, UNKOWN }
class PacketHeader { packet_number: string; packet_size?: number; payload_length?: number; // only if present in the header // if correctly using NEW_CONNECTION_ID events, // dcid can be skipped for 1RTT packets version?: string; scil?: string; dcil?: string; scid?: string; dcid?: string; // Note: short vs long header is implicit through PacketType }
type QuicFrame = AckFrame | StreamFrame | ResetStreamFrame | ConnetionCloseFrame | MaxDataFrame | MaxStreamDataFrame | UnknownFrame;
class AckFrame{ frame_type:string = "ACK"; ack_delay:string; // first number is "from": lowest packet number in interval // second number is "to": up to and including // highest packet number in interval // e.g., looks like [[1,2],[4,5]] acked_ranges:Array<[number, number]>; ect1?:string; ect0?:string; ce?:string; }
Note: the packet ranges in AckFrame.acked_ranges do not necessarily have to be ordered (e.g., [[5,9],[1,4]] is a valid value).
Note: the two numbers in the packet range can be the same (e.g., [120,120] means that packet with number 120 was ACKed). TODO: maybe make this into just [120]?
class StreamFrame{ frame_type:string = "STREAM"; id:string; // These two MUST always be set // If not present in the Frame type, log their default values offset:string; length:string; // this MAY be set any time, but MUST only be set if the value is "true" // if absent, the value MUST be assumed to be "false" fin:boolean; }
class ResetStreamFrame{ frame_type:string = "RESET_STREAM"; id:string; error_code:ApplicationError | number; final_offset:string; }
type ErrorSpace = "TRANSPORT" | "APPLICATION"; class ConnectionCloseFrame{ frame_type:string = "CONNECTION_CLOSE"; error_space:ErrorSpace; error_code:TransportError | ApplicationError | number; reason:string; trigger_frame_type?:number; // TODO: should be more defined, but we don't have a FrameType enum atm... }
class MaxDataFrame{ stream_type:string = "MAX_DATA"; maximum:string; }
class MaxStreamDataFrame{ stream_type:string = "MAX_STREAM_DATA"; id:string; maximum:string; }
class UnknownFrame{ frame_type:string = "UNKNOWN"; }
enum TransportError { NO_ERROR, INTERNAL_ERROR, SERVER_BUSY, APPLICATION_FLOW_CONTROL_ERROR, // 0x3 STREAM_FLOW_CONTROL_ERROR, // 0x4 STREAM_STATE_ERROR, FINAL_SIZE_ERROR, FRAME_ENCODING_ERROR, TRANSPORT_PARAMETER_ERROR, PROTOCOL_VIOLATION, INVALID_MIGRATION, CRYPTO_ERROR }
enum ApplicationError{ HTTP_NO_ERROR, HTTP_WRONG_SETTING_DIRECTION, HTTP_PUSH_REFUSED, HTTP_INTERNAL_ERROR, HTTP_PUSH_ALREADY_IN_CACHE, HTTP_REQUEST_CANCELLED, HTTP_INCOMPLETE_REQUEST, HTTP_CONNECT_ERROR, HTTP_EXCESSIVE_LOAD, HTTP_VERSION_FALLBACK, HTTP_WRONG_STREAM, HTTP_LIMIT_EXCEEDED, HTTP_DUPLICATE_PUSH, HTTP_UNKNOWN_STREAM_TYPE, HTTP_WRONG_STREAM_COUNT, HTTP_CLOSED_CRITICAL_STREAM, HTTP_WRONG_STREAM_DIRECTION, HTTP_EARLY_RESPONSE, HTTP_MISSING_SETTINGS, HTTP_UNEXPECTED_FRAME, HTTP_REQUEST_REJECTED, HTTP_GENERAL_PROTOCOL_ERROR, HTTP_MALFORMED_FRAME }
TODO: HTTP_MALFORMED_FRAME is not a single value, but can include the frame type in its definition. This means we need more flexible error logging. Best to wait until h3-draft-21, which will include substantial changes to error codes.
TBD
Thanks to Jana Iyengar, Brian Trammell, Dmitri Tikhonov, Stephen Petrides, Jari Arkko, Marcus Ihlar, Victor Vasiliev, Mirja Kühlewind and Lucas Pardue for their feedback and suggestions.