]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- auth-load-thread, process AXFR, by loading, swap in, delete of old.
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Wed, 1 Jul 2026 12:27:31 +0000 (14:27 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Wed, 1 Jul 2026 12:27:31 +0000 (14:27 +0200)
services/authload.c
services/authzone.c
services/authzone.h

index 610a47bbabe778e15ad748e8c12e0d16be5c8ef8..c42c129aae699c938216c4d4e17d748e0c035379 100644 (file)
@@ -522,6 +522,50 @@ auth_load_process_ixfr(struct auth_load_thread* thr)
        return 1;
 }
 
+/** Process axfr transfer */
+static int
+auth_load_process_axfr(struct auth_load_thread* thr)
+{
+       struct auth_load_task* task = thr->task;
+       struct sldns_buffer* scratch_buffer;
+       struct auth_zone* z;
+
+       scratch_buffer = sldns_buffer_new(sldns_buffer_capacity(
+               thr->task->worker->env.scratch_buffer));
+       if(!scratch_buffer) {
+               log_err("out of memory");
+               return 0;
+       }
+       z = auth_zone_create_proxy(task->name, task->namelen, task->dclass);
+       if(!z) {
+               log_err("out of memory");
+               sldns_buffer_free(scratch_buffer);
+               return 0;
+       }
+       if(auth_load_thread_poll_for_quit(thr)) {
+               sldns_buffer_free(scratch_buffer);
+               auth_zone_delete_proxy(z);
+               return 0;
+       }
+
+       if(!xfr_apply_axfr(task->chunks_first, z, scratch_buffer)) {
+               sldns_buffer_free(scratch_buffer);
+               auth_zone_delete_proxy(z);
+               return 0;
+       }
+       if(auth_load_thread_poll_for_quit(thr)) {
+               sldns_buffer_free(scratch_buffer);
+               auth_zone_delete_proxy(z);
+               return 0;
+       }
+
+       auth_load_swap_zone(thr, z);
+       auth_zone_delete_proxy(z);
+       sldns_buffer_free(scratch_buffer);
+       return 1;
+}
+
+
 /** In the auth load thread, process the task */
 static int
 auth_load_thread_process(struct auth_load_thread* thr)
@@ -536,6 +580,8 @@ auth_load_thread_process(struct auth_load_thread* thr)
                if(!auth_load_process_ixfr(thr))
                        return 0;
        } else {
+               if(!auth_load_process_axfr(thr))
+                       return 0;
        }
        return 1;
 }
index 9e601484a68f9ba29af139e5890e0e970e06fcfd..5eb89c58a5a294927a1a40a8b996e83ba98258a0 100644 (file)
@@ -5142,8 +5142,8 @@ apply_ixfr(struct auth_xfer* xfr, struct auth_zone* z,
 }
 
 /** apply AXFR to zone in memory. z is locked. false on failure(mallocfail) */
-static int
-apply_axfr(struct auth_xfer* xfr, struct auth_zone* z,
+int
+xfr_apply_axfr(struct auth_chunk* chunk_list, struct auth_zone* z,
        struct sldns_buffer* scratch_buffer)
 {
        struct auth_chunk* rr_chunk;
@@ -5152,22 +5152,16 @@ apply_axfr(struct auth_xfer* xfr, struct auth_zone* z,
        uint8_t* rr_dname, *rr_rdata;
        uint16_t rr_type, rr_class, rr_rdlen;
        uint32_t rr_ttl;
-       uint32_t serial = 0;
        size_t rr_nextpos;
        size_t rr_counter = 0;
        int have_end_soa = 0;
 
        auth_zone_clear_data(z);
-       xfr->have_zone = 0;
-       xfr->serial = 0;
-       xfr->soa_zone_acquired = 0;
-       xfr->num_ixfrs = 0;
 
        /* insert all RRs in to the zone */
        /* insert the SOA only once, skip the last one */
        /* start RR iterator over chunklist of packets */
-       chunk_rrlist_start(xfr->task_transfer->chunks_first, &rr_chunk,
-               &rr_num, &rr_pos);
+       chunk_rrlist_start(chunk_list, &rr_chunk, &rr_num, &rr_pos);
        while(!chunk_rrlist_end(rr_chunk, rr_num)) {
                if(!chunk_rrlist_get_current(rr_chunk, rr_num, rr_pos,
                        &rr_dname, &rr_type, &rr_class, &rr_ttl, &rr_rdlen,
@@ -5184,7 +5178,7 @@ apply_axfr(struct auth_xfer* xfr, struct auth_zone* z,
                                break;
                        }
                        if(rr_rdlen < 22) return 0; /* bad SOA rdlen */
-                       serial = sldns_read_uint32(rr_rdata+rr_rdlen-20);
+                       /* serial is at sldns_read_uint32(rr_rdata+rr_rdlen-20); */
                }
 
                /* add this RR */
@@ -5202,12 +5196,24 @@ apply_axfr(struct auth_xfer* xfr, struct auth_zone* z,
                log_err("no end SOA record for AXFR");
                return 0;
        }
-
-       xfr->serial = serial;
-       xfr->have_zone = 1;
+       /* xfr->serial and xfr->have_zone are set by xfr_find_soa
+        * after this function. */
        return 1;
 }
 
+/** apply AXFR to zone in memory. z is locked. false on failure(mallocfail) */
+static int
+apply_axfr(struct auth_xfer* xfr, struct auth_zone* z,
+       struct sldns_buffer* scratch_buffer)
+{
+       xfr->have_zone = 0;
+       xfr->serial = 0;
+       xfr->soa_zone_acquired = 0;
+       xfr->num_ixfrs = 0;
+       return xfr_apply_axfr(xfr->task_transfer->chunks_first, z,
+               scratch_buffer);
+}
+
 void
 xfr_http_preview(const char* file, struct auth_chunk* chunk_list)
 {
index b8f4c55b3f55d8a259069d6a8d56ec6bf9286ffe..89e34eaa1885b74cc3d235ad655dd3e66def1677 100644 (file)
@@ -885,4 +885,8 @@ int xfr_apply_http(uint8_t* name, size_t namelen, const char* host,
 int xfr_apply_ixfr(struct auth_chunk* chunk_list, uint32_t xfr_serial,
        struct auth_zone* z, struct sldns_buffer* scratch_buffer);
 
+/** Apply AXFR transfer to auth_zone */
+int xfr_apply_axfr(struct auth_chunk* chunk_list, struct auth_zone* z,
+       struct sldns_buffer* scratch_buffer);
+
 #endif /* SERVICES_AUTHZONE_H */