wireshark/doc/http3.md

4.8 KiB

Supported features

The HTTP3 dissector is a work in progress.

At the moment, the following aspects of HTTP3 are supported:

  • Diseciton of different HTTP3 stream types
  • Dissection of different HTTP3 frame types
  • Dissection of HTTP header fields
  • Dissection of QPACK instructions

In addition, the dissector suports decoding of the HTTP3 header fields. This ability requires nghttp3 third-party library.

High-level overview

The HTTP3 dissector is invoked by the QUIC dissector.

The essential call tree:

  • dissect_http3 Main entry point. Depending on the stream type, invokes one of the following:
    • dissect_http3_uni_stream Processes unidirectional streams, including the control streams, the QPACK encoder/decoder streams, and the HTTP3 server push streams. NOTE: the HTTP3 server push streams support is rudimental.
      • dissect_http3_qpack_enc Dissects the QPACK encoder stream. If Wireshark was built with the optional nghttp3 library, this function is also responsible on updating the state of the QPACK decoder.
    • dissect_http3_frame Processed HTTP3 frames from the client-initiated bidirectional stream. Determines the frame type, and dispatches the call to one of the sub-dissectors:
      • dissect_http3_data Dissects the HTTP3_DATA frames.
      • dissect_http3_headers Dissects the HTTP3_HEADER frames. If Wireshark was built with the optional nghttp3 library, this function attempts to decode the header fields, using the QPACK decoder.
      • dissect_http3_settings Dissects the HTTP3_SETTINGS frames.

Overview of the HTTP3 header dissection

The QPACK implementation from nghttp3 requires a separate QPACK decoder instance for every HTTP3 connection. The different HTTP3 streams that constitute a single HTTP3 conneciton are sharing the same QPACK decoder instance.

The HTTP3 dissector interacts with the QPACK decoder in 2 ways:

  • On the reception of QPACK encoder data (which is delivered on a dedicated unidirectional stream), the dissector updates the connection's decoder instance.
  • On the reception of compressed HTTP3 headers, the dissector uses the connection's decoder to uncompress the HTTP headers.

If decompression succeeds, the dissector adds tree items to the packet tree. Otherwise, the dissector adds expert info items.

The decompression can fail due to several reasons:

  • If the instruction count required by the compressed HTTP3 headers exceeds the maximal instruction count that the QPACK decoder is aware of, the decoding becomes "blocked". This situation can occure when the QUIC packets that carry the QPACK encoder instructions are dropped/reordered.
  • If the state of the decoder becomes invalid, which may happen when a "garbage" data is received on the QUIC stream.
  • Lastly, the decoding can fail if the underlying QUIC desegmentation is not working correctly.

Overview of HTTP3 data frames dissection

The higher-level dissectors that could use HTTP3 (e.g. WebTransport) need to be able to access the contents of a single HTTP3 stream as a contiguous span of data.

For that purpose, the HTTP3 dissector is defining a custom conversation finder. See functions http3_find_inner_conversation and http3_reset_inner_conversation.

Essential data structures

File-level state

HTTP3_CONN_INFO_MAP

The HTTP3_CONN_INFO_MAP contains session-level information for every HTTP3 connection in a PCAP file. This map is lazily allocated, and is cleared upon exiting the file scope.

HTTP3 header caches

The dissector attempts to conserve memory, by avoding allocating memory for duplicate header names/values. Instead, the dissector keeps the decoded names/values in two caches: HTTP3_HEADER_CACHE and HTTP3_HEADER_DEF_CACHE. The former stores the decoded HTTP3 header values, and the latter stores the decoded HTTP3 header names.

Connection-level state

http3_session_info_t

The http3_session_info_t keeps the state of the QPACK decoder. Every HTTP3 connection corresponds to a single session. In the future, the session may be shared between multiple connections, to support connection migration or multipath HTTP3. At the moment, there are no shared sessions.

Stream-level state

http3_stream_info_t

The http3_stream_info_t keeps the information about the individual HTTP3 streams, as well as mapping to the underlying QUIC streams.

Frame-level state

http3_header_field_t

The http3_header_field_t keeps the information about a single HTTP header. It contains both the encoded and the decoded representation of the header. The actual decoded strings are stored in HTTP3_HEADER_CACHE/HTTP3_HEADER_DEF_CACHE; the individual http3_header_field_t instances contain pointers to the strings.