LCOV - code coverage report
Current view: top level - home/net-next/net/quic - stream.h (source / functions) Hit Total Coverage
Test: quic.info Lines: 4 4 100.0 %
Date: 2025-07-04 13:24:45 Functions: 0 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_DEF_STREAMS        100
      12             : #define QUIC_MAX_STREAMS        4096ULL
      13             : 
      14             : /*
      15             :  * rfc9000#section-2.1:
      16             :  *
      17             :  *   The least significant bit (0x01) of the stream ID identifies the initiator of the stream.
      18             :  *   Client-initiated streams have even-numbered stream IDs (with the bit set to 0), and
      19             :  *   server-initiated streams have odd-numbered stream IDs (with the bit set to 1).
      20             :  *
      21             :  *   The second least significant bit (0x02) of the stream ID distinguishes between bidirectional
      22             :  *   streams (with the bit set to 0) and unidirectional streams (with the bit set to 1).
      23             :  */
      24             : #define QUIC_STREAM_TYPE_BITS   2
      25             : #define QUIC_STREAM_ID_STEP     BIT(QUIC_STREAM_TYPE_BITS)
      26             : 
      27             : #define QUIC_STREAM_TYPE_CLIENT_BIDI    0x00
      28             : #define QUIC_STREAM_TYPE_SERVER_BIDI    0x01
      29             : #define QUIC_STREAM_TYPE_CLIENT_UNI     0x02
      30             : #define QUIC_STREAM_TYPE_SERVER_UNI     0x03
      31             : 
      32             : struct quic_stream {
      33             :         struct hlist_node node;
      34             :         s64 id;                         /* Stream ID as defined in RFC 9000 Section 2.1 */
      35             :         struct {
      36             :                 /* Sending-side stream level flow control */
      37             :                 u64 last_max_bytes;     /* Maximum send offset advertised by peer at last update */
      38             :                 u64 max_bytes;          /* Current maximum offset we are allowed to send to */
      39             :                 u64 bytes;              /* Bytes already sent to peer */
      40             : 
      41             :                 u32 errcode;            /* Application error code to send in RESET_STREAM */
      42             :                 u32 frags;              /* Number of sent STREAM frames not yet acknowledged */
      43             :                 u8 state;               /* Send stream state, per rfc9000#section-3.1 */
      44             : 
      45             :                 u8 data_blocked:1;      /* True if flow control blocks sending more data */
      46             :                 u8 stop_sent:1;         /* True if STOP_SENDING has been sent, not acknowledged */
      47             :                 u8 done:1;              /* True if application indicated end of stream (FIN sent) */
      48             :         } send;
      49             :         struct {
      50             :                 /* Receiving-side stream level flow control */
      51             :                 u64 max_bytes;          /* Maximum offset peer is allowed to send to */
      52             :                 u64 window;             /* Remaining receive window before advertise a new limit */
      53             :                 u64 bytes;              /* Bytes consumed by application from the stream */
      54             : 
      55             :                 u64 highest;            /* Highest received offset */
      56             :                 u64 offset;             /* Offset up to which data is in buffer or consumed */
      57             :                 u64 finalsz;            /* Final size of the stream if FIN received */
      58             : 
      59             :                 u32 frags;              /* Number of received STREAM frames pending reassembly */
      60             :                 u8 state;               /* Receive stream state, per rfc9000#section-3.2 */
      61             :                 u8 done:1;              /* True if FIN received and final size validated */
      62             :         } recv;
      63             : };
      64             : 
      65             : struct quic_stream_table {
      66             :         struct quic_hash_table ht;      /* Hash table storing all active streams */
      67             : 
      68             :         struct {
      69             :                 /* Parameters received from peer, defined in rfc9000#section-18.2 */
      70             :                 u64 max_stream_data_bidi_remote;        /* initial_max_stream_data_bidi_remote */
      71             :                 u64 max_stream_data_bidi_local;         /* initial_max_stream_data_bidi_local */
      72             :                 u64 max_stream_data_uni;                /* initial_max_stream_data_uni */
      73             :                 u64 max_streams_bidi;                   /* initial_max_streams_bidi */
      74             :                 u64 max_streams_uni;                    /* initial_max_streams_uni */
      75             : 
      76             :                 s64 next_bidi_stream_id;        /* Next bidi stream ID to be opened */
      77             :                 s64 next_uni_stream_id;         /* Next uni stream ID to be opened */
      78             :                 s64 max_bidi_stream_id;         /* Highest allowed bidi stream ID */
      79             :                 s64 max_uni_stream_id;          /* Highest allowed uni stream ID */
      80             :                 s64 active_stream_id;           /* Most recently opened stream ID */
      81             : 
      82             :                 u8 bidi_blocked:1;      /* True if STREAMS_BLOCKED_BIDI was sent and not ACKed */
      83             :                 u8 uni_blocked:1;       /* True if STREAMS_BLOCKED_UNI was sent and not ACKed */
      84             :                 u16 streams_bidi;       /* Number of currently active bidi streams */
      85             :                 u16 streams_uni;        /* Number of currently active uni streams */
      86             :         } send;
      87             :         struct {
      88             :                  /* Our advertised limits to the peer, per rfc9000#section-18.2 */
      89             :                 u64 max_stream_data_bidi_remote;        /* initial_max_stream_data_bidi_remote */
      90             :                 u64 max_stream_data_bidi_local;         /* initial_max_stream_data_bidi_local */
      91             :                 u64 max_stream_data_uni;                /* initial_max_stream_data_uni */
      92             :                 u64 max_streams_bidi;                   /* initial_max_streams_bidi */
      93             :                 u64 max_streams_uni;                    /* initial_max_streams_uni */
      94             : 
      95             :                 s64 next_bidi_stream_id;        /* Next expected bidi stream ID from peer */
      96             :                 s64 next_uni_stream_id;         /* Next expected uni stream ID from peer */
      97             :                 s64 max_bidi_stream_id;         /* Current allowed bidi stream ID range */
      98             :                 s64 max_uni_stream_id;          /* Current allowed uni stream ID range */
      99             : 
     100             :                 u8 bidi_pending:1;      /* True if MAX_STREAMS_BIDI needs to be sent */
     101             :                 u8 uni_pending:1;       /* True if MAX_STREAMS_UNI needs to be sent */
     102             :                 u16 streams_bidi;       /* Number of currently open bidi streams */
     103             :                 u16 streams_uni;        /* Number of currently open uni streams */
     104             :         } recv;
     105             : };
     106             : 
     107       11986 : static inline u64 quic_stream_id_to_streams(s64 stream_id)
     108             : {
     109       11986 :         return (u64)(stream_id >> QUIC_STREAM_TYPE_BITS) + 1;
     110             : }
     111             : 
     112        4438 : static inline s64 quic_stream_streams_to_id(u64 streams, u8 type)
     113             : {
     114        4438 :         return (s64)((streams - 1) << QUIC_STREAM_TYPE_BITS) | type;
     115             : }
     116             : 
     117             : struct quic_stream *quic_stream_send_get(struct quic_stream_table *streams, s64 stream_id,
     118             :                                          u32 flags, bool is_serv);
     119             : struct quic_stream *quic_stream_recv_get(struct quic_stream_table *streams, s64 stream_id,
     120             :                                          bool is_serv);
     121             : void quic_stream_send_put(struct quic_stream_table *streams, struct quic_stream *stream,
     122             :                           bool is_serv);
     123             : void quic_stream_recv_put(struct quic_stream_table *streams, struct quic_stream *stream,
     124             :                           bool is_serv);
     125             : 
     126             : bool quic_stream_max_streams_update(struct quic_stream_table *streams, s64 *max_uni, s64 *max_bidi);
     127             : struct quic_stream *quic_stream_find(struct quic_stream_table *streams, s64 stream_id);
     128             : bool quic_stream_id_send_exceeds(struct quic_stream_table *streams, s64 stream_id);
     129             : 
     130             : void quic_stream_get_param(struct quic_stream_table *streams, struct quic_transport_param *p,
     131             :                            bool is_serv);
     132             : void quic_stream_set_param(struct quic_stream_table *streams, struct quic_transport_param *p,
     133             :                            bool is_serv);
     134             : void quic_stream_free(struct quic_stream_table *streams);
     135             : int quic_stream_init(struct quic_stream_table *streams);

Generated by: LCOV version 1.14