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);