1*7b5038d7SDag-Erling Smørgrav /* 2*7b5038d7SDag-Erling Smørgrav * special zone file structures and functions for better dnssec handling 3*7b5038d7SDag-Erling Smørgrav */ 4*7b5038d7SDag-Erling Smørgrav 5*7b5038d7SDag-Erling Smørgrav #include <ldns/config.h> 6*7b5038d7SDag-Erling Smørgrav 7*7b5038d7SDag-Erling Smørgrav #include <ldns/ldns.h> 8*7b5038d7SDag-Erling Smørgrav 9*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs * 10*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs_new(void) 11*7b5038d7SDag-Erling Smørgrav { 12*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs *new_rrs; 13*7b5038d7SDag-Erling Smørgrav new_rrs = LDNS_MALLOC(ldns_dnssec_rrs); 14*7b5038d7SDag-Erling Smørgrav if(!new_rrs) return NULL; 15*7b5038d7SDag-Erling Smørgrav new_rrs->rr = NULL; 16*7b5038d7SDag-Erling Smørgrav new_rrs->next = NULL; 17*7b5038d7SDag-Erling Smørgrav return new_rrs; 18*7b5038d7SDag-Erling Smørgrav } 19*7b5038d7SDag-Erling Smørgrav 20*7b5038d7SDag-Erling Smørgrav INLINE void 21*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs_free_internal(ldns_dnssec_rrs *rrs, int deep) 22*7b5038d7SDag-Erling Smørgrav { 23*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs *next; 24*7b5038d7SDag-Erling Smørgrav while (rrs) { 25*7b5038d7SDag-Erling Smørgrav next = rrs->next; 26*7b5038d7SDag-Erling Smørgrav if (deep) { 27*7b5038d7SDag-Erling Smørgrav ldns_rr_free(rrs->rr); 28*7b5038d7SDag-Erling Smørgrav } 29*7b5038d7SDag-Erling Smørgrav LDNS_FREE(rrs); 30*7b5038d7SDag-Erling Smørgrav rrs = next; 31*7b5038d7SDag-Erling Smørgrav } 32*7b5038d7SDag-Erling Smørgrav } 33*7b5038d7SDag-Erling Smørgrav 34*7b5038d7SDag-Erling Smørgrav void 35*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs_free(ldns_dnssec_rrs *rrs) 36*7b5038d7SDag-Erling Smørgrav { 37*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs_free_internal(rrs, 0); 38*7b5038d7SDag-Erling Smørgrav } 39*7b5038d7SDag-Erling Smørgrav 40*7b5038d7SDag-Erling Smørgrav void 41*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs_deep_free(ldns_dnssec_rrs *rrs) 42*7b5038d7SDag-Erling Smørgrav { 43*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs_free_internal(rrs, 1); 44*7b5038d7SDag-Erling Smørgrav } 45*7b5038d7SDag-Erling Smørgrav 46*7b5038d7SDag-Erling Smørgrav ldns_status 47*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs_add_rr(ldns_dnssec_rrs *rrs, ldns_rr *rr) 48*7b5038d7SDag-Erling Smørgrav { 49*7b5038d7SDag-Erling Smørgrav int cmp; 50*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs *new_rrs; 51*7b5038d7SDag-Erling Smørgrav if (!rrs || !rr) { 52*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 53*7b5038d7SDag-Erling Smørgrav } 54*7b5038d7SDag-Erling Smørgrav 55*7b5038d7SDag-Erling Smørgrav /* this could be done more efficiently; name and type should already 56*7b5038d7SDag-Erling Smørgrav be equal */ 57*7b5038d7SDag-Erling Smørgrav cmp = ldns_rr_compare(rrs->rr, 58*7b5038d7SDag-Erling Smørgrav rr); 59*7b5038d7SDag-Erling Smørgrav /* should we error on equal? */ 60*7b5038d7SDag-Erling Smørgrav if (cmp <= 0) { 61*7b5038d7SDag-Erling Smørgrav if (rrs->next) { 62*7b5038d7SDag-Erling Smørgrav return ldns_dnssec_rrs_add_rr(rrs->next, rr); 63*7b5038d7SDag-Erling Smørgrav } else { 64*7b5038d7SDag-Erling Smørgrav new_rrs = ldns_dnssec_rrs_new(); 65*7b5038d7SDag-Erling Smørgrav new_rrs->rr = rr; 66*7b5038d7SDag-Erling Smørgrav rrs->next = new_rrs; 67*7b5038d7SDag-Erling Smørgrav } 68*7b5038d7SDag-Erling Smørgrav } else if (cmp > 0) { 69*7b5038d7SDag-Erling Smørgrav /* put the current old rr in the new next, put the new 70*7b5038d7SDag-Erling Smørgrav rr in the current container */ 71*7b5038d7SDag-Erling Smørgrav new_rrs = ldns_dnssec_rrs_new(); 72*7b5038d7SDag-Erling Smørgrav new_rrs->rr = rrs->rr; 73*7b5038d7SDag-Erling Smørgrav new_rrs->next = rrs->next; 74*7b5038d7SDag-Erling Smørgrav rrs->rr = rr; 75*7b5038d7SDag-Erling Smørgrav rrs->next = new_rrs; 76*7b5038d7SDag-Erling Smørgrav } 77*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK; 78*7b5038d7SDag-Erling Smørgrav } 79*7b5038d7SDag-Erling Smørgrav 80*7b5038d7SDag-Erling Smørgrav void 81*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs_print_fmt(FILE *out, const ldns_output_format *fmt, 82*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs *rrs) 83*7b5038d7SDag-Erling Smørgrav { 84*7b5038d7SDag-Erling Smørgrav if (!rrs) { 85*7b5038d7SDag-Erling Smørgrav if ((fmt->flags & LDNS_COMMENT_LAYOUT)) 86*7b5038d7SDag-Erling Smørgrav fprintf(out, "; <void>"); 87*7b5038d7SDag-Erling Smørgrav } else { 88*7b5038d7SDag-Erling Smørgrav if (rrs->rr) { 89*7b5038d7SDag-Erling Smørgrav ldns_rr_print_fmt(out, fmt, rrs->rr); 90*7b5038d7SDag-Erling Smørgrav } 91*7b5038d7SDag-Erling Smørgrav if (rrs->next) { 92*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs_print_fmt(out, fmt, rrs->next); 93*7b5038d7SDag-Erling Smørgrav } 94*7b5038d7SDag-Erling Smørgrav } 95*7b5038d7SDag-Erling Smørgrav } 96*7b5038d7SDag-Erling Smørgrav 97*7b5038d7SDag-Erling Smørgrav void 98*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs_print(FILE *out, ldns_dnssec_rrs *rrs) 99*7b5038d7SDag-Erling Smørgrav { 100*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs_print_fmt(out, ldns_output_format_default, rrs); 101*7b5038d7SDag-Erling Smørgrav } 102*7b5038d7SDag-Erling Smørgrav 103*7b5038d7SDag-Erling Smørgrav 104*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets * 105*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_new(void) 106*7b5038d7SDag-Erling Smørgrav { 107*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets *new_rrsets; 108*7b5038d7SDag-Erling Smørgrav new_rrsets = LDNS_MALLOC(ldns_dnssec_rrsets); 109*7b5038d7SDag-Erling Smørgrav if(!new_rrsets) return NULL; 110*7b5038d7SDag-Erling Smørgrav new_rrsets->rrs = NULL; 111*7b5038d7SDag-Erling Smørgrav new_rrsets->type = 0; 112*7b5038d7SDag-Erling Smørgrav new_rrsets->signatures = NULL; 113*7b5038d7SDag-Erling Smørgrav new_rrsets->next = NULL; 114*7b5038d7SDag-Erling Smørgrav return new_rrsets; 115*7b5038d7SDag-Erling Smørgrav } 116*7b5038d7SDag-Erling Smørgrav 117*7b5038d7SDag-Erling Smørgrav INLINE void 118*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_free_internal(ldns_dnssec_rrsets *rrsets, int deep) 119*7b5038d7SDag-Erling Smørgrav { 120*7b5038d7SDag-Erling Smørgrav if (rrsets) { 121*7b5038d7SDag-Erling Smørgrav if (rrsets->rrs) { 122*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs_free_internal(rrsets->rrs, deep); 123*7b5038d7SDag-Erling Smørgrav } 124*7b5038d7SDag-Erling Smørgrav if (rrsets->next) { 125*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_free_internal(rrsets->next, deep); 126*7b5038d7SDag-Erling Smørgrav } 127*7b5038d7SDag-Erling Smørgrav if (rrsets->signatures) { 128*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs_free_internal(rrsets->signatures, deep); 129*7b5038d7SDag-Erling Smørgrav } 130*7b5038d7SDag-Erling Smørgrav LDNS_FREE(rrsets); 131*7b5038d7SDag-Erling Smørgrav } 132*7b5038d7SDag-Erling Smørgrav } 133*7b5038d7SDag-Erling Smørgrav 134*7b5038d7SDag-Erling Smørgrav void 135*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_free(ldns_dnssec_rrsets *rrsets) 136*7b5038d7SDag-Erling Smørgrav { 137*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_free_internal(rrsets, 0); 138*7b5038d7SDag-Erling Smørgrav } 139*7b5038d7SDag-Erling Smørgrav 140*7b5038d7SDag-Erling Smørgrav void 141*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_deep_free(ldns_dnssec_rrsets *rrsets) 142*7b5038d7SDag-Erling Smørgrav { 143*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_free_internal(rrsets, 1); 144*7b5038d7SDag-Erling Smørgrav } 145*7b5038d7SDag-Erling Smørgrav 146*7b5038d7SDag-Erling Smørgrav ldns_rr_type 147*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_type(ldns_dnssec_rrsets *rrsets) 148*7b5038d7SDag-Erling Smørgrav { 149*7b5038d7SDag-Erling Smørgrav if (rrsets) { 150*7b5038d7SDag-Erling Smørgrav return rrsets->type; 151*7b5038d7SDag-Erling Smørgrav } else { 152*7b5038d7SDag-Erling Smørgrav return 0; 153*7b5038d7SDag-Erling Smørgrav } 154*7b5038d7SDag-Erling Smørgrav } 155*7b5038d7SDag-Erling Smørgrav 156*7b5038d7SDag-Erling Smørgrav ldns_status 157*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_set_type(ldns_dnssec_rrsets *rrsets, 158*7b5038d7SDag-Erling Smørgrav ldns_rr_type type) 159*7b5038d7SDag-Erling Smørgrav { 160*7b5038d7SDag-Erling Smørgrav if (rrsets) { 161*7b5038d7SDag-Erling Smørgrav rrsets->type = type; 162*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK; 163*7b5038d7SDag-Erling Smørgrav } 164*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 165*7b5038d7SDag-Erling Smørgrav } 166*7b5038d7SDag-Erling Smørgrav 167*7b5038d7SDag-Erling Smørgrav static ldns_dnssec_rrsets * 168*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_new_frm_rr(ldns_rr *rr) 169*7b5038d7SDag-Erling Smørgrav { 170*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets *new_rrsets; 171*7b5038d7SDag-Erling Smørgrav ldns_rr_type rr_type; 172*7b5038d7SDag-Erling Smørgrav bool rrsig; 173*7b5038d7SDag-Erling Smørgrav 174*7b5038d7SDag-Erling Smørgrav new_rrsets = ldns_dnssec_rrsets_new(); 175*7b5038d7SDag-Erling Smørgrav rr_type = ldns_rr_get_type(rr); 176*7b5038d7SDag-Erling Smørgrav if (rr_type == LDNS_RR_TYPE_RRSIG) { 177*7b5038d7SDag-Erling Smørgrav rrsig = true; 178*7b5038d7SDag-Erling Smørgrav rr_type = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr)); 179*7b5038d7SDag-Erling Smørgrav } else { 180*7b5038d7SDag-Erling Smørgrav rrsig = false; 181*7b5038d7SDag-Erling Smørgrav } 182*7b5038d7SDag-Erling Smørgrav if (!rrsig) { 183*7b5038d7SDag-Erling Smørgrav new_rrsets->rrs = ldns_dnssec_rrs_new(); 184*7b5038d7SDag-Erling Smørgrav new_rrsets->rrs->rr = rr; 185*7b5038d7SDag-Erling Smørgrav } else { 186*7b5038d7SDag-Erling Smørgrav new_rrsets->signatures = ldns_dnssec_rrs_new(); 187*7b5038d7SDag-Erling Smørgrav new_rrsets->signatures->rr = rr; 188*7b5038d7SDag-Erling Smørgrav } 189*7b5038d7SDag-Erling Smørgrav new_rrsets->type = rr_type; 190*7b5038d7SDag-Erling Smørgrav return new_rrsets; 191*7b5038d7SDag-Erling Smørgrav } 192*7b5038d7SDag-Erling Smørgrav 193*7b5038d7SDag-Erling Smørgrav ldns_status 194*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_add_rr(ldns_dnssec_rrsets *rrsets, ldns_rr *rr) 195*7b5038d7SDag-Erling Smørgrav { 196*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets *new_rrsets; 197*7b5038d7SDag-Erling Smørgrav ldns_rr_type rr_type; 198*7b5038d7SDag-Erling Smørgrav bool rrsig = false; 199*7b5038d7SDag-Erling Smørgrav ldns_status result = LDNS_STATUS_OK; 200*7b5038d7SDag-Erling Smørgrav 201*7b5038d7SDag-Erling Smørgrav if (!rrsets || !rr) { 202*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 203*7b5038d7SDag-Erling Smørgrav } 204*7b5038d7SDag-Erling Smørgrav 205*7b5038d7SDag-Erling Smørgrav rr_type = ldns_rr_get_type(rr); 206*7b5038d7SDag-Erling Smørgrav 207*7b5038d7SDag-Erling Smørgrav if (rr_type == LDNS_RR_TYPE_RRSIG) { 208*7b5038d7SDag-Erling Smørgrav rrsig = true; 209*7b5038d7SDag-Erling Smørgrav rr_type = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr)); 210*7b5038d7SDag-Erling Smørgrav } 211*7b5038d7SDag-Erling Smørgrav 212*7b5038d7SDag-Erling Smørgrav if (!rrsets->rrs && rrsets->type == 0 && !rrsets->signatures) { 213*7b5038d7SDag-Erling Smørgrav if (!rrsig) { 214*7b5038d7SDag-Erling Smørgrav rrsets->rrs = ldns_dnssec_rrs_new(); 215*7b5038d7SDag-Erling Smørgrav rrsets->rrs->rr = rr; 216*7b5038d7SDag-Erling Smørgrav rrsets->type = rr_type; 217*7b5038d7SDag-Erling Smørgrav } else { 218*7b5038d7SDag-Erling Smørgrav rrsets->signatures = ldns_dnssec_rrs_new(); 219*7b5038d7SDag-Erling Smørgrav rrsets->signatures->rr = rr; 220*7b5038d7SDag-Erling Smørgrav rrsets->type = rr_type; 221*7b5038d7SDag-Erling Smørgrav } 222*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK; 223*7b5038d7SDag-Erling Smørgrav } 224*7b5038d7SDag-Erling Smørgrav 225*7b5038d7SDag-Erling Smørgrav if (rr_type > ldns_dnssec_rrsets_type(rrsets)) { 226*7b5038d7SDag-Erling Smørgrav if (rrsets->next) { 227*7b5038d7SDag-Erling Smørgrav result = ldns_dnssec_rrsets_add_rr(rrsets->next, rr); 228*7b5038d7SDag-Erling Smørgrav } else { 229*7b5038d7SDag-Erling Smørgrav new_rrsets = ldns_dnssec_rrsets_new_frm_rr(rr); 230*7b5038d7SDag-Erling Smørgrav rrsets->next = new_rrsets; 231*7b5038d7SDag-Erling Smørgrav } 232*7b5038d7SDag-Erling Smørgrav } else if (rr_type < ldns_dnssec_rrsets_type(rrsets)) { 233*7b5038d7SDag-Erling Smørgrav /* move the current one into the new next, 234*7b5038d7SDag-Erling Smørgrav replace field of current with data from new rr */ 235*7b5038d7SDag-Erling Smørgrav new_rrsets = ldns_dnssec_rrsets_new(); 236*7b5038d7SDag-Erling Smørgrav new_rrsets->rrs = rrsets->rrs; 237*7b5038d7SDag-Erling Smørgrav new_rrsets->type = rrsets->type; 238*7b5038d7SDag-Erling Smørgrav new_rrsets->signatures = rrsets->signatures; 239*7b5038d7SDag-Erling Smørgrav new_rrsets->next = rrsets->next; 240*7b5038d7SDag-Erling Smørgrav if (!rrsig) { 241*7b5038d7SDag-Erling Smørgrav rrsets->rrs = ldns_dnssec_rrs_new(); 242*7b5038d7SDag-Erling Smørgrav rrsets->rrs->rr = rr; 243*7b5038d7SDag-Erling Smørgrav rrsets->signatures = NULL; 244*7b5038d7SDag-Erling Smørgrav } else { 245*7b5038d7SDag-Erling Smørgrav rrsets->rrs = NULL; 246*7b5038d7SDag-Erling Smørgrav rrsets->signatures = ldns_dnssec_rrs_new(); 247*7b5038d7SDag-Erling Smørgrav rrsets->signatures->rr = rr; 248*7b5038d7SDag-Erling Smørgrav } 249*7b5038d7SDag-Erling Smørgrav rrsets->type = rr_type; 250*7b5038d7SDag-Erling Smørgrav rrsets->next = new_rrsets; 251*7b5038d7SDag-Erling Smørgrav } else { 252*7b5038d7SDag-Erling Smørgrav /* equal, add to current rrsets */ 253*7b5038d7SDag-Erling Smørgrav if (rrsig) { 254*7b5038d7SDag-Erling Smørgrav if (rrsets->signatures) { 255*7b5038d7SDag-Erling Smørgrav result = ldns_dnssec_rrs_add_rr(rrsets->signatures, rr); 256*7b5038d7SDag-Erling Smørgrav } else { 257*7b5038d7SDag-Erling Smørgrav rrsets->signatures = ldns_dnssec_rrs_new(); 258*7b5038d7SDag-Erling Smørgrav rrsets->signatures->rr = rr; 259*7b5038d7SDag-Erling Smørgrav } 260*7b5038d7SDag-Erling Smørgrav } else { 261*7b5038d7SDag-Erling Smørgrav if (rrsets->rrs) { 262*7b5038d7SDag-Erling Smørgrav result = ldns_dnssec_rrs_add_rr(rrsets->rrs, rr); 263*7b5038d7SDag-Erling Smørgrav } else { 264*7b5038d7SDag-Erling Smørgrav rrsets->rrs = ldns_dnssec_rrs_new(); 265*7b5038d7SDag-Erling Smørgrav rrsets->rrs->rr = rr; 266*7b5038d7SDag-Erling Smørgrav } 267*7b5038d7SDag-Erling Smørgrav } 268*7b5038d7SDag-Erling Smørgrav } 269*7b5038d7SDag-Erling Smørgrav 270*7b5038d7SDag-Erling Smørgrav return result; 271*7b5038d7SDag-Erling Smørgrav } 272*7b5038d7SDag-Erling Smørgrav 273*7b5038d7SDag-Erling Smørgrav static void 274*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_print_soa_fmt(FILE *out, const ldns_output_format *fmt, 275*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets *rrsets, 276*7b5038d7SDag-Erling Smørgrav bool follow, 277*7b5038d7SDag-Erling Smørgrav bool show_soa) 278*7b5038d7SDag-Erling Smørgrav { 279*7b5038d7SDag-Erling Smørgrav if (!rrsets) { 280*7b5038d7SDag-Erling Smørgrav if ((fmt->flags & LDNS_COMMENT_LAYOUT)) 281*7b5038d7SDag-Erling Smørgrav fprintf(out, "; <void>\n"); 282*7b5038d7SDag-Erling Smørgrav } else { 283*7b5038d7SDag-Erling Smørgrav if (rrsets->rrs && 284*7b5038d7SDag-Erling Smørgrav (show_soa || 285*7b5038d7SDag-Erling Smørgrav ldns_rr_get_type(rrsets->rrs->rr) != LDNS_RR_TYPE_SOA 286*7b5038d7SDag-Erling Smørgrav ) 287*7b5038d7SDag-Erling Smørgrav ) { 288*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs_print_fmt(out, fmt, rrsets->rrs); 289*7b5038d7SDag-Erling Smørgrav if (rrsets->signatures) { 290*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs_print_fmt(out, fmt, 291*7b5038d7SDag-Erling Smørgrav rrsets->signatures); 292*7b5038d7SDag-Erling Smørgrav } 293*7b5038d7SDag-Erling Smørgrav } 294*7b5038d7SDag-Erling Smørgrav if (follow && rrsets->next) { 295*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_print_soa_fmt(out, fmt, 296*7b5038d7SDag-Erling Smørgrav rrsets->next, follow, show_soa); 297*7b5038d7SDag-Erling Smørgrav } 298*7b5038d7SDag-Erling Smørgrav } 299*7b5038d7SDag-Erling Smørgrav } 300*7b5038d7SDag-Erling Smørgrav 301*7b5038d7SDag-Erling Smørgrav static void 302*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_print_soa(FILE *out, 303*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets *rrsets, 304*7b5038d7SDag-Erling Smørgrav bool follow, 305*7b5038d7SDag-Erling Smørgrav bool show_soa) 306*7b5038d7SDag-Erling Smørgrav { 307*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_print_soa_fmt(out, ldns_output_format_default, 308*7b5038d7SDag-Erling Smørgrav rrsets, follow, show_soa); 309*7b5038d7SDag-Erling Smørgrav } 310*7b5038d7SDag-Erling Smørgrav 311*7b5038d7SDag-Erling Smørgrav 312*7b5038d7SDag-Erling Smørgrav void 313*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_print_fmt(FILE *out, const ldns_output_format *fmt, 314*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets *rrsets, 315*7b5038d7SDag-Erling Smørgrav bool follow) 316*7b5038d7SDag-Erling Smørgrav { 317*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_print_soa_fmt(out, fmt, rrsets, follow, true); 318*7b5038d7SDag-Erling Smørgrav } 319*7b5038d7SDag-Erling Smørgrav 320*7b5038d7SDag-Erling Smørgrav void 321*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_print(FILE *out, ldns_dnssec_rrsets *rrsets, bool follow) 322*7b5038d7SDag-Erling Smørgrav { 323*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_print_fmt(out, ldns_output_format_default, 324*7b5038d7SDag-Erling Smørgrav rrsets, follow); 325*7b5038d7SDag-Erling Smørgrav } 326*7b5038d7SDag-Erling Smørgrav 327*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name * 328*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name_new(void) 329*7b5038d7SDag-Erling Smørgrav { 330*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name *new_name; 331*7b5038d7SDag-Erling Smørgrav 332*7b5038d7SDag-Erling Smørgrav new_name = LDNS_CALLOC(ldns_dnssec_name, 1); 333*7b5038d7SDag-Erling Smørgrav if (!new_name) { 334*7b5038d7SDag-Erling Smørgrav return NULL; 335*7b5038d7SDag-Erling Smørgrav } 336*7b5038d7SDag-Erling Smørgrav /* 337*7b5038d7SDag-Erling Smørgrav * not needed anymore because CALLOC initalizes everything to zero. 338*7b5038d7SDag-Erling Smørgrav 339*7b5038d7SDag-Erling Smørgrav new_name->name = NULL; 340*7b5038d7SDag-Erling Smørgrav new_name->rrsets = NULL; 341*7b5038d7SDag-Erling Smørgrav new_name->name_alloced = false; 342*7b5038d7SDag-Erling Smørgrav new_name->nsec = NULL; 343*7b5038d7SDag-Erling Smørgrav new_name->nsec_signatures = NULL; 344*7b5038d7SDag-Erling Smørgrav 345*7b5038d7SDag-Erling Smørgrav new_name->is_glue = false; 346*7b5038d7SDag-Erling Smørgrav new_name->hashed_name = NULL; 347*7b5038d7SDag-Erling Smørgrav 348*7b5038d7SDag-Erling Smørgrav */ 349*7b5038d7SDag-Erling Smørgrav return new_name; 350*7b5038d7SDag-Erling Smørgrav } 351*7b5038d7SDag-Erling Smørgrav 352*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name * 353*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name_new_frm_rr(ldns_rr *rr) 354*7b5038d7SDag-Erling Smørgrav { 355*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name *new_name = ldns_dnssec_name_new(); 356*7b5038d7SDag-Erling Smørgrav 357*7b5038d7SDag-Erling Smørgrav new_name->name = ldns_rr_owner(rr); 358*7b5038d7SDag-Erling Smørgrav if(ldns_dnssec_name_add_rr(new_name, rr) != LDNS_STATUS_OK) { 359*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name_free(new_name); 360*7b5038d7SDag-Erling Smørgrav return NULL; 361*7b5038d7SDag-Erling Smørgrav } 362*7b5038d7SDag-Erling Smørgrav 363*7b5038d7SDag-Erling Smørgrav return new_name; 364*7b5038d7SDag-Erling Smørgrav } 365*7b5038d7SDag-Erling Smørgrav 366*7b5038d7SDag-Erling Smørgrav INLINE void 367*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name_free_internal(ldns_dnssec_name *name, 368*7b5038d7SDag-Erling Smørgrav int deep) 369*7b5038d7SDag-Erling Smørgrav { 370*7b5038d7SDag-Erling Smørgrav if (name) { 371*7b5038d7SDag-Erling Smørgrav if (name->name_alloced) { 372*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(name->name); 373*7b5038d7SDag-Erling Smørgrav } 374*7b5038d7SDag-Erling Smørgrav if (name->rrsets) { 375*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_free_internal(name->rrsets, deep); 376*7b5038d7SDag-Erling Smørgrav } 377*7b5038d7SDag-Erling Smørgrav if (name->nsec && deep) { 378*7b5038d7SDag-Erling Smørgrav ldns_rr_free(name->nsec); 379*7b5038d7SDag-Erling Smørgrav } 380*7b5038d7SDag-Erling Smørgrav if (name->nsec_signatures) { 381*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs_free_internal(name->nsec_signatures, deep); 382*7b5038d7SDag-Erling Smørgrav } 383*7b5038d7SDag-Erling Smørgrav if (name->hashed_name) { 384*7b5038d7SDag-Erling Smørgrav if (deep) { 385*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(name->hashed_name); 386*7b5038d7SDag-Erling Smørgrav } 387*7b5038d7SDag-Erling Smørgrav } 388*7b5038d7SDag-Erling Smørgrav LDNS_FREE(name); 389*7b5038d7SDag-Erling Smørgrav } 390*7b5038d7SDag-Erling Smørgrav } 391*7b5038d7SDag-Erling Smørgrav 392*7b5038d7SDag-Erling Smørgrav void 393*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name_free(ldns_dnssec_name *name) 394*7b5038d7SDag-Erling Smørgrav { 395*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name_free_internal(name, 0); 396*7b5038d7SDag-Erling Smørgrav } 397*7b5038d7SDag-Erling Smørgrav 398*7b5038d7SDag-Erling Smørgrav void 399*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name_deep_free(ldns_dnssec_name *name) 400*7b5038d7SDag-Erling Smørgrav { 401*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name_free_internal(name, 1); 402*7b5038d7SDag-Erling Smørgrav } 403*7b5038d7SDag-Erling Smørgrav 404*7b5038d7SDag-Erling Smørgrav ldns_rdf * 405*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name_name(ldns_dnssec_name *name) 406*7b5038d7SDag-Erling Smørgrav { 407*7b5038d7SDag-Erling Smørgrav if (name) { 408*7b5038d7SDag-Erling Smørgrav return name->name; 409*7b5038d7SDag-Erling Smørgrav } 410*7b5038d7SDag-Erling Smørgrav return NULL; 411*7b5038d7SDag-Erling Smørgrav } 412*7b5038d7SDag-Erling Smørgrav 413*7b5038d7SDag-Erling Smørgrav bool 414*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name_is_glue(ldns_dnssec_name *name) 415*7b5038d7SDag-Erling Smørgrav { 416*7b5038d7SDag-Erling Smørgrav if (name) { 417*7b5038d7SDag-Erling Smørgrav return name->is_glue; 418*7b5038d7SDag-Erling Smørgrav } 419*7b5038d7SDag-Erling Smørgrav return false; 420*7b5038d7SDag-Erling Smørgrav } 421*7b5038d7SDag-Erling Smørgrav 422*7b5038d7SDag-Erling Smørgrav void 423*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name_set_name(ldns_dnssec_name *rrset, 424*7b5038d7SDag-Erling Smørgrav ldns_rdf *dname) 425*7b5038d7SDag-Erling Smørgrav { 426*7b5038d7SDag-Erling Smørgrav if (rrset && dname) { 427*7b5038d7SDag-Erling Smørgrav rrset->name = dname; 428*7b5038d7SDag-Erling Smørgrav } 429*7b5038d7SDag-Erling Smørgrav } 430*7b5038d7SDag-Erling Smørgrav 431*7b5038d7SDag-Erling Smørgrav static ldns_rr * 432*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name_nsec(ldns_dnssec_name *rrset) 433*7b5038d7SDag-Erling Smørgrav { 434*7b5038d7SDag-Erling Smørgrav if (rrset) { 435*7b5038d7SDag-Erling Smørgrav return rrset->nsec; 436*7b5038d7SDag-Erling Smørgrav } 437*7b5038d7SDag-Erling Smørgrav return NULL; 438*7b5038d7SDag-Erling Smørgrav } 439*7b5038d7SDag-Erling Smørgrav 440*7b5038d7SDag-Erling Smørgrav void 441*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name_set_nsec(ldns_dnssec_name *rrset, ldns_rr *nsec) 442*7b5038d7SDag-Erling Smørgrav { 443*7b5038d7SDag-Erling Smørgrav if (rrset && nsec) { 444*7b5038d7SDag-Erling Smørgrav rrset->nsec = nsec; 445*7b5038d7SDag-Erling Smørgrav } 446*7b5038d7SDag-Erling Smørgrav } 447*7b5038d7SDag-Erling Smørgrav 448*7b5038d7SDag-Erling Smørgrav int 449*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name_cmp(const void *a, const void *b) 450*7b5038d7SDag-Erling Smørgrav { 451*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name *na = (ldns_dnssec_name *) a; 452*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name *nb = (ldns_dnssec_name *) b; 453*7b5038d7SDag-Erling Smørgrav 454*7b5038d7SDag-Erling Smørgrav if (na && nb) { 455*7b5038d7SDag-Erling Smørgrav return ldns_dname_compare(ldns_dnssec_name_name(na), 456*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name_name(nb)); 457*7b5038d7SDag-Erling Smørgrav } else if (na) { 458*7b5038d7SDag-Erling Smørgrav return 1; 459*7b5038d7SDag-Erling Smørgrav } else if (nb) { 460*7b5038d7SDag-Erling Smørgrav return -1; 461*7b5038d7SDag-Erling Smørgrav } else { 462*7b5038d7SDag-Erling Smørgrav return 0; 463*7b5038d7SDag-Erling Smørgrav } 464*7b5038d7SDag-Erling Smørgrav } 465*7b5038d7SDag-Erling Smørgrav 466*7b5038d7SDag-Erling Smørgrav ldns_status 467*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name_add_rr(ldns_dnssec_name *name, 468*7b5038d7SDag-Erling Smørgrav ldns_rr *rr) 469*7b5038d7SDag-Erling Smørgrav { 470*7b5038d7SDag-Erling Smørgrav ldns_status result = LDNS_STATUS_OK; 471*7b5038d7SDag-Erling Smørgrav ldns_rdf *name_name; 472*7b5038d7SDag-Erling Smørgrav bool hashed_name = false; 473*7b5038d7SDag-Erling Smørgrav ldns_rr_type rr_type; 474*7b5038d7SDag-Erling Smørgrav ldns_rr_type typecovered = 0; 475*7b5038d7SDag-Erling Smørgrav 476*7b5038d7SDag-Erling Smørgrav /* special handling for NSEC3 and NSECX covering RRSIGS */ 477*7b5038d7SDag-Erling Smørgrav 478*7b5038d7SDag-Erling Smørgrav if (!name || !rr) { 479*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 480*7b5038d7SDag-Erling Smørgrav } 481*7b5038d7SDag-Erling Smørgrav 482*7b5038d7SDag-Erling Smørgrav rr_type = ldns_rr_get_type(rr); 483*7b5038d7SDag-Erling Smørgrav 484*7b5038d7SDag-Erling Smørgrav if (rr_type == LDNS_RR_TYPE_RRSIG) { 485*7b5038d7SDag-Erling Smørgrav typecovered = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr)); 486*7b5038d7SDag-Erling Smørgrav } 487*7b5038d7SDag-Erling Smørgrav 488*7b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 489*7b5038d7SDag-Erling Smørgrav if (rr_type == LDNS_RR_TYPE_NSEC3 || 490*7b5038d7SDag-Erling Smørgrav typecovered == LDNS_RR_TYPE_NSEC3) { 491*7b5038d7SDag-Erling Smørgrav name_name = ldns_nsec3_hash_name_frm_nsec3(rr, 492*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name_name(name)); 493*7b5038d7SDag-Erling Smørgrav hashed_name = true; 494*7b5038d7SDag-Erling Smørgrav } else { 495*7b5038d7SDag-Erling Smørgrav name_name = ldns_dnssec_name_name(name); 496*7b5038d7SDag-Erling Smørgrav } 497*7b5038d7SDag-Erling Smørgrav #else 498*7b5038d7SDag-Erling Smørgrav name_name = ldns_dnssec_name_name(name); 499*7b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 500*7b5038d7SDag-Erling Smørgrav 501*7b5038d7SDag-Erling Smørgrav if (rr_type == LDNS_RR_TYPE_NSEC || 502*7b5038d7SDag-Erling Smørgrav rr_type == LDNS_RR_TYPE_NSEC3) { 503*7b5038d7SDag-Erling Smørgrav /* XX check if is already set (and error?) */ 504*7b5038d7SDag-Erling Smørgrav name->nsec = rr; 505*7b5038d7SDag-Erling Smørgrav } else if (typecovered == LDNS_RR_TYPE_NSEC || 506*7b5038d7SDag-Erling Smørgrav typecovered == LDNS_RR_TYPE_NSEC3) { 507*7b5038d7SDag-Erling Smørgrav if (name->nsec_signatures) { 508*7b5038d7SDag-Erling Smørgrav result = ldns_dnssec_rrs_add_rr(name->nsec_signatures, rr); 509*7b5038d7SDag-Erling Smørgrav } else { 510*7b5038d7SDag-Erling Smørgrav name->nsec_signatures = ldns_dnssec_rrs_new(); 511*7b5038d7SDag-Erling Smørgrav name->nsec_signatures->rr = rr; 512*7b5038d7SDag-Erling Smørgrav } 513*7b5038d7SDag-Erling Smørgrav } else { 514*7b5038d7SDag-Erling Smørgrav /* it's a 'normal' RR, add it to the right rrset */ 515*7b5038d7SDag-Erling Smørgrav if (name->rrsets) { 516*7b5038d7SDag-Erling Smørgrav result = ldns_dnssec_rrsets_add_rr(name->rrsets, rr); 517*7b5038d7SDag-Erling Smørgrav } else { 518*7b5038d7SDag-Erling Smørgrav name->rrsets = ldns_dnssec_rrsets_new(); 519*7b5038d7SDag-Erling Smørgrav result = ldns_dnssec_rrsets_add_rr(name->rrsets, rr); 520*7b5038d7SDag-Erling Smørgrav } 521*7b5038d7SDag-Erling Smørgrav } 522*7b5038d7SDag-Erling Smørgrav 523*7b5038d7SDag-Erling Smørgrav if (hashed_name) { 524*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(name_name); 525*7b5038d7SDag-Erling Smørgrav } 526*7b5038d7SDag-Erling Smørgrav 527*7b5038d7SDag-Erling Smørgrav return result; 528*7b5038d7SDag-Erling Smørgrav } 529*7b5038d7SDag-Erling Smørgrav 530*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets * 531*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name_find_rrset(ldns_dnssec_name *name, 532*7b5038d7SDag-Erling Smørgrav ldns_rr_type type) { 533*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets *result; 534*7b5038d7SDag-Erling Smørgrav 535*7b5038d7SDag-Erling Smørgrav result = name->rrsets; 536*7b5038d7SDag-Erling Smørgrav while (result) { 537*7b5038d7SDag-Erling Smørgrav if (result->type == type) { 538*7b5038d7SDag-Erling Smørgrav return result; 539*7b5038d7SDag-Erling Smørgrav } else { 540*7b5038d7SDag-Erling Smørgrav result = result->next; 541*7b5038d7SDag-Erling Smørgrav } 542*7b5038d7SDag-Erling Smørgrav } 543*7b5038d7SDag-Erling Smørgrav return NULL; 544*7b5038d7SDag-Erling Smørgrav } 545*7b5038d7SDag-Erling Smørgrav 546*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets * 547*7b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_find_rrset(ldns_dnssec_zone *zone, 548*7b5038d7SDag-Erling Smørgrav ldns_rdf *dname, 549*7b5038d7SDag-Erling Smørgrav ldns_rr_type type) 550*7b5038d7SDag-Erling Smørgrav { 551*7b5038d7SDag-Erling Smørgrav ldns_rbnode_t *node; 552*7b5038d7SDag-Erling Smørgrav 553*7b5038d7SDag-Erling Smørgrav if (!zone || !dname) { 554*7b5038d7SDag-Erling Smørgrav return NULL; 555*7b5038d7SDag-Erling Smørgrav } 556*7b5038d7SDag-Erling Smørgrav 557*7b5038d7SDag-Erling Smørgrav node = ldns_rbtree_search(zone->names, dname); 558*7b5038d7SDag-Erling Smørgrav if (node) { 559*7b5038d7SDag-Erling Smørgrav return ldns_dnssec_name_find_rrset((ldns_dnssec_name *)node->data, 560*7b5038d7SDag-Erling Smørgrav type); 561*7b5038d7SDag-Erling Smørgrav } else { 562*7b5038d7SDag-Erling Smørgrav return NULL; 563*7b5038d7SDag-Erling Smørgrav } 564*7b5038d7SDag-Erling Smørgrav } 565*7b5038d7SDag-Erling Smørgrav 566*7b5038d7SDag-Erling Smørgrav static void 567*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name_print_soa_fmt(FILE *out, const ldns_output_format *fmt, 568*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name *name, 569*7b5038d7SDag-Erling Smørgrav bool show_soa) 570*7b5038d7SDag-Erling Smørgrav { 571*7b5038d7SDag-Erling Smørgrav if (name) { 572*7b5038d7SDag-Erling Smørgrav if(name->rrsets) { 573*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_print_soa_fmt(out, fmt, 574*7b5038d7SDag-Erling Smørgrav name->rrsets, true, show_soa); 575*7b5038d7SDag-Erling Smørgrav } else if ((fmt->flags & LDNS_COMMENT_LAYOUT)) { 576*7b5038d7SDag-Erling Smørgrav fprintf(out, ";; Empty nonterminal: "); 577*7b5038d7SDag-Erling Smørgrav ldns_rdf_print(out, name->name); 578*7b5038d7SDag-Erling Smørgrav fprintf(out, "\n"); 579*7b5038d7SDag-Erling Smørgrav } 580*7b5038d7SDag-Erling Smørgrav if(name->nsec) { 581*7b5038d7SDag-Erling Smørgrav ldns_rr_print_fmt(out, fmt, name->nsec); 582*7b5038d7SDag-Erling Smørgrav } 583*7b5038d7SDag-Erling Smørgrav if (name->nsec_signatures) { 584*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs_print_fmt(out, fmt, 585*7b5038d7SDag-Erling Smørgrav name->nsec_signatures); 586*7b5038d7SDag-Erling Smørgrav } 587*7b5038d7SDag-Erling Smørgrav } else if ((fmt->flags & LDNS_COMMENT_LAYOUT)) { 588*7b5038d7SDag-Erling Smørgrav fprintf(out, "; <void>\n"); 589*7b5038d7SDag-Erling Smørgrav } 590*7b5038d7SDag-Erling Smørgrav } 591*7b5038d7SDag-Erling Smørgrav 592*7b5038d7SDag-Erling Smørgrav static void 593*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name_print_soa(FILE *out, ldns_dnssec_name *name, bool show_soa) 594*7b5038d7SDag-Erling Smørgrav { 595*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name_print_soa_fmt(out, ldns_output_format_default, 596*7b5038d7SDag-Erling Smørgrav name, show_soa); 597*7b5038d7SDag-Erling Smørgrav } 598*7b5038d7SDag-Erling Smørgrav 599*7b5038d7SDag-Erling Smørgrav void 600*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name_print_fmt(FILE *out, const ldns_output_format *fmt, 601*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name *name) 602*7b5038d7SDag-Erling Smørgrav { 603*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name_print_soa_fmt(out, fmt, name, true); 604*7b5038d7SDag-Erling Smørgrav } 605*7b5038d7SDag-Erling Smørgrav 606*7b5038d7SDag-Erling Smørgrav void 607*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name_print(FILE *out, ldns_dnssec_name *name) 608*7b5038d7SDag-Erling Smørgrav { 609*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name_print_fmt(out, ldns_output_format_default, name); 610*7b5038d7SDag-Erling Smørgrav } 611*7b5038d7SDag-Erling Smørgrav 612*7b5038d7SDag-Erling Smørgrav 613*7b5038d7SDag-Erling Smørgrav ldns_dnssec_zone * 614*7b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_new(void) 615*7b5038d7SDag-Erling Smørgrav { 616*7b5038d7SDag-Erling Smørgrav ldns_dnssec_zone *zone = LDNS_MALLOC(ldns_dnssec_zone); 617*7b5038d7SDag-Erling Smørgrav if(!zone) return NULL; 618*7b5038d7SDag-Erling Smørgrav zone->soa = NULL; 619*7b5038d7SDag-Erling Smørgrav zone->names = NULL; 620*7b5038d7SDag-Erling Smørgrav 621*7b5038d7SDag-Erling Smørgrav return zone; 622*7b5038d7SDag-Erling Smørgrav } 623*7b5038d7SDag-Erling Smørgrav 624*7b5038d7SDag-Erling Smørgrav static bool 625*7b5038d7SDag-Erling Smørgrav rr_is_rrsig_covering(ldns_rr* rr, ldns_rr_type t) 626*7b5038d7SDag-Erling Smørgrav { 627*7b5038d7SDag-Erling Smørgrav return ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG 628*7b5038d7SDag-Erling Smørgrav && ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr)) == t; 629*7b5038d7SDag-Erling Smørgrav } 630*7b5038d7SDag-Erling Smørgrav 631*7b5038d7SDag-Erling Smørgrav /* When the zone is first read into an list and then inserted into an 632*7b5038d7SDag-Erling Smørgrav * ldns_dnssec_zone (rbtree) the nodes of the rbtree are allocated close (next) 633*7b5038d7SDag-Erling Smørgrav * to each other. Because ldns-verify-zone (the only program that uses this 634*7b5038d7SDag-Erling Smørgrav * function) uses the rbtree mostly for sequentual walking, this results 635*7b5038d7SDag-Erling Smørgrav * in a speed increase (of 15% on linux) because we have less CPU-cache misses. 636*7b5038d7SDag-Erling Smørgrav */ 637*7b5038d7SDag-Erling Smørgrav #define FASTER_DNSSEC_ZONE_NEW_FRM_FP 1 /* Because of L2 cache efficiency */ 638*7b5038d7SDag-Erling Smørgrav 639*7b5038d7SDag-Erling Smørgrav ldns_status 640*7b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_new_frm_fp_l(ldns_dnssec_zone** z, FILE* fp, ldns_rdf* origin, 641*7b5038d7SDag-Erling Smørgrav uint32_t ttl, ldns_rr_class ATTR_UNUSED(c), int* line_nr) 642*7b5038d7SDag-Erling Smørgrav { 643*7b5038d7SDag-Erling Smørgrav ldns_rr* cur_rr; 644*7b5038d7SDag-Erling Smørgrav size_t i; 645*7b5038d7SDag-Erling Smørgrav 646*7b5038d7SDag-Erling Smørgrav ldns_rdf *my_origin = NULL; 647*7b5038d7SDag-Erling Smørgrav ldns_rdf *my_prev = NULL; 648*7b5038d7SDag-Erling Smørgrav 649*7b5038d7SDag-Erling Smørgrav ldns_dnssec_zone *newzone = ldns_dnssec_zone_new(); 650*7b5038d7SDag-Erling Smørgrav /* when reading NSEC3s, there is a chance that we encounter nsecs 651*7b5038d7SDag-Erling Smørgrav for empty nonterminals, whose nonterminals we cannot derive yet 652*7b5038d7SDag-Erling Smørgrav because the needed information is to be read later. in that case 653*7b5038d7SDag-Erling Smørgrav we keep a list of those nsec3's and retry to add them later */ 654*7b5038d7SDag-Erling Smørgrav ldns_rr_list* todo_nsec3s = ldns_rr_list_new(); 655*7b5038d7SDag-Erling Smørgrav ldns_rr_list* todo_nsec3_rrsigs = ldns_rr_list_new(); 656*7b5038d7SDag-Erling Smørgrav 657*7b5038d7SDag-Erling Smørgrav ldns_status status = LDNS_STATUS_MEM_ERR; 658*7b5038d7SDag-Erling Smørgrav 659*7b5038d7SDag-Erling Smørgrav #ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP 660*7b5038d7SDag-Erling Smørgrav ldns_zone* zone = NULL; 661*7b5038d7SDag-Erling Smørgrav if (ldns_zone_new_frm_fp_l(&zone, fp, origin,ttl, c, line_nr) 662*7b5038d7SDag-Erling Smørgrav != LDNS_STATUS_OK) goto error; 663*7b5038d7SDag-Erling Smørgrav #else 664*7b5038d7SDag-Erling Smørgrav uint32_t my_ttl = ttl; 665*7b5038d7SDag-Erling Smørgrav #endif 666*7b5038d7SDag-Erling Smørgrav 667*7b5038d7SDag-Erling Smørgrav if (!newzone || !todo_nsec3s || !todo_nsec3_rrsigs ) goto error; 668*7b5038d7SDag-Erling Smørgrav 669*7b5038d7SDag-Erling Smørgrav if (origin) { 670*7b5038d7SDag-Erling Smørgrav if (!(my_origin = ldns_rdf_clone(origin))) goto error; 671*7b5038d7SDag-Erling Smørgrav if (!(my_prev = ldns_rdf_clone(origin))) goto error; 672*7b5038d7SDag-Erling Smørgrav } 673*7b5038d7SDag-Erling Smørgrav 674*7b5038d7SDag-Erling Smørgrav #ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP 675*7b5038d7SDag-Erling Smørgrav if (ldns_dnssec_zone_add_rr(newzone, ldns_zone_soa(zone)) 676*7b5038d7SDag-Erling Smørgrav != LDNS_STATUS_OK) goto error; 677*7b5038d7SDag-Erling Smørgrav 678*7b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) { 679*7b5038d7SDag-Erling Smørgrav cur_rr = ldns_rr_list_rr(ldns_zone_rrs(zone), i); 680*7b5038d7SDag-Erling Smørgrav status = LDNS_STATUS_OK; 681*7b5038d7SDag-Erling Smørgrav #else 682*7b5038d7SDag-Erling Smørgrav while (!feof(fp)) { 683*7b5038d7SDag-Erling Smørgrav status = ldns_rr_new_frm_fp_l(&cur_rr, fp, &my_ttl, &my_origin, 684*7b5038d7SDag-Erling Smørgrav &my_prev, line_nr); 685*7b5038d7SDag-Erling Smørgrav 686*7b5038d7SDag-Erling Smørgrav #endif 687*7b5038d7SDag-Erling Smørgrav switch (status) { 688*7b5038d7SDag-Erling Smørgrav case LDNS_STATUS_OK: 689*7b5038d7SDag-Erling Smørgrav 690*7b5038d7SDag-Erling Smørgrav status = ldns_dnssec_zone_add_rr(newzone, cur_rr); 691*7b5038d7SDag-Erling Smørgrav if (status == 692*7b5038d7SDag-Erling Smørgrav LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND) { 693*7b5038d7SDag-Erling Smørgrav 694*7b5038d7SDag-Erling Smørgrav if (rr_is_rrsig_covering(cur_rr, 695*7b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_NSEC3)){ 696*7b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr(todo_nsec3_rrsigs, 697*7b5038d7SDag-Erling Smørgrav cur_rr); 698*7b5038d7SDag-Erling Smørgrav } else { 699*7b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr(todo_nsec3s, 700*7b5038d7SDag-Erling Smørgrav cur_rr); 701*7b5038d7SDag-Erling Smørgrav } 702*7b5038d7SDag-Erling Smørgrav } else if (status != LDNS_STATUS_OK) 703*7b5038d7SDag-Erling Smørgrav goto error; 704*7b5038d7SDag-Erling Smørgrav 705*7b5038d7SDag-Erling Smørgrav break; 706*7b5038d7SDag-Erling Smørgrav 707*7b5038d7SDag-Erling Smørgrav 708*7b5038d7SDag-Erling Smørgrav case LDNS_STATUS_SYNTAX_EMPTY: /* empty line was seen */ 709*7b5038d7SDag-Erling Smørgrav case LDNS_STATUS_SYNTAX_TTL: /* the ttl was set*/ 710*7b5038d7SDag-Erling Smørgrav case LDNS_STATUS_SYNTAX_ORIGIN: /* the origin was set*/ 711*7b5038d7SDag-Erling Smørgrav break; 712*7b5038d7SDag-Erling Smørgrav 713*7b5038d7SDag-Erling Smørgrav case LDNS_STATUS_SYNTAX_INCLUDE:/* $include not implemented */ 714*7b5038d7SDag-Erling Smørgrav status = LDNS_STATUS_SYNTAX_INCLUDE_ERR_NOTIMPL; 715*7b5038d7SDag-Erling Smørgrav break; 716*7b5038d7SDag-Erling Smørgrav 717*7b5038d7SDag-Erling Smørgrav default: 718*7b5038d7SDag-Erling Smørgrav goto error; 719*7b5038d7SDag-Erling Smørgrav } 720*7b5038d7SDag-Erling Smørgrav } 721*7b5038d7SDag-Erling Smørgrav 722*7b5038d7SDag-Erling Smørgrav if (ldns_rr_list_rr_count(todo_nsec3s) > 0) { 723*7b5038d7SDag-Erling Smørgrav (void) ldns_dnssec_zone_add_empty_nonterminals(newzone); 724*7b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(todo_nsec3s); i++) { 725*7b5038d7SDag-Erling Smørgrav cur_rr = ldns_rr_list_rr(todo_nsec3s, i); 726*7b5038d7SDag-Erling Smørgrav status = ldns_dnssec_zone_add_rr(newzone, cur_rr); 727*7b5038d7SDag-Erling Smørgrav } 728*7b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(todo_nsec3_rrsigs); i++){ 729*7b5038d7SDag-Erling Smørgrav cur_rr = ldns_rr_list_rr(todo_nsec3_rrsigs, i); 730*7b5038d7SDag-Erling Smørgrav status = ldns_dnssec_zone_add_rr(newzone, cur_rr); 731*7b5038d7SDag-Erling Smørgrav } 732*7b5038d7SDag-Erling Smørgrav } else if (ldns_rr_list_rr_count(todo_nsec3_rrsigs) > 0) { 733*7b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(todo_nsec3_rrsigs); i++){ 734*7b5038d7SDag-Erling Smørgrav cur_rr = ldns_rr_list_rr(todo_nsec3_rrsigs, i); 735*7b5038d7SDag-Erling Smørgrav status = ldns_dnssec_zone_add_rr(newzone, cur_rr); 736*7b5038d7SDag-Erling Smørgrav } 737*7b5038d7SDag-Erling Smørgrav } 738*7b5038d7SDag-Erling Smørgrav 739*7b5038d7SDag-Erling Smørgrav ldns_rr_list_free(todo_nsec3_rrsigs); 740*7b5038d7SDag-Erling Smørgrav ldns_rr_list_free(todo_nsec3s); 741*7b5038d7SDag-Erling Smørgrav 742*7b5038d7SDag-Erling Smørgrav if (z) { 743*7b5038d7SDag-Erling Smørgrav *z = newzone; 744*7b5038d7SDag-Erling Smørgrav } else { 745*7b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_free(newzone); 746*7b5038d7SDag-Erling Smørgrav } 747*7b5038d7SDag-Erling Smørgrav 748*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK; 749*7b5038d7SDag-Erling Smørgrav 750*7b5038d7SDag-Erling Smørgrav error: 751*7b5038d7SDag-Erling Smørgrav #ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP 752*7b5038d7SDag-Erling Smørgrav if (zone) { 753*7b5038d7SDag-Erling Smørgrav ldns_zone_free(zone); 754*7b5038d7SDag-Erling Smørgrav } 755*7b5038d7SDag-Erling Smørgrav #endif 756*7b5038d7SDag-Erling Smørgrav if (my_origin) { 757*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(my_origin); 758*7b5038d7SDag-Erling Smørgrav } 759*7b5038d7SDag-Erling Smørgrav if (my_prev) { 760*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(my_prev); 761*7b5038d7SDag-Erling Smørgrav } 762*7b5038d7SDag-Erling Smørgrav if (newzone) { 763*7b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_free(newzone); 764*7b5038d7SDag-Erling Smørgrav } 765*7b5038d7SDag-Erling Smørgrav return status; 766*7b5038d7SDag-Erling Smørgrav } 767*7b5038d7SDag-Erling Smørgrav 768*7b5038d7SDag-Erling Smørgrav ldns_status 769*7b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_new_frm_fp(ldns_dnssec_zone** z, FILE* fp, ldns_rdf* origin, 770*7b5038d7SDag-Erling Smørgrav uint32_t ttl, ldns_rr_class ATTR_UNUSED(c)) 771*7b5038d7SDag-Erling Smørgrav { 772*7b5038d7SDag-Erling Smørgrav return ldns_dnssec_zone_new_frm_fp_l(z, fp, origin, ttl, c, NULL); 773*7b5038d7SDag-Erling Smørgrav } 774*7b5038d7SDag-Erling Smørgrav 775*7b5038d7SDag-Erling Smørgrav static void 776*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name_node_free(ldns_rbnode_t *node, void *arg) { 777*7b5038d7SDag-Erling Smørgrav (void) arg; 778*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name_free((ldns_dnssec_name *)node->data); 779*7b5038d7SDag-Erling Smørgrav LDNS_FREE(node); 780*7b5038d7SDag-Erling Smørgrav } 781*7b5038d7SDag-Erling Smørgrav 782*7b5038d7SDag-Erling Smørgrav static void 783*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name_node_deep_free(ldns_rbnode_t *node, void *arg) { 784*7b5038d7SDag-Erling Smørgrav (void) arg; 785*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name_deep_free((ldns_dnssec_name *)node->data); 786*7b5038d7SDag-Erling Smørgrav LDNS_FREE(node); 787*7b5038d7SDag-Erling Smørgrav } 788*7b5038d7SDag-Erling Smørgrav 789*7b5038d7SDag-Erling Smørgrav void 790*7b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_free(ldns_dnssec_zone *zone) 791*7b5038d7SDag-Erling Smørgrav { 792*7b5038d7SDag-Erling Smørgrav if (zone) { 793*7b5038d7SDag-Erling Smørgrav if (zone->names) { 794*7b5038d7SDag-Erling Smørgrav /* destroy all name structures within the tree */ 795*7b5038d7SDag-Erling Smørgrav ldns_traverse_postorder(zone->names, 796*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name_node_free, 797*7b5038d7SDag-Erling Smørgrav NULL); 798*7b5038d7SDag-Erling Smørgrav LDNS_FREE(zone->names); 799*7b5038d7SDag-Erling Smørgrav } 800*7b5038d7SDag-Erling Smørgrav LDNS_FREE(zone); 801*7b5038d7SDag-Erling Smørgrav } 802*7b5038d7SDag-Erling Smørgrav } 803*7b5038d7SDag-Erling Smørgrav 804*7b5038d7SDag-Erling Smørgrav void 805*7b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_deep_free(ldns_dnssec_zone *zone) 806*7b5038d7SDag-Erling Smørgrav { 807*7b5038d7SDag-Erling Smørgrav if (zone) { 808*7b5038d7SDag-Erling Smørgrav if (zone->names) { 809*7b5038d7SDag-Erling Smørgrav /* destroy all name structures within the tree */ 810*7b5038d7SDag-Erling Smørgrav ldns_traverse_postorder(zone->names, 811*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name_node_deep_free, 812*7b5038d7SDag-Erling Smørgrav NULL); 813*7b5038d7SDag-Erling Smørgrav LDNS_FREE(zone->names); 814*7b5038d7SDag-Erling Smørgrav } 815*7b5038d7SDag-Erling Smørgrav LDNS_FREE(zone); 816*7b5038d7SDag-Erling Smørgrav } 817*7b5038d7SDag-Erling Smørgrav } 818*7b5038d7SDag-Erling Smørgrav 819*7b5038d7SDag-Erling Smørgrav /* use for dname comparison in tree */ 820*7b5038d7SDag-Erling Smørgrav static int 821*7b5038d7SDag-Erling Smørgrav ldns_dname_compare_v(const void *a, const void *b) { 822*7b5038d7SDag-Erling Smørgrav return ldns_dname_compare((ldns_rdf *)a, (ldns_rdf *)b); 823*7b5038d7SDag-Erling Smørgrav } 824*7b5038d7SDag-Erling Smørgrav 825*7b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 826*7b5038d7SDag-Erling Smørgrav static ldns_rbnode_t * 827*7b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_find_nsec3_original(ldns_dnssec_zone *zone, 828*7b5038d7SDag-Erling Smørgrav ldns_rr *rr) { 829*7b5038d7SDag-Erling Smørgrav ldns_rbnode_t *current_node = ldns_rbtree_first(zone->names); 830*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name *current_name; 831*7b5038d7SDag-Erling Smørgrav ldns_rdf *hashed_name; 832*7b5038d7SDag-Erling Smørgrav 833*7b5038d7SDag-Erling Smørgrav hashed_name = ldns_dname_label(ldns_rr_owner(rr), 0); 834*7b5038d7SDag-Erling Smørgrav 835*7b5038d7SDag-Erling Smørgrav while (current_node != LDNS_RBTREE_NULL) { 836*7b5038d7SDag-Erling Smørgrav current_name = (ldns_dnssec_name *) current_node->data; 837*7b5038d7SDag-Erling Smørgrav if (!current_name->hashed_name) { 838*7b5038d7SDag-Erling Smørgrav current_name->hashed_name = 839*7b5038d7SDag-Erling Smørgrav ldns_nsec3_hash_name_frm_nsec3(rr, current_name->name); 840*7b5038d7SDag-Erling Smørgrav } 841*7b5038d7SDag-Erling Smørgrav if (ldns_dname_compare(hashed_name, 842*7b5038d7SDag-Erling Smørgrav current_name->hashed_name) 843*7b5038d7SDag-Erling Smørgrav == 0) { 844*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(hashed_name); 845*7b5038d7SDag-Erling Smørgrav return current_node; 846*7b5038d7SDag-Erling Smørgrav } 847*7b5038d7SDag-Erling Smørgrav current_node = ldns_rbtree_next(current_node); 848*7b5038d7SDag-Erling Smørgrav } 849*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(hashed_name); 850*7b5038d7SDag-Erling Smørgrav return NULL; 851*7b5038d7SDag-Erling Smørgrav } 852*7b5038d7SDag-Erling Smørgrav 853*7b5038d7SDag-Erling Smørgrav ldns_status 854*7b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_add_rr(ldns_dnssec_zone *zone, ldns_rr *rr) 855*7b5038d7SDag-Erling Smørgrav { 856*7b5038d7SDag-Erling Smørgrav ldns_status result = LDNS_STATUS_OK; 857*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name *cur_name; 858*7b5038d7SDag-Erling Smørgrav ldns_rbnode_t *cur_node; 859*7b5038d7SDag-Erling Smørgrav ldns_rr_type type_covered = 0; 860*7b5038d7SDag-Erling Smørgrav 861*7b5038d7SDag-Erling Smørgrav if (!zone || !rr) { 862*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 863*7b5038d7SDag-Erling Smørgrav } 864*7b5038d7SDag-Erling Smørgrav 865*7b5038d7SDag-Erling Smørgrav if (!zone->names) { 866*7b5038d7SDag-Erling Smørgrav zone->names = ldns_rbtree_create(ldns_dname_compare_v); 867*7b5038d7SDag-Erling Smørgrav if(!zone->names) return LDNS_STATUS_MEM_ERR; 868*7b5038d7SDag-Erling Smørgrav } 869*7b5038d7SDag-Erling Smørgrav 870*7b5038d7SDag-Erling Smørgrav /* we need the original of the hashed name if this is 871*7b5038d7SDag-Erling Smørgrav an NSEC3, or an RRSIG that covers an NSEC3 */ 872*7b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG) { 873*7b5038d7SDag-Erling Smørgrav type_covered = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr)); 874*7b5038d7SDag-Erling Smørgrav } 875*7b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_NSEC3 || 876*7b5038d7SDag-Erling Smørgrav type_covered == LDNS_RR_TYPE_NSEC3) { 877*7b5038d7SDag-Erling Smørgrav cur_node = ldns_dnssec_zone_find_nsec3_original(zone, 878*7b5038d7SDag-Erling Smørgrav rr); 879*7b5038d7SDag-Erling Smørgrav if (!cur_node) { 880*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND; 881*7b5038d7SDag-Erling Smørgrav } 882*7b5038d7SDag-Erling Smørgrav } else { 883*7b5038d7SDag-Erling Smørgrav cur_node = ldns_rbtree_search(zone->names, ldns_rr_owner(rr)); 884*7b5038d7SDag-Erling Smørgrav } 885*7b5038d7SDag-Erling Smørgrav 886*7b5038d7SDag-Erling Smørgrav if (!cur_node) { 887*7b5038d7SDag-Erling Smørgrav /* add */ 888*7b5038d7SDag-Erling Smørgrav cur_name = ldns_dnssec_name_new_frm_rr(rr); 889*7b5038d7SDag-Erling Smørgrav if(!cur_name) return LDNS_STATUS_MEM_ERR; 890*7b5038d7SDag-Erling Smørgrav cur_node = LDNS_MALLOC(ldns_rbnode_t); 891*7b5038d7SDag-Erling Smørgrav if(!cur_node) { 892*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name_free(cur_name); 893*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR; 894*7b5038d7SDag-Erling Smørgrav } 895*7b5038d7SDag-Erling Smørgrav cur_node->key = ldns_rr_owner(rr); 896*7b5038d7SDag-Erling Smørgrav cur_node->data = cur_name; 897*7b5038d7SDag-Erling Smørgrav (void)ldns_rbtree_insert(zone->names, cur_node); 898*7b5038d7SDag-Erling Smørgrav } else { 899*7b5038d7SDag-Erling Smørgrav cur_name = (ldns_dnssec_name *) cur_node->data; 900*7b5038d7SDag-Erling Smørgrav result = ldns_dnssec_name_add_rr(cur_name, rr); 901*7b5038d7SDag-Erling Smørgrav } 902*7b5038d7SDag-Erling Smørgrav 903*7b5038d7SDag-Erling Smørgrav if (result != LDNS_STATUS_OK) { 904*7b5038d7SDag-Erling Smørgrav fprintf(stderr, "error adding rr: "); 905*7b5038d7SDag-Erling Smørgrav ldns_rr_print(stderr, rr); 906*7b5038d7SDag-Erling Smørgrav } 907*7b5038d7SDag-Erling Smørgrav 908*7b5038d7SDag-Erling Smørgrav /*TODO ldns_dnssec_name_print_names(stdout, zone->names, 0);*/ 909*7b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) { 910*7b5038d7SDag-Erling Smørgrav zone->soa = cur_name; 911*7b5038d7SDag-Erling Smørgrav } 912*7b5038d7SDag-Erling Smørgrav 913*7b5038d7SDag-Erling Smørgrav return result; 914*7b5038d7SDag-Erling Smørgrav } 915*7b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 916*7b5038d7SDag-Erling Smørgrav 917*7b5038d7SDag-Erling Smørgrav void 918*7b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_names_print_fmt(FILE *out, const ldns_output_format *fmt, 919*7b5038d7SDag-Erling Smørgrav ldns_rbtree_t *tree, 920*7b5038d7SDag-Erling Smørgrav bool print_soa) 921*7b5038d7SDag-Erling Smørgrav { 922*7b5038d7SDag-Erling Smørgrav ldns_rbnode_t *node; 923*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name *name; 924*7b5038d7SDag-Erling Smørgrav 925*7b5038d7SDag-Erling Smørgrav node = ldns_rbtree_first(tree); 926*7b5038d7SDag-Erling Smørgrav while (node != LDNS_RBTREE_NULL) { 927*7b5038d7SDag-Erling Smørgrav name = (ldns_dnssec_name *) node->data; 928*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name_print_soa_fmt(out, fmt, name, print_soa); 929*7b5038d7SDag-Erling Smørgrav if ((fmt->flags & LDNS_COMMENT_LAYOUT)) 930*7b5038d7SDag-Erling Smørgrav fprintf(out, ";\n"); 931*7b5038d7SDag-Erling Smørgrav node = ldns_rbtree_next(node); 932*7b5038d7SDag-Erling Smørgrav } 933*7b5038d7SDag-Erling Smørgrav } 934*7b5038d7SDag-Erling Smørgrav 935*7b5038d7SDag-Erling Smørgrav void 936*7b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_names_print(FILE *out, ldns_rbtree_t *tree, bool print_soa) 937*7b5038d7SDag-Erling Smørgrav { 938*7b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_names_print_fmt(out, ldns_output_format_default, 939*7b5038d7SDag-Erling Smørgrav tree, print_soa); 940*7b5038d7SDag-Erling Smørgrav } 941*7b5038d7SDag-Erling Smørgrav 942*7b5038d7SDag-Erling Smørgrav void 943*7b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_print_fmt(FILE *out, const ldns_output_format *fmt, 944*7b5038d7SDag-Erling Smørgrav ldns_dnssec_zone *zone) 945*7b5038d7SDag-Erling Smørgrav { 946*7b5038d7SDag-Erling Smørgrav if (zone) { 947*7b5038d7SDag-Erling Smørgrav if (zone->soa) { 948*7b5038d7SDag-Erling Smørgrav if ((fmt->flags & LDNS_COMMENT_LAYOUT)) { 949*7b5038d7SDag-Erling Smørgrav fprintf(out, ";; Zone: "); 950*7b5038d7SDag-Erling Smørgrav ldns_rdf_print(out, ldns_dnssec_name_name( 951*7b5038d7SDag-Erling Smørgrav zone->soa)); 952*7b5038d7SDag-Erling Smørgrav fprintf(out, "\n;\n"); 953*7b5038d7SDag-Erling Smørgrav } 954*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_print_fmt(out, fmt, 955*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name_find_rrset( 956*7b5038d7SDag-Erling Smørgrav zone->soa, 957*7b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_SOA), 958*7b5038d7SDag-Erling Smørgrav false); 959*7b5038d7SDag-Erling Smørgrav if ((fmt->flags & LDNS_COMMENT_LAYOUT)) 960*7b5038d7SDag-Erling Smørgrav fprintf(out, ";\n"); 961*7b5038d7SDag-Erling Smørgrav } 962*7b5038d7SDag-Erling Smørgrav 963*7b5038d7SDag-Erling Smørgrav if (zone->names) { 964*7b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_names_print_fmt(out, fmt, 965*7b5038d7SDag-Erling Smørgrav zone->names, false); 966*7b5038d7SDag-Erling Smørgrav } 967*7b5038d7SDag-Erling Smørgrav } 968*7b5038d7SDag-Erling Smørgrav } 969*7b5038d7SDag-Erling Smørgrav 970*7b5038d7SDag-Erling Smørgrav void 971*7b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_print(FILE *out, ldns_dnssec_zone *zone) 972*7b5038d7SDag-Erling Smørgrav { 973*7b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_print_fmt(out, ldns_output_format_default, zone); 974*7b5038d7SDag-Erling Smørgrav } 975*7b5038d7SDag-Erling Smørgrav 976*7b5038d7SDag-Erling Smørgrav ldns_status 977*7b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_add_empty_nonterminals(ldns_dnssec_zone *zone) 978*7b5038d7SDag-Erling Smørgrav { 979*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name *new_name; 980*7b5038d7SDag-Erling Smørgrav ldns_rdf *cur_name; 981*7b5038d7SDag-Erling Smørgrav ldns_rdf *next_name; 982*7b5038d7SDag-Erling Smørgrav ldns_rbnode_t *cur_node, *next_node, *new_node; 983*7b5038d7SDag-Erling Smørgrav 984*7b5038d7SDag-Erling Smørgrav /* for the detection */ 985*7b5038d7SDag-Erling Smørgrav uint16_t i, cur_label_count, next_label_count; 986*7b5038d7SDag-Erling Smørgrav uint16_t soa_label_count = 0; 987*7b5038d7SDag-Erling Smørgrav ldns_rdf *l1, *l2; 988*7b5038d7SDag-Erling Smørgrav int lpos; 989*7b5038d7SDag-Erling Smørgrav 990*7b5038d7SDag-Erling Smørgrav if (!zone) { 991*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 992*7b5038d7SDag-Erling Smørgrav } 993*7b5038d7SDag-Erling Smørgrav if (zone->soa && zone->soa->name) { 994*7b5038d7SDag-Erling Smørgrav soa_label_count = ldns_dname_label_count(zone->soa->name); 995*7b5038d7SDag-Erling Smørgrav } 996*7b5038d7SDag-Erling Smørgrav 997*7b5038d7SDag-Erling Smørgrav cur_node = ldns_rbtree_first(zone->names); 998*7b5038d7SDag-Erling Smørgrav while (cur_node != LDNS_RBTREE_NULL) { 999*7b5038d7SDag-Erling Smørgrav next_node = ldns_rbtree_next(cur_node); 1000*7b5038d7SDag-Erling Smørgrav 1001*7b5038d7SDag-Erling Smørgrav /* skip glue */ 1002*7b5038d7SDag-Erling Smørgrav while (next_node != LDNS_RBTREE_NULL && 1003*7b5038d7SDag-Erling Smørgrav next_node->data && 1004*7b5038d7SDag-Erling Smørgrav ((ldns_dnssec_name *)next_node->data)->is_glue 1005*7b5038d7SDag-Erling Smørgrav ) { 1006*7b5038d7SDag-Erling Smørgrav next_node = ldns_rbtree_next(next_node); 1007*7b5038d7SDag-Erling Smørgrav } 1008*7b5038d7SDag-Erling Smørgrav 1009*7b5038d7SDag-Erling Smørgrav if (next_node == LDNS_RBTREE_NULL) { 1010*7b5038d7SDag-Erling Smørgrav next_node = ldns_rbtree_first(zone->names); 1011*7b5038d7SDag-Erling Smørgrav } 1012*7b5038d7SDag-Erling Smørgrav 1013*7b5038d7SDag-Erling Smørgrav cur_name = ((ldns_dnssec_name *)cur_node->data)->name; 1014*7b5038d7SDag-Erling Smørgrav next_name = ((ldns_dnssec_name *)next_node->data)->name; 1015*7b5038d7SDag-Erling Smørgrav cur_label_count = ldns_dname_label_count(cur_name); 1016*7b5038d7SDag-Erling Smørgrav next_label_count = ldns_dname_label_count(next_name); 1017*7b5038d7SDag-Erling Smørgrav 1018*7b5038d7SDag-Erling Smørgrav /* Since the names are in canonical order, we can 1019*7b5038d7SDag-Erling Smørgrav * recognize empty non-terminals by their labels; 1020*7b5038d7SDag-Erling Smørgrav * every label after the first one on the next owner 1021*7b5038d7SDag-Erling Smørgrav * name is a non-terminal if it either does not exist 1022*7b5038d7SDag-Erling Smørgrav * in the current name or is different from the same 1023*7b5038d7SDag-Erling Smørgrav * label in the current name (counting from the end) 1024*7b5038d7SDag-Erling Smørgrav */ 1025*7b5038d7SDag-Erling Smørgrav for (i = 1; i < next_label_count - soa_label_count; i++) { 1026*7b5038d7SDag-Erling Smørgrav lpos = (int)cur_label_count - (int)next_label_count + (int)i; 1027*7b5038d7SDag-Erling Smørgrav if (lpos >= 0) { 1028*7b5038d7SDag-Erling Smørgrav l1 = ldns_dname_clone_from(cur_name, (uint8_t)lpos); 1029*7b5038d7SDag-Erling Smørgrav } else { 1030*7b5038d7SDag-Erling Smørgrav l1 = NULL; 1031*7b5038d7SDag-Erling Smørgrav } 1032*7b5038d7SDag-Erling Smørgrav l2 = ldns_dname_clone_from(next_name, i); 1033*7b5038d7SDag-Erling Smørgrav 1034*7b5038d7SDag-Erling Smørgrav if (!l1 || ldns_dname_compare(l1, l2) != 0) { 1035*7b5038d7SDag-Erling Smørgrav /* We have an empty nonterminal, add it to the 1036*7b5038d7SDag-Erling Smørgrav * tree 1037*7b5038d7SDag-Erling Smørgrav */ 1038*7b5038d7SDag-Erling Smørgrav new_name = ldns_dnssec_name_new(); 1039*7b5038d7SDag-Erling Smørgrav if (!new_name) { 1040*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR; 1041*7b5038d7SDag-Erling Smørgrav } 1042*7b5038d7SDag-Erling Smørgrav new_name->name = ldns_dname_clone_from(next_name, 1043*7b5038d7SDag-Erling Smørgrav i); 1044*7b5038d7SDag-Erling Smørgrav if (!new_name->name) { 1045*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name_free(new_name); 1046*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR; 1047*7b5038d7SDag-Erling Smørgrav } 1048*7b5038d7SDag-Erling Smørgrav new_name->name_alloced = true; 1049*7b5038d7SDag-Erling Smørgrav new_node = LDNS_MALLOC(ldns_rbnode_t); 1050*7b5038d7SDag-Erling Smørgrav if (!new_node) { 1051*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name_free(new_name); 1052*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR; 1053*7b5038d7SDag-Erling Smørgrav } 1054*7b5038d7SDag-Erling Smørgrav new_node->key = new_name->name; 1055*7b5038d7SDag-Erling Smørgrav new_node->data = new_name; 1056*7b5038d7SDag-Erling Smørgrav (void)ldns_rbtree_insert(zone->names, new_node); 1057*7b5038d7SDag-Erling Smørgrav } 1058*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(l1); 1059*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(l2); 1060*7b5038d7SDag-Erling Smørgrav } 1061*7b5038d7SDag-Erling Smørgrav 1062*7b5038d7SDag-Erling Smørgrav /* we might have inserted a new node after 1063*7b5038d7SDag-Erling Smørgrav * the current one so we can't just use next() 1064*7b5038d7SDag-Erling Smørgrav */ 1065*7b5038d7SDag-Erling Smørgrav if (next_node != ldns_rbtree_first(zone->names)) { 1066*7b5038d7SDag-Erling Smørgrav cur_node = next_node; 1067*7b5038d7SDag-Erling Smørgrav } else { 1068*7b5038d7SDag-Erling Smørgrav cur_node = LDNS_RBTREE_NULL; 1069*7b5038d7SDag-Erling Smørgrav } 1070*7b5038d7SDag-Erling Smørgrav } 1071*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK; 1072*7b5038d7SDag-Erling Smørgrav } 1073*7b5038d7SDag-Erling Smørgrav 1074*7b5038d7SDag-Erling Smørgrav bool 1075*7b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_is_nsec3_optout(ldns_dnssec_zone* zone) 1076*7b5038d7SDag-Erling Smørgrav { 1077*7b5038d7SDag-Erling Smørgrav ldns_rr* nsec3; 1078*7b5038d7SDag-Erling Smørgrav ldns_rbnode_t* node; 1079*7b5038d7SDag-Erling Smørgrav 1080*7b5038d7SDag-Erling Smørgrav if (ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_NSEC3PARAM)) { 1081*7b5038d7SDag-Erling Smørgrav node = ldns_rbtree_first(zone->names); 1082*7b5038d7SDag-Erling Smørgrav while (node != LDNS_RBTREE_NULL) { 1083*7b5038d7SDag-Erling Smørgrav nsec3 = ((ldns_dnssec_name*)node->data)->nsec; 1084*7b5038d7SDag-Erling Smørgrav if (nsec3 &&ldns_rr_get_type(nsec3) 1085*7b5038d7SDag-Erling Smørgrav == LDNS_RR_TYPE_NSEC3 && 1086*7b5038d7SDag-Erling Smørgrav ldns_nsec3_optout(nsec3)) { 1087*7b5038d7SDag-Erling Smørgrav return true; 1088*7b5038d7SDag-Erling Smørgrav } 1089*7b5038d7SDag-Erling Smørgrav node = ldns_rbtree_next(node); 1090*7b5038d7SDag-Erling Smørgrav } 1091*7b5038d7SDag-Erling Smørgrav } 1092*7b5038d7SDag-Erling Smørgrav return false; 1093*7b5038d7SDag-Erling Smørgrav } 1094