From: W.C.A. Wijngaards Date: Thu, 2 Jul 2026 09:10:06 +0000 (+0200) Subject: - auth-load-thread, basic test and fixes so it works. X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=55ae8da0324acced551802fcfaa889bce9714301;p=thirdparty%2Funbound.git - auth-load-thread, basic test and fixes so it works. --- diff --git a/services/authload.c b/services/authload.c index 756ece7da..ea45ef1c5 100644 --- a/services/authload.c +++ b/services/authload.c @@ -631,6 +631,7 @@ auth_load_thread_delete(struct auth_load_thread* thr) sock_close(thr->commpair[0]); if(thr->commpair[1] != -1) sock_close(thr->commpair[1]); + auth_load_task_delete(thr->task); free(thr); } @@ -746,7 +747,12 @@ auth_load_thread_attach(struct auth_load_thread* thr, struct worker* worker) * The commpair[1] element can stay blocking, it is used by the * auth load thread. The thread needs to wait at these times, when * it has to check briefly it can use poll. */ + verbose(VERB_ALGO, "auth_load_thread_attach"); fd_set_nonblock(thr->commpair[0]); + if(!comm_base_internal(worker->base)) { + verbose(VERB_ALGO, "auth load thread: no event base"); + return 0; + } thr->service_event = ub_event_new(comm_base_internal(worker->base), thr->commpair[0], UB_EV_READ | UB_EV_PERSIST, worker_auth_load_service_cb, thr); @@ -787,6 +793,7 @@ int auth_load_add_task_xfr(struct auth_xfer* xfr, struct worker* worker) { struct auth_load_task* task; int can_run = 0; + verbose(VERB_ALGO, "auth load add task"); /* Check auth load count */ can_run = 1; @@ -796,8 +803,10 @@ int auth_load_add_task_xfr(struct auth_xfer* xfr, struct worker* worker) if(!task) return 0; if(can_run) { + verbose(VERB_ALGO, "auth load start thread"); if(!auth_load_start_thread(task)) return 0; + verbose(VERB_ALGO, "auth load thread started"); return 1; } diff --git a/services/authzone.c b/services/authzone.c index cdf1b9533..12f5b220c 100644 --- a/services/authzone.c +++ b/services/authzone.c @@ -6394,6 +6394,7 @@ process_list_end_transfer(struct auth_xfer* xfr, struct module_env* env) * is signalled with the result. */ /* When it is done, the xfr_process_load_end_transfer * routine is called. */ + lock_basic_unlock(&xfr->lock); return; } } else if(xfr_process_chunk_list(xfr, env, &ixfr_fail)) { @@ -6414,6 +6415,7 @@ xfr_process_loaded_transfer(struct auth_xfer* xfr, struct module_env* env, int* gone) { struct auth_zone* z = NULL; + verbose(VERB_ALGO, "xfr_process_loaded_transfer"); lock_basic_unlock(&xfr->lock); if(!xfr_process_reacquire_locks(xfr, env, &z)) { /* the zone is gone, ignore xfr results */ @@ -6422,6 +6424,7 @@ xfr_process_loaded_transfer(struct auth_xfer* xfr, struct module_env* env, } /* holding xfr and z locks */ + verbose(VERB_ALGO, "xfr_process_loaded_transfer: num_ixfrs"); if(xfr->task_transfer->master->http) { xfr->num_ixfrs = 0; xfr->have_zone = 0; @@ -6436,6 +6439,7 @@ xfr_process_loaded_transfer(struct auth_xfer* xfr, struct module_env* env, xfr->serial = 0; } + verbose(VERB_ALGO, "xfr_process_loaded_transfer: find_soa"); xfr->zone_expired = 0; z->zone_expired = 0; if(!xfr_find_soa(z, xfr)) { @@ -6450,6 +6454,7 @@ xfr_process_loaded_transfer(struct auth_xfer* xfr, struct module_env* env, /* release xfr lock while verifying zonemd because it may have * to spawn lookups in the state machines */ lock_basic_unlock(&xfr->lock); + verbose(VERB_ALGO, "xfr_process_loaded_transfer: verify_zonemd"); /* holding z lock */ auth_zone_verify_zonemd(z, env, &env->mesh->mods, NULL, 0, 0); if(z->zone_expired) { @@ -6479,6 +6484,7 @@ xfr_process_loaded_transfer(struct auth_xfer* xfr, struct module_env* env, } /* holding xfr and z locks */ + verbose(VERB_ALGO, "xfr_process_loaded_transfer: lease"); if(xfr->have_zone) xfr->lease_time = *env->now; /* unlock */ @@ -6490,6 +6496,7 @@ xfr_process_loaded_transfer(struct auth_xfer* xfr, struct module_env* env, verbose(VERB_QUERY, "auth zone %s updated to serial %u", zname, (unsigned)xfr->serial); } + verbose(VERB_ALGO, "xfr_process_loaded_transfer: write after update"); /* see if we need to write to a zonefile */ xfr_write_after_update(xfr, env); @@ -6501,6 +6508,7 @@ void xfr_process_load_end_transfer(struct auth_xfer* xfr, struct auth_chunk* chunk_list) { /* Chunks are put here for the auth zone write for the http case. */ + verbose(VERB_ALGO, "xfr_process_load_end_transfer"); xfr->task_transfer->chunks_first = chunk_list; if(status) { int gone = 0; @@ -6514,14 +6522,17 @@ void xfr_process_load_end_transfer(struct auth_xfer* xfr, } } } + verbose(VERB_ALGO, "xfr_process_load_end_transfer: chunks delete"); auth_chunks_delete(xfr->task_transfer); if(status) { /* it worked! */ + verbose(VERB_ALGO, "xfr_process_load_end_transfer: success"); xfr_process_transfer_success(xfr, env); return; } /* The transfer failed */ + verbose(VERB_ALGO, "xfr_process_load_end_transfer: failed"); xfr_process_transfer_failed(xfr, env, ixfr_fail); } diff --git a/testdata/auth_load.tdir/auth_load.conf b/testdata/auth_load.tdir/auth_load.conf new file mode 100644 index 000000000..a3be0c0b9 --- /dev/null +++ b/testdata/auth_load.tdir/auth_load.conf @@ -0,0 +1,17 @@ +server: + verbosity: 7 + # num-threads: 1 + interface: 127.0.0.1 + port: @PORT@ + use-syslog: no + directory: "" + pidfile: "unbound.pid" + chroot: "" + username: "" + do-not-query-localhost: no +auth-zone: + name: "example.com" + for-upstream: yes + for-downstream: yes + master: "127.0.0.1@@TOPORT@" + diff --git a/testdata/auth_load.tdir/auth_load.dsc b/testdata/auth_load.tdir/auth_load.dsc new file mode 100644 index 000000000..292b7bc1e --- /dev/null +++ b/testdata/auth_load.tdir/auth_load.dsc @@ -0,0 +1,16 @@ +BaseName: auth_load +Version: 1.0 +Description: Perform AXFR for authority zone with auth load thread +CreationDate: Thu 2 Jul 09:35:40 CEST 2026 +Maintainer: dr. W.C.A. Wijngaards +Category: +Component: +CmdDepends: +Depends: +Help: +Pre: auth_load.pre +Post: auth_load.post +Test: auth_load.test +AuxFiles: +Passed: +Failure: diff --git a/testdata/auth_load.tdir/auth_load.post b/testdata/auth_load.tdir/auth_load.post new file mode 100644 index 000000000..114017a4f --- /dev/null +++ b/testdata/auth_load.tdir/auth_load.post @@ -0,0 +1,12 @@ +# #-- auth_load.post --# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# source the test var file when it's there +[ -f .tpkg.var.test ] && source .tpkg.var.test +# +# do your teardown here +. ../common.sh +kill_pid $FWD_PID +kill_pid $UNBOUND_PID +cat fwd.log +cat unbound.log diff --git a/testdata/auth_load.tdir/auth_load.pre b/testdata/auth_load.tdir/auth_load.pre new file mode 100644 index 000000000..27ee585d2 --- /dev/null +++ b/testdata/auth_load.tdir/auth_load.pre @@ -0,0 +1,32 @@ +# #-- auth_load.pre--# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# use .tpkg.var.test for in test variable passing +[ -f .tpkg.var.test ] && source .tpkg.var.test + +. ../common.sh +get_random_port 2 +UNBOUND_PORT=$RND_PORT +FWD_PORT=$(($RND_PORT + 1)) +echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test +echo "FWD_PORT=$FWD_PORT" >> .tpkg.var.test + +# start forwarder +get_ldns_testns +$LDNS_TESTNS -p $FWD_PORT auth_load.testns >fwd.log 2>&1 & +FWD_PID=$! +echo "FWD_PID=$FWD_PID" >> .tpkg.var.test + +# make config file +sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@TOPORT\@/'$FWD_PORT'/' < auth_load.conf > ub.conf +# start unbound in the background +PRE="../.." +$PRE/unbound -d -c ub.conf >unbound.log 2>&1 & +#valgrind --leak-check=full --show-reachable=yes $PRE/unbound -d -c ub.conf >unbound.log 2>&1 & +UNBOUND_PID=$! +echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test + +cat .tpkg.var.test +wait_ldns_testns_up fwd.log +wait_unbound_up unbound.log + diff --git a/testdata/auth_load.tdir/auth_load.test b/testdata/auth_load.tdir/auth_load.test new file mode 100644 index 000000000..c14b463c3 --- /dev/null +++ b/testdata/auth_load.tdir/auth_load.test @@ -0,0 +1,48 @@ +# #-- auth_load.test --# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# use .tpkg.var.test for in test variable passing +[ -f .tpkg.var.test ] && source .tpkg.var.test + +PRE="../.." +# do the test +echo "> dig www.example.com." +dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile +if grep SERVFAIL outfile; then + echo "> try again" + dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile +fi +if grep SERVFAIL outfile; then + echo "> try again" + sleep 1 + dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile +fi +if grep SERVFAIL outfile; then + echo "> try again" + sleep 1 + dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile +fi +if grep SERVFAIL outfile; then + echo "> try again" + sleep 1 + dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile +fi +if grep SERVFAIL outfile; then + echo "> try again" +# sleep 10 + dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile +fi +if grep SERVFAIL outfile; then + echo "> try again" +# sleep 10 + dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile +fi +echo "> check answer" +if grep "1.2.3.4" outfile; then + echo "OK" +else + echo "Not OK" + exit 1 +fi + +exit 0 diff --git a/testdata/auth_load.tdir/auth_load.testns b/testdata/auth_load.tdir/auth_load.testns new file mode 100644 index 000000000..f1678a1cc --- /dev/null +++ b/testdata/auth_load.tdir/auth_load.testns @@ -0,0 +1,27 @@ +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +example.com. IN SOA +SECTION ANSWER +example.com. IN SOA ns.example.com. hostmaster.example.com. 1 3600 900 86400 3600 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +example.com. IN AXFR +SECTION ANSWER +example.com. IN SOA ns.example.com. hostmaster.example.com. 1 3600 900 86400 3600 +example.com. IN NS ns.example.net. +EXTRA_PACKET +REPLY QR AA NOERROR +SECTION QUESTION +example.com. IN AXFR +SECTION ANSWER +www.example.com. IN A 1.2.3.4 +example.com. IN SOA ns.example.com. hostmaster.example.com. 1 3600 900 86400 3600 +ENTRY_END