diff options
Diffstat (limited to 'daemon')
| -rw-r--r-- | daemon/daemon.c | 9 | ||||
| -rw-r--r-- | daemon/daemon.h | 2 | ||||
| -rw-r--r-- | daemon/remote.c | 40 | ||||
| -rw-r--r-- | daemon/stats.c | 8 | ||||
| -rw-r--r-- | daemon/unbound.c | 25 | ||||
| -rw-r--r-- | daemon/worker.c | 146 |
6 files changed, 154 insertions, 76 deletions
diff --git a/daemon/daemon.c b/daemon/daemon.c index 0b1200a2e00a..8b0fc3483ab7 100644 --- a/daemon/daemon.c +++ b/daemon/daemon.c @@ -617,7 +617,8 @@ daemon_fork(struct daemon* daemon) have_view_respip_cfg; /* read auth zonefiles */ - if(!auth_zones_apply_cfg(daemon->env->auth_zones, daemon->cfg, 1)) + if(!auth_zones_apply_cfg(daemon->env->auth_zones, daemon->cfg, 1, + &daemon->use_rpz)) fatal_exit("auth_zones could not be setup"); /* setup modules */ @@ -629,6 +630,12 @@ daemon_fork(struct daemon* daemon) if(daemon->use_response_ip && modstack_find(&daemon->mods, "respip") < 0) fatal_exit("response-ip options require respip module"); + /* RPZ response ip triggers don't work as expected without the respip + * module. To avoid run-time operational surprise we reject such + * configuration. */ + if(daemon->use_rpz && + modstack_find(&daemon->mods, "respip") < 0) + fatal_exit("RPZ requires the respip module"); /* first create all the worker structures, so we can pass * them to the newly created threads. diff --git a/daemon/daemon.h b/daemon/daemon.h index 5749dbef8fbf..3effbafb7918 100644 --- a/daemon/daemon.h +++ b/daemon/daemon.h @@ -132,6 +132,8 @@ struct daemon { struct respip_set* respip_set; /** some response-ip tags or actions are configured if true */ int use_response_ip; + /** some RPZ policies are configured */ + int use_rpz; #ifdef USE_DNSCRYPT /** the dnscrypt environment */ struct dnsc_env* dnscenv; diff --git a/daemon/remote.c b/daemon/remote.c index 25547f5705d9..1782a39cad7c 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -69,6 +69,7 @@ #include "services/mesh.h" #include "services/localzone.h" #include "services/authzone.h" +#include "services/rpz.h" #include "util/storage/slabhash.h" #include "util/fptr_wlist.h" #include "util/data/dname.h" @@ -719,8 +720,8 @@ print_stats(RES* ssl, const char* nm, struct ub_stats_info* s) (unsigned long)s->svr.num_queries_missed_cache)) return 0; if(!ssl_printf(ssl, "%s.num.prefetch"SQ"%lu\n", nm, (unsigned long)s->svr.num_queries_prefetch)) return 0; - if(!ssl_printf(ssl, "%s.num.zero_ttl"SQ"%lu\n", nm, - (unsigned long)s->svr.zero_ttl_responses)) return 0; + if(!ssl_printf(ssl, "%s.num.expired"SQ"%lu\n", nm, + (unsigned long)s->svr.ans_expired)) return 0; if(!ssl_printf(ssl, "%s.num.recursivereplies"SQ"%lu\n", nm, (unsigned long)s->mesh_replies_sent)) return 0; #ifdef USE_DNSCRYPT @@ -1045,6 +1046,16 @@ print_ext(RES* ssl, struct ub_stats_info* s) (unsigned)s->svr.infra_cache_count)) return 0; if(!ssl_printf(ssl, "key.cache.count"SQ"%u\n", (unsigned)s->svr.key_cache_count)) return 0; + /* applied RPZ actions */ + for(i=0; i<UB_STATS_RPZ_ACTION_NUM; i++) { + if(i == RPZ_NO_OVERRIDE_ACTION) + continue; + if(inhibit_zero && s->svr.rpz_action[i] == 0) + continue; + if(!ssl_printf(ssl, "num.rpz.action.%s"SQ"%lu\n", + rpz_action_to_string(i), + (unsigned long)s->svr.rpz_action[i])) return 0; + } #ifdef USE_DNSCRYPT if(!ssl_printf(ssl, "dnscrypt_shared_secret.cache.count"SQ"%u\n", (unsigned)s->svr.shared_secret_cache_count)) return 0; @@ -1479,6 +1490,27 @@ do_view_data_remove(RES* ssl, struct worker* worker, char* arg) lock_rw_unlock(&v->lock); } +/** Remove RR data from stdin from view */ +static void +do_view_datas_remove(RES* ssl, struct worker* worker, char* arg) +{ + struct view* v; + v = views_find_view(worker->daemon->views, + arg, 1 /* get write lock*/); + if(!v) { + ssl_printf(ssl,"no view with name: %s\n", arg); + return; + } + if(!v->local_zones){ + lock_rw_unlock(&v->lock); + ssl_printf(ssl, "removed 0 datas\n"); + return; + } + + do_datas_remove(ssl, v->local_zones); + lock_rw_unlock(&v->lock); +} + /** cache lookup of nameservers */ static void do_lookup(RES* ssl, struct worker* worker, char* arg) @@ -2506,8 +2538,10 @@ do_auth_zone_transfer(RES* ssl, struct worker* worker, char* arg) if(!az || !auth_zones_startprobesequence(az, &worker->env, nm, nmlen, LDNS_RR_CLASS_IN)) { (void)ssl_printf(ssl, "error zone xfr task not found %s\n", arg); + free(nm); return; } + free(nm); send_ok(ssl); } @@ -2989,6 +3023,8 @@ execute_cmd(struct daemon_remote* rc, RES* ssl, char* cmd, do_view_zone_add(ssl, worker, skipwhite(p+15)); } else if(cmdcmp(p, "view_local_data_remove", 22)) { do_view_data_remove(ssl, worker, skipwhite(p+22)); + } else if(cmdcmp(p, "view_local_datas_remove", 23)){ + do_view_datas_remove(ssl, worker, skipwhite(p+23)); } else if(cmdcmp(p, "view_local_data", 15)) { do_view_data_add(ssl, worker, skipwhite(p+15)); } else if(cmdcmp(p, "view_local_datas", 16)) { diff --git a/daemon/stats.c b/daemon/stats.c index a01fb6d342ca..a568ba070a57 100644 --- a/daemon/stats.c +++ b/daemon/stats.c @@ -271,8 +271,10 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset) s->svr.ans_secure += (long long)worker->env.mesh->ans_secure; s->svr.ans_bogus += (long long)worker->env.mesh->ans_bogus; s->svr.ans_rcode_nodata += (long long)worker->env.mesh->ans_nodata; - for(i=0; i<16; i++) + for(i=0; i<UB_STATS_RCODE_NUM; i++) s->svr.ans_rcode[i] += (long long)worker->env.mesh->ans_rcode[i]; + for(i=0; i<UB_STATS_RPZ_ACTION_NUM; i++) + s->svr.rpz_action[i] += (long long)worker->env.mesh->rpz_action[i]; timehist_export(worker->env.mesh->histogram, s->svr.hist, NUM_BUCKETS_HIST); /* values from outside network */ @@ -398,6 +400,7 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a) total->svr.num_queries_missed_cache += a->svr.num_queries_missed_cache; total->svr.num_queries_prefetch += a->svr.num_queries_prefetch; total->svr.sum_query_list_size += a->svr.sum_query_list_size; + total->svr.ans_expired += a->svr.ans_expired; #ifdef USE_DNSCRYPT total->svr.num_query_dnscrypt_crypted += a->svr.num_query_dnscrypt_crypted; total->svr.num_query_dnscrypt_cert += a->svr.num_query_dnscrypt_cert; @@ -430,7 +433,6 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a) total->svr.qEDNS += a->svr.qEDNS; total->svr.qEDNS_DO += a->svr.qEDNS_DO; total->svr.ans_rcode_nodata += a->svr.ans_rcode_nodata; - total->svr.zero_ttl_responses += a->svr.zero_ttl_responses; total->svr.ans_secure += a->svr.ans_secure; total->svr.ans_bogus += a->svr.ans_bogus; total->svr.unwanted_replies += a->svr.unwanted_replies; @@ -446,6 +448,8 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a) total->svr.ans_rcode[i] += a->svr.ans_rcode[i]; for(i=0; i<NUM_BUCKETS_HIST; i++) total->svr.hist[i] += a->svr.hist[i]; + for(i=0; i<UB_STATS_RPZ_ACTION_NUM; i++) + total->svr.rpz_action[i] += a->svr.rpz_action[i]; } total->mesh_num_states += a->mesh_num_states; diff --git a/daemon/unbound.c b/daemon/unbound.c index beffb57005fa..af76fc84fe51 100644 --- a/daemon/unbound.c +++ b/daemon/unbound.c @@ -259,21 +259,10 @@ checkrlimits(struct config_file* cfg) #endif /* S_SPLINT_S */ } -/** set default logfile identity based on value from argv[0] at startup **/ -static void -log_ident_set_fromdefault(struct config_file* cfg, - const char *log_default_identity) -{ - if(cfg->log_identity == NULL || cfg->log_identity[0] == 0) - log_ident_set(log_default_identity); - else - log_ident_set(cfg->log_identity); -} - /** set verbosity, check rlimits, cache settings */ static void -apply_settings(struct daemon* daemon, struct config_file* cfg, - int cmdline_verbose, int debug_mode, const char* log_default_identity) +apply_settings(struct daemon* daemon, struct config_file* cfg, + int cmdline_verbose, int debug_mode) { /* apply if they have changed */ verbosity = cmdline_verbose + cfg->verbosity; @@ -289,7 +278,7 @@ apply_settings(struct daemon* daemon, struct config_file* cfg, log_warn("use-systemd and do-daemonize should not be enabled at the same time"); } - log_ident_set_fromdefault(cfg, log_default_identity); + log_ident_set_or_default(cfg->log_identity); } #ifdef HAVE_KILL @@ -639,11 +628,10 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode, * @param cmdline_verbose: verbosity resulting from commandline -v. * These increase verbosity as specified in the config file. * @param debug_mode: if set, do not daemonize. - * @param log_default_identity: Default identity to report in logs * @param need_pidfile: if false, no pidfile is checked or created. */ static void -run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode, const char* log_default_identity, int need_pidfile) +run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode, int need_pidfile) { struct config_file* cfg = NULL; struct daemon* daemon = NULL; @@ -667,7 +655,7 @@ run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode, const char* "or unbound-checkconf", cfgfile); log_warn("Continuing with default config settings"); } - apply_settings(daemon, cfg, cmdline_verbose, debug_mode, log_default_identity); + apply_settings(daemon, cfg, cmdline_verbose, debug_mode); if(!done_setup) config_lookup_uid(cfg); @@ -733,6 +721,7 @@ main(int argc, char* argv[]) log_init(NULL, 0, NULL); log_ident_default = strrchr(argv[0],'/')?strrchr(argv[0],'/')+1:argv[0]; + log_ident_set_default(log_ident_default); log_ident_set(log_ident_default); /* parse the options */ while( (c=getopt(argc, argv, "c:dhpvw:V")) != -1) { @@ -783,7 +772,7 @@ main(int argc, char* argv[]) return 1; } - run_daemon(cfgfile, cmdline_verbose, debug_mode, log_ident_default, need_pidfile); + run_daemon(cfgfile, cmdline_verbose, debug_mode, need_pidfile); log_init(NULL, 0, NULL); /* close logfile */ #ifndef unbound_testbound if(log_get_lock()) { diff --git a/daemon/worker.c b/daemon/worker.c index e2ce0e87009b..eb7fdf2f576d 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -61,6 +61,7 @@ #include "services/authzone.h" #include "services/mesh.h" #include "services/localzone.h" +#include "services/rpz.h" #include "util/data/msgparse.h" #include "util/data/msgencode.h" #include "util/data/dname.h" @@ -572,9 +573,10 @@ static int apply_respip_action(struct worker* worker, const struct query_info* qinfo, struct respip_client_info* cinfo, struct reply_info* rep, struct comm_reply* repinfo, struct ub_packed_rrset_key** alias_rrset, - struct reply_info** encode_repp) + struct reply_info** encode_repp, struct auth_zones* az) { - struct respip_action_info actinfo = {respip_none, NULL}; + struct respip_action_info actinfo = {0}; + actinfo.action = respip_none; if(qinfo->qtype != LDNS_RR_TYPE_A && qinfo->qtype != LDNS_RR_TYPE_AAAA && @@ -582,7 +584,7 @@ apply_respip_action(struct worker* worker, const struct query_info* qinfo, return 1; if(!respip_rewrite_reply(qinfo, cinfo, rep, encode_repp, &actinfo, - alias_rrset, 0, worker->scratchpad)) + alias_rrset, 0, worker->scratchpad, az)) return 0; /* xxx_deny actions mean dropping the reply, unless the original reply @@ -595,9 +597,19 @@ apply_respip_action(struct worker* worker, const struct query_info* qinfo, /* If address info is returned, it means the action should be an * 'inform' variant and the information should be logged. */ if(actinfo.addrinfo) { - respip_inform_print(actinfo.addrinfo, qinfo->qname, + respip_inform_print(&actinfo, qinfo->qname, qinfo->qtype, qinfo->qclass, qinfo->local_alias, repinfo); + + if(worker->stats.extended && actinfo.rpz_used) { + if(actinfo.rpz_disabled) + worker->stats.rpz_action[RPZ_DISABLED_ACTION]++; + if(actinfo.rpz_cname_override) + worker->stats.rpz_action[RPZ_CNAME_OVERRIDE_ACTION]++; + else + worker->stats.rpz_action[ + respip_action_to_rpz_action(actinfo.action)]++; + } } return 1; @@ -613,10 +625,10 @@ apply_respip_action(struct worker* worker, const struct query_info* qinfo, * be completely dropped, '*need_drop' will be set to 1. */ static int answer_from_cache(struct worker* worker, struct query_info* qinfo, - struct respip_client_info* cinfo, int* need_drop, - struct ub_packed_rrset_key** alias_rrset, + struct respip_client_info* cinfo, int* need_drop, int* is_expired_answer, + int* is_secure_answer, struct ub_packed_rrset_key** alias_rrset, struct reply_info** partial_repp, - struct reply_info* rep, uint16_t id, uint16_t flags, + struct reply_info* rep, uint16_t id, uint16_t flags, struct comm_reply* repinfo, struct edns_data* edns) { struct edns_data edns_bak; @@ -624,38 +636,37 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo, uint16_t udpsize = edns->udp_size; struct reply_info* encode_rep = rep; struct reply_info* partial_rep = *partial_repp; - int secure; int must_validate = (!(flags&BIT_CD) || worker->env.cfg->ignore_cd) && worker->env.need_to_validate; - *partial_repp = NULL; /* avoid accidental further pass */ - if(worker->env.cfg->serve_expired) { - if(worker->env.cfg->serve_expired_ttl && - rep->serve_expired_ttl < timenow) - return 0; - if(!rrset_array_lock(rep->ref, rep->rrset_count, 0)) - return 0; - /* below, rrsets with ttl before timenow become TTL 0 in - * the response */ - /* This response was served with zero TTL */ - if (timenow >= rep->ttl) { - worker->stats.zero_ttl_responses++; - } - } else { - /* see if it is possible */ - if(rep->ttl < timenow) { + *partial_repp = NULL; /* avoid accidental further pass */ + + /* Check TTL */ + if(rep->ttl < timenow) { + /* Check if we need to serve expired now */ + if(worker->env.cfg->serve_expired && + !worker->env.cfg->serve_expired_client_timeout) { + if(worker->env.cfg->serve_expired_ttl && + rep->serve_expired_ttl < timenow) + return 0; + if(!rrset_array_lock(rep->ref, rep->rrset_count, 0)) + return 0; + *is_expired_answer = 1; + } else { /* the rrsets may have been updated in the meantime. * we will refetch the message format from the - * authoritative server + * authoritative server */ return 0; } + } else { if(!rrset_array_lock(rep->ref, rep->rrset_count, timenow)) return 0; - /* locked and ids and ttls are OK. */ } + /* locked and ids and ttls are OK. */ + /* check CNAME chain (if any) */ - if(rep->an_numrrsets > 0 && (rep->rrsets[0]->rk.type == - htons(LDNS_RR_TYPE_CNAME) || rep->rrsets[0]->rk.type == + if(rep->an_numrrsets > 0 && (rep->rrsets[0]->rk.type == + htons(LDNS_RR_TYPE_CNAME) || rep->rrsets[0]->rk.type == htons(LDNS_RR_TYPE_DNAME))) { if(!reply_check_cname_chain(qinfo, rep)) { /* cname chain invalid, redo iterator steps */ @@ -674,31 +685,31 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo, if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, rep, LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad)) goto bail_out; - error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL, + error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL, qinfo, id, flags, edns); - rrset_array_unlock_touch(worker->env.rrset_cache, + rrset_array_unlock_touch(worker->env.rrset_cache, worker->scratchpad, rep->ref, rep->rrset_count); if(worker->stats.extended) { worker->stats.ans_bogus ++; worker->stats.ans_rcode[LDNS_RCODE_SERVFAIL] ++; } return 1; - } else if( rep->security == sec_status_unchecked && must_validate) { + } else if(rep->security == sec_status_unchecked && must_validate) { verbose(VERB_ALGO, "Cache reply: unchecked entry needs " "validation"); goto bail_out; /* need to validate cache entry first */ } else if(rep->security == sec_status_secure) { - if(reply_all_rrsets_secure(rep)) - secure = 1; - else { + if(reply_all_rrsets_secure(rep)) { + *is_secure_answer = 1; + } else { if(must_validate) { verbose(VERB_ALGO, "Cache reply: secure entry" " changed status"); goto bail_out; /* rrset changed, re-verify */ } - secure = 0; + *is_secure_answer = 0; } - } else secure = 0; + } else *is_secure_answer = 0; edns_bak = *edns; edns->edns_version = EDNS_ADVERTISED_VERSION; @@ -709,17 +720,21 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo, (int)(flags&LDNS_RCODE_MASK), edns, repinfo, worker->scratchpad)) goto bail_out; *alias_rrset = NULL; /* avoid confusion if caller set it to non-NULL */ - if(worker->daemon->use_response_ip && !partial_rep && - !apply_respip_action(worker, qinfo, cinfo, rep, repinfo, alias_rrset, - &encode_rep)) { + if((worker->daemon->use_response_ip || worker->daemon->use_rpz) && + !partial_rep && !apply_respip_action(worker, qinfo, cinfo, rep, + repinfo, alias_rrset, + &encode_rep, worker->env.auth_zones)) { goto bail_out; } else if(partial_rep && !respip_merge_cname(partial_rep, qinfo, rep, cinfo, - must_validate, &encode_rep, worker->scratchpad)) { + must_validate, &encode_rep, worker->scratchpad, + worker->env.auth_zones)) { goto bail_out; } - if(encode_rep != rep) - secure = 0; /* if rewritten, it can't be considered "secure" */ + if(encode_rep != rep) { + /* if rewritten, it can't be considered "secure" */ + *is_secure_answer = 0; + } if(!encode_rep || *alias_rrset) { if(!encode_rep) *need_drop = 1; @@ -736,7 +751,7 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo, repinfo->c, worker->scratchpad) || !reply_info_answer_encode(qinfo, encode_rep, id, flags, repinfo->c->buffer, timenow, 1, worker->scratchpad, - udpsize, edns, (int)(edns->bits & EDNS_DO), secure)) { + udpsize, edns, (int)(edns->bits & EDNS_DO), *is_secure_answer)) { if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, NULL, LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad)) edns->opt_list = NULL; @@ -747,10 +762,6 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo, * is bad while holding locks. */ rrset_array_unlock_touch(worker->env.rrset_cache, worker->scratchpad, rep->ref, rep->rrset_count); - if(worker->stats.extended) { - if(secure) worker->stats.ans_secure++; - server_stats_insrcode(&worker->stats, repinfo->c->buffer); - } /* go and return this buffer to the client */ return 1; @@ -1085,6 +1096,8 @@ worker_handle_request(struct comm_point* c, void* arg, int error, struct acl_addr* acladdr; int rc = 0; int need_drop = 0; + int is_expired_answer = 0; + int is_secure_answer = 0; /* We might have to chase a CNAME chain internally, in which case * we'll have up to two replies and combine them to build a complete * answer. These variables control this case. */ @@ -1365,6 +1378,18 @@ worker_handle_request(struct comm_point* c, void* arg, int error, goto send_reply; } if(worker->env.auth_zones && + rpz_apply_qname_trigger(worker->env.auth_zones, + &worker->env, &qinfo, &edns, c->buffer, worker->scratchpad, + repinfo, acladdr->taglist, acladdr->taglen, &worker->stats)) { + regional_free_all(worker->scratchpad); + if(sldns_buffer_limit(c->buffer) == 0) { + comm_point_drop_reply(repinfo); + return 0; + } + server_stats_insrcode(&worker->stats, c->buffer); + goto send_reply; + } + if(worker->env.auth_zones && auth_zones_answer(worker->env.auth_zones, &worker->env, &qinfo, &edns, repinfo, c->buffer, worker->scratchpad)) { regional_free_all(worker->scratchpad); @@ -1434,7 +1459,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error, /* If we may apply IP-based actions to the answer, build the client * information. As this can be expensive, skip it if there is * absolutely no possibility of it. */ - if(worker->daemon->use_response_ip && + if((worker->daemon->use_response_ip || worker->daemon->use_rpz) && (qinfo.qtype == LDNS_RR_TYPE_A || qinfo.qtype == LDNS_RR_TYPE_AAAA || qinfo.qtype == LDNS_RR_TYPE_ANY)) { @@ -1455,12 +1480,14 @@ lookup_cache: * each pass. We should still pass the original qinfo to * answer_from_cache(), however, since it's used to build the reply. */ if(!edns_bypass_cache_stage(edns.opt_list, &worker->env)) { + is_expired_answer = 0; + is_secure_answer = 0; h = query_info_hash(lookup_qinfo, sldns_buffer_read_u16_at(c->buffer, 2)); if((e=slabhash_lookup(worker->env.msg_cache, h, lookup_qinfo, 0))) { /* answer from cache - we have acquired a readlock on it */ if(answer_from_cache(worker, &qinfo, - cinfo, &need_drop, &alias_rrset, &partial_rep, - (struct reply_info*)e->data, + cinfo, &need_drop, &is_expired_answer, &is_secure_answer, + &alias_rrset, &partial_rep, (struct reply_info*)e->data, *(uint16_t*)(void *)sldns_buffer_begin(c->buffer), sldns_buffer_read_u16_at(c->buffer, 2), repinfo, &edns)) { @@ -1468,9 +1495,11 @@ lookup_cache: * Note that if there is more than one pass * its qname must be that used for cache * lookup. */ - if((worker->env.cfg->prefetch || worker->env.cfg->serve_expired) - && *worker->env.now >= - ((struct reply_info*)e->data)->prefetch_ttl) { + if((worker->env.cfg->prefetch && *worker->env.now >= + ((struct reply_info*)e->data)->prefetch_ttl) || + (worker->env.cfg->serve_expired && + *worker->env.now >= ((struct reply_info*)e->data)->ttl)) { + time_t leeway = ((struct reply_info*)e-> data)->ttl - *worker->env.now; if(((struct reply_info*)e->data)->ttl @@ -1555,6 +1584,13 @@ send_reply_rc: comm_point_drop_reply(repinfo); return 0; } + if(is_expired_answer) { + worker->stats.ans_expired++; + } + if(worker->stats.extended) { + if(is_secure_answer) worker->stats.ans_secure++; + server_stats_insrcode(&worker->stats, repinfo->c->buffer); + } #ifdef USE_DNSTAP if(worker->dtenv.log_client_response_messages) dt_msg_send_client_response(&worker->dtenv, &repinfo->addr, @@ -1830,6 +1866,10 @@ worker_init(struct worker* worker, struct config_file *cfg, return 0; } worker->env.mesh = mesh_create(&worker->daemon->mods, &worker->env); + /* Pass on daemon variables that we would need in the mesh area */ + worker->env.mesh->use_response_ip = worker->daemon->use_response_ip; + worker->env.mesh->use_rpz = worker->daemon->use_rpz; + worker->env.detach_subs = &mesh_detach_subs; worker->env.attach_sub = &mesh_attach_sub; worker->env.add_sub = &mesh_add_sub; |
