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