Home | History | Annotate | Line # | Download | only in internal
      1 /*
      2  * Copyright 2022-2025 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_TXP_H
     11 #define OSSL_QUIC_TXP_H
     12 
     13 #include <openssl/ssl.h>
     14 #include "internal/quic_types.h"
     15 #include "internal/quic_predef.h"
     16 #include "internal/quic_record_tx.h"
     17 #include "internal/quic_cfq.h"
     18 #include "internal/quic_txpim.h"
     19 #include "internal/quic_stream.h"
     20 #include "internal/quic_stream_map.h"
     21 #include "internal/quic_fc.h"
     22 #include "internal/bio_addr.h"
     23 #include "internal/time.h"
     24 #include "internal/qlog.h"
     25 
     26 #ifndef OPENSSL_NO_QUIC
     27 
     28 /*
     29  * QUIC TX Packetiser
     30  * ==================
     31  */
     32 typedef struct ossl_quic_tx_packetiser_args_st {
     33     /* Configuration Settings */
     34     QUIC_CONN_ID cur_scid; /* Current Source Connection ID we use. */
     35     QUIC_CONN_ID cur_dcid; /* Current Destination Connection ID we use. */
     36     BIO_ADDR peer; /* Current destination L4 address we use. */
     37     uint32_t ack_delay_exponent; /* ACK delay exponent used when encoding. */
     38 
     39     /* Injected Dependencies */
     40     OSSL_QTX *qtx; /* QUIC Record Layer TX we are using */
     41     QUIC_TXPIM *txpim; /* QUIC TX'd Packet Information Manager */
     42     QUIC_CFQ *cfq; /* QUIC Control Frame Queue */
     43     OSSL_ACKM *ackm; /* QUIC Acknowledgement Manager */
     44     QUIC_STREAM_MAP *qsm; /* QUIC Streams Map */
     45     QUIC_TXFC *conn_txfc; /* QUIC Connection-Level TX Flow Controller */
     46     QUIC_RXFC *conn_rxfc; /* QUIC Connection-Level RX Flow Controller */
     47     QUIC_RXFC *max_streams_bidi_rxfc; /* QUIC RXFC for MAX_STREAMS generation */
     48     QUIC_RXFC *max_streams_uni_rxfc;
     49     const OSSL_CC_METHOD *cc_method; /* QUIC Congestion Controller */
     50     OSSL_CC_DATA *cc_data; /* QUIC Congestion Controller Instance */
     51     OSSL_TIME (*now)(void *arg); /* Callback to get current time. */
     52     void *now_arg;
     53     QLOG *(*get_qlog_cb)(void *arg); /* Optional QLOG retrieval func */
     54     void *get_qlog_cb_arg;
     55     uint32_t protocol_version; /* The protocol version to try negotiating */
     56 
     57     /*
     58      * Injected dependencies - crypto streams.
     59      *
     60      * Note: There is no crypto stream for the 0-RTT EL.
     61      *       crypto[QUIC_PN_SPACE_APP] is the 1-RTT crypto stream.
     62      */
     63     QUIC_SSTREAM *crypto[QUIC_PN_SPACE_NUM];
     64 
     65 } OSSL_QUIC_TX_PACKETISER_ARGS;
     66 
     67 OSSL_QUIC_TX_PACKETISER *ossl_quic_tx_packetiser_new(const OSSL_QUIC_TX_PACKETISER_ARGS *args);
     68 
     69 void ossl_quic_tx_packetiser_set_validated(OSSL_QUIC_TX_PACKETISER *txp);
     70 void ossl_quic_tx_packetiser_add_unvalidated_credit(OSSL_QUIC_TX_PACKETISER *txp,
     71     size_t credit);
     72 void ossl_quic_tx_packetiser_consume_unvalidated_credit(OSSL_QUIC_TX_PACKETISER *txp,
     73     size_t credit);
     74 int ossl_quic_tx_packetiser_check_unvalidated_credit(OSSL_QUIC_TX_PACKETISER *txp,
     75     size_t req_credit);
     76 
     77 typedef void(ossl_quic_initial_token_free_fn)(const unsigned char *buf,
     78     size_t buf_len, void *arg);
     79 
     80 void ossl_quic_tx_packetiser_free(OSSL_QUIC_TX_PACKETISER *txp);
     81 
     82 /*
     83  * When in the closing state we need to maintain a count of received bytes
     84  * so that we can limit the number of close connection frames we send.
     85  * Refer RFC 9000 s. 10.2.1 Closing Connection State.
     86  */
     87 void ossl_quic_tx_packetiser_record_received_closing_bytes(
     88     OSSL_QUIC_TX_PACKETISER *txp, size_t n);
     89 
     90 /*
     91  * Generates a datagram by polling the various ELs to determine if they want to
     92  * generate any frames, and generating a datagram which coalesces packets for
     93  * any ELs which do.
     94  *
     95  * Returns 0 on failure (e.g. allocation error or other errors), 1 otherwise.
     96  *
     97  * *status is filled with status information about the generated packet.
     98  * It is always filled even in case of failure. In particular, packets can be
     99  * sent even if failure is later returned.
    100  * See QUIC_TXP_STATUS for details.
    101  */
    102 typedef struct quic_txp_status_st {
    103     int sent_ack_eliciting; /* Was an ACK-eliciting packet sent? */
    104     int sent_handshake; /* Was a Handshake packet sent? */
    105     size_t sent_pkt; /* Number of packets sent (0 if nothing was sent) */
    106 } QUIC_TXP_STATUS;
    107 
    108 int ossl_quic_tx_packetiser_generate(OSSL_QUIC_TX_PACKETISER *txp,
    109     QUIC_TXP_STATUS *status);
    110 
    111 /*
    112  * Returns a deadline after which a call to ossl_quic_tx_packetiser_generate()
    113  * might succeed even if it did not previously. This may return
    114  * ossl_time_infinite() if there is no such deadline currently applicable. It
    115  * returns ossl_time_zero() if there is (potentially) more data to be generated
    116  * immediately. The value returned is liable to change after any call to
    117  * ossl_quic_tx_packetiser_generate() (or after ACKM or CC state changes). Note
    118  * that ossl_quic_tx_packetiser_generate() can also start to succeed for other
    119  * non-chronological reasons, such as changes to send stream buffers, etc.
    120  */
    121 OSSL_TIME ossl_quic_tx_packetiser_get_deadline(OSSL_QUIC_TX_PACKETISER *txp);
    122 
    123 /*
    124  * Set the token used in Initial packets. The callback is called when the buffer
    125  * is no longer needed; for example, when the TXP is freed or when this function
    126  * is called again with a new buffer. Fails returning 0 if the token is too big
    127  * to ever be reasonably encapsulated in an outgoing packet based on our current
    128  * understanding of our PMTU.
    129  */
    130 int ossl_quic_tx_packetiser_set_initial_token(OSSL_QUIC_TX_PACKETISER *txp,
    131     const unsigned char *token,
    132     size_t token_len,
    133     ossl_quic_initial_token_free_fn *free_cb,
    134     void *free_cb_arg);
    135 
    136 /*
    137  * Set the protocol version used when generating packets.  Currently should
    138  * only ever be set to QUIC_VERSION_1
    139  */
    140 int ossl_quic_tx_packetiser_set_protocol_version(OSSL_QUIC_TX_PACKETISER *txp,
    141     uint32_t protocol_version);
    142 
    143 /* Change the DCID the TXP uses to send outgoing packets. */
    144 int ossl_quic_tx_packetiser_set_cur_dcid(OSSL_QUIC_TX_PACKETISER *txp,
    145     const QUIC_CONN_ID *dcid);
    146 
    147 /* Change the SCID the TXP uses to send outgoing (long) packets. */
    148 int ossl_quic_tx_packetiser_set_cur_scid(OSSL_QUIC_TX_PACKETISER *txp,
    149     const QUIC_CONN_ID *scid);
    150 
    151 /*
    152  * Change the destination L4 address the TXP uses to send datagrams. Specify
    153  * NULL (or AF_UNSPEC) to disable use of addressed mode.
    154  */
    155 int ossl_quic_tx_packetiser_set_peer(OSSL_QUIC_TX_PACKETISER *txp,
    156     const BIO_ADDR *peer);
    157 
    158 /*
    159  * Change the QLOG instance retrieval function in use after instantiation.
    160  */
    161 void ossl_quic_tx_packetiser_set_qlog_cb(OSSL_QUIC_TX_PACKETISER *txp,
    162     QLOG *(*get_qlog_cb)(void *arg),
    163     void *get_qlog_cb_arg);
    164 
    165 /*
    166  * Inform the TX packetiser that an EL has been discarded. Idempotent.
    167  *
    168  * This does not inform the QTX as well; the caller must also inform the QTX.
    169  *
    170  * The TXP will no longer reference the crypto[enc_level] QUIC_SSTREAM which was
    171  * provided in the TXP arguments. However, it is the callers responsibility to
    172  * free that QUIC_SSTREAM if desired.
    173  */
    174 int ossl_quic_tx_packetiser_discard_enc_level(OSSL_QUIC_TX_PACKETISER *txp,
    175     uint32_t enc_level);
    176 
    177 /*
    178  * Informs the TX packetiser that the handshake is complete. The TX packetiser
    179  * will not send 1-RTT application data until the handshake is complete,
    180  * as the authenticity of the peer is not confirmed until the handshake
    181  * complete event occurs.
    182  */
    183 void ossl_quic_tx_packetiser_notify_handshake_complete(OSSL_QUIC_TX_PACKETISER *txp);
    184 
    185 /* Asks the TXP to generate a HANDSHAKE_DONE frame in the next 1-RTT packet. */
    186 void ossl_quic_tx_packetiser_schedule_handshake_done(OSSL_QUIC_TX_PACKETISER *txp);
    187 
    188 /* Asks the TXP to ensure the next packet in the given PN space is ACK-eliciting. */
    189 void ossl_quic_tx_packetiser_schedule_ack_eliciting(OSSL_QUIC_TX_PACKETISER *txp,
    190     uint32_t pn_space);
    191 
    192 /*
    193  * Asks the TXP to ensure an ACK is put in the next packet in the given PN
    194  * space.
    195  */
    196 void ossl_quic_tx_packetiser_schedule_ack(OSSL_QUIC_TX_PACKETISER *txp,
    197     uint32_t pn_space);
    198 
    199 /*
    200  * Schedules a connection close. *f and f->reason are copied. This operation is
    201  * irreversible and causes all further packets generated by the TXP to contain a
    202  * CONNECTION_CLOSE frame. This function fails if it has already been called
    203  * successfully; the information in *f cannot be changed after the first
    204  * successful call to this function.
    205  */
    206 int ossl_quic_tx_packetiser_schedule_conn_close(OSSL_QUIC_TX_PACKETISER *txp,
    207     const OSSL_QUIC_FRAME_CONN_CLOSE *f);
    208 
    209 /* Setters for the msg_callback and msg_callback_arg */
    210 void ossl_quic_tx_packetiser_set_msg_callback(OSSL_QUIC_TX_PACKETISER *txp,
    211     ossl_msg_cb msg_callback,
    212     SSL *msg_callback_ssl);
    213 void ossl_quic_tx_packetiser_set_msg_callback_arg(OSSL_QUIC_TX_PACKETISER *txp,
    214     void *msg_callback_arg);
    215 
    216 /*
    217  * Determines the next PN which will be used for a given PN space.
    218  */
    219 QUIC_PN ossl_quic_tx_packetiser_get_next_pn(OSSL_QUIC_TX_PACKETISER *txp,
    220     uint32_t pn_space);
    221 
    222 /*
    223  * Sets a callback which is called whenever TXP sends an ACK frame. The callee
    224  * must not modify the ACK frame data. Can be used to snoop on PNs being ACKed.
    225  */
    226 void ossl_quic_tx_packetiser_set_ack_tx_cb(OSSL_QUIC_TX_PACKETISER *txp,
    227     void (*cb)(const OSSL_QUIC_FRAME_ACK *ack,
    228         uint32_t pn_space,
    229         void *arg),
    230     void *cb_arg);
    231 
    232 #endif
    233 
    234 #endif
    235