diff --git a/configure b/configure index 9fe75aa2c..b9e65ecc5 100755 --- a/configure +++ b/configure @@ -2108,7 +2108,8 @@ LIBUNBOUND_AGE=0 # 1.3.2 had 1:2:0 # 1.3.3 had 1:3:0 # 1.3.4 had 1:4:0 -# 1.4.0 had 1:5:0 +# 1.4.0-snapshots had 1:5:0 +# 1.4.0 had 2:0:0 # ub_result.why_bogus # Current -- the number of the binary API that we're implementing # Revision -- which iteration of the implementation of the binary @@ -7279,13 +7280,13 @@ if test "${lt_cv_nm_interface+set}" = set; then else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:7282: $ac_compile\"" >&5) + (eval echo "\"\$as_me:7283: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 - (eval echo "\"\$as_me:7285: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval echo "\"\$as_me:7286: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 - (eval echo "\"\$as_me:7288: output\"" >&5) + (eval echo "\"\$as_me:7289: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" @@ -8490,7 +8491,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 8493 "configure"' > conftest.$ac_ext + echo '#line 8494 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -9857,11 +9858,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:9860: $lt_compile\"" >&5) + (eval echo "\"\$as_me:9861: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:9864: \$? = $ac_status" >&5 + echo "$as_me:9865: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -10196,11 +10197,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:10199: $lt_compile\"" >&5) + (eval echo "\"\$as_me:10200: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:10203: \$? = $ac_status" >&5 + echo "$as_me:10204: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -10301,11 +10302,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:10304: $lt_compile\"" >&5) + (eval echo "\"\$as_me:10305: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:10308: \$? = $ac_status" >&5 + echo "$as_me:10309: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -10356,11 +10357,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:10359: $lt_compile\"" >&5) + (eval echo "\"\$as_me:10360: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:10363: \$? = $ac_status" >&5 + echo "$as_me:10364: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -13159,7 +13160,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 13162 "configure" +#line 13163 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -13255,7 +13256,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 13258 "configure" +#line 13259 "configure" #include "confdefs.h" #if HAVE_DLFCN_H diff --git a/configure.ac b/configure.ac index eabdecdab..ae83babda 100644 --- a/configure.ac +++ b/configure.ac @@ -23,7 +23,8 @@ LIBUNBOUND_AGE=0 # 1.3.2 had 1:2:0 # 1.3.3 had 1:3:0 # 1.3.4 had 1:4:0 -# 1.4.0 had 1:5:0 +# 1.4.0-snapshots had 1:5:0 +# 1.4.0 had 2:0:0 # ub_result.why_bogus # Current -- the number of the binary API that we're implementing # Revision -- which iteration of the implementation of the binary diff --git a/daemon/worker.c b/daemon/worker.c index e8fe788ef..7d87595f8 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -1281,13 +1281,15 @@ void libworker_handle_control_cmd(struct tube* ATTR_UNUSED(tube), } void libworker_fg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode), - ldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s)) + ldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s), + char* ATTR_UNUSED(why_bogus)) { log_assert(0); } void libworker_bg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode), - ldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s)) + ldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s), + char* ATTR_UNUSED(why_bogus)) { log_assert(0); } diff --git a/doc/Changelog b/doc/Changelog index c891c4c89..35ec577da 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -4,6 +4,10 @@ - more detail to errors from insecure delegation checks. - Fix double time subtraction in negative cache reported by Amanda Constant and Hugh Mahon. + - Made new validator error string available from libunbound for + applications. It is in result->why_bogus, a zero-terminated string. + unbound-host prints it by default if a result is bogus. + Also the errinf is public in module_qstate (for other modules). 7 October 2009: Wouter - retry for validation failure in DS and prime results. Less mem use. diff --git a/doc/libunbound.3.in b/doc/libunbound.3.in index ddb7eeb37..0d79254e2 100644 --- a/doc/libunbound.3.in +++ b/doc/libunbound.3.in @@ -351,6 +351,7 @@ The result of the DNS resolution and validation is returned as int nxdomain; /* true if nodata because name does not exist */ int secure; /* true if result is secure */ int bogus; /* true if a security failure happened */ + char* why_bogus; /* string with error if bogus */ }; .fi .P diff --git a/libunbound/context.c b/libunbound/context.c index dc6137920..f28307971 100644 --- a/libunbound/context.c +++ b/libunbound/context.c @@ -288,20 +288,27 @@ context_serialize_answer(struct ctx_query* q, int err, ldns_buffer* pkt, * o uint32 id * o uint32 error_code * o uint32 msg_security + * o uint32 length of why_bogus string (+1 for eos); 0 absent. + * o why_bogus_string * o the remainder is the answer msg from resolver lookup. * remainder can be length 0. */ size_t pkt_len = pkt?ldns_buffer_remaining(pkt):0; + size_t wlen = (pkt&&q->res->why_bogus)?strlen(q->res->why_bogus)+1:0; uint8_t* p; - *len = sizeof(uint32_t)*4 + pkt_len; + *len = sizeof(uint32_t)*5 + pkt_len + wlen; p = (uint8_t*)malloc(*len); if(!p) return NULL; ldns_write_uint32(p, UB_LIBCMD_ANSWER); ldns_write_uint32(p+sizeof(uint32_t), (uint32_t)q->querynum); ldns_write_uint32(p+2*sizeof(uint32_t), (uint32_t)err); ldns_write_uint32(p+3*sizeof(uint32_t), (uint32_t)q->msg_security); + ldns_write_uint32(p+4*sizeof(uint32_t), (uint32_t)wlen); + if(wlen > 0) + memmove(p+5*sizeof(uint32_t), q->res->why_bogus, wlen); if(pkt_len > 0) - memmove(p+4*sizeof(uint32_t), ldns_buffer_begin(pkt), pkt_len); + memmove(p+5*sizeof(uint32_t)+wlen, + ldns_buffer_begin(pkt), pkt_len); return p; } @@ -311,16 +318,31 @@ context_deserialize_answer(struct ub_ctx* ctx, { struct ctx_query* q = NULL ; int id; - if(len < 4*sizeof(uint32_t)) return NULL; + size_t wlen; + if(len < 5*sizeof(uint32_t)) return NULL; log_assert( ldns_read_uint32(p) == UB_LIBCMD_ANSWER); id = (int)ldns_read_uint32(p+sizeof(uint32_t)); q = (struct ctx_query*)rbtree_search(&ctx->queries, &id); if(!q) return NULL; *err = (int)ldns_read_uint32(p+2*sizeof(uint32_t)); q->msg_security = ldns_read_uint32(p+3*sizeof(uint32_t)); - if(len > 4*sizeof(uint32_t)) { - q->msg_len = len - 4*sizeof(uint32_t); - q->msg = (uint8_t*)memdup(p+4*sizeof(uint32_t), q->msg_len); + wlen = (size_t)ldns_read_uint32(p+4*sizeof(uint32_t)); + if(len > 5*sizeof(uint32_t) && wlen > 0) { + if(len >= 5*sizeof(uint32_t)+wlen) + q->res->why_bogus = (char*)memdup( + p+5*sizeof(uint32_t), wlen); + if(!q->res->why_bogus) { + /* pass malloc failure to the user callback */ + q->msg_len = 0; + *err = UB_NOMEM; + return q; + } + q->res->why_bogus[wlen-1] = 0; /* zero terminated for sure */ + } + if(len > 5*sizeof(uint32_t)+wlen) { + q->msg_len = len - 5*sizeof(uint32_t) - wlen; + q->msg = (uint8_t*)memdup(p+5*sizeof(uint32_t)+wlen, + q->msg_len); if(!q->msg) { /* pass malloc failure to the user callback */ q->msg_len = 0; diff --git a/libunbound/libunbound.c b/libunbound/libunbound.c index 6df145bb1..e22dd5571 100644 --- a/libunbound/libunbound.c +++ b/libunbound/libunbound.c @@ -691,6 +691,7 @@ ub_resolve_free(struct ub_result* result) free(result->data); free(result->len); free(result->answer_packet); + free(result->why_bogus); free(result); } diff --git a/libunbound/libworker.c b/libunbound/libworker.c index a35359c39..3491b79cc 100644 --- a/libunbound/libworker.c +++ b/libunbound/libworker.c @@ -438,8 +438,10 @@ libworker_enter_result(struct ub_result* res, ldns_buffer* buf, /** fillup fg results */ static void libworker_fillup_fg(struct ctx_query* q, int rcode, ldns_buffer* buf, - enum sec_status s) + enum sec_status s, char* why_bogus) { + if(why_bogus) + q->res->why_bogus = strdup(why_bogus); if(rcode != 0) { q->res->rcode = rcode; q->msg_security = s; @@ -460,13 +462,14 @@ libworker_fillup_fg(struct ctx_query* q, int rcode, ldns_buffer* buf, } void -libworker_fg_done_cb(void* arg, int rcode, ldns_buffer* buf, enum sec_status s) +libworker_fg_done_cb(void* arg, int rcode, ldns_buffer* buf, enum sec_status s, + char* why_bogus) { struct ctx_query* q = (struct ctx_query*)arg; /* fg query is done; exit comm base */ comm_base_exit(q->w->base); - libworker_fillup_fg(q, rcode, buf, s); + libworker_fillup_fg(q, rcode, buf, s, why_bogus); } /** setup qinfo and edns */ @@ -517,7 +520,7 @@ int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q) w->back->udp_buff, w->env->scratch)) { regional_free_all(w->env->scratch); libworker_fillup_fg(q, LDNS_RCODE_NOERROR, - w->back->udp_buff, sec_status_insecure); + w->back->udp_buff, sec_status_insecure, NULL); libworker_delete(w); free(qinfo.qname); return UB_NOERROR; @@ -540,7 +543,7 @@ int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q) /** add result to the bg worker result queue */ static void add_bg_result(struct libworker* w, struct ctx_query* q, ldns_buffer* pkt, - int err) + int err, char* reason) { uint8_t* msg = NULL; uint32_t len = 0; @@ -548,6 +551,8 @@ add_bg_result(struct libworker* w, struct ctx_query* q, ldns_buffer* pkt, /* serialize and delete unneeded q */ if(w->is_bg_thread) { lock_basic_lock(&w->ctx->cfglock); + if(reason) + q->res->why_bogus = strdup(reason); if(pkt) { q->msg_len = ldns_buffer_remaining(pkt); q->msg = memdup(ldns_buffer_begin(pkt), q->msg_len); @@ -559,6 +564,8 @@ add_bg_result(struct libworker* w, struct ctx_query* q, ldns_buffer* pkt, } else msg = context_serialize_answer(q, err, NULL, &len); lock_basic_unlock(&w->ctx->cfglock); } else { + if(reason) + q->res->why_bogus = strdup(reason); msg = context_serialize_answer(q, err, pkt, &len); (void)rbtree_delete(&w->ctx->queries, q->node.key); w->ctx->num_async--; @@ -576,7 +583,8 @@ add_bg_result(struct libworker* w, struct ctx_query* q, ldns_buffer* pkt, } void -libworker_bg_done_cb(void* arg, int rcode, ldns_buffer* buf, enum sec_status s) +libworker_bg_done_cb(void* arg, int rcode, ldns_buffer* buf, enum sec_status s, + char* why_bogus) { struct ctx_query* q = (struct ctx_query*)arg; @@ -597,7 +605,7 @@ libworker_bg_done_cb(void* arg, int rcode, ldns_buffer* buf, enum sec_status s) if(rcode != 0) { error_encode(buf, rcode, NULL, 0, BIT_RD, NULL); } - add_bg_result(q->w, q, buf, UB_NOERROR); + add_bg_result(q->w, q, buf, UB_NOERROR, why_bogus); } @@ -622,7 +630,7 @@ handle_newq(struct libworker* w, uint8_t* buf, uint32_t len) return; } if(!setup_qinfo_edns(w, q, &qinfo, &edns)) { - add_bg_result(w, q, NULL, UB_SYNTAX); + add_bg_result(w, q, NULL, UB_SYNTAX, NULL); return; } qid = 0; @@ -634,7 +642,7 @@ handle_newq(struct libworker* w, uint8_t* buf, uint32_t len) w->back->udp_buff, w->env->scratch)) { regional_free_all(w->env->scratch); q->msg_security = sec_status_insecure; - add_bg_result(w, q, w->back->udp_buff, UB_NOERROR); + add_bg_result(w, q, w->back->udp_buff, UB_NOERROR, NULL); free(qinfo.qname); return; } @@ -642,7 +650,7 @@ handle_newq(struct libworker* w, uint8_t* buf, uint32_t len) /* process new query */ if(!mesh_new_callback(w->env->mesh, &qinfo, qflags, &edns, w->back->udp_buff, qid, libworker_bg_done_cb, q)) { - add_bg_result(w, q, NULL, UB_NOMEM); + add_bg_result(w, q, NULL, UB_NOMEM, NULL); } free(qinfo.qname); } diff --git a/libunbound/libworker.h b/libunbound/libworker.h index 93a6ad7f3..74ae89443 100644 --- a/libunbound/libworker.h +++ b/libunbound/libworker.h @@ -158,11 +158,11 @@ void libworker_handle_result_write(struct tube* tube, uint8_t* msg, size_t len, /** mesh callback with fg results */ void libworker_fg_done_cb(void* arg, int rcode, ldns_buffer* buf, - enum sec_status s); + enum sec_status s, char* why_bogus); /** mesh callback with bg results */ void libworker_bg_done_cb(void* arg, int rcode, ldns_buffer* buf, - enum sec_status s); + enum sec_status s, char* why_bogus); /** * fill result from parsed message, on error fills servfail diff --git a/libunbound/unbound.h b/libunbound/unbound.h index abcefb57e..bbbe60387 100644 --- a/libunbound/unbound.h +++ b/libunbound/unbound.h @@ -181,6 +181,14 @@ struct ub_result { * This means the data is from a domain where data is not signed. */ int bogus; + + /** + * If the result is bogus this contains a string (zero terminated) + * that describes the failure. There may be other errors as well + * as the one described, the description may not be perfectly accurate. + * Is NULL if the result is not bogus. + */ + char* why_bogus; }; /** diff --git a/services/mesh.c b/services/mesh.c index 1b408e826..cc199d0da 100644 --- a/services/mesh.c +++ b/services/mesh.c @@ -472,7 +472,7 @@ mesh_state_cleanup(struct mesh_state* mstate) for(cb=mstate->cb_list; cb; cb=cb->next) { fptr_ok(fptr_whitelist_mesh_cb(cb->cb)); (*cb->cb)(cb->cb_arg, LDNS_RCODE_SERVFAIL, NULL, - sec_status_unchecked); + sec_status_unchecked, NULL); } } @@ -615,6 +615,7 @@ mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep, struct mesh_cb* r) { int secure; + char* reason = NULL; /* bogus messages are not made into servfail, sec_status passed * to the callback function */ if(rep && rep->security == sec_status_secure) @@ -622,10 +623,14 @@ mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep, else secure = 0; if(!rep && rcode == LDNS_RCODE_NOERROR) rcode = LDNS_RCODE_SERVFAIL; + if(!rcode && rep->security == sec_status_bogus) { + if(!(reason = errinf_to_str(&m->s))) + rcode = LDNS_RCODE_SERVFAIL; + } /* send the reply */ if(rcode) { fptr_ok(fptr_whitelist_mesh_cb(r->cb)); - (*r->cb)(r->cb_arg, rcode, r->buf, sec_status_unchecked); + (*r->cb)(r->cb_arg, rcode, r->buf, sec_status_unchecked, NULL); } else { size_t udp_size = r->edns.udp_size; ldns_buffer_clear(r->buf); @@ -640,13 +645,14 @@ mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep, { fptr_ok(fptr_whitelist_mesh_cb(r->cb)); (*r->cb)(r->cb_arg, LDNS_RCODE_SERVFAIL, r->buf, - sec_status_unchecked); + sec_status_unchecked, NULL); } else { fptr_ok(fptr_whitelist_mesh_cb(r->cb)); (*r->cb)(r->cb_arg, LDNS_RCODE_NOERROR, r->buf, - rep->security); + rep->security, reason); } } + free(reason); m->s.env->mesh->num_reply_addrs--; } diff --git a/services/mesh.h b/services/mesh.h index 2e2dca69f..5628f4c29 100644 --- a/services/mesh.h +++ b/services/mesh.h @@ -206,9 +206,10 @@ struct mesh_reply { /** * Mesh result callback func. - * called as func(cb_arg, rcode, buffer_with_reply, security); - * */ -typedef void (*mesh_cb_func_t)(void*, int, ldns_buffer*, enum sec_status); + * called as func(cb_arg, rcode, buffer_with_reply, security, why_bogus); + */ +typedef void (*mesh_cb_func_t)(void*, int, ldns_buffer*, enum sec_status, + char*); /** * Callback to result routine diff --git a/smallapp/unbound-host.c b/smallapp/unbound-host.c index d46c753fb..5aff65298 100644 --- a/smallapp/unbound-host.c +++ b/smallapp/unbound-host.c @@ -304,6 +304,8 @@ pretty_output(char* q, int t, int c, struct ub_result* result, int docname) if(verb > 0) printf(" %s", secstatus); printf("\n"); + if(result->bogus && result->why_bogus) + printf("%s\n", result->why_bogus); return; } if(docname && result->canonname && @@ -335,6 +337,8 @@ pretty_output(char* q, int t, int c, struct ub_result* result, int docname) printf(" %s\n", secstatus); } /* else: emptiness to indicate no data */ + if(result->bogus && result->why_bogus) + printf("%s\n", result->why_bogus); return; } i=0; @@ -346,6 +350,8 @@ pretty_output(char* q, int t, int c, struct ub_result* result, int docname) (size_t)result->len[i]); i++; } + if(result->bogus && result->why_bogus) + printf("%s\n", result->why_bogus); } /** perform a lookup and printout return if domain existed */ diff --git a/smallapp/worker_cb.c b/smallapp/worker_cb.c index f5f6f5335..02774c756 100644 --- a/smallapp/worker_cb.c +++ b/smallapp/worker_cb.c @@ -182,13 +182,15 @@ void libworker_handle_control_cmd(struct tube* ATTR_UNUSED(tube), } void libworker_fg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode), - ldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s)) + ldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s), + char* ATTR_UNUSED(why_bogus)) { log_assert(0); } void libworker_bg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode), - ldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s)) + ldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s), + char* ATTR_UNUSED(why_bogus)) { log_assert(0); } diff --git a/util/config_file.c b/util/config_file.c index 1a2a842b0..5aa30addb 100644 --- a/util/config_file.c +++ b/util/config_file.c @@ -47,6 +47,9 @@ #include "util/configparser.h" #include "util/net_help.h" #include "util/data/msgparse.h" +#include "util/module.h" +#include "util/regional.h" +#include "util/data/dname.h" /** global config during parsing */ struct config_parser_state* cfg_parser = 0; /** lex in file */ @@ -156,6 +159,7 @@ config_create() cfg->val_sig_skew_max = 86400; /* at most timezone settings trouble */ cfg->val_clean_additional = 1; cfg->val_log_level = 0; + cfg->val_log_squelch = 0; cfg->val_permissive_mode = 0; cfg->add_holddown = 30*24*3600; cfg->del_holddown = 30*24*3600; @@ -210,6 +214,8 @@ struct config_file* config_create_forlib() cfg->neg_cache_size = 100 * 1024; cfg->donotquery_localhost = 0; /* allow, so that you can ask a forward nameserver running on localhost */ + cfg->val_log_level = 2; /* to fill why_bogus with */ + cfg->val_log_squelch = 1; return cfg; } @@ -387,6 +393,9 @@ int config_set_option(struct config_file* cfg, const char* opt, } else if(strcmp(opt, "val-log-level:") == 0) { IS_NUMBER_OR_ZERO; cfg->val_log_level = atoi(val); + } else if(strcmp(opt, "val-log-squelch:") == 0) { + IS_YES_OR_NO; + cfg->val_log_squelch = (strcmp(val, "yes") == 0); } else if(strcmp(opt, "val-permissive-mode:") == 0) { IS_YES_OR_NO; cfg->val_permissive_mode = (strcmp(val, "yes") == 0); @@ -1095,3 +1104,113 @@ char* cfg_ptr_reverse(char* str) } return result; } + +void errinf(struct module_qstate* qstate, const char* str) +{ + struct config_strlist* p; + if(qstate->env->cfg->val_log_level < 2 || !str) + return; + p = (struct config_strlist*)regional_alloc(qstate->region, sizeof(*p)); + if(!p) { + log_err("malloc failure in validator-error-info string"); + return; + } + p->next = NULL; + p->str = regional_strdup(qstate->region, str); + if(!p->str) { + log_err("malloc failure in validator-error-info string"); + return; + } + /* add at end */ + if(qstate->errinf) { + struct config_strlist* q = qstate->errinf; + while(q->next) + q = q->next; + q->next = p; + } else qstate->errinf = p; +} + +void errinf_origin(struct module_qstate* qstate, struct sock_list *origin) +{ + struct sock_list* p; + if(qstate->env->cfg->val_log_level < 2) + return; + for(p=origin; p; p=p->next) { + char buf[256]; + if(p == origin) + snprintf(buf, sizeof(buf), "from "); + else snprintf(buf, sizeof(buf), "and from "); + if(p->len == 0) + snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), + "cache"); + else + addr_to_str(&p->addr, p->len, buf+strlen(buf), + sizeof(buf)-strlen(buf)); + errinf(qstate, buf); + } +} + +char* errinf_to_str(struct module_qstate* qstate) +{ + char buf[20480]; + char* p = buf; + size_t left = sizeof(buf); + struct config_strlist* s; + char dname[LDNS_MAX_DOMAINLEN+1]; + char* t = ldns_rr_type2str(qstate->qinfo.qtype); + char* c = ldns_rr_class2str(qstate->qinfo.qclass); + if(!t || !c) { + free(t); + free(c); + log_err("malloc failure in errinf_to_str"); + return NULL; + } + dname_str(qstate->qinfo.qname, dname); + snprintf(p, left, "validation failure <%s %s %s>:", dname, t, c); + free(t); + free(c); + left -= strlen(p); p += strlen(p); + if(!qstate->errinf) + snprintf(p, left, " misc failure"); + else for(s=qstate->errinf; s; s=s->next) { + snprintf(p, left, " %s", s->str); + left -= strlen(p); p += strlen(p); + } + p = strdup(buf); + if(!p) + log_err("malloc failure in errinf_to_str"); + return p; +} + +void errinf_rrset(struct module_qstate* qstate, struct ub_packed_rrset_key *rr) +{ + char buf[1024]; + char dname[LDNS_MAX_DOMAINLEN+1]; + char *t, *c; + if(qstate->env->cfg->val_log_level < 2 || !rr) + return; + t = ldns_rr_type2str(ntohs(rr->rk.type)); + c = ldns_rr_class2str(ntohs(rr->rk.rrset_class)); + if(!t || !c) { + free(t); + free(c); + log_err("malloc failure in errinf_rrset"); + return; + } + dname_str(qstate->qinfo.qname, dname); + snprintf(buf, sizeof(buf), "for <%s %s %s>", dname, t, c); + free(t); + free(c); + errinf(qstate, buf); +} + +void errinf_dname(struct module_qstate* qstate, const char* str, uint8_t* dname) +{ + char b[1024]; + char buf[LDNS_MAX_DOMAINLEN+1]; + if(qstate->env->cfg->val_log_level < 2 || !str || !dname) + return; + dname_str(dname, buf); + snprintf(b, sizeof(b), "%s %s", str, buf); + errinf(qstate, b); +} diff --git a/util/config_file.h b/util/config_file.h index 3ad6731b5..c8379db65 100644 --- a/util/config_file.h +++ b/util/config_file.h @@ -44,6 +44,9 @@ struct config_stub; struct config_strlist; struct config_str2list; +struct module_qstate; +struct sock_list; +struct ub_packed_rrset_key; /** * The configuration options. @@ -219,6 +222,8 @@ struct config_file { int val_clean_additional; /** log bogus messages by the validator */ int val_log_level; + /** squelch val_log_level to log - this is library goes to callback */ + int val_log_squelch; /** should validator allow bogus messages to go through */ int val_permissive_mode; /** nsec3 maximum iterations per key size, string */ @@ -469,6 +474,48 @@ char* fname_after_chroot(const char* fname, struct config_file* cfg, */ char* cfg_ptr_reverse(char* str); +/** + * Append text to the error info for validation. + * @param qstate: query state. + * @param str: copied into query region and appended. + * Failures to allocate are logged. + */ +void errinf(struct module_qstate* qstate, const char* str); + +/** + * Append text to error info: from 1.2.3.4 + * @param qstate: query state. + * @param origin: sock list with origin of trouble. + * Every element added. + * If NULL: nothing is added. + * if 0len element: 'from cache' is added. + */ +void errinf_origin(struct module_qstate* qstate, struct sock_list *origin); + +/** + * Append text to error info: for RRset name type class + * @param qstate: query state. + * @param rr: rrset_key. + */ +void errinf_rrset(struct module_qstate* qstate, struct ub_packed_rrset_key *rr); + +/** + * Append text to error info: str dname + * @param qstate: query state. + * @param str: explanation string + * @param dname: the dname. + */ +void errinf_dname(struct module_qstate* qstate, const char* str, + uint8_t* dname); + +/** + * Create error info in string + * @param qstate: query state. + * @return string or NULL on malloc failure (already logged). + * This string is malloced and has to be freed by caller. + */ +char* errinf_to_str(struct module_qstate* qstate); + /** * Used during options parsing */ diff --git a/util/module.h b/util/module.h index f320b02c1..b27e2d1bb 100644 --- a/util/module.h +++ b/util/module.h @@ -299,6 +299,8 @@ struct module_qstate { struct sock_list* blacklist; /** region for this query. Cleared when query process finishes. */ struct regional* region; + /** failure reason information if val-log-level is high */ + struct config_strlist* errinf; /** which module is executing */ int curmod; diff --git a/validator/autotrust.c b/validator/autotrust.c index 1c99fb622..c079aef61 100644 --- a/validator/autotrust.c +++ b/validator/autotrust.c @@ -1925,7 +1925,8 @@ autr_debug_print(struct val_anchors* anchors) } void probe_answer_cb(void* arg, int ATTR_UNUSED(rcode), - ldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(sec)) + ldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(sec), + char* ATTR_UNUSED(why_bogus)) { /* retry was set before the query was done, * re-querytime is set when query succeeded, but that may not diff --git a/validator/autotrust.h b/validator/autotrust.h index cb2c6e77b..61b6a9dc8 100644 --- a/validator/autotrust.h +++ b/validator/autotrust.h @@ -199,6 +199,6 @@ void autr_debug_print(struct val_anchors* anchors); /** callback for query answer to 5011 probe */ void probe_answer_cb(void* arg, int rcode, ldns_buffer* buf, - enum sec_status sec); + enum sec_status sec, char* errinf); #endif /* VALIDATOR_AUTOTRUST_H */ diff --git a/validator/val_utils.c b/validator/val_utils.c index e9addfdd5..d582f87df 100644 --- a/validator/val_utils.c +++ b/validator/val_utils.c @@ -850,120 +850,6 @@ void val_blacklist(struct sock_list** blacklist, struct regional* region, else sock_list_merge(blacklist, region, origin); } -void val_errinf(struct module_qstate* qstate, struct val_qstate* vq, - const char* str) -{ - struct config_strlist* p; - if(qstate->env->cfg->val_log_level < 2 || !str) - return; - p = (struct config_strlist*)regional_alloc(qstate->region, sizeof(*p)); - if(!p) { - log_err("malloc failure in validator-error-info string"); - return; - } - p->next = NULL; - p->str = regional_strdup(qstate->region, str); - if(!p->str) { - log_err("malloc failure in validator-error-info string"); - return; - } - /* add at end */ - if(vq->errinf) { - struct config_strlist* q = vq->errinf; - while(q->next) - q = q->next; - q->next = p; - } else vq->errinf = p; -} - -void val_errinf_origin(struct module_qstate* qstate, struct val_qstate* vq, - struct sock_list *origin) -{ - struct sock_list* p; - if(qstate->env->cfg->val_log_level < 2) - return; - for(p=origin; p; p=p->next) { - char buf[256]; - if(p == origin) - snprintf(buf, sizeof(buf), "from "); - else snprintf(buf, sizeof(buf), "and from "); - if(p->len == 0) - snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), - "cache"); - else - addr_to_str(&p->addr, p->len, buf+strlen(buf), - sizeof(buf)-strlen(buf)); - val_errinf(qstate, vq, buf); - } -} - -char* val_errinf_to_str(struct module_qstate* qstate, struct val_qstate* vq) -{ - char buf[20480]; - char* p = buf; - size_t left = sizeof(buf); - struct config_strlist* s; - char dname[LDNS_MAX_DOMAINLEN+1]; - char* t = ldns_rr_type2str(qstate->qinfo.qtype); - char* c = ldns_rr_class2str(qstate->qinfo.qclass); - if(!t || !c) { - free(t); - free(c); - log_err("malloc failure in errinf_to_str"); - return NULL; - } - dname_str(qstate->qinfo.qname, dname); - snprintf(p, left, "validation failure <%s %s %s>:", dname, t, c); - free(t); - free(c); - left -= strlen(p); p += strlen(p); - if(!vq->errinf) - snprintf(p, left, " misc failure"); - else for(s=vq->errinf; s; s=s->next) { - snprintf(p, left, " %s", s->str); - left -= strlen(p); p += strlen(p); - } - p = strdup(buf); - if(!p) - log_err("malloc failure in errinf_to_str"); - return p; -} - -void val_errinf_rrset(struct module_qstate* qstate, struct val_qstate* vq, - struct ub_packed_rrset_key *rr) -{ - char buf[1024]; - char dname[LDNS_MAX_DOMAINLEN+1]; - char *t, *c; - if(qstate->env->cfg->val_log_level < 2 || !rr) - return; - t = ldns_rr_type2str(ntohs(rr->rk.type)); - c = ldns_rr_class2str(ntohs(rr->rk.rrset_class)); - if(!t || !c) { - free(t); - free(c); - log_err("malloc failure in errinf_rrset"); - return; - } - dname_str(qstate->qinfo.qname, dname); - snprintf(buf, sizeof(buf), "for <%s %s %s>", dname, t, c); - free(t); - free(c); - val_errinf(qstate, vq, buf); -} - -void val_errinf_dname(struct module_qstate* qstate, struct val_qstate* vq, - const char* str, uint8_t* dname) -{ - char b[1024]; - char buf[LDNS_MAX_DOMAINLEN+1]; - if(qstate->env->cfg->val_log_level < 2 || !str || !dname) - return; - dname_str(dname, buf); - snprintf(b, sizeof(b), "%s %s", str, buf); - val_errinf(qstate, vq, b); -} - int val_has_signed_nsecs(struct reply_info* rep, char** reason) { size_t i, num_nsec = 0, num_nsec3 = 0; diff --git a/validator/val_utils.h b/validator/val_utils.h index 3be69a35f..11c7e0969 100644 --- a/validator/val_utils.h +++ b/validator/val_utils.h @@ -52,8 +52,6 @@ struct regional; struct val_anchors; struct rrset_cache; struct sock_list; -struct module_qstate; -struct val_qstate; /** * Response classifications for the validator. The different types of proofs. @@ -308,56 +306,6 @@ const char* val_classification_to_string(enum val_classification subtype); void val_blacklist(struct sock_list** blacklist, struct regional* region, struct sock_list* origin, int cross); -/** - * Append text to the error info for validation. - * @param qstate: query state. - * @param vq: validator state. - * @param str: copied into query region and appended. - * Failures to allocate are logged. - */ -void val_errinf(struct module_qstate* qstate, struct val_qstate* vq, - const char* str); - -/** - * Append text to error info: from 1.2.3.4 - * @param qstate: query state. - * @param vq: validator state. - * @param origin: sock list with origin of trouble. - * Every element added. - * If NULL: nothing is added. - * if 0len element: 'from cache' is added. - */ -void val_errinf_origin(struct module_qstate* qstate, struct val_qstate* vq, - struct sock_list *origin); - -/** - * Append text to error info: for RRset name type class - * @param qstate: query state. - * @param vq: validator state. - * @param rr: rrset_key. - */ -void val_errinf_rrset(struct module_qstate* qstate, struct val_qstate* vq, - struct ub_packed_rrset_key *rr); - -/** - * Append text to error info: str dname - * @param qstate: query state. - * @param vq: validator state. - * @param str: explanation string - * @param dname: the dname. - */ -void val_errinf_dname(struct module_qstate* qstate, struct val_qstate* vq, - const char* str, uint8_t* dname); - -/** - * Create error info in string - * @param qstate: query state. (for query name) - * @param vq: validator state. - * @return string or NULL on malloc failure (already logged). - * This string is malloced and has to be freed by caller. - */ -char* val_errinf_to_str(struct module_qstate* qstate, struct val_qstate* vq); - /** * check if has dnssec info, and if it has signed nsecs. gives error reason. * @param rep: reply to check. diff --git a/validator/validator.c b/validator/validator.c index f388e0dbc..4f2e41b24 100644 --- a/validator/validator.c +++ b/validator/validator.c @@ -410,7 +410,6 @@ prime_trust_anchor(struct module_qstate* qstate, struct val_qstate* vq, * completed. * * @param qstate: query state. - * @param vq: validator query state. * @param env: module env for verify. * @param ve: validator env for verify. * @param qchase: query that was made. @@ -421,8 +420,8 @@ prime_trust_anchor(struct module_qstate* qstate, struct val_qstate* vq, * fail to verify. The message is then set to bogus. */ static int -validate_msg_signatures(struct module_qstate* qstate, struct val_qstate* vq, - struct module_env* env, struct val_env* ve, struct query_info* qchase, +validate_msg_signatures(struct module_qstate* qstate, struct module_env* env, + struct val_env* ve, struct query_info* qchase, struct reply_info* chase_reply, struct key_entry_key* key_entry) { uint8_t* sname; @@ -458,12 +457,12 @@ validate_msg_signatures(struct module_qstate* qstate, struct val_qstate* vq, log_nametypeclass(VERB_QUERY, "validator: response " "has failed ANSWER rrset:", s->rk.dname, ntohs(s->rk.type), ntohs(s->rk.rrset_class)); - val_errinf(qstate, vq, reason); + errinf(qstate, reason); if(ntohs(s->rk.type) == LDNS_RR_TYPE_CNAME) - val_errinf(qstate, vq, "for CNAME"); + errinf(qstate, "for CNAME"); else if(ntohs(s->rk.type) == LDNS_RR_TYPE_DNAME) - val_errinf(qstate, vq, "for DNAME"); - val_errinf_origin(qstate, vq, qstate->reply_origin); + errinf(qstate, "for DNAME"); + errinf_origin(qstate, qstate->reply_origin); chase_reply->security = sec_status_bogus; return 0; } @@ -487,9 +486,9 @@ validate_msg_signatures(struct module_qstate* qstate, struct val_qstate* vq, log_nametypeclass(VERB_QUERY, "validator: response " "has failed AUTHORITY rrset:", s->rk.dname, ntohs(s->rk.type), ntohs(s->rk.rrset_class)); - val_errinf(qstate, vq, reason); - val_errinf_rrset(qstate, vq, s); - val_errinf_origin(qstate, vq, qstate->reply_origin); + errinf(qstate, reason); + errinf_rrset(qstate, s); + errinf_origin(qstate, qstate->reply_origin); chase_reply->security = sec_status_bogus; return 0; } @@ -1511,7 +1510,7 @@ processValidate(struct module_qstate* qstate, struct val_qstate* vq, "of trust to keys for", vq->key_entry->name, LDNS_RR_TYPE_DNSKEY, vq->key_entry->key_class); vq->chase_reply->security = sec_status_bogus; - val_errinf(qstate, vq, "while building chain of trust"); + errinf(qstate, "while building chain of trust"); return 1; } @@ -1522,8 +1521,8 @@ processValidate(struct module_qstate* qstate, struct val_qstate* vq, "signer name", &vq->qchase); verbose(VERB_DETAIL, "Could not establish validation of " "INSECURE status of unsigned response."); - val_errinf(qstate, vq, "no signatures"); - val_errinf_origin(qstate, vq, qstate->reply_origin); + errinf(qstate, "no signatures"); + errinf_origin(qstate, qstate->reply_origin); vq->chase_reply->security = sec_status_bogus; return 1; } @@ -1532,7 +1531,7 @@ processValidate(struct module_qstate* qstate, struct val_qstate* vq, /* check signatures in the message; * answer and authority must be valid, additional is only checked. */ - if(!validate_msg_signatures(qstate, vq, qstate->env, ve, &vq->qchase, + if(!validate_msg_signatures(qstate, qstate->env, ve, &vq->qchase, vq->chase_reply, vq->key_entry)) { /* workaround bad recursor out there that truncates (even * with EDNS4k) to 512 by removing RRSIG from auth section @@ -1549,7 +1548,7 @@ processValidate(struct module_qstate* qstate, struct val_qstate* vq, vq->chase_reply->ar_numrrsets = 0; vq->chase_reply->rrset_count = vq->chase_reply->an_numrrsets; - vq->errinf = NULL; + qstate->errinf = NULL; } else { verbose(VERB_DETAIL, "Validate: message contains " @@ -1629,11 +1628,10 @@ processValidate(struct module_qstate* qstate, struct val_qstate* vq, } if(vq->chase_reply->security == sec_status_bogus) { if(subtype == VAL_CLASS_POSITIVE) - val_errinf(qstate, vq, "wildcard"); - else val_errinf(qstate, vq, - val_classification_to_string(subtype)); - val_errinf(qstate, vq, "proof failed"); - val_errinf_origin(qstate, vq, qstate->reply_origin); + errinf(qstate, "wildcard"); + else errinf(qstate, val_classification_to_string(subtype)); + errinf(qstate, "proof failed"); + errinf_origin(qstate, qstate->reply_origin); } return 1; @@ -1884,12 +1882,13 @@ processFinished(struct module_qstate* qstate, struct val_qstate* vq, } vq->orig_msg->rep->ttl = ve->bogus_ttl; - if(qstate->env->cfg->val_log_level >= 1) { + if(qstate->env->cfg->val_log_level >= 1 && + !qstate->env->cfg->val_log_squelch) { if(qstate->env->cfg->val_log_level < 2) log_query_info(0, "validation failure", &qstate->qinfo); else { - char* err = val_errinf_to_str(qstate, vq); + char* err = errinf_to_str(qstate); if(err) log_info(err); free(err); } @@ -2157,9 +2156,7 @@ primeResponseToKE(struct ub_packed_rrset_key* dnskey_rrset, "could not fetch DNSKEY rrset", ta->name, LDNS_RR_TYPE_DNSKEY, ta->dclass); if(qstate->env->cfg->harden_dnssec_stripped) { - struct val_qstate* vq = (struct val_qstate*) - qstate->minfo[id]; - val_errinf(qstate, vq, "no DNSKEY rrset"); + errinf(qstate, "no DNSKEY rrset"); kkey = key_entry_create_bad(qstate->region, ta->name, ta->namelen, ta->dclass); } else kkey = key_entry_create_null(qstate->region, ta->name, @@ -2209,9 +2206,7 @@ primeResponseToKE(struct ub_packed_rrset_key* dnskey_rrset, /* NOTE: in this case, we should probably reject the trust * anchor for longer, perhaps forever. */ if(qstate->env->cfg->harden_dnssec_stripped) { - struct val_qstate* vq = (struct val_qstate*) - qstate->minfo[id]; - val_errinf(qstate, vq, reason); + errinf(qstate, reason); kkey = key_entry_create_bad(qstate->region, ta->name, ta->namelen, ta->dclass); } else kkey = key_entry_create_null(qstate->region, ta->name, @@ -2258,8 +2253,8 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq, char* rc = ldns_pkt_rcode2str(rcode); /* errors here pretty much break validation */ verbose(VERB_DETAIL, "DS response was error, thus bogus"); - val_errinf(qstate, vq, rc); - val_errinf(qstate, vq, "no DS"); + errinf(qstate, rc); + errinf(qstate, "no DS"); free(rc); goto return_bogus; } @@ -2274,7 +2269,7 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq, if(!ds) { log_warn("internal error: POSITIVE DS response was " "missing DS."); - val_errinf(qstate, vq, "no DS record"); + errinf(qstate, "no DS record"); goto return_bogus; } /* Verify only returns BOGUS or SECURE. If the rrset is @@ -2284,7 +2279,7 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq, if(sec != sec_status_secure) { verbose(VERB_DETAIL, "DS rrset in DS response did " "not verify"); - val_errinf(qstate, vq, reason); + errinf(qstate, reason); goto return_bogus; } @@ -2315,7 +2310,7 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq, /* make sure there are NSECs or NSEC3s with signatures */ if(!val_has_signed_nsecs(msg->rep, &reason)) { verbose(VERB_ALGO, "no NSECs: %s", reason); - val_errinf(qstate, vq, reason); + errinf(qstate, reason); goto return_bogus; } @@ -2345,7 +2340,7 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq, case sec_status_bogus: verbose(VERB_DETAIL, "NSEC RRset for the " "referral did not prove no DS."); - val_errinf(qstate, vq, reason); + errinf(qstate, reason); goto return_bogus; case sec_status_unchecked: default: @@ -2373,7 +2368,7 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq, case sec_status_bogus: verbose(VERB_DETAIL, "NSEC3s for the " "referral did not prove no DS."); - val_errinf(qstate, vq, reason); + errinf(qstate, reason); goto return_bogus; case sec_status_insecure: case sec_status_unchecked: @@ -2386,20 +2381,19 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq, * this is BOGUS. */ verbose(VERB_DETAIL, "DS %s ran out of options, so return " "bogus", val_classification_to_string(subtype)); - val_errinf(qstate, vq, "no DS but also no proof of that"); + errinf(qstate, "no DS but also no proof of that"); goto return_bogus; } else { verbose(VERB_QUERY, "Encountered an unhandled type of " "DS response, thus bogus."); - val_errinf(qstate, vq, "no DS and "); + errinf(qstate, "no DS and "); if(FLAGS_GET_RCODE(msg->rep->flags) != LDNS_RCODE_NOERROR) { char* rc = ldns_pkt_rcode2str( FLAGS_GET_RCODE(msg->rep->flags)); - val_errinf(qstate, vq, rc); + errinf(qstate, rc); free(rc); - } else val_errinf(qstate, vq, - val_classification_to_string(subtype)); - val_errinf(qstate, vq, "message fails to prove that"); + } else errinf(qstate, val_classification_to_string(subtype)); + errinf(qstate, "message fails to prove that"); goto return_bogus; } return_bogus: @@ -2464,12 +2458,12 @@ process_ds_response(struct module_qstate* qstate, struct val_qstate* vq, && vq->restart_count < VAL_MAX_RESTART_COUNT) { vq->empty_DS_name = olds; val_blacklist(&vq->chain_blacklist, qstate->region, origin, 1); - vq->errinf = NULL; + qstate->errinf = NULL; vq->restart_count++; } else { if(key_entry_isbad(dske)) { - val_errinf_origin(qstate, vq, origin); - val_errinf_dname(qstate, vq, "for DS", qinfo->qname); + errinf_origin(qstate, origin); + errinf_dname(qstate, "for DS", qinfo->qname); } /* NOTE: the reason for the DS to be not good (that is, * either bad or null) should have been logged by @@ -2516,7 +2510,7 @@ process_dnskey_response(struct module_qstate* qstate, struct val_qstate* vq, if(vq->restart_count < VAL_MAX_RESTART_COUNT) { val_blacklist(&vq->chain_blacklist, qstate->region, origin, 1); - vq->errinf = NULL; + qstate->errinf = NULL; vq->restart_count++; return; } @@ -2526,9 +2520,9 @@ process_dnskey_response(struct module_qstate* qstate, struct val_qstate* vq, log_err("alloc failure in missing dnskey response"); /* key_entry is NULL for failure in Validate */ } - val_errinf(qstate, vq, "No DNSKEY record"); - val_errinf_origin(qstate, vq, origin); - val_errinf_dname(qstate, vq, "for key", qinfo->qname); + errinf(qstate, "No DNSKEY record"); + errinf_origin(qstate, origin); + errinf_dname(qstate, "for key", qinfo->qname); vq->state = VAL_VALIDATE_STATE; return; } @@ -2553,23 +2547,23 @@ process_dnskey_response(struct module_qstate* qstate, struct val_qstate* vq, if(vq->restart_count < VAL_MAX_RESTART_COUNT) { val_blacklist(&vq->chain_blacklist, qstate->region, origin, 1); - vq->errinf = NULL; + qstate->errinf = NULL; vq->restart_count++; vq->key_entry = old; return; } verbose(VERB_DETAIL, "Did not match a DS to a DNSKEY, " "thus bogus."); - val_errinf(qstate, vq, reason); - val_errinf_origin(qstate, vq, origin); - val_errinf_dname(qstate, vq, "for key", qinfo->qname); + errinf(qstate, reason); + errinf_origin(qstate, origin); + errinf_dname(qstate, "for key", qinfo->qname); } vq->chain_blacklist = NULL; vq->state = VAL_VALIDATE_STATE; return; } vq->chain_blacklist = NULL; - vq->errinf = NULL; + qstate->errinf = NULL; /* The DNSKEY validated, so cache it as a trusted key rrset. */ key_cache_insert(ve->kcache, vq->key_entry); @@ -2628,15 +2622,15 @@ process_prime_response(struct module_qstate* qstate, struct val_qstate* vq, && vq->restart_count < VAL_MAX_RESTART_COUNT) { val_blacklist(&vq->chain_blacklist, qstate->region, origin, 1); - vq->errinf = NULL; + qstate->errinf = NULL; vq->restart_count++; vq->key_entry = NULL; vq->state = VAL_INIT_STATE; return; } vq->chain_blacklist = NULL; - val_errinf_origin(qstate, vq, origin); - val_errinf_dname(qstate, vq, "for trust anchor", ta->name); + errinf_origin(qstate, origin); + errinf_dname(qstate, "for trust anchor", ta->name); /* store the freshly primed entry in the cache */ key_cache_insert(ve->kcache, vq->key_entry); } diff --git a/validator/validator.h b/validator/validator.h index b4d0bf324..8ccf25307 100644 --- a/validator/validator.h +++ b/validator/validator.h @@ -237,9 +237,6 @@ struct val_qstate { dlv_ask_higher, /* ask again */ dlv_there_is_no_dlv /* got no DLV, sure of it */ } dlv_status; - - /** failure reason information if val-log-level is high */ - struct config_strlist* errinf; }; /**