- fast-reload, unshare forwards, making the structure locked, with an rwlock.

This commit is contained in:
W.C.A. Wijngaards 2024-01-04 16:53:02 +01:00
parent 91e8e0e511
commit f2fb498c69
16 changed files with 142 additions and 55 deletions

View File

@ -1278,7 +1278,7 @@ daemon.lo daemon.o: $(srcdir)/daemon/daemon.c config.h $(srcdir)/daemon/daemon.h
$(srcdir)/util/edns.h $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h \
$(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/services/localzone.h \
$(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h $(srcdir)/respip/respip.h \
$(srcdir)/util/random.h $(srcdir)/util/tube.h $(srcdir)/util/net_help.h $(srcdir)/sldns/keyraw.h
$(srcdir)/util/random.h $(srcdir)/util/tube.h $(srcdir)/util/net_help.h $(srcdir)/sldns/keyraw.h $(srcdir)/iterator/iter_fwd.h
remote.lo remote.o: $(srcdir)/daemon/remote.c config.h $(srcdir)/daemon/remote.h $(srcdir)/daemon/worker.h \
$(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/netevent.h \
@ -1484,7 +1484,7 @@ context.lo context.o: $(srcdir)/libunbound/context.c config.h $(srcdir)/libunbou
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h $(srcdir)/daemon/stats.h \
$(srcdir)/util/timehist.h $(srcdir)/respip/respip.h $(srcdir)/util/edns.h
$(srcdir)/util/timehist.h $(srcdir)/respip/respip.h $(srcdir)/util/edns.h $(srcdir)/iterator/iter_fwd.h
libunbound.lo libunbound.o: $(srcdir)/libunbound/libunbound.c $(srcdir)/libunbound/unbound.h \
$(srcdir)/libunbound/unbound-event.h config.h $(srcdir)/libunbound/context.h $(srcdir)/util/locks.h \
$(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \
@ -1496,7 +1496,7 @@ libunbound.lo libunbound.o: $(srcdir)/libunbound/libunbound.c $(srcdir)/libunbou
$(srcdir)/sldns/sbuffer.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h \
$(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/services/cache/rrset.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \
$(srcdir)/services/rpz.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/respip/respip.h
$(srcdir)/services/rpz.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/respip/respip.h $(srcdir)/iterator/iter_fwd.h
libworker.lo libworker.o: $(srcdir)/libunbound/libworker.c config.h $(srcdir)/libunbound/libworker.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/libunbound/context.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \

View File

@ -666,6 +666,7 @@ cachedb_extcache_store(struct module_qstate* qstate, struct cachedb_env* ie)
static int
cachedb_intcache_lookup(struct module_qstate* qstate, struct cachedb_env* cde)
{
uint8_t dpname_storage[LDNS_MAX_DOMAINLEN+1];
uint8_t* dpname=NULL;
size_t dpnamelen=0;
struct dns_msg* msg;
@ -674,7 +675,7 @@ cachedb_intcache_lookup(struct module_qstate* qstate, struct cachedb_env* cde)
return 0;
}
if(iter_stub_fwd_no_cache(qstate, &qstate->qinfo,
&dpname, &dpnamelen))
&dpname, &dpnamelen, dpname_storage, sizeof(dpname_storage)))
return 0; /* no cache for these queries */
msg = dns_cache_lookup(qstate->env, qstate->qinfo.qname,
qstate->qinfo.qname_len, qstate->qinfo.qtype,

View File

@ -850,15 +850,20 @@ int print_deleg_lookup(RES* ssl, struct worker* worker, uint8_t* nm,
if(!ssl_printf(ssl, "The following name servers are used for lookup "
"of %s\n", b))
return 0;
lock_rw_rdlock(&worker->env.fwds->lock);
dp = forwards_lookup(worker->env.fwds, nm, qinfo.qclass);
if(dp) {
if(!ssl_printf(ssl, "forwarding request:\n"))
if(!ssl_printf(ssl, "forwarding request:\n")) {
lock_rw_unlock(&worker->env.fwds->lock);
return 0;
}
print_dp_main(ssl, dp, NULL);
print_dp_details(ssl, worker, dp);
lock_rw_unlock(&worker->env.fwds->lock);
return 1;
}
lock_rw_unlock(&worker->env.fwds->lock);
while(1) {
dp = dns_cache_find_delegation(&worker->env, nm, nmlen,

View File

@ -91,6 +91,7 @@
#include "util/net_help.h"
#include "sldns/keyraw.h"
#include "respip/respip.h"
#include "iterator/iter_fwd.h"
#include <signal.h>
#ifdef HAVE_SYSTEMD
@ -714,6 +715,9 @@ daemon_fork(struct daemon* daemon)
fatal_exit("Could not create local zones: out of memory");
if(!local_zones_apply_cfg(daemon->local_zones, daemon->cfg))
fatal_exit("Could not set up local zones");
if(!(daemon->env->fwds = forwards_create()) ||
!forwards_apply_cfg(daemon->env->fwds, daemon->cfg))
fatal_exit("Could not set forward zones");
/* process raw response-ip configuration data */
if(!(daemon->respip_set = respip_set_create()))
@ -830,6 +834,8 @@ daemon_cleanup(struct daemon* daemon)
slabhash_clear(daemon->env->msg_cache);
}
daemon->old_num = daemon->num; /* save the current num */
forwards_delete(daemon->env->fwds);
daemon->env->fwds = NULL;
local_zones_delete(daemon->local_zones);
daemon->local_zones = NULL;
respip_set_delete(daemon->respip_set);

View File

@ -1992,12 +1992,20 @@ static int
print_root_fwds(RES* ssl, struct iter_forwards* fwds, uint8_t* root)
{
struct delegpt* dp;
lock_rw_rdlock(&fwds->lock);
dp = forwards_lookup(fwds, root, LDNS_RR_CLASS_IN);
if(!dp)
if(!dp) {
lock_rw_unlock(&fwds->lock);
return ssl_printf(ssl, "off (using root hints)\n");
}
/* if dp is returned it must be the root */
log_assert(query_dname_compare(dp->name, root)==0);
return ssl_print_name_dp(ssl, NULL, root, LDNS_RR_CLASS_IN, dp);
if(!ssl_print_name_dp(ssl, NULL, root, LDNS_RR_CLASS_IN, dp)) {
lock_rw_unlock(&fwds->lock);
return 0;
}
lock_rw_unlock(&fwds->lock);
return 1;
}
/** parse args into delegpt */
@ -2082,15 +2090,20 @@ do_forward(RES* ssl, struct worker* worker, char* args)
/* delete all the existing queries first */
mesh_delete_all(worker->env.mesh);
if(strcmp(args, "off") == 0) {
lock_rw_wrlock(&fwd->lock);
forwards_delete_zone(fwd, LDNS_RR_CLASS_IN, root);
lock_rw_unlock(&fwd->lock);
} else {
struct delegpt* dp;
if(!(dp = parse_delegpt(ssl, args, root)))
return;
lock_rw_wrlock(&fwd->lock);
if(!forwards_add_zone(fwd, LDNS_RR_CLASS_IN, dp)) {
lock_rw_unlock(&fwd->lock);
(void)ssl_printf(ssl, "error out of memory\n");
return;
}
lock_rw_unlock(&fwd->lock);
}
send_ok(ssl);
}
@ -2153,9 +2166,11 @@ do_forward_add(RES* ssl, struct worker* worker, char* args)
return;
if(tls)
dp->ssl_upstream = 1;
lock_rw_wrlock(&fwd->lock);
if(insecure && worker->env.anchors) {
if(!anchors_add_insecure(worker->env.anchors, LDNS_RR_CLASS_IN,
nm)) {
lock_rw_unlock(&fwd->lock);
(void)ssl_printf(ssl, "error out of memory\n");
delegpt_free_mlc(dp);
free(nm);
@ -2163,10 +2178,12 @@ do_forward_add(RES* ssl, struct worker* worker, char* args)
}
}
if(!forwards_add_zone(fwd, LDNS_RR_CLASS_IN, dp)) {
lock_rw_unlock(&fwd->lock);
(void)ssl_printf(ssl, "error out of memory\n");
free(nm);
return;
}
lock_rw_unlock(&fwd->lock);
free(nm);
send_ok(ssl);
}
@ -2180,10 +2197,12 @@ do_forward_remove(RES* ssl, struct worker* worker, char* args)
uint8_t* nm = NULL;
if(!parse_fs_args(ssl, args, &nm, NULL, &insecure, NULL, NULL))
return;
lock_rw_wrlock(&fwd->lock);
if(insecure && worker->env.anchors)
anchors_delete_insecure(worker->env.anchors, LDNS_RR_CLASS_IN,
nm);
forwards_delete_zone(fwd, LDNS_RR_CLASS_IN, nm);
lock_rw_unlock(&fwd->lock);
free(nm);
send_ok(ssl);
}
@ -2200,6 +2219,7 @@ do_stub_add(RES* ssl, struct worker* worker, char* args)
return;
if(tls)
dp->ssl_upstream = 1;
lock_rw_wrlock(&fwd->lock);
if(insecure && worker->env.anchors) {
if(!anchors_add_insecure(worker->env.anchors, LDNS_RR_CLASS_IN,
nm)) {
@ -2213,6 +2233,7 @@ do_stub_add(RES* ssl, struct worker* worker, char* args)
if(insecure && worker->env.anchors)
anchors_delete_insecure(worker->env.anchors,
LDNS_RR_CLASS_IN, nm);
lock_rw_unlock(&fwd->lock);
(void)ssl_printf(ssl, "error out of memory\n");
delegpt_free_mlc(dp);
free(nm);
@ -2224,9 +2245,11 @@ do_stub_add(RES* ssl, struct worker* worker, char* args)
if(insecure && worker->env.anchors)
anchors_delete_insecure(worker->env.anchors,
LDNS_RR_CLASS_IN, nm);
lock_rw_unlock(&fwd->lock);
free(nm);
return;
}
lock_rw_unlock(&fwd->lock);
free(nm);
send_ok(ssl);
}
@ -2240,11 +2263,13 @@ do_stub_remove(RES* ssl, struct worker* worker, char* args)
uint8_t* nm = NULL;
if(!parse_fs_args(ssl, args, &nm, NULL, &insecure, NULL, NULL))
return;
lock_rw_wrlock(&fwd->lock);
if(insecure && worker->env.anchors)
anchors_delete_insecure(worker->env.anchors, LDNS_RR_CLASS_IN,
nm);
forwards_delete_stub_hole(fwd, LDNS_RR_CLASS_IN, nm);
hints_delete_stub(worker->env.hints, LDNS_RR_CLASS_IN, nm);
lock_rw_unlock(&fwd->lock);
free(nm);
send_ok(ssl);
}
@ -2673,6 +2698,7 @@ do_list_forwards(RES* ssl, struct worker* worker)
struct iter_forward_zone* z;
struct trust_anchor* a;
int insecure;
lock_rw_rdlock(&fwds->lock);
RBTREE_FOR(z, struct iter_forward_zone*, fwds->tree) {
if(!z->dp) continue; /* skip empty marker for stub */
@ -2687,9 +2713,12 @@ do_list_forwards(RES* ssl, struct worker* worker)
}
if(!ssl_print_name_dp(ssl, (insecure?"forward +i":"forward"),
z->name, z->dclass, z->dp))
z->name, z->dclass, z->dp)) {
lock_rw_unlock(&fwds->lock);
return;
}
}
lock_rw_unlock(&fwds->lock);
}
/** do the list_stubs command */
@ -3088,13 +3117,9 @@ execute_cmd(struct daemon_remote* rc, RES* ssl, char* cmd,
do_stub_remove(ssl, worker, skipwhite(p+11));
return;
} else if(cmdcmp(p, "forward_add", 11)) {
/* must always distribute this cmd */
if(rc) distribute_cmd(rc, ssl, cmd);
do_forward_add(ssl, worker, skipwhite(p+11));
return;
} else if(cmdcmp(p, "forward_remove", 14)) {
/* must always distribute this cmd */
if(rc) distribute_cmd(rc, ssl, cmd);
do_forward_remove(ssl, worker, skipwhite(p+14));
return;
} else if(cmdcmp(p, "insecure_add", 12)) {
@ -3108,8 +3133,6 @@ execute_cmd(struct daemon_remote* rc, RES* ssl, char* cmd,
do_insecure_remove(ssl, worker, skipwhite(p+15));
return;
} else if(cmdcmp(p, "forward", 7)) {
/* must always distribute this cmd */
if(rc) distribute_cmd(rc, ssl, cmd);
do_forward(ssl, worker, skipwhite(p+7));
return;
} else if(cmdcmp(p, "flush_stats", 11)) {

View File

@ -2261,12 +2261,6 @@ worker_init(struct worker* worker, struct config_file *cfg,
worker_delete(worker);
return 0;
}
if(!(worker->env.fwds = forwards_create()) ||
!forwards_apply_cfg(worker->env.fwds, cfg)) {
log_err("Could not set forward zones");
worker_delete(worker);
return 0;
}
if(!(worker->env.hints = hints_create()) ||
!hints_apply_cfg(worker->env.hints, cfg)) {
log_err("Could not set root or stub hints");
@ -2345,7 +2339,6 @@ worker_delete(struct worker* worker)
outside_network_quit_prepare(worker->back);
mesh_delete(worker->env.mesh);
sldns_buffer_free(worker->env.scratch_buffer);
forwards_delete(worker->env.fwds);
hints_delete(worker->env.hints);
listen_delete(worker->front);
outside_network_delete(worker->back);

View File

@ -152,7 +152,7 @@ int ecs_whitelist_check(struct query_info* qinfo,
/* Cache by default, might be disabled after parsing EDNS option
* received from nameserver. */
if(!iter_stub_fwd_no_cache(qstate, &qstate->qinfo, NULL, NULL)) {
if(!iter_stub_fwd_no_cache(qstate, &qstate->qinfo, NULL, NULL, NULL, 0)) {
qstate->no_cache_store = 0;
}

View File

@ -71,6 +71,7 @@ forwards_create(void)
sizeof(struct iter_forwards));
if(!fwd)
return NULL;
lock_rw_init(&fwd->lock);
return fwd;
}
@ -100,6 +101,7 @@ forwards_delete(struct iter_forwards* fwd)
{
if(!fwd)
return;
lock_rw_destroy(&fwd->lock);
fwd_del_tree(fwd);
free(fwd);
}
@ -332,17 +334,27 @@ make_stub_holes(struct iter_forwards* fwd, struct config_file* cfg)
int
forwards_apply_cfg(struct iter_forwards* fwd, struct config_file* cfg)
{
if(fwd->tree) {
lock_unprotect(&fwd->lock, fwd->tree);
}
fwd_del_tree(fwd);
fwd->tree = rbtree_create(fwd_cmp);
if(!fwd->tree)
return 0;
lock_protect(&fwd->lock, fwd->tree, sizeof(*fwd->tree));
lock_rw_wrlock(&fwd->lock);
/* read forward zones */
if(!read_forwards(fwd, cfg))
if(!read_forwards(fwd, cfg)) {
lock_rw_unlock(&fwd->lock);
return 0;
if(!make_stub_holes(fwd, cfg))
}
if(!make_stub_holes(fwd, cfg)) {
lock_rw_unlock(&fwd->lock);
return 0;
}
fwd_init_parents(fwd);
lock_rw_unlock(&fwd->lock);
return 1;
}
@ -458,10 +470,12 @@ forwards_get_mem(struct iter_forwards* fwd)
size_t s;
if(!fwd)
return 0;
lock_rw_rdlock(&fwd->lock);
s = sizeof(*fwd) + sizeof(*fwd->tree);
RBTREE_FOR(p, struct iter_forward_zone*, fwd->tree) {
s += sizeof(*p) + p->namelen + delegpt_get_mem(p->dp);
}
lock_rw_unlock(&fwd->lock);
return s;
}
@ -504,6 +518,8 @@ forwards_delete_zone(struct iter_forwards* fwd, uint16_t c, uint8_t* nm)
int
forwards_add_stub_hole(struct iter_forwards* fwd, uint16_t c, uint8_t* nm)
{
if(fwd_zone_find(fwd, c, nm) != NULL)
return 1; /* already a stub zone there */
if(!fwd_add_stub_hole(fwd, c, nm)) {
return 0;
}

View File

@ -43,6 +43,7 @@
#ifndef ITERATOR_ITER_FWD_H
#define ITERATOR_ITER_FWD_H
#include "util/rbtree.h"
#include "util/locks.h"
struct config_file;
struct delegpt;
@ -50,6 +51,10 @@ struct delegpt;
* Iterator forward zones structure
*/
struct iter_forwards {
/** lock on the forwards tree.
* When grabbing both this lock and the anchors.lock, this lock
* is grabbed first. */
lock_rw_type lock;
/**
* Zones are stored in this tree. Sort order is specially chosen.
* first sorted on qclass. Then on dname in nsec-like order, so that
@ -106,6 +111,8 @@ int forwards_apply_cfg(struct iter_forwards* fwd, struct config_file* cfg);
/**
* Find forward zone exactly by name
* The return value is contents of the forwards structure, caller should
* lock and unlock a readlock on the forwards structure.
* @param fwd: forward storage.
* @param qname: The qname of the query.
* @param qclass: The qclass of the query.
@ -118,6 +125,8 @@ struct delegpt* forwards_find(struct iter_forwards* fwd, uint8_t* qname,
* Find forward zone information
* For this qname/qclass find forward zone information, returns delegation
* point with server names and addresses, or NULL if no forwarding is needed.
* The return value is contents of the forwards structure, caller should
* lock and unlock a readlock on the forwards structure.
*
* @param fwd: forward storage.
* @param qname: The qname of the query.
@ -147,6 +156,7 @@ int forwards_next_root(struct iter_forwards* fwd, uint16_t* qclass);
/**
* Get memory in use by forward storage
* Locks and unlocks the structure.
* @param fwd: forward storage.
* @return bytes in use
*/

View File

@ -1285,7 +1285,12 @@ iter_get_next_root(struct iter_hints* hints, struct iter_forwards* fwd,
{
uint16_t c1 = *c, c2 = *c;
int r1 = hints_next_root(hints, &c1);
int r2 = forwards_next_root(fwd, &c2);
int r2;
lock_rw_rdlock(&fwd->lock);
r2 = forwards_next_root(fwd, &c2);
lock_rw_unlock(&fwd->lock);
if(!r1 && !r2) /* got none, end of list */
return 0;
else if(!r1) /* got one, return that */
@ -1450,7 +1455,8 @@ int iter_dp_cangodown(struct query_info* qinfo, struct delegpt* dp)
int
iter_stub_fwd_no_cache(struct module_qstate *qstate, struct query_info *qinf,
uint8_t** retdpname, size_t* retdpnamelen)
uint8_t** retdpname, size_t* retdpnamelen, uint8_t* dpname_storage,
size_t dpname_storage_len)
{
struct iter_hints_stub *stub;
struct delegpt *dp;
@ -1458,6 +1464,7 @@ iter_stub_fwd_no_cache(struct module_qstate *qstate, struct query_info *qinf,
/* Check for stub. */
stub = hints_lookup_stub(qstate->env->hints, qinf->qname,
qinf->qclass, NULL);
lock_rw_rdlock(&qstate->env->fwds->lock);
dp = forwards_lookup(qstate->env->fwds, qinf->qname, qinf->qclass);
/* see if forward or stub is more pertinent */
@ -1472,6 +1479,7 @@ iter_stub_fwd_no_cache(struct module_qstate *qstate, struct query_info *qinf,
/* check stub */
if (stub != NULL && stub->dp != NULL) {
lock_rw_unlock(&qstate->env->fwds->lock);
if(stub->dp->no_cache) {
char qname[255+1];
char dpname[255+1];
@ -1488,7 +1496,8 @@ iter_stub_fwd_no_cache(struct module_qstate *qstate, struct query_info *qinf,
/* Check for forward. */
if (dp) {
if(dp->no_cache) {
int dp_no_cache = dp->no_cache;
if(dp_no_cache) {
char qname[255+1];
char dpname[255+1];
dname_str(qinf->qname, qname);
@ -1496,11 +1505,19 @@ iter_stub_fwd_no_cache(struct module_qstate *qstate, struct query_info *qinf,
verbose(VERB_ALGO, "forward for %s %s has no_cache", qname, dpname);
}
if(retdpname) {
*retdpname = dp->name;
if(dp->namelen > dpname_storage_len) {
verbose(VERB_ALGO, "no cache dpname too long");
lock_rw_unlock(&qstate->env->fwds->lock);
return (dp_no_cache);
}
memmove(dpname_storage, dp->name, dp->namelen);
*retdpname = dpname_storage;
*retdpnamelen = dp->namelen;
}
return (dp->no_cache);
lock_rw_unlock(&qstate->env->fwds->lock);
return (dp_no_cache);
}
lock_rw_unlock(&qstate->env->fwds->lock);
if(retdpname) {
*retdpname = NULL;
*retdpnamelen = 0;

View File

@ -407,10 +407,14 @@ int iter_dp_cangodown(struct query_info* qinfo, struct delegpt* dp);
* Used for NXDOMAIN checks, above that it is an nxdomain from a
* different server and zone. You can pass NULL to not get it.
* @param retdpnamelen: returns the length of the dpname.
* @param dpname_storage: this is where the dpname buf is stored, if any.
* So that caller can manage the buffer.
* @param dpname_storage_len: size of dpname_storage buffer.
* @return true if no_cache is set in stub or fwd.
*/
int iter_stub_fwd_no_cache(struct module_qstate *qstate,
struct query_info *qinf, uint8_t** retdpname, size_t* retdpnamelen);
struct query_info *qinf, uint8_t** retdpname, size_t* retdpnamelen,
uint8_t* dpname_storage, size_t dpname_storage_len);
/**
* Set support for IP4 and IP6 depending on outgoing interfaces

View File

@ -679,7 +679,8 @@ errinf_reply(struct module_qstate* qstate, struct iter_qstate* iq)
/** see if last resort is possible - does config allow queries to parent */
static int
can_have_last_resort(struct module_env* env, uint8_t* nm, size_t nmlen,
uint16_t qclass, struct delegpt** retdp)
uint16_t qclass, int* have_dp, struct delegpt** retdp,
struct regional* region)
{
struct delegpt* fwddp;
struct iter_hints_stub* stub;
@ -693,15 +694,20 @@ can_have_last_resort(struct module_env* env, uint8_t* nm, size_t nmlen,
* are allowed to go to the parent */
stub->dp->has_parent_side_NS) {
if(retdp) *retdp = stub->dp;
if(have_dp) *have_dp = 1;
return 0;
}
lock_rw_rdlock(&env->fwds->lock);
if((fwddp = forwards_find(env->fwds, nm, qclass)) &&
/* has_parent_side is turned off for forward_first, where
* we are allowed to go to the parent */
fwddp->has_parent_side_NS) {
if(retdp) *retdp = fwddp;
if(retdp) *retdp = delegpt_copy(fwddp, region);
lock_rw_unlock(&env->fwds->lock);
if(have_dp) *have_dp = 1;
return 0;
}
lock_rw_unlock(&env->fwds->lock);
return 1;
}
@ -1181,7 +1187,7 @@ generate_ns_check(struct module_qstate* qstate, struct iter_qstate* iq, int id)
if(iq->depth == ie->max_dependency_depth)
return;
if(!can_have_last_resort(qstate->env, iq->dp->name, iq->dp->namelen,
iq->qchase.qclass, NULL))
iq->qchase.qclass, NULL, NULL, NULL))
return;
/* is this query the same as the nscheck? */
if(qstate->qinfo.qtype == LDNS_RR_TYPE_NS &&
@ -1302,12 +1308,16 @@ forward_request(struct module_qstate* qstate, struct iter_qstate* iq)
if( (iq->qchase.qtype == LDNS_RR_TYPE_DS || iq->refetch_glue)
&& !dname_is_root(iq->qchase.qname))
dname_remove_label(&delname, &delnamelen);
lock_rw_rdlock(&qstate->env->fwds->lock);
dp = forwards_lookup(qstate->env->fwds, delname, iq->qchase.qclass);
if(!dp)
if(!dp) {
lock_rw_unlock(&qstate->env->fwds->lock);
return 0;
}
/* send recursion desired to forward addr */
iq->chase_flags |= BIT_RD;
iq->dp = delegpt_copy(dp, qstate->region);
lock_rw_unlock(&qstate->env->fwds->lock);
/* iq->dp checked by caller */
verbose(VERB_ALGO, "forwarding request");
return 1;
@ -1335,6 +1345,7 @@ static int
processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
struct iter_env* ie, int id)
{
uint8_t dpname_storage[LDNS_MAX_DOMAINLEN+1];
uint8_t* delname, *dpname=NULL;
size_t delnamelen, dpnamelen=0;
struct dns_msg* msg = NULL;
@ -1381,7 +1392,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
if (iq->refetch_glue &&
iq->dp &&
!can_have_last_resort(qstate->env, iq->dp->name,
iq->dp->namelen, iq->qchase.qclass, NULL)) {
iq->dp->namelen, iq->qchase.qclass, NULL, NULL, NULL)) {
iq->refetch_glue = 0;
}
@ -1442,7 +1453,8 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
}
}
if (iter_stub_fwd_no_cache(qstate, &iq->qchase, &dpname, &dpnamelen)) {
if (iter_stub_fwd_no_cache(qstate, &iq->qchase, &dpname, &dpnamelen,
dpname_storage, sizeof(dpname_storage))) {
/* Asked to not query cache. */
verbose(VERB_ALGO, "no-cache set, going to the network");
qstate->no_cache_lookup = 1;
@ -1573,7 +1585,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
}
if(iq->qchase.qtype == LDNS_RR_TYPE_DS || iq->refetch_glue ||
(iq->qchase.qtype == LDNS_RR_TYPE_NS && qstate->prefetch_leeway
&& can_have_last_resort(qstate->env, delname, delnamelen, iq->qchase.qclass, NULL))) {
&& can_have_last_resort(qstate->env, delname, delnamelen, iq->qchase.qclass, NULL, NULL, NULL))) {
/* remove first label from delname, root goes to hints,
* but only to fetch glue, not for qtype=DS. */
/* also when prefetching an NS record, fetch it again from
@ -1615,8 +1627,10 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
break; /* got noprime-stub-zone, continue */
else if(r)
return 0; /* stub prime request made */
lock_rw_rdlock(&qstate->env->fwds->lock);
if(forwards_lookup_root(qstate->env->fwds,
iq->qchase.qclass)) {
lock_rw_unlock(&qstate->env->fwds->lock);
/* forward zone root, no root prime needed */
/* fill in some dp - safety belt */
iq->dp = hints_lookup_root(qstate->env->hints,
@ -1636,6 +1650,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
}
return next_state(iq, INIT_REQUEST_2_STATE);
}
lock_rw_unlock(&qstate->env->fwds->lock);
/* Note that the result of this will set a new
* DelegationPoint based on the result of priming. */
if(!prime_root(qstate, iq, id, iq->qchase.qclass))
@ -1667,15 +1682,13 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
if(iter_dp_is_useless(&qstate->qinfo, qstate->query_flags,
iq->dp, ie->supports_ipv4, ie->supports_ipv6,
ie->use_nat64)) {
struct delegpt* retdp = NULL;
if(!can_have_last_resort(qstate->env, iq->dp->name, iq->dp->namelen, iq->qchase.qclass, &retdp)) {
if(retdp) {
int have_dp = 0;
if(!can_have_last_resort(qstate->env, iq->dp->name, iq->dp->namelen, iq->qchase.qclass, &have_dp, &iq->dp, qstate->region)) {
if(have_dp) {
verbose(VERB_QUERY, "cache has stub "
"or fwd but no addresses, "
"fallback to config");
iq->dp = delegpt_copy(retdp,
qstate->region);
if(!iq->dp) {
if(have_dp && !iq->dp) {
log_err("out of memory in "
"stub/fwd fallback");
errinf(qstate, "malloc failure, for fallback to config");
@ -2080,7 +2093,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
log_assert(iq->dp);
if(!can_have_last_resort(qstate->env, iq->dp->name, iq->dp->namelen,
iq->qchase.qclass, NULL)) {
iq->qchase.qclass, NULL, NULL, NULL)) {
/* fail -- no more targets, no more hope of targets, no hope
* of a response. */
errinf(qstate, "all the configured stub or forward servers failed,");
@ -2182,7 +2195,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
if( ((ie->supports_ipv6 && !ns->done_pside6) ||
((ie->supports_ipv4 || ie->use_nat64) && !ns->done_pside4)) &&
!can_have_last_resort(qstate->env, ns->name, ns->namelen,
iq->qchase.qclass, NULL)) {
iq->qchase.qclass, NULL, NULL, NULL)) {
log_nametypeclass(VERB_ALGO, "cannot pside lookup ns "
"because it is also a stub/forward,",
ns->name, LDNS_RR_TYPE_NS, iq->qchase.qclass);

View File

@ -53,6 +53,7 @@
#include "util/storage/slabhash.h"
#include "util/edns.h"
#include "sldns/sbuffer.h"
#include "iterator/iter_fwd.h"
int
context_finalize(struct ub_ctx* ctx)
@ -85,6 +86,9 @@ context_finalize(struct ub_ctx* ctx)
if(!auth_zones_apply_cfg(ctx->env->auth_zones, cfg, 1, &is_rpz,
ctx->env, &ctx->mods))
return UB_INITFAIL;
if(!(ctx->env->fwds = forwards_create()) ||
!forwards_apply_cfg(ctx->env->fwds, cfg))
return UB_INITFAIL;
if(!edns_strings_apply_cfg(ctx->env->edns_strings, cfg))
return UB_INITFAIL;
if(!slabhash_is_size(ctx->env->msg_cache, cfg->msg_cache_size,

View File

@ -66,6 +66,7 @@
#include "services/authzone.h"
#include "services/listen_dnsport.h"
#include "sldns/sbuffer.h"
#include "iterator/iter_fwd.h"
#ifdef HAVE_PTHREAD
#include <signal.h>
#endif
@ -379,6 +380,7 @@ ub_ctx_delete(struct ub_ctx* ctx)
config_delete(ctx->env->cfg);
edns_known_options_delete(ctx->env);
edns_strings_delete(ctx->env->edns_strings);
forwards_delete(ctx->env->fwds);
auth_zones_delete(ctx->env->auth_zones);
free(ctx->env);
}

View File

@ -100,7 +100,6 @@ libworker_delete_env(struct libworker* w)
!w->is_bg || w->is_bg_thread);
sldns_buffer_free(w->env->scratch_buffer);
regional_destroy(w->env->scratch);
forwards_delete(w->env->fwds);
hints_delete(w->env->hints);
ub_randfree(w->env->rnd);
free(w->env);
@ -159,11 +158,6 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb)
}
w->env->scratch = regional_create_custom(cfg->msg_buffer_size);
w->env->scratch_buffer = sldns_buffer_new(cfg->msg_buffer_size);
w->env->fwds = forwards_create();
if(w->env->fwds && !forwards_apply_cfg(w->env->fwds, cfg)) {
forwards_delete(w->env->fwds);
w->env->fwds = NULL;
}
w->env->hints = hints_create();
if(w->env->hints && !hints_apply_cfg(w->env->hints, cfg)) {
hints_delete(w->env->hints);
@ -181,8 +175,7 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb)
if(!w->is_bg || w->is_bg_thread) {
lock_basic_unlock(&ctx->cfglock);
}
if(!w->env->scratch || !w->env->scratch_buffer || !w->env->fwds ||
!w->env->hints) {
if(!w->env->scratch || !w->env->scratch_buffer || !w->env->hints) {
libworker_delete(w);
return NULL;
}

View File

@ -511,7 +511,7 @@ struct module_env {
/** auth zones */
struct auth_zones* auth_zones;
/** Mapping of forwarding zones to targets.
* iterator forwarder information. per-thread, created by worker */
* iterator forwarder information. */
struct iter_forwards* fwds;
/**
* iterator forwarder information. per-thread, created by worker.