]> git.ipfire.org Git - thirdparty/openssl.git/blob - ssl/quic/quic_local.h
QUIC Thread Assisted Mode: Fix typos and use of CRYPTO_RWLOCK type
[thirdparty/openssl.git] / ssl / quic / quic_local.h
1 /*
2 * Copyright 2022 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_LOCAL_H
11 # define OSSL_QUIC_LOCAL_H
12
13 # include <openssl/ssl.h>
14 # include "internal/quic_ssl.h" /* QUIC_CONNECTION */
15 # include "internal/quic_txp.h"
16 # include "internal/quic_statm.h"
17 # include "internal/quic_demux.h"
18 # include "internal/quic_record_rx.h"
19 # include "internal/quic_tls.h"
20 # include "internal/quic_fc.h"
21 # include "internal/quic_stream.h"
22 # include "internal/quic_channel.h"
23 # include "internal/quic_reactor.h"
24 # include "internal/quic_thread_assist.h"
25 # include "../ssl_local.h"
26
27 # ifndef OPENSSL_NO_QUIC
28
29 struct quic_conn_st {
30 /*
31 * ssl_st is a common header for ordinary SSL objects, QUIC connection
32 * objects and QUIC stream objects, allowing objects of these different
33 * types to be disambiguated at runtime and providing some common fields.
34 *
35 * Note: This must come first in the QUIC_CONNECTION structure.
36 */
37 struct ssl_st ssl;
38
39 SSL *tls;
40
41 /*
42 * The QUIC channel providing the core QUIC connection implementation. Note
43 * that this is not instantiated until we actually start trying to do the
44 * handshake. This is to allow us to gather information like whether we are
45 * going to be in client or server mode before committing to instantiating
46 * the channel, since we want to determine the channel arguments based on
47 * that.
48 *
49 * The channel remains available after connection termination until the SSL
50 * object is freed, thus (ch != NULL) iff (started == 1).
51 */
52 QUIC_CHANNEL *ch;
53
54 /*
55 * The mutex used to synchronise access to the QUIC_CHANNEL. We own this but
56 * provide it to the channel.
57 */
58 CRYPTO_MUTEX *mutex;
59
60 /* Our single bidirectional application data stream. */
61 QUIC_STREAM *stream0;
62
63 /* The network read and write BIOs. */
64 BIO *net_rbio, *net_wbio;
65
66 /* Initial peer L4 address. */
67 BIO_ADDR init_peer_addr;
68
69 #ifndef OPENSSL_NO_QUIC_THREAD_ASSIST
70 /* Manages thread for QUIC thread assisted mode. */
71 QUIC_THREAD_ASSIST thread_assist;
72 #endif
73
74 /* If non-NULL, used instead of ossl_time_now(). Used for testing. */
75 OSSL_TIME (*override_now_cb)(void *arg);
76 void *override_now_cb_arg;
77
78 /* Have we started? */
79 unsigned int started : 1;
80
81 /* Are we in blocking mode? */
82 unsigned int blocking : 1;
83
84 /* Can the read and write network BIOs support blocking? */
85 unsigned int can_poll_net_rbio : 1;
86 unsigned int can_poll_net_wbio : 1;
87
88 /*
89 * Has the application called SSL_set_accept_state? We do not support this
90 * but track it here so we can reject a subsequent handshake call.
91 */
92 unsigned int as_server : 1;
93
94 /* Are we using thread assisted mode? Never changes after init. */
95 unsigned int is_thread_assisted : 1;
96
97 /*
98 * This state tracks SSL_write all-or-nothing (AON) write semantics
99 * emulation.
100 *
101 * Example chronology:
102 *
103 * t=0: aon_write_in_progress=0
104 * t=1: SSL_write(ssl, b1, l1) called;
105 * too big to enqueue into sstream at once, SSL_ERROR_WANT_WRITE;
106 * aon_write_in_progress=1; aon_buf_base=b1; aon_buf_len=l1;
107 * aon_buf_pos < l1 (depends on how much room was in sstream);
108 * t=2: SSL_write(ssl, b2, l2);
109 * b2 must equal b1 (validated unless ACCEPT_MOVING_WRITE_BUFFER)
110 * l2 must equal l1 (always validated)
111 * append into sstream from [b2 + aon_buf_pos, b2 + aon_buf_len)
112 * if done, aon_write_in_progess=0
113 *
114 */
115 /* Is an AON write in progress? */
116 unsigned int aon_write_in_progress : 1;
117 /*
118 * The base buffer pointer the caller passed us for the initial AON write
119 * call. We use this for validation purposes unless
120 * ACCEPT_MOVING_WRITE_BUFFER is enabled.
121 *
122 * NOTE: We never dereference this, as the caller might pass a different
123 * (but identical) buffer if using ACCEPT_MOVING_WRITE_BUFFER. It is for
124 * validation by pointer comparison only.
125 */
126 const unsigned char *aon_buf_base;
127 /* The total length of the AON buffer being sent, in bytes. */
128 size_t aon_buf_len;
129 /*
130 * The position in the AON buffer up to which we have successfully sent data
131 * so far.
132 */
133 size_t aon_buf_pos;
134
135 /* SSL_set_mode */
136 uint32_t ssl_mode;
137
138 /*
139 * Last 'normal' error during an app-level I/O operation, used by
140 * SSL_get_error(); used to track data-path errors like SSL_ERROR_WANT_READ
141 * and SSL_ERROR_WANT_WRITE.
142 */
143 int last_error;
144 };
145
146 /* Internal calls to the QUIC CSM which come from various places. */
147 int ossl_quic_conn_on_handshake_confirmed(QUIC_CONNECTION *qc);
148
149 /*
150 * To be called when a protocol violation occurs. The connection is torn down
151 * with the given error code, which should be a QUIC_ERR_* value. Reason string
152 * is optional and copied if provided. frame_type should be 0 if not applicable.
153 */
154 void ossl_quic_conn_raise_protocol_error(QUIC_CONNECTION *qc,
155 uint64_t error_code,
156 uint64_t frame_type,
157 const char *reason);
158
159 void ossl_quic_conn_on_remote_conn_close(QUIC_CONNECTION *qc,
160 OSSL_QUIC_FRAME_CONN_CLOSE *f);
161
162 # define OSSL_QUIC_ANY_VERSION 0xFFFFF
163
164 # define QUIC_CONNECTION_FROM_SSL_int(ssl, c) \
165 ((ssl) == NULL ? NULL \
166 : ((ssl)->type == SSL_TYPE_QUIC_CONNECTION \
167 ? (c QUIC_CONNECTION *)(ssl) \
168 : NULL))
169
170 # define QUIC_STREAM_FROM_SSL_int(ssl, c) \
171 ((ssl) == NULL ? NULL \
172 : ((ssl)->type == SSL_TYPE_QUIC_CONNECTION \
173 || (ssl)->type == SSL_TYPE_QUIC_STREAM \
174 ? (c QUIC_STREAM *)(ssl) \
175 : NULL))
176
177 # define SSL_CONNECTION_FROM_QUIC_SSL_int(ssl, c) \
178 ((ssl) == NULL ? NULL \
179 : ((ssl)->type == SSL_TYPE_QUIC_CONNECTION \
180 ? (c SSL_CONNECTION *)((c QUIC_CONNECTION *)(ssl))->tls \
181 : NULL))
182 # else
183 # define QUIC_CONNECTION_FROM_SSL_int(ssl, c) NULL
184 # define QUIC_STREAM_FROM_SSL_int(ssl, c) NULL
185 # define SSL_CONNECTION_FROM_QUIC_SSL_int(ssl, c) NULL
186 # endif
187
188 # define QUIC_CONNECTION_FROM_SSL(ssl) \
189 QUIC_CONNECTION_FROM_SSL_int(ssl, SSL_CONNECTION_NO_CONST)
190 # define QUIC_CONNECTION_FROM_CONST_SSL(ssl) \
191 QUIC_CONNECTION_FROM_SSL_int(ssl, const)
192 # define QUIC_STREAM_FROM_SSL(ssl) \
193 QUIC_STREAM_FROM_SSL_int(ssl, SSL_CONNECTION_NO_CONST)
194 # define QUIC_STREAM_FROM_CONST_SSL(ssl) \
195 QUIC_STREAM_FROM_SSL_int(ssl, const)
196 # define SSL_CONNECTION_FROM_QUIC_SSL(ssl) \
197 SSL_CONNECTION_FROM_QUIC_SSL_int(ssl, SSL_CONNECTION_NO_CONST)
198 # define SSL_CONNECTION_FROM_CONST_QUIC_SSL(ssl) \
199 SSL_CONNECTION_FROM_CONST_QUIC_SSL_int(ssl, const)
200
201 # define IMPLEMENT_quic_meth_func(version, func_name, q_accept, \
202 q_connect, enc_data) \
203 const SSL_METHOD *func_name(void) \
204 { \
205 static const SSL_METHOD func_name##_data= { \
206 version, \
207 0, \
208 0, \
209 ossl_quic_new, \
210 ossl_quic_free, \
211 ossl_quic_reset, \
212 ossl_quic_init, \
213 ossl_quic_clear, \
214 ossl_quic_deinit, \
215 q_accept, \
216 q_connect, \
217 ossl_quic_read, \
218 ossl_quic_peek, \
219 ossl_quic_write, \
220 NULL /* shutdown */, \
221 NULL /* renegotiate */, \
222 ossl_quic_renegotiate_check, \
223 NULL /* read_bytes */, \
224 NULL /* write_bytes */, \
225 NULL /* dispatch_alert */, \
226 ossl_quic_ctrl, \
227 ossl_quic_ctx_ctrl, \
228 NULL /* get_cipher_by_char */, \
229 NULL /* put_cipher_by_char */, \
230 ossl_quic_pending, \
231 ossl_quic_num_ciphers, \
232 ossl_quic_get_cipher, \
233 tls1_default_timeout, \
234 &enc_data, \
235 ssl_undefined_void_function, \
236 ossl_quic_callback_ctrl, \
237 ossl_quic_ctx_callback_ctrl, \
238 }; \
239 return &func_name##_data; \
240 }
241
242 #endif