1 | /*
|
---|
2 | * Copyright 2022-2023 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_TSERVER_H
|
---|
11 | # define OSSL_QUIC_TSERVER_H
|
---|
12 |
|
---|
13 | # include <openssl/ssl.h>
|
---|
14 | # include <openssl/bio.h>
|
---|
15 | # include "internal/quic_stream.h"
|
---|
16 | # include "internal/quic_channel.h"
|
---|
17 | # include "internal/statem.h"
|
---|
18 | # include "internal/time.h"
|
---|
19 |
|
---|
20 | # ifndef OPENSSL_NO_QUIC
|
---|
21 |
|
---|
22 | /*
|
---|
23 | * QUIC Test Server Module
|
---|
24 | * =======================
|
---|
25 | *
|
---|
26 | * This implements a QUIC test server. Since full QUIC server support is not yet
|
---|
27 | * implemented this server is limited in features and scope. It exists to
|
---|
28 | * provide a target for our QUIC client to talk to for testing purposes.
|
---|
29 | *
|
---|
30 | * A given QUIC test server instance supports only one client at a time.
|
---|
31 | *
|
---|
32 | * Note that this test server is not suitable for production use because it does
|
---|
33 | * not implement address verification, anti-amplification or retry logic.
|
---|
34 | */
|
---|
35 | typedef struct quic_tserver_st QUIC_TSERVER;
|
---|
36 |
|
---|
37 | typedef struct quic_tserver_args_st {
|
---|
38 | OSSL_LIB_CTX *libctx;
|
---|
39 | const char *propq;
|
---|
40 | SSL_CTX *ctx;
|
---|
41 | BIO *net_rbio, *net_wbio;
|
---|
42 | OSSL_TIME (*now_cb)(void *arg);
|
---|
43 | void *now_cb_arg;
|
---|
44 | const unsigned char *alpn;
|
---|
45 | size_t alpnlen;
|
---|
46 | } QUIC_TSERVER_ARGS;
|
---|
47 |
|
---|
48 | QUIC_TSERVER *ossl_quic_tserver_new(const QUIC_TSERVER_ARGS *args,
|
---|
49 | const char *certfile, const char *keyfile);
|
---|
50 |
|
---|
51 | void ossl_quic_tserver_free(QUIC_TSERVER *srv);
|
---|
52 |
|
---|
53 | /* Set mutator callbacks for test framework support */
|
---|
54 | int ossl_quic_tserver_set_plain_packet_mutator(QUIC_TSERVER *srv,
|
---|
55 | ossl_mutate_packet_cb mutatecb,
|
---|
56 | ossl_finish_mutate_cb finishmutatecb,
|
---|
57 | void *mutatearg);
|
---|
58 |
|
---|
59 | int ossl_quic_tserver_set_handshake_mutator(QUIC_TSERVER *srv,
|
---|
60 | ossl_statem_mutate_handshake_cb mutate_handshake_cb,
|
---|
61 | ossl_statem_finish_mutate_handshake_cb finish_mutate_handshake_cb,
|
---|
62 | void *mutatearg);
|
---|
63 |
|
---|
64 | /* Advances the state machine. */
|
---|
65 | int ossl_quic_tserver_tick(QUIC_TSERVER *srv);
|
---|
66 |
|
---|
67 | /* Returns 1 if we have a (non-terminated) client. */
|
---|
68 | int ossl_quic_tserver_is_connected(QUIC_TSERVER *srv);
|
---|
69 |
|
---|
70 | /*
|
---|
71 | * Returns 1 if we have finished the TLS handshake
|
---|
72 | */
|
---|
73 | int ossl_quic_tserver_is_handshake_confirmed(const QUIC_TSERVER *srv);
|
---|
74 |
|
---|
75 | /* Returns 1 if the server is in any terminating or terminated state */
|
---|
76 | int ossl_quic_tserver_is_term_any(const QUIC_TSERVER *srv);
|
---|
77 |
|
---|
78 | const QUIC_TERMINATE_CAUSE *
|
---|
79 | ossl_quic_tserver_get_terminate_cause(const QUIC_TSERVER *srv);
|
---|
80 |
|
---|
81 | /* Returns 1 if the server is in a terminated state */
|
---|
82 | int ossl_quic_tserver_is_terminated(const QUIC_TSERVER *srv);
|
---|
83 |
|
---|
84 | /*
|
---|
85 | * Attempts to read from stream 0. Writes the number of bytes read to
|
---|
86 | * *bytes_read and returns 1 on success. If no bytes are available, 0 is written
|
---|
87 | * to *bytes_read and 1 is returned (this is considered a success case).
|
---|
88 | *
|
---|
89 | * Returns 0 if connection is not currently active. If the receive part of
|
---|
90 | * the stream has reached the end of stream condition, returns 0; call
|
---|
91 | * ossl_quic_tserver_has_read_ended() to identify this condition.
|
---|
92 | */
|
---|
93 | int ossl_quic_tserver_read(QUIC_TSERVER *srv,
|
---|
94 | uint64_t stream_id,
|
---|
95 | unsigned char *buf,
|
---|
96 | size_t buf_len,
|
---|
97 | size_t *bytes_read);
|
---|
98 |
|
---|
99 | /*
|
---|
100 | * Returns 1 if the read part of the stream has ended normally.
|
---|
101 | */
|
---|
102 | int ossl_quic_tserver_has_read_ended(QUIC_TSERVER *srv, uint64_t stream_id);
|
---|
103 |
|
---|
104 | /*
|
---|
105 | * Attempts to write to the given stream. Writes the number of bytes consumed to
|
---|
106 | * *bytes_written and returns 1 on success. If there is no space currently
|
---|
107 | * available to write any bytes, 0 is written to *consumed and 1 is returned
|
---|
108 | * (this is considered a success case).
|
---|
109 | *
|
---|
110 | * Note that unlike libssl public APIs, this API always works in a 'partial
|
---|
111 | * write' mode.
|
---|
112 | *
|
---|
113 | * Returns 0 if connection is not currently active.
|
---|
114 | */
|
---|
115 | int ossl_quic_tserver_write(QUIC_TSERVER *srv,
|
---|
116 | uint64_t stream_id,
|
---|
117 | const unsigned char *buf,
|
---|
118 | size_t buf_len,
|
---|
119 | size_t *bytes_written);
|
---|
120 |
|
---|
121 | /*
|
---|
122 | * Signals normal end of the stream.
|
---|
123 | */
|
---|
124 | int ossl_quic_tserver_conclude(QUIC_TSERVER *srv, uint64_t stream_id);
|
---|
125 |
|
---|
126 | /*
|
---|
127 | * Create a server-initiated stream. The stream ID of the newly
|
---|
128 | * created stream is written to *stream_id.
|
---|
129 | */
|
---|
130 | int ossl_quic_tserver_stream_new(QUIC_TSERVER *srv,
|
---|
131 | int is_uni,
|
---|
132 | uint64_t *stream_id);
|
---|
133 |
|
---|
134 | BIO *ossl_quic_tserver_get0_rbio(QUIC_TSERVER *srv);
|
---|
135 |
|
---|
136 | SSL_CTX *ossl_quic_tserver_get0_ssl_ctx(QUIC_TSERVER *srv);
|
---|
137 |
|
---|
138 | /*
|
---|
139 | * Returns 1 if the peer has sent a STOP_SENDING frame for a stream.
|
---|
140 | * app_error_code is written if this returns 1.
|
---|
141 | */
|
---|
142 | int ossl_quic_tserver_stream_has_peer_stop_sending(QUIC_TSERVER *srv,
|
---|
143 | uint64_t stream_id,
|
---|
144 | uint64_t *app_error_code);
|
---|
145 |
|
---|
146 | /*
|
---|
147 | * Returns 1 if the peer has sent a RESET_STREAM frame for a stream.
|
---|
148 | * app_error_code is written if this returns 1.
|
---|
149 | */
|
---|
150 | int ossl_quic_tserver_stream_has_peer_reset_stream(QUIC_TSERVER *srv,
|
---|
151 | uint64_t stream_id,
|
---|
152 | uint64_t *app_error_code);
|
---|
153 |
|
---|
154 | /*
|
---|
155 | * Replaces existing local connection ID in the underlying QUIC_CHANNEL.
|
---|
156 | */
|
---|
157 | int ossl_quic_tserver_set_new_local_cid(QUIC_TSERVER *srv,
|
---|
158 | const QUIC_CONN_ID *conn_id);
|
---|
159 |
|
---|
160 | /*
|
---|
161 | * Returns the stream ID of the next incoming stream, or UINT64_MAX if there
|
---|
162 | * currently is none.
|
---|
163 | */
|
---|
164 | uint64_t ossl_quic_tserver_pop_incoming_stream(QUIC_TSERVER *srv);
|
---|
165 |
|
---|
166 | /*
|
---|
167 | * Returns 1 if all data sent on the given stream_id has been acked by the peer.
|
---|
168 | */
|
---|
169 | int ossl_quic_tserver_is_stream_totally_acked(QUIC_TSERVER *srv,
|
---|
170 | uint64_t stream_id);
|
---|
171 |
|
---|
172 | /* Returns 1 if we are currently interested in reading data from the network */
|
---|
173 | int ossl_quic_tserver_get_net_read_desired(QUIC_TSERVER *srv);
|
---|
174 |
|
---|
175 | /* Returns 1 if we are currently interested in writing data to the network */
|
---|
176 | int ossl_quic_tserver_get_net_write_desired(QUIC_TSERVER *srv);
|
---|
177 |
|
---|
178 | /* Returns the next event deadline */
|
---|
179 | OSSL_TIME ossl_quic_tserver_get_deadline(QUIC_TSERVER *srv);
|
---|
180 |
|
---|
181 | /*
|
---|
182 | * Shutdown the QUIC connection. Returns 1 if the connection is terminated and
|
---|
183 | * 0 otherwise.
|
---|
184 | */
|
---|
185 | int ossl_quic_tserver_shutdown(QUIC_TSERVER *srv, uint64_t app_error_code);
|
---|
186 |
|
---|
187 | /* Force generation of an ACK-eliciting packet. */
|
---|
188 | int ossl_quic_tserver_ping(QUIC_TSERVER *srv);
|
---|
189 |
|
---|
190 | /* Set tracing callback on channel. */
|
---|
191 | void ossl_quic_tserver_set_msg_callback(QUIC_TSERVER *srv,
|
---|
192 | void (*f)(int write_p, int version,
|
---|
193 | int content_type,
|
---|
194 | const void *buf, size_t len,
|
---|
195 | SSL *ssl, void *arg),
|
---|
196 | void *arg);
|
---|
197 |
|
---|
198 | /*
|
---|
199 | * This is similar to ossl_quic_conn_get_channel; it should be used for test
|
---|
200 | * instrumentation only and not to bypass QUIC_TSERVER for 'normal' operations.
|
---|
201 | */
|
---|
202 | QUIC_CHANNEL *ossl_quic_tserver_get_channel(QUIC_TSERVER *srv);
|
---|
203 |
|
---|
204 | /* Send a TLS new session ticket */
|
---|
205 | int ossl_quic_tserver_new_ticket(QUIC_TSERVER *srv);
|
---|
206 |
|
---|
207 | /*
|
---|
208 | * Set the max_early_data value to be sent in NewSessionTickets. Only the
|
---|
209 | * values 0 and 0xffffffff are valid for use in QUIC.
|
---|
210 | */
|
---|
211 | int ossl_quic_tserver_set_max_early_data(QUIC_TSERVER *srv,
|
---|
212 | uint32_t max_early_data);
|
---|
213 |
|
---|
214 | /* Set the find session callback for getting a server PSK */
|
---|
215 | void ossl_quic_tserver_set_psk_find_session_cb(QUIC_TSERVER *srv,
|
---|
216 | SSL_psk_find_session_cb_func cb);
|
---|
217 |
|
---|
218 | # endif
|
---|
219 |
|
---|
220 | #endif
|
---|