1 | /*
|
---|
2 | * Copyright 2022-2024 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 |
|
---|
56 | /*
|
---|
57 | * Injected dependencies - crypto streams.
|
---|
58 | *
|
---|
59 | * Note: There is no crypto stream for the 0-RTT EL.
|
---|
60 | * crypto[QUIC_PN_SPACE_APP] is the 1-RTT crypto stream.
|
---|
61 | */
|
---|
62 | QUIC_SSTREAM *crypto[QUIC_PN_SPACE_NUM];
|
---|
63 |
|
---|
64 | } OSSL_QUIC_TX_PACKETISER_ARGS;
|
---|
65 |
|
---|
66 | OSSL_QUIC_TX_PACKETISER *ossl_quic_tx_packetiser_new(const OSSL_QUIC_TX_PACKETISER_ARGS *args);
|
---|
67 |
|
---|
68 | typedef void (ossl_quic_initial_token_free_fn)(const unsigned char *buf,
|
---|
69 | size_t buf_len, void *arg);
|
---|
70 |
|
---|
71 | void ossl_quic_tx_packetiser_free(OSSL_QUIC_TX_PACKETISER *txp);
|
---|
72 |
|
---|
73 | /*
|
---|
74 | * When in the closing state we need to maintain a count of received bytes
|
---|
75 | * so that we can limit the number of close connection frames we send.
|
---|
76 | * Refer RFC 9000 s. 10.2.1 Closing Connection State.
|
---|
77 | */
|
---|
78 | void ossl_quic_tx_packetiser_record_received_closing_bytes(
|
---|
79 | OSSL_QUIC_TX_PACKETISER *txp, size_t n);
|
---|
80 |
|
---|
81 | /*
|
---|
82 | * Generates a datagram by polling the various ELs to determine if they want to
|
---|
83 | * generate any frames, and generating a datagram which coalesces packets for
|
---|
84 | * any ELs which do.
|
---|
85 | *
|
---|
86 | * Returns 0 on failure (e.g. allocation error or other errors), 1 otherwise.
|
---|
87 | *
|
---|
88 | * *status is filled with status information about the generated packet.
|
---|
89 | * It is always filled even in case of failure. In particular, packets can be
|
---|
90 | * sent even if failure is later returned.
|
---|
91 | * See QUIC_TXP_STATUS for details.
|
---|
92 | */
|
---|
93 | typedef struct quic_txp_status_st {
|
---|
94 | int sent_ack_eliciting; /* Was an ACK-eliciting packet sent? */
|
---|
95 | int sent_handshake; /* Was a Handshake packet sent? */
|
---|
96 | size_t sent_pkt; /* Number of packets sent (0 if nothing was sent) */
|
---|
97 | } QUIC_TXP_STATUS;
|
---|
98 |
|
---|
99 | int ossl_quic_tx_packetiser_generate(OSSL_QUIC_TX_PACKETISER *txp,
|
---|
100 | QUIC_TXP_STATUS *status);
|
---|
101 |
|
---|
102 | /*
|
---|
103 | * Returns a deadline after which a call to ossl_quic_tx_packetiser_generate()
|
---|
104 | * might succeed even if it did not previously. This may return
|
---|
105 | * ossl_time_infinite() if there is no such deadline currently applicable. It
|
---|
106 | * returns ossl_time_zero() if there is (potentially) more data to be generated
|
---|
107 | * immediately. The value returned is liable to change after any call to
|
---|
108 | * ossl_quic_tx_packetiser_generate() (or after ACKM or CC state changes). Note
|
---|
109 | * that ossl_quic_tx_packetiser_generate() can also start to succeed for other
|
---|
110 | * non-chronological reasons, such as changes to send stream buffers, etc.
|
---|
111 | */
|
---|
112 | OSSL_TIME ossl_quic_tx_packetiser_get_deadline(OSSL_QUIC_TX_PACKETISER *txp);
|
---|
113 |
|
---|
114 | /*
|
---|
115 | * Set the token used in Initial packets. The callback is called when the buffer
|
---|
116 | * is no longer needed; for example, when the TXP is freed or when this function
|
---|
117 | * is called again with a new buffer. Fails returning 0 if the token is too big
|
---|
118 | * to ever be reasonably encapsulated in an outgoing packet based on our current
|
---|
119 | * understanding of our PMTU.
|
---|
120 | */
|
---|
121 | int ossl_quic_tx_packetiser_set_initial_token(OSSL_QUIC_TX_PACKETISER *txp,
|
---|
122 | const unsigned char *token,
|
---|
123 | size_t token_len,
|
---|
124 | ossl_quic_initial_token_free_fn *free_cb,
|
---|
125 | void *free_cb_arg);
|
---|
126 |
|
---|
127 | /* Change the DCID the TXP uses to send outgoing packets. */
|
---|
128 | int ossl_quic_tx_packetiser_set_cur_dcid(OSSL_QUIC_TX_PACKETISER *txp,
|
---|
129 | const QUIC_CONN_ID *dcid);
|
---|
130 |
|
---|
131 | /* Change the SCID the TXP uses to send outgoing (long) packets. */
|
---|
132 | int ossl_quic_tx_packetiser_set_cur_scid(OSSL_QUIC_TX_PACKETISER *txp,
|
---|
133 | const QUIC_CONN_ID *scid);
|
---|
134 |
|
---|
135 | /*
|
---|
136 | * Change the destination L4 address the TXP uses to send datagrams. Specify
|
---|
137 | * NULL (or AF_UNSPEC) to disable use of addressed mode.
|
---|
138 | */
|
---|
139 | int ossl_quic_tx_packetiser_set_peer(OSSL_QUIC_TX_PACKETISER *txp,
|
---|
140 | const BIO_ADDR *peer);
|
---|
141 |
|
---|
142 | /*
|
---|
143 | * Change the QLOG instance retrieval function in use after instantiation.
|
---|
144 | */
|
---|
145 | void ossl_quic_tx_packetiser_set_qlog_cb(OSSL_QUIC_TX_PACKETISER *txp,
|
---|
146 | QLOG *(*get_qlog_cb)(void *arg),
|
---|
147 | void *get_qlog_cb_arg);
|
---|
148 |
|
---|
149 | /*
|
---|
150 | * Inform the TX packetiser that an EL has been discarded. Idempotent.
|
---|
151 | *
|
---|
152 | * This does not inform the QTX as well; the caller must also inform the QTX.
|
---|
153 | *
|
---|
154 | * The TXP will no longer reference the crypto[enc_level] QUIC_SSTREAM which was
|
---|
155 | * provided in the TXP arguments. However, it is the callers responsibility to
|
---|
156 | * free that QUIC_SSTREAM if desired.
|
---|
157 | */
|
---|
158 | int ossl_quic_tx_packetiser_discard_enc_level(OSSL_QUIC_TX_PACKETISER *txp,
|
---|
159 | uint32_t enc_level);
|
---|
160 |
|
---|
161 | /*
|
---|
162 | * Informs the TX packetiser that the handshake is complete. The TX packetiser
|
---|
163 | * will not send 1-RTT application data until the handshake is complete,
|
---|
164 | * as the authenticity of the peer is not confirmed until the handshake
|
---|
165 | * complete event occurs.
|
---|
166 | */
|
---|
167 | void ossl_quic_tx_packetiser_notify_handshake_complete(OSSL_QUIC_TX_PACKETISER *txp);
|
---|
168 |
|
---|
169 | /* Asks the TXP to generate a HANDSHAKE_DONE frame in the next 1-RTT packet. */
|
---|
170 | void ossl_quic_tx_packetiser_schedule_handshake_done(OSSL_QUIC_TX_PACKETISER *txp);
|
---|
171 |
|
---|
172 | /* Asks the TXP to ensure the next packet in the given PN space is ACK-eliciting. */
|
---|
173 | void ossl_quic_tx_packetiser_schedule_ack_eliciting(OSSL_QUIC_TX_PACKETISER *txp,
|
---|
174 | uint32_t pn_space);
|
---|
175 |
|
---|
176 | /*
|
---|
177 | * Asks the TXP to ensure an ACK is put in the next packet in the given PN
|
---|
178 | * space.
|
---|
179 | */
|
---|
180 | void ossl_quic_tx_packetiser_schedule_ack(OSSL_QUIC_TX_PACKETISER *txp,
|
---|
181 | uint32_t pn_space);
|
---|
182 |
|
---|
183 | /*
|
---|
184 | * Schedules a connection close. *f and f->reason are copied. This operation is
|
---|
185 | * irreversible and causes all further packets generated by the TXP to contain a
|
---|
186 | * CONNECTION_CLOSE frame. This function fails if it has already been called
|
---|
187 | * successfully; the information in *f cannot be changed after the first
|
---|
188 | * successful call to this function.
|
---|
189 | */
|
---|
190 | int ossl_quic_tx_packetiser_schedule_conn_close(OSSL_QUIC_TX_PACKETISER *txp,
|
---|
191 | const OSSL_QUIC_FRAME_CONN_CLOSE *f);
|
---|
192 |
|
---|
193 | /* Setters for the msg_callback and msg_callback_arg */
|
---|
194 | void ossl_quic_tx_packetiser_set_msg_callback(OSSL_QUIC_TX_PACKETISER *txp,
|
---|
195 | ossl_msg_cb msg_callback,
|
---|
196 | SSL *msg_callback_ssl);
|
---|
197 | void ossl_quic_tx_packetiser_set_msg_callback_arg(OSSL_QUIC_TX_PACKETISER *txp,
|
---|
198 | void *msg_callback_arg);
|
---|
199 |
|
---|
200 | /*
|
---|
201 | * Determines the next PN which will be used for a given PN space.
|
---|
202 | */
|
---|
203 | QUIC_PN ossl_quic_tx_packetiser_get_next_pn(OSSL_QUIC_TX_PACKETISER *txp,
|
---|
204 | uint32_t pn_space);
|
---|
205 |
|
---|
206 | /*
|
---|
207 | * Sets a callback which is called whenever TXP sends an ACK frame. The callee
|
---|
208 | * must not modify the ACK frame data. Can be used to snoop on PNs being ACKed.
|
---|
209 | */
|
---|
210 | void ossl_quic_tx_packetiser_set_ack_tx_cb(OSSL_QUIC_TX_PACKETISER *txp,
|
---|
211 | void (*cb)(const OSSL_QUIC_FRAME_ACK *ack,
|
---|
212 | uint32_t pn_space,
|
---|
213 | void *arg),
|
---|
214 | void *cb_arg);
|
---|
215 |
|
---|
216 | # endif
|
---|
217 |
|
---|
218 | #endif
|
---|