quic_tserver_test.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. /*
  2. * Copyright 2022-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. #include <openssl/ssl.h>
  10. #include <openssl/quic.h>
  11. #include <openssl/bio.h>
  12. #include "internal/common.h"
  13. #include "internal/sockets.h"
  14. #include "internal/quic_tserver.h"
  15. #include "internal/quic_thread_assist.h"
  16. #include "internal/quic_ssl.h"
  17. #include "internal/time.h"
  18. #include "testutil.h"
  19. static const char msg1[] = "The quick brown fox jumped over the lazy dogs.";
  20. static char msg2[1024], msg3[1024];
  21. static OSSL_TIME fake_time;
  22. static CRYPTO_RWLOCK *fake_time_lock;
  23. static const char *certfile, *keyfile;
  24. static int is_want(SSL *s, int ret)
  25. {
  26. int ec = SSL_get_error(s, ret);
  27. return ec == SSL_ERROR_WANT_READ || ec == SSL_ERROR_WANT_WRITE;
  28. }
  29. static unsigned char scratch_buf[2048];
  30. static OSSL_TIME fake_now(void *arg)
  31. {
  32. OSSL_TIME t;
  33. if (!CRYPTO_THREAD_read_lock(fake_time_lock))
  34. return ossl_time_zero();
  35. t = fake_time;
  36. CRYPTO_THREAD_unlock(fake_time_lock);
  37. return t;
  38. }
  39. static OSSL_TIME real_now(void *arg)
  40. {
  41. return ossl_time_now();
  42. }
  43. static int do_test(int use_thread_assist, int use_fake_time, int use_inject)
  44. {
  45. int testresult = 0, ret;
  46. int s_fd = -1, c_fd = -1;
  47. BIO *s_net_bio = NULL, *s_net_bio_own = NULL;
  48. BIO *c_net_bio = NULL, *c_net_bio_own = NULL;
  49. BIO *c_pair_own = NULL, *s_pair_own = NULL;
  50. QUIC_TSERVER_ARGS tserver_args = {0};
  51. QUIC_TSERVER *tserver = NULL;
  52. BIO_ADDR *s_addr_ = NULL;
  53. struct in_addr ina = {0};
  54. union BIO_sock_info_u s_info = {0};
  55. SSL_CTX *c_ctx = NULL;
  56. SSL *c_ssl = NULL;
  57. int c_connected = 0, c_write_done = 0, c_begin_read = 0, s_read_done = 0;
  58. int c_wait_eos = 0, c_done_eos = 0;
  59. int c_start_idle_test = 0, c_done_idle_test = 0;
  60. size_t l = 0, s_total_read = 0, s_total_written = 0, c_total_read = 0;
  61. size_t idle_units_done = 0;
  62. int s_begin_write = 0;
  63. OSSL_TIME start_time;
  64. unsigned char alpn[] = { 8, 'o', 's', 's', 'l', 't', 'e', 's', 't' };
  65. size_t limit_ms = 10000;
  66. #if defined(OPENSSL_NO_QUIC_THREAD_ASSIST)
  67. if (use_thread_assist) {
  68. TEST_skip("thread assisted mode not enabled");
  69. return 1;
  70. }
  71. #endif
  72. ina.s_addr = htonl(0x7f000001UL);
  73. /* Setup test server. */
  74. s_fd = BIO_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, 0);
  75. if (!TEST_int_ge(s_fd, 0))
  76. goto err;
  77. if (!TEST_true(BIO_socket_nbio(s_fd, 1)))
  78. goto err;
  79. if (!TEST_ptr(s_addr_ = BIO_ADDR_new()))
  80. goto err;
  81. if (!TEST_true(BIO_ADDR_rawmake(s_addr_, AF_INET, &ina, sizeof(ina), 0)))
  82. goto err;
  83. if (!TEST_true(BIO_bind(s_fd, s_addr_, 0)))
  84. goto err;
  85. s_info.addr = s_addr_;
  86. if (!TEST_true(BIO_sock_info(s_fd, BIO_SOCK_INFO_ADDRESS, &s_info)))
  87. goto err;
  88. if (!TEST_int_gt(BIO_ADDR_rawport(s_addr_), 0))
  89. goto err;
  90. if (!TEST_ptr(s_net_bio = s_net_bio_own = BIO_new_dgram(s_fd, 0)))
  91. goto err;
  92. if (!BIO_up_ref(s_net_bio))
  93. goto err;
  94. fake_time = ossl_ms2time(1000);
  95. tserver_args.net_rbio = s_net_bio;
  96. tserver_args.net_wbio = s_net_bio;
  97. tserver_args.alpn = NULL;
  98. tserver_args.ctx = NULL;
  99. if (use_fake_time)
  100. tserver_args.now_cb = fake_now;
  101. if (!TEST_ptr(tserver = ossl_quic_tserver_new(&tserver_args, certfile,
  102. keyfile))) {
  103. BIO_free(s_net_bio);
  104. goto err;
  105. }
  106. s_net_bio_own = NULL;
  107. if (use_inject) {
  108. /*
  109. * In inject mode we create a dgram pair to feed to the QUIC client on
  110. * the read side. We don't feed anything to this, it is just a
  111. * placeholder to give the client something which never returns any
  112. * datagrams.
  113. */
  114. if (!TEST_true(BIO_new_bio_dgram_pair(&c_pair_own, 5000,
  115. &s_pair_own, 5000)))
  116. goto err;
  117. }
  118. /* Setup test client. */
  119. c_fd = BIO_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, 0);
  120. if (!TEST_int_ge(c_fd, 0))
  121. goto err;
  122. if (!TEST_true(BIO_socket_nbio(c_fd, 1)))
  123. goto err;
  124. if (!TEST_ptr(c_net_bio = c_net_bio_own = BIO_new_dgram(c_fd, 0)))
  125. goto err;
  126. if (!BIO_dgram_set_peer(c_net_bio, s_addr_))
  127. goto err;
  128. if (!TEST_ptr(c_ctx = SSL_CTX_new(use_thread_assist
  129. ? OSSL_QUIC_client_thread_method()
  130. : OSSL_QUIC_client_method())))
  131. goto err;
  132. if (!TEST_ptr(c_ssl = SSL_new(c_ctx)))
  133. goto err;
  134. if (use_fake_time)
  135. if (!TEST_true(ossl_quic_conn_set_override_now_cb(c_ssl, fake_now, NULL)))
  136. goto err;
  137. /* 0 is a success for SSL_set_alpn_protos() */
  138. if (!TEST_false(SSL_set_alpn_protos(c_ssl, alpn, sizeof(alpn))))
  139. goto err;
  140. /* Takes ownership of our reference to the BIO. */
  141. if (use_inject) {
  142. SSL_set0_rbio(c_ssl, c_pair_own);
  143. c_pair_own = NULL;
  144. } else {
  145. SSL_set0_rbio(c_ssl, c_net_bio);
  146. /* Get another reference to be transferred in the SSL_set0_wbio call. */
  147. if (!TEST_true(BIO_up_ref(c_net_bio))) {
  148. c_net_bio_own = NULL; /* SSL_free will free the first reference. */
  149. goto err;
  150. }
  151. }
  152. SSL_set0_wbio(c_ssl, c_net_bio);
  153. c_net_bio_own = NULL;
  154. if (!TEST_true(SSL_set_blocking_mode(c_ssl, 0)))
  155. goto err;
  156. /*
  157. * We use real time for the timeout not fake time. Otherwise with fake time
  158. * we could hit a hang if we never increment the fake time
  159. */
  160. start_time = real_now(NULL);
  161. for (;;) {
  162. if (ossl_time_compare(ossl_time_subtract(real_now(NULL), start_time),
  163. ossl_ms2time(limit_ms)) >= 0) {
  164. TEST_error("timeout while attempting QUIC server test");
  165. goto err;
  166. }
  167. if (!c_start_idle_test) {
  168. ret = SSL_connect(c_ssl);
  169. if (!TEST_true(ret == 1 || is_want(c_ssl, ret)))
  170. goto err;
  171. if (ret == 1)
  172. c_connected = 1;
  173. }
  174. if (c_connected && !c_write_done) {
  175. if (!TEST_int_eq(SSL_write(c_ssl, msg1, sizeof(msg1) - 1),
  176. (int)sizeof(msg1) - 1))
  177. goto err;
  178. if (!TEST_true(SSL_stream_conclude(c_ssl, 0)))
  179. goto err;
  180. c_write_done = 1;
  181. }
  182. if (c_connected && c_write_done && !s_read_done) {
  183. if (!ossl_quic_tserver_read(tserver, 0,
  184. (unsigned char *)msg2 + s_total_read,
  185. sizeof(msg2) - s_total_read, &l)) {
  186. if (!TEST_true(ossl_quic_tserver_has_read_ended(tserver, 0)))
  187. goto err;
  188. if (!TEST_mem_eq(msg1, sizeof(msg1) - 1, msg2, s_total_read))
  189. goto err;
  190. s_begin_write = 1;
  191. s_read_done = 1;
  192. } else {
  193. s_total_read += l;
  194. if (!TEST_size_t_le(s_total_read, sizeof(msg1) - 1))
  195. goto err;
  196. }
  197. }
  198. if (s_begin_write && s_total_written < sizeof(msg1) - 1) {
  199. if (!TEST_true(ossl_quic_tserver_write(tserver, 0,
  200. (unsigned char *)msg2 + s_total_written,
  201. sizeof(msg1) - 1 - s_total_written, &l)))
  202. goto err;
  203. s_total_written += l;
  204. if (s_total_written == sizeof(msg1) - 1) {
  205. ossl_quic_tserver_conclude(tserver, 0);
  206. c_begin_read = 1;
  207. }
  208. }
  209. if (c_begin_read && c_total_read < sizeof(msg1) - 1) {
  210. ret = SSL_read_ex(c_ssl, msg3 + c_total_read,
  211. sizeof(msg1) - 1 - c_total_read, &l);
  212. if (!TEST_true(ret == 1 || is_want(c_ssl, ret)))
  213. goto err;
  214. c_total_read += l;
  215. if (c_total_read == sizeof(msg1) - 1) {
  216. if (!TEST_mem_eq(msg1, sizeof(msg1) - 1,
  217. msg3, c_total_read))
  218. goto err;
  219. c_wait_eos = 1;
  220. }
  221. }
  222. if (c_wait_eos && !c_done_eos) {
  223. unsigned char c;
  224. ret = SSL_read_ex(c_ssl, &c, sizeof(c), &l);
  225. if (!TEST_false(ret))
  226. goto err;
  227. /*
  228. * Allow the implementation to take as long as it wants to finally
  229. * notice EOS. Account for varied timings in OS networking stacks.
  230. */
  231. if (SSL_get_error(c_ssl, ret) != SSL_ERROR_WANT_READ) {
  232. if (!TEST_int_eq(SSL_get_error(c_ssl, ret),
  233. SSL_ERROR_ZERO_RETURN))
  234. goto err;
  235. c_done_eos = 1;
  236. if (use_thread_assist && use_fake_time) {
  237. if (!TEST_true(ossl_quic_tserver_is_connected(tserver)))
  238. goto err;
  239. c_start_idle_test = 1;
  240. limit_ms = 120000; /* extend time limit */
  241. } else {
  242. /* DONE */
  243. break;
  244. }
  245. }
  246. }
  247. if (c_start_idle_test && !c_done_idle_test) {
  248. /* This is more than our default idle timeout of 30s. */
  249. if (idle_units_done < 600) {
  250. struct timeval tv;
  251. int isinf;
  252. if (!TEST_true(CRYPTO_THREAD_write_lock(fake_time_lock)))
  253. goto err;
  254. fake_time = ossl_time_add(fake_time, ossl_ms2time(100));
  255. CRYPTO_THREAD_unlock(fake_time_lock);
  256. ++idle_units_done;
  257. ossl_quic_conn_force_assist_thread_wake(c_ssl);
  258. /*
  259. * If the event timeout has expired then give the assistance
  260. * thread a chance to catch up
  261. */
  262. if (!TEST_true(SSL_get_event_timeout(c_ssl, &tv, &isinf)))
  263. goto err;
  264. if (!isinf && ossl_time_compare(ossl_time_zero(),
  265. ossl_time_from_timeval(tv)) >= 0)
  266. OSSL_sleep(100); /* Ensure CPU scheduling for test purposes */
  267. } else {
  268. c_done_idle_test = 1;
  269. }
  270. }
  271. if (c_done_idle_test) {
  272. /*
  273. * If we have finished the fake idling duration, the connection
  274. * should still be healthy in TA mode.
  275. */
  276. if (!TEST_true(ossl_quic_tserver_is_connected(tserver)))
  277. goto err;
  278. /* DONE */
  279. break;
  280. }
  281. /*
  282. * This is inefficient because we spin until things work without
  283. * blocking but this is just a test.
  284. */
  285. if (!c_start_idle_test || c_done_idle_test) {
  286. /* Inhibit manual ticking during idle test to test TA mode. */
  287. SSL_handle_events(c_ssl);
  288. }
  289. ossl_quic_tserver_tick(tserver);
  290. if (use_inject) {
  291. BIO_MSG rmsg = {0};
  292. size_t msgs_processed = 0;
  293. for (;;) {
  294. /*
  295. * Manually spoonfeed received datagrams from the real BIO_dgram
  296. * into QUIC via the injection interface, thereby testing the
  297. * injection interface.
  298. */
  299. rmsg.data = scratch_buf;
  300. rmsg.data_len = sizeof(scratch_buf);
  301. if (!BIO_recvmmsg(c_net_bio, &rmsg, sizeof(rmsg), 1, 0, &msgs_processed)
  302. || msgs_processed == 0 || rmsg.data_len == 0)
  303. break;
  304. if (!TEST_true(SSL_inject_net_dgram(c_ssl, rmsg.data, rmsg.data_len,
  305. NULL, NULL)))
  306. goto err;
  307. }
  308. }
  309. }
  310. testresult = 1;
  311. err:
  312. SSL_free(c_ssl);
  313. SSL_CTX_free(c_ctx);
  314. ossl_quic_tserver_free(tserver);
  315. BIO_ADDR_free(s_addr_);
  316. BIO_free(s_net_bio_own);
  317. BIO_free(c_net_bio_own);
  318. BIO_free(c_pair_own);
  319. BIO_free(s_pair_own);
  320. if (s_fd >= 0)
  321. BIO_closesocket(s_fd);
  322. if (c_fd >= 0)
  323. BIO_closesocket(c_fd);
  324. return testresult;
  325. }
  326. static int test_tserver(int idx)
  327. {
  328. int thread_assisted, use_fake_time, use_inject;
  329. thread_assisted = idx % 2;
  330. idx /= 2;
  331. use_inject = idx % 2;
  332. idx /= 2;
  333. use_fake_time = idx % 2;
  334. if (use_fake_time && !thread_assisted)
  335. return 1;
  336. return do_test(thread_assisted, use_fake_time, use_inject);
  337. }
  338. OPT_TEST_DECLARE_USAGE("certfile privkeyfile\n")
  339. int setup_tests(void)
  340. {
  341. if (!test_skip_common_options()) {
  342. TEST_error("Error parsing test options\n");
  343. return 0;
  344. }
  345. if (!TEST_ptr(certfile = test_get_argument(0))
  346. || !TEST_ptr(keyfile = test_get_argument(1)))
  347. return 0;
  348. if ((fake_time_lock = CRYPTO_THREAD_lock_new()) == NULL)
  349. return 0;
  350. ADD_ALL_TESTS(test_tserver, 2 * 2 * 2);
  351. return 1;
  352. }