quic-server-non-block.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  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. * NB: Changes to this file should also be reflected in
  11. * doc/man7/ossl-guide-quic-server-non-block.pod
  12. */
  13. #include <string.h>
  14. /* Include the appropriate header file for SOCK_STREAM */
  15. #ifdef _WIN32 /* Windows */
  16. # include <stdarg.h>
  17. # include <winsock2.h>
  18. #else /* Linux/Unix */
  19. # include <err.h>
  20. # include <sys/socket.h>
  21. # include <sys/select.h>
  22. # include <netinet/in.h>
  23. # include <unistd.h>
  24. #endif
  25. #include <openssl/bio.h>
  26. #include <openssl/ssl.h>
  27. #include <openssl/err.h>
  28. #include <openssl/quic.h>
  29. #ifdef _WIN32
  30. static const char *progname;
  31. static void vwarnx(const char *fmt, va_list ap)
  32. {
  33. if (progname != NULL)
  34. fprintf(stderr, "%s: ", progname);
  35. vfprintf(stderr, fmt, ap);
  36. putc('\n', stderr);
  37. }
  38. static void errx(int status, const char *fmt, ...)
  39. {
  40. va_list ap;
  41. va_start(ap, fmt);
  42. vwarnx(fmt, ap);
  43. va_end(ap);
  44. exit(status);
  45. }
  46. static void warnx(const char *fmt, ...)
  47. {
  48. va_list ap;
  49. va_start(ap, fmt);
  50. vwarnx(fmt, ap);
  51. va_end(ap);
  52. }
  53. #endif
  54. /*
  55. * ALPN strings for TLS handshake. Only 'http/1.0' and 'hq-interop'
  56. * are accepted.
  57. */
  58. static const unsigned char alpn_ossltest[] = {
  59. 8, 'h', 't', 't', 'p', '/', '1', '.', '0',
  60. 10, 'h', 'q', '-', 'i', 'n', 't', 'e', 'r', 'o', 'p',
  61. };
  62. /*
  63. * This callback validates and negotiates the desired ALPN on the server side.
  64. */
  65. static int select_alpn(SSL *ssl, const unsigned char **out,
  66. unsigned char *out_len, const unsigned char *in,
  67. unsigned int in_len, void *arg)
  68. {
  69. if (SSL_select_next_proto((unsigned char **)out, out_len, alpn_ossltest,
  70. sizeof(alpn_ossltest), in,
  71. in_len) == OPENSSL_NPN_NEGOTIATED)
  72. return SSL_TLSEXT_ERR_OK;
  73. return SSL_TLSEXT_ERR_ALERT_FATAL;
  74. }
  75. /* Create SSL_CTX. */
  76. static SSL_CTX *create_ctx(const char *cert_path, const char *key_path)
  77. {
  78. SSL_CTX *ctx;
  79. /*
  80. * An SSL_CTX holds shared configuration information for multiple
  81. * subsequent per-client connections. We specifically load a QUIC
  82. * server method here.
  83. */
  84. ctx = SSL_CTX_new(OSSL_QUIC_server_method());
  85. if (ctx == NULL)
  86. goto err;
  87. /*
  88. * Load the server's certificate *chain* file (PEM format), which includes
  89. * not only the leaf (end-entity) server certificate, but also any
  90. * intermediate issuer-CA certificates. The leaf certificate must be the
  91. * first certificate in the file.
  92. *
  93. * In advanced use-cases this can be called multiple times, once per public
  94. * key algorithm for which the server has a corresponding certificate.
  95. * However, the corresponding private key (see below) must be loaded first,
  96. * *before* moving on to the next chain file.
  97. *
  98. * The requisite files "chain.pem" and "pkey.pem" can be generated by running
  99. * "make chain" in this directory. If the server will be executed from some
  100. * other directory, move or copy the files there.
  101. */
  102. if (SSL_CTX_use_certificate_chain_file(ctx, cert_path) <= 0) {
  103. fprintf(stderr, "couldn't load certificate file: %s\n", cert_path);
  104. goto err;
  105. }
  106. /*
  107. * Load the corresponding private key, this also checks that the private
  108. * key matches the just loaded end-entity certificate. It does not check
  109. * whether the certificate chain is valid, the certificates could be
  110. * expired, or may otherwise fail to form a chain that a client can validate.
  111. */
  112. if (SSL_CTX_use_PrivateKey_file(ctx, key_path, SSL_FILETYPE_PEM) <= 0) {
  113. fprintf(stderr, "couldn't load key file: %s\n", key_path);
  114. goto err;
  115. }
  116. /*
  117. * Clients rarely employ certificate-based authentication, and so we don't
  118. * require "mutual" TLS authentication (indeed there's no way to know
  119. * whether or how the client authenticated the server, so the term "mutual"
  120. * is potentially misleading).
  121. *
  122. * Since we're not soliciting or processing client certificates, we don't
  123. * need to configure a trusted-certificate store, so no call to
  124. * SSL_CTX_set_default_verify_paths() is needed. The server's own
  125. * certificate chain is assumed valid.
  126. */
  127. SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
  128. /* Setup ALPN negotiation callback to decide which ALPN is accepted. */
  129. SSL_CTX_set_alpn_select_cb(ctx, select_alpn, NULL);
  130. return ctx;
  131. err:
  132. SSL_CTX_free(ctx);
  133. return NULL;
  134. }
  135. /* Create UDP socket on the given port. */
  136. static int create_socket(uint16_t port)
  137. {
  138. int fd;
  139. struct sockaddr_in sa = {0};
  140. /* Retrieve the file descriptor for a new UDP socket */
  141. if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
  142. fprintf(stderr, "cannot create socket");
  143. return -1;
  144. }
  145. sa.sin_family = AF_INET;
  146. sa.sin_port = htons(port);
  147. /* Bind to the new UDP socket on localhost */
  148. if (bind(fd, (const struct sockaddr *)&sa, sizeof(sa)) < 0) {
  149. fprintf(stderr, "cannot bind to %u\n", port);
  150. BIO_closesocket(fd);
  151. return -1;
  152. }
  153. /* Set port to nonblocking mode */
  154. if (BIO_socket_nbio(fd, 1) <= 0) {
  155. fprintf(stderr, "Unable to set port to nonblocking mode");
  156. BIO_closesocket(fd);
  157. return -1;
  158. }
  159. return fd;
  160. }
  161. /**
  162. * @brief Waits for activity on the SSL socket, either for reading or writing.
  163. *
  164. * This function monitors the underlying file descriptor of the given SSL
  165. * connection to determine when it is ready for reading or writing, or both.
  166. * It uses the select function to wait until the socket is either readable
  167. * or writable, depending on what the SSL connection requires.
  168. *
  169. * @param ssl A pointer to the SSL object representing the connection.
  170. *
  171. * @note This function blocks until there is activity on the socket. In a real
  172. * application, you might want to perform other tasks while waiting, such as
  173. * updating a GUI or handling other connections.
  174. *
  175. * @note This function uses select for simplicity and portability. Depending
  176. * on your application's requirements, you might consider using other
  177. * mechanisms like poll or epoll for handling multiple file descriptors.
  178. */
  179. static void wait_for_activity(SSL *ssl)
  180. {
  181. int sock, isinfinite;
  182. fd_set read_fd, write_fd;
  183. struct timeval tv;
  184. struct timeval *tvp = NULL;
  185. /* Get hold of the underlying file descriptor for the socket */
  186. if ((sock = SSL_get_fd(ssl)) == -1) {
  187. fprintf(stderr, "Unable to get file descriptor");
  188. return;
  189. }
  190. /* Initialize the fd_set structure */
  191. FD_ZERO(&read_fd);
  192. FD_ZERO(&write_fd);
  193. /*
  194. * Determine if we would like to write to the socket, read from it, or both.
  195. */
  196. if (SSL_net_write_desired(ssl))
  197. FD_SET(sock, &write_fd);
  198. if (SSL_net_read_desired(ssl))
  199. FD_SET(sock, &read_fd);
  200. /*
  201. * Find out when OpenSSL would next like to be called, regardless of
  202. * whether the state of the underlying socket has changed or not.
  203. */
  204. if (SSL_get_event_timeout(ssl, &tv, &isinfinite) && !isinfinite)
  205. tvp = &tv;
  206. /*
  207. * Wait until the socket is writeable or readable. We use select here
  208. * for the sake of simplicity and portability, but you could equally use
  209. * poll/epoll or similar functions
  210. *
  211. * NOTE: For the purposes of this demonstration code this effectively
  212. * makes this demo block until it has something more useful to do. In a
  213. * real application you probably want to go and do other work here (e.g.
  214. * update a GUI, or service other connections).
  215. *
  216. * Let's say for example that you want to update the progress counter on
  217. * a GUI every 100ms. One way to do that would be to use the timeout in
  218. * the last parameter to "select" below. If the tvp value is greater
  219. * than 100ms then use 100ms instead. Then, when select returns, you
  220. * check if it did so because of activity on the file descriptors or
  221. * because of the timeout. If the 100ms GUI timeout has expired but the
  222. * tvp timeout has not then go and update the GUI and then restart the
  223. * "select" (with updated timeouts).
  224. */
  225. select(sock + 1, &read_fd, &write_fd, NULL, tvp);
  226. }
  227. /**
  228. * @brief Handles I/O failures on an SSL connection based on the result code.
  229. *
  230. * This function processes the result of an SSL I/O operation and handles
  231. * different types of errors that may occur during the operation. It takes
  232. * appropriate actions such as retrying the operation, reporting errors, or
  233. * returning specific status codes based on the error type.
  234. *
  235. * @param ssl A pointer to the SSL object representing the connection.
  236. * @param res The result code from the SSL I/O operation.
  237. * @return An integer indicating the outcome:
  238. * - 1: Temporary failure, the operation should be retried.
  239. * - 0: EOF, indicating the connection has been closed.
  240. * - -1: A fatal error occurred or the connection has been reset.
  241. *
  242. * @note This function may block if a temporary failure occurs and
  243. * wait_for_activity() is called.
  244. *
  245. * @note If the failure is due to an SSL verification error, additional
  246. * information will be logged to stderr.
  247. */
  248. static int handle_io_failure(SSL *ssl, int res)
  249. {
  250. switch (SSL_get_error(ssl, res)) {
  251. case SSL_ERROR_WANT_READ:
  252. case SSL_ERROR_WANT_WRITE:
  253. /* Temporary failure. Wait until we can read/write and try again */
  254. wait_for_activity(ssl);
  255. return 1;
  256. case SSL_ERROR_ZERO_RETURN:
  257. case SSL_ERROR_NONE:
  258. /* EOF */
  259. return 0;
  260. case SSL_ERROR_SYSCALL:
  261. return -1;
  262. case SSL_ERROR_SSL:
  263. /*
  264. * Some stream fatal error occurred. This could be because of a
  265. * stream reset - or some failure occurred on the underlying
  266. * connection.
  267. */
  268. switch (SSL_get_stream_read_state(ssl)) {
  269. case SSL_STREAM_STATE_RESET_REMOTE:
  270. printf("Stream reset occurred\n");
  271. /*
  272. * The stream has been reset but the connection is still
  273. * healthy.
  274. */
  275. break;
  276. case SSL_STREAM_STATE_CONN_CLOSED:
  277. printf("Connection closed\n");
  278. /* Connection is already closed. */
  279. break;
  280. default:
  281. printf("Unknown stream failure\n");
  282. break;
  283. }
  284. /*
  285. * If the failure is due to a verification error we can get more
  286. * information about it from SSL_get_verify_result().
  287. */
  288. if (SSL_get_verify_result(ssl) != X509_V_OK)
  289. printf("Verify error: %s\n",
  290. X509_verify_cert_error_string(SSL_get_verify_result(ssl)));
  291. return -1;
  292. default:
  293. return -1;
  294. }
  295. }
  296. /*
  297. * Main loop for server to accept QUIC connections.
  298. * Echo every request back to the client.
  299. */
  300. static int run_quic_server(SSL_CTX *ctx, int fd)
  301. {
  302. int ok = -1;
  303. int ret, eof;
  304. SSL *listener, *conn = NULL;
  305. unsigned char buf[8192];
  306. size_t nread, total_read, total_written;
  307. /* Create a new QUIC listener */
  308. if ((listener = SSL_new_listener(ctx, 0)) == NULL)
  309. goto err;
  310. /* Provide the listener with our UDP socket. */
  311. if (!SSL_set_fd(listener, fd))
  312. goto err;
  313. /*
  314. * Set the listener mode to non-blocking, which is inherited by
  315. * child objects.
  316. */
  317. if (!SSL_set_blocking_mode(listener, 0))
  318. goto err;
  319. /*
  320. * Begin listening. Note that is not usually needed as SSL_accept_connection
  321. * will implicitly start listening. It is only needed if a server wishes to
  322. * ensure it has started to accept incoming connections but does not wish to
  323. * actually call SSL_accept_connection yet.
  324. */
  325. if (!SSL_listen(listener))
  326. goto err;
  327. /*
  328. * Begin an infinite loop of listening for connections. We will only
  329. * exit this loop if we encounter an error.
  330. */
  331. for (;;) {
  332. eof = 0;
  333. total_read = 0;
  334. total_written = 0;
  335. /* Pristine error stack for each new connection */
  336. ERR_clear_error();
  337. /* Block while waiting for a client connection */
  338. printf("Waiting for connection\n");
  339. while ((conn = SSL_accept_connection(listener, 0)) == NULL)
  340. wait_for_activity(listener);
  341. printf("Accepted new connection\n");
  342. /* Read from client until the client sends a end of stream packet */
  343. while (!eof) {
  344. ret = SSL_read_ex(conn, buf + total_read, sizeof(buf) - total_read,
  345. &nread);
  346. total_read += nread;
  347. if (total_read >= 8192) {
  348. fprintf(stderr, "Could not fit all data into buffer\n");
  349. goto err;
  350. }
  351. switch (handle_io_failure(conn, ret)) {
  352. case 1:
  353. continue; /* Retry */
  354. case 0:
  355. /* Reached end of stream */
  356. if (!SSL_has_pending(conn))
  357. eof = 1;
  358. break;
  359. default:
  360. fprintf(stderr, "Failed reading remaining data\n");
  361. goto err;
  362. }
  363. }
  364. /* Echo client input */
  365. while (!SSL_write_ex2(conn, buf,
  366. total_read,
  367. SSL_WRITE_FLAG_CONCLUDE, &total_written)) {
  368. if (handle_io_failure(conn, 0) == 1)
  369. continue;
  370. fprintf(stderr, "Failed to write data\n");
  371. goto err;
  372. }
  373. if (total_read != total_written)
  374. fprintf(stderr, "Failed to echo data [read: %lu, written: %lu]\n",
  375. total_read, total_written);
  376. /*
  377. * Shut down the connection. We may need to call this multiple times
  378. * to ensure the connection is shutdown completely.
  379. */
  380. while ((ret = SSL_shutdown(conn)) != 1) {
  381. if (ret < 0 && handle_io_failure(conn, ret) == 1)
  382. continue; /* Retry */
  383. }
  384. SSL_free(conn);
  385. }
  386. ok = EXIT_SUCCESS;
  387. err:
  388. SSL_free(listener);
  389. return ok;
  390. }
  391. /* Minimal QUIC HTTP/1.0 server. */
  392. int main(int argc, char *argv[])
  393. {
  394. int res = EXIT_FAILURE;
  395. SSL_CTX *ctx = NULL;
  396. int fd;
  397. unsigned long port;
  398. #ifdef _WIN32
  399. progname = argv[0];
  400. #endif
  401. if (argc != 4)
  402. errx(res, "usage: %s <port> <server.crt> <server.key>", argv[0]);
  403. /* Create SSL_CTX that supports QUIC. */
  404. if ((ctx = create_ctx(argv[2], argv[3])) == NULL) {
  405. ERR_print_errors_fp(stderr);
  406. errx(res, "Failed to create context");
  407. }
  408. /* Parse port number from command line arguments. */
  409. port = strtoul(argv[1], NULL, 0);
  410. if (port == 0 || port > UINT16_MAX) {
  411. SSL_CTX_free(ctx);
  412. errx(res, "Failed to parse port number");
  413. }
  414. /* Create and bind a UDP socket. */
  415. if ((fd = create_socket((uint16_t)port)) < 0) {
  416. SSL_CTX_free(ctx);
  417. ERR_print_errors_fp(stderr);
  418. errx(res, "Failed to create socket");
  419. }
  420. /* QUIC server connection acceptance loop. */
  421. if (run_quic_server(ctx, fd) < 0) {
  422. SSL_CTX_free(ctx);
  423. BIO_closesocket(fd);
  424. ERR_print_errors_fp(stderr);
  425. errx(res, "Error in QUIC server loop");
  426. }
  427. /* Free resources. */
  428. SSL_CTX_free(ctx);
  429. BIO_closesocket(fd);
  430. res = EXIT_SUCCESS;
  431. return res;
  432. }