LCOV - code coverage report
Current view: top level - home/net-next/net/quic - frame.h (source / functions) Hit Total Coverage
Test: quic.info Lines: 15 16 93.8 %
Date: 2025-07-04 13:24:45 Functions: 1 1 100.0 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: GPL-2.0-or-later */
       2             : /* QUIC kernel implementation
       3             :  * (C) Copyright Red Hat Corp. 2023
       4             :  *
       5             :  * This file is part of the QUIC kernel implementation
       6             :  *
       7             :  * Written or modified by:
       8             :  *    Xin Long <lucien.xin@gmail.com>
       9             :  */
      10             : 
      11             : #define QUIC_CLOSE_PHRASE_MAX_LEN       80
      12             : 
      13             : #define QUIC_TOKEN_MAX_LEN              120
      14             : 
      15             : #define QUIC_TICKET_MIN_LEN             64
      16             : #define QUIC_TICKET_MAX_LEN             4096
      17             : 
      18             : #define QUIC_FRAME_BUF_SMALL            20
      19             : #define QUIC_FRAME_BUF_LARGE            100
      20             : 
      21             : enum {
      22             :         QUIC_FRAME_PADDING = 0x00,
      23             :         QUIC_FRAME_PING = 0x01,
      24             :         QUIC_FRAME_ACK = 0x02,
      25             :         QUIC_FRAME_ACK_ECN = 0x03,
      26             :         QUIC_FRAME_RESET_STREAM = 0x04,
      27             :         QUIC_FRAME_STOP_SENDING = 0x05,
      28             :         QUIC_FRAME_CRYPTO = 0x06,
      29             :         QUIC_FRAME_NEW_TOKEN = 0x07,
      30             :         QUIC_FRAME_STREAM = 0x08,
      31             :         QUIC_FRAME_MAX_DATA = 0x10,
      32             :         QUIC_FRAME_MAX_STREAM_DATA = 0x11,
      33             :         QUIC_FRAME_MAX_STREAMS_BIDI = 0x12,
      34             :         QUIC_FRAME_MAX_STREAMS_UNI = 0x13,
      35             :         QUIC_FRAME_DATA_BLOCKED = 0x14,
      36             :         QUIC_FRAME_STREAM_DATA_BLOCKED = 0x15,
      37             :         QUIC_FRAME_STREAMS_BLOCKED_BIDI = 0x16,
      38             :         QUIC_FRAME_STREAMS_BLOCKED_UNI = 0x17,
      39             :         QUIC_FRAME_NEW_CONNECTION_ID = 0x18,
      40             :         QUIC_FRAME_RETIRE_CONNECTION_ID = 0x19,
      41             :         QUIC_FRAME_PATH_CHALLENGE = 0x1a,
      42             :         QUIC_FRAME_PATH_RESPONSE = 0x1b,
      43             :         QUIC_FRAME_CONNECTION_CLOSE = 0x1c,
      44             :         QUIC_FRAME_CONNECTION_CLOSE_APP = 0x1d,
      45             :         QUIC_FRAME_HANDSHAKE_DONE = 0x1e,
      46             :         QUIC_FRAME_DATAGRAM = 0x30, /* RFC 9221 */
      47             :         QUIC_FRAME_DATAGRAM_LEN = 0x31,
      48             :         QUIC_FRAME_MAX = QUIC_FRAME_DATAGRAM_LEN,
      49             : };
      50             : 
      51             : enum {
      52             :         QUIC_TRANSPORT_PARAM_ORIGINAL_DESTINATION_CONNECTION_ID = 0x0000,
      53             :         QUIC_TRANSPORT_PARAM_MAX_IDLE_TIMEOUT = 0x0001,
      54             :         QUIC_TRANSPORT_PARAM_STATELESS_RESET_TOKEN = 0x0002,
      55             :         QUIC_TRANSPORT_PARAM_MAX_UDP_PAYLOAD_SIZE = 0x0003,
      56             :         QUIC_TRANSPORT_PARAM_INITIAL_MAX_DATA = 0x0004,
      57             :         QUIC_TRANSPORT_PARAM_INITIAL_MAX_STREAM_DATA_BIDI_LOCAL = 0x0005,
      58             :         QUIC_TRANSPORT_PARAM_INITIAL_MAX_STREAM_DATA_BIDI_REMOTE = 0x0006,
      59             :         QUIC_TRANSPORT_PARAM_INITIAL_MAX_STREAM_DATA_UNI = 0x0007,
      60             :         QUIC_TRANSPORT_PARAM_INITIAL_MAX_STREAMS_BIDI = 0x0008,
      61             :         QUIC_TRANSPORT_PARAM_INITIAL_MAX_STREAMS_UNI = 0x0009,
      62             :         QUIC_TRANSPORT_PARAM_ACK_DELAY_EXPONENT = 0x000a,
      63             :         QUIC_TRANSPORT_PARAM_MAX_ACK_DELAY = 0x000b,
      64             :         QUIC_TRANSPORT_PARAM_DISABLE_ACTIVE_MIGRATION = 0x000c,
      65             :         QUIC_TRANSPORT_PARAM_PREFERRED_ADDRESS = 0x000d,
      66             :         QUIC_TRANSPORT_PARAM_ACTIVE_CONNECTION_ID_LIMIT = 0x000e,
      67             :         QUIC_TRANSPORT_PARAM_INITIAL_SOURCE_CONNECTION_ID = 0x000f,
      68             :         QUIC_TRANSPORT_PARAM_RETRY_SOURCE_CONNECTION_ID = 0x0010,
      69             :         QUIC_TRANSPORT_PARAM_MAX_DATAGRAM_FRAME_SIZE = 0x0020,
      70             :         QUIC_TRANSPORT_PARAM_GREASE_QUIC_BIT = 0x2ab2,
      71             :         QUIC_TRANSPORT_PARAM_VERSION_INFORMATION = 0x11,
      72             :         QUIC_TRANSPORT_PARAM_DISABLE_1RTT_ENCRYPTION = 0xbaad,
      73             : };
      74             : 
      75             : /* Arguments passed to create a STREAM frame */
      76             : struct quic_msginfo {
      77             :         struct quic_stream *stream;     /* The QUIC stream associated with this frame */
      78             :         struct iov_iter *msg;           /* Iterator over message data to send */
      79             :         u32 flags;                      /* Flags controlling stream frame creation */
      80             :         u8 level;                       /* Encryption level for this frame */
      81             : };
      82             : 
      83             : /* Arguments passed to create a PING frame */
      84             : struct quic_probeinfo {
      85             :         u16 size;       /* Size of the PING packet */
      86             :         u8 level;       /* Encryption level for this frame */
      87             : };
      88             : 
      89             : /* Operations for creating, processing, and acknowledging QUIC frames */
      90             : struct quic_frame_ops {
      91             :         struct quic_frame *(*frame_create)(struct sock *sk, void *data, u8 type);
      92             :         int (*frame_process)(struct sock *sk, struct quic_frame *frame, u8 type);
      93             :         void (*frame_ack)(struct sock *sk, struct quic_frame *frame);
      94             :         u8 ack_eliciting;
      95             : };
      96             : 
      97             : /* Fragment of data appended to a STREAM frame */
      98             : struct quic_frame_frag {
      99             :         struct quic_frame_frag *next;   /* Next fragment in the linked list */
     100             :         u16 size;                       /* Size of this data fragment */
     101             :         u8 data[];                      /* Flexible array member holding fragment data */
     102             : };
     103             : 
     104             : struct quic_frame {
     105             :         union {
     106             :                 struct quic_frame_frag *flist;  /* For TX: linked list of appended data fragments */
     107             :                 struct sk_buff *skb;            /* For RX: skb containing the raw frame data */
     108             :         };
     109             :         struct quic_stream *stream;             /* Stream related to this frame, NULL if none */
     110             :         struct list_head list;                  /* Linked list node for queuing frames */
     111             :         s64 offset;             /* Stream offset, crypto data offset, or first pkt number */
     112             :         u8  *data;              /* Pointer to the actual frame data buffer */
     113             : 
     114             :         refcount_t refcnt;
     115             :         u16 errcode;            /* Error code set during frame processing */
     116             :         u8  level;              /* Packet number space: Initial, Handshake, or App */
     117             :         u8  type;               /* Frame type identifier */
     118             :         u16 bytes;              /* Number of user data bytes */
     119             :         u16 size;               /* Allocated data buffer size */
     120             :         u16 len;                /* Total frame length including appended fragments */
     121             : 
     122             :         u8  ack_eliciting:1;    /* Frame requires acknowledgment */
     123             :         u8  transmitted:1;      /* Frame is in the transmitted queue */
     124             :         u8  stream_fin:1;       /* Frame includes FIN flag for stream */
     125             :         u8  nodelay:1;          /* Frame bypasses Nagle's algorithm for sending */
     126             :         u8  padding:1;          /* Padding is needed after this frame */
     127             :         u8  dgram:1;            /* Frame represents a datagram message (RX only) */
     128             :         u8  event:1;            /* Frame represents an event (RX only) */
     129             :         u8  path:1;             /* Path index used to send this frame */
     130             : };
     131             : 
     132             : static inline bool quic_frame_new_conn_id(u8 type)
     133             : {
     134             :         return type == QUIC_FRAME_NEW_CONNECTION_ID;
     135             : }
     136             : 
     137       14129 : static inline bool quic_frame_dgram(u8 type)
     138             : {
     139       14129 :         return type == QUIC_FRAME_DATAGRAM || type == QUIC_FRAME_DATAGRAM_LEN;
     140             : }
     141             : 
     142     6577785 : static inline bool quic_frame_stream(u8 type)
     143             : {
     144     6577785 :         return type >= QUIC_FRAME_STREAM && type < QUIC_FRAME_MAX_DATA;
     145             : }
     146             : 
     147     6976494 : static inline bool quic_frame_sack(u8 type)
     148             : {
     149     6976494 :         return type == QUIC_FRAME_ACK || type == QUIC_FRAME_ACK_ECN;
     150             : }
     151             : 
     152             : static inline bool quic_frame_ping(u8 type)
     153             : {
     154             :         return type == QUIC_FRAME_PING;
     155             : }
     156             : 
     157             : /* Check if a given frame type is valid for the specified encryption level,
     158             :  * based on the Frame Types table from rfc9000#section-12.4.
     159             :  *
     160             :  * Returns 0 if valid, 1 otherwise.
     161             :  */
     162     6972596 : static inline int quic_frame_level_check(u8 level, u8 type)
     163             : {
     164     6972596 :         if (level == QUIC_CRYPTO_APP)
     165             :                 return 0;
     166             : 
     167        6270 :         if (level == QUIC_CRYPTO_EARLY) {
     168         381 :                 if (type == QUIC_FRAME_ACK || type == QUIC_FRAME_ACK_ECN ||
     169         381 :                     type == QUIC_FRAME_CRYPTO || type == QUIC_FRAME_HANDSHAKE_DONE ||
     170             :                     type == QUIC_FRAME_NEW_TOKEN || type == QUIC_FRAME_PATH_RESPONSE ||
     171             :                     type == QUIC_FRAME_RETIRE_CONNECTION_ID)
     172             :                         return 1;
     173         381 :                 return 0;
     174             :         }
     175             : 
     176        5889 :         if (type != QUIC_FRAME_ACK && type != QUIC_FRAME_ACK_ECN &&
     177        5889 :             type != QUIC_FRAME_PADDING && type != QUIC_FRAME_PING &&
     178        3333 :             type != QUIC_FRAME_CRYPTO && type != QUIC_FRAME_CONNECTION_CLOSE)
     179           0 :                 return 1;
     180             :         return 0;
     181             : }
     182             : 
     183             : int quic_frame_build_transport_params_ext(struct sock *sk, struct quic_transport_param *params,
     184             :                                           u8 *data, u32 *len);
     185             : int quic_frame_parse_transport_params_ext(struct sock *sk, struct quic_transport_param *params,
     186             :                                           u8 *data, u32 len);
     187             : int quic_frame_stream_append(struct sock *sk, struct quic_frame *frame,
     188             :                              struct quic_msginfo *info, u8 pack);
     189             : 
     190             : struct quic_frame *quic_frame_alloc(u32 size, u8 *data, gfp_t gfp);
     191             : struct quic_frame *quic_frame_get(struct quic_frame *frame);
     192             : void quic_frame_put(struct quic_frame *frame);
     193             : 
     194             : struct quic_frame *quic_frame_create(struct sock *sk, u8 type, void *data);
     195             : int quic_frame_process(struct sock *sk, struct quic_frame *frame);
     196             : void quic_frame_ack(struct sock *sk, struct quic_frame *frame);

Generated by: LCOV version 1.14