quic-client-non-block.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. /*
  2. * Copyright 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. * NB: Changes to this file should also be reflected in
  11. * doc/man7/ossl-guide-quic-client-non-block.pod
  12. */
  13. #include <string.h>
  14. /* Include the appropriate header file for SOCK_DGRAM */
  15. #ifdef _WIN32 /* Windows */
  16. # include <winsock2.h>
  17. #else /* Linux/Unix */
  18. # include <sys/socket.h>
  19. # include <sys/select.h>
  20. #endif
  21. #include <openssl/bio.h>
  22. #include <openssl/ssl.h>
  23. #include <openssl/err.h>
  24. /* Helper function to create a BIO connected to the server */
  25. static BIO *create_socket_bio(const char *hostname, const char *port,
  26. int family, BIO_ADDR **peer_addr)
  27. {
  28. int sock = -1;
  29. BIO_ADDRINFO *res;
  30. const BIO_ADDRINFO *ai = NULL;
  31. BIO *bio;
  32. /*
  33. * Lookup IP address info for the server.
  34. */
  35. if (!BIO_lookup_ex(hostname, port, BIO_LOOKUP_CLIENT, family, SOCK_DGRAM, 0,
  36. &res))
  37. return NULL;
  38. /*
  39. * Loop through all the possible addresses for the server and find one
  40. * we can connect to.
  41. */
  42. for (ai = res; ai != NULL; ai = BIO_ADDRINFO_next(ai)) {
  43. /*
  44. * Create a UDP socket. We could equally use non-OpenSSL calls such
  45. * as "socket" here for this and the subsequent connect and close
  46. * functions. But for portability reasons and also so that we get
  47. * errors on the OpenSSL stack in the event of a failure we use
  48. * OpenSSL's versions of these functions.
  49. */
  50. sock = BIO_socket(BIO_ADDRINFO_family(ai), SOCK_DGRAM, 0, 0);
  51. if (sock == -1)
  52. continue;
  53. /* Connect the socket to the server's address */
  54. if (!BIO_connect(sock, BIO_ADDRINFO_address(ai), 0)) {
  55. BIO_closesocket(sock);
  56. sock = -1;
  57. continue;
  58. }
  59. /* Set to nonblocking mode */
  60. if (!BIO_socket_nbio(sock, 1)) {
  61. BIO_closesocket(sock);
  62. sock = -1;
  63. continue;
  64. }
  65. break;
  66. }
  67. if (sock != -1) {
  68. *peer_addr = BIO_ADDR_dup(BIO_ADDRINFO_address(ai));
  69. if (*peer_addr == NULL) {
  70. BIO_closesocket(sock);
  71. return NULL;
  72. }
  73. }
  74. /* Free the address information resources we allocated earlier */
  75. BIO_ADDRINFO_free(res);
  76. /* If sock is -1 then we've been unable to connect to the server */
  77. if (sock == -1)
  78. return NULL;
  79. /* Create a BIO to wrap the socket */
  80. bio = BIO_new(BIO_s_datagram());
  81. if (bio == NULL) {
  82. BIO_closesocket(sock);
  83. return NULL;
  84. }
  85. /*
  86. * Associate the newly created BIO with the underlying socket. By
  87. * passing BIO_CLOSE here the socket will be automatically closed when
  88. * the BIO is freed. Alternatively you can use BIO_NOCLOSE, in which
  89. * case you must close the socket explicitly when it is no longer
  90. * needed.
  91. */
  92. BIO_set_fd(bio, sock, BIO_CLOSE);
  93. return bio;
  94. }
  95. static void wait_for_activity(SSL *ssl)
  96. {
  97. fd_set wfds, rfds;
  98. int width, sock, isinfinite;
  99. struct timeval tv;
  100. struct timeval *tvp = NULL;
  101. /* Get hold of the underlying file descriptor for the socket */
  102. sock = SSL_get_fd(ssl);
  103. FD_ZERO(&wfds);
  104. FD_ZERO(&rfds);
  105. /*
  106. * Find out if we would like to write to the socket, or read from it (or
  107. * both)
  108. */
  109. if (SSL_net_write_desired(ssl))
  110. FD_SET(sock, &wfds);
  111. if (SSL_net_read_desired(ssl))
  112. FD_SET(sock, &rfds);
  113. width = sock + 1;
  114. /*
  115. * Find out when OpenSSL would next like to be called, regardless of
  116. * whether the state of the underlying socket has changed or not.
  117. */
  118. if (SSL_get_event_timeout(ssl, &tv, &isinfinite) && !isinfinite)
  119. tvp = &tv;
  120. /*
  121. * Wait until the socket is writeable or readable. We use select here
  122. * for the sake of simplicity and portability, but you could equally use
  123. * poll/epoll or similar functions
  124. *
  125. * NOTE: For the purposes of this demonstration code this effectively
  126. * makes this demo block until it has something more useful to do. In a
  127. * real application you probably want to go and do other work here (e.g.
  128. * update a GUI, or service other connections).
  129. *
  130. * Let's say for example that you want to update the progress counter on
  131. * a GUI every 100ms. One way to do that would be to use the timeout in
  132. * the last parameter to "select" below. If the tvp value is greater
  133. * than 100ms then use 100ms instead. Then, when select returns, you
  134. * check if it did so because of activity on the file descriptors or
  135. * because of the timeout. If the 100ms GUI timeout has expired but the
  136. * tvp timeout has not then go and update the GUI and then restart the
  137. * "select" (with updated timeouts).
  138. */
  139. select(width, &rfds, &wfds, NULL, tvp);
  140. }
  141. static int handle_io_failure(SSL *ssl, int res)
  142. {
  143. switch (SSL_get_error(ssl, res)) {
  144. case SSL_ERROR_WANT_READ:
  145. case SSL_ERROR_WANT_WRITE:
  146. /* Temporary failure. Wait until we can read/write and try again */
  147. wait_for_activity(ssl);
  148. return 1;
  149. case SSL_ERROR_ZERO_RETURN:
  150. /* EOF */
  151. return 0;
  152. case SSL_ERROR_SYSCALL:
  153. return -1;
  154. case SSL_ERROR_SSL:
  155. /*
  156. * Some stream fatal error occurred. This could be because of a
  157. * stream reset - or some failure occurred on the underlying
  158. * connection.
  159. */
  160. switch (SSL_get_stream_read_state(ssl)) {
  161. case SSL_STREAM_STATE_RESET_REMOTE:
  162. printf("Stream reset occurred\n");
  163. /*
  164. * The stream has been reset but the connection is still
  165. * healthy.
  166. */
  167. break;
  168. case SSL_STREAM_STATE_CONN_CLOSED:
  169. printf("Connection closed\n");
  170. /* Connection is already closed. */
  171. break;
  172. default:
  173. printf("Unknown stream failure\n");
  174. break;
  175. }
  176. /*
  177. * If the failure is due to a verification error we can get more
  178. * information about it from SSL_get_verify_result().
  179. */
  180. if (SSL_get_verify_result(ssl) != X509_V_OK)
  181. printf("Verify error: %s\n",
  182. X509_verify_cert_error_string(SSL_get_verify_result(ssl)));
  183. return -1;
  184. default:
  185. return -1;
  186. }
  187. }
  188. /*
  189. * Simple application to send a basic HTTP/1.0 request to a server and
  190. * print the response on the screen. Note that HTTP/1.0 over QUIC is
  191. * non-standard and will not typically be supported by real world servers. This
  192. * is for demonstration purposes only.
  193. */
  194. int main(int argc, char *argv[])
  195. {
  196. SSL_CTX *ctx = NULL;
  197. SSL *ssl = NULL;
  198. BIO *bio = NULL;
  199. int res = EXIT_FAILURE;
  200. int ret;
  201. unsigned char alpn[] = { 8, 'h', 't', 't', 'p', '/', '1', '.', '0' };
  202. const char *request_start = "GET / HTTP/1.0\r\nConnection: close\r\nHost: ";
  203. const char *request_end = "\r\n\r\n";
  204. size_t written, readbytes;
  205. char buf[160];
  206. BIO_ADDR *peer_addr = NULL;
  207. int eof = 0;
  208. char *hostname, *port;
  209. int ipv6 = 0;
  210. int argnext = 1;
  211. if (argc < 3) {
  212. printf("Usage: quic-client-non-block [-6] hostname port\n");
  213. goto end;
  214. }
  215. if (!strcmp(argv[argnext], "-6")) {
  216. if (argc < 4) {
  217. printf("Usage: quic-client-non-block [-6] hostname port\n");
  218. goto end;
  219. }
  220. ipv6 = 1;
  221. argnext++;
  222. }
  223. hostname = argv[argnext++];
  224. port = argv[argnext];
  225. /*
  226. * Create an SSL_CTX which we can use to create SSL objects from. We
  227. * want an SSL_CTX for creating clients so we use
  228. * OSSL_QUIC_client_method() here.
  229. */
  230. ctx = SSL_CTX_new(OSSL_QUIC_client_method());
  231. if (ctx == NULL) {
  232. printf("Failed to create the SSL_CTX\n");
  233. goto end;
  234. }
  235. /*
  236. * Configure the client to abort the handshake if certificate
  237. * verification fails. Virtually all clients should do this unless you
  238. * really know what you are doing.
  239. */
  240. SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
  241. /* Use the default trusted certificate store */
  242. if (!SSL_CTX_set_default_verify_paths(ctx)) {
  243. printf("Failed to set the default trusted certificate store\n");
  244. goto end;
  245. }
  246. /* Create an SSL object to represent the TLS connection */
  247. ssl = SSL_new(ctx);
  248. if (ssl == NULL) {
  249. printf("Failed to create the SSL object\n");
  250. goto end;
  251. }
  252. /*
  253. * Create the underlying transport socket/BIO and associate it with the
  254. * connection.
  255. */
  256. bio = create_socket_bio(hostname, port, ipv6 ? AF_INET6 : AF_INET,
  257. &peer_addr);
  258. if (bio == NULL) {
  259. printf("Failed to crete the BIO\n");
  260. goto end;
  261. }
  262. SSL_set_bio(ssl, bio, bio);
  263. /*
  264. * Tell the server during the handshake which hostname we are attempting
  265. * to connect to in case the server supports multiple hosts.
  266. */
  267. if (!SSL_set_tlsext_host_name(ssl, hostname)) {
  268. printf("Failed to set the SNI hostname\n");
  269. goto end;
  270. }
  271. /*
  272. * Ensure we check during certificate verification that the server has
  273. * supplied a certificate for the hostname that we were expecting.
  274. * Virtually all clients should do this unless you really know what you
  275. * are doing.
  276. */
  277. if (!SSL_set1_host(ssl, hostname)) {
  278. printf("Failed to set the certificate verification hostname");
  279. goto end;
  280. }
  281. /* SSL_set_alpn_protos returns 0 for success! */
  282. if (SSL_set_alpn_protos(ssl, alpn, sizeof(alpn)) != 0) {
  283. printf("Failed to set the ALPN for the connection\n");
  284. goto end;
  285. }
  286. /* Set the IP address of the remote peer */
  287. if (!SSL_set1_initial_peer_addr(ssl, peer_addr)) {
  288. printf("Failed to set the initial peer address\n");
  289. goto end;
  290. }
  291. /*
  292. * The underlying socket is always nonblocking with QUIC, but the default
  293. * behaviour of the SSL object is still to block. We set it for nonblocking
  294. * mode in this demo.
  295. */
  296. if (!SSL_set_blocking_mode(ssl, 0)) {
  297. printf("Failed to turn off blocking mode\n");
  298. goto end;
  299. }
  300. /* Do the handshake with the server */
  301. while ((ret = SSL_connect(ssl)) != 1) {
  302. if (handle_io_failure(ssl, ret) == 1)
  303. continue; /* Retry */
  304. printf("Failed to connect to server\n");
  305. goto end; /* Cannot retry: error */
  306. }
  307. /* Write an HTTP GET request to the peer */
  308. while (!SSL_write_ex(ssl, request_start, strlen(request_start), &written)) {
  309. if (handle_io_failure(ssl, 0) == 1)
  310. continue; /* Retry */
  311. printf("Failed to write start of HTTP request\n");
  312. goto end; /* Cannot retry: error */
  313. }
  314. while (!SSL_write_ex(ssl, hostname, strlen(hostname), &written)) {
  315. if (handle_io_failure(ssl, 0) == 1)
  316. continue; /* Retry */
  317. printf("Failed to write hostname in HTTP request\n");
  318. goto end; /* Cannot retry: error */
  319. }
  320. while (!SSL_write_ex(ssl, request_end, strlen(request_end), &written)) {
  321. if (handle_io_failure(ssl, 0) == 1)
  322. continue; /* Retry */
  323. printf("Failed to write end of HTTP request\n");
  324. goto end; /* Cannot retry: error */
  325. }
  326. do {
  327. /*
  328. * Get up to sizeof(buf) bytes of the response. We keep reading until
  329. * the server closes the connection.
  330. */
  331. while (!eof && !SSL_read_ex(ssl, buf, sizeof(buf), &readbytes)) {
  332. switch (handle_io_failure(ssl, 0)) {
  333. case 1:
  334. continue; /* Retry */
  335. case 0:
  336. eof = 1;
  337. continue;
  338. case -1:
  339. default:
  340. printf("Failed reading remaining data\n");
  341. goto end; /* Cannot retry: error */
  342. }
  343. }
  344. /*
  345. * OpenSSL does not guarantee that the returned data is a string or
  346. * that it is NUL terminated so we use fwrite() to write the exact
  347. * number of bytes that we read. The data could be non-printable or
  348. * have NUL characters in the middle of it. For this simple example
  349. * we're going to print it to stdout anyway.
  350. */
  351. if (!eof)
  352. fwrite(buf, 1, readbytes, stdout);
  353. } while (!eof);
  354. /* In case the response didn't finish with a newline we add one now */
  355. printf("\n");
  356. /*
  357. * Repeatedly call SSL_shutdown() until the connection is fully
  358. * closed.
  359. */
  360. while ((ret = SSL_shutdown(ssl)) != 1) {
  361. if (ret < 0 && handle_io_failure(ssl, ret) == 1)
  362. continue; /* Retry */
  363. }
  364. /* Success! */
  365. res = EXIT_SUCCESS;
  366. end:
  367. /*
  368. * If something bad happened then we will dump the contents of the
  369. * OpenSSL error stack to stderr. There might be some useful diagnostic
  370. * information there.
  371. */
  372. if (res == EXIT_FAILURE)
  373. ERR_print_errors_fp(stderr);
  374. /*
  375. * Free the resources we allocated. We do not free the BIO object here
  376. * because ownership of it was immediately transferred to the SSL object
  377. * via SSL_set_bio(). The BIO will be freed when we free the SSL object.
  378. */
  379. SSL_free(ssl);
  380. SSL_CTX_free(ctx);
  381. BIO_ADDR_free(peer_addr);
  382. return res;
  383. }