mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-09-28 12:44:58 +02:00
- auth-load-thread, process end of successful transfer.
This commit is contained in:
+11
-1
@@ -668,6 +668,7 @@ worker_auth_load_service_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(bits),
|
||||
uint8_t recv_item;
|
||||
ssize_t ret;
|
||||
struct auth_xfer* xfr;
|
||||
struct auth_chunk* chunk_list;
|
||||
struct module_env* env;
|
||||
int ixfr_fail;
|
||||
|
||||
@@ -721,8 +722,17 @@ worker_auth_load_service_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(bits),
|
||||
lock_rw_unlock(&thr->task->worker->env.auth_zones->lock);
|
||||
env = &thr->task->worker->env;
|
||||
ixfr_fail = thr->task->ixfr_fail;
|
||||
if(thr->task->on_http) {
|
||||
chunk_list = thr->task->chunks_first;
|
||||
thr->task->chunks_first = NULL;
|
||||
thr->task->chunks_last = NULL;
|
||||
thr->task->chunks_total = 0;
|
||||
} else {
|
||||
chunk_list = NULL;
|
||||
}
|
||||
auth_load_thread_delete(thr);
|
||||
xfr_process_load_end_transfer(xfr, env, recv_item, ixfr_fail);
|
||||
xfr_process_load_end_transfer(xfr, env, recv_item, ixfr_fail,
|
||||
chunk_list);
|
||||
}
|
||||
|
||||
/** Attach worker to the auth load thread. */
|
||||
|
||||
+105
-35
@@ -6407,47 +6407,117 @@ process_list_end_transfer(struct auth_xfer* xfr, struct module_env* env)
|
||||
xfr_process_transfer_failed(xfr, env, ixfr_fail);
|
||||
}
|
||||
|
||||
void xfr_process_load_end_transfer(struct auth_xfer* xfr,
|
||||
struct module_env* env, uint8_t status, int ixfr_fail)
|
||||
/** deal with successful load end, starts holding xfr lock,
|
||||
* ends holding xfr lock. */
|
||||
static int
|
||||
xfr_process_loaded_transfer(struct auth_xfer* xfr, struct module_env* env,
|
||||
int* gone)
|
||||
{
|
||||
if(status) {
|
||||
struct auth_zone* z = NULL;
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
if(!xfr_process_reacquire_locks(xfr, env, &z)) {
|
||||
/* the zone is gone, ignore xfr results */
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
return;
|
||||
}
|
||||
/* holding xfr and z locks */
|
||||
|
||||
if(xfr->task_transfer->master->http) {
|
||||
xfr->num_ixfrs = 0;
|
||||
} else if(xfr->task_transfer->on_ixfr &&
|
||||
!xfr->task_transfer->on_ixfr_is_axfr) {
|
||||
xfr->num_ixfrs++;
|
||||
} else {
|
||||
/* AXFR */
|
||||
xfr->num_ixfrs = 0;
|
||||
}
|
||||
|
||||
xfr->zone_expired = 0;
|
||||
z->zone_expired = 0;
|
||||
struct auth_zone* z = NULL;
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
if(!xfr_process_reacquire_locks(xfr, env, &z)) {
|
||||
/* the zone is gone, ignore xfr results */
|
||||
*gone = 1;
|
||||
return 0;
|
||||
}
|
||||
/* holding xfr and z locks */
|
||||
|
||||
if(xfr->task_transfer->master->http) {
|
||||
xfr->num_ixfrs = 0;
|
||||
xfr->have_zone = 0;
|
||||
xfr->serial = 0;
|
||||
} else if(xfr->task_transfer->on_ixfr &&
|
||||
!xfr->task_transfer->on_ixfr_is_axfr) {
|
||||
xfr->num_ixfrs++;
|
||||
} else {
|
||||
/* AXFR */
|
||||
xfr->num_ixfrs = 0;
|
||||
xfr->have_zone = 0;
|
||||
xfr->serial = 0;
|
||||
if(!xfr_find_soa(z, xfr)) {
|
||||
verbose(VERB_ALGO, "xfr from %s: no SOA in zone after update"
|
||||
" (or malformed RR)", xfr->task_transfer->master->host);
|
||||
status = 0;
|
||||
}
|
||||
if(status) {
|
||||
z->soa_zone_acquired = *env->now;
|
||||
xfr->soa_zone_acquired = *env->now;
|
||||
xfr->is_rpz = (z->rpz!=NULL);
|
||||
}
|
||||
lock_rw_unlock(&z->lock);
|
||||
}
|
||||
|
||||
xfr->zone_expired = 0;
|
||||
z->zone_expired = 0;
|
||||
if(!xfr_find_soa(z, xfr)) {
|
||||
verbose(VERB_ALGO, "xfr from %s: no SOA in zone after update"
|
||||
" (or malformed RR)", xfr->task_transfer->master->host);
|
||||
return 0;
|
||||
}
|
||||
z->soa_zone_acquired = *env->now;
|
||||
xfr->soa_zone_acquired = *env->now;
|
||||
xfr->is_rpz = (z->rpz!=NULL);
|
||||
|
||||
/* release xfr lock while verifying zonemd because it may have
|
||||
* to spawn lookups in the state machines */
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
/* holding z lock */
|
||||
auth_zone_verify_zonemd(z, env, &env->mesh->mods, NULL, 0, 0);
|
||||
if(z->zone_expired) {
|
||||
char zname[LDNS_MAX_DOMAINLEN];
|
||||
/* ZONEMD must have failed */
|
||||
/* reacquire locks, so we hold xfr lock on exit of routine,
|
||||
* and both xfr and z again after releasing xfr for potential
|
||||
* state machine mesh callbacks */
|
||||
lock_rw_unlock(&z->lock);
|
||||
if(!xfr_process_reacquire_locks(xfr, env, &z)) {
|
||||
*gone = 1;
|
||||
return 0;
|
||||
}
|
||||
dname_str(xfr->name, zname);
|
||||
verbose(VERB_ALGO, "xfr from %s: ZONEMD failed for %s, transfer is failed", xfr->task_transfer->master->host, zname);
|
||||
xfr->zone_expired = 1;
|
||||
lock_rw_unlock(&z->lock);
|
||||
return 0;
|
||||
}
|
||||
/* reacquire locks, so we hold xfr lock on exit of routine,
|
||||
* and both xfr and z again after releasing xfr for potential
|
||||
* state machine mesh callbacks */
|
||||
lock_rw_unlock(&z->lock);
|
||||
if(!xfr_process_reacquire_locks(xfr, env, &z)) {
|
||||
*gone = 1;
|
||||
return 0;
|
||||
}
|
||||
/* holding xfr and z locks */
|
||||
|
||||
if(xfr->have_zone)
|
||||
xfr->lease_time = *env->now;
|
||||
/* unlock */
|
||||
lock_rw_unlock(&z->lock);
|
||||
|
||||
if(verbosity >= VERB_QUERY && xfr->have_zone) {
|
||||
char zname[LDNS_MAX_DOMAINLEN];
|
||||
dname_str(xfr->name, zname);
|
||||
verbose(VERB_QUERY, "auth zone %s updated to serial %u", zname,
|
||||
(unsigned)xfr->serial);
|
||||
}
|
||||
/* see if we need to write to a zonefile */
|
||||
xfr_write_after_update(xfr, env);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void xfr_process_load_end_transfer(struct auth_xfer* xfr,
|
||||
struct module_env* env, uint8_t status, int ixfr_fail,
|
||||
struct auth_chunk* chunk_list)
|
||||
{
|
||||
/* Chunks are put here for the auth zone write for the http case. */
|
||||
xfr->task_transfer->chunks_first = chunk_list;
|
||||
if(status) {
|
||||
int gone = 0;
|
||||
if(!xfr_process_loaded_transfer(xfr, env, &gone)) {
|
||||
status = 0;
|
||||
if(gone) {
|
||||
/* the zone is gone from the authzones. */
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
auth_chunks_delete(xfr->task_transfer);
|
||||
xfr->task_transfer->chunks_first = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
auth_chunks_delete(xfr->task_transfer);
|
||||
xfr->task_transfer->chunks_first = NULL;
|
||||
|
||||
if(status) {
|
||||
/* it worked! */
|
||||
xfr_process_transfer_success(xfr, env);
|
||||
|
||||
+2
-1
@@ -867,7 +867,8 @@ void auth_data_del(rbnode_type* n, void* arg);
|
||||
|
||||
/** Handle the end of an auth load task. */
|
||||
void xfr_process_load_end_transfer(struct auth_xfer* xfr,
|
||||
struct module_env* env, uint8_t status, int ixfr_fail);
|
||||
struct module_env* env, uint8_t status, int ixfr_fail,
|
||||
struct auth_chunk* chunk_list);
|
||||
|
||||
/** Log preview of http transfer */
|
||||
void xfr_http_preview(const char* file, struct auth_chunk* chunk_list);
|
||||
|
||||
Reference in New Issue
Block a user