Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/openssl/ssl/quic/quic_obj_local.h
48261 views
1
/*
2
* Copyright 2024-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_OBJ_LOCAL_H
11
# define OSSL_QUIC_OBJ_LOCAL_H
12
13
# include <openssl/ssl.h>
14
# include "internal/quic_predef.h"
15
# include "internal/quic_engine.h"
16
# include "../ssl_local.h"
17
18
# ifndef OPENSSL_NO_QUIC
19
20
/*
21
* QUIC Object Structure.
22
*
23
* In the libssl APL, we have QLSOs, QCSOs and QSSOs, and in the future might
24
* choose to introduce QDSOs. There are also roles such as Port Leader and Event
25
* Leader which can be assumed by these different types under different
26
* circumstances — in other words, whether an APL object is a Port or Event
27
* Leader is not a static function of its type and these roles can 'float'
28
* dynamically depending on the circumstances under which an APL object was
29
* created.
30
*
31
* The QUIC_OBJ is a base type for QUIC APL objects which provides functionality
32
* common to all QUIC objects and which supports having different APL objects
33
* dynamically assume leader roles. It can therefore be seen as an extension of
34
* the SSL base class and extends the SSL object for QUIC APL objects. This
35
* avoids duplication of functionality for different types of QUIC object and
36
* allows access to common responsibilities of different types of APL object
37
* without regard to the kind of APL object we are dealing with.
38
*
39
* The "inheritance" hierarchy is as follows:
40
*
41
* SSL
42
* SSL_CONNECTION
43
* QUIC_OBJ
44
* QUIC_DOMAIN (QDSO) -> QUIC_ENGINE *E
45
* QUIC_LISTENER (QLSO) -> QUIC_PORT eP
46
* QUIC_CONNECTION (QCSO) -> QUIC_CHANNEL epCs
47
* QUIC_XSO (QSSO) -> QUIC_STREAM S
48
*
49
* Legend:
50
*
51
* *: Not currently modelled in the APL, though QUIC_ENGINE exists internally.
52
*
53
* E: Always an event leader if it exists.
54
* e: Potentially an event leader (namely if it is the root APL object in a
55
* hierarchy).
56
*
57
* P: Always a port leader if it exists.
58
* p: Potentially a port leader (namely if there is no port leader above it).
59
*
60
* C: Always a connection leader.
61
*
62
* s: Potentially usable as a stream (if it has a default stream attached).
63
* S: Always has the stream role if it exists.
64
*
65
* This structure must come at the start of a QUIC object structure definition.
66
*
67
* ssl->type still determines the actual object type. An SSL object
68
* pointer s can be safely cast to (QUIC_OBJ *) iff IS_QUIC(s) is true.
69
*/
70
struct quic_obj_st {
71
/* SSL object common header. */
72
struct ssl_st ssl;
73
74
/*
75
* Pointer to a parent APL object in a QUIC APL object hierarchy, or NULL if
76
* this is the root object.
77
*/
78
QUIC_OBJ *parent_obj;
79
80
/* invariant: != NULL */
81
QUIC_OBJ *cached_event_leader;
82
/* invariant: != NULL iff this is a port leader or subsidiary object */
83
QUIC_OBJ *cached_port_leader;
84
85
/*
86
* Points to the QUIC_ENGINE instance. Always equals
87
* cached_event_leader->engine. The containing_obj APL object owns this
88
* instance iff is_event_leader is set, otherwise it is an additional
89
* reference cached for convenience. Unlike port this is never NULL because
90
* a QUIC domain is always rooted in an event leader.
91
*/
92
QUIC_ENGINE *engine;
93
94
/*
95
* Points to the QUIC_PORT instance applicable to the containing_obj APL
96
* object, or NULL if we are not at or below a port leader. Always equals
97
* cached_port_leader->port. The containing_obj APL object owns this
98
* instance iff is_port_leader is set, otherwise it is an additional
99
* reference cached for convenience.
100
*/
101
QUIC_PORT *port;
102
103
/* SSL_DOMAIN_FLAG values taken from SSL_CTX at construction time. */
104
uint64_t domain_flags;
105
106
unsigned int init_done : 1;
107
unsigned int is_event_leader : 1;
108
unsigned int is_port_leader : 1;
109
110
/*
111
* Blocking mode configuration is handled generically through QUIC_OBJ as it
112
* by default inherits from the parent SSL object.
113
*/
114
unsigned int req_blocking_mode : 2; /* QUIC_BLOCKING_MODE */
115
116
/* Event handling mode. One of SSL_QUIC_VALUE_EVENT_HANDLING. */
117
unsigned int event_handling_mode : 2;
118
};
119
120
enum {
121
QUIC_BLOCKING_MODE_INHERIT,
122
QUIC_BLOCKING_MODE_NONBLOCKING,
123
QUIC_BLOCKING_MODE_BLOCKING
124
};
125
126
/*
127
* Core Functions and Inlines
128
* ==========================
129
*/
130
131
/*
132
* Initialises a QUIC_OBJ structure with zero or more roles active. Returns 1
133
* on success or 0 on failure.
134
*
135
* ctx: A SSL_CTX used to initialise the SSL base object structure.
136
*
137
* type: A SSL_TYPE_* value designating the SSL object type.
138
*
139
* parent_obj: NULL if this is the root APL object in a new hierarchy, or a
140
* pointer to the parent APL object otherwise.
141
*
142
* engine: If non-NULL, this object becomes the Event Leader. parent_obj must be
143
* NULL iff this is non-NULL as currently the Event Leader is always the root in
144
* an APL object hierarchy. If NULL, the contextually applicable engine is
145
* determined by using parent_obj and ancestors to find the Event Leader.
146
*
147
* port: If non-NULL, this object becomes a Port Leader. If NULL, the
148
* contextually applicable port (if any) is determined by using parent_obj and
149
* ancestors to find the Port Leader.
150
*/
151
int ossl_quic_obj_init(QUIC_OBJ *obj,
152
SSL_CTX *ctx,
153
int type,
154
SSL *parent_obj,
155
QUIC_ENGINE *engine,
156
QUIC_PORT *port);
157
158
/*
159
* Returns a pointer to the handshake layer object which should be accessible on
160
* obj for purposes of handshake API autoforwarding, if any.
161
*
162
* This returns NULL if a handshake layer SSL object is available but should not
163
* be used for autoforwarding purposes, for example on a QSSO.
164
*/
165
SSL_CONNECTION *ossl_quic_obj_get0_handshake_layer(QUIC_OBJ *obj);
166
167
/*
168
* Returns a pointer to the SSL base object structure. Returns NULL if obj is
169
* NULL. If obj is non-NULL, it must be initialised.
170
*/
171
static ossl_inline ossl_unused SSL *
172
ossl_quic_obj_get0_ssl(QUIC_OBJ *obj)
173
{
174
/*
175
* ->ssl is guaranteed to have an offset of 0 but the NULL check here makes
176
* ubsan happy.
177
*/
178
if (!ossl_assert(obj != NULL))
179
return NULL;
180
181
return &obj->ssl;
182
}
183
184
/*
185
* Determines the applicable engine and return a pointer to it. Never returns
186
* NULL.
187
*/
188
static ossl_inline ossl_unused QUIC_ENGINE *
189
ossl_quic_obj_get0_engine(const QUIC_OBJ *obj)
190
{
191
assert(obj->init_done);
192
assert(obj->engine != NULL);
193
return obj->engine;
194
}
195
196
/* Determines the applicable port (if any) and returns a pointer to it. */
197
static ossl_inline ossl_unused QUIC_PORT *
198
ossl_quic_obj_get0_port(const QUIC_OBJ *obj)
199
{
200
assert(obj->init_done);
201
return obj->port;
202
}
203
204
/* Returns 1 iff this leader structure represents an event leader. */
205
static ossl_inline ossl_unused int
206
ossl_quic_obj_is_event_leader(const QUIC_OBJ *obj)
207
{
208
return obj->is_event_leader;
209
}
210
211
/*
212
* Similar to ossl_quic_obj_get0_engine, but only returns a non-NULL value if
213
* the obj object itself is an event leader, rather than one of its ancestors.
214
*/
215
static ossl_inline ossl_unused QUIC_ENGINE *
216
ossl_quic_obj_get0_engine_local(const QUIC_OBJ *obj)
217
{
218
return ossl_quic_obj_is_event_leader(obj)
219
? ossl_quic_obj_get0_engine(obj) : NULL;
220
}
221
222
/* Returns 1 iff this leader structure represents a port leader. */
223
static ossl_inline ossl_unused int
224
ossl_quic_obj_is_port_leader(const QUIC_OBJ *obj)
225
{
226
return obj->is_port_leader;
227
}
228
229
/*
230
* Similar to ossl_quic_obj_get0_port, but only returns a non-NULL value if
231
* the obj object itself is a port leader, rather than one of its ancestors.
232
*/
233
static ossl_inline ossl_unused QUIC_PORT *
234
ossl_quic_obj_get0_port_local(const QUIC_OBJ *obj)
235
{
236
return ossl_quic_obj_is_port_leader(obj)
237
? ossl_quic_obj_get0_port(obj) : NULL;
238
}
239
240
/*
241
* Return 1 if we are currently capable of supporting blocking mode (regardless
242
* of whether it is actually turned on).
243
*/
244
int ossl_quic_obj_can_support_blocking(const QUIC_OBJ *obj);
245
246
/*
247
* Returns 1 if we *desire* to do blocking I/O, regardless of whether it will
248
* actually be used (e.g. because it cannot currently be supported).
249
*/
250
int ossl_quic_obj_desires_blocking(const QUIC_OBJ *obj);
251
252
/*
253
* Return 1 if an API call directly to the given object should use blocking mode
254
* and 0 otherwise.
255
*/
256
int ossl_quic_obj_blocking(const QUIC_OBJ *obj);
257
258
/*
259
* Set the (requested) blocking mode, which might or might not be honoured
260
* depending on whether the BIO configuration can support it. Argument is a
261
* QUIC_BLOCKING_MODE value. If the top-level object in a QSO hierarchy is set
262
* to QUIC_BLOCKING_MODE_INHERIT, defaults to blocking mode.
263
*/
264
void ossl_quic_obj_set_blocking_mode(QUIC_OBJ *obj, unsigned int mode);
265
266
/*
267
* Convenience Inlines
268
* ===================
269
*
270
* These inlines are expressed in terms of the core functions and inlines above.
271
*/
272
273
/* Get a pointer to the QUIC domain mutex. Always returns non-NULL. */
274
static ossl_inline ossl_unused CRYPTO_MUTEX *
275
ossl_quic_obj_get0_mutex(const QUIC_OBJ *obj)
276
{
277
return ossl_quic_engine_get0_mutex(ossl_quic_obj_get0_engine(obj));
278
}
279
280
/*
281
* Get a reference to the reactor applicable to a leader. Always returns
282
* non-NULL.
283
*/
284
static ossl_inline ossl_unused QUIC_REACTOR *
285
ossl_quic_obj_get0_reactor(const QUIC_OBJ *obj)
286
{
287
return ossl_quic_engine_get0_reactor(ossl_quic_obj_get0_engine(obj));
288
}
289
290
/* Get a reference to the OSSL_LIB_CTX pointer applicable to a leader. */
291
static ossl_inline ossl_unused OSSL_LIB_CTX *
292
ossl_quic_obj_get0_libctx(const QUIC_OBJ *obj)
293
{
294
return ossl_quic_engine_get0_libctx(ossl_quic_obj_get0_engine(obj));
295
}
296
297
/* Get a reference to the propq pointer applicable to a leader. */
298
static ossl_inline ossl_unused const char *
299
ossl_quic_obj_get0_propq(const QUIC_OBJ *obj)
300
{
301
return ossl_quic_engine_get0_propq(ossl_quic_obj_get0_engine(obj));
302
}
303
304
/*
305
* Returns the APL object pointer to the event leader in a hierarchy. Always
306
* returns non-NULL.
307
*/
308
static ossl_inline ossl_unused SSL *
309
ossl_quic_obj_get0_event_leader(const QUIC_OBJ *obj)
310
{
311
assert(obj->init_done);
312
return obj->cached_event_leader != NULL
313
? &obj->cached_event_leader->ssl
314
: NULL;
315
}
316
317
/*
318
* Returns the APL object pointer to the port leader in a hierarchy (if any).
319
* Always returns non-NULL.
320
*/
321
static ossl_inline ossl_unused SSL *
322
ossl_quic_obj_get0_port_leader(const QUIC_OBJ *obj)
323
{
324
assert(obj->init_done);
325
return obj->cached_port_leader != NULL
326
? &obj->cached_port_leader->ssl
327
: NULL;
328
}
329
330
/*
331
* Change the domain flags. Should only be called immediately after
332
* ossl_quic_obj_init().
333
*/
334
static ossl_inline ossl_unused void
335
ossl_quic_obj_set_domain_flags(QUIC_OBJ *obj, uint64_t domain_flags)
336
{
337
obj->domain_flags = domain_flags;
338
}
339
340
# endif
341
#endif
342
343