diff options
Diffstat (limited to 'iterator/iter_utils.c')
-rw-r--r-- | iterator/iter_utils.c | 153 |
1 files changed, 104 insertions, 49 deletions
diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c index cacba420e845..1da21896cb20 100644 --- a/iterator/iter_utils.c +++ b/iterator/iter_utils.c @@ -77,41 +77,73 @@ static const char DEFAULT_NAT64_PREFIX[] = "64:ff9b::/96"; /** fillup fetch policy array */ -static void -fetch_fill(struct iter_env* ie, const char* str) +static int +fetch_fill(int* target_fetch_policy, int max_dependency_depth, const char* str) { char* s = (char*)str, *e; int i; - for(i=0; i<ie->max_dependency_depth+1; i++) { - ie->target_fetch_policy[i] = strtol(s, &e, 10); - if(s == e) - fatal_exit("cannot parse fetch policy number %s", s); + for(i=0; i<max_dependency_depth+1; i++) { + target_fetch_policy[i] = strtol(s, &e, 10); + if(s == e) { + log_err("cannot parse fetch policy number %s", s); + return 0; + } s = e; } + return 1; } /** Read config string that represents the target fetch policy */ -static int -read_fetch_policy(struct iter_env* ie, const char* str) +int +read_fetch_policy(int** target_fetch_policy, int* max_dependency_depth, + const char* str) { int count = cfg_count_numbers(str); if(count < 1) { log_err("Cannot parse target fetch policy: \"%s\"", str); return 0; } - ie->max_dependency_depth = count - 1; - ie->target_fetch_policy = (int*)calloc( - (size_t)ie->max_dependency_depth+1, sizeof(int)); - if(!ie->target_fetch_policy) { + *max_dependency_depth = count - 1; + *target_fetch_policy = (int*)calloc( + (size_t)(*max_dependency_depth)+1, sizeof(int)); + if(!*target_fetch_policy) { log_err("alloc fetch policy: out of memory"); return 0; } - fetch_fill(ie, str); + if(!fetch_fill(*target_fetch_policy, *max_dependency_depth, str)) + return 0; return 1; } -/** apply config caps whitelist items to name tree */ -static int +struct rbtree_type* +caps_white_create(void) +{ + struct rbtree_type* caps_white = rbtree_create(name_tree_compare); + if(!caps_white) + log_err("out of memory"); + return caps_white; +} + +/** delete caps_whitelist element */ +static void +caps_free(struct rbnode_type* n, void* ATTR_UNUSED(d)) +{ + if(n) { + free(((struct name_tree_node*)n)->name); + free(n); + } +} + +void +caps_white_delete(struct rbtree_type* caps_white) +{ + if(!caps_white) + return; + traverse_postorder(caps_white, caps_free, NULL); + free(caps_white); +} + +int caps_white_apply_cfg(rbtree_type* ntree, struct config_file* cfg) { struct config_strlist* p; @@ -145,12 +177,41 @@ caps_white_apply_cfg(rbtree_type* ntree, struct config_file* cfg) } int -iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg) +nat64_apply_cfg(struct iter_nat64* nat64, struct config_file* cfg) { const char *nat64_prefix; + + nat64_prefix = cfg->nat64_prefix; + if(!nat64_prefix) + nat64_prefix = cfg->dns64_prefix; + if(!nat64_prefix) + nat64_prefix = DEFAULT_NAT64_PREFIX; + if(!netblockstrtoaddr(nat64_prefix, 0, &nat64->nat64_prefix_addr, + &nat64->nat64_prefix_addrlen, &nat64->nat64_prefix_net)) { + log_err("cannot parse nat64-prefix netblock: %s", nat64_prefix); + return 0; + } + if(!addr_is_ip6(&nat64->nat64_prefix_addr, + nat64->nat64_prefix_addrlen)) { + log_err("nat64-prefix is not IPv6: %s", cfg->nat64_prefix); + return 0; + } + if(!prefixnet_is_nat64(nat64->nat64_prefix_net)) { + log_err("nat64-prefix length it not 32, 40, 48, 56, 64 or 96: %s", + nat64_prefix); + return 0; + } + nat64->use_nat64 = cfg->do_nat64; + return 1; +} + +int +iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg) +{ int i; /* target fetch policy */ - if(!read_fetch_policy(iter_env, cfg->target_fetch_policy)) + if(!read_fetch_policy(&iter_env->target_fetch_policy, + &iter_env->max_dependency_depth, cfg->target_fetch_policy)) return 0; for(i=0; i<iter_env->max_dependency_depth+1; i++) verbose(VERB_QUERY, "target fetch policy for level %d is %d", @@ -170,7 +231,7 @@ iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg) } if(cfg->caps_whitelist) { if(!iter_env->caps_white) - iter_env->caps_white = rbtree_create(name_tree_compare); + iter_env->caps_white = caps_white_create(); if(!iter_env->caps_white || !caps_white_apply_cfg( iter_env->caps_white, cfg)) { log_err("Could not set capsforid whitelist"); @@ -179,31 +240,13 @@ iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg) } - nat64_prefix = cfg->nat64_prefix; - if(!nat64_prefix) - nat64_prefix = cfg->dns64_prefix; - if(!nat64_prefix) - nat64_prefix = DEFAULT_NAT64_PREFIX; - if(!netblockstrtoaddr(nat64_prefix, 0, &iter_env->nat64_prefix_addr, - &iter_env->nat64_prefix_addrlen, - &iter_env->nat64_prefix_net)) { - log_err("cannot parse nat64-prefix netblock: %s", nat64_prefix); - return 0; - } - if(!addr_is_ip6(&iter_env->nat64_prefix_addr, - iter_env->nat64_prefix_addrlen)) { - log_err("nat64-prefix is not IPv6: %s", cfg->nat64_prefix); - return 0; - } - if(!prefixnet_is_nat64(iter_env->nat64_prefix_net)) { - log_err("nat64-prefix length it not 32, 40, 48, 56, 64 or 96: %s", - nat64_prefix); + if(!nat64_apply_cfg(&iter_env->nat64, cfg)) { + log_err("Could not setup nat64"); return 0; } iter_env->supports_ipv6 = cfg->do_ip6; iter_env->supports_ipv4 = cfg->do_ip4; - iter_env->use_nat64 = cfg->do_nat64; iter_env->outbound_msg_retry = cfg->outbound_msg_retry; iter_env->max_sent_count = cfg->max_sent_count; iter_env->max_query_restarts = cfg->max_query_restarts; @@ -270,7 +313,7 @@ iter_filter_unsuitable(struct iter_env* iter_env, struct module_env* env, if(!iter_env->supports_ipv6 && addr_is_ip6(&a->addr, a->addrlen)) { return -1; /* there is no ip6 available */ } - if(!iter_env->supports_ipv4 && !iter_env->use_nat64 && + if(!iter_env->supports_ipv4 && !iter_env->nat64.use_nat64 && !addr_is_ip6(&a->addr, a->addrlen)) { return -1; /* there is no ip4 available */ } @@ -693,10 +736,11 @@ dns_copy_msg(struct dns_msg* from, struct regional* region) void iter_dns_store(struct module_env* env, struct query_info* msgqinf, struct reply_info* msgrep, int is_referral, time_t leeway, int pside, - struct regional* region, uint16_t flags, time_t qstarttime) + struct regional* region, uint16_t flags, time_t qstarttime, + int is_valrec) { if(!dns_cache_store(env, msgqinf, msgrep, is_referral, leeway, - pside, region, flags, qstarttime)) + pside, region, flags, qstarttime, is_valrec)) log_err("out of memory: cannot store data in cache"); } @@ -1488,14 +1532,15 @@ iter_stub_fwd_no_cache(struct module_qstate *qstate, struct query_info *qinf, /* check stub */ if (stub != NULL && stub->dp != NULL) { + enum verbosity_value level = VERB_ALGO; int stub_no_cache = stub->dp->no_cache; lock_rw_unlock(&qstate->env->fwds->lock); - if(stub_no_cache) { - char qname[255+1]; - char dpname[255+1]; + if(verbosity >= level && stub_no_cache) { + char qname[LDNS_MAX_DOMAINLEN]; + char dpname[LDNS_MAX_DOMAINLEN]; dname_str(qinf->qname, qname); dname_str(stub->dp->name, dpname); - verbose(VERB_ALGO, "stub for %s %s has no_cache", qname, dpname); + verbose(level, "stub for %s %s has no_cache", qname, dpname); } if(retdpname) { if(stub->dp->namelen > dpname_storage_len) { @@ -1516,14 +1561,15 @@ iter_stub_fwd_no_cache(struct module_qstate *qstate, struct query_info *qinf, /* Check for forward. */ if (dp) { + enum verbosity_value level = VERB_ALGO; int dp_no_cache = dp->no_cache; lock_rw_unlock(&qstate->env->hints->lock); - if(dp_no_cache) { - char qname[255+1]; - char dpname[255+1]; + if(verbosity >= level && dp_no_cache) { + char qname[LDNS_MAX_DOMAINLEN]; + char dpname[LDNS_MAX_DOMAINLEN]; dname_str(qinf->qname, qname); dname_str(dp->name, dpname); - verbose(VERB_ALGO, "forward for %s %s has no_cache", qname, dpname); + verbose(level, "forward for %s %s has no_cache", qname, dpname); } if(retdpname) { if(dp->namelen > dpname_storage_len) { @@ -1606,3 +1652,12 @@ limit_nsec_ttl(struct dns_msg* msg) } } } + +void +iter_make_minimal(struct reply_info* rep) +{ + size_t rem = rep->ns_numrrsets + rep->ar_numrrsets; + rep->ns_numrrsets = 0; + rep->ar_numrrsets = 0; + rep->rrset_count -= rem; +} |