- 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).
	Binary API different. bumped library ABI version.


git-svn-id: file:///svn/unbound/trunk@1874 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2009-10-08 17:05:53 +00:00
parent d7868e4077
commit f42d27e1a2
23 changed files with 329 additions and 272 deletions

31
configure vendored
View file

@ -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

View file

@ -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

View file

@ -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);
}

View file

@ -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.

View file

@ -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

View file

@ -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;

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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

View file

@ -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;
};
/**

View file

@ -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--;
}

View file

@ -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

View file

@ -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 */

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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
*/

View file

@ -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;

View file

@ -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

View file

@ -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 */

View file

@ -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;

View file

@ -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.

View file

@ -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);
}

View file

@ -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;
};
/**