Home | History | Annotate | Line # | Download | only in internal
      1 /*
      2  * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved.
      3  *
      4  * Licensed under the Apache License 2.0 (the "License").  You may not use
      5  * this file except in compliance with the License.  You can obtain a copy
      6  * in the file LICENSE in the source distribution or at
      7  * https://www.openssl.org/source/license.html
      8  */
      9 
     10 #ifndef OSSL_QUIC_CFQ_H
     11 #define OSSL_QUIC_CFQ_H
     12 
     13 #include <openssl/ssl.h>
     14 #include "internal/quic_types.h"
     15 #include "internal/quic_predef.h"
     16 
     17 #ifndef OPENSSL_NO_QUIC
     18 
     19 /*
     20  * QUIC Control Frame Queue Item
     21  * =============================
     22  *
     23  * The CFQ item structure has a public and a private part. This structure
     24  * documents the public part.
     25  */
     26 typedef struct quic_cfq_item_st QUIC_CFQ_ITEM;
     27 
     28 struct quic_cfq_item_st {
     29     /*
     30      * These fields are not used by the CFQ, but are a convenience to assist the
     31      * TXPIM in keeping a list of GCR control frames which were sent in a
     32      * packet. They may be used for any purpose.
     33      */
     34     QUIC_CFQ_ITEM *pkt_prev, *pkt_next;
     35 
     36     /* All other fields are private; use ossl_quic_cfq_item_* accessors. */
     37 };
     38 
     39 #define QUIC_CFQ_STATE_NEW 0
     40 #define QUIC_CFQ_STATE_TX 1
     41 
     42 /* If set, do not retransmit on loss */
     43 #define QUIC_CFQ_ITEM_FLAG_UNRELIABLE (1U << 0)
     44 
     45 /* Returns the frame type of a CFQ item. */
     46 uint64_t ossl_quic_cfq_item_get_frame_type(const QUIC_CFQ_ITEM *item);
     47 
     48 /* Returns a pointer to the encoded buffer of a CFQ item. */
     49 const unsigned char *ossl_quic_cfq_item_get_encoded(const QUIC_CFQ_ITEM *item);
     50 
     51 /* Returns the length of the encoded buffer in bytes. */
     52 size_t ossl_quic_cfq_item_get_encoded_len(const QUIC_CFQ_ITEM *item);
     53 
     54 /* Returns the CFQ item state, a QUIC_CFQ_STATE_* value. */
     55 int ossl_quic_cfq_item_get_state(const QUIC_CFQ_ITEM *item);
     56 
     57 /* Returns the PN space for the CFQ item. */
     58 uint32_t ossl_quic_cfq_item_get_pn_space(const QUIC_CFQ_ITEM *item);
     59 
     60 /* Returns 1 if this is an unreliable frame. */
     61 int ossl_quic_cfq_item_is_unreliable(const QUIC_CFQ_ITEM *item);
     62 
     63 /*
     64  * QUIC Control Frame Queue
     65  * ========================
     66  */
     67 
     68 QUIC_CFQ *ossl_quic_cfq_new(void);
     69 void ossl_quic_cfq_free(QUIC_CFQ *cfq);
     70 
     71 /*
     72  * Input Side
     73  * ----------
     74  */
     75 
     76 /*
     77  * Enqueue a frame to the CFQ.
     78  *
     79  * encoded points to the opaque encoded frame.
     80  *
     81  * free_cb is called by the CFQ when the buffer is no longer needed;
     82  * free_cb_arg is an opaque value passed to free_cb.
     83  *
     84  * priority determines the relative ordering of control frames in a packet.
     85  * Lower numerical values for priority mean that a frame should come earlier in
     86  * a packet. pn_space is a QUIC_PN_SPACE_* value.
     87  *
     88  * On success, returns a QUIC_CFQ_ITEM pointer which acts as a handle to
     89  * the queued frame. On failure, returns NULL.
     90  *
     91  * The frame is initially in the TX state, so there is no need to call
     92  * ossl_quic_cfq_mark_tx() immediately after calling this function.
     93  *
     94  * The frame type is duplicated as the frame_type argument here, even though it
     95  * is also encoded into the buffer. This allows the caller to determine the
     96  * frame type if desired without having to decode the frame.
     97  *
     98  * flags is zero or more QUIC_CFQ_ITEM_FLAG values.
     99  */
    100 typedef void(cfq_free_cb)(unsigned char *buf, size_t buf_len, void *arg);
    101 
    102 QUIC_CFQ_ITEM *ossl_quic_cfq_add_frame(QUIC_CFQ *cfq,
    103     uint32_t priority,
    104     uint32_t pn_space,
    105     uint64_t frame_type,
    106     uint32_t flags,
    107     const unsigned char *encoded,
    108     size_t encoded_len,
    109     cfq_free_cb *free_cb,
    110     void *free_cb_arg);
    111 
    112 /*
    113  * Effects an immediate transition of the given CFQ item to the TX state.
    114  */
    115 void ossl_quic_cfq_mark_tx(QUIC_CFQ *cfq, QUIC_CFQ_ITEM *item);
    116 
    117 /*
    118  * Effects an immediate transition of the given CFQ item to the NEW state,
    119  * allowing the frame to be retransmitted. If priority is not UINT32_MAX,
    120  * the priority is changed to the given value.
    121  */
    122 void ossl_quic_cfq_mark_lost(QUIC_CFQ *cfq, QUIC_CFQ_ITEM *item,
    123     uint32_t priority);
    124 
    125 /*
    126  * Releases a CFQ item. The item may be in either state (NEW or TX) prior to the
    127  * call. The QUIC_CFQ_ITEM pointer must not be used following this call.
    128  */
    129 void ossl_quic_cfq_release(QUIC_CFQ *cfq, QUIC_CFQ_ITEM *item);
    130 
    131 /*
    132  * Output Side
    133  * -----------
    134  */
    135 
    136 /*
    137  * Gets the highest priority CFQ item in the given PN space awaiting
    138  * transmission. If there are none, returns NULL.
    139  */
    140 QUIC_CFQ_ITEM *ossl_quic_cfq_get_priority_head(const QUIC_CFQ *cfq,
    141     uint32_t pn_space);
    142 
    143 /*
    144  * Given a CFQ item, gets the next CFQ item awaiting transmission in priority
    145  * order in the given PN space. In other words, given the return value of
    146  * ossl_quic_cfq_get_priority_head(), returns the next-lower priority item.
    147  * Returns NULL if the given item is the last item in priority order.
    148  */
    149 QUIC_CFQ_ITEM *ossl_quic_cfq_item_get_priority_next(const QUIC_CFQ_ITEM *item,
    150     uint32_t pn_space);
    151 
    152 int ossl_quic_cfq_discard_unreliable(QUIC_CFQ *cfq, QUIC_CFQ_ITEM *item);
    153 #endif
    154 
    155 #endif
    156