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;
/* 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;
/* 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; i<d->count; 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; i<d->count; 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; i<numtag; i++) {
+ snprintf(str, str_len, " %u", (unsigned)tags[i]);
+ str_len -= strlen(str); str += strlen(str);
}
lock_basic_unlock(&ta->lock);
}
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,
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; i<d->count; 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; i<d->count; i++) {
+ if(ret == num) continue;
+ list[ret++] = dnskey_calc_keytag(
+ ta->dnskey_rrset, i);
+ }
+ }
+ qsort(list, ret, sizeof(*list), keytag_compare);
+ return ret;
+}
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 */