]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
add a UDP timeout recovery test
authorEvan Hunt <each@isc.org>
Wed, 21 Apr 2021 04:08:10 +0000 (21:08 -0700)
committerEvan Hunt <each@isc.org>
Thu, 22 Apr 2021 19:08:04 +0000 (12:08 -0700)
this test sets up a server socket that listens for UDP connections
but never responds. the client will always time out; it should retry
five times before giving up.

lib/isc/tests/netmgr_test.c

index 793a6b04f3e8b5be29fb072d642895a1b8254a43..55b7d3ef37b63172f9499e1ac6b4e6db31f832ce 100644 (file)
@@ -73,13 +73,14 @@ static unsigned int workers = 0;
 static atomic_int_fast64_t nsends;
 static int_fast64_t esends; /* expected sends */
 
-static atomic_int_fast64_t ssends;
-static atomic_int_fast64_t sreads;
-static atomic_int_fast64_t saccepts;
+static atomic_int_fast64_t ssends = ATOMIC_VAR_INIT(0);
+static atomic_int_fast64_t sreads = ATOMIC_VAR_INIT(0);
+static atomic_int_fast64_t saccepts = ATOMIC_VAR_INIT(0);
 
-static atomic_int_fast64_t cconnects;
-static atomic_int_fast64_t csends;
-static atomic_int_fast64_t creads;
+static atomic_int_fast64_t cconnects = ATOMIC_VAR_INIT(0);
+static atomic_int_fast64_t csends = ATOMIC_VAR_INIT(0);
+static atomic_int_fast64_t creads = ATOMIC_VAR_INIT(0);
+static atomic_int_fast64_t ctimeouts = ATOMIC_VAR_INIT(0);
 
 static isc_refcount_t active_cconnects;
 static isc_refcount_t active_csends;
@@ -314,6 +315,7 @@ nm_setup(void **state __attribute__((unused))) {
        atomic_store(&cconnects, 0);
        atomic_store(&csends, 0);
        atomic_store(&creads, 0);
+       atomic_store(&ctimeouts, 0);
        allow_send_back = false;
        stream_use_TLS = false;
 
@@ -463,7 +465,7 @@ connect_read_cb(isc_nmhandle_t *handle, isc_result_t eresult,
        }
 
 unref:
-       atomic_fetch_sub(&active_creads, 1);
+       isc_refcount_decrement(&active_creads);
        isc_nmhandle_detach(&handle);
 }
 
@@ -794,6 +796,67 @@ udp_noresponse(void **state __attribute__((unused))) {
        atomic_assert_int_eq(ssends, 0);
 }
 
+static void
+timeout_retry_cb(isc_nmhandle_t *handle, isc_result_t eresult,
+                isc_region_t *region, void *cbarg) {
+       UNUSED(region);
+       UNUSED(cbarg);
+
+       assert_non_null(handle);
+
+       F();
+
+       if (eresult == ISC_R_TIMEDOUT && atomic_load(&csends) < 5) {
+               isc_nmhandle_settimeout(handle, 50);
+               connect_send(handle);
+               return;
+       }
+
+       atomic_fetch_add(&ctimeouts, 1);
+
+       isc_refcount_decrement(&active_creads);
+       isc_nmhandle_detach(&handle);
+}
+
+static void
+udp_timeout_recovery(void **state __attribute__((unused))) {
+       isc_result_t result = ISC_R_SUCCESS;
+       isc_nmsocket_t *listen_sock = NULL;
+
+       SKIP_IN_CI;
+
+       /*
+        * Listen using the noop callback so that client reads will time out.
+        */
+       result = isc_nm_listenudp(listen_nm, (isc_nmiface_t *)&udp_listen_addr,
+                                 noop_recv_cb, NULL, 0, &listen_sock);
+       assert_int_equal(result, ISC_R_SUCCESS);
+
+       /*
+        * Connect with client timeout set to 0.05 seconds, then sleep for at
+        * least a second for each 'tick'. timeout_retry_cb() will give up
+        * after five timeouts.
+        */
+       connect_readcb = timeout_retry_cb;
+       isc_refcount_increment0(&active_cconnects);
+       isc_nm_udpconnect(connect_nm, (isc_nmiface_t *)&udp_connect_addr,
+                         (isc_nmiface_t *)&udp_listen_addr, connect_connect_cb,
+                         NULL, 50, 0);
+
+       WAIT_FOR_EQ(cconnects, 1);
+       WAIT_FOR_GE(csends, 1);
+       WAIT_FOR_GE(csends, 2);
+       WAIT_FOR_GE(csends, 3);
+       WAIT_FOR_GE(csends, 4);
+       WAIT_FOR_EQ(csends, 5);
+       WAIT_FOR_EQ(ctimeouts, 1);
+
+       isc_nm_stoplistening(listen_sock);
+       isc_nmsocket_close(&listen_sock);
+       assert_null(listen_sock);
+       isc_nm_closedown(connect_nm);
+}
+
 static void
 udp_recv_one(void **state __attribute__((unused))) {
        isc_result_t result = ISC_R_SUCCESS;
@@ -2562,6 +2625,8 @@ main(void) {
                                                nm_teardown),
                cmocka_unit_test_setup_teardown(udp_noresponse, nm_setup,
                                                nm_teardown),
+               cmocka_unit_test_setup_teardown(udp_timeout_recovery, nm_setup,
+                                               nm_teardown),
                cmocka_unit_test_setup_teardown(udp_recv_one, nm_setup,
                                                nm_teardown),
                cmocka_unit_test_setup_teardown(udp_recv_two, nm_setup,