Trust anchors in wireformat in context

This commit is contained in:
Willem Toorop 2015-06-30 14:43:52 +02:00
parent 996b09ba2b
commit 41cf772fb3
8 changed files with 234 additions and 164 deletions

View File

@ -771,6 +771,7 @@ getdns_context_create_with_extended_memory_functions(
getdns_return_t r; getdns_return_t r;
struct getdns_context *result = NULL; struct getdns_context *result = NULL;
mf_union mf; mf_union mf;
gldns_buffer gbuf;
if (!context || !malloc || !realloc || !free) if (!context || !malloc || !realloc || !free)
return GETDNS_RETURN_INVALID_PARAMETER; return GETDNS_RETURN_INVALID_PARAMETER;
@ -815,7 +816,30 @@ getdns_context_create_with_extended_memory_functions(
result->append_name = GETDNS_APPEND_NAME_ALWAYS; result->append_name = GETDNS_APPEND_NAME_ALWAYS;
result->suffix = NULL; result->suffix = NULL;
result->dnssec_trust_anchors = NULL; gldns_buffer_init_frm_data(&gbuf, result->trust_anchors_spc
, sizeof(result->trust_anchors_spc));
if (!_getdns_parse_ta_file(NULL, &gbuf)) {
result->trust_anchors = NULL;
result->trust_anchors_len = 0;
} else if ((result->trust_anchors_len = gldns_buffer_position(&gbuf))
> sizeof(result->trust_anchors_spc)) {
if ((result->trust_anchors = GETDNS_XMALLOC(
result->mf, uint8_t, result->trust_anchors_len))) {
gldns_buffer_init_frm_data(&gbuf
, result->trust_anchors
, result->trust_anchors_len);
if (!_getdns_parse_ta_file(NULL, &gbuf)) {
result->trust_anchors = NULL;
result->trust_anchors_len = 0;
}
}
} else
result->trust_anchors = result->trust_anchors_spc;
result->upstreams = NULL; result->upstreams = NULL;
result->edns_extended_rcode = 0; result->edns_extended_rcode = 0;
@ -828,7 +852,7 @@ getdns_context_create_with_extended_memory_functions(
goto error; goto error;
result->fchg_resolvconf = NULL; result->fchg_resolvconf = NULL;
result->fchg_hosts = NULL; result->fchg_hosts = NULL;
if (set_from_os && (r = set_os_defaults(result))) if (set_from_os && (r = set_os_defaults(result)))
goto error; goto error;
@ -840,12 +864,6 @@ getdns_context_create_with_extended_memory_functions(
result->limit_outstanding_queries = 0; result->limit_outstanding_queries = 0;
result->return_dnssec_status = GETDNS_EXTENSION_FALSE; result->return_dnssec_status = GETDNS_EXTENSION_FALSE;
if (! (result->dnssec_trust_anchors =
getdns_list_create_with_context(result)))
goto error;
result->has_ta = priv_getdns_parse_ta_file(
NULL, result->dnssec_trust_anchors);
/* unbound context is initialized here */ /* unbound context is initialized here */
/* Unbound needs SSL to be init'ed this early when TLS is used. However we /* Unbound needs SSL to be init'ed this early when TLS is used. However we
* don't know that till later so we will have to do this every time. */ * don't know that till later so we will have to do this every time. */
@ -944,7 +962,10 @@ getdns_context_destroy(struct getdns_context *context)
getdns_list_destroy(context->dns_root_servers); getdns_list_destroy(context->dns_root_servers);
getdns_list_destroy(context->suffix); getdns_list_destroy(context->suffix);
getdns_list_destroy(context->dnssec_trust_anchors);
if (context->trust_anchors &&
context->trust_anchors != context->trust_anchors_spc)
GETDNS_FREE(context->mf, context->trust_anchors);
/* destroy the contexts */ /* destroy the contexts */
if (context->unbound_ctx) if (context->unbound_ctx)
@ -1076,7 +1097,7 @@ rebuild_ub_ctx(struct getdns_context* context) {
context->dns_transport); context->dns_transport);
/* Set default trust anchor */ /* Set default trust anchor */
if (context->has_ta) { if (context->trust_anchors) {
(void) ub_ctx_add_ta_file( (void) ub_ctx_add_ta_file(
context->unbound_ctx, TRUST_ANCHOR_FILE); context->unbound_ctx, TRUST_ANCHOR_FILE);
} }
@ -1442,23 +1463,26 @@ getdns_context_set_suffix(struct getdns_context *context, struct getdns_list * v
* *
*/ */
getdns_return_t getdns_return_t
getdns_context_set_dnssec_trust_anchors(struct getdns_context *context, getdns_context_set_dnssec_trust_anchors(
struct getdns_list * value) getdns_context *context, getdns_list *value)
{ {
struct getdns_list *copy = NULL; RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
if (value != NULL) {
if (getdns_list_copy(value, &copy) != GETDNS_RETURN_GOOD) {
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
}
value = copy;
}
getdns_list_destroy(context->dnssec_trust_anchors);
context->dnssec_trust_anchors = value;
dispatch_updated(context, GETDNS_CONTEXT_CODE_DNSSEC_TRUST_ANCHORS); if (context->trust_anchors &&
context->trust_anchors != context->trust_anchors_spc)
GETDNS_FREE(context->mf, context->trust_anchors);
return GETDNS_RETURN_GOOD; if (value) {
context->trust_anchors_len = sizeof(context->trust_anchors_spc);
context->trust_anchors = _getdns_list2wire(value,
context->trust_anchors_spc, &context->trust_anchors_len,
&context->mf);
} else {
context->trust_anchors = NULL;
context->trust_anchors_len = 0;
}
dispatch_updated(context, GETDNS_CONTEXT_CODE_DNSSEC_TRUST_ANCHORS);
return GETDNS_RETURN_GOOD;
} /* getdns_context_set_dnssec_trust_anchors */ } /* getdns_context_set_dnssec_trust_anchors */
static void static void
@ -2482,15 +2506,23 @@ getdns_context_get_suffix(getdns_context *context, getdns_list **value) {
} }
getdns_return_t getdns_return_t
getdns_context_get_dnssec_trust_anchors(getdns_context *context, getdns_context_get_dnssec_trust_anchors(
getdns_list **value) { getdns_context *context, getdns_list **value)
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); {
RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER); RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
*value = NULL; RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER);
if (context->dnssec_trust_anchors) {
return getdns_list_copy(context->dnssec_trust_anchors, value); if (context->trust_anchors) {
} if ((*value = getdns_list_create_with_context(context)))
return GETDNS_RETURN_GOOD; _getdns_wire2list( context->trust_anchors
, context->trust_anchors_len
, *value);
else
return GETDNS_RETURN_MEMORY_ERROR;
} else
*value = NULL;
return GETDNS_RETURN_GOOD;
} }
getdns_return_t getdns_return_t

View File

@ -135,7 +135,8 @@ struct getdns_context {
struct getdns_list *dns_root_servers; struct getdns_list *dns_root_servers;
getdns_append_name_t append_name; getdns_append_name_t append_name;
struct getdns_list *suffix; struct getdns_list *suffix;
struct getdns_list *dnssec_trust_anchors; uint8_t *trust_anchors;
size_t trust_anchors_len;
getdns_upstreams *upstreams; getdns_upstreams *upstreams;
getdns_transport_t dns_transport; getdns_transport_t dns_transport;
getdns_base_transport_t dns_base_transports[GETDNS_BASE_TRANSPORT_MAX]; getdns_base_transport_t dns_base_transports[GETDNS_BASE_TRANSPORT_MAX];
@ -163,7 +164,7 @@ struct getdns_context {
/* A tree to hold local host information*/ /* A tree to hold local host information*/
getdns_rbtree_t local_hosts; getdns_rbtree_t local_hosts;
int has_ta; /* No DNSSEC without trust anchor */
int return_dnssec_status; int return_dnssec_status;
/* which resolution type the contexts are configured for /* which resolution type the contexts are configured for
@ -189,6 +190,8 @@ struct getdns_context {
struct filechg *fchg_resolvconf; struct filechg *fchg_resolvconf;
struct filechg *fchg_hosts; struct filechg *fchg_hosts;
uint8_t trust_anchors_spc[1024];
}; /* getdns_context */ }; /* getdns_context */
/** internal functions **/ /** internal functions **/

View File

@ -70,6 +70,10 @@ struct getdns_dict
struct mem_funcs mf; struct mem_funcs mf;
}; };
inline struct getdns_dict *_getdns_dict_create_with_mf(struct mem_funcs *mf)
{ return getdns_dict_create_with_extended_memory_functions(
mf->mf_arg, mf->mf.ext.malloc, mf->mf.ext.realloc, mf->mf.ext.free); }
#endif #endif
/* dict.h */ /* dict.h */

View File

@ -67,58 +67,6 @@ static int is_subdomain(
return *parent == 0; return *parent == 0;
} }
static void _getdns_list2wire(gldns_buffer *buf, getdns_list *l)
{
getdns_dict *rr_dict;
getdns_return_t r;
size_t i, pkt_start, ancount;
uint32_t qtype, qclass;
getdns_bindata *qname;
pkt_start = gldns_buffer_position(buf);
/* Empty header */
gldns_buffer_write_u32(buf, 0);
gldns_buffer_write_u32(buf, 0);
gldns_buffer_write_u32(buf, 0);
for ( i = 0
; (r = getdns_list_get_dict(l, i, &rr_dict))
!= GETDNS_RETURN_NO_SUCH_LIST_ITEM
; i++ ) {
if (r) {
if (r == GETDNS_RETURN_WRONG_TYPE_REQUESTED)
continue;
else
break;
}
if (getdns_dict_get_int(rr_dict, "qtype", &qtype) ||
getdns_dict_get_bindata(rr_dict, "qname", &qname))
continue;
(void) getdns_dict_get_int(rr_dict, "qclass", &qclass);
gldns_buffer_write(buf, qname->data, qname->size);
gldns_buffer_write_u16(buf, (uint16_t)qtype);
gldns_buffer_write_u16(buf, (uint16_t)qclass);
gldns_buffer_write_u16_at(buf, pkt_start+GLDNS_QDCOUNT_OFF, 1);
break;
}
for ( i = 0, ancount = 0
; (r = getdns_list_get_dict(l, i, &rr_dict))
!= GETDNS_RETURN_NO_SUCH_LIST_ITEM
; i++ ) {
if (r) {
if (r == GETDNS_RETURN_WRONG_TYPE_REQUESTED)
continue;
else
break;
}
if (priv_getdns_rr_dict2wire(rr_dict, buf) == GETDNS_RETURN_GOOD)
ancount++;
}
gldns_buffer_write_u16_at(buf, pkt_start+GLDNS_ANCOUNT_OFF, ancount);
}
#if defined(SEC_DEBUG) && SEC_DEBUG #if defined(SEC_DEBUG) && SEC_DEBUG
inline static void debug_sec_print_rr(const char *msg, priv_getdns_rr_iter *rr) inline static void debug_sec_print_rr(const char *msg, priv_getdns_rr_iter *rr)
{ {
@ -1332,8 +1280,9 @@ static void append_rrs2val_chain_list(getdns_context *ctxt,
for ( rr = rrtype_iter_init(&rr_spc, rrset) for ( rr = rrtype_iter_init(&rr_spc, rrset)
; rr; rr = rrtype_iter_next(rr)) { ; rr; rr = rrtype_iter_next(rr)) {
rr_dict = priv_getdns_rr_iter2rr_dict(ctxt, &rr->rr_i); if (!(rr_dict = priv_getdns_rr_iter2rr_dict(
if (!rr_dict) continue; &ctxt->mf, &rr->rr_i)))
continue;
(void)getdns_list_append_dict(val_chain_list, rr_dict); (void)getdns_list_append_dict(val_chain_list, rr_dict);
getdns_dict_destroy(rr_dict); getdns_dict_destroy(rr_dict);
@ -1341,8 +1290,9 @@ static void append_rrs2val_chain_list(getdns_context *ctxt,
for ( rrsig = rrsig_iter_init(&rrsig_spc, rrset) for ( rrsig = rrsig_iter_init(&rrsig_spc, rrset)
; rrsig; rrsig = rrsig_iter_next(rrsig)) { ; rrsig; rrsig = rrsig_iter_next(rrsig)) {
rr_dict=priv_getdns_rr_iter2rr_dict(ctxt,&rrsig->rr_i); if (!(rr_dict = priv_getdns_rr_iter2rr_dict(
if (!rr_dict) continue; &ctxt->mf, &rrsig->rr_i)))
continue;
(void)getdns_list_append_dict(val_chain_list, rr_dict); (void)getdns_list_append_dict(val_chain_list, rr_dict);
getdns_dict_destroy(rr_dict); getdns_dict_destroy(rr_dict);
@ -1360,9 +1310,6 @@ static void check_chain_complete(chain_head *chain)
getdns_list *val_chain_list; getdns_list *val_chain_list;
getdns_dict *response_dict; getdns_dict *response_dict;
#ifdef STUB_NATIVE_DNSSEC #ifdef STUB_NATIVE_DNSSEC
uint8_t tas_spc[4096], *tas = tas_spc;
size_t tas_sz;
gldns_buffer tas_buf;
rrset_iter tas_iter; rrset_iter tas_iter;
#endif #endif
@ -1380,25 +1327,9 @@ static void check_chain_complete(chain_head *chain)
* RRSIG per RRSET, it might be usefull to perform a fake dnssec * RRSIG per RRSET, it might be usefull to perform a fake dnssec
* validation to find out which RRSIGs should be returned. * validation to find out which RRSIGs should be returned.
*/ */
if (chain->netreq->unbound_id == -1) { if (chain->netreq->unbound_id == -1 && context->trust_anchors)
gldns_buffer_init_frm_data(&tas_buf, tas, sizeof(tas_spc)); chain_validate_dnssec(chain, rrset_iter_init(&tas_iter,
_getdns_list2wire(&tas_buf, context->dnssec_trust_anchors); context->trust_anchors, context->trust_anchors_len));
if ((tas_sz = gldns_buffer_position(&tas_buf))
> sizeof(tas_spc)) {
if ((tas = GETDNS_XMALLOC(
dnsreq->my_mf, uint8_t, tas_sz))) {
gldns_buffer_init_frm_data(
&tas_buf, tas, tas_sz);
_getdns_list2wire(
&tas_buf, context->dnssec_trust_anchors);
}
} else if (! GLDNS_ANCOUNT(tas))
tas = NULL;
if (tas)
chain_validate_dnssec(chain,
rrset_iter_init(&tas_iter, tas, tas_sz));
}
#endif #endif
val_chain_list = dnsreq->dnssec_return_validation_chain val_chain_list = dnsreq->dnssec_return_validation_chain
@ -1432,13 +1363,7 @@ static void check_chain_complete(chain_head *chain)
getdns_list_destroy(val_chain_list); getdns_list_destroy(val_chain_list);
} }
#ifdef STUB_NATIVE_DNSSEC
if (tas && tas != tas_spc)
GETDNS_FREE(dnsreq->my_mf, tas);
#endif
/* Final user callback */ /* Final user callback */
priv_getdns_call_user_callback(dnsreq, response_dict); priv_getdns_call_user_callback(dnsreq, response_dict);
} }
@ -2275,26 +2200,17 @@ done_free_trusted:
return r; return r;
} /* getdns_validate_dnssec */ } /* getdns_validate_dnssec */
int uint16_t
priv_getdns_parse_ta_file(time_t *ta_mtime, getdns_list *ta_rrs) _getdns_parse_ta_file(time_t *ta_mtime, gldns_buffer *gbuf)
{ {
struct gldns_file_parse_state pst; struct gldns_file_parse_state pst;
struct stat st; struct stat st;
struct { uint8_t rr[8192]; /* Reasonable size for a single DNSKEY or DS RR */
uint16_t id;
uint16_t flags;
uint16_t qdcount;
uint16_t ancount;
uint16_t nscount;
uint16_t arcount;
uint8_t rr[8192]; /* Reasonable max size for a single RR */
} pkt;
size_t len, dname_len; size_t len, dname_len;
FILE *in; FILE *in;
priv_getdns_rr_iter rr_iter; uint16_t ta_count = 0;
getdns_dict *rr_dict = NULL; size_t pkt_start;
int ta_count = 0;
if (stat(TRUST_ANCHOR_FILE, &st) != 0) if (stat(TRUST_ANCHOR_FILE, &st) != 0)
return 0; return 0;
@ -2305,38 +2221,34 @@ priv_getdns_parse_ta_file(time_t *ta_mtime, getdns_list *ta_rrs)
if (!(in = fopen(TRUST_ANCHOR_FILE, "r"))) if (!(in = fopen(TRUST_ANCHOR_FILE, "r")))
return 0; return 0;
pkt.id = pkt.flags = pkt.qdcount = pkt.nscount = pkt.arcount = 0;
pkt.ancount = htons(1);
memset(&pst, 0, sizeof(pst)); memset(&pst, 0, sizeof(pst));
pst.default_ttl = 3600; pst.default_ttl = 3600;
pst.lineno = 1; pst.lineno = 1;
pkt_start = gldns_buffer_position(gbuf);
/* Empty header */
gldns_buffer_write_u32(gbuf, 0);
gldns_buffer_write_u32(gbuf, 0);
gldns_buffer_write_u32(gbuf, 0);
while (!feof(in)) { while (!feof(in)) {
len = sizeof(pkt.rr); len = sizeof(rr);
dname_len = 0; dname_len = 0;
if (gldns_fp2wire_rr_buf(in, pkt.rr, &len, &dname_len, &pst)) if (gldns_fp2wire_rr_buf(in, rr, &len, &dname_len, &pst))
break; break;
if (len == 0) /* empty, $TTL, $ORIGIN */ if (len == 0) /* empty, $TTL, $ORIGIN */
continue; continue;
if (gldns_wirerr_get_type(pkt.rr, len, dname_len) if (gldns_wirerr_get_type(rr, len, dname_len)
!= LDNS_RR_TYPE_DS && != LDNS_RR_TYPE_DS &&
gldns_wirerr_get_type(pkt.rr, len, dname_len) gldns_wirerr_get_type(rr, len, dname_len)
!= LDNS_RR_TYPE_DNSKEY) != LDNS_RR_TYPE_DNSKEY)
continue; continue;
if (!priv_getdns_rr_iter_init(&rr_iter, (void *)&pkt, sizeof(pkt)))
break; gldns_buffer_write(gbuf, rr, len);
if (!(rr_dict = priv_getdns_rr_iter2rr_dict(NULL, &rr_iter)))
break;
if (ta_rrs && getdns_list_append_dict(ta_rrs, rr_dict))
break;
getdns_dict_destroy(rr_dict);
rr_dict = NULL;
ta_count++; ta_count++;
} }
if (rr_dict)
getdns_dict_destroy(rr_dict);
fclose(in); fclose(in);
gldns_buffer_write_u16_at(gbuf, pkt_start+GLDNS_ANCOUNT_OFF, ta_count);
return ta_count; return ta_count;
} }
@ -2344,9 +2256,29 @@ priv_getdns_parse_ta_file(time_t *ta_mtime, getdns_list *ta_rrs)
getdns_list * getdns_list *
getdns_root_trust_anchor(time_t *utc_date_of_anchor) getdns_root_trust_anchor(time_t *utc_date_of_anchor)
{ {
getdns_list *ta_rrs = getdns_list_create(); gldns_buffer *gbuf;
(void) priv_getdns_parse_ta_file(utc_date_of_anchor, ta_rrs); getdns_list *ta_rrs;
if (!(ta_rrs = getdns_list_create()))
return NULL;
if (!(gbuf = gldns_buffer_new(4096)))
goto error_free_ta_rrs;
if (!_getdns_parse_ta_file(utc_date_of_anchor, gbuf))
goto error_free_gbuf;
_getdns_wire2list( gldns_buffer_export(gbuf)
, gldns_buffer_position(gbuf), ta_rrs);
gldns_buffer_free(gbuf);
return ta_rrs; return ta_rrs;
error_free_gbuf:
gldns_buffer_free(gbuf);
error_free_ta_rrs:
getdns_list_destroy(ta_rrs);
return NULL;
} }
/* dnssec.c */ /* dnssec.c */

View File

@ -39,12 +39,14 @@
#define DNSSEC_H_ #define DNSSEC_H_
#include "getdns/getdns.h" #include "getdns/getdns.h"
#include "config.h"
#include "gldns/gbuffer.h"
#include "types-internal.h" #include "types-internal.h"
/* Do some additional requests to fetch the complete validation chain */ /* Do some additional requests to fetch the complete validation chain */
void priv_getdns_get_validation_chain(getdns_dns_req *dns_req); void priv_getdns_get_validation_chain(getdns_dns_req *dns_req);
int priv_getdns_parse_ta_file(time_t *ta_mtime, getdns_list *ta_rrs); uint16_t _getdns_parse_ta_file(time_t *ta_mtime, gldns_buffer *gbuf);
#endif #endif

View File

@ -74,6 +74,10 @@ struct getdns_list
struct mem_funcs mf; struct mem_funcs mf;
}; };
inline struct getdns_list *_getdns_list_create_with_mf(struct mem_funcs *mf)
{ return getdns_list_create_with_extended_memory_functions(
mf->mf_arg, mf->mf.ext.malloc, mf->mf.ext.realloc, mf->mf.ext.free); }
#endif #endif
/* list.h */ /* list.h */

View File

@ -179,7 +179,7 @@ sockaddr_to_dict(struct getdns_context *context, struct sockaddr_storage *addres
} }
getdns_dict * getdns_dict *
priv_getdns_rr_iter2rr_dict(getdns_context *context, priv_getdns_rr_iter *i) priv_getdns_rr_iter2rr_dict(struct mem_funcs *mf, priv_getdns_rr_iter *i)
{ {
getdns_dict *rr_dict, *rdata_dict; getdns_dict *rr_dict, *rdata_dict;
getdns_bindata bindata; getdns_bindata bindata;
@ -192,7 +192,7 @@ priv_getdns_rr_iter2rr_dict(getdns_context *context, priv_getdns_rr_iter *i)
uint16_t rr_type; uint16_t rr_type;
assert(i); assert(i);
if (!(rr_dict = getdns_dict_create_with_context(context))) if (!(rr_dict = _getdns_dict_create_with_mf(mf)))
return NULL; return NULL;
bindata.data = priv_getdns_owner_if_or_as_decompressed( bindata.data = priv_getdns_owner_if_or_as_decompressed(
@ -248,8 +248,8 @@ priv_getdns_rr_iter2rr_dict(getdns_context *context, priv_getdns_rr_iter *i)
goto error; goto error;
} }
if (!(rdata_dict = getdns_dict_create_with_context(context))) if (!(rdata_dict = _getdns_dict_create_with_mf(mf)))
goto error; return NULL;
if (i->rr_type + 10 <= i->nxt) { if (i->rr_type + 10 <= i->nxt) {
bindata.size = i->nxt - (i->rr_type + 10); bindata.size = i->nxt - (i->rr_type + 10);
@ -330,7 +330,8 @@ priv_getdns_rr_iter2rr_dict(getdns_context *context, priv_getdns_rr_iter *i)
/* list with rdf values */ /* list with rdf values */
if (! repeat_list && !(repeat_list = if (! repeat_list && !(repeat_list =
getdns_list_create_with_context(context))) _getdns_list_create_with_mf(mf)))
goto rdata_error; goto rdata_error;
switch (val_type) { switch (val_type) {
@ -357,7 +358,7 @@ priv_getdns_rr_iter2rr_dict(getdns_context *context, priv_getdns_rr_iter *i)
if (repeat_dict) { if (repeat_dict) {
if (! repeat_list && !(repeat_list = if (! repeat_list && !(repeat_list =
getdns_list_create_with_context(context))) _getdns_list_create_with_mf(mf)))
goto rdata_error; goto rdata_error;
if (getdns_list_append_dict( if (getdns_list_append_dict(
@ -368,7 +369,7 @@ priv_getdns_rr_iter2rr_dict(getdns_context *context, priv_getdns_rr_iter *i)
repeat_dict = NULL; repeat_dict = NULL;
} }
if (!(repeat_dict = if (!(repeat_dict =
getdns_dict_create_with_context(context))) _getdns_dict_create_with_mf(mf)))
goto rdata_error; goto rdata_error;
} }
assert(repeat_dict); assert(repeat_dict);
@ -393,7 +394,7 @@ priv_getdns_rr_iter2rr_dict(getdns_context *context, priv_getdns_rr_iter *i)
} }
if (repeat_dict) { if (repeat_dict) {
if (!repeat_list && !(repeat_list = if (!repeat_list && !(repeat_list =
getdns_list_create_with_context(context))) _getdns_list_create_with_mf(mf)))
goto rdata_error; goto rdata_error;
if (getdns_list_append_dict(repeat_list, repeat_dict)) if (getdns_list_append_dict(repeat_list, repeat_dict))
goto rdata_error; goto rdata_error;
@ -553,7 +554,7 @@ priv_getdns_create_reply_dict(getdns_context *context, getdns_network_req *req,
; rr_iter = priv_getdns_rr_iter_next(rr_iter)) { ; rr_iter = priv_getdns_rr_iter_next(rr_iter)) {
if (!set_dict(&rr_dict, if (!set_dict(&rr_dict,
priv_getdns_rr_iter2rr_dict(context, rr_iter))) priv_getdns_rr_iter2rr_dict(&context->mf, rr_iter)))
continue; continue;
section = priv_getdns_rr_iter_section(rr_iter); section = priv_getdns_rr_iter_section(rr_iter);
@ -866,7 +867,7 @@ getdns_apply_network_result(getdns_network_req* netreq,
netreq->dnssec_status = GETDNS_DNSSEC_BOGUS; netreq->dnssec_status = GETDNS_DNSSEC_BOGUS;
else if (ub_res->secure) else if (ub_res->secure)
netreq->dnssec_status = GETDNS_DNSSEC_SECURE; netreq->dnssec_status = GETDNS_DNSSEC_SECURE;
else if (netreq->owner->context->has_ta) else if (netreq->owner->context->trust_anchors)
netreq->dnssec_status = GETDNS_DNSSEC_INSECURE; netreq->dnssec_status = GETDNS_DNSSEC_INSECURE;
if (ub_res == NULL) /* Timeout */ if (ub_res == NULL) /* Timeout */
@ -989,4 +990,92 @@ priv_getdns_validate_dname(const char* dname) {
} /* priv_getdns_validate_dname */ } /* priv_getdns_validate_dname */
static void _getdns_list2wire_buf(gldns_buffer *buf, getdns_list *l)
{
getdns_dict *rr_dict;
getdns_return_t r;
size_t i, pkt_start, ancount;
uint32_t qtype, qclass;
getdns_bindata *qname;
pkt_start = gldns_buffer_position(buf);
/* Empty header */
gldns_buffer_write_u32(buf, 0);
gldns_buffer_write_u32(buf, 0);
gldns_buffer_write_u32(buf, 0);
for ( i = 0
; (r = getdns_list_get_dict(l, i, &rr_dict))
!= GETDNS_RETURN_NO_SUCH_LIST_ITEM
; i++ ) {
if (r) {
if (r == GETDNS_RETURN_WRONG_TYPE_REQUESTED)
continue;
else
break;
}
if (getdns_dict_get_int(rr_dict, "qtype", &qtype) ||
getdns_dict_get_bindata(rr_dict, "qname", &qname))
continue;
(void) getdns_dict_get_int(rr_dict, "qclass", &qclass);
gldns_buffer_write(buf, qname->data, qname->size);
gldns_buffer_write_u16(buf, (uint16_t)qtype);
gldns_buffer_write_u16(buf, (uint16_t)qclass);
gldns_buffer_write_u16_at(buf, pkt_start+GLDNS_QDCOUNT_OFF, 1);
break;
}
for ( i = 0, ancount = 0
; (r = getdns_list_get_dict(l, i, &rr_dict))
!= GETDNS_RETURN_NO_SUCH_LIST_ITEM
; i++ ) {
if (r) {
if (r == GETDNS_RETURN_WRONG_TYPE_REQUESTED)
continue;
else
break;
}
if (priv_getdns_rr_dict2wire(rr_dict, buf) == GETDNS_RETURN_GOOD)
ancount++;
}
gldns_buffer_write_u16_at(buf, pkt_start+GLDNS_ANCOUNT_OFF, ancount);
}
uint8_t *_getdns_list2wire(
getdns_list *l, uint8_t *buf, size_t *buf_len, struct mem_funcs *mf)
{
gldns_buffer gbuf;
size_t sz;
gldns_buffer_init_frm_data(&gbuf, buf, *buf_len);
_getdns_list2wire_buf(&gbuf, l);
if ((sz = gldns_buffer_position(&gbuf)) <= *buf_len)
return buf;
if (!(buf = GETDNS_XMALLOC(*mf, uint8_t, (*buf_len = sz))))
return NULL;
gldns_buffer_init_frm_data(&gbuf, buf, sz);
_getdns_list2wire_buf(&gbuf, l);
return buf;
}
void _getdns_wire2list(uint8_t *pkt, size_t pkt_len, getdns_list *l)
{
priv_getdns_rr_iter rr_spc, *rr;
getdns_dict *rr_dict;
for ( rr = priv_getdns_rr_iter_init(&rr_spc, pkt, pkt_len)
; rr ; rr = priv_getdns_rr_iter_next(rr)) {
if (!(rr_dict = priv_getdns_rr_iter2rr_dict(&l->mf, rr)))
continue;
(void)getdns_list_append_dict(l, rr_dict);
getdns_dict_destroy(rr_dict);
}
}
/* util-internal.c */ /* util-internal.c */

View File

@ -123,7 +123,7 @@ getdns_return_t sockaddr_to_dict(struct getdns_context *context,
struct sockaddr_storage *sockaddr, struct getdns_dict ** output); struct sockaddr_storage *sockaddr, struct getdns_dict ** output);
getdns_dict * getdns_dict *
priv_getdns_rr_iter2rr_dict(getdns_context *context, priv_getdns_rr_iter *i); priv_getdns_rr_iter2rr_dict(struct mem_funcs *mf, priv_getdns_rr_iter *i);
struct getdns_dns_req; struct getdns_dns_req;
struct getdns_dict *create_getdns_response(struct getdns_dns_req *completed_request); struct getdns_dict *create_getdns_response(struct getdns_dns_req *completed_request);
@ -135,6 +135,10 @@ getdns_return_t priv_getdns_validate_dname(const char* dname);
int priv_getdns_dname_equal(const uint8_t *s1, const uint8_t *s2); int priv_getdns_dname_equal(const uint8_t *s1, const uint8_t *s2);
uint8_t *_getdns_list2wire(
getdns_list *l, uint8_t *buf, size_t *buf_len, struct mem_funcs *mf);
void _getdns_wire2list(uint8_t *pkt, size_t pkt_len, getdns_list *l);
/** /**