- Add that log-servfail prints an IP address and more information

about one of the last failures for that query.
This commit is contained in:
W.C.A. Wijngaards
2021-04-29 10:24:35 +02:00
parent 45328d37b1
commit ecb8aed2f2
5 changed files with 81 additions and 1 deletions
+64 -1
View File
@@ -585,6 +585,60 @@ handle_cname_response(struct module_qstate* qstate, struct iter_qstate* iq,
return 1;
}
/** add response specific error information for log servfail */
static void
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)) {
char from[256], frm[512];
if(qstate->reply && qstate->reply->addrlen != 0)
addr_to_str(&qstate->reply->addr, qstate->reply->addrlen,
from, sizeof(from));
else
addr_to_str(&iq->fail_reply->addr, iq->fail_reply->addrlen,
from, sizeof(from));
snprintf(frm, sizeof(frm), "from %s", from);
errinf(qstate, frm);
}
if(iq->scrub_failures || iq->parse_failures) {
if(iq->scrub_failures)
errinf(qstate, "upstream response failed scrub");
if(iq->parse_failures)
errinf(qstate, "could not parse upstream response");
} else if(iq->response == NULL && iq->timeout_count != 0) {
errinf(qstate, "upstream server timeout");
} else if(iq->response == NULL) {
errinf(qstate, "no server to query");
if(iq->dp) {
if(iq->dp->target_list == NULL)
errinf(qstate, "no addresses for nameservers");
else errinf(qstate, "nameserver addresses not usable");
if(iq->dp->nslist == NULL)
errinf(qstate, "have no nameserver names");
if(iq->dp->bogus)
errinf(qstate, "NS record was dnssec bogus");
}
}
if(iq->response && iq->response->rep) {
if(FLAGS_GET_RCODE(iq->response->rep->flags) != 0) {
char rcode[256], rc[32];
(void)sldns_wire2str_rcode_buf(
FLAGS_GET_RCODE(iq->response->rep->flags),
rc, sizeof(rc));
snprintf(rcode, sizeof(rcode), "got %s", rc);
errinf(qstate, rcode);
} else {
/* rcode NOERROR */
if(iq->response->rep->an_numrrsets == 0) {
errinf(qstate, "nodata answer");
}
}
}
}
/** 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,
@@ -1922,6 +1976,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
* of a response. */
errinf(qstate, "all the configured stub or forward servers failed,");
errinf_dname(qstate, "at zone", iq->dp->name);
errinf_reply(qstate, iq);
verbose(VERB_QUERY, "configured stub or forward servers failed -- returning SERVFAIL");
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
}
@@ -2068,6 +2123,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
errinf(qstate, "all servers for this domain failed,");
errinf_dname(qstate, "at zone", iq->dp->name);
errinf_reply(qstate, iq);
verbose(VERB_QUERY, "out of query targets -- returning SERVFAIL");
/* fail -- no more targets, no more hope of targets, no hope
* of a response. */
@@ -2959,6 +3015,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
qstate->env->detach_subs));
(*qstate->env->detach_subs)(qstate);
iq->num_target_queries = 0;
iq->response = NULL;
iq->fail_reply = NULL;
verbose(VERB_ALGO, "cleared outbound list for next round");
return next_state(iq, QUERYTARGETS_STATE);
} else if(type == RESPONSE_TYPE_CNAME) {
@@ -3722,6 +3780,7 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
}
/* parse message */
iq->fail_reply = qstate->reply;
prs = (struct msg_parse*)regional_alloc(qstate->env->scratch,
sizeof(struct msg_parse));
if(!prs) {
@@ -3735,12 +3794,15 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
sldns_buffer_set_position(pkt, 0);
if(parse_packet(pkt, prs, qstate->env->scratch) != LDNS_RCODE_NOERROR) {
verbose(VERB_ALGO, "parse error on reply packet");
iq->parse_failures++;
goto handle_it;
}
/* edns is not examined, but removed from message to help cache */
if(parse_extract_edns(prs, &edns, qstate->env->scratch) !=
LDNS_RCODE_NOERROR)
LDNS_RCODE_NOERROR) {
iq->parse_failures++;
goto handle_it;
}
/* Copy the edns options we may got from the back end */
if(edns.opt_list) {
@@ -3774,6 +3836,7 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
iq->num_current_queries--;
verbose(VERB_DETAIL, "Capsforid: scrub failed, starting fallback with no response");
}
iq->scrub_failures++;
goto handle_it;
}