Update the OpenSSL Guide tutorials with changes to the demos
[openssl.git] / doc / man7 / ossl-guide-quic-multi-stream.pod
1 =pod
2
3 =begin comment
4
5 NB: Changes to the source code samples in this file should also be reflected in
6 demos/guide/quic-multi-stream.c
7
8 =end comment
9
10 =head1 NAME
11
12 ossl-guide-quic-multi-stream
13 - OpenSSL Guide: Writing a simple multi-stream QUIC client
14
15 =head1 INTRODUCTION
16
17 This page will introduce some important concepts required to write a simple
18 QUIC multi-stream application. It assumes a basic understanding of QUIC and how
19 it is used in OpenSSL. See L<ossl-guide-quic-introduction(7)> and
20 L<ossl-guide-quic-client-block(7)>.
21
22 =head1 QUIC STREAMS
23
24 In a QUIC multi-stream application we separate out the concepts of a QUIC
25 "connection" and a QUIC "stream". A connection object represents the overarching
26 details of the connection between a client and a server including all its
27 negotiated and configured parameters. We use the B<SSL> object for that in an
28 OpenSSL application (known as the connection B<SSL> object). It is created by an
29 application calling L<SSL_new(3)>.
30
31 Separately a connection can have zero or more streams associated with it
32 (although a connection with zero streams is probably not very useful, so
33 normally you would have at least one). A stream is used to send and receive
34 data between the two peers. Each stream is also represented by an B<SSL>
35 object. A stream is logically independent of all the other streams associated
36 with the same connection. Data sent on a stream is guaranteed to be delivered
37 in the order that it was sent within that stream. The same is not true across
38 streams, e.g. if an application sends data on stream 1 first and then sends some
39 more data on stream 2 second, then the remote peer may receive the data sent on
40 stream 2 before it receives the data sent on stream 1.
41
42 Once the connection B<SSL> object has completed its handshake (i.e.
43 L<SSL_connect(3)> has returned 1), stream B<SSL> objects are created by the
44 application calling L<SSL_new_stream(3)> or L<SSL_accept_stream(3)> (see
45 L</CREATING NEW STREAMS> below).
46
47 The same threading rules apply to B<SSL> objects as for most OpenSSL objects
48 (see L<ossl-guide-libraries-introduction(7)>). In particular most OpenSSL
49 functions are thread safe, but the B<SSL> object is not. This means that you can
50 use an B<SSL> object representing one stream at the same time as another thread
51 is using a different B<SSL> object for a different stream on the same
52 connection. But you cannot use the same B<SSL> object on two different threads
53 at the same time (without additional application level locking).
54
55 =head1 THE DEFAULT STREAM
56
57 A connection B<SSL> object may also (optionally) be associated with a stream.
58 This stream is known as the default stream. The default stream is automatically
59 created and associated with the B<SSL> object when the application calls
60 L<SSL_read_ex(3)>, L<SSL_read(3)>, L<SSL_write_ex(3)> or L<SSL_write(3)> and
61 passes the connection B<SSL> object as a parameter.
62
63 If a client application calls L<SSL_write_ex(3)> or L<SSL_write(3)> first then
64 (by default) the default stream will be a client-initiated bi-directional
65 stream. If a client application calls L<SSL_read_ex(3)> or L<SSL_read(3)>
66 first then the first stream initiated by the server will be used as the default
67 stream (whether it is bi-directional or uni-directional).
68
69 This behaviour can be controlled via the default stream mode. See
70 L<SSL_set_default_stream_mode(3)> for further details.
71
72 It is recommended that new multi-stream applications should not use a default
73 stream at all and instead should use a separate stream B<SSL> object for each
74 stream that is used. This requires calling L<SSL_set_default_stream_mode(3)>
75 and setting the mode to B<SSL_DEFAULT_STREAM_MODE_NONE>.
76
77 =head1 CREATING NEW STREAMS
78
79 An endpoint can create a new stream by calling L<SSL_new_stream(3)>. This
80 creates a locally initiated stream. In order to do so you must pass the QUIC
81 connection B<SSL> object as a parameter. You can also specify whether you want a
82 bi-directional or a uni-directional stream.
83
84 The function returns a new QUIC stream B<SSL> object for sending and receiving
85 data on that stream.
86
87 The peer may also initiate streams. An application can use the function
88 L<SSL_get_accept_stream_queue_len(3)> to determine the number of streams that
89 the peer has initiated that are waiting for the application to handle. An
90 application can call L<SSL_accept_stream(3)> to create a new B<SSL> object for
91 a remotely initiated stream. If the peer has not initiated any then this call
92 will block until one is available if the connection object is in blocking mode
93 (see L<SSL_set_blocking_mode(3)>).
94
95 When using a default stream OpenSSL will prevent new streams from being
96 accepted. To override this behaviour you must call
97 L<SSL_set_incoming_stream_policy(3)> to set the policy to
98 B<SSL_INCOMING_STREAM_POLICY_ACCEPT>. See the man page for further details. This
99 is not relevant if the default stream has been disabled as described in
100 L</THE DEFAULT STREAM> above.
101
102 Any stream may be bi-directional or uni-directional. If it is uni-directional
103 then the initiator can write to it but not read from it, and vice-versa for the
104 peer. You can determine what type of stream an B<SSL> object represents by
105 calling L<SSL_get_stream_type(3)>. See the man page for further details.
106
107 =head1 USING A STREAM TO SEND AND RECEIVE DATA
108
109 Once you have a stream B<SSL> object (which includes the connection B<SSL>
110 object if a default stream is in use) then you can send and receive data over it
111 using the L<SSL_write_ex(3)>, L<SSL_write(3)>, L<SSL_read_ex(3)> or
112 L<SSL_read(3)> functions. See the man pages for further details.
113
114 In the event of one of these functions not returning a success code then
115 you should call L<SSL_get_error(3)> to find out further details about the error.
116 In blocking mode this will either be a fatal error (e.g. B<SSL_ERROR_SYSCALL>
117 or B<SSL_ERROR_SSL>), or it will be B<SSL_ERROR_ZERO_RETURN> which can occur
118 when attempting to read data from a stream and the peer has indicated that the
119 stream is concluded (i.e. "FIN" has been signalled on the stream). This means
120 that the peer will send no more data on that stream. Note that the
121 interpretation of B<SSL_ERROR_ZERO_RETURN> is slightly different for a QUIC
122 application compared to a TLS application. In TLS it occurs when the connection
123 has been shutdown by the peer. In QUIC this only tells you that the current
124 stream has been concluded by the peer. It tells you nothing about the underlying
125 connection. If the peer has concluded the stream then no more data will be
126 received on it, however an application can still send data to the peer until
127 the send side of the stream has also been concluded. This can happen by the
128 application calling L<SSL_stream_conclude(3)>. It is an error to attempt to
129 send more data on a stream after L<SSL_stream_conclude(3)> has been called.
130
131 It is also possible to abandon a stream abnormally by calling
132 L<SSL_stream_reset(3)>.
133
134 Once a stream object is no longer needed it should be freed via a call to
135 L<SSL_free(3)>. An application should not call L<SSL_shutdown(3)> on it since
136 this is only meaningful for connection level B<SSL> objects. Freeing the stream
137 will automatically signal STOP_SENDING to the peer.
138
139 =head1 STREAMS AND CONNECTIONS
140
141 Given a stream object it is possible to get the B<SSL> object corresponding to
142 the connection via a call to L<SSL_get0_connection(3)>. Multi-threaded
143 restrictions apply so care should be taken when using the returned connection
144 object. Specifically, if you are handling each of your stream objects in a
145 different thread and call L<SSL_get0_connection(3)> from within that thread then
146 you must be careful to not to call any function that uses the connection object
147 at the same time as one of the other threads is also using that connection
148 object (with the exception of L<SSL_accept_stream(3)> and
149 L<SSL_get_accept_stream_queue_len(3)> which are thread-safe).
150
151 A stream object does not inherit all its settings and values from its parent
152 B<SSL> connection object. Therefore certain function calls that are relevant to
153 the connection as a whole will not work on a stream. For example the function
154 L<SSL_get_certificate(3)> can be used to obtain a handle on the peer certificate
155 when called with a connection B<SSL> object. When called with a stream B<SSL>
156 object it will return NULL.
157
158 =head1 SIMPLE MULTI-STREAM QUIC CLIENT EXAMPLE
159
160 This section will present various source code samples demonstrating how to write
161 a simple multi-stream QUIC client application which connects to a server, send
162 some HTTP/1.0 requests to it, and read back the responses. Note that HTTP/1.0
163 over QUIC is non-standard and will not be supported by real world servers. This
164 is for demonstration purposes only.
165
166 We will build on the example code for the simple blocking QUIC client that is
167 covered on the L<ossl-guide-quic-client-block(7)> page and we assume that you
168 are familiar with it. We will only describe the differences between the simple
169 blocking QUIC client and the multi-stream QUIC client. Although the example code
170 uses blocking B<SSL> objects, you can equally use nonblocking B<SSL> objects.
171 See L<ossl-guide-quic-client-non-block(7)> for more information about writing a
172 nonblocking QUIC client.
173
174 The complete source code for this example multi-stream QUIC client is available
175 in the C<demos/guide> directory of the OpenSSL source distribution in the file
176 C<quic-multi-stream.c>. It is also available online at
177 L<https://github.com/openssl/openssl/blob/master/demos/guide/quic-multi-stream.c>.
178
179 =head2 Disabling the default stream
180
181 As discussed above in L</THE DEFAULT STREAM> we will follow the recommendation
182 to disable the default stream for our multi-stream client. To do this we call
183 the L<SSL_set_default_stream_mode(3)> function and pass in our connection B<SSL>
184 object and the value B<SSL_DEFAULT_STREAM_MODE_NONE>.
185
186     /*
187      * We will use multiple streams so we will disable the default stream mode.
188      * This is not a requirement for using multiple streams but is recommended.
189      */
190     if (!SSL_set_default_stream_mode(ssl, SSL_DEFAULT_STREAM_MODE_NONE)) {
191         printf("Failed to disable the default stream mode\n");
192         goto end;
193     }
194
195 =head2 Creating the request streams
196
197 For the purposes of this example we will create two different streams to send
198 two different HTTP requests to the server. For the purposes of demonstration the
199 first of these will be a bi-directional stream and the second one will be a
200 uni-directional one:
201
202     /*
203      * We create two new client initiated streams. The first will be
204      * bi-directional, and the second will be uni-directional.
205      */
206     stream1 = SSL_new_stream(ssl, 0);
207     stream2 = SSL_new_stream(ssl, SSL_STREAM_FLAG_UNI);
208     if (stream1 == NULL || stream2 == NULL) {
209         printf("Failed to create streams\n");
210         goto end;
211     }
212
213 =head2 Writing data to the streams
214
215 Once the streams are successfully created we can start writing data to them. In
216 this example we will be sending a different HTTP request on each stream. To
217 avoid repeating too much code we write a simple helper function to send an HTTP
218 request to a stream:
219
220     int write_a_request(SSL *stream, const char *request_start,
221                         const char *hostname)
222     {
223         const char *request_end = "\r\n\r\n";
224         size_t written;
225
226         if (!SSL_write_ex(stream, request_start, strlen(request_start), &written))
227             return 0;
228         if (!SSL_write_ex(stream, hostname, strlen(hostname), &written))
229             return 0;
230         if (!SSL_write_ex(stream, request_end, strlen(request_end), &written))
231             return 0;
232
233         return 1;
234     }
235
236 We assume the strings B<request1_start> and B<request2_start> hold the
237 appropriate HTTP requests. We can then call our helper function above to send
238 the requests on the two streams. For the sake of simplicity this example does
239 this sequentially, writing to B<stream1> first and, when this is successful,
240 writing to B<stream2> second. Remember that our client is blocking so these
241 calls will only return once they have been successfully completed. A real
242 application would not need to do these writes sequentially or in any particular
243 order. For example we could start two threads (one for each stream) and write
244 the requests to each stream simultaneously.
245
246     /* Write an HTTP GET request on each of our streams to the peer */
247     if (!write_a_request(stream1, request1_start, hostname)) {
248         printf("Failed to write HTTP request on stream 1\n");
249         goto end;
250     }
251
252     if (!write_a_request(stream2, request2_start, hostname)) {
253         printf("Failed to write HTTP request on stream 2\n");
254         goto end;
255     }
256
257 =head2 Reading data from a stream
258
259 In this example B<stream1> is a bi-directional stream so, once we have sent the
260 request on it, we can attempt to read the response from the server back. Here
261 we just repeatedly call L<SSL_read_ex(3)> until that function fails (indicating
262 either that there has been a problem, or that the peer has signalled the stream
263 as concluded).
264
265     printf("Stream 1 data:\n");
266     /*
267      * Get up to sizeof(buf) bytes of the response from stream 1 (which is a
268      * bidirectional stream). We keep reading until the server closes the
269      * connection.
270      */
271     while (SSL_read_ex(stream1, buf, sizeof(buf), &readbytes)) {
272         /*
273         * OpenSSL does not guarantee that the returned data is a string or
274         * that it is NUL terminated so we use fwrite() to write the exact
275         * number of bytes that we read. The data could be non-printable or
276         * have NUL characters in the middle of it. For this simple example
277         * we're going to print it to stdout anyway.
278         */
279         fwrite(buf, 1, readbytes, stdout);
280     }
281     /* In case the response didn't finish with a newline we add one now */
282     printf("\n");
283
284 In a blocking application like this one calls to L<SSL_read_ex(3)> will either
285 succeed immediately returning data that is already available, or they will block
286 waiting for more data to become available and return it when it is, or they will
287 fail with a 0 response code.
288
289 Once we exit the while loop above we know that the last call to
290 L<SSL_read_ex(3)> gave a 0 response code so we call the L<SSL_get_error(3)>
291 function to find out more details. Since this is a blocking application this
292 will either return B<SSL_ERROR_SYSCALL> or B<SSL_ERROR_SSL> indicating a
293 fundamental problem, or it will return B<SSL_ERROR_ZERO_RETURN> indicating that
294 the stream is concluded and there will be no more data available to read from
295 it. Care must be taken to distinguish between an error at the stream level (i.e.
296 a stream reset) and an error at the connection level (i.e. a connection closed).
297 The L<SSL_get_stream_read_state(3)> function can be used to distinguish between
298 these different cases.
299
300     /*
301      * Check whether we finished the while loop above normally or as the
302      * result of an error. The 0 argument to SSL_get_error() is the return
303      * code we received from the SSL_read_ex() call. It must be 0 in order
304      * to get here. Normal completion is indicated by SSL_ERROR_ZERO_RETURN. In
305      * QUIC terms this means that the peer has sent FIN on the stream to
306      * indicate that no further data will be sent.
307      */
308     switch (SSL_get_error(stream1, 0)) {
309     case SSL_ERROR_ZERO_RETURN:
310         /* Normal completion of the stream */
311         break;
312
313     case SSL_ERROR_SSL:
314         /*
315          * Some stream fatal error occurred. This could be because of a stream
316          * reset - or some failure occurred on the underlying connection.
317          */
318         switch (SSL_get_stream_read_state(stream1)) {
319         case SSL_STREAM_STATE_RESET_REMOTE:
320             printf("Stream reset occurred\n");
321             /* The stream has been reset but the connection is still healthy. */
322             break;
323
324         case SSL_STREAM_STATE_CONN_CLOSED:
325             printf("Connection closed\n");
326             /* Connection is already closed. Skip SSL_shutdown() */
327             goto end;
328
329         default:
330             printf("Unknown stream failure\n");
331             break;
332         }
333         break;
334
335     default:
336         /* Some other unexpected error occurred */
337         printf ("Failed reading remaining data\n");
338         break;
339     }
340
341 =head2 Accepting an incoming stream
342
343 Our B<stream2> object that we created above was a uni-directional stream so it
344 cannot be used to receive data from the server. In this hypothetical example
345 we assume that the server initiates a new stream to send us back the data that
346 we requested. To do that we call L<SSL_accept_stream(3)>. Since this is a
347 blocking application this will wait indefinitely until the new stream has
348 arrived and is available for us to accept. In the event of an error it will
349 return B<NULL>.
350
351     /*
352      * In our hypothetical HTTP/1.0 over QUIC protocol that we are using we
353      * assume that the server will respond with a server initiated stream
354      * containing the data requested in our uni-directional stream. This doesn't
355      * really make sense to do in a real protocol, but its just for
356      * demonstration purposes.
357      *
358      * We're using blocking mode so this will block until a stream becomes
359      * available. We could override this behaviour if we wanted to by setting
360      * the SSL_ACCEPT_STREAM_NO_BLOCK flag in the second argument below.
361      */
362     stream3 = SSL_accept_stream(ssl, 0);
363     if (stream3 == NULL) {
364         printf("Failed to accept a new stream\n");
365         goto end;
366     }
367
368 We can now read data from the stream in the same way that we did for B<stream1>
369 above. We won't repeat that here.
370
371 =head2 Cleaning up the streams
372
373 Once we have finished using our streams we can simply free them by calling
374 L<SSL_free(3)>. Optionally we could call L<SSL_stream_conclude(3)> on them if
375 we want to indicate to the peer that we won't be sending them any more data, but
376 we don't do that in this example because we assume that the HTTP application
377 protocol supplies sufficient information for the peer to know when we have
378 finished sending request data.
379
380 We should not call L<SSL_shutdown(3)> or L<SSL_shutdown_ex(3)> on the stream
381 objects since those calls should not be used for streams.
382
383     SSL_free(stream1);
384     SSL_free(stream2);
385     SSL_free(stream3);
386
387 =head1 SEE ALSO
388
389 L<ossl-guide-introduction(7)>, L<ossl-guide-libraries-introduction(7)>,
390 L<ossl-guide-libssl-introduction(7)> L<ossl-guide-quic-introduction(7)>,
391 L<ossl-guide-quic-client-block(7)>
392
393 =head1 COPYRIGHT
394
395 Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
396
397 Licensed under the Apache License 2.0 (the "License").  You may not use
398 this file except in compliance with the License.  You can obtain a copy
399 in the file LICENSE in the source distribution or at
400 L<https://www.openssl.org/source/license.html>.
401
402 =cut