diff options
Diffstat (limited to 'iterator')
| -rw-r--r-- | iterator/iter_hints.c | 2 | ||||
| -rw-r--r-- | iterator/iter_resptype.c | 6 | ||||
| -rw-r--r-- | iterator/iterator.c | 105 | ||||
| -rw-r--r-- | iterator/iterator.h | 2 |
4 files changed, 79 insertions, 36 deletions
diff --git a/iterator/iter_hints.c b/iterator/iter_hints.c index 9b1a200bbb17..a60d9a6b1cf2 100644 --- a/iterator/iter_hints.c +++ b/iterator/iter_hints.c @@ -100,7 +100,7 @@ ah(struct delegpt* dp, const char* sv, const char* ip) return 0; } if(!delegpt_add_ns_mlc(dp, dname, 0, NULL, UNBOUND_DNS_PORT) || - !extstrtoaddr(ip, &addr, &addrlen) || + !extstrtoaddr(ip, &addr, &addrlen, UNBOUND_DNS_PORT) || !delegpt_add_target_mlc(dp, dname, dname_len, &addr, addrlen, 0, 0)) { free(dname); diff --git a/iterator/iter_resptype.c b/iterator/iter_resptype.c index f146a2b6bfe8..c2b824a0f9b8 100644 --- a/iterator/iter_resptype.c +++ b/iterator/iter_resptype.c @@ -113,7 +113,11 @@ response_type_from_server(int rdset, if(!msg || !request) return RESPONSE_TYPE_THROWAWAY; - + /* If the TC flag is set, the response is incomplete. Too large to + * fit even in TCP or so. Discard it, it cannot be retrieved here. */ + if((msg->rep->flags & BIT_TC)) + return RESPONSE_TYPE_THROWAWAY; + /* If the message is NXDOMAIN, then it answers the question. */ if(FLAGS_GET_RCODE(msg->rep->flags) == LDNS_RCODE_NXDOMAIN) { /* make sure its not recursive when we don't want it to */ diff --git a/iterator/iterator.c b/iterator/iterator.c index da9b7990c506..2f3ad06fe6ea 100644 --- a/iterator/iterator.c +++ b/iterator/iterator.c @@ -255,9 +255,9 @@ error_supers(struct module_qstate* qstate, int id, struct module_qstate* super) log_err("out of memory adding missing"); } delegpt_mark_neg(dpns, qstate->qinfo.qtype); - dpns->resolved = 1; /* mark as failed */ if((dpns->got4 == 2 || !ie->supports_ipv4) && (dpns->got6 == 2 || !ie->supports_ipv6)) { + dpns->resolved = 1; /* mark as failed */ target_count_increase_nx(super_iq, 1); } } @@ -596,15 +596,17 @@ errinf_reply(struct module_qstate* qstate, struct iter_qstate* iq) { if(qstate->env->cfg->val_log_level < 2 && !qstate->env->cfg->log_servfail) return; - if((qstate->reply && qstate->reply->addrlen != 0) || - (iq->fail_reply && iq->fail_reply->addrlen != 0)) { + if((qstate->reply && qstate->reply->remote_addrlen != 0) || + (iq->fail_reply && iq->fail_reply->remote_addrlen != 0)) { char from[256], frm[512]; - if(qstate->reply && qstate->reply->addrlen != 0) - addr_to_str(&qstate->reply->addr, qstate->reply->addrlen, - from, sizeof(from)); + if(qstate->reply && qstate->reply->remote_addrlen != 0) + addr_to_str(&qstate->reply->remote_addr, + qstate->reply->remote_addrlen, from, + sizeof(from)); else - addr_to_str(&iq->fail_reply->addr, iq->fail_reply->addrlen, - from, sizeof(from)); + addr_to_str(&iq->fail_reply->remote_addr, + iq->fail_reply->remote_addrlen, from, + sizeof(from)); snprintf(frm, sizeof(frm), "from %s", from); errinf(qstate, frm); } @@ -2262,6 +2264,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, size_t qout_orig_len = 0; int sq_check_ratelimit = 1; int sq_was_ratelimited = 0; + int can_do_promisc = 0; /* NOTE: a request will encounter this state for each target it * needs to send a query to. That is, at least one per referral, @@ -2589,12 +2592,12 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, if(iq->depth < ie->max_dependency_depth && iq->num_target_queries == 0 && (!iq->target_count || iq->target_count[TARGET_COUNT_NX]==0) - && iq->sent_count < TARGET_FETCH_STOP - /* if the mesh query list is full, then do not waste cpu - * and sockets to fetch promiscuous targets. They can be - * looked up when needed. */ - && !mesh_jostle_exceeded(qstate->env->mesh) - ) { + && iq->sent_count < TARGET_FETCH_STOP) { + can_do_promisc = 1; + } + /* if the mesh query list is full, then do not waste cpu and sockets to + * fetch promiscuous targets. They can be looked up when needed. */ + if(can_do_promisc && !mesh_jostle_exceeded(qstate->env->mesh)) { tf_policy = ie->target_fetch_policy[iq->depth]; } @@ -2766,6 +2769,37 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, return 0; } + /* We have a target. We could have created promiscuous target + * queries but we are currently under pressure (mesh_jostle_exceeded). + * If we are configured to allow promiscuous target queries and haven't + * gone out to the network for a target query for this delegation, then + * it is possible to slip in a promiscuous one with a 1/10 chance. */ + if(can_do_promisc && tf_policy == 0 && iq->depth == 0 + && iq->depth < ie->max_dependency_depth + && ie->target_fetch_policy[iq->depth] != 0 + && iq->dp_target_count == 0 + && !ub_random_max(qstate->env->rnd, 10)) { + int extra = 0; + verbose(VERB_ALGO, "available target exists in cache but " + "attempt to get extra 1 target"); + (void)query_for_targets(qstate, iq, ie, id, 1, &extra); + /* errors ignored, these targets are not strictly necessary for + * this result, we do not have to reply with SERVFAIL */ + if(extra > 0) { + iq->num_target_queries += extra; + target_count_increase(iq, extra); + check_waiting_queries(iq, qstate, id); + /* undo qname minimise step because we'll get back here + * to do it again */ + if(qout_orig && iq->minimise_count > 0) { + iq->minimise_count--; + iq->qinfo_out.qname = qout_orig; + iq->qinfo_out.qname_len = qout_orig_len; + } + return 0; + } + } + /* Do not check ratelimit for forwarding queries or if we already got a * pass. */ sq_check_ratelimit = (!(iq->chase_flags & BIT_RD) && !iq->ratelimit_ok); @@ -2873,6 +2907,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, (int)((iq->chase_flags&BIT_RD) || iq->chase_to_rd), iq->response, &iq->qinfo_out, iq->dp); iq->chase_to_rd = 0; + /* remove TC flag, if this is erroneously set by TCP upstream */ + iq->response->rep->flags &= ~BIT_TC; if(type == RESPONSE_TYPE_REFERRAL && (iq->chase_flags&BIT_RD) && !iq->auth_zone_response) { /* When forwarding (RD bit is set), we handle referrals @@ -2896,8 +2932,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, * use dnssec-lame-bypass if it needs to query there.*/ if(qstate->reply) { struct delegpt_addr* a = delegpt_find_addr( - iq->dp, &qstate->reply->addr, - qstate->reply->addrlen); + iq->dp, &qstate->reply->remote_addr, + qstate->reply->remote_addrlen); if(a) a->dnsseclame = 1; } /* test the answer is from the zone we expected, @@ -2993,9 +3029,9 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, (*qstate->env->detach_subs)(qstate); iq->num_target_queries = 0; if(qstate->reply) - sock_list_insert(&qstate->reply_origin, - &qstate->reply->addr, qstate->reply->addrlen, - qstate->region); + sock_list_insert(&qstate->reply_origin, + &qstate->reply->remote_addr, + qstate->reply->remote_addrlen, qstate->region); if(iq->minimisation_state != DONOT_MINIMISE_STATE && !(iq->chase_flags & BIT_RD)) { if(FLAGS_GET_RCODE(iq->response->rep->flags) != @@ -3250,9 +3286,9 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, (*qstate->env->detach_subs)(qstate); iq->num_target_queries = 0; if(qstate->reply) - sock_list_insert(&qstate->reply_origin, - &qstate->reply->addr, qstate->reply->addrlen, - qstate->region); + sock_list_insert(&qstate->reply_origin, + &qstate->reply->remote_addr, + qstate->reply->remote_addrlen, qstate->region); verbose(VERB_ALGO, "cleared outbound list for query restart"); /* go to INIT_REQUEST_STATE for new qname. */ return next_state(iq, INIT_REQUEST_STATE); @@ -3266,9 +3302,10 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, } else if(qstate->reply) { /* need addr for lameness cache, but we may have * gotten this from cache, so test to be sure */ - if(!infra_set_lame(qstate->env->infra_cache, - &qstate->reply->addr, qstate->reply->addrlen, - iq->dp->name, iq->dp->namelen, + if(!infra_set_lame(qstate->env->infra_cache, + &qstate->reply->remote_addr, + qstate->reply->remote_addrlen, + iq->dp->name, iq->dp->namelen, *qstate->env->now, dnsseclame, 0, iq->qchase.qtype)) log_err("mark host lame: out of memory"); @@ -3285,8 +3322,9 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, * gotten this from cache, so test to be sure */ verbose(VERB_DETAIL, "mark as REC_LAME"); if(!infra_set_lame(qstate->env->infra_cache, - &qstate->reply->addr, qstate->reply->addrlen, - iq->dp->name, iq->dp->namelen, + &qstate->reply->remote_addr, + qstate->reply->remote_addrlen, + iq->dp->name, iq->dp->namelen, *qstate->env->now, 0, 1, iq->qchase.qtype)) log_err("mark host lame: out of memory"); } @@ -3527,12 +3565,13 @@ processTargetResponse(struct module_qstate* qstate, int id, } else { verbose(VERB_ALGO, "iterator TargetResponse failed"); delegpt_mark_neg(dpns, qstate->qinfo.qtype); - dpns->resolved = 1; /* fail the target */ if((dpns->got4 == 2 || !ie->supports_ipv4) && - (dpns->got6 == 2 || !ie->supports_ipv6) && + (dpns->got6 == 2 || !ie->supports_ipv6)) { + dpns->resolved = 1; /* fail the target */ /* do not count cached answers */ - (qstate->reply_origin && qstate->reply_origin->len != 0)) { - target_count_increase_nx(foriq, 1); + if(qstate->reply_origin && qstate->reply_origin->len != 0) { + target_count_increase_nx(foriq, 1); + } } } } @@ -4014,8 +4053,8 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq, if(!iq->response) goto handle_it; log_query_info(VERB_DETAIL, "response for", &qstate->qinfo); - log_name_addr(VERB_DETAIL, "reply from", iq->dp->name, - &qstate->reply->addr, qstate->reply->addrlen); + log_name_addr(VERB_DETAIL, "reply from", iq->dp->name, + &qstate->reply->remote_addr, qstate->reply->remote_addrlen); if(verbosity >= VERB_ALGO) log_dns_msg("incoming scrubbed packet:", &iq->response->qinfo, iq->response->rep); diff --git a/iterator/iterator.h b/iterator/iterator.h index b71b7fe9945f..e35718cf33bd 100644 --- a/iterator/iterator.h +++ b/iterator/iterator.h @@ -324,7 +324,7 @@ struct iter_qstate { /** the number of times this query has been restarted. */ int query_restart_count; - /** the number of times this query as followed a referral. */ + /** the number of times this query has followed a referral. */ int referral_count; /** number of queries fired off */ |
