1=pod 2 3=begin comment 4 5NB: Changes to the source code samples in this file should also be reflected in 6demos/guide/quic-server-non-block.c 7 8=end comment 9 10=head1 NAME 11 12ossl-guide-quic-server-non-block 13- OpenSSL Guide: Writing a simple nonblocking QUIC server 14 15=head1 SIMPLE NONBLOCKING QUIC SERVER EXAMPLE 16 17This page presents various source code samples demonstrating how to write a 18simple, non-concurrent, QUIC "echo" server application which accepts one client 19connection at a time, echoing input from the client back to the same client. 20Once the current client disconnects, the next client connection is accepted. 21 22The server only accepts C<http/1.0> and C<hq-interop> ALPN's and doesn't actually 23implement HTTP but only does a simple echo. This is non-standard and will not 24be supported by real world servers. This is for demonstration purposes only. 25 26There are various methods to test this server: B<quic-client-block.c> and 27B<quic-client-non-block.c> will send a basic HTTP/1.0 request, which the server 28will echo back. You can also test this server by running 29C<openssl s_client -connect localhost:4443 -4 -quic -alpn http/1.0> and entering 30text that will be echoed back by the server. 31 32Both the listening socket and connected socket are "nonblocking". However, 33we use select() to make the listening socket block when it cannot read/write. 34Rather than stopping and waiting, your application may need to go and do other 35tasks whilst the B<SSL> object is unable to read/write. For example: updating a 36GUI or performing operations on some other connection or stream. 37 38The complete source code for this example nonblocking QUIC server is available 39in the B<demos/guide> directory of the OpenSSL source distribution in the file 40B<quic-server-non-block.c>. It is also available online at 41L<https://github.com/openssl/openssl/blob/master/demos/guide/quic-server-non-block.c>. 42 43We assume that you already have OpenSSL installed on your system; that you 44already have some fundamental understanding of OpenSSL concepts and QUIC (see 45L<ossl-guide-libraries-introduction(7)> and L<ossl-guide-quic-introduction(7)>); 46and that you know how to write and build C code and link it against the 47libcrypto and libssl libraries that are provided by OpenSSL. It also assumes 48that you have a basic understanding of UDP/IP and sockets. 49 50=head2 Creating the SSL_CTX and SSL objects 51 52The first step is to create an B<SSL_CTX> object for our server. We use the 53L<SSL_CTX_new(3)> function for this purpose. We pass as an argument the return 54value of the function L<OSSL_QUIC_server_method(3)>. You should use this method 55whenever you are writing a QUIC server. 56 57 /* 58 * An SSL_CTX holds shared configuration information for multiple 59 * subsequent per-client SSL connections. We specifically load a QUIC 60 * server method here. 61 */ 62 ctx = SSL_CTX_new(OSSL_QUIC_server_method()); 63 if (ctx == NULL) 64 goto err; 65 66Servers need a private key and certificate. Intermediate issuer CA 67certificates are often required, and both the server (end-entity or EE) 68certificate and the issuer ("chain") certificates are most easily configured in 69a single "chain file". Below we load such a chain file (the EE certificate 70must appear first), and then load the corresponding private key, checking that 71it matches the server certificate. No checks are performed to check the 72integrity of the chain (CA signatures or certificate expiration dates, for 73example), but we do verify the consistency of the private key with the 74corresponding certificate. 75 76 /* 77 * Load the server's certificate *chain* file (PEM format), which includes 78 * not only the leaf (end-entity) server certificate, but also any 79 * intermediate issuer-CA certificates. The leaf certificate must be the 80 * first certificate in the file. 81 * 82 * In advanced use-cases this can be called multiple times, once per public 83 * key algorithm for which the server has a corresponding certificate. 84 * However, the corresponding private key (see below) must be loaded first, 85 * *before* moving on to the next chain file. 86 */ 87 if (SSL_CTX_use_certificate_chain_file(ctx, cert_path) <= 0) { 88 fprintf(stderr, "couldn't load certificate file: %s\n", cert_path); 89 goto err; 90 } 91 92 /* 93 * Load the corresponding private key, this also checks that the private 94 * key matches the just loaded end-entity certificate. It does not check 95 * whether the certificate chain is valid, the certificates could be 96 * expired, or may otherwise fail to form a chain that a client can 97 * validate. 98 */ 99 if (SSL_CTX_use_PrivateKey_file(ctx, key_path, SSL_FILETYPE_PEM) <= 0) { 100 fprintf(stderr, "couldn't load key file: %s\n", key_path); 101 goto err; 102 } 103 104Most servers, including this one, do not solicit client certificates. We 105therefore do not need a "trust store" and allow the handshake to complete even 106when the client does not present a certificate. Note: Even if a client did 107present a trusted certificate, for it to be useful, the server application 108would still need custom code to use the verified identity to grant nondefault 109access to that particular client. Some servers grant access to all clients 110with certificates from a private CA, this then requires processing of 111certificate revocation lists to deauthorise a client. It is often simpler and 112more secure to instead keep a list of authorised public keys. 113 114Though this is the default setting, we explicitly call the 115L<SSL_CTX_set_verify(3)> function and pass the B<SSL_VERIFY_NONE> value to it. 116The final argument to this function is a callback that you can optionally 117supply to override the default handling for certificate verification. Most 118applications do not need to do this so this can safely be set to NULL to get 119the default handling. 120 121 /* 122 * Clients rarely employ certificate-based authentication, and so we don't 123 * require "mutual" TLS authentication (indeed there's no way to know 124 * whether or how the client authenticated the server, so the term "mutual" 125 * is potentially misleading). 126 * 127 * Since we're not soliciting or processing client certificates, we don't 128 * need to configure a trusted-certificate store, so no call to 129 * SSL_CTX_set_default_verify_paths() is needed. The server's own 130 * certificate chain is assumed valid. 131 */ 132 SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL); 133 134 135QUIC also dictates using Application-Layer Protocol Negotiation (ALPN) to select 136an application protocol. We use L<SSL_CTX_set_alpn_select_cb(3)> for this 137purpose. We can pass a callback which will be called for each connection to 138select an ALPN the server considers acceptable. 139 140 /* Setup ALPN negotiation callback to decide which ALPN is accepted. */ 141 SSL_CTX_set_alpn_select_cb(ctx, select_alpn, NULL); 142 143In this case, we only accept "http/1.0" and "hq-interop". 144 145 /* 146 * ALPN strings for TLS handshake. Only 'http/1.0' and 'hq-interop' 147 * are accepted. 148 */ 149 static const unsigned char alpn_ossltest[] = { 150 8, 'h', 't', 't', 'p', '/', '1', '.', '0', 151 10, 'h', 'q', '-', 'i', 'n', 't', 'e', 'r', 'o', 'p', 152 }; 153 154 static int select_alpn(SSL *ssl, const unsigned char **out, 155 unsigned char *out_len, const unsigned char *in, 156 unsigned int in_len, void *arg) 157 { 158 if (SSL_select_next_proto((unsigned char **)out, out_len, alpn_ossltest, 159 sizeof(alpn_ossltest), in, 160 in_len) == OPENSSL_NPN_NEGOTIATED) 161 return SSL_TLSEXT_ERR_OK; 162 return SSL_TLSEXT_ERR_ALERT_FATAL; 163 } 164 165That is all the setup that we need to do for the B<SSL_CTX>. Next, we create a 166UDP socket and bind to it on localhost. 167 168 /* Retrieve the file descriptor for a new UDP socket */ 169 if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { 170 fprintf(stderr, "cannot create socket"); 171 return -1; 172 } 173 174 sa.sin_family = AF_INET; 175 sa.sin_port = htons(port); 176 177 /* Bind to the new UDP socket on localhost */ 178 if (bind(fd, (const struct sockaddr *)&sa, sizeof(sa)) < 0) { 179 fprintf(stderr, "cannot bind to %u\n", port); 180 BIO_closesocket(fd); 181 return -1; 182 } 183 184 /* Set port to nonblocking mode */ 185 if (BIO_socket_nbio(fd, 1) <= 0) { 186 fprintf(stderr, "Unable to set port to nonblocking mode"); 187 BIO_closesocket(fd); 188 return -1; 189 } 190 191To run the QUIC server, we create an B<SSL_LISTENER> to listen for incoming 192connections. We provide it with the bound UDP port to then explicitly begin 193listening for new connections. 194 195 /* Create a new QUIC listener */ 196 if ((listener = SSL_new_listener(ctx, 0)) == NULL) 197 goto err; 198 199 /* Provide the listener with our UDP socket. */ 200 if (!SSL_set_fd(listener, fd)) 201 goto err; 202 203 /* Set the listener mode to nonblocking, which is inherited by 204 * child objects. 205 */ 206 if (!SSL_set_blocking_mode(listener, 0)) 207 goto err; 208 209 /* 210 * Begin listening. Note that is not usually needed as SSL_accept_connection 211 * will implicitly start listening. It is only needed if a server wishes to 212 * ensure it has started to accept incoming connections but does not wish to 213 * actually call SSL_accept_connection yet. 214 */ 215 if (!SSL_listen(listener)) 216 goto err; 217 218=head2 Server loop 219 220The server now enters a "forever" loop, handling one client connection at a 221time. Before each connection, we clear the OpenSSL error stack so that any 222error reports are related to just the new connection. 223 224 /* Pristine error stack for each new connection */ 225 ERR_clear_error(); 226 227We then wait until a connection is ready for reading. 228It uses the select function to wait until the socket is either readable 229or writable, depending on what the SSL connection requires. 230 231We then accept a new connection in which the handshake will have already 232occurred. However, since we are in nonblocking mode, L<SSL_accept_connection(3)> 233will return immediately. Therefore, we use a helper function to essentially 234block until a connection is established. 235 236 printf("Waiting for connection\n"); 237 while ((conn = SSL_accept_connection(listener, 0)) == NULL) { 238 wait_for_activity(listener); 239 } 240 printf("Accepted new connection\n"); 241 242The helper function wait_for_activity uses select() to block until the file 243descriptor belonging to the passed SSL object is readable. As mentioned earlier, 244a more real-world application would likely use this time to perform other tasks. 245 246 /* Initialize the fd_set structure */ 247 FD_ZERO(&read_fd); 248 FD_ZERO(&write_fd); 249 250 /* 251 * Determine if we would like to write to the socket, read from it, or both. 252 */ 253 if (SSL_net_write_desired(ssl)) 254 FD_SET(sock, &write_fd); 255 if (SSL_net_read_desired(ssl)) 256 FD_SET(sock, &read_fd); 257 258 /* 259 * Find out when OpenSSL would next like to be called, regardless of 260 * whether the state of the underlying socket has changed or not. 261 */ 262 if (SSL_get_event_timeout(ssl, &tv, &isinfinite) && !isinfinite) 263 tvp = &tv; 264 265 /* 266 * Wait until the socket is writeable or readable. We use select here 267 * for the sake of simplicity and portability, but you could equally use 268 * poll/epoll or similar functions 269 * 270 * NOTE: For the purposes of this demonstration code this effectively 271 * makes this demo block until it has something more useful to do. In a 272 * real application you probably want to go and do other work here (e.g. 273 * update a GUI, or service other connections). 274 * 275 * Let's say for example that you want to update the progress counter on 276 * a GUI every 100ms. One way to do that would be to use the timeout in 277 * the last parameter to "select" below. If the tvp value is greater 278 * than 100ms then use 100ms instead. Then, when select returns, you 279 * check if it did so because of activity on the file descriptors or 280 * because of the timeout. If the 100ms GUI timeout has expired but the 281 * tvp timeout has not then go and update the GUI and then restart the 282 * "select" (with updated timeouts). 283 */ 284 285 select(sock + 1, &read_fd, &write_fd, NULL, tvp); 286 287With the handshake complete, the server reads all the client input. 288 289 /* Read from client until the client sends a end of stream packet */ 290 while (!eof) { 291 ret = SSL_read_ex(conn, buf + total_read, sizeof(buf) - total_read, 292 &nread); 293 total_read += nread; 294 if (total_read >= 8192) { 295 fprintf(stderr, "Could not fit all data into buffer\n"); 296 goto err; 297 } 298 switch (handle_io_failure(conn, ret)) { 299 case 1: 300 continue; /* Retry */ 301 case 0: 302 /* Reached end of stream */ 303 if (!SSL_has_pending(conn)) 304 eof = 1; 305 break; 306 default: 307 fprintf(stderr, "Failed reading remaining data\n"); 308 goto err; 309 } 310 } 311 312Finally, we echo the received data back to the client. We can use 313L<SSL_write_ex2(3)> to pass in a special flag SSL_WRITE_FLAG_CONCLUDE that will 314send a FIN packet once the write has successfully finished writing all the data 315to the peer. 316 317 /* Echo client input */ 318 while (!SSL_write_ex2(conn, buf, 319 total_read, 320 SSL_WRITE_FLAG_CONCLUDE, &total_written)) { 321 if (handle_io_failure(conn, 0) == 1) 322 continue; 323 fprintf(stderr, "Failed to write data\n"); 324 goto err; 325 } 326 327We then shut down the connection with L<SSL_shutdown(3)>, which may need 328to be called multiple times to ensure the connection is shutdown completely. 329 330 /* 331 * Shut down the connection. We may need to call this multiple times 332 * to ensure the connection is shutdown completely. 333 */ 334 while ((ret = SSL_shutdown(conn)) != 1) { 335 if (ret < 0 && handle_io_failure(conn, ret) == 1) 336 continue; /* Retry */ 337 } 338 339Finally, we free the SSL connection, and the server is now ready to accept the 340next client connection. 341 342 SSL_free(conn); 343 344=head2 Final clean up 345 346If the server somehow manages to break out of the infinite loop and 347be ready to exit, it would deallocate the constructed B<SSL>. 348 349 SSL_free(listener); 350 351And in the main function, it would deallocate the constructed B<SSL_CTX>. 352 353 SSL_CTX_free(ctx); 354 BIO_closesocket(fd); 355 356=head1 SEE ALSO 357 358L<ossl-guide-introduction(7)>, L<ossl-guide-libraries-introduction(7)>, 359L<ossl-guide-libssl-introduction(7)>, L<ossl-guide-quic-introduction(7)>, 360L<ossl-guide-quic-client-non-block(7)>, L<ossl-guide-quic-client-block(7)>, 361L<ossl-guide-tls-server-block(7)>, L<ossl-guide-quic-server-block(7)> 362 363=head1 COPYRIGHT 364 365Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. 366 367Licensed under the Apache License 2.0 (the "License"). You may not use 368this file except in compliance with the License. You can obtain a copy 369in the file LICENSE in the source distribution or at 370L<https://www.openssl.org/source/license.html>. 371 372=cut 373