17b5038d7SDag-Erling Smørgrav /* 27b5038d7SDag-Erling Smørgrav * special zone file structures and functions for better dnssec handling 37b5038d7SDag-Erling Smørgrav */ 47b5038d7SDag-Erling Smørgrav 57b5038d7SDag-Erling Smørgrav #include <ldns/config.h> 67b5038d7SDag-Erling Smørgrav 77b5038d7SDag-Erling Smørgrav #include <ldns/ldns.h> 87b5038d7SDag-Erling Smørgrav 97b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs * 107b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs_new(void) 117b5038d7SDag-Erling Smørgrav { 127b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs *new_rrs; 137b5038d7SDag-Erling Smørgrav new_rrs = LDNS_MALLOC(ldns_dnssec_rrs); 147b5038d7SDag-Erling Smørgrav if(!new_rrs) return NULL; 157b5038d7SDag-Erling Smørgrav new_rrs->rr = NULL; 167b5038d7SDag-Erling Smørgrav new_rrs->next = NULL; 177b5038d7SDag-Erling Smørgrav return new_rrs; 187b5038d7SDag-Erling Smørgrav } 197b5038d7SDag-Erling Smørgrav 207b5038d7SDag-Erling Smørgrav INLINE void 217b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs_free_internal(ldns_dnssec_rrs *rrs, int deep) 227b5038d7SDag-Erling Smørgrav { 237b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs *next; 247b5038d7SDag-Erling Smørgrav while (rrs) { 257b5038d7SDag-Erling Smørgrav next = rrs->next; 267b5038d7SDag-Erling Smørgrav if (deep) { 277b5038d7SDag-Erling Smørgrav ldns_rr_free(rrs->rr); 287b5038d7SDag-Erling Smørgrav } 297b5038d7SDag-Erling Smørgrav LDNS_FREE(rrs); 307b5038d7SDag-Erling Smørgrav rrs = next; 317b5038d7SDag-Erling Smørgrav } 327b5038d7SDag-Erling Smørgrav } 337b5038d7SDag-Erling Smørgrav 347b5038d7SDag-Erling Smørgrav void 357b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs_free(ldns_dnssec_rrs *rrs) 367b5038d7SDag-Erling Smørgrav { 377b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs_free_internal(rrs, 0); 387b5038d7SDag-Erling Smørgrav } 397b5038d7SDag-Erling Smørgrav 407b5038d7SDag-Erling Smørgrav void 417b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs_deep_free(ldns_dnssec_rrs *rrs) 427b5038d7SDag-Erling Smørgrav { 437b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs_free_internal(rrs, 1); 447b5038d7SDag-Erling Smørgrav } 457b5038d7SDag-Erling Smørgrav 467b5038d7SDag-Erling Smørgrav ldns_status 477b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs_add_rr(ldns_dnssec_rrs *rrs, ldns_rr *rr) 487b5038d7SDag-Erling Smørgrav { 497b5038d7SDag-Erling Smørgrav int cmp; 507b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs *new_rrs; 517b5038d7SDag-Erling Smørgrav if (!rrs || !rr) { 527b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 537b5038d7SDag-Erling Smørgrav } 547b5038d7SDag-Erling Smørgrav 557b5038d7SDag-Erling Smørgrav /* this could be done more efficiently; name and type should already 567b5038d7SDag-Erling Smørgrav be equal */ 57*17d15b25SDag-Erling Smørgrav cmp = ldns_rr_compare(rrs->rr, rr); 58*17d15b25SDag-Erling Smørgrav if (cmp < 0) { 597b5038d7SDag-Erling Smørgrav if (rrs->next) { 607b5038d7SDag-Erling Smørgrav return ldns_dnssec_rrs_add_rr(rrs->next, rr); 617b5038d7SDag-Erling Smørgrav } else { 627b5038d7SDag-Erling Smørgrav new_rrs = ldns_dnssec_rrs_new(); 637b5038d7SDag-Erling Smørgrav new_rrs->rr = rr; 647b5038d7SDag-Erling Smørgrav rrs->next = new_rrs; 657b5038d7SDag-Erling Smørgrav } 667b5038d7SDag-Erling Smørgrav } else if (cmp > 0) { 677b5038d7SDag-Erling Smørgrav /* put the current old rr in the new next, put the new 687b5038d7SDag-Erling Smørgrav rr in the current container */ 697b5038d7SDag-Erling Smørgrav new_rrs = ldns_dnssec_rrs_new(); 707b5038d7SDag-Erling Smørgrav new_rrs->rr = rrs->rr; 717b5038d7SDag-Erling Smørgrav new_rrs->next = rrs->next; 727b5038d7SDag-Erling Smørgrav rrs->rr = rr; 737b5038d7SDag-Erling Smørgrav rrs->next = new_rrs; 747b5038d7SDag-Erling Smørgrav } 75*17d15b25SDag-Erling Smørgrav /* Silently ignore equal rr's */ 767b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK; 777b5038d7SDag-Erling Smørgrav } 787b5038d7SDag-Erling Smørgrav 797b5038d7SDag-Erling Smørgrav void 807b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs_print_fmt(FILE *out, const ldns_output_format *fmt, 817b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs *rrs) 827b5038d7SDag-Erling Smørgrav { 837b5038d7SDag-Erling Smørgrav if (!rrs) { 847b5038d7SDag-Erling Smørgrav if ((fmt->flags & LDNS_COMMENT_LAYOUT)) 857b5038d7SDag-Erling Smørgrav fprintf(out, "; <void>"); 867b5038d7SDag-Erling Smørgrav } else { 877b5038d7SDag-Erling Smørgrav if (rrs->rr) { 887b5038d7SDag-Erling Smørgrav ldns_rr_print_fmt(out, fmt, rrs->rr); 897b5038d7SDag-Erling Smørgrav } 907b5038d7SDag-Erling Smørgrav if (rrs->next) { 917b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs_print_fmt(out, fmt, rrs->next); 927b5038d7SDag-Erling Smørgrav } 937b5038d7SDag-Erling Smørgrav } 947b5038d7SDag-Erling Smørgrav } 957b5038d7SDag-Erling Smørgrav 967b5038d7SDag-Erling Smørgrav void 977b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs_print(FILE *out, ldns_dnssec_rrs *rrs) 987b5038d7SDag-Erling Smørgrav { 997b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs_print_fmt(out, ldns_output_format_default, rrs); 1007b5038d7SDag-Erling Smørgrav } 1017b5038d7SDag-Erling Smørgrav 1027b5038d7SDag-Erling Smørgrav 1037b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets * 1047b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_new(void) 1057b5038d7SDag-Erling Smørgrav { 1067b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets *new_rrsets; 1077b5038d7SDag-Erling Smørgrav new_rrsets = LDNS_MALLOC(ldns_dnssec_rrsets); 1087b5038d7SDag-Erling Smørgrav if(!new_rrsets) return NULL; 1097b5038d7SDag-Erling Smørgrav new_rrsets->rrs = NULL; 1107b5038d7SDag-Erling Smørgrav new_rrsets->type = 0; 1117b5038d7SDag-Erling Smørgrav new_rrsets->signatures = NULL; 1127b5038d7SDag-Erling Smørgrav new_rrsets->next = NULL; 1137b5038d7SDag-Erling Smørgrav return new_rrsets; 1147b5038d7SDag-Erling Smørgrav } 1157b5038d7SDag-Erling Smørgrav 1167b5038d7SDag-Erling Smørgrav INLINE void 1177b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_free_internal(ldns_dnssec_rrsets *rrsets, int deep) 1187b5038d7SDag-Erling Smørgrav { 1197b5038d7SDag-Erling Smørgrav if (rrsets) { 1207b5038d7SDag-Erling Smørgrav if (rrsets->rrs) { 1217b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs_free_internal(rrsets->rrs, deep); 1227b5038d7SDag-Erling Smørgrav } 1237b5038d7SDag-Erling Smørgrav if (rrsets->next) { 1247b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_free_internal(rrsets->next, deep); 1257b5038d7SDag-Erling Smørgrav } 1267b5038d7SDag-Erling Smørgrav if (rrsets->signatures) { 1277b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs_free_internal(rrsets->signatures, deep); 1287b5038d7SDag-Erling Smørgrav } 1297b5038d7SDag-Erling Smørgrav LDNS_FREE(rrsets); 1307b5038d7SDag-Erling Smørgrav } 1317b5038d7SDag-Erling Smørgrav } 1327b5038d7SDag-Erling Smørgrav 1337b5038d7SDag-Erling Smørgrav void 1347b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_free(ldns_dnssec_rrsets *rrsets) 1357b5038d7SDag-Erling Smørgrav { 1367b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_free_internal(rrsets, 0); 1377b5038d7SDag-Erling Smørgrav } 1387b5038d7SDag-Erling Smørgrav 1397b5038d7SDag-Erling Smørgrav void 1407b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_deep_free(ldns_dnssec_rrsets *rrsets) 1417b5038d7SDag-Erling Smørgrav { 1427b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_free_internal(rrsets, 1); 1437b5038d7SDag-Erling Smørgrav } 1447b5038d7SDag-Erling Smørgrav 1457b5038d7SDag-Erling Smørgrav ldns_rr_type 1467b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_type(ldns_dnssec_rrsets *rrsets) 1477b5038d7SDag-Erling Smørgrav { 1487b5038d7SDag-Erling Smørgrav if (rrsets) { 1497b5038d7SDag-Erling Smørgrav return rrsets->type; 1507b5038d7SDag-Erling Smørgrav } else { 1517b5038d7SDag-Erling Smørgrav return 0; 1527b5038d7SDag-Erling Smørgrav } 1537b5038d7SDag-Erling Smørgrav } 1547b5038d7SDag-Erling Smørgrav 1557b5038d7SDag-Erling Smørgrav ldns_status 1567b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_set_type(ldns_dnssec_rrsets *rrsets, 1577b5038d7SDag-Erling Smørgrav ldns_rr_type type) 1587b5038d7SDag-Erling Smørgrav { 1597b5038d7SDag-Erling Smørgrav if (rrsets) { 1607b5038d7SDag-Erling Smørgrav rrsets->type = type; 1617b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK; 1627b5038d7SDag-Erling Smørgrav } 1637b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 1647b5038d7SDag-Erling Smørgrav } 1657b5038d7SDag-Erling Smørgrav 1667b5038d7SDag-Erling Smørgrav static ldns_dnssec_rrsets * 1677b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_new_frm_rr(ldns_rr *rr) 1687b5038d7SDag-Erling Smørgrav { 1697b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets *new_rrsets; 1707b5038d7SDag-Erling Smørgrav ldns_rr_type rr_type; 1717b5038d7SDag-Erling Smørgrav bool rrsig; 1727b5038d7SDag-Erling Smørgrav 1737b5038d7SDag-Erling Smørgrav new_rrsets = ldns_dnssec_rrsets_new(); 1747b5038d7SDag-Erling Smørgrav rr_type = ldns_rr_get_type(rr); 1757b5038d7SDag-Erling Smørgrav if (rr_type == LDNS_RR_TYPE_RRSIG) { 1767b5038d7SDag-Erling Smørgrav rrsig = true; 1777b5038d7SDag-Erling Smørgrav rr_type = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr)); 1787b5038d7SDag-Erling Smørgrav } else { 1797b5038d7SDag-Erling Smørgrav rrsig = false; 1807b5038d7SDag-Erling Smørgrav } 1817b5038d7SDag-Erling Smørgrav if (!rrsig) { 1827b5038d7SDag-Erling Smørgrav new_rrsets->rrs = ldns_dnssec_rrs_new(); 1837b5038d7SDag-Erling Smørgrav new_rrsets->rrs->rr = rr; 1847b5038d7SDag-Erling Smørgrav } else { 1857b5038d7SDag-Erling Smørgrav new_rrsets->signatures = ldns_dnssec_rrs_new(); 1867b5038d7SDag-Erling Smørgrav new_rrsets->signatures->rr = rr; 1877b5038d7SDag-Erling Smørgrav } 1887b5038d7SDag-Erling Smørgrav new_rrsets->type = rr_type; 1897b5038d7SDag-Erling Smørgrav return new_rrsets; 1907b5038d7SDag-Erling Smørgrav } 1917b5038d7SDag-Erling Smørgrav 1927b5038d7SDag-Erling Smørgrav ldns_status 1937b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_add_rr(ldns_dnssec_rrsets *rrsets, ldns_rr *rr) 1947b5038d7SDag-Erling Smørgrav { 1957b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets *new_rrsets; 1967b5038d7SDag-Erling Smørgrav ldns_rr_type rr_type; 1977b5038d7SDag-Erling Smørgrav bool rrsig = false; 1987b5038d7SDag-Erling Smørgrav ldns_status result = LDNS_STATUS_OK; 1997b5038d7SDag-Erling Smørgrav 2007b5038d7SDag-Erling Smørgrav if (!rrsets || !rr) { 2017b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 2027b5038d7SDag-Erling Smørgrav } 2037b5038d7SDag-Erling Smørgrav 2047b5038d7SDag-Erling Smørgrav rr_type = ldns_rr_get_type(rr); 2057b5038d7SDag-Erling Smørgrav 2067b5038d7SDag-Erling Smørgrav if (rr_type == LDNS_RR_TYPE_RRSIG) { 2077b5038d7SDag-Erling Smørgrav rrsig = true; 2087b5038d7SDag-Erling Smørgrav rr_type = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr)); 2097b5038d7SDag-Erling Smørgrav } 2107b5038d7SDag-Erling Smørgrav 2117b5038d7SDag-Erling Smørgrav if (!rrsets->rrs && rrsets->type == 0 && !rrsets->signatures) { 2127b5038d7SDag-Erling Smørgrav if (!rrsig) { 2137b5038d7SDag-Erling Smørgrav rrsets->rrs = ldns_dnssec_rrs_new(); 2147b5038d7SDag-Erling Smørgrav rrsets->rrs->rr = rr; 2157b5038d7SDag-Erling Smørgrav rrsets->type = rr_type; 2167b5038d7SDag-Erling Smørgrav } else { 2177b5038d7SDag-Erling Smørgrav rrsets->signatures = ldns_dnssec_rrs_new(); 2187b5038d7SDag-Erling Smørgrav rrsets->signatures->rr = rr; 2197b5038d7SDag-Erling Smørgrav rrsets->type = rr_type; 2207b5038d7SDag-Erling Smørgrav } 2217b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK; 2227b5038d7SDag-Erling Smørgrav } 2237b5038d7SDag-Erling Smørgrav 2247b5038d7SDag-Erling Smørgrav if (rr_type > ldns_dnssec_rrsets_type(rrsets)) { 2257b5038d7SDag-Erling Smørgrav if (rrsets->next) { 2267b5038d7SDag-Erling Smørgrav result = ldns_dnssec_rrsets_add_rr(rrsets->next, rr); 2277b5038d7SDag-Erling Smørgrav } else { 2287b5038d7SDag-Erling Smørgrav new_rrsets = ldns_dnssec_rrsets_new_frm_rr(rr); 2297b5038d7SDag-Erling Smørgrav rrsets->next = new_rrsets; 2307b5038d7SDag-Erling Smørgrav } 2317b5038d7SDag-Erling Smørgrav } else if (rr_type < ldns_dnssec_rrsets_type(rrsets)) { 2327b5038d7SDag-Erling Smørgrav /* move the current one into the new next, 2337b5038d7SDag-Erling Smørgrav replace field of current with data from new rr */ 2347b5038d7SDag-Erling Smørgrav new_rrsets = ldns_dnssec_rrsets_new(); 2357b5038d7SDag-Erling Smørgrav new_rrsets->rrs = rrsets->rrs; 2367b5038d7SDag-Erling Smørgrav new_rrsets->type = rrsets->type; 2377b5038d7SDag-Erling Smørgrav new_rrsets->signatures = rrsets->signatures; 2387b5038d7SDag-Erling Smørgrav new_rrsets->next = rrsets->next; 2397b5038d7SDag-Erling Smørgrav if (!rrsig) { 2407b5038d7SDag-Erling Smørgrav rrsets->rrs = ldns_dnssec_rrs_new(); 2417b5038d7SDag-Erling Smørgrav rrsets->rrs->rr = rr; 2427b5038d7SDag-Erling Smørgrav rrsets->signatures = NULL; 2437b5038d7SDag-Erling Smørgrav } else { 2447b5038d7SDag-Erling Smørgrav rrsets->rrs = NULL; 2457b5038d7SDag-Erling Smørgrav rrsets->signatures = ldns_dnssec_rrs_new(); 2467b5038d7SDag-Erling Smørgrav rrsets->signatures->rr = rr; 2477b5038d7SDag-Erling Smørgrav } 2487b5038d7SDag-Erling Smørgrav rrsets->type = rr_type; 2497b5038d7SDag-Erling Smørgrav rrsets->next = new_rrsets; 2507b5038d7SDag-Erling Smørgrav } else { 2517b5038d7SDag-Erling Smørgrav /* equal, add to current rrsets */ 2527b5038d7SDag-Erling Smørgrav if (rrsig) { 2537b5038d7SDag-Erling Smørgrav if (rrsets->signatures) { 2547b5038d7SDag-Erling Smørgrav result = ldns_dnssec_rrs_add_rr(rrsets->signatures, rr); 2557b5038d7SDag-Erling Smørgrav } else { 2567b5038d7SDag-Erling Smørgrav rrsets->signatures = ldns_dnssec_rrs_new(); 2577b5038d7SDag-Erling Smørgrav rrsets->signatures->rr = rr; 2587b5038d7SDag-Erling Smørgrav } 2597b5038d7SDag-Erling Smørgrav } else { 2607b5038d7SDag-Erling Smørgrav if (rrsets->rrs) { 2617b5038d7SDag-Erling Smørgrav result = ldns_dnssec_rrs_add_rr(rrsets->rrs, rr); 2627b5038d7SDag-Erling Smørgrav } else { 2637b5038d7SDag-Erling Smørgrav rrsets->rrs = ldns_dnssec_rrs_new(); 2647b5038d7SDag-Erling Smørgrav rrsets->rrs->rr = rr; 2657b5038d7SDag-Erling Smørgrav } 2667b5038d7SDag-Erling Smørgrav } 2677b5038d7SDag-Erling Smørgrav } 2687b5038d7SDag-Erling Smørgrav 2697b5038d7SDag-Erling Smørgrav return result; 2707b5038d7SDag-Erling Smørgrav } 2717b5038d7SDag-Erling Smørgrav 2727b5038d7SDag-Erling Smørgrav static void 2737b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_print_soa_fmt(FILE *out, const ldns_output_format *fmt, 2747b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets *rrsets, 2757b5038d7SDag-Erling Smørgrav bool follow, 2767b5038d7SDag-Erling Smørgrav bool show_soa) 2777b5038d7SDag-Erling Smørgrav { 2787b5038d7SDag-Erling Smørgrav if (!rrsets) { 2797b5038d7SDag-Erling Smørgrav if ((fmt->flags & LDNS_COMMENT_LAYOUT)) 2807b5038d7SDag-Erling Smørgrav fprintf(out, "; <void>\n"); 2817b5038d7SDag-Erling Smørgrav } else { 2827b5038d7SDag-Erling Smørgrav if (rrsets->rrs && 2837b5038d7SDag-Erling Smørgrav (show_soa || 2847b5038d7SDag-Erling Smørgrav ldns_rr_get_type(rrsets->rrs->rr) != LDNS_RR_TYPE_SOA 2857b5038d7SDag-Erling Smørgrav ) 2867b5038d7SDag-Erling Smørgrav ) { 2877b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs_print_fmt(out, fmt, rrsets->rrs); 2887b5038d7SDag-Erling Smørgrav if (rrsets->signatures) { 2897b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs_print_fmt(out, fmt, 2907b5038d7SDag-Erling Smørgrav rrsets->signatures); 2917b5038d7SDag-Erling Smørgrav } 2927b5038d7SDag-Erling Smørgrav } 2937b5038d7SDag-Erling Smørgrav if (follow && rrsets->next) { 2947b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_print_soa_fmt(out, fmt, 2957b5038d7SDag-Erling Smørgrav rrsets->next, follow, show_soa); 2967b5038d7SDag-Erling Smørgrav } 2977b5038d7SDag-Erling Smørgrav } 2987b5038d7SDag-Erling Smørgrav } 2997b5038d7SDag-Erling Smørgrav 3007b5038d7SDag-Erling Smørgrav 3017b5038d7SDag-Erling Smørgrav void 3027b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_print_fmt(FILE *out, const ldns_output_format *fmt, 3037b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets *rrsets, 3047b5038d7SDag-Erling Smørgrav bool follow) 3057b5038d7SDag-Erling Smørgrav { 3067b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_print_soa_fmt(out, fmt, rrsets, follow, true); 3077b5038d7SDag-Erling Smørgrav } 3087b5038d7SDag-Erling Smørgrav 3097b5038d7SDag-Erling Smørgrav void 3107b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_print(FILE *out, ldns_dnssec_rrsets *rrsets, bool follow) 3117b5038d7SDag-Erling Smørgrav { 3127b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_print_fmt(out, ldns_output_format_default, 3137b5038d7SDag-Erling Smørgrav rrsets, follow); 3147b5038d7SDag-Erling Smørgrav } 3157b5038d7SDag-Erling Smørgrav 3167b5038d7SDag-Erling Smørgrav ldns_dnssec_name * 3177b5038d7SDag-Erling Smørgrav ldns_dnssec_name_new(void) 3187b5038d7SDag-Erling Smørgrav { 3197b5038d7SDag-Erling Smørgrav ldns_dnssec_name *new_name; 3207b5038d7SDag-Erling Smørgrav 3217b5038d7SDag-Erling Smørgrav new_name = LDNS_CALLOC(ldns_dnssec_name, 1); 3227b5038d7SDag-Erling Smørgrav if (!new_name) { 3237b5038d7SDag-Erling Smørgrav return NULL; 3247b5038d7SDag-Erling Smørgrav } 3257b5038d7SDag-Erling Smørgrav /* 3267b5038d7SDag-Erling Smørgrav * not needed anymore because CALLOC initalizes everything to zero. 3277b5038d7SDag-Erling Smørgrav 3287b5038d7SDag-Erling Smørgrav new_name->name = NULL; 3297b5038d7SDag-Erling Smørgrav new_name->rrsets = NULL; 3307b5038d7SDag-Erling Smørgrav new_name->name_alloced = false; 3317b5038d7SDag-Erling Smørgrav new_name->nsec = NULL; 3327b5038d7SDag-Erling Smørgrav new_name->nsec_signatures = NULL; 3337b5038d7SDag-Erling Smørgrav 3347b5038d7SDag-Erling Smørgrav new_name->is_glue = false; 3357b5038d7SDag-Erling Smørgrav new_name->hashed_name = NULL; 3367b5038d7SDag-Erling Smørgrav 3377b5038d7SDag-Erling Smørgrav */ 3387b5038d7SDag-Erling Smørgrav return new_name; 3397b5038d7SDag-Erling Smørgrav } 3407b5038d7SDag-Erling Smørgrav 3417b5038d7SDag-Erling Smørgrav ldns_dnssec_name * 3427b5038d7SDag-Erling Smørgrav ldns_dnssec_name_new_frm_rr(ldns_rr *rr) 3437b5038d7SDag-Erling Smørgrav { 3447b5038d7SDag-Erling Smørgrav ldns_dnssec_name *new_name = ldns_dnssec_name_new(); 3457b5038d7SDag-Erling Smørgrav 3467b5038d7SDag-Erling Smørgrav new_name->name = ldns_rr_owner(rr); 3477b5038d7SDag-Erling Smørgrav if(ldns_dnssec_name_add_rr(new_name, rr) != LDNS_STATUS_OK) { 3487b5038d7SDag-Erling Smørgrav ldns_dnssec_name_free(new_name); 3497b5038d7SDag-Erling Smørgrav return NULL; 3507b5038d7SDag-Erling Smørgrav } 3517b5038d7SDag-Erling Smørgrav 3527b5038d7SDag-Erling Smørgrav return new_name; 3537b5038d7SDag-Erling Smørgrav } 3547b5038d7SDag-Erling Smørgrav 3557b5038d7SDag-Erling Smørgrav INLINE void 3567b5038d7SDag-Erling Smørgrav ldns_dnssec_name_free_internal(ldns_dnssec_name *name, 3577b5038d7SDag-Erling Smørgrav int deep) 3587b5038d7SDag-Erling Smørgrav { 3597b5038d7SDag-Erling Smørgrav if (name) { 3607b5038d7SDag-Erling Smørgrav if (name->name_alloced) { 3617b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(name->name); 3627b5038d7SDag-Erling Smørgrav } 3637b5038d7SDag-Erling Smørgrav if (name->rrsets) { 3647b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_free_internal(name->rrsets, deep); 3657b5038d7SDag-Erling Smørgrav } 3667b5038d7SDag-Erling Smørgrav if (name->nsec && deep) { 3677b5038d7SDag-Erling Smørgrav ldns_rr_free(name->nsec); 3687b5038d7SDag-Erling Smørgrav } 3697b5038d7SDag-Erling Smørgrav if (name->nsec_signatures) { 3707b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs_free_internal(name->nsec_signatures, deep); 3717b5038d7SDag-Erling Smørgrav } 3727b5038d7SDag-Erling Smørgrav if (name->hashed_name) { 3737b5038d7SDag-Erling Smørgrav if (deep) { 3747b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(name->hashed_name); 3757b5038d7SDag-Erling Smørgrav } 3767b5038d7SDag-Erling Smørgrav } 3777b5038d7SDag-Erling Smørgrav LDNS_FREE(name); 3787b5038d7SDag-Erling Smørgrav } 3797b5038d7SDag-Erling Smørgrav } 3807b5038d7SDag-Erling Smørgrav 3817b5038d7SDag-Erling Smørgrav void 3827b5038d7SDag-Erling Smørgrav ldns_dnssec_name_free(ldns_dnssec_name *name) 3837b5038d7SDag-Erling Smørgrav { 3847b5038d7SDag-Erling Smørgrav ldns_dnssec_name_free_internal(name, 0); 3857b5038d7SDag-Erling Smørgrav } 3867b5038d7SDag-Erling Smørgrav 3877b5038d7SDag-Erling Smørgrav void 3887b5038d7SDag-Erling Smørgrav ldns_dnssec_name_deep_free(ldns_dnssec_name *name) 3897b5038d7SDag-Erling Smørgrav { 3907b5038d7SDag-Erling Smørgrav ldns_dnssec_name_free_internal(name, 1); 3917b5038d7SDag-Erling Smørgrav } 3927b5038d7SDag-Erling Smørgrav 3937b5038d7SDag-Erling Smørgrav ldns_rdf * 3947b5038d7SDag-Erling Smørgrav ldns_dnssec_name_name(ldns_dnssec_name *name) 3957b5038d7SDag-Erling Smørgrav { 3967b5038d7SDag-Erling Smørgrav if (name) { 3977b5038d7SDag-Erling Smørgrav return name->name; 3987b5038d7SDag-Erling Smørgrav } 3997b5038d7SDag-Erling Smørgrav return NULL; 4007b5038d7SDag-Erling Smørgrav } 4017b5038d7SDag-Erling Smørgrav 4027b5038d7SDag-Erling Smørgrav bool 4037b5038d7SDag-Erling Smørgrav ldns_dnssec_name_is_glue(ldns_dnssec_name *name) 4047b5038d7SDag-Erling Smørgrav { 4057b5038d7SDag-Erling Smørgrav if (name) { 4067b5038d7SDag-Erling Smørgrav return name->is_glue; 4077b5038d7SDag-Erling Smørgrav } 4087b5038d7SDag-Erling Smørgrav return false; 4097b5038d7SDag-Erling Smørgrav } 4107b5038d7SDag-Erling Smørgrav 4117b5038d7SDag-Erling Smørgrav void 4127b5038d7SDag-Erling Smørgrav ldns_dnssec_name_set_name(ldns_dnssec_name *rrset, 4137b5038d7SDag-Erling Smørgrav ldns_rdf *dname) 4147b5038d7SDag-Erling Smørgrav { 4157b5038d7SDag-Erling Smørgrav if (rrset && dname) { 4167b5038d7SDag-Erling Smørgrav rrset->name = dname; 4177b5038d7SDag-Erling Smørgrav } 4187b5038d7SDag-Erling Smørgrav } 4197b5038d7SDag-Erling Smørgrav 4207b5038d7SDag-Erling Smørgrav 4217b5038d7SDag-Erling Smørgrav void 4227b5038d7SDag-Erling Smørgrav ldns_dnssec_name_set_nsec(ldns_dnssec_name *rrset, ldns_rr *nsec) 4237b5038d7SDag-Erling Smørgrav { 4247b5038d7SDag-Erling Smørgrav if (rrset && nsec) { 4257b5038d7SDag-Erling Smørgrav rrset->nsec = nsec; 4267b5038d7SDag-Erling Smørgrav } 4277b5038d7SDag-Erling Smørgrav } 4287b5038d7SDag-Erling Smørgrav 4297b5038d7SDag-Erling Smørgrav int 4307b5038d7SDag-Erling Smørgrav ldns_dnssec_name_cmp(const void *a, const void *b) 4317b5038d7SDag-Erling Smørgrav { 4327b5038d7SDag-Erling Smørgrav ldns_dnssec_name *na = (ldns_dnssec_name *) a; 4337b5038d7SDag-Erling Smørgrav ldns_dnssec_name *nb = (ldns_dnssec_name *) b; 4347b5038d7SDag-Erling Smørgrav 4357b5038d7SDag-Erling Smørgrav if (na && nb) { 4367b5038d7SDag-Erling Smørgrav return ldns_dname_compare(ldns_dnssec_name_name(na), 4377b5038d7SDag-Erling Smørgrav ldns_dnssec_name_name(nb)); 4387b5038d7SDag-Erling Smørgrav } else if (na) { 4397b5038d7SDag-Erling Smørgrav return 1; 4407b5038d7SDag-Erling Smørgrav } else if (nb) { 4417b5038d7SDag-Erling Smørgrav return -1; 4427b5038d7SDag-Erling Smørgrav } else { 4437b5038d7SDag-Erling Smørgrav return 0; 4447b5038d7SDag-Erling Smørgrav } 4457b5038d7SDag-Erling Smørgrav } 4467b5038d7SDag-Erling Smørgrav 4477b5038d7SDag-Erling Smørgrav ldns_status 4487b5038d7SDag-Erling Smørgrav ldns_dnssec_name_add_rr(ldns_dnssec_name *name, 4497b5038d7SDag-Erling Smørgrav ldns_rr *rr) 4507b5038d7SDag-Erling Smørgrav { 4517b5038d7SDag-Erling Smørgrav ldns_status result = LDNS_STATUS_OK; 4527b5038d7SDag-Erling Smørgrav ldns_rr_type rr_type; 4537b5038d7SDag-Erling Smørgrav ldns_rr_type typecovered = 0; 4547b5038d7SDag-Erling Smørgrav 4557b5038d7SDag-Erling Smørgrav /* special handling for NSEC3 and NSECX covering RRSIGS */ 4567b5038d7SDag-Erling Smørgrav 4577b5038d7SDag-Erling Smørgrav if (!name || !rr) { 4587b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 4597b5038d7SDag-Erling Smørgrav } 4607b5038d7SDag-Erling Smørgrav 4617b5038d7SDag-Erling Smørgrav rr_type = ldns_rr_get_type(rr); 4627b5038d7SDag-Erling Smørgrav 4637b5038d7SDag-Erling Smørgrav if (rr_type == LDNS_RR_TYPE_RRSIG) { 4647b5038d7SDag-Erling Smørgrav typecovered = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr)); 4657b5038d7SDag-Erling Smørgrav } 4667b5038d7SDag-Erling Smørgrav 4677b5038d7SDag-Erling Smørgrav if (rr_type == LDNS_RR_TYPE_NSEC || 4687b5038d7SDag-Erling Smørgrav rr_type == LDNS_RR_TYPE_NSEC3) { 4697b5038d7SDag-Erling Smørgrav /* XX check if is already set (and error?) */ 4707b5038d7SDag-Erling Smørgrav name->nsec = rr; 4717b5038d7SDag-Erling Smørgrav } else if (typecovered == LDNS_RR_TYPE_NSEC || 4727b5038d7SDag-Erling Smørgrav typecovered == LDNS_RR_TYPE_NSEC3) { 4737b5038d7SDag-Erling Smørgrav if (name->nsec_signatures) { 4747b5038d7SDag-Erling Smørgrav result = ldns_dnssec_rrs_add_rr(name->nsec_signatures, rr); 4757b5038d7SDag-Erling Smørgrav } else { 4767b5038d7SDag-Erling Smørgrav name->nsec_signatures = ldns_dnssec_rrs_new(); 4777b5038d7SDag-Erling Smørgrav name->nsec_signatures->rr = rr; 4787b5038d7SDag-Erling Smørgrav } 4797b5038d7SDag-Erling Smørgrav } else { 4807b5038d7SDag-Erling Smørgrav /* it's a 'normal' RR, add it to the right rrset */ 4817b5038d7SDag-Erling Smørgrav if (name->rrsets) { 4827b5038d7SDag-Erling Smørgrav result = ldns_dnssec_rrsets_add_rr(name->rrsets, rr); 4837b5038d7SDag-Erling Smørgrav } else { 4847b5038d7SDag-Erling Smørgrav name->rrsets = ldns_dnssec_rrsets_new(); 4857b5038d7SDag-Erling Smørgrav result = ldns_dnssec_rrsets_add_rr(name->rrsets, rr); 4867b5038d7SDag-Erling Smørgrav } 4877b5038d7SDag-Erling Smørgrav } 4887b5038d7SDag-Erling Smørgrav return result; 4897b5038d7SDag-Erling Smørgrav } 4907b5038d7SDag-Erling Smørgrav 4917b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets * 4927b5038d7SDag-Erling Smørgrav ldns_dnssec_name_find_rrset(ldns_dnssec_name *name, 4937b5038d7SDag-Erling Smørgrav ldns_rr_type type) { 4947b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets *result; 4957b5038d7SDag-Erling Smørgrav 4967b5038d7SDag-Erling Smørgrav result = name->rrsets; 4977b5038d7SDag-Erling Smørgrav while (result) { 4987b5038d7SDag-Erling Smørgrav if (result->type == type) { 4997b5038d7SDag-Erling Smørgrav return result; 5007b5038d7SDag-Erling Smørgrav } else { 5017b5038d7SDag-Erling Smørgrav result = result->next; 5027b5038d7SDag-Erling Smørgrav } 5037b5038d7SDag-Erling Smørgrav } 5047b5038d7SDag-Erling Smørgrav return NULL; 5057b5038d7SDag-Erling Smørgrav } 5067b5038d7SDag-Erling Smørgrav 5077b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets * 5087b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_find_rrset(ldns_dnssec_zone *zone, 5097b5038d7SDag-Erling Smørgrav ldns_rdf *dname, 5107b5038d7SDag-Erling Smørgrav ldns_rr_type type) 5117b5038d7SDag-Erling Smørgrav { 5127b5038d7SDag-Erling Smørgrav ldns_rbnode_t *node; 5137b5038d7SDag-Erling Smørgrav 5147b5038d7SDag-Erling Smørgrav if (!zone || !dname) { 5157b5038d7SDag-Erling Smørgrav return NULL; 5167b5038d7SDag-Erling Smørgrav } 5177b5038d7SDag-Erling Smørgrav 5187b5038d7SDag-Erling Smørgrav node = ldns_rbtree_search(zone->names, dname); 5197b5038d7SDag-Erling Smørgrav if (node) { 5207b5038d7SDag-Erling Smørgrav return ldns_dnssec_name_find_rrset((ldns_dnssec_name *)node->data, 5217b5038d7SDag-Erling Smørgrav type); 5227b5038d7SDag-Erling Smørgrav } else { 5237b5038d7SDag-Erling Smørgrav return NULL; 5247b5038d7SDag-Erling Smørgrav } 5257b5038d7SDag-Erling Smørgrav } 5267b5038d7SDag-Erling Smørgrav 5277b5038d7SDag-Erling Smørgrav static void 5287b5038d7SDag-Erling Smørgrav ldns_dnssec_name_print_soa_fmt(FILE *out, const ldns_output_format *fmt, 5297b5038d7SDag-Erling Smørgrav ldns_dnssec_name *name, 5307b5038d7SDag-Erling Smørgrav bool show_soa) 5317b5038d7SDag-Erling Smørgrav { 5327b5038d7SDag-Erling Smørgrav if (name) { 5337b5038d7SDag-Erling Smørgrav if(name->rrsets) { 5347b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_print_soa_fmt(out, fmt, 5357b5038d7SDag-Erling Smørgrav name->rrsets, true, show_soa); 5367b5038d7SDag-Erling Smørgrav } else if ((fmt->flags & LDNS_COMMENT_LAYOUT)) { 5377b5038d7SDag-Erling Smørgrav fprintf(out, ";; Empty nonterminal: "); 5387b5038d7SDag-Erling Smørgrav ldns_rdf_print(out, name->name); 5397b5038d7SDag-Erling Smørgrav fprintf(out, "\n"); 5407b5038d7SDag-Erling Smørgrav } 5417b5038d7SDag-Erling Smørgrav if(name->nsec) { 5427b5038d7SDag-Erling Smørgrav ldns_rr_print_fmt(out, fmt, name->nsec); 5437b5038d7SDag-Erling Smørgrav } 5447b5038d7SDag-Erling Smørgrav if (name->nsec_signatures) { 5457b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs_print_fmt(out, fmt, 5467b5038d7SDag-Erling Smørgrav name->nsec_signatures); 5477b5038d7SDag-Erling Smørgrav } 5487b5038d7SDag-Erling Smørgrav } else if ((fmt->flags & LDNS_COMMENT_LAYOUT)) { 5497b5038d7SDag-Erling Smørgrav fprintf(out, "; <void>\n"); 5507b5038d7SDag-Erling Smørgrav } 5517b5038d7SDag-Erling Smørgrav } 5527b5038d7SDag-Erling Smørgrav 5537b5038d7SDag-Erling Smørgrav 5547b5038d7SDag-Erling Smørgrav void 5557b5038d7SDag-Erling Smørgrav ldns_dnssec_name_print_fmt(FILE *out, const ldns_output_format *fmt, 5567b5038d7SDag-Erling Smørgrav ldns_dnssec_name *name) 5577b5038d7SDag-Erling Smørgrav { 5587b5038d7SDag-Erling Smørgrav ldns_dnssec_name_print_soa_fmt(out, fmt, name, true); 5597b5038d7SDag-Erling Smørgrav } 5607b5038d7SDag-Erling Smørgrav 5617b5038d7SDag-Erling Smørgrav void 5627b5038d7SDag-Erling Smørgrav ldns_dnssec_name_print(FILE *out, ldns_dnssec_name *name) 5637b5038d7SDag-Erling Smørgrav { 5647b5038d7SDag-Erling Smørgrav ldns_dnssec_name_print_fmt(out, ldns_output_format_default, name); 5657b5038d7SDag-Erling Smørgrav } 5667b5038d7SDag-Erling Smørgrav 5677b5038d7SDag-Erling Smørgrav 5687b5038d7SDag-Erling Smørgrav ldns_dnssec_zone * 5697b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_new(void) 5707b5038d7SDag-Erling Smørgrav { 5717b5038d7SDag-Erling Smørgrav ldns_dnssec_zone *zone = LDNS_MALLOC(ldns_dnssec_zone); 5727b5038d7SDag-Erling Smørgrav if(!zone) return NULL; 5737b5038d7SDag-Erling Smørgrav zone->soa = NULL; 5747b5038d7SDag-Erling Smørgrav zone->names = NULL; 575*17d15b25SDag-Erling Smørgrav zone->hashed_names = NULL; 576*17d15b25SDag-Erling Smørgrav zone->_nsec3params = NULL; 5777b5038d7SDag-Erling Smørgrav 5787b5038d7SDag-Erling Smørgrav return zone; 5797b5038d7SDag-Erling Smørgrav } 5807b5038d7SDag-Erling Smørgrav 5817b5038d7SDag-Erling Smørgrav static bool 5827b5038d7SDag-Erling Smørgrav rr_is_rrsig_covering(ldns_rr* rr, ldns_rr_type t) 5837b5038d7SDag-Erling Smørgrav { 5847b5038d7SDag-Erling Smørgrav return ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG 5857b5038d7SDag-Erling Smørgrav && ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr)) == t; 5867b5038d7SDag-Erling Smørgrav } 5877b5038d7SDag-Erling Smørgrav 5887b5038d7SDag-Erling Smørgrav /* When the zone is first read into an list and then inserted into an 5897b5038d7SDag-Erling Smørgrav * ldns_dnssec_zone (rbtree) the nodes of the rbtree are allocated close (next) 5907b5038d7SDag-Erling Smørgrav * to each other. Because ldns-verify-zone (the only program that uses this 5917b5038d7SDag-Erling Smørgrav * function) uses the rbtree mostly for sequentual walking, this results 5927b5038d7SDag-Erling Smørgrav * in a speed increase (of 15% on linux) because we have less CPU-cache misses. 5937b5038d7SDag-Erling Smørgrav */ 5947b5038d7SDag-Erling Smørgrav #define FASTER_DNSSEC_ZONE_NEW_FRM_FP 1 /* Because of L2 cache efficiency */ 5957b5038d7SDag-Erling Smørgrav 5967b5038d7SDag-Erling Smørgrav ldns_status 5977b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_new_frm_fp_l(ldns_dnssec_zone** z, FILE* fp, ldns_rdf* origin, 5987b5038d7SDag-Erling Smørgrav uint32_t ttl, ldns_rr_class ATTR_UNUSED(c), int* line_nr) 5997b5038d7SDag-Erling Smørgrav { 6007b5038d7SDag-Erling Smørgrav ldns_rr* cur_rr; 6017b5038d7SDag-Erling Smørgrav size_t i; 6027b5038d7SDag-Erling Smørgrav 6037b5038d7SDag-Erling Smørgrav ldns_rdf *my_origin = NULL; 6047b5038d7SDag-Erling Smørgrav ldns_rdf *my_prev = NULL; 6057b5038d7SDag-Erling Smørgrav 6067b5038d7SDag-Erling Smørgrav ldns_dnssec_zone *newzone = ldns_dnssec_zone_new(); 6077b5038d7SDag-Erling Smørgrav /* when reading NSEC3s, there is a chance that we encounter nsecs 6087b5038d7SDag-Erling Smørgrav for empty nonterminals, whose nonterminals we cannot derive yet 6097b5038d7SDag-Erling Smørgrav because the needed information is to be read later. in that case 6107b5038d7SDag-Erling Smørgrav we keep a list of those nsec3's and retry to add them later */ 6117b5038d7SDag-Erling Smørgrav ldns_rr_list* todo_nsec3s = ldns_rr_list_new(); 6127b5038d7SDag-Erling Smørgrav ldns_rr_list* todo_nsec3_rrsigs = ldns_rr_list_new(); 6137b5038d7SDag-Erling Smørgrav 6147b5038d7SDag-Erling Smørgrav ldns_status status = LDNS_STATUS_MEM_ERR; 6157b5038d7SDag-Erling Smørgrav 6167b5038d7SDag-Erling Smørgrav #ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP 6177b5038d7SDag-Erling Smørgrav ldns_zone* zone = NULL; 6187b5038d7SDag-Erling Smørgrav if (ldns_zone_new_frm_fp_l(&zone, fp, origin,ttl, c, line_nr) 6197b5038d7SDag-Erling Smørgrav != LDNS_STATUS_OK) goto error; 6207b5038d7SDag-Erling Smørgrav #else 6217b5038d7SDag-Erling Smørgrav uint32_t my_ttl = ttl; 6227b5038d7SDag-Erling Smørgrav #endif 6237b5038d7SDag-Erling Smørgrav 6247b5038d7SDag-Erling Smørgrav if (!newzone || !todo_nsec3s || !todo_nsec3_rrsigs ) goto error; 6257b5038d7SDag-Erling Smørgrav 6267b5038d7SDag-Erling Smørgrav if (origin) { 6277b5038d7SDag-Erling Smørgrav if (!(my_origin = ldns_rdf_clone(origin))) goto error; 6287b5038d7SDag-Erling Smørgrav if (!(my_prev = ldns_rdf_clone(origin))) goto error; 6297b5038d7SDag-Erling Smørgrav } 6307b5038d7SDag-Erling Smørgrav 6317b5038d7SDag-Erling Smørgrav #ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP 6327b5038d7SDag-Erling Smørgrav if (ldns_dnssec_zone_add_rr(newzone, ldns_zone_soa(zone)) 6337b5038d7SDag-Erling Smørgrav != LDNS_STATUS_OK) goto error; 6347b5038d7SDag-Erling Smørgrav 6357b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) { 6367b5038d7SDag-Erling Smørgrav cur_rr = ldns_rr_list_rr(ldns_zone_rrs(zone), i); 6377b5038d7SDag-Erling Smørgrav status = LDNS_STATUS_OK; 6387b5038d7SDag-Erling Smørgrav #else 6397b5038d7SDag-Erling Smørgrav while (!feof(fp)) { 6407b5038d7SDag-Erling Smørgrav status = ldns_rr_new_frm_fp_l(&cur_rr, fp, &my_ttl, &my_origin, 6417b5038d7SDag-Erling Smørgrav &my_prev, line_nr); 6427b5038d7SDag-Erling Smørgrav 6437b5038d7SDag-Erling Smørgrav #endif 6447b5038d7SDag-Erling Smørgrav switch (status) { 6457b5038d7SDag-Erling Smørgrav case LDNS_STATUS_OK: 6467b5038d7SDag-Erling Smørgrav 6477b5038d7SDag-Erling Smørgrav status = ldns_dnssec_zone_add_rr(newzone, cur_rr); 6487b5038d7SDag-Erling Smørgrav if (status == 6497b5038d7SDag-Erling Smørgrav LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND) { 6507b5038d7SDag-Erling Smørgrav 6517b5038d7SDag-Erling Smørgrav if (rr_is_rrsig_covering(cur_rr, 6527b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_NSEC3)){ 6537b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr(todo_nsec3_rrsigs, 6547b5038d7SDag-Erling Smørgrav cur_rr); 6557b5038d7SDag-Erling Smørgrav } else { 6567b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr(todo_nsec3s, 6577b5038d7SDag-Erling Smørgrav cur_rr); 6587b5038d7SDag-Erling Smørgrav } 659*17d15b25SDag-Erling Smørgrav status = LDNS_STATUS_OK; 660*17d15b25SDag-Erling Smørgrav 6617b5038d7SDag-Erling Smørgrav } else if (status != LDNS_STATUS_OK) 6627b5038d7SDag-Erling Smørgrav goto error; 6637b5038d7SDag-Erling Smørgrav 6647b5038d7SDag-Erling Smørgrav break; 6657b5038d7SDag-Erling Smørgrav 6667b5038d7SDag-Erling Smørgrav 6677b5038d7SDag-Erling Smørgrav case LDNS_STATUS_SYNTAX_EMPTY: /* empty line was seen */ 6687b5038d7SDag-Erling Smørgrav case LDNS_STATUS_SYNTAX_TTL: /* the ttl was set*/ 6697b5038d7SDag-Erling Smørgrav case LDNS_STATUS_SYNTAX_ORIGIN: /* the origin was set*/ 6702787e39aSDag-Erling Smørgrav status = LDNS_STATUS_OK; 6717b5038d7SDag-Erling Smørgrav break; 6727b5038d7SDag-Erling Smørgrav 6737b5038d7SDag-Erling Smørgrav case LDNS_STATUS_SYNTAX_INCLUDE:/* $include not implemented */ 6747b5038d7SDag-Erling Smørgrav status = LDNS_STATUS_SYNTAX_INCLUDE_ERR_NOTIMPL; 6757b5038d7SDag-Erling Smørgrav break; 6767b5038d7SDag-Erling Smørgrav 6777b5038d7SDag-Erling Smørgrav default: 6787b5038d7SDag-Erling Smørgrav goto error; 6797b5038d7SDag-Erling Smørgrav } 6807b5038d7SDag-Erling Smørgrav } 6817b5038d7SDag-Erling Smørgrav 6827b5038d7SDag-Erling Smørgrav if (ldns_rr_list_rr_count(todo_nsec3s) > 0) { 6837b5038d7SDag-Erling Smørgrav (void) ldns_dnssec_zone_add_empty_nonterminals(newzone); 6842787e39aSDag-Erling Smørgrav for (i = 0; status == LDNS_STATUS_OK && 6852787e39aSDag-Erling Smørgrav i < ldns_rr_list_rr_count(todo_nsec3s); i++) { 6867b5038d7SDag-Erling Smørgrav cur_rr = ldns_rr_list_rr(todo_nsec3s, i); 6877b5038d7SDag-Erling Smørgrav status = ldns_dnssec_zone_add_rr(newzone, cur_rr); 6887b5038d7SDag-Erling Smørgrav } 6897b5038d7SDag-Erling Smørgrav } 690*17d15b25SDag-Erling Smørgrav if (ldns_rr_list_rr_count(todo_nsec3_rrsigs) > 0) { 6912787e39aSDag-Erling Smørgrav for (i = 0; status == LDNS_STATUS_OK && 6922787e39aSDag-Erling Smørgrav i < ldns_rr_list_rr_count(todo_nsec3_rrsigs); 6932787e39aSDag-Erling Smørgrav i++){ 6947b5038d7SDag-Erling Smørgrav cur_rr = ldns_rr_list_rr(todo_nsec3_rrsigs, i); 6957b5038d7SDag-Erling Smørgrav status = ldns_dnssec_zone_add_rr(newzone, cur_rr); 6967b5038d7SDag-Erling Smørgrav } 6977b5038d7SDag-Erling Smørgrav } 6987b5038d7SDag-Erling Smørgrav 6997b5038d7SDag-Erling Smørgrav if (z) { 7007b5038d7SDag-Erling Smørgrav *z = newzone; 7012787e39aSDag-Erling Smørgrav newzone = NULL; 7027b5038d7SDag-Erling Smørgrav } else { 7037b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_free(newzone); 7047b5038d7SDag-Erling Smørgrav } 7057b5038d7SDag-Erling Smørgrav 7067b5038d7SDag-Erling Smørgrav error: 7077b5038d7SDag-Erling Smørgrav #ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP 7087b5038d7SDag-Erling Smørgrav if (zone) { 7097b5038d7SDag-Erling Smørgrav ldns_zone_free(zone); 7107b5038d7SDag-Erling Smørgrav } 7117b5038d7SDag-Erling Smørgrav #endif 7122787e39aSDag-Erling Smørgrav ldns_rr_list_free(todo_nsec3_rrsigs); 7132787e39aSDag-Erling Smørgrav ldns_rr_list_free(todo_nsec3s); 7142787e39aSDag-Erling Smørgrav 7157b5038d7SDag-Erling Smørgrav if (my_origin) { 7167b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(my_origin); 7177b5038d7SDag-Erling Smørgrav } 7187b5038d7SDag-Erling Smørgrav if (my_prev) { 7197b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(my_prev); 7207b5038d7SDag-Erling Smørgrav } 7217b5038d7SDag-Erling Smørgrav if (newzone) { 7227b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_free(newzone); 7237b5038d7SDag-Erling Smørgrav } 7247b5038d7SDag-Erling Smørgrav return status; 7257b5038d7SDag-Erling Smørgrav } 7267b5038d7SDag-Erling Smørgrav 7277b5038d7SDag-Erling Smørgrav ldns_status 7287b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_new_frm_fp(ldns_dnssec_zone** z, FILE* fp, ldns_rdf* origin, 7297b5038d7SDag-Erling Smørgrav uint32_t ttl, ldns_rr_class ATTR_UNUSED(c)) 7307b5038d7SDag-Erling Smørgrav { 7317b5038d7SDag-Erling Smørgrav return ldns_dnssec_zone_new_frm_fp_l(z, fp, origin, ttl, c, NULL); 7327b5038d7SDag-Erling Smørgrav } 7337b5038d7SDag-Erling Smørgrav 7347b5038d7SDag-Erling Smørgrav static void 7357b5038d7SDag-Erling Smørgrav ldns_dnssec_name_node_free(ldns_rbnode_t *node, void *arg) { 7367b5038d7SDag-Erling Smørgrav (void) arg; 7377b5038d7SDag-Erling Smørgrav ldns_dnssec_name_free((ldns_dnssec_name *)node->data); 7387b5038d7SDag-Erling Smørgrav LDNS_FREE(node); 7397b5038d7SDag-Erling Smørgrav } 7407b5038d7SDag-Erling Smørgrav 7417b5038d7SDag-Erling Smørgrav static void 7427b5038d7SDag-Erling Smørgrav ldns_dnssec_name_node_deep_free(ldns_rbnode_t *node, void *arg) { 7437b5038d7SDag-Erling Smørgrav (void) arg; 7447b5038d7SDag-Erling Smørgrav ldns_dnssec_name_deep_free((ldns_dnssec_name *)node->data); 7457b5038d7SDag-Erling Smørgrav LDNS_FREE(node); 7467b5038d7SDag-Erling Smørgrav } 7477b5038d7SDag-Erling Smørgrav 7487b5038d7SDag-Erling Smørgrav void 7497b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_free(ldns_dnssec_zone *zone) 7507b5038d7SDag-Erling Smørgrav { 7517b5038d7SDag-Erling Smørgrav if (zone) { 7527b5038d7SDag-Erling Smørgrav if (zone->names) { 7537b5038d7SDag-Erling Smørgrav /* destroy all name structures within the tree */ 7547b5038d7SDag-Erling Smørgrav ldns_traverse_postorder(zone->names, 7557b5038d7SDag-Erling Smørgrav ldns_dnssec_name_node_free, 7567b5038d7SDag-Erling Smørgrav NULL); 7577b5038d7SDag-Erling Smørgrav LDNS_FREE(zone->names); 7587b5038d7SDag-Erling Smørgrav } 7597b5038d7SDag-Erling Smørgrav LDNS_FREE(zone); 7607b5038d7SDag-Erling Smørgrav } 7617b5038d7SDag-Erling Smørgrav } 7627b5038d7SDag-Erling Smørgrav 7637b5038d7SDag-Erling Smørgrav void 7647b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_deep_free(ldns_dnssec_zone *zone) 7657b5038d7SDag-Erling Smørgrav { 7667b5038d7SDag-Erling Smørgrav if (zone) { 7677b5038d7SDag-Erling Smørgrav if (zone->names) { 7687b5038d7SDag-Erling Smørgrav /* destroy all name structures within the tree */ 7697b5038d7SDag-Erling Smørgrav ldns_traverse_postorder(zone->names, 7707b5038d7SDag-Erling Smørgrav ldns_dnssec_name_node_deep_free, 7717b5038d7SDag-Erling Smørgrav NULL); 7727b5038d7SDag-Erling Smørgrav LDNS_FREE(zone->names); 7737b5038d7SDag-Erling Smørgrav } 7747b5038d7SDag-Erling Smørgrav LDNS_FREE(zone); 7757b5038d7SDag-Erling Smørgrav } 7767b5038d7SDag-Erling Smørgrav } 7777b5038d7SDag-Erling Smørgrav 7787b5038d7SDag-Erling Smørgrav /* use for dname comparison in tree */ 779d6e492feSDag-Erling Smørgrav int 7807b5038d7SDag-Erling Smørgrav ldns_dname_compare_v(const void *a, const void *b) { 7817b5038d7SDag-Erling Smørgrav return ldns_dname_compare((ldns_rdf *)a, (ldns_rdf *)b); 7827b5038d7SDag-Erling Smørgrav } 7837b5038d7SDag-Erling Smørgrav 784*17d15b25SDag-Erling Smørgrav static void 785*17d15b25SDag-Erling Smørgrav ldns_dnssec_name_make_hashed_name(ldns_dnssec_zone *zone, 786*17d15b25SDag-Erling Smørgrav ldns_dnssec_name* name, ldns_rr* nsec3rr); 787*17d15b25SDag-Erling Smørgrav 788*17d15b25SDag-Erling Smørgrav static void 789*17d15b25SDag-Erling Smørgrav ldns_hashed_names_node_free(ldns_rbnode_t *node, void *arg) { 790*17d15b25SDag-Erling Smørgrav (void) arg; 791*17d15b25SDag-Erling Smørgrav LDNS_FREE(node); 792*17d15b25SDag-Erling Smørgrav } 793*17d15b25SDag-Erling Smørgrav 794*17d15b25SDag-Erling Smørgrav static void 795*17d15b25SDag-Erling Smørgrav ldns_dnssec_zone_hashed_names_from_nsec3( 796*17d15b25SDag-Erling Smørgrav ldns_dnssec_zone* zone, ldns_rr* nsec3rr) 797*17d15b25SDag-Erling Smørgrav { 798*17d15b25SDag-Erling Smørgrav ldns_rbnode_t* current_node; 7997b5038d7SDag-Erling Smørgrav ldns_dnssec_name* current_name; 800*17d15b25SDag-Erling Smørgrav 801*17d15b25SDag-Erling Smørgrav assert(zone != NULL); 802*17d15b25SDag-Erling Smørgrav assert(nsec3rr != NULL); 803*17d15b25SDag-Erling Smørgrav 804*17d15b25SDag-Erling Smørgrav if (zone->hashed_names) { 805*17d15b25SDag-Erling Smørgrav ldns_traverse_postorder(zone->hashed_names, 806*17d15b25SDag-Erling Smørgrav ldns_hashed_names_node_free, NULL); 807*17d15b25SDag-Erling Smørgrav LDNS_FREE(zone->hashed_names); 808*17d15b25SDag-Erling Smørgrav } 809*17d15b25SDag-Erling Smørgrav zone->_nsec3params = nsec3rr; 810*17d15b25SDag-Erling Smørgrav 811*17d15b25SDag-Erling Smørgrav /* So this is a NSEC3 zone. 812*17d15b25SDag-Erling Smørgrav * Calculate hashes for all names already in the zone 813*17d15b25SDag-Erling Smørgrav */ 814*17d15b25SDag-Erling Smørgrav zone->hashed_names = ldns_rbtree_create(ldns_dname_compare_v); 815*17d15b25SDag-Erling Smørgrav if (zone->hashed_names == NULL) { 816*17d15b25SDag-Erling Smørgrav return; 817*17d15b25SDag-Erling Smørgrav } 818*17d15b25SDag-Erling Smørgrav for ( current_node = ldns_rbtree_first(zone->names) 819*17d15b25SDag-Erling Smørgrav ; current_node != LDNS_RBTREE_NULL 820*17d15b25SDag-Erling Smørgrav ; current_node = ldns_rbtree_next(current_node) 821*17d15b25SDag-Erling Smørgrav ) { 822*17d15b25SDag-Erling Smørgrav current_name = (ldns_dnssec_name *) current_node->data; 823*17d15b25SDag-Erling Smørgrav ldns_dnssec_name_make_hashed_name(zone, current_name, nsec3rr); 824*17d15b25SDag-Erling Smørgrav 825*17d15b25SDag-Erling Smørgrav } 826*17d15b25SDag-Erling Smørgrav } 827*17d15b25SDag-Erling Smørgrav 828*17d15b25SDag-Erling Smørgrav static void 829*17d15b25SDag-Erling Smørgrav ldns_dnssec_name_make_hashed_name(ldns_dnssec_zone *zone, 830*17d15b25SDag-Erling Smørgrav ldns_dnssec_name* name, ldns_rr* nsec3rr) 831*17d15b25SDag-Erling Smørgrav { 832*17d15b25SDag-Erling Smørgrav ldns_rbnode_t* new_node; 833*17d15b25SDag-Erling Smørgrav 834*17d15b25SDag-Erling Smørgrav assert(name != NULL); 835*17d15b25SDag-Erling Smørgrav if (! zone->_nsec3params) { 836*17d15b25SDag-Erling Smørgrav if (! nsec3rr) { 837*17d15b25SDag-Erling Smørgrav return; 838*17d15b25SDag-Erling Smørgrav } 839*17d15b25SDag-Erling Smørgrav ldns_dnssec_zone_hashed_names_from_nsec3(zone, nsec3rr); 840*17d15b25SDag-Erling Smørgrav 841*17d15b25SDag-Erling Smørgrav } else if (! nsec3rr) { 842*17d15b25SDag-Erling Smørgrav nsec3rr = zone->_nsec3params; 843*17d15b25SDag-Erling Smørgrav } 844*17d15b25SDag-Erling Smørgrav name->hashed_name = ldns_nsec3_hash_name_frm_nsec3(nsec3rr, name->name); 845*17d15b25SDag-Erling Smørgrav 846*17d15b25SDag-Erling Smørgrav /* Also store in zone->hashed_names */ 847*17d15b25SDag-Erling Smørgrav if ((new_node = LDNS_MALLOC(ldns_rbnode_t))) { 848*17d15b25SDag-Erling Smørgrav 849*17d15b25SDag-Erling Smørgrav new_node->key = name->hashed_name; 850*17d15b25SDag-Erling Smørgrav new_node->data = name; 851*17d15b25SDag-Erling Smørgrav 852*17d15b25SDag-Erling Smørgrav if (ldns_rbtree_insert(zone->hashed_names, new_node) == NULL) { 853*17d15b25SDag-Erling Smørgrav 854*17d15b25SDag-Erling Smørgrav LDNS_FREE(new_node); 855*17d15b25SDag-Erling Smørgrav } 856*17d15b25SDag-Erling Smørgrav } 857*17d15b25SDag-Erling Smørgrav } 858*17d15b25SDag-Erling Smørgrav 859*17d15b25SDag-Erling Smørgrav 860*17d15b25SDag-Erling Smørgrav static ldns_rbnode_t * 861*17d15b25SDag-Erling Smørgrav ldns_dnssec_zone_find_nsec3_original(ldns_dnssec_zone *zone, ldns_rr *rr) { 8627b5038d7SDag-Erling Smørgrav ldns_rdf *hashed_name; 8637b5038d7SDag-Erling Smørgrav 8647b5038d7SDag-Erling Smørgrav hashed_name = ldns_dname_label(ldns_rr_owner(rr), 0); 865*17d15b25SDag-Erling Smørgrav if (hashed_name == NULL) { 866*17d15b25SDag-Erling Smørgrav return NULL; 867*17d15b25SDag-Erling Smørgrav } 868*17d15b25SDag-Erling Smørgrav if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_NSEC3 && ! zone->_nsec3params){ 8697b5038d7SDag-Erling Smørgrav 870*17d15b25SDag-Erling Smørgrav ldns_dnssec_zone_hashed_names_from_nsec3(zone, rr); 8717b5038d7SDag-Erling Smørgrav } 872*17d15b25SDag-Erling Smørgrav if (zone->hashed_names == NULL) { 8737b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(hashed_name); 8747b5038d7SDag-Erling Smørgrav return NULL; 8757b5038d7SDag-Erling Smørgrav } 876*17d15b25SDag-Erling Smørgrav return ldns_rbtree_search(zone->hashed_names, hashed_name); 877*17d15b25SDag-Erling Smørgrav } 8787b5038d7SDag-Erling Smørgrav 8797b5038d7SDag-Erling Smørgrav ldns_status 8807b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_add_rr(ldns_dnssec_zone *zone, ldns_rr *rr) 8817b5038d7SDag-Erling Smørgrav { 8827b5038d7SDag-Erling Smørgrav ldns_status result = LDNS_STATUS_OK; 8837b5038d7SDag-Erling Smørgrav ldns_dnssec_name *cur_name; 8847b5038d7SDag-Erling Smørgrav ldns_rbnode_t *cur_node; 8857b5038d7SDag-Erling Smørgrav ldns_rr_type type_covered = 0; 8867b5038d7SDag-Erling Smørgrav 8877b5038d7SDag-Erling Smørgrav if (!zone || !rr) { 8887b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 8897b5038d7SDag-Erling Smørgrav } 8907b5038d7SDag-Erling Smørgrav 8917b5038d7SDag-Erling Smørgrav if (!zone->names) { 8927b5038d7SDag-Erling Smørgrav zone->names = ldns_rbtree_create(ldns_dname_compare_v); 8937b5038d7SDag-Erling Smørgrav if(!zone->names) return LDNS_STATUS_MEM_ERR; 8947b5038d7SDag-Erling Smørgrav } 8957b5038d7SDag-Erling Smørgrav 8967b5038d7SDag-Erling Smørgrav /* we need the original of the hashed name if this is 8977b5038d7SDag-Erling Smørgrav an NSEC3, or an RRSIG that covers an NSEC3 */ 8987b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG) { 8997b5038d7SDag-Erling Smørgrav type_covered = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr)); 9007b5038d7SDag-Erling Smørgrav } 9017b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_NSEC3 || 9027b5038d7SDag-Erling Smørgrav type_covered == LDNS_RR_TYPE_NSEC3) { 903*17d15b25SDag-Erling Smørgrav cur_node = ldns_dnssec_zone_find_nsec3_original(zone, rr); 9047b5038d7SDag-Erling Smørgrav if (!cur_node) { 9057b5038d7SDag-Erling Smørgrav return LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND; 9067b5038d7SDag-Erling Smørgrav } 9077b5038d7SDag-Erling Smørgrav } else { 9087b5038d7SDag-Erling Smørgrav cur_node = ldns_rbtree_search(zone->names, ldns_rr_owner(rr)); 9097b5038d7SDag-Erling Smørgrav } 9107b5038d7SDag-Erling Smørgrav if (!cur_node) { 9117b5038d7SDag-Erling Smørgrav /* add */ 9127b5038d7SDag-Erling Smørgrav cur_name = ldns_dnssec_name_new_frm_rr(rr); 9137b5038d7SDag-Erling Smørgrav if(!cur_name) return LDNS_STATUS_MEM_ERR; 9147b5038d7SDag-Erling Smørgrav cur_node = LDNS_MALLOC(ldns_rbnode_t); 9157b5038d7SDag-Erling Smørgrav if(!cur_node) { 9167b5038d7SDag-Erling Smørgrav ldns_dnssec_name_free(cur_name); 9177b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR; 9187b5038d7SDag-Erling Smørgrav } 9197b5038d7SDag-Erling Smørgrav cur_node->key = ldns_rr_owner(rr); 9207b5038d7SDag-Erling Smørgrav cur_node->data = cur_name; 9217b5038d7SDag-Erling Smørgrav (void)ldns_rbtree_insert(zone->names, cur_node); 922*17d15b25SDag-Erling Smørgrav ldns_dnssec_name_make_hashed_name(zone, cur_name, NULL); 9237b5038d7SDag-Erling Smørgrav } else { 9247b5038d7SDag-Erling Smørgrav cur_name = (ldns_dnssec_name *) cur_node->data; 9257b5038d7SDag-Erling Smørgrav result = ldns_dnssec_name_add_rr(cur_name, rr); 9267b5038d7SDag-Erling Smørgrav } 9277b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) { 9287b5038d7SDag-Erling Smørgrav zone->soa = cur_name; 9297b5038d7SDag-Erling Smørgrav } 9307b5038d7SDag-Erling Smørgrav return result; 9317b5038d7SDag-Erling Smørgrav } 9327b5038d7SDag-Erling Smørgrav 9337b5038d7SDag-Erling Smørgrav void 9347b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_names_print_fmt(FILE *out, const ldns_output_format *fmt, 9357b5038d7SDag-Erling Smørgrav ldns_rbtree_t *tree, 9367b5038d7SDag-Erling Smørgrav bool print_soa) 9377b5038d7SDag-Erling Smørgrav { 9387b5038d7SDag-Erling Smørgrav ldns_rbnode_t *node; 9397b5038d7SDag-Erling Smørgrav ldns_dnssec_name *name; 9407b5038d7SDag-Erling Smørgrav 9417b5038d7SDag-Erling Smørgrav node = ldns_rbtree_first(tree); 9427b5038d7SDag-Erling Smørgrav while (node != LDNS_RBTREE_NULL) { 9437b5038d7SDag-Erling Smørgrav name = (ldns_dnssec_name *) node->data; 9447b5038d7SDag-Erling Smørgrav ldns_dnssec_name_print_soa_fmt(out, fmt, name, print_soa); 9457b5038d7SDag-Erling Smørgrav if ((fmt->flags & LDNS_COMMENT_LAYOUT)) 9467b5038d7SDag-Erling Smørgrav fprintf(out, ";\n"); 9477b5038d7SDag-Erling Smørgrav node = ldns_rbtree_next(node); 9487b5038d7SDag-Erling Smørgrav } 9497b5038d7SDag-Erling Smørgrav } 9507b5038d7SDag-Erling Smørgrav 9517b5038d7SDag-Erling Smørgrav void 9527b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_names_print(FILE *out, ldns_rbtree_t *tree, bool print_soa) 9537b5038d7SDag-Erling Smørgrav { 9547b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_names_print_fmt(out, ldns_output_format_default, 9557b5038d7SDag-Erling Smørgrav tree, print_soa); 9567b5038d7SDag-Erling Smørgrav } 9577b5038d7SDag-Erling Smørgrav 9587b5038d7SDag-Erling Smørgrav void 9597b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_print_fmt(FILE *out, const ldns_output_format *fmt, 9607b5038d7SDag-Erling Smørgrav ldns_dnssec_zone *zone) 9617b5038d7SDag-Erling Smørgrav { 9627b5038d7SDag-Erling Smørgrav if (zone) { 9637b5038d7SDag-Erling Smørgrav if (zone->soa) { 9647b5038d7SDag-Erling Smørgrav if ((fmt->flags & LDNS_COMMENT_LAYOUT)) { 9657b5038d7SDag-Erling Smørgrav fprintf(out, ";; Zone: "); 9667b5038d7SDag-Erling Smørgrav ldns_rdf_print(out, ldns_dnssec_name_name( 9677b5038d7SDag-Erling Smørgrav zone->soa)); 9687b5038d7SDag-Erling Smørgrav fprintf(out, "\n;\n"); 9697b5038d7SDag-Erling Smørgrav } 9707b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_print_fmt(out, fmt, 9717b5038d7SDag-Erling Smørgrav ldns_dnssec_name_find_rrset( 9727b5038d7SDag-Erling Smørgrav zone->soa, 9737b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_SOA), 9747b5038d7SDag-Erling Smørgrav false); 9757b5038d7SDag-Erling Smørgrav if ((fmt->flags & LDNS_COMMENT_LAYOUT)) 9767b5038d7SDag-Erling Smørgrav fprintf(out, ";\n"); 9777b5038d7SDag-Erling Smørgrav } 9787b5038d7SDag-Erling Smørgrav 9797b5038d7SDag-Erling Smørgrav if (zone->names) { 9807b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_names_print_fmt(out, fmt, 9817b5038d7SDag-Erling Smørgrav zone->names, false); 9827b5038d7SDag-Erling Smørgrav } 9837b5038d7SDag-Erling Smørgrav } 9847b5038d7SDag-Erling Smørgrav } 9857b5038d7SDag-Erling Smørgrav 9867b5038d7SDag-Erling Smørgrav void 9877b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_print(FILE *out, ldns_dnssec_zone *zone) 9887b5038d7SDag-Erling Smørgrav { 9897b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_print_fmt(out, ldns_output_format_default, zone); 9907b5038d7SDag-Erling Smørgrav } 9917b5038d7SDag-Erling Smørgrav 9927b5038d7SDag-Erling Smørgrav ldns_status 9937b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_add_empty_nonterminals(ldns_dnssec_zone *zone) 9947b5038d7SDag-Erling Smørgrav { 9957b5038d7SDag-Erling Smørgrav ldns_dnssec_name *new_name; 9967b5038d7SDag-Erling Smørgrav ldns_rdf *cur_name; 9977b5038d7SDag-Erling Smørgrav ldns_rdf *next_name; 9987b5038d7SDag-Erling Smørgrav ldns_rbnode_t *cur_node, *next_node, *new_node; 9997b5038d7SDag-Erling Smørgrav 10007b5038d7SDag-Erling Smørgrav /* for the detection */ 10017b5038d7SDag-Erling Smørgrav uint16_t i, cur_label_count, next_label_count; 10027b5038d7SDag-Erling Smørgrav uint16_t soa_label_count = 0; 10037b5038d7SDag-Erling Smørgrav ldns_rdf *l1, *l2; 10047b5038d7SDag-Erling Smørgrav int lpos; 10057b5038d7SDag-Erling Smørgrav 10067b5038d7SDag-Erling Smørgrav if (!zone) { 10077b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 10087b5038d7SDag-Erling Smørgrav } 10097b5038d7SDag-Erling Smørgrav if (zone->soa && zone->soa->name) { 10107b5038d7SDag-Erling Smørgrav soa_label_count = ldns_dname_label_count(zone->soa->name); 10117b5038d7SDag-Erling Smørgrav } 10127b5038d7SDag-Erling Smørgrav 10137b5038d7SDag-Erling Smørgrav cur_node = ldns_rbtree_first(zone->names); 10147b5038d7SDag-Erling Smørgrav while (cur_node != LDNS_RBTREE_NULL) { 10157b5038d7SDag-Erling Smørgrav next_node = ldns_rbtree_next(cur_node); 10167b5038d7SDag-Erling Smørgrav 10177b5038d7SDag-Erling Smørgrav /* skip glue */ 10187b5038d7SDag-Erling Smørgrav while (next_node != LDNS_RBTREE_NULL && 10197b5038d7SDag-Erling Smørgrav next_node->data && 10207b5038d7SDag-Erling Smørgrav ((ldns_dnssec_name *)next_node->data)->is_glue 10217b5038d7SDag-Erling Smørgrav ) { 10227b5038d7SDag-Erling Smørgrav next_node = ldns_rbtree_next(next_node); 10237b5038d7SDag-Erling Smørgrav } 10247b5038d7SDag-Erling Smørgrav 10257b5038d7SDag-Erling Smørgrav if (next_node == LDNS_RBTREE_NULL) { 10267b5038d7SDag-Erling Smørgrav next_node = ldns_rbtree_first(zone->names); 10277b5038d7SDag-Erling Smørgrav } 10282787e39aSDag-Erling Smørgrav if (! cur_node->data || ! next_node->data) { 10292787e39aSDag-Erling Smørgrav return LDNS_STATUS_ERR; 10302787e39aSDag-Erling Smørgrav } 10317b5038d7SDag-Erling Smørgrav cur_name = ((ldns_dnssec_name *)cur_node->data)->name; 10327b5038d7SDag-Erling Smørgrav next_name = ((ldns_dnssec_name *)next_node->data)->name; 10337b5038d7SDag-Erling Smørgrav cur_label_count = ldns_dname_label_count(cur_name); 10347b5038d7SDag-Erling Smørgrav next_label_count = ldns_dname_label_count(next_name); 10357b5038d7SDag-Erling Smørgrav 10367b5038d7SDag-Erling Smørgrav /* Since the names are in canonical order, we can 10377b5038d7SDag-Erling Smørgrav * recognize empty non-terminals by their labels; 10387b5038d7SDag-Erling Smørgrav * every label after the first one on the next owner 10397b5038d7SDag-Erling Smørgrav * name is a non-terminal if it either does not exist 10407b5038d7SDag-Erling Smørgrav * in the current name or is different from the same 10417b5038d7SDag-Erling Smørgrav * label in the current name (counting from the end) 10427b5038d7SDag-Erling Smørgrav */ 10437b5038d7SDag-Erling Smørgrav for (i = 1; i < next_label_count - soa_label_count; i++) { 10447b5038d7SDag-Erling Smørgrav lpos = (int)cur_label_count - (int)next_label_count + (int)i; 10457b5038d7SDag-Erling Smørgrav if (lpos >= 0) { 10467b5038d7SDag-Erling Smørgrav l1 = ldns_dname_clone_from(cur_name, (uint8_t)lpos); 10477b5038d7SDag-Erling Smørgrav } else { 10487b5038d7SDag-Erling Smørgrav l1 = NULL; 10497b5038d7SDag-Erling Smørgrav } 10507b5038d7SDag-Erling Smørgrav l2 = ldns_dname_clone_from(next_name, i); 10517b5038d7SDag-Erling Smørgrav 10527b5038d7SDag-Erling Smørgrav if (!l1 || ldns_dname_compare(l1, l2) != 0) { 10537b5038d7SDag-Erling Smørgrav /* We have an empty nonterminal, add it to the 10547b5038d7SDag-Erling Smørgrav * tree 10557b5038d7SDag-Erling Smørgrav */ 10567b5038d7SDag-Erling Smørgrav new_name = ldns_dnssec_name_new(); 10577b5038d7SDag-Erling Smørgrav if (!new_name) { 10587b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR; 10597b5038d7SDag-Erling Smørgrav } 10607b5038d7SDag-Erling Smørgrav new_name->name = ldns_dname_clone_from(next_name, 10617b5038d7SDag-Erling Smørgrav i); 10627b5038d7SDag-Erling Smørgrav if (!new_name->name) { 10637b5038d7SDag-Erling Smørgrav ldns_dnssec_name_free(new_name); 10647b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR; 10657b5038d7SDag-Erling Smørgrav } 10667b5038d7SDag-Erling Smørgrav new_name->name_alloced = true; 10677b5038d7SDag-Erling Smørgrav new_node = LDNS_MALLOC(ldns_rbnode_t); 10687b5038d7SDag-Erling Smørgrav if (!new_node) { 10697b5038d7SDag-Erling Smørgrav ldns_dnssec_name_free(new_name); 10707b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR; 10717b5038d7SDag-Erling Smørgrav } 10727b5038d7SDag-Erling Smørgrav new_node->key = new_name->name; 10737b5038d7SDag-Erling Smørgrav new_node->data = new_name; 10747b5038d7SDag-Erling Smørgrav (void)ldns_rbtree_insert(zone->names, new_node); 1075*17d15b25SDag-Erling Smørgrav ldns_dnssec_name_make_hashed_name( 1076*17d15b25SDag-Erling Smørgrav zone, new_name, NULL); 10777b5038d7SDag-Erling Smørgrav } 10787b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(l1); 10797b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(l2); 10807b5038d7SDag-Erling Smørgrav } 10817b5038d7SDag-Erling Smørgrav 10827b5038d7SDag-Erling Smørgrav /* we might have inserted a new node after 10837b5038d7SDag-Erling Smørgrav * the current one so we can't just use next() 10847b5038d7SDag-Erling Smørgrav */ 10857b5038d7SDag-Erling Smørgrav if (next_node != ldns_rbtree_first(zone->names)) { 10867b5038d7SDag-Erling Smørgrav cur_node = next_node; 10877b5038d7SDag-Erling Smørgrav } else { 10887b5038d7SDag-Erling Smørgrav cur_node = LDNS_RBTREE_NULL; 10897b5038d7SDag-Erling Smørgrav } 10907b5038d7SDag-Erling Smørgrav } 10917b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK; 10927b5038d7SDag-Erling Smørgrav } 10937b5038d7SDag-Erling Smørgrav 10947b5038d7SDag-Erling Smørgrav bool 10957b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_is_nsec3_optout(ldns_dnssec_zone* zone) 10967b5038d7SDag-Erling Smørgrav { 10977b5038d7SDag-Erling Smørgrav ldns_rr* nsec3; 10987b5038d7SDag-Erling Smørgrav ldns_rbnode_t* node; 10997b5038d7SDag-Erling Smørgrav 11007b5038d7SDag-Erling Smørgrav if (ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_NSEC3PARAM)) { 11017b5038d7SDag-Erling Smørgrav node = ldns_rbtree_first(zone->names); 11027b5038d7SDag-Erling Smørgrav while (node != LDNS_RBTREE_NULL) { 11037b5038d7SDag-Erling Smørgrav nsec3 = ((ldns_dnssec_name*)node->data)->nsec; 11047b5038d7SDag-Erling Smørgrav if (nsec3 &&ldns_rr_get_type(nsec3) 11057b5038d7SDag-Erling Smørgrav == LDNS_RR_TYPE_NSEC3 && 11067b5038d7SDag-Erling Smørgrav ldns_nsec3_optout(nsec3)) { 11077b5038d7SDag-Erling Smørgrav return true; 11087b5038d7SDag-Erling Smørgrav } 11097b5038d7SDag-Erling Smørgrav node = ldns_rbtree_next(node); 11107b5038d7SDag-Erling Smørgrav } 11117b5038d7SDag-Erling Smørgrav } 11127b5038d7SDag-Erling Smørgrav return false; 11137b5038d7SDag-Erling Smørgrav } 1114