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