]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- auth-load-thread, basic test and fixes so it works.
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Thu, 2 Jul 2026 09:10:06 +0000 (11:10 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Thu, 2 Jul 2026 09:10:06 +0000 (11:10 +0200)
services/authload.c
services/authzone.c
testdata/auth_load.tdir/auth_load.conf [new file with mode: 0644]
testdata/auth_load.tdir/auth_load.dsc [new file with mode: 0644]
testdata/auth_load.tdir/auth_load.post [new file with mode: 0644]
testdata/auth_load.tdir/auth_load.pre [new file with mode: 0644]
testdata/auth_load.tdir/auth_load.test [new file with mode: 0644]
testdata/auth_load.tdir/auth_load.testns [new file with mode: 0644]

index 756ece7daedfe4587e916b55ce403b9e3defcd5f..ea45ef1c55edd61aabd025a723feb506c944adcf 100644 (file)
@@ -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;
        }
 
index cdf1b953312743b7608cd0a2987c1c9ae79a366e..12f5b220c17fdc553ab0f7aff65b0499ae96ccc0 100644 (file)
@@ -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 (file)
index 0000000..a3be0c0
--- /dev/null
@@ -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 (file)
index 0000000..292b7bc
--- /dev/null
@@ -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 (file)
index 0000000..114017a
--- /dev/null
@@ -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 (file)
index 0000000..27ee585
--- /dev/null
@@ -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 (file)
index 0000000..c14b463
--- /dev/null
@@ -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 (file)
index 0000000..f1678a1
--- /dev/null
@@ -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