summaryrefslogtreecommitdiffstats
path: root/include/internal/quic_txp.h
blob: 2a503770bc8646658a3074781c9a979caeadd2c9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
/*
 * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#ifndef OSSL_QUIC_TXP_H
# define OSSL_QUIC_TXP_H

# include <openssl/ssl.h>
# include "internal/quic_types.h"
# include "internal/quic_record_tx.h"
# include "internal/quic_cfq.h"
# include "internal/quic_txpim.h"
# include "internal/quic_stream.h"
# include "internal/quic_stream_map.h"
# include "internal/quic_fc.h"
# include "internal/bio_addr.h"
# include "internal/time.h"

# ifndef OPENSSL_NO_QUIC

/*
 * QUIC TX Packetiser
 * ==================
 */
typedef struct ossl_quic_tx_packetiser_args_st {
    /* Configuration Settings */
    QUIC_CONN_ID    cur_scid;   /* Current Source Connection ID we use. */
    QUIC_CONN_ID    cur_dcid;   /* Current Destination Connection ID we use. */
    BIO_ADDR        peer;       /* Current destination L4 address we use. */
    uint32_t        ack_delay_exponent; /* ACK delay exponent used when encoding. */

    /* Injected Dependencies */
    OSSL_QTX        *qtx;       /* QUIC Record Layer TX we are using */
    QUIC_TXPIM      *txpim;     /* QUIC TX'd Packet Information Manager */
    QUIC_CFQ        *cfq;       /* QUIC Control Frame Queue */
    OSSL_ACKM       *ackm;      /* QUIC Acknowledgement Manager */
    QUIC_STREAM_MAP *qsm;       /* QUIC Streams Map */
    QUIC_TXFC       *conn_txfc; /* QUIC Connection-Level TX Flow Controller */
    QUIC_RXFC       *conn_rxfc; /* QUIC Connection-Level RX Flow Controller */
    QUIC_RXFC       *max_streams_bidi_rxfc; /* QUIC RXFC for MAX_STREAMS generation */
    QUIC_RXFC       *max_streams_uni_rxfc;
    const OSSL_CC_METHOD *cc_method; /* QUIC Congestion Controller */
    OSSL_CC_DATA    *cc_data;   /* QUIC Congestion Controller Instance */
    OSSL_TIME       (*now)(void *arg);  /* Callback to get current time. */
    void            *now_arg;

    /*
     * Injected dependencies - crypto streams.
     *
     * Note: There is no crypto stream for the 0-RTT EL.
     *       crypto[QUIC_PN_SPACE_APP] is the 1-RTT crypto stream.
     */
    QUIC_SSTREAM    *crypto[QUIC_PN_SPACE_NUM];
} OSSL_QUIC_TX_PACKETISER_ARGS;

typedef struct ossl_quic_tx_packetiser_st OSSL_QUIC_TX_PACKETISER;

OSSL_QUIC_TX_PACKETISER *ossl_quic_tx_packetiser_new(const OSSL_QUIC_TX_PACKETISER_ARGS *args);

typedef void (ossl_quic_initial_token_free_fn)(const unsigned char *buf,
                                               size_t buf_len, void *arg);

void ossl_quic_tx_packetiser_free(OSSL_QUIC_TX_PACKETISER *txp);

/* Generate normal packets containing most frame types. */
#define TX_PACKETISER_ARCHETYPE_NORMAL      0
/* Generate ACKs only. */
#define TX_PACKETISER_ARCHETYPE_ACK_ONLY    1
#define TX_PACKETISER_ARCHETYPE_NUM         2

/*
 * Generates a datagram by polling the various ELs to determine if they want to
 * generate any frames, and generating a datagram which coalesces packets for
 * any ELs which do.
 *
 * archetype is a TX_PACKETISER_ARCHETYPE_* value.
 *
 * Returns TX_PACKETISER_RES_FAILURE on failure (e.g. allocation error),
 * TX_PACKETISER_RES_NO_PKT if no packets were sent (e.g. because nothing wants
 * to send anything), and TX_PACKETISER_RES_SENT_PKT if packets were sent.
 *
 * *status is filled with status information about the generated packet, if any.
 * See QUIC_TXP_STATUS for details.
 */
#define TX_PACKETISER_RES_FAILURE   0
#define TX_PACKETISER_RES_NO_PKT    1
#define TX_PACKETISER_RES_SENT_PKT  2

typedef struct quic_txp_status_st {
    int sent_ack_eliciting; /* Was an ACK-eliciting packet sent? */
} QUIC_TXP_STATUS;

int ossl_quic_tx_packetiser_generate(OSSL_QUIC_TX_PACKETISER *txp,
                                     uint32_t archetype,
                                     QUIC_TXP_STATUS *status);

/*
 * Returns 1 if one or more packets would be generated if
 * ossl_quic_tx_packetiser_generate were called.
 *
 * If TX_PACKETISER_BYPASS_CC is set in flags, congestion control is
 * ignored for the purposes of making this determination.
 */
#define TX_PACKETISER_BYPASS_CC   (1U << 0)

int ossl_quic_tx_packetiser_has_pending(OSSL_QUIC_TX_PACKETISER *txp,
                                        uint32_t archetype,
                                        uint32_t flags);

/*
 * Set the token used in Initial packets. The callback is called when the buffer
 * is no longer needed; for example, when the TXP is freed or when this function
 * is called again with a new buffer.
 */
void ossl_quic_tx_packetiser_set_initial_token(OSSL_QUIC_TX_PACKETISER *txp,
                                               const unsigned char *token,
                                               size_t token_len,
                                               ossl_quic_initial_token_free_fn *free_cb,
                                               void *free_cb_arg);

/* Change the DCID the TXP uses to send outgoing packets. */
int ossl_quic_tx_packetiser_set_cur_dcid(OSSL_QUIC_TX_PACKETISER *txp,
                                         const QUIC_CONN_ID *dcid);

/* Change the SCID the TXP uses to send outgoing (long) packets. */
int ossl_quic_tx_packetiser_set_cur_scid(OSSL_QUIC_TX_PACKETISER *txp,
                                         const QUIC_CONN_ID *scid);

/* Change the destination L4 address the TXP uses to send datagrams. */
int ossl_quic_tx_packetiser_set_peer(OSSL_QUIC_TX_PACKETISER *txp,
                                     const BIO_ADDR *peer);

/*
 * Inform the TX packetiser that an EL has been discarded. Idempotent.
 *
 * This does not inform the QTX as well; the caller must also inform the QTX.
 *
 * The TXP will no longer reference the crypto[enc_level] QUIC_SSTREAM which was
 * provided in the TXP arguments. However, it is the callers responsibility to
 * free that QUIC_SSTREAM if desired.
 */
int ossl_quic_tx_packetiser_discard_enc_level(OSSL_QUIC_TX_PACKETISER *txp,
                                              uint32_t enc_level);

/*
 * Informs the TX packetiser that the handshake is complete. The TX packetiser
 * will not send 1-RTT application data until the handshake is complete,
 * as the authenticity of the peer is not confirmed until the handshake
 * complete event occurs.
 */
void ossl_quic_tx_packetiser_notify_handshake_complete(OSSL_QUIC_TX_PACKETISER *txp);

/* Asks the TXP to generate a HANDSHAKE_DONE frame in the next 1-RTT packet. */
void ossl_quic_tx_packetiser_schedule_handshake_done(OSSL_QUIC_TX_PACKETISER *txp);

/* Asks the TXP to ensure the next packet in the given PN space is ACK-eliciting. */
void ossl_quic_tx_packetiser_schedule_ack_eliciting(OSSL_QUIC_TX_PACKETISER *txp,
                                                    uint32_t pn_space);

/*
 * Asks the TXP to ensure an ACK is put in the next packet in the given PN
 * space.
 */
void ossl_quic_tx_packetiser_schedule_ack(OSSL_QUIC_TX_PACKETISER *txp,
                                          uint32_t pn_space);

/*
 * Schedules a connection close. *f and f->reason are copied. This operation is
 * irreversible and causes all further packets generated by the TXP to contain a
 * CONNECTION_CLOSE frame. This function fails if it has already been called
 * successfully; the information in *f cannot be changed after the first
 * successful call to this function.
 */
int ossl_quic_tx_packetiser_schedule_conn_close(OSSL_QUIC_TX_PACKETISER *txp,
                                                const OSSL_QUIC_FRAME_CONN_CLOSE *f);

/* Setters for the msg_callback and msg_callback_arg */
void ossl_quic_tx_packetiser_set_msg_callback(OSSL_QUIC_TX_PACKETISER *txp,
                                              ossl_msg_cb msg_callback,
                                              SSL *msg_callback_ssl);
void ossl_quic_tx_packetiser_set_msg_callback_arg(OSSL_QUIC_TX_PACKETISER *txp,
                                                  void *msg_callback_arg);

/*
 * Determines the next PN which will be used for a given PN space.
 */
QUIC_PN ossl_quic_tx_packetiser_get_next_pn(OSSL_QUIC_TX_PACKETISER *txp,
                                            uint32_t pn_space);

/*
 * Sets a callback which is called whenever TXP sends an ACK frame. The callee
 * must not modify the ACK frame data. Can be used to snoop on PNs being ACKed.
 */
void ossl_quic_tx_packetiser_set_ack_tx_cb(OSSL_QUIC_TX_PACKETISER *txp,
                                           void (*cb)(const OSSL_QUIC_FRAME_ACK *ack,
                                                      uint32_t pn_space,
                                                      void *arg),
                                           void *cb_arg);

# endif

#endif