1 /* $NetBSD: doh_test.c,v 1.3 2025/01/26 16:25:49 christos Exp $ */ 2 3 /* 4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 * 6 * SPDX-License-Identifier: MPL-2.0 7 * 8 * This Source Code Form is subject to the terms of the Mozilla Public 9 * License, v. 2.0. If a copy of the MPL was not distributed with this 10 * file, you can obtain one at https://mozilla.org/MPL/2.0/. 11 * 12 * See the COPYRIGHT file distributed with this work for additional 13 * information regarding copyright ownership. 14 */ 15 16 #include <inttypes.h> 17 #include <sched.h> /* IWYU pragma: keep */ 18 #include <setjmp.h> 19 #include <stdarg.h> 20 #include <stdbool.h> 21 #include <stddef.h> 22 #include <stdlib.h> 23 #include <time.h> 24 #include <unistd.h> 25 26 /* 27 * As a workaround, include an OpenSSL header file before including cmocka.h, 28 * because OpenSSL 3.1.0 uses __attribute__(malloc), conflicting with a 29 * redefined malloc in cmocka.h. 30 */ 31 #include <openssl/err.h> 32 33 #define UNIT_TESTING 34 #include <cmocka.h> 35 36 #include <isc/async.h> 37 #include <isc/atomic.h> 38 #include <isc/buffer.h> 39 #include <isc/condition.h> 40 #include <isc/mutex.h> 41 #include <isc/netmgr.h> 42 #include <isc/nonce.h> 43 #include <isc/os.h> 44 #include <isc/refcount.h> 45 #include <isc/sockaddr.h> 46 #include <isc/thread.h> 47 #include <isc/util.h> 48 #include <isc/uv.h> 49 50 #include "uv_wrap.h" 51 #define KEEP_BEFORE 52 53 #include "netmgr/http.c" 54 #include "netmgr/netmgr-int.h" 55 #include "netmgr/socket.c" 56 57 #include <tests/isc.h> 58 59 #define MAX_NM 2 60 61 static isc_sockaddr_t tcp_listen_addr; 62 63 static uint64_t send_magic = 0; 64 static uint64_t stop_magic = 0; 65 66 static uv_buf_t send_msg = { .base = (char *)&send_magic, 67 .len = sizeof(send_magic) }; 68 69 static atomic_int_fast64_t active_cconnects = 0; 70 static atomic_int_fast64_t nsends = 0; 71 static atomic_int_fast64_t ssends = 0; 72 static atomic_int_fast64_t sreads = 0; 73 static atomic_int_fast64_t csends = 0; 74 static atomic_int_fast64_t creads = 0; 75 static atomic_int_fast64_t ctimeouts = 0; 76 static atomic_int_fast64_t total_sends = 0; 77 78 static int expected_ssends; 79 static int expected_sreads; 80 static int expected_csends; 81 static int expected_cconnects; 82 static int expected_creads; 83 static int expected_ctimeouts; 84 85 #define have_expected_ssends(v) ((v) >= expected_ssends && expected_ssends >= 0) 86 #define have_expected_sreads(v) ((v) >= expected_sreads && expected_sreads >= 0) 87 #define have_expected_csends(v) ((v) >= expected_csends && expected_csends >= 0) 88 #define have_expected_cconnects(v) \ 89 ((v) >= expected_cconnects && expected_cconnects >= 0) 90 #define have_expected_creads(v) ((v) >= expected_creads && expected_creads >= 0) 91 #define have_expected_ctimeouts(v) \ 92 ((v) >= expected_ctimeouts && expected_ctimeouts >= 0) 93 94 static bool noanswer = false; 95 96 static atomic_bool POST = true; 97 98 static atomic_bool use_TLS = false; 99 static isc_tlsctx_t *server_tlsctx = NULL; 100 static isc_tlsctx_t *client_tlsctx = NULL; 101 static isc_tlsctx_client_session_cache_t *client_sess_cache = NULL; 102 103 static isc_quota_t listener_quota; 104 static atomic_bool check_listener_quota = false; 105 106 static isc_nm_http_endpoints_t *endpoints = NULL; 107 108 static atomic_bool use_PROXY = false; 109 static atomic_bool use_PROXY_over_TLS = false; 110 111 static isc_nm_t **nm = NULL; 112 113 /* Timeout for soft-timeout tests (0.05 seconds) */ 114 #define T_SOFT 50 115 #define T_CONNECT 30 * 1000 116 117 #define NSENDS 100 118 #define NWRITES 10 119 120 #define CHECK_RANGE_FULL(v) \ 121 { \ 122 int __v = atomic_load(&v); \ 123 assert_true(__v >= atomic_load(&total_sends)); \ 124 } 125 126 #define CHECK_RANGE_HALF(v) \ 127 { \ 128 int __v = atomic_load(&v); \ 129 assert_true(__v >= atomic_load(&total_sends) / 2); \ 130 } 131 132 /* Enable this to print values while running tests */ 133 #undef PRINT_DEBUG 134 #ifdef PRINT_DEBUG 135 #define X(v) fprintf(stderr, #v " = %" PRIu64 "\n", atomic_load(&v)) 136 #else 137 #define X(v) 138 #endif 139 140 static isc_nm_proxy_type_t 141 get_proxy_type(void) { 142 if (!atomic_load(&use_PROXY)) { 143 return ISC_NM_PROXY_NONE; 144 } else if (atomic_load(&use_TLS) && atomic_load(&use_PROXY_over_TLS)) { 145 return ISC_NM_PROXY_ENCRYPTED; 146 } 147 148 return ISC_NM_PROXY_PLAIN; 149 } 150 151 static void 152 proxy_verify_unspec_endpoint(isc_nmhandle_t *handle) { 153 isc_sockaddr_t real_local, real_peer, local, peer; 154 155 if (isc_nm_is_proxy_unspec(handle)) { 156 peer = isc_nmhandle_peeraddr(handle); 157 local = isc_nmhandle_localaddr(handle); 158 real_peer = isc_nmhandle_real_peeraddr(handle); 159 real_local = isc_nmhandle_real_localaddr(handle); 160 161 assert_true(isc_sockaddr_equal(&peer, &real_peer)); 162 assert_true(isc_sockaddr_equal(&local, &real_local)); 163 } 164 } 165 166 typedef struct csdata { 167 isc_mem_t *mctx; 168 isc_nm_recv_cb_t reply_cb; 169 void *cb_arg; 170 isc_region_t region; 171 } csdata_t; 172 173 static void 174 connect_send_cb(isc_nmhandle_t *handle, isc_result_t result, void *arg) { 175 csdata_t data; 176 177 (void)atomic_fetch_sub(&active_cconnects, 1); 178 memmove(&data, arg, sizeof(data)); 179 isc_mem_put(data.mctx, arg, sizeof(data)); 180 if (result != ISC_R_SUCCESS) { 181 goto error; 182 } 183 184 REQUIRE(VALID_NMHANDLE(handle)); 185 186 result = isc__nm_http_request(handle, &data.region, data.reply_cb, 187 data.cb_arg); 188 if (result != ISC_R_SUCCESS) { 189 goto error; 190 } 191 192 isc_mem_putanddetach(&data.mctx, data.region.base, data.region.length); 193 return; 194 error: 195 data.reply_cb(handle, result, NULL, data.cb_arg); 196 isc_mem_putanddetach(&data.mctx, data.region.base, data.region.length); 197 } 198 199 static void 200 connect_send_request(isc_nm_t *mgr, const char *uri, bool post, 201 isc_region_t *region, isc_nm_recv_cb_t cb, void *cbarg, 202 bool tls, unsigned int timeout) { 203 isc_region_t copy; 204 csdata_t *data = NULL; 205 isc_tlsctx_t *ctx = NULL; 206 207 copy = (isc_region_t){ .base = isc_mem_get(mgr->mctx, region->length), 208 .length = region->length }; 209 memmove(copy.base, region->base, region->length); 210 data = isc_mem_get(mgr->mctx, sizeof(*data)); 211 *data = (csdata_t){ .reply_cb = cb, .cb_arg = cbarg, .region = copy }; 212 isc_mem_attach(mgr->mctx, &data->mctx); 213 if (tls) { 214 ctx = client_tlsctx; 215 } 216 217 isc_nm_httpconnect(mgr, NULL, &tcp_listen_addr, uri, post, 218 connect_send_cb, data, ctx, client_sess_cache, 219 timeout, get_proxy_type(), NULL); 220 } 221 222 static int 223 setup_ephemeral_port(isc_sockaddr_t *addr, sa_family_t family) { 224 isc_result_t result; 225 socklen_t addrlen = sizeof(*addr); 226 int fd; 227 int r; 228 229 isc_sockaddr_fromin6(addr, &in6addr_loopback, 0); 230 231 fd = socket(AF_INET6, family, 0); 232 if (fd < 0) { 233 perror("setup_ephemeral_port: socket()"); 234 return -1; 235 } 236 237 r = bind(fd, (const struct sockaddr *)&addr->type.sa, 238 sizeof(addr->type.sin6)); 239 if (r != 0) { 240 perror("setup_ephemeral_port: bind()"); 241 isc__nm_closesocket(fd); 242 return r; 243 } 244 245 r = getsockname(fd, (struct sockaddr *)&addr->type.sa, &addrlen); 246 if (r != 0) { 247 perror("setup_ephemeral_port: getsockname()"); 248 isc__nm_closesocket(fd); 249 return r; 250 } 251 252 result = isc__nm_socket_reuse(fd, 1); 253 if (result != ISC_R_SUCCESS && result != ISC_R_NOTIMPLEMENTED) { 254 fprintf(stderr, 255 "setup_ephemeral_port: isc__nm_socket_reuse(): %s", 256 isc_result_totext(result)); 257 close(fd); 258 return -1; 259 } 260 261 result = isc__nm_socket_reuse_lb(fd); 262 if (result != ISC_R_SUCCESS && result != ISC_R_NOTIMPLEMENTED) { 263 fprintf(stderr, 264 "setup_ephemeral_port: isc__nm_socket_reuse_lb(): %s", 265 isc_result_totext(result)); 266 close(fd); 267 return -1; 268 } 269 270 #if IPV6_RECVERR 271 #define setsockopt_on(socket, level, name) \ 272 setsockopt(socket, level, name, &(int){ 1 }, sizeof(int)) 273 274 r = setsockopt_on(fd, IPPROTO_IPV6, IPV6_RECVERR); 275 if (r != 0) { 276 perror("setup_ephemeral_port"); 277 close(fd); 278 return r; 279 } 280 #endif 281 282 return fd; 283 } 284 285 /* Generic */ 286 287 static void 288 noop_read_cb(isc_nmhandle_t *handle, isc_result_t result, isc_region_t *region, 289 void *cbarg) { 290 UNUSED(handle); 291 UNUSED(result); 292 UNUSED(region); 293 UNUSED(cbarg); 294 } 295 296 thread_local uint8_t tcp_buffer_storage[4096]; 297 thread_local size_t tcp_buffer_length = 0; 298 299 static int 300 setup_test(void **state) { 301 char *env_workers = getenv("ISC_TASK_WORKERS"); 302 uv_os_sock_t tcp_listen_sock = -1; 303 304 tcp_listen_addr = (isc_sockaddr_t){ .length = 0 }; 305 tcp_listen_sock = setup_ephemeral_port(&tcp_listen_addr, SOCK_STREAM); 306 if (tcp_listen_sock < 0) { 307 return -1; 308 } 309 close(tcp_listen_sock); 310 tcp_listen_sock = -1; 311 312 if (env_workers != NULL) { 313 workers = atoi(env_workers); 314 } else { 315 workers = isc_os_ncpus(); 316 } 317 INSIST(workers > 0); 318 319 atomic_store(&total_sends, NSENDS * NWRITES); 320 atomic_store(&nsends, atomic_load(&total_sends)); 321 322 atomic_store(&csends, 0); 323 atomic_store(&creads, 0); 324 atomic_store(&sreads, 0); 325 atomic_store(&ssends, 0); 326 atomic_store(&ctimeouts, 0); 327 atomic_store(&active_cconnects, 0); 328 329 expected_cconnects = -1; 330 expected_csends = -1; 331 expected_creads = -1; 332 expected_sreads = -1; 333 expected_ssends = -1; 334 expected_ctimeouts = -1; 335 336 atomic_store(&POST, false); 337 atomic_store(&use_TLS, false); 338 atomic_store(&use_PROXY, false); 339 atomic_store(&use_PROXY_over_TLS, false); 340 341 noanswer = false; 342 343 isc_nonce_buf(&send_magic, sizeof(send_magic)); 344 isc_nonce_buf(&stop_magic, sizeof(stop_magic)); 345 if (send_magic == stop_magic) { 346 return -1; 347 } 348 349 setup_loopmgr(state); 350 351 nm = isc_mem_cget(mctx, MAX_NM, sizeof(nm[0])); 352 for (size_t i = 0; i < MAX_NM; i++) { 353 isc_netmgr_create(mctx, loopmgr, &nm[i]); 354 assert_non_null(nm[i]); 355 } 356 357 server_tlsctx = NULL; 358 isc_tlsctx_createserver(NULL, NULL, &server_tlsctx); 359 isc_tlsctx_enable_http2server_alpn(server_tlsctx); 360 client_tlsctx = NULL; 361 isc_tlsctx_createclient(&client_tlsctx); 362 isc_tlsctx_enable_http2client_alpn(client_tlsctx); 363 isc_tlsctx_client_session_cache_create( 364 mctx, client_tlsctx, 365 ISC_TLSCTX_CLIENT_SESSION_CACHE_DEFAULT_SIZE, 366 &client_sess_cache); 367 368 isc_quota_init(&listener_quota, 0); 369 atomic_store(&check_listener_quota, false); 370 371 INSIST(endpoints == NULL); 372 endpoints = isc_nm_http_endpoints_new(mctx); 373 374 *state = nm; 375 376 return 0; 377 } 378 379 static int 380 teardown_test(void **state ISC_ATTR_UNUSED) { 381 for (size_t i = 0; i < MAX_NM; i++) { 382 isc_netmgr_destroy(&nm[i]); 383 assert_null(nm[i]); 384 } 385 isc_mem_cput(mctx, nm, MAX_NM, sizeof(nm[0])); 386 387 teardown_loopmgr(state); 388 389 if (server_tlsctx != NULL) { 390 isc_tlsctx_free(&server_tlsctx); 391 } 392 if (client_tlsctx != NULL) { 393 isc_tlsctx_free(&client_tlsctx); 394 } 395 396 isc_tlsctx_client_session_cache_detach(&client_sess_cache); 397 398 isc_quota_destroy(&listener_quota); 399 400 isc_nm_http_endpoints_detach(&endpoints); 401 402 return 0; 403 } 404 405 thread_local size_t nwrites = NWRITES; 406 407 static void 408 sockaddr_to_url(isc_sockaddr_t *sa, const bool https, char *outbuf, 409 size_t outbuf_len, const char *append) { 410 isc_nm_http_makeuri(https, sa, NULL, 0, append, outbuf, outbuf_len); 411 } 412 413 static isc_quota_t * 414 init_listener_quota(size_t nthreads) { 415 isc_quota_t *quotap = NULL; 416 if (atomic_load(&check_listener_quota)) { 417 unsigned int max_quota = ISC_MAX(nthreads / 2, 1); 418 isc_quota_max(&listener_quota, max_quota); 419 quotap = &listener_quota; 420 } 421 return quotap; 422 } 423 424 static void 425 doh_receive_reply_cb(isc_nmhandle_t *handle, isc_result_t eresult, 426 isc_region_t *region, void *cbarg) { 427 assert_non_null(handle); 428 UNUSED(cbarg); 429 UNUSED(region); 430 431 if (eresult == ISC_R_SUCCESS) { 432 if (atomic_load(&use_PROXY)) { 433 assert_true(isc_nm_is_proxy_handle(handle)); 434 } 435 (void)atomic_fetch_sub(&nsends, 1); 436 if (have_expected_csends(atomic_fetch_add(&csends, 1) + 1) || 437 have_expected_creads(atomic_fetch_add(&creads, 1) + 1)) 438 { 439 isc_loopmgr_shutdown(loopmgr); 440 } 441 } else { 442 isc_loopmgr_shutdown(loopmgr); 443 } 444 } 445 446 static void 447 doh_reply_sent_cb(isc_nmhandle_t *handle, isc_result_t eresult, void *cbarg) { 448 UNUSED(eresult); 449 UNUSED(cbarg); 450 451 assert_non_null(handle); 452 453 if (eresult == ISC_R_SUCCESS) { 454 atomic_fetch_add(&ssends, 1); 455 } 456 } 457 458 static void 459 doh_receive_request_cb(isc_nmhandle_t *handle, isc_result_t eresult, 460 isc_region_t *region, void *cbarg) { 461 uint64_t magic = 0; 462 463 UNUSED(cbarg); 464 assert_non_null(handle); 465 466 if (eresult != ISC_R_SUCCESS) { 467 return; 468 } 469 470 if (atomic_load(&use_PROXY)) { 471 assert_true(isc_nm_is_proxy_handle(handle)); 472 proxy_verify_unspec_endpoint(handle); 473 } 474 475 atomic_fetch_add(&sreads, 1); 476 477 memmove(tcp_buffer_storage + tcp_buffer_length, region->base, 478 region->length); 479 tcp_buffer_length += region->length; 480 481 while (tcp_buffer_length >= sizeof(magic)) { 482 magic = *(uint64_t *)tcp_buffer_storage; 483 assert_true(magic == stop_magic || magic == send_magic); 484 485 tcp_buffer_length -= sizeof(magic); 486 memmove(tcp_buffer_storage, tcp_buffer_storage + sizeof(magic), 487 tcp_buffer_length); 488 489 if (magic == send_magic) { 490 if (!noanswer) { 491 isc_nm_send(handle, region, doh_reply_sent_cb, 492 NULL); 493 } 494 return; 495 } else if (magic == stop_magic) { 496 /* 497 * We are done, so we don't send anything back. 498 * There should be no more packets in the buffer. 499 */ 500 assert_int_equal(tcp_buffer_length, 0); 501 } 502 } 503 } 504 505 ISC_LOOP_TEST_IMPL(mock_doh_uv_tcp_bind) { 506 isc_nm_t *listen_nm = nm[0]; 507 isc_result_t result = ISC_R_SUCCESS; 508 isc_nmsocket_t *listen_sock = NULL; 509 510 WILL_RETURN(uv_tcp_bind, UV_EADDRINUSE); 511 512 result = isc_nm_http_endpoints_add(endpoints, ISC_NM_HTTP_DEFAULT_PATH, 513 noop_read_cb, NULL); 514 assert_int_equal(result, ISC_R_SUCCESS); 515 result = isc_nm_listenhttp(listen_nm, ISC_NM_LISTEN_ALL, 516 &tcp_listen_addr, 0, NULL, NULL, endpoints, 517 0, false, &listen_sock); 518 assert_int_not_equal(result, ISC_R_SUCCESS); 519 assert_null(listen_sock); 520 521 RESET_RETURN; 522 523 isc_loopmgr_shutdown(loopmgr); 524 } 525 526 static void 527 listen_sock_close(void *arg) { 528 isc_nmsocket_t *listen_sock = arg; 529 530 isc_nm_stoplistening(listen_sock); 531 isc_nmsocket_close(&listen_sock); 532 assert_null(listen_sock); 533 } 534 535 static void 536 doh_noop(void *arg ISC_ATTR_UNUSED) { 537 isc_nm_t *listen_nm = nm[0]; 538 isc_nm_t *connect_nm = nm[1]; 539 isc_result_t result = ISC_R_SUCCESS; 540 isc_nmsocket_t *listen_sock = NULL; 541 char req_url[256]; 542 543 result = isc_nm_http_endpoints_add(endpoints, ISC_NM_HTTP_DEFAULT_PATH, 544 noop_read_cb, NULL); 545 assert_int_equal(result, ISC_R_SUCCESS); 546 547 result = isc_nm_listenhttp(listen_nm, ISC_NM_LISTEN_ALL, 548 &tcp_listen_addr, 0, NULL, NULL, endpoints, 549 0, get_proxy_type(), &listen_sock); 550 assert_int_equal(result, ISC_R_SUCCESS); 551 isc_loop_teardown(mainloop, listen_sock_close, listen_sock); 552 553 sockaddr_to_url(&tcp_listen_addr, false, req_url, sizeof(req_url), 554 ISC_NM_HTTP_DEFAULT_PATH); 555 connect_send_request(connect_nm, req_url, atomic_load(&POST), 556 &(isc_region_t){ .base = (uint8_t *)send_msg.base, 557 .length = send_msg.len }, 558 noop_read_cb, NULL, atomic_load(&use_TLS), 30000); 559 560 isc_loopmgr_shutdown(loopmgr); 561 562 assert_int_equal(0, atomic_load(&csends)); 563 assert_int_equal(0, atomic_load(&creads)); 564 assert_int_equal(0, atomic_load(&sreads)); 565 assert_int_equal(0, atomic_load(&ssends)); 566 } 567 568 ISC_LOOP_TEST_IMPL(doh_noop_POST) { 569 atomic_store(&POST, true); 570 doh_noop(arg); 571 } 572 573 ISC_LOOP_TEST_IMPL(doh_noop_GET) { 574 atomic_store(&POST, false); 575 doh_noop(arg); 576 } 577 578 static void 579 doh_noresponse(void *arg ISC_ATTR_UNUSED) { 580 isc_nm_t *listen_nm = nm[0]; 581 isc_nm_t *connect_nm = nm[1]; 582 isc_result_t result = ISC_R_SUCCESS; 583 isc_nmsocket_t *listen_sock = NULL; 584 char req_url[256]; 585 586 result = isc_nm_http_endpoints_add(endpoints, ISC_NM_HTTP_DEFAULT_PATH, 587 noop_read_cb, NULL); 588 assert_int_equal(result, ISC_R_SUCCESS); 589 590 result = isc_nm_listenhttp(listen_nm, ISC_NM_LISTEN_ALL, 591 &tcp_listen_addr, 0, NULL, NULL, endpoints, 592 0, get_proxy_type(), &listen_sock); 593 assert_int_equal(result, ISC_R_SUCCESS); 594 isc_loop_teardown(mainloop, listen_sock_close, listen_sock); 595 596 sockaddr_to_url(&tcp_listen_addr, false, req_url, sizeof(req_url), 597 ISC_NM_HTTP_DEFAULT_PATH); 598 connect_send_request(connect_nm, req_url, atomic_load(&POST), 599 &(isc_region_t){ .base = (uint8_t *)send_msg.base, 600 .length = send_msg.len }, 601 noop_read_cb, NULL, atomic_load(&use_TLS), 30000); 602 603 isc_loopmgr_shutdown(loopmgr); 604 } 605 606 ISC_LOOP_TEST_IMPL(doh_noresponse_POST) { 607 atomic_store(&POST, true); 608 doh_noresponse(arg); 609 } 610 611 ISC_LOOP_TEST_IMPL(doh_noresponse_GET) { 612 atomic_store(&POST, false); 613 doh_noresponse(arg); 614 } 615 616 static void 617 timeout_query_sent_cb(isc_nmhandle_t *handle, isc_result_t eresult, 618 void *cbarg) { 619 UNUSED(eresult); 620 UNUSED(cbarg); 621 622 assert_non_null(handle); 623 624 if (eresult == ISC_R_SUCCESS) { 625 atomic_fetch_add(&csends, 1); 626 } 627 628 isc_nmhandle_detach(&handle); 629 } 630 631 static void 632 timeout_retry_cb(isc_nmhandle_t *handle, isc_result_t eresult, 633 isc_region_t *region ISC_ATTR_UNUSED, 634 void *arg ISC_ATTR_UNUSED) { 635 assert_non_null(handle); 636 637 atomic_fetch_add(&ctimeouts, 1); 638 639 if (eresult == ISC_R_TIMEDOUT && atomic_load(&ctimeouts) < 5) { 640 isc_nmhandle_settimeout(handle, T_SOFT); 641 return; 642 } 643 644 isc_nmhandle_detach(&handle); 645 isc_loopmgr_shutdown(loopmgr); 646 } 647 648 static void 649 timeout_request_cb(isc_nmhandle_t *handle, isc_result_t result, void *arg) { 650 isc_nmhandle_t *sendhandle = NULL; 651 isc_nmhandle_t *readhandle = NULL; 652 653 REQUIRE(VALID_NMHANDLE(handle)); 654 655 if (result != ISC_R_SUCCESS) { 656 return; 657 } 658 659 isc_nmhandle_attach(handle, &sendhandle); 660 isc_nm_send(handle, 661 &(isc_region_t){ .base = (uint8_t *)send_msg.base, 662 .length = send_msg.len }, 663 timeout_query_sent_cb, arg); 664 665 isc_nmhandle_attach(handle, &readhandle); 666 isc_nm_read(handle, timeout_retry_cb, NULL); 667 } 668 669 static void 670 doh_timeout_recovery(void *arg ISC_ATTR_UNUSED) { 671 isc_nm_t *listen_nm = nm[0]; 672 isc_nmsocket_t *listen_sock = NULL; 673 isc_nm_t *connect_nm = nm[1]; 674 isc_result_t result = ISC_R_SUCCESS; 675 isc_tlsctx_t *ctx = atomic_load(&use_TLS) ? server_tlsctx : NULL; 676 char req_url[256]; 677 678 result = isc_nm_http_endpoints_add(endpoints, ISC_NM_HTTP_DEFAULT_PATH, 679 doh_receive_request_cb, NULL); 680 assert_int_equal(result, ISC_R_SUCCESS); 681 682 result = isc_nm_listenhttp(listen_nm, ISC_NM_LISTEN_ALL, 683 &tcp_listen_addr, 0, NULL, NULL, endpoints, 684 0, get_proxy_type(), &listen_sock); 685 assert_int_equal(result, ISC_R_SUCCESS); 686 isc_loop_teardown(mainloop, listen_sock_close, listen_sock); 687 688 /* 689 * Accept connections but don't send responses, forcing client 690 * reads to time out. 691 */ 692 noanswer = true; 693 694 /* 695 * Shorten all the TCP client timeouts to 0.05 seconds. 696 * timeout_retry_cb() will give up after five timeouts. 697 */ 698 isc_nm_settimeouts(connect_nm, T_SOFT, T_SOFT, T_SOFT, T_SOFT); 699 sockaddr_to_url(&tcp_listen_addr, false, req_url, sizeof(req_url), 700 ISC_NM_HTTP_DEFAULT_PATH); 701 isc_nm_httpconnect(connect_nm, NULL, &tcp_listen_addr, req_url, 702 atomic_load(&POST), timeout_request_cb, NULL, ctx, 703 client_sess_cache, T_CONNECT, get_proxy_type(), 704 NULL); 705 } 706 707 static int 708 doh_timeout_recovery_teardown(void **state) { 709 assert_true(atomic_load(&ctimeouts) == 5); 710 return teardown_test(state); 711 } 712 713 ISC_LOOP_TEST_IMPL(doh_timeout_recovery_POST) { 714 atomic_store(&POST, true); 715 doh_timeout_recovery(arg); 716 } 717 718 ISC_LOOP_TEST_IMPL(doh_timeout_recovery_GET) { 719 atomic_store(&POST, false); 720 doh_timeout_recovery(arg); 721 } 722 723 static void 724 doh_connect_thread(void *arg); 725 726 static void 727 doh_receive_send_reply_cb(isc_nmhandle_t *handle, isc_result_t eresult, 728 isc_region_t *region, void *cbarg) { 729 isc_nm_t *connect_nm = (isc_nm_t *)cbarg; 730 731 if (eresult != ISC_R_SUCCESS) { 732 return; 733 } 734 735 assert_non_null(handle); 736 UNUSED(region); 737 738 int_fast64_t sends = atomic_fetch_sub(&nsends, 1); 739 atomic_fetch_add(&csends, 1); 740 atomic_fetch_add(&creads, 1); 741 if (sends > 0 && connect_nm != NULL) { 742 size_t i; 743 for (i = 0; i < NWRITES / 2; i++) { 744 eresult = isc__nm_http_request( 745 handle, 746 &(isc_region_t){ 747 .base = (uint8_t *)send_msg.base, 748 .length = send_msg.len }, 749 doh_receive_send_reply_cb, NULL); 750 if (eresult == ISC_R_CANCELED) { 751 break; 752 } 753 assert_true(eresult == ISC_R_SUCCESS); 754 } 755 756 isc_async_current(doh_connect_thread, connect_nm); 757 } 758 if (sends <= 0) { 759 isc_loopmgr_shutdown(loopmgr); 760 } 761 } 762 763 static void 764 doh_connect_thread(void *arg) { 765 isc_nm_t *connect_nm = (isc_nm_t *)arg; 766 char req_url[256]; 767 int64_t sends = atomic_load(&nsends); 768 769 sockaddr_to_url(&tcp_listen_addr, atomic_load(&use_TLS), req_url, 770 sizeof(req_url), ISC_NM_HTTP_DEFAULT_PATH); 771 772 /* 773 * We need to back off and slow down if we start getting 774 * errors, to prevent a thundering herd problem. 775 */ 776 int_fast64_t active = atomic_fetch_add(&active_cconnects, 1); 777 if (active > workers) { 778 atomic_fetch_sub(&active_cconnects, 1); 779 return; 780 } 781 connect_send_request(connect_nm, req_url, atomic_load(&POST), 782 &(isc_region_t){ .base = (uint8_t *)send_msg.base, 783 .length = send_msg.len }, 784 doh_receive_send_reply_cb, connect_nm, 785 atomic_load(&use_TLS), 30000); 786 787 if (sends <= 0) { 788 isc_loopmgr_shutdown(loopmgr); 789 } 790 } 791 792 static void 793 doh_recv_one(void *arg ISC_ATTR_UNUSED) { 794 isc_nm_t *listen_nm = nm[0]; 795 isc_nm_t *connect_nm = nm[1]; 796 isc_result_t result = ISC_R_SUCCESS; 797 isc_nmsocket_t *listen_sock = NULL; 798 char req_url[256]; 799 isc_quota_t *quotap = init_listener_quota(workers); 800 801 atomic_store(&total_sends, 1); 802 expected_creads = 1; 803 804 atomic_store(&nsends, atomic_load(&total_sends)); 805 806 result = isc_nm_http_endpoints_add(endpoints, ISC_NM_HTTP_DEFAULT_PATH, 807 doh_receive_request_cb, NULL); 808 assert_int_equal(result, ISC_R_SUCCESS); 809 810 result = isc_nm_listenhttp( 811 listen_nm, ISC_NM_LISTEN_ALL, &tcp_listen_addr, 0, quotap, 812 atomic_load(&use_TLS) ? server_tlsctx : NULL, endpoints, 0, 813 get_proxy_type(), &listen_sock); 814 assert_int_equal(result, ISC_R_SUCCESS); 815 816 sockaddr_to_url(&tcp_listen_addr, atomic_load(&use_TLS), req_url, 817 sizeof(req_url), ISC_NM_HTTP_DEFAULT_PATH); 818 connect_send_request(connect_nm, req_url, atomic_load(&POST), 819 &(isc_region_t){ .base = (uint8_t *)send_msg.base, 820 .length = send_msg.len }, 821 doh_receive_reply_cb, NULL, atomic_load(&use_TLS), 822 30000); 823 824 isc_loop_teardown(mainloop, listen_sock_close, listen_sock); 825 } 826 827 static int 828 doh_recv_one_teardown(void **state) { 829 X(total_sends); 830 X(csends); 831 X(creads); 832 X(sreads); 833 X(ssends); 834 835 assert_int_equal(atomic_load(&csends), 1); 836 assert_int_equal(atomic_load(&creads), 1); 837 assert_int_equal(atomic_load(&sreads), 1); 838 assert_int_equal(atomic_load(&ssends), 1); 839 840 return teardown_test(state); 841 } 842 843 ISC_LOOP_TEST_IMPL(doh_recv_one_POST) { 844 atomic_store(&POST, true); 845 doh_recv_one(arg); 846 } 847 848 ISC_LOOP_TEST_IMPL(doh_recv_one_GET) { 849 atomic_store(&POST, false); 850 doh_recv_one(arg); 851 } 852 853 ISC_LOOP_TEST_IMPL(doh_recv_one_POST_TLS) { 854 atomic_store(&use_TLS, true); 855 atomic_store(&POST, true); 856 doh_recv_one(arg); 857 } 858 859 ISC_LOOP_TEST_IMPL(doh_recv_one_GET_TLS) { 860 atomic_store(&use_TLS, true); 861 atomic_store(&POST, false); 862 doh_recv_one(arg); 863 } 864 865 ISC_LOOP_TEST_IMPL(doh_recv_one_POST_quota) { 866 atomic_store(&POST, true); 867 atomic_store(&check_listener_quota, true); 868 doh_recv_one(arg); 869 } 870 871 ISC_LOOP_TEST_IMPL(doh_recv_one_GET_quota) { 872 atomic_store(&POST, false); 873 atomic_store(&check_listener_quota, true); 874 doh_recv_one(arg); 875 } 876 877 ISC_LOOP_TEST_IMPL(doh_recv_one_POST_TLS_quota) { 878 atomic_store(&use_TLS, true); 879 atomic_store(&POST, true); 880 atomic_store(&check_listener_quota, true); 881 doh_recv_one(arg); 882 } 883 884 ISC_LOOP_TEST_IMPL(doh_recv_one_GET_TLS_quota) { 885 atomic_store(&use_TLS, true); 886 atomic_store(&POST, false); 887 atomic_store(&check_listener_quota, true); 888 doh_recv_one(arg); 889 } 890 891 static void 892 doh_connect_send_two_requests_cb(isc_nmhandle_t *handle, isc_result_t result, 893 void *arg) { 894 REQUIRE(VALID_NMHANDLE(handle)); 895 if (result != ISC_R_SUCCESS) { 896 return; 897 } 898 899 result = isc__nm_http_request( 900 handle, 901 &(isc_region_t){ .base = (uint8_t *)send_msg.base, 902 .length = send_msg.len }, 903 doh_receive_reply_cb, arg); 904 if (result != ISC_R_SUCCESS) { 905 return; 906 } 907 908 result = isc__nm_http_request( 909 handle, 910 &(isc_region_t){ .base = (uint8_t *)send_msg.base, 911 .length = send_msg.len }, 912 doh_receive_reply_cb, arg); 913 if (result != ISC_R_SUCCESS) { 914 return; 915 } 916 } 917 918 static void 919 doh_recv_two(void *arg ISC_ATTR_UNUSED) { 920 isc_nm_t *listen_nm = nm[0]; 921 isc_nm_t *connect_nm = nm[1]; 922 isc_result_t result = ISC_R_SUCCESS; 923 isc_nmsocket_t *listen_sock = NULL; 924 char req_url[256]; 925 isc_tlsctx_t *ctx = NULL; 926 isc_quota_t *quotap = init_listener_quota(workers); 927 928 atomic_store(&total_sends, 2); 929 expected_creads = 2; 930 931 atomic_store(&nsends, atomic_load(&total_sends)); 932 933 result = isc_nm_http_endpoints_add(endpoints, ISC_NM_HTTP_DEFAULT_PATH, 934 doh_receive_request_cb, NULL); 935 assert_int_equal(result, ISC_R_SUCCESS); 936 937 result = isc_nm_listenhttp( 938 listen_nm, ISC_NM_LISTEN_ALL, &tcp_listen_addr, 0, quotap, 939 atomic_load(&use_TLS) ? server_tlsctx : NULL, endpoints, 0, 940 get_proxy_type(), &listen_sock); 941 assert_int_equal(result, ISC_R_SUCCESS); 942 943 sockaddr_to_url(&tcp_listen_addr, atomic_load(&use_TLS), req_url, 944 sizeof(req_url), ISC_NM_HTTP_DEFAULT_PATH); 945 946 if (atomic_load(&use_TLS)) { 947 ctx = client_tlsctx; 948 } 949 950 isc_nm_httpconnect(connect_nm, NULL, &tcp_listen_addr, req_url, 951 atomic_load(&POST), doh_connect_send_two_requests_cb, 952 NULL, ctx, client_sess_cache, 5000, get_proxy_type(), 953 NULL); 954 955 isc_loop_teardown(mainloop, listen_sock_close, listen_sock); 956 } 957 958 static int 959 doh_recv_two_teardown(void **state) { 960 X(total_sends); 961 X(csends); 962 X(creads); 963 X(sreads); 964 X(ssends); 965 966 assert_int_equal(atomic_load(&csends), 2); 967 assert_int_equal(atomic_load(&creads), 2); 968 assert_int_equal(atomic_load(&sreads), 2); 969 assert_int_equal(atomic_load(&ssends), 2); 970 971 return teardown_test(state); 972 } 973 974 ISC_LOOP_TEST_IMPL(doh_recv_two_POST) { 975 atomic_store(&POST, true); 976 doh_recv_two(arg); 977 } 978 979 ISC_LOOP_TEST_IMPL(doh_recv_two_GET) { 980 atomic_store(&POST, false); 981 doh_recv_two(arg); 982 } 983 984 ISC_LOOP_TEST_IMPL(doh_recv_two_POST_TLS) { 985 atomic_store(&use_TLS, true); 986 atomic_store(&POST, true); 987 doh_recv_two(arg); 988 } 989 990 ISC_LOOP_TEST_IMPL(doh_recv_two_GET_TLS) { 991 atomic_store(&use_TLS, true); 992 atomic_store(&POST, false); 993 doh_recv_two(arg); 994 } 995 996 ISC_LOOP_TEST_IMPL(doh_recv_two_POST_quota) { 997 atomic_store(&POST, true); 998 atomic_store(&check_listener_quota, true); 999 doh_recv_two(arg); 1000 } 1001 1002 ISC_LOOP_TEST_IMPL(doh_recv_two_GET_quota) { 1003 atomic_store(&POST, false); 1004 atomic_store(&check_listener_quota, true); 1005 doh_recv_two(arg); 1006 } 1007 1008 ISC_LOOP_TEST_IMPL(doh_recv_two_POST_TLS_quota) { 1009 atomic_store(&use_TLS, true); 1010 atomic_store(&POST, true); 1011 atomic_store(&check_listener_quota, true); 1012 doh_recv_two(arg); 1013 } 1014 1015 ISC_LOOP_TEST_IMPL(doh_recv_two_GET_TLS_quota) { 1016 atomic_store(&use_TLS, true); 1017 atomic_store(&POST, false); 1018 atomic_store(&check_listener_quota, true); 1019 doh_recv_two(arg); 1020 } 1021 1022 static void 1023 doh_recv_send(void *arg ISC_ATTR_UNUSED) { 1024 isc_nm_t *listen_nm = nm[0]; 1025 isc_nm_t *connect_nm = nm[1]; 1026 isc_result_t result = ISC_R_SUCCESS; 1027 isc_nmsocket_t *listen_sock = NULL; 1028 size_t nthreads = isc_loopmgr_nloops(loopmgr); 1029 isc_quota_t *quotap = init_listener_quota(workers); 1030 1031 atomic_store(&total_sends, 1000); 1032 atomic_store(&nsends, 1000); 1033 1034 result = isc_nm_http_endpoints_add(endpoints, ISC_NM_HTTP_DEFAULT_PATH, 1035 doh_receive_request_cb, NULL); 1036 assert_int_equal(result, ISC_R_SUCCESS); 1037 1038 result = isc_nm_listenhttp( 1039 listen_nm, ISC_NM_LISTEN_ALL, &tcp_listen_addr, 0, quotap, 1040 atomic_load(&use_TLS) ? server_tlsctx : NULL, endpoints, 0, 1041 get_proxy_type(), &listen_sock); 1042 assert_int_equal(result, ISC_R_SUCCESS); 1043 1044 for (size_t i = 0; i < nthreads; i++) { 1045 isc_async_run(isc_loop_get(loopmgr, i), doh_connect_thread, 1046 connect_nm); 1047 } 1048 1049 isc_loop_teardown(mainloop, listen_sock_close, listen_sock); 1050 } 1051 1052 static int 1053 doh_recv_send_teardown(void **state) { 1054 int res = teardown_test(state); 1055 1056 X(total_sends); 1057 X(csends); 1058 X(creads); 1059 X(sreads); 1060 X(ssends); 1061 1062 CHECK_RANGE_FULL(csends); 1063 CHECK_RANGE_FULL(creads); 1064 CHECK_RANGE_FULL(sreads); 1065 CHECK_RANGE_FULL(ssends); 1066 1067 return res; 1068 } 1069 1070 ISC_LOOP_TEST_IMPL(doh_recv_send_POST) { 1071 atomic_store(&POST, true); 1072 doh_recv_send(arg); 1073 } 1074 1075 ISC_LOOP_TEST_IMPL(doh_recv_send_GET) { 1076 atomic_store(&POST, false); 1077 doh_recv_send(arg); 1078 } 1079 1080 ISC_LOOP_TEST_IMPL(doh_recv_send_POST_TLS) { 1081 atomic_store(&POST, true); 1082 atomic_store(&use_TLS, true); 1083 doh_recv_send(arg); 1084 } 1085 1086 ISC_LOOP_TEST_IMPL(doh_recv_send_GET_TLS) { 1087 atomic_store(&POST, false); 1088 atomic_store(&use_TLS, true); 1089 doh_recv_send(arg); 1090 } 1091 1092 ISC_LOOP_TEST_IMPL(doh_recv_send_POST_quota) { 1093 atomic_store(&POST, true); 1094 atomic_store(&check_listener_quota, true); 1095 doh_recv_send(arg); 1096 } 1097 1098 ISC_LOOP_TEST_IMPL(doh_recv_send_GET_quota) { 1099 atomic_store(&POST, false); 1100 atomic_store(&check_listener_quota, true); 1101 doh_recv_send(arg); 1102 } 1103 1104 ISC_LOOP_TEST_IMPL(doh_recv_send_POST_TLS_quota) { 1105 atomic_store(&POST, true); 1106 atomic_store(&use_TLS, true); 1107 atomic_store(&check_listener_quota, true); 1108 doh_recv_send(arg); 1109 } 1110 1111 ISC_LOOP_TEST_IMPL(doh_recv_send_GET_TLS_quota) { 1112 atomic_store(&POST, false); 1113 atomic_store(&use_TLS, true); 1114 atomic_store(&check_listener_quota, true); 1115 doh_recv_send(arg); 1116 } 1117 1118 static int 1119 doh_bad_connect_uri_teardown(void **state) { 1120 X(total_sends); 1121 X(csends); 1122 X(creads); 1123 X(sreads); 1124 X(ssends); 1125 1126 /* As we used an ill-formed URI, there ought to be an error. */ 1127 assert_int_equal(atomic_load(&csends), 0); 1128 assert_int_equal(atomic_load(&creads), 0); 1129 assert_int_equal(atomic_load(&sreads), 0); 1130 assert_int_equal(atomic_load(&ssends), 0); 1131 1132 return teardown_test(state); 1133 } 1134 1135 /* See: GL #2858, !5319 */ 1136 ISC_LOOP_TEST_IMPL(doh_bad_connect_uri) { 1137 isc_nm_t *listen_nm = nm[0]; 1138 isc_nm_t *connect_nm = nm[1]; 1139 isc_result_t result = ISC_R_SUCCESS; 1140 isc_nmsocket_t *listen_sock = NULL; 1141 char req_url[256]; 1142 isc_quota_t *quotap = init_listener_quota(workers); 1143 1144 atomic_store(&total_sends, 1); 1145 1146 atomic_store(&nsends, atomic_load(&total_sends)); 1147 1148 result = isc_nm_http_endpoints_add(endpoints, ISC_NM_HTTP_DEFAULT_PATH, 1149 doh_receive_request_cb, NULL); 1150 assert_int_equal(result, ISC_R_SUCCESS); 1151 1152 result = isc_nm_listenhttp( 1153 listen_nm, ISC_NM_LISTEN_ALL, &tcp_listen_addr, 0, quotap, 1154 server_tlsctx, endpoints, 0, get_proxy_type(), &listen_sock); 1155 assert_int_equal(result, ISC_R_SUCCESS); 1156 1157 /* 1158 * "https://::1:XXXX/dns-query" is a bad URI, it should be 1159 * "https://[::1]:XXXX/dns-query" 1160 */ 1161 (void)snprintf(req_url, sizeof(req_url), "https://::1:%u/%s", 1162 isc_sockaddr_getport(&tcp_listen_addr), 1163 ISC_NM_HTTP_DEFAULT_PATH); 1164 connect_send_request(connect_nm, req_url, atomic_load(&POST), 1165 &(isc_region_t){ .base = (uint8_t *)send_msg.base, 1166 .length = send_msg.len }, 1167 doh_receive_reply_cb, NULL, true, 30000); 1168 1169 isc_loop_teardown(mainloop, listen_sock_close, listen_sock); 1170 } 1171 1172 ISC_RUN_TEST_IMPL(doh_parse_GET_query_string) { 1173 /* valid */ 1174 { 1175 bool ret; 1176 const char *queryp = NULL; 1177 size_t len = 0; 1178 char str[] = 1179 "dns=AAABAAABAAAAAAAAAWE-" 1180 "NjJjaGFyYWN0ZXJsYWJlbC1tYWtlcy1iYXNlNjR1cmwtZGlzdGluY3" 1181 "QtZnJvbS1zdGFuZGFyZC1iYXNlNjQHZXhhbXBsZQNjb20AAAEAAQ"; 1182 1183 ret = isc__nm_parse_httpquery(str, &queryp, &len); 1184 assert_true(ret); 1185 assert_non_null(queryp); 1186 assert_true(len > 0); 1187 assert_true(len == strlen(str) - 4); 1188 assert_true(memcmp(queryp, str + 4, len) == 0); 1189 } 1190 /* valid */ 1191 { 1192 bool ret; 1193 const char *queryp = NULL; 1194 size_t len = 0; 1195 char str[] = 1196 "?dns=AAABAAABAAAAAAAAAWE-" 1197 "NjJjaGFyYWN0ZXJsYWJlbC1tYWtlcy1iYXNlNjR1cmwtZGlzdGluY3" 1198 "QtZnJvbS1zdGFuZGFyZC1iYXNlNjQHZXhhbXBsZQNjb20AAAEAAQ&"; 1199 1200 ret = isc__nm_parse_httpquery(str, &queryp, &len); 1201 assert_true(ret); 1202 assert_non_null(queryp); 1203 assert_true(len > 0); 1204 assert_true(len == strlen(str) - 6); 1205 assert_true(memcmp(queryp, str + 5, len) == 0); 1206 } 1207 /* valid */ 1208 { 1209 bool ret; 1210 const char *queryp = NULL; 1211 size_t len = 0; 1212 char str[] = "?dns=123&dns=567"; 1213 1214 ret = isc__nm_parse_httpquery(str, &queryp, &len); 1215 assert_true(ret); 1216 assert_non_null(queryp); 1217 assert_true(len > 0); 1218 assert_true(len == 3); 1219 assert_true(memcmp(queryp, "567", 3) == 0); 1220 } 1221 /* valid */ 1222 { 1223 bool ret; 1224 const char *queryp = NULL; 1225 size_t len = 0; 1226 char str[] = "?name1=123&dns=567&name2=123&"; 1227 1228 ret = isc__nm_parse_httpquery(str, &queryp, &len); 1229 assert_true(ret); 1230 assert_non_null(queryp); 1231 assert_true(len > 0); 1232 assert_true(len == 3); 1233 assert_true(memcmp(queryp, "567", 3) == 0); 1234 } 1235 /* complex, but still valid */ 1236 { 1237 bool ret; 1238 const char *queryp = NULL; 1239 size_t len = 0; 1240 char str[] = 1241 "?title=%D0%92%D1%96%D0%B4%D1%81%D0%BE%D1%82%D0%BA%D0%" 1242 "BE%D0%B2%D0%B5_%D0%BA%D0%BE%D0%B4%D1%83%D0%B2%D0%B0%" 1243 "D0%BD%D0%BD%D1%8F&dns=123&veaction=edit§ion=0"; 1244 1245 ret = isc__nm_parse_httpquery(str, &queryp, &len); 1246 assert_true(ret); 1247 assert_non_null(queryp); 1248 assert_true(len > 0); 1249 assert_true(len == 3); 1250 assert_true(memcmp(queryp, "123", 3) == 0); 1251 } 1252 /* invalid */ 1253 { 1254 bool ret; 1255 const char *queryp = NULL; 1256 size_t len = 0; 1257 char str[] = 1258 "?title=%D0%92%D1%96%D0%B4%D1%81%D0%BE%D1%82%D0%BA%D0%" 1259 "BE%D0%B2%D0%B5_%D0%BA%D0%BE%D0%B4%D1%83%D0%B2%D0%B0%" 1260 "D0%BD%D0%BD%D1%8F&veaction=edit§ion=0"; 1261 1262 ret = isc__nm_parse_httpquery(str, &queryp, &len); 1263 assert_false(ret); 1264 assert_null(queryp); 1265 assert_true(len == 0); 1266 } 1267 /* invalid */ 1268 { 1269 bool ret; 1270 const char *queryp = NULL; 1271 size_t len = 0; 1272 char str[] = ""; 1273 1274 ret = isc__nm_parse_httpquery(str, &queryp, &len); 1275 assert_false(ret); 1276 assert_null(queryp); 1277 assert_true(len == 0); 1278 } 1279 /* invalid */ 1280 { 1281 bool ret; 1282 const char *queryp = NULL; 1283 size_t len = 0; 1284 char str[] = "?&"; 1285 1286 ret = isc__nm_parse_httpquery(str, &queryp, &len); 1287 assert_false(ret); 1288 assert_null(queryp); 1289 assert_true(len == 0); 1290 } 1291 /* invalid */ 1292 { 1293 bool ret; 1294 const char *queryp = NULL; 1295 size_t len = 0; 1296 char str[] = "?dns&"; 1297 1298 ret = isc__nm_parse_httpquery(str, &queryp, &len); 1299 assert_false(ret); 1300 assert_null(queryp); 1301 assert_true(len == 0); 1302 } 1303 /* invalid */ 1304 { 1305 bool ret; 1306 const char *queryp = NULL; 1307 size_t len = 0; 1308 char str[] = "?dns=&"; 1309 1310 ret = isc__nm_parse_httpquery(str, &queryp, &len); 1311 assert_false(ret); 1312 assert_null(queryp); 1313 assert_true(len == 0); 1314 } 1315 /* invalid */ 1316 { 1317 bool ret; 1318 const char *queryp = NULL; 1319 size_t len = 0; 1320 char str[] = "?dns=123&&"; 1321 1322 ret = isc__nm_parse_httpquery(str, &queryp, &len); 1323 assert_false(ret); 1324 assert_null(queryp); 1325 assert_true(len == 0); 1326 } 1327 /* valid */ 1328 { 1329 bool ret; 1330 const char *queryp = NULL; 1331 size_t len = 0; 1332 char str[] = "?dns=123%12&"; 1333 1334 ret = isc__nm_parse_httpquery(str, &queryp, &len); 1335 assert_true(ret); 1336 assert_non_null(queryp); 1337 assert_true(len > 0); 1338 assert_true(len == 6); 1339 assert_true(memcmp(queryp, "123%12", 6) == 0); 1340 } 1341 /* invalid */ 1342 { 1343 bool ret; 1344 const char *queryp = NULL; 1345 size_t len = 0; 1346 char str[] = "?dns=123%ZZ&"; 1347 1348 ret = isc__nm_parse_httpquery(str, &queryp, &len); 1349 assert_false(ret); 1350 assert_null(queryp); 1351 assert_true(len == 0); 1352 } 1353 /* invalid */ 1354 { 1355 bool ret; 1356 const char *queryp = NULL; 1357 size_t len = 0; 1358 char str[] = "?dns=123%%&"; 1359 1360 ret = isc__nm_parse_httpquery(str, &queryp, &len); 1361 assert_false(ret); 1362 assert_null(queryp); 1363 assert_true(len == 0); 1364 } 1365 /* invalid */ 1366 { 1367 bool ret; 1368 const char *queryp = NULL; 1369 size_t len = 0; 1370 char str[] = "?dns=123%AZ&"; 1371 1372 ret = isc__nm_parse_httpquery(str, &queryp, &len); 1373 assert_false(ret); 1374 assert_null(queryp); 1375 assert_true(len == 0); 1376 } 1377 /* valid */ 1378 { 1379 bool ret; 1380 const char *queryp = NULL; 1381 size_t len = 0; 1382 char str[] = "?dns=123%0AZ&"; 1383 1384 ret = isc__nm_parse_httpquery(str, &queryp, &len); 1385 assert_true(ret); 1386 assert_non_null(queryp); 1387 assert_true(len > 0); 1388 assert_true(len == 7); 1389 assert_true(memcmp(queryp, "123%0AZ", 7) == 0); 1390 } 1391 } 1392 1393 ISC_RUN_TEST_IMPL(doh_base64url_to_base64) { 1394 char *res; 1395 size_t res_len = 0; 1396 /* valid */ 1397 { 1398 char test[] = "YW55IGNhcm5hbCBwbGVhc3VyZS4"; 1399 char res_test[] = "YW55IGNhcm5hbCBwbGVhc3VyZS4="; 1400 1401 res = isc__nm_base64url_to_base64(mctx, test, strlen(test), 1402 &res_len); 1403 assert_non_null(res); 1404 assert_true(res_len == strlen(res_test)); 1405 assert_true(strcmp(res, res_test) == 0); 1406 isc_mem_free(mctx, res); 1407 } 1408 /* valid */ 1409 { 1410 char test[] = "YW55IGNhcm5hbCBwbGVhcw"; 1411 char res_test[] = "YW55IGNhcm5hbCBwbGVhcw=="; 1412 1413 res = isc__nm_base64url_to_base64(mctx, test, strlen(test), 1414 &res_len); 1415 assert_non_null(res); 1416 assert_true(res_len == strlen(res_test)); 1417 assert_true(strcmp(res, res_test) == 0); 1418 isc_mem_free(mctx, res); 1419 } 1420 /* valid */ 1421 { 1422 char test[] = "YW55IGNhcm5hbCBwbGVhc3Vy"; 1423 char res_test[] = "YW55IGNhcm5hbCBwbGVhc3Vy"; 1424 1425 res = isc__nm_base64url_to_base64(mctx, test, strlen(test), 1426 &res_len); 1427 assert_non_null(res); 1428 assert_true(res_len == strlen(res_test)); 1429 assert_true(strcmp(res, res_test) == 0); 1430 isc_mem_free(mctx, res); 1431 } 1432 /* valid */ 1433 { 1434 char test[] = "YW55IGNhcm5hbCBwbGVhc3U"; 1435 char res_test[] = "YW55IGNhcm5hbCBwbGVhc3U="; 1436 1437 res = isc__nm_base64url_to_base64(mctx, test, strlen(test), 1438 &res_len); 1439 assert_non_null(res); 1440 assert_true(res_len == strlen(res_test)); 1441 assert_true(strcmp(res, res_test) == 0); 1442 isc_mem_free(mctx, res); 1443 } 1444 /* valid */ 1445 { 1446 char test[] = "YW55IGNhcm5hbCBwbGVhcw"; 1447 char res_test[] = "YW55IGNhcm5hbCBwbGVhcw=="; 1448 1449 res = isc__nm_base64url_to_base64(mctx, test, strlen(test), 1450 &res_len); 1451 assert_non_null(res); 1452 assert_true(res_len == strlen(res_test)); 1453 assert_true(strcmp(res, res_test) == 0); 1454 isc_mem_free(mctx, res); 1455 } 1456 /* valid */ 1457 { 1458 char test[] = "PDw_Pz8-Pg"; 1459 char res_test[] = "PDw/Pz8+Pg=="; 1460 1461 res = isc__nm_base64url_to_base64(mctx, test, strlen(test), 1462 &res_len); 1463 assert_non_null(res); 1464 assert_true(res_len == strlen(res_test)); 1465 assert_true(strcmp(res, res_test) == 0); 1466 isc_mem_free(mctx, res); 1467 } 1468 /* valid */ 1469 { 1470 char test[] = "PDw_Pz8-Pg"; 1471 char res_test[] = "PDw/Pz8+Pg=="; 1472 1473 res = isc__nm_base64url_to_base64(mctx, test, strlen(test), 1474 NULL); 1475 assert_non_null(res); 1476 assert_true(strcmp(res, res_test) == 0); 1477 isc_mem_free(mctx, res); 1478 } 1479 /* invalid */ 1480 { 1481 char test[] = "YW55IGNhcm5hbCBwbGVhcw"; 1482 res_len = 0; 1483 1484 res = isc__nm_base64url_to_base64(mctx, test, 0, &res_len); 1485 assert_null(res); 1486 assert_true(res_len == 0); 1487 } 1488 /* invalid */ 1489 { 1490 char test[] = ""; 1491 res_len = 0; 1492 1493 res = isc__nm_base64url_to_base64(mctx, test, strlen(test), 1494 &res_len); 1495 assert_null(res); 1496 assert_true(res_len == 0); 1497 } 1498 /* invalid */ 1499 { 1500 char test[] = "PDw_Pz8-Pg=="; 1501 res_len = 0; 1502 1503 res = isc__nm_base64url_to_base64(mctx, test, strlen(test), 1504 &res_len); 1505 assert_null(res); 1506 assert_true(res_len == 0); 1507 } 1508 /* invalid */ 1509 { 1510 char test[] = "PDw_Pz8-Pg%3D%3D"; /* percent encoded "==" at the 1511 end */ 1512 res_len = 0; 1513 1514 res = isc__nm_base64url_to_base64(mctx, test, strlen(test), 1515 &res_len); 1516 assert_null(res); 1517 assert_true(res_len == 0); 1518 } 1519 /* invalid */ 1520 { 1521 res_len = 0; 1522 1523 res = isc__nm_base64url_to_base64(mctx, NULL, 31231, &res_len); 1524 assert_null(res); 1525 assert_true(res_len == 0); 1526 } 1527 } 1528 1529 ISC_RUN_TEST_IMPL(doh_base64_to_base64url) { 1530 char *res; 1531 size_t res_len = 0; 1532 /* valid */ 1533 { 1534 char res_test[] = "YW55IGNhcm5hbCBwbGVhc3VyZS4"; 1535 char test[] = "YW55IGNhcm5hbCBwbGVhc3VyZS4="; 1536 1537 res = isc__nm_base64_to_base64url(mctx, test, strlen(test), 1538 &res_len); 1539 assert_non_null(res); 1540 assert_true(res_len == strlen(res_test)); 1541 assert_true(strcmp(res, res_test) == 0); 1542 isc_mem_free(mctx, res); 1543 } 1544 /* valid */ 1545 { 1546 char res_test[] = "YW55IGNhcm5hbCBwbGVhcw"; 1547 char test[] = "YW55IGNhcm5hbCBwbGVhcw=="; 1548 1549 res = isc__nm_base64_to_base64url(mctx, test, strlen(test), 1550 &res_len); 1551 assert_non_null(res); 1552 assert_true(res_len == strlen(res_test)); 1553 assert_true(strcmp(res, res_test) == 0); 1554 isc_mem_free(mctx, res); 1555 } 1556 /* valid */ 1557 { 1558 char res_test[] = "YW55IGNhcm5hbCBwbGVhc3Vy"; 1559 char test[] = "YW55IGNhcm5hbCBwbGVhc3Vy"; 1560 1561 res = isc__nm_base64_to_base64url(mctx, test, strlen(test), 1562 &res_len); 1563 assert_non_null(res); 1564 assert_true(res_len == strlen(res_test)); 1565 assert_true(strcmp(res, res_test) == 0); 1566 isc_mem_free(mctx, res); 1567 } 1568 /* valid */ 1569 { 1570 char res_test[] = "YW55IGNhcm5hbCBwbGVhc3U"; 1571 char test[] = "YW55IGNhcm5hbCBwbGVhc3U="; 1572 1573 res = isc__nm_base64_to_base64url(mctx, test, strlen(test), 1574 &res_len); 1575 assert_non_null(res); 1576 assert_true(res_len == strlen(res_test)); 1577 assert_true(strcmp(res, res_test) == 0); 1578 isc_mem_free(mctx, res); 1579 } 1580 /* valid */ 1581 { 1582 char res_test[] = "YW55IGNhcm5hbCBwbGVhcw"; 1583 char test[] = "YW55IGNhcm5hbCBwbGVhcw=="; 1584 1585 res = isc__nm_base64_to_base64url(mctx, test, strlen(test), 1586 &res_len); 1587 assert_non_null(res); 1588 assert_true(res_len == strlen(res_test)); 1589 assert_true(strcmp(res, res_test) == 0); 1590 isc_mem_free(mctx, res); 1591 } 1592 /* valid */ 1593 { 1594 char res_test[] = "PDw_Pz8-Pg"; 1595 char test[] = "PDw/Pz8+Pg=="; 1596 1597 res = isc__nm_base64_to_base64url(mctx, test, strlen(test), 1598 &res_len); 1599 assert_non_null(res); 1600 assert_true(res_len == strlen(res_test)); 1601 assert_true(strcmp(res, res_test) == 0); 1602 isc_mem_free(mctx, res); 1603 } 1604 /* valid */ 1605 { 1606 char res_test[] = "PDw_Pz8-Pg"; 1607 char test[] = "PDw/Pz8+Pg=="; 1608 1609 res = isc__nm_base64_to_base64url(mctx, test, strlen(test), 1610 NULL); 1611 assert_non_null(res); 1612 assert_true(strcmp(res, res_test) == 0); 1613 isc_mem_free(mctx, res); 1614 } 1615 /* invalid */ 1616 { 1617 char test[] = "YW55IGNhcm5hbCBwbGVhcw"; 1618 res_len = 0; 1619 1620 res = isc__nm_base64_to_base64url(mctx, test, 0, &res_len); 1621 assert_null(res); 1622 assert_true(res_len == 0); 1623 } 1624 /* invalid */ 1625 { 1626 char test[] = ""; 1627 res_len = 0; 1628 1629 res = isc__nm_base64_to_base64url(mctx, test, strlen(test), 1630 &res_len); 1631 assert_null(res); 1632 assert_true(res_len == 0); 1633 } 1634 /* invalid */ 1635 { 1636 char test[] = "PDw_Pz8-Pg=="; 1637 res_len = 0; 1638 1639 res = isc__nm_base64_to_base64url(mctx, test, strlen(test), 1640 &res_len); 1641 assert_null(res); 1642 assert_true(res_len == 0); 1643 } 1644 /* invalid */ 1645 { 1646 char test[] = "PDw_Pz8-Pg%3D%3D"; /* percent encoded "==" at the 1647 end */ 1648 res_len = 0; 1649 1650 res = isc__nm_base64_to_base64url(mctx, test, strlen(test), 1651 &res_len); 1652 assert_null(res); 1653 assert_true(res_len == 0); 1654 } 1655 /* invalid */ 1656 { 1657 res_len = 0; 1658 1659 res = isc__nm_base64_to_base64url(mctx, NULL, 31231, &res_len); 1660 assert_null(res); 1661 assert_true(res_len == 0); 1662 } 1663 } 1664 1665 ISC_RUN_TEST_IMPL(doh_path_validation) { 1666 assert_true(isc_nm_http_path_isvalid("/")); 1667 assert_true(isc_nm_http_path_isvalid(ISC_NM_HTTP_DEFAULT_PATH)); 1668 assert_false(isc_nm_http_path_isvalid("laaaa")); 1669 assert_false(isc_nm_http_path_isvalid("")); 1670 assert_false(isc_nm_http_path_isvalid("//")); 1671 assert_true(isc_nm_http_path_isvalid("/lala///")); 1672 assert_true(isc_nm_http_path_isvalid("/lalaaaaaa")); 1673 assert_true(isc_nm_http_path_isvalid("/lalaaa/la/la/la")); 1674 assert_true(isc_nm_http_path_isvalid("/la/a")); 1675 assert_true(isc_nm_http_path_isvalid("/la+la")); 1676 assert_true(isc_nm_http_path_isvalid("/la&la/la*la/l-a_/la!/la\'")); 1677 assert_true(isc_nm_http_path_isvalid("/la/(la)/la")); 1678 assert_true(isc_nm_http_path_isvalid("/la,la,la")); 1679 assert_true(isc_nm_http_path_isvalid("/la-'la'-la")); 1680 assert_true(isc_nm_http_path_isvalid("/la:la=la")); 1681 assert_true(isc_nm_http_path_isvalid("/l@l@l@")); 1682 assert_false(isc_nm_http_path_isvalid("/#lala")); 1683 assert_true(isc_nm_http_path_isvalid("/lala;la")); 1684 assert_false( 1685 isc_nm_http_path_isvalid("la&la/laalaala*lala/l-al_a/lal!/")); 1686 assert_true(isc_nm_http_path_isvalid("/Lal/lAla.jpg")); 1687 1688 /* had to replace ? with ! because it does not verify a query string */ 1689 assert_true(isc_nm_http_path_isvalid("/watch!v=oavMtUWDBTM")); 1690 assert_false(isc_nm_http_path_isvalid("/watch?v=dQw4w9WgXcQ")); 1691 assert_true(isc_nm_http_path_isvalid("/datatracker.ietf.org/doc/html/" 1692 "rfc2616")); 1693 assert_true(isc_nm_http_path_isvalid("/doc/html/rfc8484")); 1694 assert_true(isc_nm_http_path_isvalid("/123")); 1695 } 1696 1697 ISC_RUN_TEST_IMPL(doh_connect_makeuri) { 1698 struct in_addr localhostv4 = { .s_addr = ntohl(INADDR_LOOPBACK) }; 1699 isc_sockaddr_t sa; 1700 char uri[256]; 1701 1702 /* Firstly, test URI generation using isc_sockaddr_t */ 1703 isc_sockaddr_fromin(&sa, &localhostv4, 0); 1704 uri[0] = '\0'; 1705 isc_nm_http_makeuri(true, &sa, NULL, 0, ISC_NM_HTTP_DEFAULT_PATH, uri, 1706 sizeof(uri)); 1707 assert_true(strcmp("https://127.0.0.1:443/dns-query", uri) == 0); 1708 1709 uri[0] = '\0'; 1710 isc_nm_http_makeuri(false, &sa, NULL, 0, ISC_NM_HTTP_DEFAULT_PATH, uri, 1711 sizeof(uri)); 1712 assert_true(strcmp("http://127.0.0.1:80/dns-query", uri) == 0); 1713 1714 /* 1715 * The port value should be ignored, because we can get one from 1716 * the isc_sockaddr_t object. 1717 */ 1718 uri[0] = '\0'; 1719 isc_nm_http_makeuri(true, &sa, NULL, 44343, ISC_NM_HTTP_DEFAULT_PATH, 1720 uri, sizeof(uri)); 1721 assert_true(strcmp("https://127.0.0.1:443/dns-query", uri) == 0); 1722 1723 uri[0] = '\0'; 1724 isc_nm_http_makeuri(false, &sa, NULL, 8080, ISC_NM_HTTP_DEFAULT_PATH, 1725 uri, sizeof(uri)); 1726 assert_true(strcmp("http://127.0.0.1:80/dns-query", uri) == 0); 1727 1728 /* IPv6 */ 1729 isc_sockaddr_fromin6(&sa, &in6addr_loopback, 0); 1730 uri[0] = '\0'; 1731 isc_nm_http_makeuri(true, &sa, NULL, 0, ISC_NM_HTTP_DEFAULT_PATH, uri, 1732 sizeof(uri)); 1733 assert_true(strcmp("https://[::1]:443/dns-query", uri) == 0); 1734 1735 uri[0] = '\0'; 1736 isc_nm_http_makeuri(false, &sa, NULL, 0, ISC_NM_HTTP_DEFAULT_PATH, uri, 1737 sizeof(uri)); 1738 assert_true(strcmp("http://[::1]:80/dns-query", uri) == 0); 1739 1740 /* 1741 * The port value should be ignored, because we can get one from 1742 * the isc_sockaddr_t object. 1743 */ 1744 uri[0] = '\0'; 1745 isc_nm_http_makeuri(true, &sa, NULL, 44343, ISC_NM_HTTP_DEFAULT_PATH, 1746 uri, sizeof(uri)); 1747 assert_true(strcmp("https://[::1]:443/dns-query", uri) == 0); 1748 1749 uri[0] = '\0'; 1750 isc_nm_http_makeuri(false, &sa, NULL, 8080, ISC_NM_HTTP_DEFAULT_PATH, 1751 uri, sizeof(uri)); 1752 assert_true(strcmp("http://[::1]:80/dns-query", uri) == 0); 1753 1754 /* Try to set the port numbers. */ 1755 isc_sockaddr_setport(&sa, 44343); 1756 uri[0] = '\0'; 1757 isc_nm_http_makeuri(true, &sa, NULL, 0, ISC_NM_HTTP_DEFAULT_PATH, uri, 1758 sizeof(uri)); 1759 assert_true(strcmp("https://[::1]:44343/dns-query", uri) == 0); 1760 1761 isc_sockaddr_setport(&sa, 8080); 1762 uri[0] = '\0'; 1763 isc_nm_http_makeuri(false, &sa, NULL, 0, ISC_NM_HTTP_DEFAULT_PATH, uri, 1764 sizeof(uri)); 1765 assert_true(strcmp("http://[::1]:8080/dns-query", uri) == 0); 1766 1767 /* 1768 * Try to make a URI using a hostname and a port number. The 1769 * isc_sockaddr_t object will be ignored. 1770 */ 1771 isc_sockaddr_any(&sa); 1772 uri[0] = '\0'; 1773 isc_nm_http_makeuri(true, &sa, "example.com", 0, 1774 ISC_NM_HTTP_DEFAULT_PATH, uri, sizeof(uri)); 1775 assert_true(strcmp("https://example.com:443/dns-query", uri) == 0); 1776 1777 uri[0] = '\0'; 1778 isc_nm_http_makeuri(false, &sa, "example.com", 0, 1779 ISC_NM_HTTP_DEFAULT_PATH, uri, sizeof(uri)); 1780 assert_true(strcmp("http://example.com:80/dns-query", uri) == 0); 1781 1782 /* Try to set the port numbers. */ 1783 isc_sockaddr_setport(&sa, 443); 1784 uri[0] = '\0'; 1785 isc_nm_http_makeuri(true, &sa, "example.com", 44343, 1786 ISC_NM_HTTP_DEFAULT_PATH, uri, sizeof(uri)); 1787 assert_true(strcmp("https://example.com:44343/dns-query", uri) == 0); 1788 1789 isc_sockaddr_setport(&sa, 80); 1790 uri[0] = '\0'; 1791 isc_nm_http_makeuri(false, &sa, "example.com", 8080, 1792 ISC_NM_HTTP_DEFAULT_PATH, uri, sizeof(uri)); 1793 assert_true(strcmp("http://example.com:8080/dns-query", uri) == 0); 1794 1795 /* IPv4 as the hostname - nothing fancy here */ 1796 uri[0] = '\0'; 1797 isc_nm_http_makeuri(false, NULL, "127.0.0.1", 8080, 1798 ISC_NM_HTTP_DEFAULT_PATH, uri, sizeof(uri)); 1799 assert_true(strcmp("http://127.0.0.1:8080/dns-query", uri) == 0); 1800 1801 uri[0] = '\0'; 1802 isc_nm_http_makeuri(true, NULL, "127.0.0.1", 44343, 1803 ISC_NM_HTTP_DEFAULT_PATH, uri, sizeof(uri)); 1804 assert_true(strcmp("https://127.0.0.1:44343/dns-query", uri) == 0); 1805 1806 /* 1807 * A peculiar edge case: IPv6 given as the hostname (notice 1808 * the brackets) 1809 */ 1810 uri[0] = '\0'; 1811 isc_nm_http_makeuri(false, NULL, "::1", 8080, ISC_NM_HTTP_DEFAULT_PATH, 1812 uri, sizeof(uri)); 1813 assert_true(strcmp("http://[::1]:8080/dns-query", uri) == 0); 1814 1815 uri[0] = '\0'; 1816 isc_nm_http_makeuri(true, NULL, "[::1]", 44343, 1817 ISC_NM_HTTP_DEFAULT_PATH, uri, sizeof(uri)); 1818 assert_true(strcmp("https://[::1]:44343/dns-query", uri) == 0); 1819 } 1820 1821 /* PROXY */ 1822 ISC_LOOP_TEST_IMPL(proxy_doh_noop_POST) { 1823 atomic_store(&POST, true); 1824 atomic_store(&use_PROXY, true); 1825 doh_noop(arg); 1826 } 1827 1828 ISC_LOOP_TEST_IMPL(proxy_doh_noop_GET) { 1829 atomic_store(&use_PROXY, true); 1830 doh_noop(arg); 1831 } 1832 1833 ISC_LOOP_TEST_IMPL(proxy_doh_noresponse_POST) { 1834 atomic_store(&POST, true); 1835 atomic_store(&use_PROXY, true); 1836 doh_noresponse(arg); 1837 } 1838 1839 ISC_LOOP_TEST_IMPL(proxy_doh_noresponse_GET) { 1840 atomic_store(&use_PROXY, true); 1841 doh_noresponse(arg); 1842 } 1843 1844 ISC_LOOP_TEST_IMPL(proxy_doh_timeout_recovery_POST) { 1845 atomic_store(&POST, true); 1846 atomic_store(&use_PROXY, true); 1847 doh_timeout_recovery(arg); 1848 } 1849 1850 ISC_LOOP_TEST_IMPL(proxy_doh_timeout_recovery_GET) { 1851 atomic_store(&use_PROXY, true); 1852 doh_timeout_recovery(arg); 1853 } 1854 1855 ISC_LOOP_TEST_IMPL(proxy_doh_recv_one_POST) { 1856 atomic_store(&POST, true); 1857 atomic_store(&use_PROXY, true); 1858 doh_recv_one(arg); 1859 } 1860 1861 ISC_LOOP_TEST_IMPL(proxy_doh_recv_one_GET) { 1862 atomic_store(&use_PROXY, true); 1863 doh_recv_one(arg); 1864 } 1865 1866 ISC_LOOP_TEST_IMPL(proxy_doh_recv_one_POST_TLS) { 1867 atomic_store(&POST, true); 1868 atomic_store(&use_TLS, true); 1869 atomic_store(&use_PROXY, true); 1870 doh_recv_one(arg); 1871 } 1872 1873 ISC_LOOP_TEST_IMPL(proxy_doh_recv_one_GET_TLS) { 1874 atomic_store(&use_TLS, true); 1875 atomic_store(&use_PROXY, true); 1876 doh_recv_one(arg); 1877 } 1878 1879 ISC_LOOP_TEST_IMPL(proxy_doh_recv_one_POST_quota) { 1880 atomic_store(&POST, true); 1881 atomic_store(&use_PROXY, true); 1882 atomic_store(&check_listener_quota, true); 1883 doh_recv_one(arg); 1884 } 1885 1886 ISC_LOOP_TEST_IMPL(proxy_doh_recv_one_GET_quota) { 1887 atomic_store(&use_PROXY, true); 1888 atomic_store(&check_listener_quota, true); 1889 doh_recv_one(arg); 1890 } 1891 1892 ISC_LOOP_TEST_IMPL(proxy_doh_recv_one_GET_TLS_quota) { 1893 atomic_store(&use_TLS, true); 1894 atomic_store(&use_PROXY, true); 1895 atomic_store(&check_listener_quota, true); 1896 doh_recv_one(arg); 1897 } 1898 1899 ISC_LOOP_TEST_IMPL(proxy_doh_recv_one_POST_TLS_quota) { 1900 atomic_store(&POST, true); 1901 atomic_store(&use_TLS, true); 1902 atomic_store(&use_PROXY, true); 1903 atomic_store(&check_listener_quota, true); 1904 doh_recv_one(arg); 1905 } 1906 1907 ISC_LOOP_TEST_IMPL(proxy_doh_recv_two_POST) { 1908 atomic_store(&POST, true); 1909 atomic_store(&use_PROXY, true); 1910 doh_recv_two(arg); 1911 } 1912 1913 ISC_LOOP_TEST_IMPL(proxy_doh_recv_two_GET) { 1914 ; 1915 atomic_store(&use_PROXY, true); 1916 doh_recv_two(arg); 1917 } 1918 1919 ISC_LOOP_TEST_IMPL(proxy_doh_recv_two_POST_TLS) { 1920 atomic_store(&POST, true); 1921 atomic_store(&use_TLS, true); 1922 atomic_store(&use_PROXY, true); 1923 doh_recv_two(arg); 1924 } 1925 1926 ISC_LOOP_TEST_IMPL(proxy_doh_recv_two_GET_TLS) { 1927 atomic_store(&use_TLS, true); 1928 atomic_store(&use_PROXY, true); 1929 doh_recv_two(arg); 1930 } 1931 1932 ISC_LOOP_TEST_IMPL(proxy_doh_recv_two_POST_quota) { 1933 atomic_store(&POST, true); 1934 atomic_store(&use_PROXY, true); 1935 atomic_store(&check_listener_quota, true); 1936 doh_recv_two(arg); 1937 } 1938 1939 ISC_LOOP_TEST_IMPL(proxy_doh_recv_two_GET_quota) { 1940 atomic_store(&use_PROXY, true); 1941 atomic_store(&check_listener_quota, true); 1942 doh_recv_two(arg); 1943 } 1944 1945 ISC_LOOP_TEST_IMPL(proxy_doh_recv_two_POST_TLS_quota) { 1946 atomic_store(&POST, true); 1947 atomic_store(&use_TLS, true); 1948 atomic_store(&use_PROXY, true); 1949 atomic_store(&check_listener_quota, true); 1950 doh_recv_two(arg); 1951 } 1952 1953 ISC_LOOP_TEST_IMPL(proxy_doh_recv_two_GET_TLS_quota) { 1954 atomic_store(&use_TLS, true); 1955 atomic_store(&use_PROXY, true); 1956 atomic_store(&check_listener_quota, true); 1957 doh_recv_two(arg); 1958 } 1959 1960 ISC_LOOP_TEST_IMPL(proxy_doh_recv_send_POST) { 1961 atomic_store(&POST, true); 1962 atomic_store(&use_PROXY, true); 1963 doh_recv_send(arg); 1964 } 1965 1966 ISC_LOOP_TEST_IMPL(proxy_doh_recv_send_GET) { 1967 atomic_store(&use_PROXY, true); 1968 doh_recv_send(arg); 1969 } 1970 1971 ISC_LOOP_TEST_IMPL(proxy_doh_recv_send_POST_TLS) { 1972 atomic_store(&POST, true); 1973 atomic_store(&use_TLS, true); 1974 atomic_store(&use_PROXY, true); 1975 doh_recv_send(arg); 1976 } 1977 1978 ISC_LOOP_TEST_IMPL(proxy_doh_recv_send_GET_TLS) { 1979 atomic_store(&use_TLS, true); 1980 atomic_store(&use_PROXY, true); 1981 doh_recv_send(arg); 1982 } 1983 1984 ISC_LOOP_TEST_IMPL(proxy_doh_recv_send_POST_quota) { 1985 atomic_store(&POST, true); 1986 atomic_store(&use_PROXY, true); 1987 atomic_store(&check_listener_quota, true); 1988 doh_recv_send(arg); 1989 } 1990 1991 ISC_LOOP_TEST_IMPL(proxy_doh_recv_send_GET_quota) { 1992 atomic_store(&use_PROXY, true); 1993 atomic_store(&check_listener_quota, true); 1994 doh_recv_send(arg); 1995 } 1996 1997 ISC_LOOP_TEST_IMPL(proxy_doh_recv_send_POST_TLS_quota) { 1998 atomic_store(&POST, true); 1999 atomic_store(&use_TLS, true); 2000 atomic_store(&use_PROXY, true); 2001 atomic_store(&check_listener_quota, true); 2002 doh_recv_send(arg); 2003 } 2004 2005 ISC_LOOP_TEST_IMPL(proxy_doh_recv_send_GET_TLS_quota) { 2006 atomic_store(&use_TLS, true); 2007 atomic_store(&use_PROXY, true); 2008 atomic_store(&check_listener_quota, true); 2009 doh_recv_send(arg); 2010 } 2011 2012 /* PROXY over TLS */ 2013 2014 ISC_LOOP_TEST_IMPL(proxytls_doh_recv_one_POST_TLS) { 2015 atomic_store(&POST, true); 2016 atomic_store(&use_TLS, true); 2017 atomic_store(&use_PROXY, true); 2018 atomic_store(&use_PROXY_over_TLS, true); 2019 doh_recv_one(arg); 2020 } 2021 2022 ISC_LOOP_TEST_IMPL(proxytls_doh_recv_one_GET_TLS) { 2023 atomic_store(&use_TLS, true); 2024 atomic_store(&use_PROXY, true); 2025 atomic_store(&use_PROXY_over_TLS, true); 2026 doh_recv_one(arg); 2027 } 2028 2029 ISC_LOOP_TEST_IMPL(proxytls_doh_recv_one_GET_TLS_quota) { 2030 atomic_store(&use_TLS, true); 2031 atomic_store(&use_PROXY, true); 2032 atomic_store(&use_PROXY_over_TLS, true); 2033 atomic_store(&check_listener_quota, true); 2034 doh_recv_one(arg); 2035 } 2036 2037 ISC_LOOP_TEST_IMPL(proxytls_doh_recv_one_POST_TLS_quota) { 2038 atomic_store(&POST, true); 2039 atomic_store(&use_TLS, true); 2040 atomic_store(&use_PROXY, true); 2041 atomic_store(&use_PROXY_over_TLS, true); 2042 atomic_store(&check_listener_quota, true); 2043 doh_recv_one(arg); 2044 } 2045 2046 ISC_LOOP_TEST_IMPL(proxytls_doh_recv_two_POST_TLS) { 2047 atomic_store(&POST, true); 2048 atomic_store(&use_TLS, true); 2049 atomic_store(&use_PROXY, true); 2050 atomic_store(&use_PROXY_over_TLS, true); 2051 doh_recv_two(arg); 2052 } 2053 2054 ISC_LOOP_TEST_IMPL(proxytls_doh_recv_two_GET_TLS) { 2055 atomic_store(&use_TLS, true); 2056 atomic_store(&use_PROXY, true); 2057 atomic_store(&use_PROXY_over_TLS, true); 2058 doh_recv_two(arg); 2059 } 2060 2061 ISC_LOOP_TEST_IMPL(proxytls_doh_recv_two_POST_TLS_quota) { 2062 atomic_store(&POST, true); 2063 atomic_store(&use_TLS, true); 2064 atomic_store(&use_PROXY, true); 2065 atomic_store(&use_PROXY_over_TLS, true); 2066 atomic_store(&check_listener_quota, true); 2067 doh_recv_two(arg); 2068 } 2069 2070 ISC_LOOP_TEST_IMPL(proxytls_doh_recv_two_GET_TLS_quota) { 2071 atomic_store(&use_TLS, true); 2072 atomic_store(&use_PROXY, true); 2073 atomic_store(&use_PROXY_over_TLS, true); 2074 atomic_store(&check_listener_quota, true); 2075 doh_recv_two(arg); 2076 } 2077 2078 ISC_LOOP_TEST_IMPL(proxytls_doh_recv_send_POST_TLS) { 2079 atomic_store(&POST, true); 2080 atomic_store(&use_TLS, true); 2081 atomic_store(&use_PROXY, true); 2082 atomic_store(&use_PROXY_over_TLS, true); 2083 doh_recv_send(arg); 2084 } 2085 2086 ISC_LOOP_TEST_IMPL(proxytls_doh_recv_send_GET_TLS) { 2087 atomic_store(&use_TLS, true); 2088 atomic_store(&use_PROXY, true); 2089 atomic_store(&use_PROXY_over_TLS, true); 2090 doh_recv_send(arg); 2091 } 2092 2093 ISC_LOOP_TEST_IMPL(proxytls_doh_recv_send_POST_TLS_quota) { 2094 atomic_store(&POST, true); 2095 atomic_store(&use_TLS, true); 2096 atomic_store(&use_PROXY, true); 2097 atomic_store(&use_PROXY_over_TLS, true); 2098 atomic_store(&check_listener_quota, true); 2099 doh_recv_send(arg); 2100 } 2101 2102 ISC_LOOP_TEST_IMPL(proxytls_doh_recv_send_GET_TLS_quota) { 2103 atomic_store(&use_TLS, true); 2104 atomic_store(&use_PROXY, true); 2105 atomic_store(&use_PROXY_over_TLS, true); 2106 atomic_store(&check_listener_quota, true); 2107 doh_recv_send(arg); 2108 } 2109 2110 ISC_TEST_LIST_START 2111 2112 ISC_TEST_ENTRY_CUSTOM(mock_doh_uv_tcp_bind, setup_test, teardown_test) 2113 ISC_TEST_ENTRY(doh_parse_GET_query_string) 2114 ISC_TEST_ENTRY(doh_base64url_to_base64) 2115 ISC_TEST_ENTRY(doh_base64_to_base64url) 2116 ISC_TEST_ENTRY(doh_path_validation) 2117 ISC_TEST_ENTRY(doh_connect_makeuri) 2118 ISC_TEST_ENTRY_CUSTOM(doh_noop_POST, setup_test, teardown_test) 2119 ISC_TEST_ENTRY_CUSTOM(doh_noop_GET, setup_test, teardown_test) 2120 ISC_TEST_ENTRY_CUSTOM(doh_noresponse_POST, setup_test, teardown_test) 2121 ISC_TEST_ENTRY_CUSTOM(doh_noresponse_GET, setup_test, teardown_test) 2122 ISC_TEST_ENTRY_CUSTOM(doh_timeout_recovery_POST, setup_test, 2123 doh_timeout_recovery_teardown) 2124 ISC_TEST_ENTRY_CUSTOM(doh_timeout_recovery_GET, setup_test, 2125 doh_timeout_recovery_teardown) 2126 ISC_TEST_ENTRY_CUSTOM(doh_recv_one_POST, setup_test, doh_recv_one_teardown) 2127 ISC_TEST_ENTRY_CUSTOM(doh_recv_one_GET, setup_test, doh_recv_one_teardown) 2128 ISC_TEST_ENTRY_CUSTOM(doh_recv_one_POST_TLS, setup_test, doh_recv_one_teardown) 2129 ISC_TEST_ENTRY_CUSTOM(doh_recv_one_GET_TLS, setup_test, doh_recv_one_teardown) 2130 ISC_TEST_ENTRY_CUSTOM(doh_recv_one_POST_quota, setup_test, 2131 doh_recv_one_teardown) 2132 ISC_TEST_ENTRY_CUSTOM(doh_recv_one_GET_quota, setup_test, doh_recv_one_teardown) 2133 ISC_TEST_ENTRY_CUSTOM(doh_recv_one_POST_TLS_quota, setup_test, 2134 doh_recv_one_teardown) 2135 ISC_TEST_ENTRY_CUSTOM(doh_recv_one_GET_TLS_quota, setup_test, 2136 doh_recv_one_teardown) 2137 ISC_TEST_ENTRY_CUSTOM(doh_recv_two_POST, setup_test, doh_recv_two_teardown) 2138 ISC_TEST_ENTRY_CUSTOM(doh_recv_two_GET, setup_test, doh_recv_two_teardown) 2139 ISC_TEST_ENTRY_CUSTOM(doh_recv_two_POST_TLS, setup_test, doh_recv_two_teardown) 2140 ISC_TEST_ENTRY_CUSTOM(doh_recv_two_GET_TLS, setup_test, doh_recv_two_teardown) 2141 ISC_TEST_ENTRY_CUSTOM(doh_recv_two_POST_quota, setup_test, 2142 doh_recv_two_teardown) 2143 ISC_TEST_ENTRY_CUSTOM(doh_recv_two_GET_quota, setup_test, doh_recv_two_teardown) 2144 ISC_TEST_ENTRY_CUSTOM(doh_recv_two_POST_TLS_quota, setup_test, 2145 doh_recv_two_teardown) 2146 ISC_TEST_ENTRY_CUSTOM(doh_recv_two_GET_TLS_quota, setup_test, 2147 doh_recv_two_teardown) 2148 ISC_TEST_ENTRY_CUSTOM(doh_recv_send_GET, setup_test, doh_recv_send_teardown) 2149 ISC_TEST_ENTRY_CUSTOM(doh_recv_send_POST, setup_test, doh_recv_send_teardown) 2150 ISC_TEST_ENTRY_CUSTOM(doh_recv_send_GET_TLS, setup_test, doh_recv_send_teardown) 2151 ISC_TEST_ENTRY_CUSTOM(doh_recv_send_POST_TLS, setup_test, 2152 doh_recv_send_teardown) 2153 ISC_TEST_ENTRY_CUSTOM(doh_recv_send_GET_quota, setup_test, 2154 doh_recv_send_teardown) 2155 ISC_TEST_ENTRY_CUSTOM(doh_recv_send_POST_quota, setup_test, 2156 doh_recv_send_teardown) 2157 ISC_TEST_ENTRY_CUSTOM(doh_recv_send_GET_TLS_quota, setup_test, 2158 doh_recv_send_teardown) 2159 ISC_TEST_ENTRY_CUSTOM(doh_recv_send_POST_TLS_quota, setup_test, 2160 doh_recv_send_teardown) 2161 ISC_TEST_ENTRY_CUSTOM(doh_bad_connect_uri, setup_test, 2162 doh_bad_connect_uri_teardown) 2163 /* PROXY */ 2164 ISC_TEST_ENTRY_CUSTOM(proxy_doh_noop_POST, setup_test, teardown_test) 2165 ISC_TEST_ENTRY_CUSTOM(proxy_doh_noop_GET, setup_test, teardown_test) 2166 ISC_TEST_ENTRY_CUSTOM(proxy_doh_noresponse_POST, setup_test, teardown_test) 2167 ISC_TEST_ENTRY_CUSTOM(proxy_doh_noresponse_GET, setup_test, teardown_test) 2168 ISC_TEST_ENTRY_CUSTOM(proxy_doh_timeout_recovery_POST, setup_test, 2169 doh_timeout_recovery_teardown) 2170 ISC_TEST_ENTRY_CUSTOM(proxy_doh_timeout_recovery_GET, setup_test, 2171 doh_timeout_recovery_teardown) 2172 ISC_TEST_ENTRY_CUSTOM(proxy_doh_recv_one_POST, setup_test, 2173 doh_recv_one_teardown) 2174 ISC_TEST_ENTRY_CUSTOM(proxy_doh_recv_one_GET, setup_test, doh_recv_one_teardown) 2175 ISC_TEST_ENTRY_CUSTOM(proxy_doh_recv_one_POST_TLS, setup_test, 2176 doh_recv_one_teardown) 2177 ISC_TEST_ENTRY_CUSTOM(proxy_doh_recv_one_GET_TLS, setup_test, 2178 doh_recv_one_teardown) 2179 ISC_TEST_ENTRY_CUSTOM(proxy_doh_recv_one_POST_quota, setup_test, 2180 doh_recv_one_teardown) 2181 ISC_TEST_ENTRY_CUSTOM(proxy_doh_recv_one_GET_quota, setup_test, 2182 doh_recv_one_teardown) 2183 ISC_TEST_ENTRY_CUSTOM(proxy_doh_recv_one_POST_TLS_quota, setup_test, 2184 doh_recv_one_teardown) 2185 ISC_TEST_ENTRY_CUSTOM(proxy_doh_recv_one_GET_TLS_quota, setup_test, 2186 doh_recv_one_teardown) 2187 ISC_TEST_ENTRY_CUSTOM(proxy_doh_recv_two_POST, setup_test, 2188 doh_recv_two_teardown) 2189 ISC_TEST_ENTRY_CUSTOM(proxy_doh_recv_two_GET, setup_test, doh_recv_two_teardown) 2190 ISC_TEST_ENTRY_CUSTOM(proxy_doh_recv_two_POST_TLS, setup_test, 2191 doh_recv_two_teardown) 2192 ISC_TEST_ENTRY_CUSTOM(proxy_doh_recv_two_GET_TLS, setup_test, 2193 doh_recv_two_teardown) 2194 ISC_TEST_ENTRY_CUSTOM(proxy_doh_recv_two_POST_quota, setup_test, 2195 doh_recv_two_teardown) 2196 ISC_TEST_ENTRY_CUSTOM(proxy_doh_recv_two_GET_quota, setup_test, 2197 doh_recv_two_teardown) 2198 ISC_TEST_ENTRY_CUSTOM(proxy_doh_recv_two_POST_TLS_quota, setup_test, 2199 doh_recv_two_teardown) 2200 ISC_TEST_ENTRY_CUSTOM(proxy_doh_recv_two_GET_TLS_quota, setup_test, 2201 doh_recv_two_teardown) 2202 ISC_TEST_ENTRY_CUSTOM(proxy_doh_recv_send_GET, setup_test, 2203 doh_recv_send_teardown) 2204 ISC_TEST_ENTRY_CUSTOM(proxy_doh_recv_send_POST, setup_test, 2205 doh_recv_send_teardown) 2206 ISC_TEST_ENTRY_CUSTOM(proxy_doh_recv_send_GET_TLS, setup_test, 2207 doh_recv_send_teardown) 2208 ISC_TEST_ENTRY_CUSTOM(proxy_doh_recv_send_POST_TLS, setup_test, 2209 doh_recv_send_teardown) 2210 ISC_TEST_ENTRY_CUSTOM(proxy_doh_recv_send_GET_quota, setup_test, 2211 doh_recv_send_teardown) 2212 ISC_TEST_ENTRY_CUSTOM(proxy_doh_recv_send_POST_quota, setup_test, 2213 doh_recv_send_teardown) 2214 ISC_TEST_ENTRY_CUSTOM(proxy_doh_recv_send_GET_TLS_quota, setup_test, 2215 doh_recv_send_teardown) 2216 ISC_TEST_ENTRY_CUSTOM(proxy_doh_recv_send_POST_TLS_quota, setup_test, 2217 doh_recv_send_teardown) 2218 /* PROXY over TLS */ 2219 ISC_TEST_ENTRY_CUSTOM(proxytls_doh_recv_one_POST_TLS, setup_test, 2220 doh_recv_one_teardown) 2221 ISC_TEST_ENTRY_CUSTOM(proxytls_doh_recv_one_GET_TLS, setup_test, 2222 doh_recv_one_teardown) 2223 ISC_TEST_ENTRY_CUSTOM(proxytls_doh_recv_one_POST_TLS_quota, setup_test, 2224 doh_recv_one_teardown) 2225 ISC_TEST_ENTRY_CUSTOM(proxytls_doh_recv_one_GET_TLS_quota, setup_test, 2226 doh_recv_one_teardown) 2227 ISC_TEST_ENTRY_CUSTOM(proxytls_doh_recv_two_POST_TLS, setup_test, 2228 doh_recv_two_teardown) 2229 ISC_TEST_ENTRY_CUSTOM(proxytls_doh_recv_two_GET_TLS, setup_test, 2230 doh_recv_two_teardown) 2231 ISC_TEST_ENTRY_CUSTOM(proxytls_doh_recv_two_POST_TLS_quota, setup_test, 2232 doh_recv_two_teardown) 2233 ISC_TEST_ENTRY_CUSTOM(proxytls_doh_recv_two_GET_TLS_quota, setup_test, 2234 doh_recv_two_teardown) 2235 ISC_TEST_ENTRY_CUSTOM(proxytls_doh_recv_send_GET_TLS, setup_test, 2236 doh_recv_send_teardown) 2237 ISC_TEST_ENTRY_CUSTOM(proxytls_doh_recv_send_POST_TLS, setup_test, 2238 doh_recv_send_teardown) 2239 ISC_TEST_ENTRY_CUSTOM(proxytls_doh_recv_send_GET_TLS_quota, setup_test, 2240 doh_recv_send_teardown) 2241 ISC_TEST_ENTRY_CUSTOM(proxytls_doh_recv_send_POST_TLS_quota, setup_test, 2242 doh_recv_send_teardown) 2243 ISC_TEST_LIST_END 2244 2245 ISC_TEST_MAIN 2246