if(!qstate->env->cfg->ipsecmod_ignore_bogus &&
rrset_data->security == sec_status_bogus) {
log_err("ipsecmod: bogus IPSECKEY");
+ errinf(qstate, "ipsecmod: bogus IPSECKEY");
ipsecmod_error(qstate, id);
return;
}
if(!call_hook(qstate, iq, ie) &&
qstate->env->cfg->ipsecmod_strict) {
log_err("ipsecmod: ipsecmod-hook failed");
+ errinf(qstate, "ipsecmod: ipsecmod-hook failed");
ipsecmod_error(qstate, id);
return;
}
qstate->qinfo.qname_len, LDNS_RR_TYPE_IPSECKEY,
qstate->qinfo.qclass, 0)) {
log_err("ipsecmod: could not generate subquery.");
+ errinf(qstate, "ipsecmod: could not generate subquery.");
ipsecmod_error(qstate, id);
}
return;
if((event == module_event_new || event == module_event_pass) &&
iq == NULL) {
if(!ipsecmod_new(qstate, id)) {
+ errinf(qstate, "ipsecmod: could not ipsecmod_new");
ipsecmod_error(qstate, id);
return;
}
}
if(event == module_event_error) {
verbose(VERB_ALGO, "got called with event error, giving up");
+ errinf(qstate, "ipsecmod: got called with event error");
ipsecmod_error(qstate, id);
return;
}
}
log_err("ipsecmod: bad event %s", strmodulevent(event));
+ errinf(qstate, "ipsecmod: operate got bad event");
ipsecmod_error(qstate, id);
return;
}
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,
* 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);
}
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. */
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) {
}
/* parse message */
+ iq->fail_reply = qstate->reply;
prs = (struct msg_parse*)regional_alloc(qstate->env->scratch,
sizeof(struct msg_parse));
if(!prs) {
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) {
iq->num_current_queries--;
verbose(VERB_DETAIL, "Capsforid: scrub failed, starting fallback with no response");
}
+ iq->scrub_failures++;
goto handle_it;
}