From e1126c9cf81892a016a55878d0acadab7ceab2fd Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Mon, 18 Apr 2016 15:36:39 +0200 Subject: [PATCH 1/7] Canonicalize dnssec chain When validated --- src/dict.c | 18 +++++++ src/dnssec.c | 121 +++++++++++++++++++++++++++++--------------- src/dnssec.h | 16 ++++++ src/util-internal.c | 62 +++++++++++++++++++++-- src/util-internal.h | 25 +++++++++ 5 files changed, 196 insertions(+), 46 deletions(-) diff --git a/src/dict.c b/src/dict.c index ebd129ca..58b10631 100644 --- a/src/dict.c +++ b/src/dict.c @@ -601,6 +601,24 @@ getdns_dict_set_list( /*---------------------------------------- getdns_dict_set_bindata */ +getdns_return_t +_getdns_dict_set_this_bindata( + getdns_dict *dict, const char *name, getdns_bindata *bindata) +{ + getdns_item *item; + getdns_return_t r; + + if (!dict || !name || !bindata) + return GETDNS_RETURN_INVALID_PARAMETER; + + if ((r = _getdns_dict_find_and_add(dict, name, &item))) + return r; + + item->dtype = t_bindata; + item->data.bindata = bindata; + return GETDNS_RETURN_GOOD; +} + getdns_return_t _getdns_dict_set_const_bindata( getdns_dict *dict, const char *name, size_t size, const void *data) diff --git a/src/dnssec.c b/src/dnssec.c index 9bb95471..ce77dcea 100644 --- a/src/dnssec.c +++ b/src/dnssec.c @@ -268,23 +268,6 @@ static uint8_t *_dname_label_copy(uint8_t *dst, const uint8_t *src, size_t dst_l return r; } -inline static void _dname_canonicalize(const uint8_t *src, uint8_t *dst) -{ - const uint8_t *next_label; - - while (*src) { - next_label = src + *src + 1; - *dst++ = *src++; - while (src < next_label) - *dst++ = (uint8_t)tolower((unsigned char)*src++); - } -} - -inline static void _dname_canonicalize2(uint8_t *dname) -{ - _dname_canonicalize(dname, dname); -} - /* Fills the array pointed to by labels (of at least 128 uint8_t * pointers) * with pointers to labels in given dname in reversed order. So that @@ -1528,21 +1511,6 @@ inline static void canon_rdata_iter_next(canon_rdata_iter *i) i->pos++; } -inline static int _dnssec_rdata_to_canonicalize(uint16_t rr_type) -{ - return rr_type == GLDNS_RR_TYPE_NS || rr_type == GLDNS_RR_TYPE_MD - || rr_type == GLDNS_RR_TYPE_MF || rr_type == GLDNS_RR_TYPE_CNAME - || rr_type == GLDNS_RR_TYPE_SOA || rr_type == GLDNS_RR_TYPE_MB - || rr_type == GLDNS_RR_TYPE_MG || rr_type == GLDNS_RR_TYPE_MR - || rr_type == GLDNS_RR_TYPE_PTR || rr_type == GLDNS_RR_TYPE_MINFO - || rr_type == GLDNS_RR_TYPE_MX || rr_type == GLDNS_RR_TYPE_RP - || rr_type == GLDNS_RR_TYPE_AFSDB || rr_type == GLDNS_RR_TYPE_RT - || rr_type == GLDNS_RR_TYPE_SIG || rr_type == GLDNS_RR_TYPE_PX - || rr_type == GLDNS_RR_TYPE_NXT || rr_type == GLDNS_RR_TYPE_NAPTR - || rr_type == GLDNS_RR_TYPE_KX || rr_type == GLDNS_RR_TYPE_SRV - || rr_type == GLDNS_RR_TYPE_DNAME || rr_type == GLDNS_RR_TYPE_RRSIG; -} - static int _rr_iter_rdata_cmp(const void *a, const void *b) { _getdns_rr_iter *x = (_getdns_rr_iter *)a; @@ -1656,6 +1624,7 @@ static int _getdns_verify_rrsig(struct mem_funcs *mf, if (!_dnssec_rdata_to_canonicalize(rrset->rr_type)) for (i = 0; i < n_rrs; i++) { + /* Get rid of doubles */ if (i && !_rr_iter_rdata_cmp( &val_rrset[i], &val_rrset[i-1])) continue; @@ -3047,6 +3016,62 @@ static int rrset_in_list(getdns_rrset *rrset, getdns_list *list) return 0; } +static void append_canonical_rrset2val_chain_list( + getdns_list *val_chain_list, getdns_rrset *rrset, rrsig_iter *rrsig) +{ + _getdns_rr_iter val_rrset_spc[VAL_RRSET_SPC_SZ]; + _getdns_rr_iter *val_rrset = val_rrset_spc; + rrtype_iter rr_spc, *rr; + size_t n_rrs, i; + uint32_t orig_ttl; + getdns_dict *rr_dict; + + assert(val_chain_list && rrset && rrsig); + + /* keytag was already read, so orig_ttl should cause no problem */ + assert(rrsig->rr_i.nxt >= rrsig->rr_i.rr_type + 18); + + orig_ttl = gldns_read_uint32(rrsig->rr_i.rr_type + 14); + + for (;;) { + for ( rr = rrtype_iter_init(&rr_spc, rrset), n_rrs = 0 + ; rr + ; rr = rrtype_iter_next(rr), n_rrs++) { + + if (n_rrs < VAL_RRSET_SPC_SZ || + val_rrset != val_rrset_spc) + val_rrset[n_rrs] = rr->rr_i; + } + /* Did everything fit? Then break */ + if (val_rrset != val_rrset_spc || n_rrs <= VAL_RRSET_SPC_SZ) + break; + + /* More space needed for val_rrset */ + val_rrset = GETDNS_XMALLOC( + val_chain_list->mf, _getdns_rr_iter, n_rrs); + } + qsort(val_rrset, n_rrs, sizeof(_getdns_rr_iter), _rr_iter_rdata_cmp); + for (i = 0; i < n_rrs; i++) { + /* Get rid of doubles */ + if (i && !_rr_iter_rdata_cmp(&val_rrset[i], &val_rrset[i-1])) + continue; + + if (!(rr_dict = _getdns_rr_iter2rr_dict_canonical( + &val_chain_list->mf, &val_rrset[i], &orig_ttl))) + continue; + + if (_getdns_list_append_this_dict(val_chain_list, rr_dict)) + getdns_dict_destroy(rr_dict); + } + if ((rr_dict = _getdns_rr_iter2rr_dict_canonical( + &val_chain_list->mf, &rrsig->rr_i, &orig_ttl)) && + _getdns_list_append_this_dict(val_chain_list, rr_dict)) + getdns_dict_destroy(rr_dict); + + if (val_rrset != val_rrset_spc) + GETDNS_FREE(val_chain_list->mf, val_rrset); +} + static void append_rrs2val_chain_list(getdns_context *ctxt, getdns_list *val_chain_list, getdns_network_req *netreq, int signer) { @@ -3072,6 +3097,27 @@ static void append_rrs2val_chain_list(getdns_context *ctxt, rrset->rr_type != GETDNS_RRTYPE_DS) continue; + if ((signer & 0xFFFF)) { + /* We have a signer! Return RRset in canonical + * form and order with only the RRSIG that signed + * the RRset. + */ + for ( rrsig = rrsig_iter_init(&rrsig_spc, rrset) + ; rrsig && + ( rrsig->rr_i.nxt < rrsig->rr_i.rr_type + 28 + || gldns_read_uint16(rrsig->rr_i.rr_type + 26) + != (signer & 0xFFFF)) + ; rrsig = rrsig_iter_next(rrsig)) + ; /* pass */ + + if (!rrsig) { + /* Signer not found, try next RR set */ + continue; + } + append_canonical_rrset2val_chain_list( + val_chain_list, rrset, rrsig); + continue; + } for ( rr = rrtype_iter_init(&rr_spc, rrset) ; rr; rr = rrtype_iter_next(rr)) { @@ -3085,16 +3131,7 @@ static void append_rrs2val_chain_list(getdns_context *ctxt, for ( rrsig = rrsig_iter_init(&rrsig_spc, rrset) ; rrsig; rrsig = rrsig_iter_next(rrsig)) { - if (/* No space for keytag & signer in rrsig rdata? */ - rrsig->rr_i.nxt < rrsig->rr_i.rr_type + 28 - - /* We have a signer and it doesn't match? */ - || ((signer & 0xFFFF) && - gldns_read_uint16(rrsig->rr_i.rr_type + 26) - != (signer & 0xFFFF)) - - /* Could not convert to rr_dict */ - || !(rr_dict = _getdns_rr_iter2rr_dict( + if (!(rr_dict = _getdns_rr_iter2rr_dict( &ctxt->mf, &rrsig->rr_i))) continue; diff --git a/src/dnssec.h b/src/dnssec.h index 263d6e0e..ae131efc 100644 --- a/src/dnssec.h +++ b/src/dnssec.h @@ -41,6 +41,7 @@ #include "getdns/getdns.h" #include "config.h" #include "gldns/gbuffer.h" +#include "gldns/rrdef.h" #include "types-internal.h" /* Do some additional requests to fetch the complete validation chain */ @@ -48,6 +49,21 @@ void _getdns_get_validation_chain(getdns_dns_req *dns_req); uint16_t _getdns_parse_ta_file(time_t *ta_mtime, gldns_buffer *gbuf); +inline static int _dnssec_rdata_to_canonicalize(uint16_t rr_type) +{ + return rr_type == GLDNS_RR_TYPE_NS || rr_type == GLDNS_RR_TYPE_MD + || rr_type == GLDNS_RR_TYPE_MF || rr_type == GLDNS_RR_TYPE_CNAME + || rr_type == GLDNS_RR_TYPE_SOA || rr_type == GLDNS_RR_TYPE_MB + || rr_type == GLDNS_RR_TYPE_MG || rr_type == GLDNS_RR_TYPE_MR + || rr_type == GLDNS_RR_TYPE_PTR || rr_type == GLDNS_RR_TYPE_MINFO + || rr_type == GLDNS_RR_TYPE_MX || rr_type == GLDNS_RR_TYPE_RP + || rr_type == GLDNS_RR_TYPE_AFSDB || rr_type == GLDNS_RR_TYPE_RT + || rr_type == GLDNS_RR_TYPE_SIG || rr_type == GLDNS_RR_TYPE_PX + || rr_type == GLDNS_RR_TYPE_NXT || rr_type == GLDNS_RR_TYPE_NAPTR + || rr_type == GLDNS_RR_TYPE_KX || rr_type == GLDNS_RR_TYPE_SRV + || rr_type == GLDNS_RR_TYPE_DNAME || rr_type == GLDNS_RR_TYPE_RRSIG; +} + #endif /* dnssec.h */ diff --git a/src/util-internal.c b/src/util-internal.c index 14912982..84b4ef7e 100644 --- a/src/util-internal.c +++ b/src/util-internal.c @@ -51,6 +51,7 @@ #include "gldns/str2wire.h" #include "gldns/gbuffer.h" #include "gldns/pkthdr.h" +#include "dnssec.h" getdns_return_t @@ -145,11 +146,12 @@ _getdns_sockaddr_to_dict(struct getdns_context *context, struct sockaddr_storage } getdns_dict * -_getdns_rr_iter2rr_dict(struct mem_funcs *mf, _getdns_rr_iter *i) +_getdns_rr_iter2rr_dict_canonical( + struct mem_funcs *mf, _getdns_rr_iter *i, uint32_t *orig_ttl) { getdns_dict *rr_dict, *rdata_dict; const uint8_t *bin_data; - size_t bin_size; + size_t bin_size, owner_len = 0, rdata_sz; uint32_t int_val = 0; enum wf_data_type { wf_int, wf_bindata, wf_special } val_type; _getdns_rdf_iter rdf_storage, *rdf; @@ -157,6 +159,7 @@ _getdns_rr_iter2rr_dict(struct mem_funcs *mf, _getdns_rr_iter *i) getdns_dict *repeat_dict = NULL; uint8_t ff_bytes[256]; uint16_t rr_type; + int canonicalize; assert(i); if (!(rr_dict = _getdns_dict_create_with_mf(mf))) @@ -165,6 +168,12 @@ _getdns_rr_iter2rr_dict(struct mem_funcs *mf, _getdns_rr_iter *i) bin_data = _getdns_owner_if_or_as_decompressed( i, ff_bytes, &bin_size); + if (orig_ttl) { + if (bin_data != ff_bytes) + bin_data = memcpy(ff_bytes, bin_data, bin_size); + _dname_canonicalize2(ff_bytes); + owner_len = bin_size; + } /* question */ if (_getdns_rr_iter_section(i) == GLDNS_SECTION_QUESTION) { @@ -186,6 +195,9 @@ _getdns_rr_iter2rr_dict(struct mem_funcs *mf, _getdns_rr_iter *i) goto error; } + canonicalize = orig_ttl && _dnssec_rdata_to_canonicalize(rr_type) + && (i->rr_type + 12 <= i->nxt) /* To estimate rdata size */; + if (rr_type == GETDNS_RRTYPE_OPT) { int_val = gldns_read_uint16(i->rr_type + 6); @@ -210,7 +222,8 @@ _getdns_rr_iter2rr_dict(struct mem_funcs *mf, _getdns_rr_iter *i) (uint32_t) gldns_read_uint16(i->rr_type + 2)) || getdns_dict_set_int(rr_dict, "ttl", - (uint32_t) gldns_read_uint32(i->rr_type + 4)) || + ( orig_ttl && rr_type != GETDNS_RRTYPE_RRSIG + ? *orig_ttl : (uint32_t) gldns_read_uint32(i->rr_type + 4))) || _getdns_dict_set_const_bindata( rr_dict, "name", bin_size, bin_data)) { @@ -220,15 +233,21 @@ _getdns_rr_iter2rr_dict(struct mem_funcs *mf, _getdns_rr_iter *i) if (!(rdata_dict = _getdns_dict_create_with_mf(mf))) return NULL; - if (i->rr_type + 10 <= i->nxt) { + if (i->rr_type + 10 <= i->nxt && !canonicalize) { bin_size = i->nxt - (i->rr_type + 10); bin_data = i->rr_type + 10; if (_getdns_dict_set_const_bindata( rdata_dict, "rdata_raw", bin_size, bin_data)) goto rdata_error; } + if (canonicalize) + rdata_sz = 0; + for ( rdf = _getdns_rdf_iter_init(&rdf_storage, i) ; rdf; rdf = _getdns_rdf_iter_next(rdf)) { + if (canonicalize && !(rdf->rdd_pos->type & GETDNS_RDF_DNAME)) { + rdata_sz += rdf->nxt - rdf->pos; + } if (rdf->rdd_pos->type & GETDNS_RDF_INTEGER) { val_type = wf_int; switch (rdf->rdd_pos->type & GETDNS_RDF_FIXEDSZ) { @@ -247,6 +266,12 @@ _getdns_rr_iter2rr_dict(struct mem_funcs *mf, _getdns_rr_iter *i) bin_data = _getdns_rdf_if_or_as_decompressed( rdf, ff_bytes, &bin_size); + if (canonicalize) { + if (bin_data != ff_bytes) + bin_data = memcpy(ff_bytes, bin_data, bin_size); + _dname_canonicalize2(ff_bytes); + rdata_sz += bin_size; + } } else if (rdf->rdd_pos->type & GETDNS_RDF_BINDATA) { val_type = wf_bindata; if (rdf->rdd_pos->type & GETDNS_RDF_FIXEDSZ) { @@ -376,6 +401,29 @@ _getdns_rr_iter2rr_dict(struct mem_funcs *mf, _getdns_rr_iter *i) if (_getdns_dict_set_this_dict(rr_dict, "rdata", rdata_dict)) goto rdata_error; + if (canonicalize && rdata_sz) { + fprintf(stderr, "XXXXXXXXXX: owner_len: %zu, rdata_len: %zu\n", owner_len, rdata_sz); + + gldns_buffer gbuf; + getdns_bindata *bindata; + uint8_t *data = GETDNS_XMALLOC( + *mf, uint8_t, owner_len + 10 + rdata_sz); + + if (!data) + return rr_dict; + + gldns_buffer_init_frm_data(&gbuf, data, owner_len+10+rdata_sz); + if (_getdns_rr_dict2wire(rr_dict, &gbuf) || + gldns_buffer_position(&gbuf) != owner_len + 10 + rdata_sz || + !(bindata = GETDNS_MALLOC(*mf, struct getdns_bindata))) { + GETDNS_FREE(*mf, data); + return rr_dict; + } + bindata->size = rdata_sz; + bindata->data = memmove(data, data + owner_len + 10, rdata_sz); + (void) _getdns_dict_set_this_bindata(rr_dict, + "/rdata/rdata_raw", bindata); + } return rr_dict; rdata_error: @@ -387,6 +435,12 @@ error: return NULL; } +getdns_dict * +_getdns_rr_iter2rr_dict(struct mem_funcs *mf, _getdns_rr_iter *i) +{ + return _getdns_rr_iter2rr_dict_canonical(mf, i, NULL); +} + int _getdns_dname_equal(const uint8_t *s1, const uint8_t *s2) { diff --git a/src/util-internal.h b/src/util-internal.h index 37e6f73b..d3c05ab7 100644 --- a/src/util-internal.h +++ b/src/util-internal.h @@ -41,6 +41,7 @@ #include "config.h" #include "context.h" #include "rr-iter.h" +#include #define UNCONST_UINT8_p uint8_t * @@ -95,6 +96,9 @@ getdns_return_t _getdns_dict_set_this_list(getdns_dict *dict, getdns_return_t _getdns_dict_set_const_bindata(getdns_dict *dict, const char *name, size_t size, const void *data); +getdns_return_t _getdns_dict_set_this_bindata(getdns_dict *dict, + const char *name, getdns_bindata *child_bindata); + /** * private function (API users should not be calling this), this uses library * routines to make a copy of the list - would be faster to make the copy directly @@ -138,6 +142,10 @@ getdns_return_t _getdns_sockaddr_to_dict(struct getdns_context *context, getdns_dict * _getdns_rr_iter2rr_dict(struct mem_funcs *mf, _getdns_rr_iter *i); +getdns_dict * +_getdns_rr_iter2rr_dict_canonical( + struct mem_funcs *mf, _getdns_rr_iter *i, uint32_t *orig_ttl); + struct getdns_dns_req; struct getdns_dict *_getdns_create_getdns_response(struct getdns_dns_req *completed_request); @@ -178,5 +186,22 @@ INLINE getdns_eventloop_event *getdns_eventloop_event_init( #define GETDNS_SCHEDULE_EVENT(loop, fd, timeout, event) \ do { (loop)->vmt->schedule((loop),(fd),(timeout),(event)); } while(0) +INLINE void _dname_canonicalize(const uint8_t *src, uint8_t *dst) +{ + const uint8_t *next_label; + + while (*src) { + next_label = src + *src + 1; + *dst++ = *src++; + while (src < next_label) + *dst++ = (uint8_t)tolower((unsigned char)*src++); + } +} + +INLINE void _dname_canonicalize2(uint8_t *dname) +{ + _dname_canonicalize(dname, dname); +} + #endif /* util-internal.h */ From 484932981899d4f35c602d9041737b08fc18e334 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Mon, 18 Apr 2016 22:06:12 +0200 Subject: [PATCH 2/7] dnssec_return_full_validation_chain extension That also returns all records that had to be proofed secure in canonical form in the "validation_chain". --- src/dnssec.c | 78 ++++++++++++++++++++++++++--------------- src/general.c | 1 + src/request-internal.c | 8 ++++- src/test/getdns_query.c | 1 + src/types-internal.h | 44 ++++++++++++----------- src/util-internal.c | 13 +++---- 6 files changed, 86 insertions(+), 59 deletions(-) diff --git a/src/dnssec.c b/src/dnssec.c index ce77dcea..8a8d1937 100644 --- a/src/dnssec.c +++ b/src/dnssec.c @@ -848,7 +848,7 @@ static chain_head *add_rrset2val_chain(struct mem_funcs *mf, head->rrset.pkt = rrset->pkt; head->rrset.pkt_len = rrset->pkt_len; head->netreq = netreq; - head->signer = 0; + head->signer = -1; head->node_count = node_count; if (!node_count) { @@ -877,8 +877,8 @@ static chain_head *add_rrset2val_chain(struct mem_funcs *mf, node->ds_req = NULL; node->dnskey_req = NULL; node->soa_req = NULL; - node->ds_signer = 0; - node->dnskey_signer = 0; + node->ds_signer = -1; + node->dnskey_signer = -1; node->chains = *chain_p; } @@ -3016,8 +3016,8 @@ static int rrset_in_list(getdns_rrset *rrset, getdns_list *list) return 0; } -static void append_canonical_rrset2val_chain_list( - getdns_list *val_chain_list, getdns_rrset *rrset, rrsig_iter *rrsig) +static void append_rrset2val_chain_list( + getdns_list *val_chain_list, getdns_rrset *rrset, int signer) { _getdns_rr_iter val_rrset_spc[VAL_RRSET_SPC_SZ]; _getdns_rr_iter *val_rrset = val_rrset_spc; @@ -3025,8 +3025,23 @@ static void append_canonical_rrset2val_chain_list( size_t n_rrs, i; uint32_t orig_ttl; getdns_dict *rr_dict; + rrsig_iter *rrsig, rrsig_spc; - assert(val_chain_list && rrset && rrsig); + assert(val_chain_list && rrset); + + if (signer < 0) + return; + + for ( rrsig = rrsig_iter_init(&rrsig_spc, rrset) + ; rrsig && + ( rrsig->rr_i.nxt < rrsig->rr_i.rr_type + 28 + || gldns_read_uint16(rrsig->rr_i.rr_type + 26) + != (signer & 0xFFFF)) + ; rrsig = rrsig_iter_next(rrsig)) + ; /* pass */ + + if (!rrsig) + return; /* keytag was already read, so orig_ttl should cause no problem */ assert(rrsig->rr_i.nxt >= rrsig->rr_i.rr_type + 18); @@ -3097,25 +3112,13 @@ static void append_rrs2val_chain_list(getdns_context *ctxt, rrset->rr_type != GETDNS_RRTYPE_DS) continue; - if ((signer & 0xFFFF)) { + if (signer > 0) { /* We have a signer! Return RRset in canonical * form and order with only the RRSIG that signed * the RRset. */ - for ( rrsig = rrsig_iter_init(&rrsig_spc, rrset) - ; rrsig && - ( rrsig->rr_i.nxt < rrsig->rr_i.rr_type + 28 - || gldns_read_uint16(rrsig->rr_i.rr_type + 26) - != (signer & 0xFFFF)) - ; rrsig = rrsig_iter_next(rrsig)) - ; /* pass */ - - if (!rrsig) { - /* Signer not found, try next RR set */ - continue; - } - append_canonical_rrset2val_chain_list( - val_chain_list, rrset, rrsig); + append_rrset2val_chain_list( + val_chain_list, rrset, signer); continue; } for ( rr = rrtype_iter_init(&rr_spc, rrset) @@ -3176,7 +3179,7 @@ static void check_chain_complete(chain_head *chain) getdns_dns_req *dnsreq; getdns_context *context; size_t o, node_count; - chain_head *head, *next; + chain_head *head, *next, *same_chain; chain_node *node; getdns_list *val_chain_list; getdns_dict *response_dict; @@ -3240,22 +3243,39 @@ static void check_chain_complete(chain_head *chain) /* Walk chain to add values to val_chain_list and to cleanup */ for ( head = chain; head ; head = next ) { next = head->next; + if (dnsreq->dnssec_return_full_validation_chain && + head->node_count && head->signer > 0) { + + append_rrset2val_chain_list( + val_chain_list, &head->rrset, head->signer); + + for ( same_chain = next + ; same_chain && same_chain->signer == head->signer + ; same_chain = same_chain->next) { + append_rrset2val_chain_list(val_chain_list, + &same_chain->rrset, same_chain->signer); + same_chain->signer = -1; + } + } for ( node_count = head->node_count, node = head->parent ; node_count ; node_count--, node = node->parent ) { if (node->dnskey_req) { - append_rrs2val_chain_list( - context, val_chain_list, - node->dnskey_req, node->dnskey_signer); + if (val_chain_list) + append_rrs2val_chain_list( + context, val_chain_list, + node->dnskey_req, + node->dnskey_signer); _getdns_dns_req_free(node->dnskey_req->owner); } if (node->ds_req) { - append_rrs2val_chain_list( - context, val_chain_list, - node->ds_req, node->ds_signer); + if (val_chain_list) + append_rrs2val_chain_list( + context, val_chain_list, + node->ds_req, node->ds_signer); - if (!node->ds_signer && + if (val_chain_list && node->ds_signer == -1 && !rrset_has_rrs(&node->ds)) { /* Add empty DS, to prevent less * specific to be able to authenticate diff --git a/src/general.c b/src/general.c index 4de98853..424a2630 100644 --- a/src/general.c +++ b/src/general.c @@ -403,6 +403,7 @@ validate_extensions(struct getdns_dict * extensions) {"add_opt_parameters" , t_dict, 1}, {"add_warning_for_bad_dns" , t_int , 1}, {"dnssec_return_all_statuses" , t_int , 1}, + {"dnssec_return_full_validation_chain", t_int , 1}, {"dnssec_return_only_secure" , t_int , 1}, {"dnssec_return_status" , t_int , 1}, {"dnssec_return_validation_chain", t_int , 1}, diff --git a/src/request-internal.c b/src/request-internal.c index f619429c..1c228c7c 100644 --- a/src/request-internal.c +++ b/src/request-internal.c @@ -658,6 +658,8 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop, = is_extension_set(extensions, "dnssec_return_only_secure"); int dnssec_return_all_statuses = is_extension_set(extensions, "dnssec_return_all_statuses"); + int dnssec_return_full_validation_chain + = is_extension_set(extensions, "dnssec_return_full_validation_chain"); int dnssec_return_validation_chain = is_extension_set(extensions, "dnssec_return_validation_chain"); int edns_cookies @@ -674,6 +676,7 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop, int dnssec_extension_set = dnssec_return_status || dnssec_return_only_secure || dnssec_return_all_statuses || dnssec_return_validation_chain + || dnssec_return_full_validation_chain || (extensions == dnssec_ok_checking_disabled) || (extensions == dnssec_ok_checking_disabled_roadblock_avoidance) || (extensions == dnssec_ok_checking_disabled_avoid_roadblocks) @@ -874,7 +877,10 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop, result->dnssec_return_status = dnssec_return_status; result->dnssec_return_only_secure = dnssec_return_only_secure; result->dnssec_return_all_statuses = dnssec_return_all_statuses; - result->dnssec_return_validation_chain = dnssec_return_validation_chain; + result->dnssec_return_full_validation_chain = + dnssec_return_full_validation_chain; + result->dnssec_return_validation_chain = dnssec_return_validation_chain + || dnssec_return_full_validation_chain; result->edns_cookies = edns_cookies; #ifdef DNSSEC_ROADBLOCK_AVOIDANCE result->dnssec_roadblock_avoidance = dnssec_roadblock_avoidance; diff --git a/src/test/getdns_query.c b/src/test/getdns_query.c index fb9df6f9..44af2b5a 100644 --- a/src/test/getdns_query.c +++ b/src/test/getdns_query.c @@ -474,6 +474,7 @@ print_usage(FILE *out, const char *progname) fprintf(out, "\t+dnssec_return_only_secure\n"); fprintf(out, "\t+dnssec_return_all_statuses\n"); fprintf(out, "\t+dnssec_return_validation_chain\n"); + fprintf(out, "\t+dnssec_return_full_validation_chain\n"); #ifdef DNSSEC_ROADBLOCK_AVOIDANCE fprintf(out, "\t+dnssec_roadblock_avoidance\n"); #endif diff --git a/src/types-internal.h b/src/types-internal.h index 9e9a4d34..5ff998c2 100644 --- a/src/types-internal.h +++ b/src/types-internal.h @@ -272,37 +272,39 @@ typedef struct getdns_dns_req { uint8_t name[256]; size_t name_len; - getdns_append_name_t append_name; - const uint8_t *suffix; - size_t suffix_len; - int suffix_appended; - uint16_t request_class; - /* canceled flag */ - int canceled; - /* context that owns the request */ struct getdns_context *context; + getdns_append_name_t append_name; + const uint8_t *suffix; + size_t suffix_len; + int suffix_appended : 1; + + /* canceled flag */ + int canceled : 1; + /* request extensions */ - int dnssec_return_status; - int dnssec_return_only_secure; - int dnssec_return_all_statuses; - int dnssec_return_validation_chain; + int dnssec_return_status : 1; + int dnssec_return_only_secure : 1; + int dnssec_return_all_statuses : 1; + int dnssec_return_validation_chain : 1; + int dnssec_return_full_validation_chain : 1; #ifdef DNSSEC_ROADBLOCK_AVOIDANCE - int dnssec_roadblock_avoidance; - int avoid_dnssec_roadblocks; + int dnssec_roadblock_avoidance : 1; + int avoid_dnssec_roadblocks : 1; #endif - int edns_cookies; - int edns_client_subnet_private; - uint16_t tls_query_padding_blocksize; - int return_call_reporting; - int add_warning_for_bad_dns; + int edns_cookies : 1; + int edns_client_subnet_private : 1; + int return_call_reporting : 1; + int add_warning_for_bad_dns : 1; /* Internally used by return_validation_chain */ - int dnssec_ok_checking_disabled; - int is_sync_request; + int dnssec_ok_checking_disabled : 1; + int is_sync_request : 1; + + uint16_t tls_query_padding_blocksize; /* internally scheduled request */ internal_cb_t internal_cb; diff --git a/src/util-internal.c b/src/util-internal.c index 84b4ef7e..919c7114 100644 --- a/src/util-internal.c +++ b/src/util-internal.c @@ -160,6 +160,9 @@ _getdns_rr_iter2rr_dict_canonical( uint8_t ff_bytes[256]; uint16_t rr_type; int canonicalize; + gldns_buffer gbuf; + getdns_bindata *bindata; + uint8_t *data; assert(i); if (!(rr_dict = _getdns_dict_create_with_mf(mf))) @@ -402,14 +405,8 @@ _getdns_rr_iter2rr_dict_canonical( goto rdata_error; if (canonicalize && rdata_sz) { - fprintf(stderr, "XXXXXXXXXX: owner_len: %zu, rdata_len: %zu\n", owner_len, rdata_sz); - - gldns_buffer gbuf; - getdns_bindata *bindata; - uint8_t *data = GETDNS_XMALLOC( - *mf, uint8_t, owner_len + 10 + rdata_sz); - - if (!data) + if (!(data = GETDNS_XMALLOC( + *mf, uint8_t, owner_len + 10 + rdata_sz))) return rr_dict; gldns_buffer_init_frm_data(&gbuf, data, owner_len+10+rdata_sz); From c05f963719cab35697e645ad5aaaa72794fcccfc Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Thu, 21 Apr 2016 12:24:53 +0200 Subject: [PATCH 3/7] Fail on debugging detected errors --- .../330-event-loops-unit-tests.test | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/test/tpkg/330-event-loops-unit-tests.tpkg/330-event-loops-unit-tests.test b/src/test/tpkg/330-event-loops-unit-tests.tpkg/330-event-loops-unit-tests.test index e80948e0..c6539115 100644 --- a/src/test/tpkg/330-event-loops-unit-tests.tpkg/330-event-loops-unit-tests.test +++ b/src/test/tpkg/330-event-loops-unit-tests.tpkg/330-event-loops-unit-tests.test @@ -5,4 +5,10 @@ [ -f .tpkg.var.test ] && source .tpkg.var.test cd "${BUILDDIR}/build-event-loops" -make test +if make test +then + if grep ERROR "${BUILDDIR}/build-event-loops/src/test/*.log" + then + exit 1 + fi +fi From 0bd40268985b12ab0cb418e27f925034e95981e2 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Thu, 21 Apr 2016 12:37:09 +0200 Subject: [PATCH 4/7] Detect freed memory usage with recursive queries Only when using unbound-event-api and doing queries for names in /etc/hosts --- .../tpkg/125-valgrind-checks.tpkg/125-valgrind-checks.test | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/test/tpkg/125-valgrind-checks.tpkg/125-valgrind-checks.test b/src/test/tpkg/125-valgrind-checks.tpkg/125-valgrind-checks.test index 60f216c7..0e7c4981 100644 --- a/src/test/tpkg/125-valgrind-checks.tpkg/125-valgrind-checks.test +++ b/src/test/tpkg/125-valgrind-checks.tpkg/125-valgrind-checks.test @@ -6,8 +6,12 @@ cat >queries < Date: Thu, 21 Apr 2016 15:16:38 +0200 Subject: [PATCH 5/7] Account for callbacks fired during scheduling --- src/dnssec.c | 2 +- src/general.c | 64 ++++++++++++++++++++++++++++++++---------- src/general.h | 4 ++- src/request-internal.c | 4 ++- src/types-internal.h | 6 ++++ 5 files changed, 62 insertions(+), 18 deletions(-) diff --git a/src/dnssec.c b/src/dnssec.c index 9bb95471..3e26f7b7 100644 --- a/src/dnssec.c +++ b/src/dnssec.c @@ -3181,7 +3181,7 @@ static void check_chain_complete(chain_head *chain) && !dnsreq->avoid_dnssec_roadblocks && dnsreq->netreqs[0]->dnssec_status == GETDNS_DNSSEC_BOGUS) { - getdns_return_t r = GETDNS_RETURN_GOOD; + int r = GETDNS_RETURN_GOOD; getdns_network_req **netreq_p, *netreq; dnsreq->avoid_dnssec_roadblocks = 1; diff --git a/src/general.c b/src/general.c index 4de98853..687fca2c 100644 --- a/src/general.c +++ b/src/general.c @@ -161,7 +161,7 @@ void _getdns_check_dns_req_complete(getdns_dns_req *dns_req) { getdns_network_req **netreq_p, *netreq; - int results_found = 0; + int results_found = 0, r; for (netreq_p = dns_req->netreqs; (netreq = *netreq_p); netreq_p++) if (netreq->state != NET_REQ_FINISHED && @@ -198,8 +198,11 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req) ; (netreq = *netreq_p) ; netreq_p++ ) { _getdns_netreq_reinit(netreq); - if (_getdns_submit_netreq(netreq)) + if ((r = _getdns_submit_netreq(netreq))) { + if (r == DNS_REQ_FINISHED) + return; netreq->state = NET_REQ_FINISHED; + } } _getdns_check_dns_req_complete(dns_req); return; @@ -233,8 +236,11 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req) ; (netreq = *netreq_p) ; netreq_p++ ) { _getdns_netreq_reinit(netreq); - if (_getdns_submit_netreq(netreq)) + if ((r = _getdns_submit_netreq(netreq))) { + if (r == DNS_REQ_FINISHED) + return; netreq->state = NET_REQ_FINISHED; + } } _getdns_check_dns_req_complete(dns_req); return; @@ -312,13 +318,16 @@ ub_resolve_callback(void* arg, int err, struct ub_result* ub_res) #endif -getdns_return_t +int _getdns_submit_netreq(getdns_network_req *netreq) { getdns_return_t r; getdns_dns_req *dns_req = netreq->owner; char name[1024]; - + int dnsreq_freed = 0; +#ifdef HAVE_LIBUNBOUND + int ub_resolve_r; +#endif #ifdef STUB_NATIVE_DNSSEC # ifdef DNSSEC_ROADBLOCK_AVOIDANCE @@ -351,24 +360,34 @@ _getdns_submit_netreq(getdns_network_req *netreq) dns_req->name_len, name, sizeof(name)); #ifdef HAVE_LIBUNBOUND + dns_req->freed = &dnsreq_freed; #ifdef HAVE_UNBOUND_EVENT_API if (_getdns_ub_loop_enabled(&dns_req->context->ub_loop)) - return ub_resolve_event(dns_req->context->unbound_ctx, + ub_resolve_r = ub_resolve_event(dns_req->context->unbound_ctx, name, netreq->request_type, netreq->owner->request_class, netreq, ub_resolve_event_callback, &(netreq->unbound_id)) ? GETDNS_RETURN_GENERIC_ERROR : GETDNS_RETURN_GOOD; else #endif - return ub_resolve_async(dns_req->context->unbound_ctx, + ub_resolve_r = ub_resolve_async(dns_req->context->unbound_ctx, name, netreq->request_type, netreq->owner->request_class, netreq, ub_resolve_callback, &(netreq->unbound_id)) ? GETDNS_RETURN_GENERIC_ERROR : GETDNS_RETURN_GOOD; + if (dnsreq_freed) + return DNS_REQ_FINISHED; + dns_req->freed = NULL; + return ub_resolve_r ? GETDNS_RETURN_GENERIC_ERROR : GETDNS_RETURN_GOOD; #else return GETDNS_RETURN_NOT_IMPLEMENTED; #endif } /* Submit with stub resolver */ - return _getdns_submit_stub_request(netreq); + dns_req->freed = &dnsreq_freed; + r = _getdns_submit_stub_request(netreq); + if (dnsreq_freed) + return DNS_REQ_FINISHED; + dns_req->freed = NULL; + return r; } @@ -456,7 +475,7 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop, void *userarg, getdns_network_req **return_netreq_p, getdns_callback_t callbackfn, internal_cb_t internal_cb, int usenamespaces) { - getdns_return_t r = GETDNS_RETURN_GOOD; + int r = GETDNS_RETURN_GOOD; getdns_network_req *netreq, **netreq_p; getdns_dns_req *req; getdns_dict *localnames_response; @@ -495,8 +514,16 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop, /* issue all network requests */ for ( netreq_p = req->netreqs ; !r && (netreq = *netreq_p) - ; netreq_p++) - r = _getdns_submit_netreq(netreq); + ; netreq_p++) { + if ((r = _getdns_submit_netreq(netreq))) { + if (r == DNS_REQ_FINISHED) { + if (return_netreq_p) + *return_netreq_p = NULL; + return GETDNS_RETURN_GOOD; + } + netreq->state = NET_REQ_FINISHED; + } + } else for (i = 0; i < context->namespace_count; i++) { if (context->namespaces[i] == GETDNS_NAMESPACE_LOCALNAMES) { @@ -517,14 +544,21 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop, r = GETDNS_RETURN_GOOD; for ( netreq_p = req->netreqs ; !r && (netreq = *netreq_p) - ; netreq_p++) - r = _getdns_submit_netreq(netreq); + ; netreq_p++) { + if ((r = _getdns_submit_netreq(netreq))) { + if (r == DNS_REQ_FINISHED) { + if (return_netreq_p) + *return_netreq_p = NULL; + return GETDNS_RETURN_GOOD; + } + netreq->state = NET_REQ_FINISHED; + } + } break; } else r = GETDNS_RETURN_BAD_CONTEXT; } - - if (r != 0) { + if (r > 0) { /* i.e. r != GETDNS_RETURN_GOOD && r != DNS_REQ_FINISHED */ /* clean up the request */ _getdns_context_clear_outbound_request(req); _getdns_dns_req_free(req); diff --git a/src/general.h b/src/general.h index e9a4529e..29b52f47 100644 --- a/src/general.h +++ b/src/general.h @@ -42,9 +42,11 @@ /* private inner helper used by sync and async */ +#define DNS_REQ_FINISHED -1 + void _getdns_call_user_callback(getdns_dns_req *, getdns_dict *); void _getdns_check_dns_req_complete(getdns_dns_req *dns_req); -getdns_return_t _getdns_submit_netreq(getdns_network_req *netreq); +int _getdns_submit_netreq(getdns_network_req *netreq); getdns_return_t diff --git a/src/request-internal.c b/src/request-internal.c index f619429c..b209a971 100644 --- a/src/request-internal.c +++ b/src/request-internal.c @@ -640,7 +640,8 @@ _getdns_dns_req_free(getdns_dns_req * req) req->loop->vmt->clear(req->loop, &req->timeout); req->timeout.timeout_cb = NULL; } - + if (req->freed) + *req->freed = 1; GETDNS_FREE(req->my_mf, req); } @@ -901,6 +902,7 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop, result->upstreams->referenced++; result->finished_next = NULL; + result->freed = NULL; network_req_init(result->netreqs[0], result, request_type, dnssec_extension_set, with_opt, diff --git a/src/types-internal.h b/src/types-internal.h index 9e9a4d34..b70b59f6 100644 --- a/src/types-internal.h +++ b/src/types-internal.h @@ -304,6 +304,12 @@ typedef struct getdns_dns_req { int dnssec_ok_checking_disabled; int is_sync_request; + /* Integer pointed to by pointer will be set to 1 (if set), + * before the request is freed. + * To be used by _getdns_submit_netreq only! + */ + int *freed; + /* internally scheduled request */ internal_cb_t internal_cb; From d61e64c9c7d32cee087f5e7c0cc1f6566e78292d Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Fri, 22 Apr 2016 14:09:18 +0200 Subject: [PATCH 6/7] Fix callbacks during scheduling in DNSSEC code too --- src/dnssec.c | 34 ++++++++++++++++++++++++++-------- src/request-internal.c | 1 + src/types-internal.h | 11 ++++++++--- 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/src/dnssec.c b/src/dnssec.c index 3e26f7b7..7674636c 100644 --- a/src/dnssec.c +++ b/src/dnssec.c @@ -736,6 +736,8 @@ typedef struct chain_node chain_node; struct chain_head { struct mem_funcs my_mf; + size_t lock; + chain_head *next; chain_node *parent; size_t node_count; /* Number of nodes attached directly @@ -857,6 +859,7 @@ static chain_head *add_rrset2val_chain(struct mem_funcs *mf, head = *chain_p = (chain_head *)region; head->my_mf = *mf; + head->lock = 1; head->next = NULL; head->rrset.name = head->name_spc; memcpy(head->name_spc, rrset->name, dname_len); @@ -1319,6 +1322,7 @@ static void val_chain_node_cb(getdns_dns_req *dnsreq) default : check_chain_complete(node->chains); return; } + node->lock++; n_signers = 0; for ( i = rrset_iter_init(&i_spc,netreq->response,netreq->response_len) ; i @@ -1344,6 +1348,7 @@ static void val_chain_node_cb(getdns_dns_req *dnsreq) */ val_chain_sched_soa_node(node->parent); + node->lock--; check_chain_complete(node->chains); } @@ -1363,17 +1368,21 @@ static void val_chain_node_soa_cb(getdns_dns_req *dnsreq) ! _dname_equal(node->ds.name, rrset->name)) node = node->parent; - if (node) + if (node) { + node->lock++; val_chain_sched_ds_node(node); - else { + } else { /* SOA for a different name */ node = (chain_node *)dnsreq->user_pointer; + node->lock++; val_chain_sched_soa_node(node->parent); } - } else if (node->parent) + } else if (node->parent) { + node->lock++; val_chain_sched_soa_node(node->parent); - + } + node->lock--; check_chain_complete(node->chains); } @@ -3003,7 +3012,7 @@ static size_t count_outstanding_requests(chain_head *head) if (!head) return 0; - for ( node = head->parent, count = 0 + for ( node = head->parent, count = head->lock ; node ; node = node->parent) { @@ -3245,6 +3254,7 @@ static void check_chain_complete(chain_head *chain) } /* Final user callback */ + dnsreq->validating = 0; _getdns_call_user_callback(dnsreq, response_dict); } @@ -3252,7 +3262,11 @@ static void check_chain_complete(chain_head *chain) void _getdns_get_validation_chain(getdns_dns_req *dnsreq) { getdns_network_req *netreq, **netreq_p; - chain_head *chain = NULL; + chain_head *chain = NULL, *chain_p; + + if (dnsreq->validating) + return; + dnsreq->validating = 1; for (netreq_p = dnsreq->netreqs; (netreq = *netreq_p) ; netreq_p++) { if (! netreq->response @@ -3277,11 +3291,15 @@ void _getdns_get_validation_chain(getdns_dns_req *dnsreq) , netreq ); } - if (chain) + if (chain) { + for (chain_p = chain; chain_p; chain_p = chain_p->next) + chain_p->lock--; check_chain_complete(chain); - else + } else { + dnsreq->validating = 0; _getdns_call_user_callback(dnsreq, _getdns_create_getdns_response(dnsreq)); + } } diff --git a/src/request-internal.c b/src/request-internal.c index b209a971..52f91d89 100644 --- a/src/request-internal.c +++ b/src/request-internal.c @@ -903,6 +903,7 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop, result->finished_next = NULL; result->freed = NULL; + result->validating = 0; network_req_init(result->netreqs[0], result, request_type, dnssec_extension_set, with_opt, diff --git a/src/types-internal.h b/src/types-internal.h index b70b59f6..1a49b8e5 100644 --- a/src/types-internal.h +++ b/src/types-internal.h @@ -304,10 +304,15 @@ typedef struct getdns_dns_req { int dnssec_ok_checking_disabled; int is_sync_request; - /* Integer pointed to by pointer will be set to 1 (if set), - * before the request is freed. - * To be used by _getdns_submit_netreq only! + /* The validating and freed variables are used to make sure a single + * code path is followed while processing a DNS request, even when + * callbacks are already fired whilst the registering/scheduling call + * (i.e. ub_resolve_event) has not returned yet. + * + * validating is touched by _getdns_get_validation_chain only and + * freed is touched by _getdns_submit_netreq only */ + int validating; int *freed; /* internally scheduled request */ From 8fc89d01cbf973e4c6992759ebf0e4a399089188 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Fri, 22 Apr 2016 14:43:17 +0200 Subject: [PATCH 7/7] Post devel/scheduling_bug_detection merge cleanups --- src/Makefile.in | 13 +++++++------ src/types-internal.h | 6 +++--- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/Makefile.in b/src/Makefile.in index c8f214dd..6449ec97 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -236,7 +236,7 @@ context.lo context.o: $(srcdir)/context.c \ getdns/getdns_extra.h \ $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/extension/default_eventloop.h $(srcdir)/ub_loop.h \ $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h \ - $(srcdir)/dnssec.h $(srcdir)/stub.h $(srcdir)/list.h $(srcdir)/dict.h $(srcdir)/pubkey-pinning.h + $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/list.h $(srcdir)/dict.h $(srcdir)/pubkey-pinning.h convert.lo convert.o: $(srcdir)/convert.c \ config.h \ getdns/getdns.h \ @@ -260,8 +260,9 @@ dnssec.lo dnssec.o: $(srcdir)/dnssec.c \ getdns/getdns_extra.h \ $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/extension/default_eventloop.h $(srcdir)/ub_loop.h \ $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h \ - $(srcdir)/dnssec.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h $(srcdir)/gldns/keyraw.h \ - $(srcdir)/gldns/parseutil.h $(srcdir)/general.h $(srcdir)/dict.h $(srcdir)/list.h $(srcdir)/util/val_secalgo.h + $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h \ + $(srcdir)/gldns/keyraw.h $(srcdir)/gldns/parseutil.h $(srcdir)/general.h $(srcdir)/dict.h $(srcdir)/list.h \ + $(srcdir)/util/val_secalgo.h general.lo general.o: $(srcdir)/general.c \ config.h $(srcdir)/general.h \ getdns/getdns.h \ @@ -269,7 +270,7 @@ general.lo general.o: $(srcdir)/general.c \ getdns/getdns_extra.h \ $(srcdir)/util/rbtree.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/gldns/wire2str.h $(srcdir)/context.h \ $(srcdir)/extension/default_eventloop.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \ - $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/stub.h $(srcdir)/dict.h + $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/dict.h list.lo list.o: $(srcdir)/list.c $(srcdir)/types-internal.h \ getdns/getdns.h \ getdns/getdns_extra.h \ @@ -319,7 +320,7 @@ sync.lo sync.o: $(srcdir)/sync.c \ getdns/getdns_extra.h \ $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/extension/default_eventloop.h $(srcdir)/ub_loop.h \ $(srcdir)/debug.h $(srcdir)/general.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \ - $(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/stub.h $(srcdir)/gldns/wire2str.h + $(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/gldns/wire2str.h ub_loop.lo ub_loop.o: $(srcdir)/ub_loop.c $(srcdir)/ub_loop.h \ config.h \ getdns/getdns.h \ @@ -332,7 +333,7 @@ util-internal.lo util-internal.o: $(srcdir)/util-internal.c \ getdns/getdns_extra.h \ $(srcdir)/list.h $(srcdir)/util-internal.h $(srcdir)/context.h $(srcdir)/extension/default_eventloop.h $(srcdir)/ub_loop.h \ $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h \ - $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h + $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h gbuffer.lo gbuffer.o: $(srcdir)/gldns/gbuffer.c \ config.h \ $(srcdir)/gldns/gbuffer.h diff --git a/src/types-internal.h b/src/types-internal.h index 09e89d3a..f63fde13 100644 --- a/src/types-internal.h +++ b/src/types-internal.h @@ -304,8 +304,6 @@ typedef struct getdns_dns_req { int dnssec_ok_checking_disabled : 1; int is_sync_request : 1; - uint16_t tls_query_padding_blocksize; - /* The validating and freed variables are used to make sure a single * code path is followed while processing a DNS request, even when * callbacks are already fired whilst the registering/scheduling call @@ -314,9 +312,11 @@ typedef struct getdns_dns_req { * validating is touched by _getdns_get_validation_chain only and * freed is touched by _getdns_submit_netreq only */ - int validating; + int validating : 1; int *freed; + uint16_t tls_query_padding_blocksize; + /* internally scheduled request */ internal_cb_t internal_cb;