auth zone, make depend, fallback, create and delete, and lease_time,

and lock fixes.


git-svn-id: file:///svn/unbound/trunk@4466 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2018-01-30 10:35:20 +00:00
parent 208d045cf5
commit 0362614f94
13 changed files with 2968 additions and 2873 deletions

View file

@ -1154,8 +1154,9 @@ daemon.lo daemon.o: $(srcdir)/daemon/daemon.c config.h \
$(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h \
$(srcdir)/util/config_file.h $(srcdir)/util/shm_side/shm_main.h $(srcdir)/util/storage/lookup3.h \
$(srcdir)/util/storage/slabhash.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)/util/random.h \
$(srcdir)/util/tube.h $(srcdir)/util/net_help.h $(srcdir)/sldns/keyraw.h $(srcdir)/respip/respip.h
$(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/services/localzone.h \
$(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/util/random.h $(srcdir)/util/tube.h \
$(srcdir)/util/net_help.h $(srcdir)/sldns/keyraw.h $(srcdir)/respip/respip.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 \
@ -1265,8 +1266,9 @@ daemon.lo daemon.o: $(srcdir)/daemon/daemon.c config.h \
$(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h \
$(srcdir)/util/config_file.h $(srcdir)/util/shm_side/shm_main.h $(srcdir)/util/storage/lookup3.h \
$(srcdir)/util/storage/slabhash.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)/util/random.h \
$(srcdir)/util/tube.h $(srcdir)/util/net_help.h $(srcdir)/sldns/keyraw.h $(srcdir)/respip/respip.h
$(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/services/localzone.h \
$(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/util/random.h $(srcdir)/util/tube.h \
$(srcdir)/util/net_help.h $(srcdir)/sldns/keyraw.h $(srcdir)/respip/respip.h
stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
$(srcdir)/libunbound/unbound.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 \
@ -1340,7 +1342,7 @@ context.lo context.o: $(srcdir)/libunbound/context.c config.h $(srcdir)/libunbou
$(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/services/cache/rrset.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/sldns/sbuffer.h
$(srcdir)/dnscrypt/cert.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/sldns/sbuffer.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 \
@ -1351,7 +1353,8 @@ libunbound.lo libunbound.o: $(srcdir)/libunbound/libunbound.c $(srcdir)/libunbou
$(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h \
$(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/services/cache/rrset.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/sldns/sbuffer.h
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \
$(srcdir)/sldns/sbuffer.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 \

View file

@ -82,6 +82,7 @@
#include "services/localzone.h"
#include "services/view.h"
#include "services/modstack.h"
#include "services/authzone.h"
#include "util/module.h"
#include "util/random.h"
#include "util/tube.h"
@ -281,6 +282,13 @@ daemon_init(void)
if(gettimeofday(&daemon->time_boot, NULL) < 0)
log_err("gettimeofday: %s", strerror(errno));
daemon->time_last_stat = daemon->time_boot;
if((daemon->env->auth_zones = auth_zones_create()) == 0) {
acl_list_delete(daemon->acl);
edns_known_options_delete(daemon->env);
free(daemon->env);
free(daemon);
return NULL;
}
return daemon;
}
@ -603,6 +611,10 @@ daemon_fork(struct daemon* daemon)
fatal_exit("Could not set up per-view response IP sets");
daemon->use_response_ip = !respip_set_is_empty(daemon->respip_set) ||
have_view_respip_cfg;
/* read auth zonefiles */
if(!auth_zones_apply_cfg(daemon->env->auth_zones, daemon->cfg, 1))
fatal_exit("auth_zones could not be setup");
/* setup modules */
daemon_setup_modules(daemon);
@ -716,6 +728,7 @@ daemon_delete(struct daemon* daemon)
rrset_cache_delete(daemon->env->rrset_cache);
infra_delete(daemon->env->infra_cache);
edns_known_options_delete(daemon->env);
auth_zones_delete(daemon->env->auth_zones);
}
ub_randfree(daemon->rand);
alloc_clear(&daemon->superalloc);

View file

@ -47,6 +47,7 @@
#include "services/localzone.h"
#include "services/cache/rrset.h"
#include "services/cache/infra.h"
#include "services/authzone.h"
#include "util/data/msgreply.h"
#include "util/storage/slabhash.h"
#include "sldns/sbuffer.h"
@ -68,6 +69,8 @@ context_finalize(struct ub_ctx* ctx)
return UB_NOMEM;
if(!local_zones_apply_cfg(ctx->local_zones, cfg))
return UB_INITFAIL;
if(!auth_zones_apply_cfg(ctx->env->auth_zones, cfg, 1))
return UB_INITFAIL;
if(!ctx->env->msg_cache ||
cfg->msg_cache_size != slabhash_get_size(ctx->env->msg_cache) ||
cfg->msg_cache_slabs != ctx->env->msg_cache->size) {

View file

@ -62,6 +62,7 @@
#include "services/localzone.h"
#include "services/cache/infra.h"
#include "services/cache/rrset.h"
#include "services/authzone.h"
#include "sldns/sbuffer.h"
#ifdef HAVE_PTHREAD
#include <signal.h>
@ -141,6 +142,16 @@ static struct ub_ctx* ub_ctx_create_nopipe(void)
errno = ENOMEM;
return NULL;
}
ctx->env->auth_zones = auth_zones_create();
if(!ctx->env->auth_zones) {
edns_known_options_delete(ctx->env);
config_delete(ctx->env->cfg);
free(ctx->env);
ub_randfree(ctx->seed_rnd);
free(ctx);
errno = ENOMEM;
return NULL;
}
ctx->env->alloc = &ctx->superalloc;
ctx->env->worker = NULL;
ctx->env->need_to_validate = 0;
@ -310,6 +321,7 @@ ub_ctx_delete(struct ub_ctx* ctx)
infra_delete(ctx->env->infra_cache);
config_delete(ctx->env->cfg);
edns_known_options_delete(ctx->env);
auth_zones_delete(ctx->env->auth_zones);
free(ctx->env);
}
ub_randfree(ctx->seed_rnd);

View file

@ -267,7 +267,6 @@ msg_add_rrset_ar(struct auth_zone* z, struct regional* region,
struct auth_zones* auth_zones_create(void)
{
/* TODO: create and put in env in worker and libworker */
struct auth_zones* az = (struct auth_zones*)calloc(1, sizeof(*az));
if(!az) {
log_err("out of memory");
@ -1509,7 +1508,11 @@ auth_zone_read_zonefile(struct auth_zone* z)
FILE* in;
if(!z || !z->zonefile || z->zonefile[0]==0)
return 1; /* no file, or "", nothing to read */
verbose(VERB_ALGO, "read zonefile %s", z->zonefile);
if(verbosity >= VERB_ALGO) {
char nm[255+1];
dname_str(z->name, nm);
verbose(VERB_ALGO, "read zonefile %s for %s", z->zonefile, nm);
}
in = fopen(z->zonefile, "r");
if(!in) {
char* n = sldns_wire2str_dname(z->name, z->namelen);
@ -1680,36 +1683,32 @@ xfr_find_soa(struct auth_zone* z, struct auth_xfer* xfr)
/**
* Setup auth_xfer zone
* This populates the have_zone, soa values, next_probe and so on times.
* Doesn't do network traffic yet, sets the timeout.
* This populates the have_zone, soa values, and so on times.
* Doesn't do network traffic yet, can set option flags.
* @param z: locked by caller, and modified for setup
* @param x: locked by caller, and modified, timers and timeouts.
* @param env: module env with time.
* @param x: locked by caller, and modified.
* @return false on failure.
*/
static int
auth_xfer_setup(struct auth_zone* z, struct auth_xfer* x, struct module_env* env)
auth_xfer_setup(struct auth_zone* z, struct auth_xfer* x)
{
/* for a zone without zone transfers, x==NULL, so skip them,
* i.e. the zone config is fixed with no masters or urls */
if(!z || !x) return 1;
if(!xfr_find_soa(z, x)) {
return 1;
}
/* nextprobe setup */
x->task_nextprobe->next_probe = 0;
if(x->have_zone)
x->task_nextprobe->lease_time = *env->now;
/* nothing for probe and transfer tasks */
/* nothing for probe, nextprobe and transfer tasks */
return 1;
}
/**
* Setup all zones
* @param az: auth zones structure
* @param env: module env with time.
* @return false on failure.
*/
static int
auth_zones_setup_zones(struct auth_zones* az, struct module_env* env)
auth_zones_setup_zones(struct auth_zones* az)
{
struct auth_zone* z;
struct auth_xfer* x;
@ -1720,7 +1719,7 @@ auth_zones_setup_zones(struct auth_zones* az, struct module_env* env)
if(x) {
lock_basic_lock(&x->lock);
}
if(!auth_xfer_setup(z, x, env)) {
if(!auth_xfer_setup(z, x)) {
if(x) {
lock_basic_unlock(&x->lock);
}
@ -1771,9 +1770,7 @@ auth_zones_cfg(struct auth_zones* az, struct config_auth* c)
}
z->for_downstream = c->for_downstream;
z->for_upstream = c->for_upstream;
/* TODO fallback option */
//if(!auth_zone_set_fallback(z, zlist->str2)) {
/* TODO other options */
z->fallback_enabled = c->fallback_enabled;
/* xfer zone */
if(x) {
@ -1797,7 +1794,7 @@ auth_zones_cfg(struct auth_zones* az, struct config_auth* c)
}
int auth_zones_apply_cfg(struct auth_zones* az, struct config_file* cfg,
int setup, struct module_env* env)
int setup)
{
struct config_auth* p;
for(p = cfg->auths; p; p = p->next) {
@ -1813,7 +1810,7 @@ int auth_zones_apply_cfg(struct auth_zones* az, struct config_file* cfg,
if(!auth_zones_read_zones(az))
return 0;
if(setup) {
if(!auth_zones_setup_zones(az, env))
if(!auth_zones_setup_zones(az))
return 0;
}
return 1;
@ -3913,15 +3910,20 @@ xfr_process_chunk_list(struct auth_xfer* xfr, struct module_env* env,
struct auth_zone* z;
/* obtain locks and structures */
/* release xfr lock, then, while holding az->lock grab both
* z->lock and xfr->lock */
lock_basic_unlock(&xfr->lock);
lock_rw_rdlock(&env->auth_zones->lock);
z = auth_zone_find(env->auth_zones, xfr->name, xfr->namelen,
xfr->dclass);
if(!z) {
lock_rw_unlock(&env->auth_zones->lock);
/* the zone is gone, ignore xfr results */
lock_basic_lock(&xfr->lock);
return 0;
}
lock_rw_wrlock(&z->lock);
lock_basic_lock(&xfr->lock);
lock_rw_unlock(&env->auth_zones->lock);
/* apply data */
@ -3942,14 +3944,16 @@ xfr_process_chunk_list(struct auth_xfer* xfr, struct module_env* env,
return 0;
}
}
if(xfr->have_zone)
xfr->lease_time = *env->now;
xfr->zone_expired = 0;
z->zone_expired = 0;
if(!xfr_find_soa(z, xfr)) {
lock_rw_unlock(&z->lock);
verbose(VERB_ALGO, "xfr from %s: no SOA in zone after update"
" (or malformed RR)", xfr->task_transfer->master->host);
return 0;
}
xfr->zone_expired = 0;
z->zone_expired = 0;
/* unlock */
lock_rw_unlock(&z->lock);
@ -4588,6 +4592,7 @@ auth_xfer_transfer_tcp_callback(struct comm_point* c, void* arg, int err,
int transferdone = 0;
log_assert(xfr->task_transfer);
env = xfr->task_transfer->env;
lock_basic_lock(&xfr->lock);
if(err != NETEVENT_NOERROR) {
/* connection failed, closed, or timeout */
@ -4628,6 +4633,7 @@ auth_xfer_transfer_tcp_callback(struct comm_point* c, void* arg, int err,
/* if we want to read more messages, setup the commpoint to read
* a DNS packet, and the timeout */
lock_basic_unlock(&xfr->lock);
c->tcp_is_reading = 1;
comm_point_start_listening(c, -1, AUTH_TRANSFER_TIMEOUT);
return 0;
@ -4783,6 +4789,7 @@ auth_xfer_probe_udp_callback(struct comm_point* c, void* arg, int err,
struct module_env* env;
log_assert(xfr->task_probe);
env = xfr->task_probe->env;
lock_basic_lock(&xfr->lock);
/* the comm_point_udp_callback is in a for loop for NUM_UDP_PER_SELECT
* and we set rep.c=NULL to stop if from looking inside the commpoint*/
@ -4798,7 +4805,6 @@ auth_xfer_probe_udp_callback(struct comm_point* c, void* arg, int err,
/* successful lookup */
/* see if this serial indicates that the zone has
* to be updated */
lock_basic_lock(&xfr->lock);
if(xfr_serial_means_update(xfr, serial)) {
/* if updated, start the transfer task, if needed */
if(xfr->task_transfer->worker == NULL) {
@ -4810,6 +4816,8 @@ auth_xfer_probe_udp_callback(struct comm_point* c, void* arg, int err,
}
} else {
/* if zone not updated, start the wait timer again */
if(xfr->have_zone)
xfr->lease_time = *env->now;
if(xfr->task_nextprobe->worker == NULL)
xfr_set_timeout(xfr, env, 0);
}
@ -4979,7 +4987,7 @@ auth_xfer_timer(void* arg)
/* see if zone has expired, and if so, also set auth_zone expired */
if(xfr->have_zone && !xfr->zone_expired &&
*env->now >= xfr->task_nextprobe->lease_time + xfr->expiry) {
*env->now >= xfr->lease_time + xfr->expiry) {
lock_basic_unlock(&xfr->lock);
auth_xfer_set_expired(xfr, env, 1);
lock_basic_lock(&xfr->lock);
@ -5033,9 +5041,8 @@ xfr_set_timeout(struct auth_xfer* xfr, struct module_env* env,
* but if expiry is sooner, use that one.
* after a failure, use the retry timer instead. */
xfr->task_nextprobe->next_probe = *env->now;
if(xfr->task_nextprobe->lease_time)
xfr->task_nextprobe->next_probe =
xfr->task_nextprobe->lease_time;
if(xfr->lease_time)
xfr->task_nextprobe->next_probe = xfr->lease_time;
if(xfr->have_zone) {
time_t wait = xfr->refresh;
if(failure) wait = xfr->retry;
@ -5076,6 +5083,11 @@ auth_xfer_pickup_initial(struct auth_zones* az, struct module_env* env)
lock_rw_wrlock(&az->lock);
RBTREE_FOR(x, struct auth_xfer*, &az->xtree) {
lock_basic_lock(&x->lock);
/* set lease_time, because we now have timestamp in env,
* (not earlier during startup and apply_cfg), and this
* notes the start time when the data was acquired */
if(x->have_zone)
x->lease_time = *env->now;
if(x->task_nextprobe && x->task_nextprobe->worker == NULL)
xfr_set_timeout(x, env, 0);
lock_basic_unlock(&x->lock);
@ -5140,7 +5152,7 @@ auth_xfer_new(struct auth_zone* z)
}
/** Create auth_xfer structure.
* This populates the have_zone, soa values, next_probe and so on times.
* This populates the have_zone, soa values, and so on times.
* and sets the timeout, if a zone transfer is needed a short timeout is set.
* For that the auth_zone itself must exist (and read in zonefile)
* returns false on alloc failure. */

View file

@ -237,6 +237,11 @@ struct auth_xfer {
* valid any more, if no master responds within this time, either
* with the current zone or a new zone. */
time_t expiry;
/** zone lease start time (start+expiry is expiration time).
* this is renewed every SOA probe and transfer. On zone load
* from zonefile it is also set (with probe set soon to check) */
time_t lease_time;
};
/**
@ -256,10 +261,6 @@ struct auth_nextprobe {
/** Timeout for next probe (for SOA) */
time_t next_probe;
/** zone lease start time (start+expiry is expiration time).
* this is renewed every SOA probe and transfer. On zone load
* from zonefile it is also set (with probe set soon to check) */
time_t lease_time;
/** timeout callback for next_probe or expiry(if that is sooner).
* it is on the worker's event_base */
struct comm_timer* timer;
@ -425,11 +426,10 @@ struct auth_zones* auth_zones_create(void);
* @param az: auth zones structure
* @param cfg: config to apply.
* @param setup: if true, also sets up values in the auth zones structure
* @param env: for setup, with current time.
* @return false on failure.
*/
int auth_zones_apply_cfg(struct auth_zones* az, struct config_file* cfg,
int setup, struct module_env* env);
int setup);
/**
* Delete auth zones structure

View file

@ -589,7 +589,7 @@ static void
check_auth(struct config_file* cfg)
{
struct auth_zones* az = auth_zones_create();
if(!az || !auth_zones_apply_cfg(az, cfg, 0, NULL)) {
if(!az || !auth_zones_apply_cfg(az, cfg, 0)) {
fatal_exit("Could not setup authority zones");
}
auth_zones_delete(az);

View file

@ -551,6 +551,9 @@ struct config_auth {
int for_downstream;
/** provide upstream answers */
int for_upstream;
/** fallback to recursion to authorities if zone expired and other
* reasons perhaps (like, query bogus) */
int fallback_enabled;
};
/**

File diff suppressed because it is too large Load diff

View file

@ -306,6 +306,7 @@ master{COLON} { YDVAR(1, VAR_MASTER) }
url{COLON} { YDVAR(1, VAR_URL) }
for-downstream{COLON} { YDVAR(1, VAR_FOR_DOWNSTREAM) }
for-upstream{COLON} { YDVAR(1, VAR_FOR_UPSTREAM) }
fallback-enabled{COLON} { YDVAR(1, VAR_FALLBACK_ENABLED) }
view{COLON} { YDVAR(0, VAR_VIEW) }
view-first{COLON} { YDVAR(1, VAR_VIEW_FIRST) }
do-not-query-address{COLON} { YDVAR(1, VAR_DO_NOT_QUERY_ADDRESS) }

File diff suppressed because it is too large Load diff

View file

@ -272,7 +272,8 @@ extern int yydebug;
VAR_ZONEFILE = 482,
VAR_MASTER = 483,
VAR_URL = 484,
VAR_FOR_DOWNSTREAM = 485
VAR_FOR_DOWNSTREAM = 485,
VAR_FALLBACK_ENABLED = 486
};
#endif
/* Tokens. */
@ -504,6 +505,7 @@ extern int yydebug;
#define VAR_MASTER 483
#define VAR_URL 484
#define VAR_FOR_DOWNSTREAM 485
#define VAR_FALLBACK_ENABLED 486
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
@ -514,7 +516,7 @@ union YYSTYPE
char* str;
#line 518 "util/configparser.h" /* yacc.c:1909 */
#line 520 "util/configparser.h" /* yacc.c:1909 */
};
typedef union YYSTYPE YYSTYPE;

View file

@ -154,6 +154,7 @@ extern struct config_parser_state* cfg_parser;
%token VAR_CACHEDB VAR_CACHEDB_BACKEND VAR_CACHEDB_SECRETSEED
%token VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM VAR_FOR_UPSTREAM
%token VAR_AUTH_ZONE VAR_ZONEFILE VAR_MASTER VAR_URL VAR_FOR_DOWNSTREAM
%token VAR_FALLBACK_ENABLED
%%
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
@ -308,6 +309,7 @@ authstart: VAR_AUTH_ZONE
/* defaults for auth zone */
s->for_downstream = 1;
s->for_upstream = 1;
s->fallback_enabled = 0;
} else
yyerror("out of memory");
}
@ -315,7 +317,7 @@ authstart: VAR_AUTH_ZONE
contents_auth: contents_auth content_auth
| ;
content_auth: auth_name | auth_zonefile | auth_master | auth_url |
auth_for_downstream | auth_for_upstream
auth_for_downstream | auth_for_upstream | auth_fallback_enabled
;
server_num_threads: VAR_NUM_THREADS STRING_ARG
{
@ -2070,6 +2072,16 @@ auth_for_upstream: VAR_FOR_UPSTREAM STRING_ARG
free($2);
}
;
auth_fallback_enabled: VAR_FALLBACK_ENABLED STRING_ARG
{
OUTYY(("P(fallback-enabled:%s)\n", $2));
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
yyerror("expected yes or no.");
else cfg_parser->cfg->auths->fallback_enabled =
(strcmp($2, "yes")==0);
free($2);
}
;
view_name: VAR_NAME STRING_ARG
{
OUTYY(("P(name:%s)\n", $2));