diff --git a/daemon/worker.c b/daemon/worker.c index c2b7dc8e8..6f1f64647 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -785,8 +785,9 @@ static void chaos_trustanchor(sldns_buffer* pkt, struct edns_data* edns, struct worker* w) { int max_txt = 16; - int max_ids = 32; + int max_tags = 32; char* str_array[16]; + uint16_t tags[32]; int num = 0; struct trust_anchor* ta; @@ -799,12 +800,15 @@ chaos_trustanchor(sldns_buffer* pkt, struct edns_data* edns, struct worker* w) /* fill the string with contents */ lock_basic_lock(&w->env.anchors->lock); RBTREE_FOR(ta, struct trust_anchor*, w->env.anchors->tree) { - int numid = 0; - char* str = (char*)regional_alloc(w->scratchpad, 255); + int i, numtag; + char* str; size_t str_len = 255; - if(!str || num == max_txt) continue; + if(num == max_txt) continue; + str = (char*)regional_alloc(w->scratchpad, 255); + if(!str) continue; lock_basic_lock(&ta->lock); - if(ta->numDS == 0 && ta->numDNSKEY == 0) { + numtag = anchor_list_keytags(ta, tags, max_tags); + if(numtag == 0) { /* empty, insecure point */ lock_basic_unlock(&ta->lock); continue; @@ -815,29 +819,10 @@ chaos_trustanchor(sldns_buffer* pkt, struct edns_data* edns, struct worker* w) /* spool name of anchor */ (void)sldns_wire2str_dname_buf(ta->name, ta->namelen, str, str_len); str_len -= strlen(str); str += strlen(str); - /* spool DS */ - if(ta->numDS != 0 && ta->ds_rrset) { - struct packed_rrset_data* d=(struct packed_rrset_data*) - ta->ds_rrset->entry.data; - size_t i; - for(i=0; icount; i++) { - uint16_t tag = ds_get_keytag(ta->ds_rrset, i); - if(numid++ > max_ids) continue; - snprintf(str, str_len, " %u", (unsigned)tag); - str_len -= strlen(str); str += strlen(str); - } - } - /* spool DNSKEY */ - if(ta->numDNSKEY != 0 && ta->dnskey_rrset) { - struct packed_rrset_data* d=(struct packed_rrset_data*) - ta->dnskey_rrset->entry.data; - size_t i; - for(i=0; icount; i++) { - uint16_t tag = dnskey_calc_keytag(ta->dnskey_rrset, i); - if(numid++ > max_ids) continue; - snprintf(str, str_len, " %u", (unsigned)tag); - str_len -= strlen(str); str += strlen(str); - } + /* spool tags */ + for(i=0; ilock); } @@ -879,7 +864,7 @@ answer_chaos(struct worker* w, struct query_info* qinfo, chaos_replystr(pkt, (char**)&"no hostname", 1, edns, w); } } - else chaos_replystr(pkt, &cfg->identity, 1, edns, w); + else chaos_replystr(pkt, (char**)&cfg->identity, 1, edns, w); return 1; } if(query_dname_compare(qinfo->qname, diff --git a/doc/Changelog b/doc/Changelog index 54ac22d34..7277d6e59 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -4,6 +4,7 @@ of TXT RRs with a string like "example.com. 2345 1234" with the trust anchors and their keytags. - Fix that looped DNAMEs do not cause unbound to spend effort. + - trustanchor tags are sorted. reusable routine to fetch taglist. 13 March 2017: Wouter - testbound understands Deckard MATCH rcode question answer commands. diff --git a/validator/val_anchor.c b/validator/val_anchor.c index 2a7e0beeb..bd6a0da85 100644 --- a/validator/val_anchor.c +++ b/validator/val_anchor.c @@ -1273,3 +1273,37 @@ anchors_delete_insecure(struct val_anchors* anchors, uint16_t c, anchors_delfunc(&ta->node, NULL); } +/** compare two keytags, return -1, 0 or 1 */ +static int +keytag_compare(const void* x, const void* y) +{ + return *(uint16_t*)x - *(uint16_t*)y; +} + +int +anchor_list_keytags(struct trust_anchor* ta, uint16_t* list, int num) +{ + size_t i; + int ret = 0; + if(ta->numDS == 0 && ta->numDNSKEY == 0) + return 0; /* insecure point */ + if(ta->numDS != 0 && ta->ds_rrset) { + struct packed_rrset_data* d=(struct packed_rrset_data*) + ta->ds_rrset->entry.data; + for(i=0; icount; i++) { + if(ret == num) continue; + list[ret++] = ds_get_keytag(ta->ds_rrset, i); + } + } + if(ta->numDNSKEY != 0 && ta->dnskey_rrset) { + struct packed_rrset_data* d=(struct packed_rrset_data*) + ta->dnskey_rrset->entry.data; + for(i=0; icount; i++) { + if(ret == num) continue; + list[ret++] = dnskey_calc_keytag( + ta->dnskey_rrset, i); + } + } + qsort(list, ret, sizeof(*list), keytag_compare); + return ret; +} diff --git a/validator/val_anchor.h b/validator/val_anchor.h index 226165514..76a7b5482 100644 --- a/validator/val_anchor.h +++ b/validator/val_anchor.h @@ -216,4 +216,15 @@ int anchors_add_insecure(struct val_anchors* anchors, uint16_t c, uint8_t* nm); void anchors_delete_insecure(struct val_anchors* anchors, uint16_t c, uint8_t* nm); +/** + * Get a list of keytags for the trust anchor. Zero tags for insecure points. + * @param ta: trust anchor (locked by caller). + * @param list: array of uint16_t. + * @param num: length of array. + * @return number of keytags filled into array. If total number of keytags is + * bigger than the array, it is truncated at num. On errors, less keytags + * are filled in. The array is sorted. + */ +int anchor_list_keytags(struct trust_anchor* ta, uint16_t* list, int num); + #endif /* VALIDATOR_VAL_ANCHOR_H */