diff --git a/src/context.c b/src/context.c index 52b42bd1..7abdbedb 100644 --- a/src/context.c +++ b/src/context.c @@ -771,6 +771,7 @@ getdns_context_create_with_extended_memory_functions( getdns_return_t r; struct getdns_context *result = NULL; mf_union mf; + gldns_buffer gbuf; if (!context || !malloc || !realloc || !free) return GETDNS_RETURN_INVALID_PARAMETER; @@ -815,7 +816,30 @@ getdns_context_create_with_extended_memory_functions( result->append_name = GETDNS_APPEND_NAME_ALWAYS; 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->edns_extended_rcode = 0; @@ -828,7 +852,7 @@ getdns_context_create_with_extended_memory_functions( goto error; result->fchg_resolvconf = NULL; - result->fchg_hosts = NULL; + result->fchg_hosts = NULL; if (set_from_os && (r = set_os_defaults(result))) goto error; @@ -840,12 +864,6 @@ getdns_context_create_with_extended_memory_functions( result->limit_outstanding_queries = 0; 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 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. */ @@ -944,7 +962,10 @@ getdns_context_destroy(struct getdns_context *context) getdns_list_destroy(context->dns_root_servers); 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 */ if (context->unbound_ctx) @@ -1076,7 +1097,7 @@ rebuild_ub_ctx(struct getdns_context* context) { context->dns_transport); /* Set default trust anchor */ - if (context->has_ta) { + if (context->trust_anchors) { (void) ub_ctx_add_ta_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_context_set_dnssec_trust_anchors(struct getdns_context *context, - struct getdns_list * value) +getdns_context_set_dnssec_trust_anchors( + getdns_context *context, getdns_list *value) { - struct getdns_list *copy = NULL; - RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); - if (value != NULL) { - if (getdns_list_copy(value, ©) != GETDNS_RETURN_GOOD) { - return GETDNS_RETURN_CONTEXT_UPDATE_FAIL; - } - value = copy; - } - getdns_list_destroy(context->dnssec_trust_anchors); - context->dnssec_trust_anchors = value; + RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); - 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 */ static void @@ -2482,15 +2506,23 @@ getdns_context_get_suffix(getdns_context *context, getdns_list **value) { } getdns_return_t -getdns_context_get_dnssec_trust_anchors(getdns_context *context, - getdns_list **value) { - RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); - RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER); - *value = NULL; - if (context->dnssec_trust_anchors) { - return getdns_list_copy(context->dnssec_trust_anchors, value); - } - return GETDNS_RETURN_GOOD; +getdns_context_get_dnssec_trust_anchors( + getdns_context *context, getdns_list **value) +{ + RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); + RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER); + + if (context->trust_anchors) { + if ((*value = getdns_list_create_with_context(context))) + _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 diff --git a/src/context.h b/src/context.h index 3ad6b342..c4c77609 100644 --- a/src/context.h +++ b/src/context.h @@ -135,7 +135,8 @@ struct getdns_context { struct getdns_list *dns_root_servers; getdns_append_name_t append_name; struct getdns_list *suffix; - struct getdns_list *dnssec_trust_anchors; + uint8_t *trust_anchors; + size_t trust_anchors_len; getdns_upstreams *upstreams; getdns_transport_t dns_transport; 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*/ getdns_rbtree_t local_hosts; - int has_ta; /* No DNSSEC without trust anchor */ + int return_dnssec_status; /* which resolution type the contexts are configured for @@ -189,6 +190,8 @@ struct getdns_context { struct filechg *fchg_resolvconf; struct filechg *fchg_hosts; + uint8_t trust_anchors_spc[1024]; + }; /* getdns_context */ /** internal functions **/ diff --git a/src/dict.h b/src/dict.h index 2d45b651..0a74cc14 100644 --- a/src/dict.h +++ b/src/dict.h @@ -70,6 +70,10 @@ struct getdns_dict 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 /* dict.h */ diff --git a/src/dnssec.c b/src/dnssec.c index 4c2f2653..4b804d36 100644 --- a/src/dnssec.c +++ b/src/dnssec.c @@ -67,58 +67,6 @@ static int is_subdomain( 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 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) ; rr; rr = rrtype_iter_next(rr)) { - rr_dict = priv_getdns_rr_iter2rr_dict(ctxt, &rr->rr_i); - if (!rr_dict) continue; + if (!(rr_dict = priv_getdns_rr_iter2rr_dict( + &ctxt->mf, &rr->rr_i))) + continue; (void)getdns_list_append_dict(val_chain_list, 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) ; rrsig; rrsig = rrsig_iter_next(rrsig)) { - rr_dict=priv_getdns_rr_iter2rr_dict(ctxt,&rrsig->rr_i); - if (!rr_dict) continue; + if (!(rr_dict = priv_getdns_rr_iter2rr_dict( + &ctxt->mf, &rrsig->rr_i))) + continue; (void)getdns_list_append_dict(val_chain_list, 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_dict *response_dict; #ifdef STUB_NATIVE_DNSSEC - uint8_t tas_spc[4096], *tas = tas_spc; - size_t tas_sz; - gldns_buffer tas_buf; rrset_iter tas_iter; #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 * validation to find out which RRSIGs should be returned. */ - if (chain->netreq->unbound_id == -1) { - gldns_buffer_init_frm_data(&tas_buf, tas, sizeof(tas_spc)); - _getdns_list2wire(&tas_buf, context->dnssec_trust_anchors); - 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)); - } + if (chain->netreq->unbound_id == -1 && context->trust_anchors) + chain_validate_dnssec(chain, rrset_iter_init(&tas_iter, + context->trust_anchors, context->trust_anchors_len)); #endif 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); } - -#ifdef STUB_NATIVE_DNSSEC - if (tas && tas != tas_spc) - GETDNS_FREE(dnsreq->my_mf, tas); -#endif /* Final user callback */ - priv_getdns_call_user_callback(dnsreq, response_dict); } @@ -2275,26 +2200,17 @@ done_free_trusted: return r; } /* getdns_validate_dnssec */ -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) { struct gldns_file_parse_state pst; struct stat st; - struct { - 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; + uint8_t rr[8192]; /* Reasonable size for a single DNSKEY or DS RR */ size_t len, dname_len; FILE *in; - priv_getdns_rr_iter rr_iter; - getdns_dict *rr_dict = NULL; - int ta_count = 0; + uint16_t ta_count = 0; + size_t pkt_start; if (stat(TRUST_ANCHOR_FILE, &st) != 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"))) return 0; - pkt.id = pkt.flags = pkt.qdcount = pkt.nscount = pkt.arcount = 0; - pkt.ancount = htons(1); - memset(&pst, 0, sizeof(pst)); pst.default_ttl = 3600; 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)) { - len = sizeof(pkt.rr); + len = sizeof(rr); 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; if (len == 0) /* empty, $TTL, $ORIGIN */ continue; - if (gldns_wirerr_get_type(pkt.rr, len, dname_len) + if (gldns_wirerr_get_type(rr, len, dname_len) != 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) continue; - if (!priv_getdns_rr_iter_init(&rr_iter, (void *)&pkt, sizeof(pkt))) - break; - 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; + + gldns_buffer_write(gbuf, rr, len); ta_count++; } - if (rr_dict) - getdns_dict_destroy(rr_dict); fclose(in); + gldns_buffer_write_u16_at(gbuf, pkt_start+GLDNS_ANCOUNT_OFF, 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_root_trust_anchor(time_t *utc_date_of_anchor) { - getdns_list *ta_rrs = getdns_list_create(); - (void) priv_getdns_parse_ta_file(utc_date_of_anchor, ta_rrs); + gldns_buffer *gbuf; + 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; + +error_free_gbuf: + gldns_buffer_free(gbuf); +error_free_ta_rrs: + getdns_list_destroy(ta_rrs); + return NULL; } /* dnssec.c */ diff --git a/src/dnssec.h b/src/dnssec.h index 30af7705..30ab6b3e 100644 --- a/src/dnssec.h +++ b/src/dnssec.h @@ -39,12 +39,14 @@ #define DNSSEC_H_ #include "getdns/getdns.h" +#include "config.h" +#include "gldns/gbuffer.h" #include "types-internal.h" /* Do some additional requests to fetch the complete validation chain */ 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 diff --git a/src/list.h b/src/list.h index 0fc320a4..113361ae 100644 --- a/src/list.h +++ b/src/list.h @@ -74,6 +74,10 @@ struct getdns_list 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 /* list.h */ diff --git a/src/util-internal.c b/src/util-internal.c index 78be575c..69475e59 100644 --- a/src/util-internal.c +++ b/src/util-internal.c @@ -179,7 +179,7 @@ sockaddr_to_dict(struct getdns_context *context, struct sockaddr_storage *addres } 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_bindata bindata; @@ -192,7 +192,7 @@ priv_getdns_rr_iter2rr_dict(getdns_context *context, priv_getdns_rr_iter *i) uint16_t rr_type; assert(i); - if (!(rr_dict = getdns_dict_create_with_context(context))) + if (!(rr_dict = _getdns_dict_create_with_mf(mf))) return NULL; 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; } - if (!(rdata_dict = getdns_dict_create_with_context(context))) - goto error; + if (!(rdata_dict = _getdns_dict_create_with_mf(mf))) + return NULL; if (i->rr_type + 10 <= i->nxt) { 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 */ if (! repeat_list && !(repeat_list = - getdns_list_create_with_context(context))) + _getdns_list_create_with_mf(mf))) + goto rdata_error; 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_list && !(repeat_list = - getdns_list_create_with_context(context))) + _getdns_list_create_with_mf(mf))) goto rdata_error; 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; } if (!(repeat_dict = - getdns_dict_create_with_context(context))) + _getdns_dict_create_with_mf(mf))) goto rdata_error; } 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_list && !(repeat_list = - getdns_list_create_with_context(context))) + _getdns_list_create_with_mf(mf))) goto rdata_error; if (getdns_list_append_dict(repeat_list, repeat_dict)) 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)) { if (!set_dict(&rr_dict, - priv_getdns_rr_iter2rr_dict(context, rr_iter))) + priv_getdns_rr_iter2rr_dict(&context->mf, rr_iter))) continue; 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; else if (ub_res->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; if (ub_res == NULL) /* Timeout */ @@ -989,4 +990,92 @@ priv_getdns_validate_dname(const char* 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 */ diff --git a/src/util-internal.h b/src/util-internal.h index b81588f5..5963fecf 100644 --- a/src/util-internal.h +++ b/src/util-internal.h @@ -123,7 +123,7 @@ getdns_return_t sockaddr_to_dict(struct getdns_context *context, struct sockaddr_storage *sockaddr, struct getdns_dict ** output); 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_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); +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); /**