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)
if(!auth_load_process_ixfr(thr))
return 0;
} else {
+ if(!auth_load_process_axfr(thr))
+ return 0;
}
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,
+int
+xfr_apply_axfr(struct auth_chunk* chunk_list, struct auth_zone* z,
struct sldns_buffer* scratch_buffer)
{
struct auth_chunk* rr_chunk;
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,
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 */
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)
{
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 */