00001
00002
00003
00004
00005 #include <ldns/config.h>
00006
00007 #include <ldns/ldns.h>
00008
00009 ldns_dnssec_rrs *
00010 ldns_dnssec_rrs_new()
00011 {
00012 ldns_dnssec_rrs *new_rrs;
00013 new_rrs = LDNS_MALLOC(ldns_dnssec_rrs);
00014 if(!new_rrs) return NULL;
00015 new_rrs->rr = NULL;
00016 new_rrs->next = NULL;
00017 return new_rrs;
00018 }
00019
00020 INLINE void
00021 ldns_dnssec_rrs_free_internal(ldns_dnssec_rrs *rrs, int deep)
00022 {
00023 ldns_dnssec_rrs *next;
00024 while (rrs) {
00025 next = rrs->next;
00026 if (deep) {
00027 ldns_rr_free(rrs->rr);
00028 }
00029 LDNS_FREE(rrs);
00030 rrs = next;
00031 }
00032 }
00033
00034 void
00035 ldns_dnssec_rrs_free(ldns_dnssec_rrs *rrs)
00036 {
00037 ldns_dnssec_rrs_free_internal(rrs, 0);
00038 }
00039
00040 void
00041 ldns_dnssec_rrs_deep_free(ldns_dnssec_rrs *rrs)
00042 {
00043 ldns_dnssec_rrs_free_internal(rrs, 1);
00044 }
00045
00046 ldns_status
00047 ldns_dnssec_rrs_add_rr(ldns_dnssec_rrs *rrs, ldns_rr *rr)
00048 {
00049 int cmp;
00050 ldns_dnssec_rrs *new_rrs;
00051 if (!rrs || !rr) {
00052 return LDNS_STATUS_ERR;
00053 }
00054
00055
00056
00057 cmp = ldns_rr_compare(rrs->rr,
00058 rr);
00059
00060 if (cmp <= 0) {
00061 if (rrs->next) {
00062 return ldns_dnssec_rrs_add_rr(rrs->next, rr);
00063 } else {
00064 new_rrs = ldns_dnssec_rrs_new();
00065 new_rrs->rr = rr;
00066 rrs->next = new_rrs;
00067 }
00068 } else if (cmp > 0) {
00069
00070
00071 new_rrs = ldns_dnssec_rrs_new();
00072 new_rrs->rr = rrs->rr;
00073 new_rrs->next = rrs->next;
00074 rrs->rr = rr;
00075 rrs->next = new_rrs;
00076 }
00077 return LDNS_STATUS_OK;
00078 }
00079
00080 void
00081 ldns_dnssec_rrs_print_fmt(FILE *out, const ldns_output_format *fmt,
00082 ldns_dnssec_rrs *rrs)
00083 {
00084 if (!rrs) {
00085 if ((fmt->flags & LDNS_COMMENT_LAYOUT))
00086 fprintf(out, "; <void>");
00087 } else {
00088 if (rrs->rr) {
00089 ldns_rr_print_fmt(out, fmt, rrs->rr);
00090 }
00091 if (rrs->next) {
00092 ldns_dnssec_rrs_print_fmt(out, fmt, rrs->next);
00093 }
00094 }
00095 }
00096
00097 void
00098 ldns_dnssec_rrs_print(FILE *out, ldns_dnssec_rrs *rrs)
00099 {
00100 ldns_dnssec_rrs_print_fmt(out, ldns_output_format_default, rrs);
00101 }
00102
00103
00104 ldns_dnssec_rrsets *
00105 ldns_dnssec_rrsets_new()
00106 {
00107 ldns_dnssec_rrsets *new_rrsets;
00108 new_rrsets = LDNS_MALLOC(ldns_dnssec_rrsets);
00109 if(!new_rrsets) return NULL;
00110 new_rrsets->rrs = NULL;
00111 new_rrsets->type = 0;
00112 new_rrsets->signatures = NULL;
00113 new_rrsets->next = NULL;
00114 return new_rrsets;
00115 }
00116
00117 INLINE void
00118 ldns_dnssec_rrsets_free_internal(ldns_dnssec_rrsets *rrsets, int deep)
00119 {
00120 if (rrsets) {
00121 if (rrsets->rrs) {
00122 ldns_dnssec_rrs_free_internal(rrsets->rrs, deep);
00123 }
00124 if (rrsets->next) {
00125 ldns_dnssec_rrsets_free_internal(rrsets->next, deep);
00126 }
00127 if (rrsets->signatures) {
00128 ldns_dnssec_rrs_free_internal(rrsets->signatures, deep);
00129 }
00130 LDNS_FREE(rrsets);
00131 }
00132 }
00133
00134 void
00135 ldns_dnssec_rrsets_free(ldns_dnssec_rrsets *rrsets)
00136 {
00137 ldns_dnssec_rrsets_free_internal(rrsets, 0);
00138 }
00139
00140 void
00141 ldns_dnssec_rrsets_deep_free(ldns_dnssec_rrsets *rrsets)
00142 {
00143 ldns_dnssec_rrsets_free_internal(rrsets, 1);
00144 }
00145
00146 ldns_rr_type
00147 ldns_dnssec_rrsets_type(ldns_dnssec_rrsets *rrsets)
00148 {
00149 if (rrsets) {
00150 return rrsets->type;
00151 } else {
00152 return 0;
00153 }
00154 }
00155
00156 ldns_status
00157 ldns_dnssec_rrsets_set_type(ldns_dnssec_rrsets *rrsets,
00158 ldns_rr_type type)
00159 {
00160 if (rrsets) {
00161 rrsets->type = type;
00162 return LDNS_STATUS_OK;
00163 }
00164 return LDNS_STATUS_ERR;
00165 }
00166
00167 ldns_dnssec_rrsets *
00168 ldns_dnssec_rrsets_new_frm_rr(ldns_rr *rr)
00169 {
00170 ldns_dnssec_rrsets *new_rrsets;
00171 ldns_rr_type rr_type;
00172 bool rrsig;
00173
00174 new_rrsets = ldns_dnssec_rrsets_new();
00175 rr_type = ldns_rr_get_type(rr);
00176 if (rr_type == LDNS_RR_TYPE_RRSIG) {
00177 rrsig = true;
00178 rr_type = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr));
00179 } else {
00180 rrsig = false;
00181 }
00182 if (!rrsig) {
00183 new_rrsets->rrs = ldns_dnssec_rrs_new();
00184 new_rrsets->rrs->rr = rr;
00185 } else {
00186 new_rrsets->signatures = ldns_dnssec_rrs_new();
00187 new_rrsets->signatures->rr = rr;
00188 }
00189 new_rrsets->type = rr_type;
00190 return new_rrsets;
00191 }
00192
00193 ldns_status
00194 ldns_dnssec_rrsets_add_rr(ldns_dnssec_rrsets *rrsets, ldns_rr *rr)
00195 {
00196 ldns_dnssec_rrsets *new_rrsets;
00197 ldns_rr_type rr_type;
00198 bool rrsig = false;
00199 ldns_status result = LDNS_STATUS_OK;
00200
00201 if (!rrsets || !rr) {
00202 return LDNS_STATUS_ERR;
00203 }
00204
00205 rr_type = ldns_rr_get_type(rr);
00206
00207 if (rr_type == LDNS_RR_TYPE_RRSIG) {
00208 rrsig = true;
00209 rr_type = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr));
00210 }
00211
00212 if (!rrsets->rrs && rrsets->type == 0 && !rrsets->signatures) {
00213 if (!rrsig) {
00214 rrsets->rrs = ldns_dnssec_rrs_new();
00215 rrsets->rrs->rr = rr;
00216 rrsets->type = rr_type;
00217 } else {
00218 rrsets->signatures = ldns_dnssec_rrs_new();
00219 rrsets->signatures->rr = rr;
00220 rrsets->type = rr_type;
00221 }
00222 return LDNS_STATUS_OK;
00223 }
00224
00225 if (rr_type > ldns_dnssec_rrsets_type(rrsets)) {
00226 if (rrsets->next) {
00227 result = ldns_dnssec_rrsets_add_rr(rrsets->next, rr);
00228 } else {
00229 new_rrsets = ldns_dnssec_rrsets_new_frm_rr(rr);
00230 rrsets->next = new_rrsets;
00231 }
00232 } else if (rr_type < ldns_dnssec_rrsets_type(rrsets)) {
00233
00234
00235 new_rrsets = ldns_dnssec_rrsets_new();
00236 new_rrsets->rrs = rrsets->rrs;
00237 new_rrsets->type = rrsets->type;
00238 new_rrsets->signatures = rrsets->signatures;
00239 new_rrsets->next = rrsets->next;
00240 if (!rrsig) {
00241 rrsets->rrs = ldns_dnssec_rrs_new();
00242 rrsets->rrs->rr = rr;
00243 rrsets->signatures = NULL;
00244 } else {
00245 rrsets->rrs = NULL;
00246 rrsets->signatures = ldns_dnssec_rrs_new();
00247 rrsets->signatures->rr = rr;
00248 }
00249 rrsets->type = rr_type;
00250 rrsets->next = new_rrsets;
00251 } else {
00252
00253 if (rrsig) {
00254 if (rrsets->signatures) {
00255 result = ldns_dnssec_rrs_add_rr(rrsets->signatures, rr);
00256 } else {
00257 rrsets->signatures = ldns_dnssec_rrs_new();
00258 rrsets->signatures->rr = rr;
00259 }
00260 } else {
00261 if (rrsets->rrs) {
00262 result = ldns_dnssec_rrs_add_rr(rrsets->rrs, rr);
00263 } else {
00264 rrsets->rrs = ldns_dnssec_rrs_new();
00265 rrsets->rrs->rr = rr;
00266 }
00267 }
00268 }
00269
00270 return result;
00271 }
00272
00273 void
00274 ldns_dnssec_rrsets_print_soa_fmt(FILE *out, const ldns_output_format *fmt,
00275 ldns_dnssec_rrsets *rrsets,
00276 bool follow,
00277 bool show_soa)
00278 {
00279 if (!rrsets) {
00280 if ((fmt->flags & LDNS_COMMENT_LAYOUT))
00281 fprintf(out, "; <void>\n");
00282 } else {
00283 if (rrsets->rrs &&
00284 (show_soa ||
00285 ldns_rr_get_type(rrsets->rrs->rr) != LDNS_RR_TYPE_SOA
00286 )
00287 ) {
00288 ldns_dnssec_rrs_print_fmt(out, fmt, rrsets->rrs);
00289 if (rrsets->signatures) {
00290 ldns_dnssec_rrs_print_fmt(out, fmt,
00291 rrsets->signatures);
00292 }
00293 }
00294 if (follow && rrsets->next) {
00295 ldns_dnssec_rrsets_print_soa_fmt(out, fmt,
00296 rrsets->next, follow, show_soa);
00297 }
00298 }
00299 }
00300
00301 void
00302 ldns_dnssec_rrsets_print_soa(FILE *out,
00303 ldns_dnssec_rrsets *rrsets,
00304 bool follow,
00305 bool show_soa)
00306 {
00307 ldns_dnssec_rrsets_print_soa_fmt(out, ldns_output_format_default,
00308 rrsets, follow, show_soa);
00309 }
00310
00311
00312 void
00313 ldns_dnssec_rrsets_print_fmt(FILE *out, const ldns_output_format *fmt,
00314 ldns_dnssec_rrsets *rrsets,
00315 bool follow)
00316 {
00317 ldns_dnssec_rrsets_print_soa_fmt(out, fmt, rrsets, follow, true);
00318 }
00319
00320 void
00321 ldns_dnssec_rrsets_print(FILE *out, ldns_dnssec_rrsets *rrsets, bool follow)
00322 {
00323 ldns_dnssec_rrsets_print_fmt(out, ldns_output_format_default,
00324 rrsets, follow);
00325 }
00326
00327 ldns_dnssec_name *
00328 ldns_dnssec_name_new()
00329 {
00330 ldns_dnssec_name *new_name;
00331
00332 new_name = LDNS_CALLOC(ldns_dnssec_name, 1);
00333 if (!new_name) {
00334 return NULL;
00335 }
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349 return new_name;
00350 }
00351
00352 ldns_dnssec_name *
00353 ldns_dnssec_name_new_frm_rr(ldns_rr *rr)
00354 {
00355 ldns_dnssec_name *new_name = ldns_dnssec_name_new();
00356
00357 new_name->name = ldns_rr_owner(rr);
00358 if(ldns_dnssec_name_add_rr(new_name, rr) != LDNS_STATUS_OK) {
00359 ldns_dnssec_name_free(new_name);
00360 return NULL;
00361 }
00362
00363 return new_name;
00364 }
00365
00366 INLINE void
00367 ldns_dnssec_name_free_internal(ldns_dnssec_name *name,
00368 int deep)
00369 {
00370 if (name) {
00371 if (name->name_alloced) {
00372 ldns_rdf_deep_free(name->name);
00373 }
00374 if (name->rrsets) {
00375 ldns_dnssec_rrsets_free_internal(name->rrsets, deep);
00376 }
00377 if (name->nsec && deep) {
00378 ldns_rr_free(name->nsec);
00379 }
00380 if (name->nsec_signatures) {
00381 ldns_dnssec_rrs_free_internal(name->nsec_signatures, deep);
00382 }
00383 if (name->hashed_name) {
00384 if (deep) {
00385 ldns_rdf_deep_free(name->hashed_name);
00386 }
00387 }
00388 LDNS_FREE(name);
00389 }
00390 }
00391
00392 void
00393 ldns_dnssec_name_free(ldns_dnssec_name *name)
00394 {
00395 ldns_dnssec_name_free_internal(name, 0);
00396 }
00397
00398 void
00399 ldns_dnssec_name_deep_free(ldns_dnssec_name *name)
00400 {
00401 ldns_dnssec_name_free_internal(name, 1);
00402 }
00403
00404 ldns_rdf *
00405 ldns_dnssec_name_name(ldns_dnssec_name *name)
00406 {
00407 if (name) {
00408 return name->name;
00409 }
00410 return NULL;
00411 }
00412
00413 bool
00414 ldns_dnssec_name_is_glue(ldns_dnssec_name *name)
00415 {
00416 if (name) {
00417 return name->is_glue;
00418 }
00419 return false;
00420 }
00421
00422 void
00423 ldns_dnssec_name_set_name(ldns_dnssec_name *rrset,
00424 ldns_rdf *dname)
00425 {
00426 if (rrset && dname) {
00427 rrset->name = dname;
00428 }
00429 }
00430
00431 ldns_rr *
00432 ldns_dnssec_name_nsec(ldns_dnssec_name *rrset)
00433 {
00434 if (rrset) {
00435 return rrset->nsec;
00436 }
00437 return NULL;
00438 }
00439
00440 void
00441 ldns_dnssec_name_set_nsec(ldns_dnssec_name *rrset, ldns_rr *nsec)
00442 {
00443 if (rrset && nsec) {
00444 rrset->nsec = nsec;
00445 }
00446 }
00447
00448 int
00449 ldns_dnssec_name_cmp(const void *a, const void *b)
00450 {
00451 ldns_dnssec_name *na = (ldns_dnssec_name *) a;
00452 ldns_dnssec_name *nb = (ldns_dnssec_name *) b;
00453
00454 if (na && nb) {
00455 return ldns_dname_compare(ldns_dnssec_name_name(na),
00456 ldns_dnssec_name_name(nb));
00457 } else if (na) {
00458 return 1;
00459 } else if (nb) {
00460 return -1;
00461 } else {
00462 return 0;
00463 }
00464 }
00465
00466 ldns_status
00467 ldns_dnssec_name_add_rr(ldns_dnssec_name *name,
00468 ldns_rr *rr)
00469 {
00470 ldns_status result = LDNS_STATUS_OK;
00471 ldns_rdf *name_name;
00472 bool hashed_name = false;
00473 ldns_rr_type rr_type;
00474 ldns_rr_type typecovered = 0;
00475
00476
00477
00478 if (!name || !rr) {
00479 return LDNS_STATUS_ERR;
00480 }
00481
00482 rr_type = ldns_rr_get_type(rr);
00483
00484 if (rr_type == LDNS_RR_TYPE_RRSIG) {
00485 typecovered = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr));
00486 }
00487
00488 #ifdef HAVE_SSL
00489 if (rr_type == LDNS_RR_TYPE_NSEC3 ||
00490 typecovered == LDNS_RR_TYPE_NSEC3) {
00491 name_name = ldns_nsec3_hash_name_frm_nsec3(rr,
00492 ldns_dnssec_name_name(name));
00493 hashed_name = true;
00494 } else {
00495 name_name = ldns_dnssec_name_name(name);
00496 }
00497 #else
00498 name_name = ldns_dnssec_name_name(name);
00499 #endif
00500
00501 if (rr_type == LDNS_RR_TYPE_NSEC ||
00502 rr_type == LDNS_RR_TYPE_NSEC3) {
00503
00504 name->nsec = rr;
00505 } else if (typecovered == LDNS_RR_TYPE_NSEC ||
00506 typecovered == LDNS_RR_TYPE_NSEC3) {
00507 if (name->nsec_signatures) {
00508 result = ldns_dnssec_rrs_add_rr(name->nsec_signatures, rr);
00509 } else {
00510 name->nsec_signatures = ldns_dnssec_rrs_new();
00511 name->nsec_signatures->rr = rr;
00512 }
00513 } else {
00514
00515 if (name->rrsets) {
00516 result = ldns_dnssec_rrsets_add_rr(name->rrsets, rr);
00517 } else {
00518 name->rrsets = ldns_dnssec_rrsets_new();
00519 result = ldns_dnssec_rrsets_add_rr(name->rrsets, rr);
00520 }
00521 }
00522
00523 if (hashed_name) {
00524 ldns_rdf_deep_free(name_name);
00525 }
00526
00527 return result;
00528 }
00529
00530 ldns_dnssec_rrsets *
00531 ldns_dnssec_name_find_rrset(ldns_dnssec_name *name,
00532 ldns_rr_type type) {
00533 ldns_dnssec_rrsets *result;
00534
00535 result = name->rrsets;
00536 while (result) {
00537 if (result->type == type) {
00538 return result;
00539 } else {
00540 result = result->next;
00541 }
00542 }
00543 return NULL;
00544 }
00545
00546 ldns_dnssec_rrsets *
00547 ldns_dnssec_zone_find_rrset(ldns_dnssec_zone *zone,
00548 ldns_rdf *dname,
00549 ldns_rr_type type)
00550 {
00551 ldns_rbnode_t *node;
00552
00553 if (!zone || !dname) {
00554 return NULL;
00555 }
00556
00557 node = ldns_rbtree_search(zone->names, dname);
00558 if (node) {
00559 return ldns_dnssec_name_find_rrset((ldns_dnssec_name *)node->data,
00560 type);
00561 } else {
00562 return NULL;
00563 }
00564 }
00565
00566 void
00567 ldns_dnssec_name_print_soa_fmt(FILE *out, const ldns_output_format *fmt,
00568 ldns_dnssec_name *name,
00569 bool show_soa)
00570 {
00571 if (name) {
00572 if(name->rrsets) {
00573 ldns_dnssec_rrsets_print_soa_fmt(out, fmt,
00574 name->rrsets, true, show_soa);
00575 } else if ((fmt->flags & LDNS_COMMENT_LAYOUT)) {
00576 fprintf(out, ";; Empty nonterminal: ");
00577 ldns_rdf_print(out, name->name);
00578 fprintf(out, "\n");
00579 }
00580 if(name->nsec) {
00581 ldns_rr_print_fmt(out, fmt, name->nsec);
00582 }
00583 if (name->nsec_signatures) {
00584 ldns_dnssec_rrs_print_fmt(out, fmt,
00585 name->nsec_signatures);
00586 }
00587 } else if ((fmt->flags & LDNS_COMMENT_LAYOUT)) {
00588 fprintf(out, "; <void>\n");
00589 }
00590 }
00591
00592 void
00593 ldns_dnssec_name_print_soa(FILE *out, ldns_dnssec_name *name, bool show_soa)
00594 {
00595 ldns_dnssec_name_print_soa_fmt(out, ldns_output_format_default,
00596 name, show_soa);
00597 }
00598
00599 void
00600 ldns_dnssec_name_print_fmt(FILE *out, const ldns_output_format *fmt,
00601 ldns_dnssec_name *name)
00602 {
00603 ldns_dnssec_name_print_soa_fmt(out, fmt, name, true);
00604 }
00605
00606 void
00607 ldns_dnssec_name_print(FILE *out, ldns_dnssec_name *name)
00608 {
00609 ldns_dnssec_name_print_fmt(out, ldns_output_format_default, name);
00610 }
00611
00612
00613 ldns_dnssec_zone *
00614 ldns_dnssec_zone_new()
00615 {
00616 ldns_dnssec_zone *zone = LDNS_MALLOC(ldns_dnssec_zone);
00617 if(!zone) return NULL;
00618 zone->soa = NULL;
00619 zone->names = NULL;
00620
00621 return zone;
00622 }
00623
00624 static bool
00625 rr_is_rrsig_covering(ldns_rr* rr, ldns_rr_type t)
00626 {
00627 return ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG
00628 && ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr)) == t;
00629 }
00630
00631
00632
00633
00634
00635
00636
00637 #define FASTER_DNSSEC_ZONE_NEW_FRM_FP 1
00638
00639 ldns_status
00640 ldns_dnssec_zone_new_frm_fp_l(ldns_dnssec_zone** z, FILE* fp, ldns_rdf* origin,
00641 uint32_t ttl, ldns_rr_class ATTR_UNUSED(c), int* line_nr)
00642 {
00643 ldns_rr* cur_rr;
00644 size_t i;
00645
00646 ldns_rdf *my_origin = NULL;
00647 ldns_rdf *my_prev = NULL;
00648
00649 ldns_dnssec_zone *newzone = ldns_dnssec_zone_new();
00650
00651
00652
00653
00654 ldns_rr_list* todo_nsec3s = ldns_rr_list_new();
00655 ldns_rr_list* todo_nsec3_rrsigs = ldns_rr_list_new();
00656
00657 ldns_status status = LDNS_STATUS_MEM_ERR;
00658
00659 #ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP
00660 ldns_zone* zone = NULL;
00661 if (ldns_zone_new_frm_fp_l(&zone, fp, origin,ttl, c, line_nr)
00662 != LDNS_STATUS_OK) goto error;
00663 #else
00664 uint32_t my_ttl = ttl;
00665 #endif
00666
00667 if (!newzone || !todo_nsec3s || !todo_nsec3_rrsigs ) goto error;
00668
00669 if (origin) {
00670 if (!(my_origin = ldns_rdf_clone(origin))) goto error;
00671 if (!(my_prev = ldns_rdf_clone(origin))) goto error;
00672 }
00673
00674 #ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP
00675 if (ldns_dnssec_zone_add_rr(newzone, ldns_zone_soa(zone))
00676 != LDNS_STATUS_OK) goto error;
00677
00678 for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) {
00679 cur_rr = ldns_rr_list_rr(ldns_zone_rrs(zone), i);
00680 status = LDNS_STATUS_OK;
00681 #else
00682 while (!feof(fp)) {
00683 status = ldns_rr_new_frm_fp_l(&cur_rr, fp, &my_ttl, &my_origin,
00684 &my_prev, line_nr);
00685
00686 #endif
00687 switch (status) {
00688 case LDNS_STATUS_OK:
00689
00690 status = ldns_dnssec_zone_add_rr(newzone, cur_rr);
00691 if (status ==
00692 LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND) {
00693
00694 if (rr_is_rrsig_covering(cur_rr,
00695 LDNS_RR_TYPE_NSEC3)){
00696 ldns_rr_list_push_rr(todo_nsec3_rrsigs,
00697 cur_rr);
00698 } else {
00699 ldns_rr_list_push_rr(todo_nsec3s,
00700 cur_rr);
00701 }
00702 } else if (status != LDNS_STATUS_OK)
00703 goto error;
00704
00705 break;
00706
00707
00708 case LDNS_STATUS_SYNTAX_EMPTY:
00709 case LDNS_STATUS_SYNTAX_TTL:
00710 case LDNS_STATUS_SYNTAX_ORIGIN:
00711 status = LDNS_STATUS_OK;
00712 break;
00713
00714 case LDNS_STATUS_SYNTAX_INCLUDE:
00715 status = LDNS_STATUS_SYNTAX_INCLUDE_ERR_NOTIMPL;
00716 break;
00717
00718 default:
00719 goto error;
00720 }
00721 }
00722
00723 if (ldns_rr_list_rr_count(todo_nsec3s) > 0) {
00724 (void) ldns_dnssec_zone_add_empty_nonterminals(newzone);
00725 for (i = 0; status == LDNS_STATUS_OK &&
00726 i < ldns_rr_list_rr_count(todo_nsec3s); i++) {
00727 cur_rr = ldns_rr_list_rr(todo_nsec3s, i);
00728 status = ldns_dnssec_zone_add_rr(newzone, cur_rr);
00729 }
00730 for (i = 0; status == LDNS_STATUS_OK &&
00731 i < ldns_rr_list_rr_count(todo_nsec3_rrsigs);
00732 i++){
00733 cur_rr = ldns_rr_list_rr(todo_nsec3_rrsigs, i);
00734 status = ldns_dnssec_zone_add_rr(newzone, cur_rr);
00735 }
00736 } else if (ldns_rr_list_rr_count(todo_nsec3_rrsigs) > 0) {
00737 for (i = 0; status == LDNS_STATUS_OK &&
00738 i < ldns_rr_list_rr_count(todo_nsec3_rrsigs);
00739 i++){
00740 cur_rr = ldns_rr_list_rr(todo_nsec3_rrsigs, i);
00741 status = ldns_dnssec_zone_add_rr(newzone, cur_rr);
00742 }
00743 }
00744
00745 if (z) {
00746 *z = newzone;
00747 newzone = NULL;
00748 } else {
00749 ldns_dnssec_zone_free(newzone);
00750 }
00751
00752 error:
00753 #ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP
00754 if (zone) {
00755 ldns_zone_free(zone);
00756 }
00757 #endif
00758 ldns_rr_list_free(todo_nsec3_rrsigs);
00759 ldns_rr_list_free(todo_nsec3s);
00760
00761 if (my_origin) {
00762 ldns_rdf_deep_free(my_origin);
00763 }
00764 if (my_prev) {
00765 ldns_rdf_deep_free(my_prev);
00766 }
00767 if (newzone) {
00768 ldns_dnssec_zone_free(newzone);
00769 }
00770 return status;
00771 }
00772
00773 ldns_status
00774 ldns_dnssec_zone_new_frm_fp(ldns_dnssec_zone** z, FILE* fp, ldns_rdf* origin,
00775 uint32_t ttl, ldns_rr_class ATTR_UNUSED(c))
00776 {
00777 return ldns_dnssec_zone_new_frm_fp_l(z, fp, origin, ttl, c, NULL);
00778 }
00779
00780 void
00781 ldns_dnssec_name_node_free(ldns_rbnode_t *node, void *arg) {
00782 (void) arg;
00783 ldns_dnssec_name_free((ldns_dnssec_name *)node->data);
00784 LDNS_FREE(node);
00785 }
00786
00787 void
00788 ldns_dnssec_name_node_deep_free(ldns_rbnode_t *node, void *arg) {
00789 (void) arg;
00790 ldns_dnssec_name_deep_free((ldns_dnssec_name *)node->data);
00791 LDNS_FREE(node);
00792 }
00793
00794 void
00795 ldns_dnssec_zone_free(ldns_dnssec_zone *zone)
00796 {
00797 if (zone) {
00798 if (zone->names) {
00799
00800 ldns_traverse_postorder(zone->names,
00801 ldns_dnssec_name_node_free,
00802 NULL);
00803 LDNS_FREE(zone->names);
00804 }
00805 LDNS_FREE(zone);
00806 }
00807 }
00808
00809 void
00810 ldns_dnssec_zone_deep_free(ldns_dnssec_zone *zone)
00811 {
00812 if (zone) {
00813 if (zone->names) {
00814
00815 ldns_traverse_postorder(zone->names,
00816 ldns_dnssec_name_node_deep_free,
00817 NULL);
00818 LDNS_FREE(zone->names);
00819 }
00820 LDNS_FREE(zone);
00821 }
00822 }
00823
00824
00825 int
00826 ldns_dname_compare_v(const void *a, const void *b) {
00827 return ldns_dname_compare((ldns_rdf *)a, (ldns_rdf *)b);
00828 }
00829
00830 ldns_rbnode_t *
00831 ldns_dnssec_zone_find_nsec3_original(ldns_dnssec_zone *zone,
00832 ldns_rr *rr) {
00833 ldns_rbnode_t *current_node = ldns_rbtree_first(zone->names);
00834 ldns_dnssec_name *current_name;
00835 ldns_rdf *hashed_name;
00836
00837 hashed_name = ldns_dname_label(ldns_rr_owner(rr), 0);
00838
00839 while (current_node != LDNS_RBTREE_NULL) {
00840 current_name = (ldns_dnssec_name *) current_node->data;
00841 if (!current_name->hashed_name) {
00842 current_name->hashed_name =
00843 ldns_nsec3_hash_name_frm_nsec3(rr, current_name->name);
00844 }
00845 if (ldns_dname_compare(hashed_name,
00846 current_name->hashed_name)
00847 == 0) {
00848 ldns_rdf_deep_free(hashed_name);
00849 return current_node;
00850 }
00851 current_node = ldns_rbtree_next(current_node);
00852 }
00853 ldns_rdf_deep_free(hashed_name);
00854 return NULL;
00855 }
00856
00857 ldns_status
00858 ldns_dnssec_zone_add_rr(ldns_dnssec_zone *zone, ldns_rr *rr)
00859 {
00860 ldns_status result = LDNS_STATUS_OK;
00861 ldns_dnssec_name *cur_name;
00862 ldns_rbnode_t *cur_node;
00863 ldns_rr_type type_covered = 0;
00864
00865 if (!zone || !rr) {
00866 return LDNS_STATUS_ERR;
00867 }
00868
00869 if (!zone->names) {
00870 zone->names = ldns_rbtree_create(ldns_dname_compare_v);
00871 if(!zone->names) return LDNS_STATUS_MEM_ERR;
00872 }
00873
00874
00875
00876 if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG) {
00877 type_covered = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr));
00878 }
00879 if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_NSEC3 ||
00880 type_covered == LDNS_RR_TYPE_NSEC3) {
00881 cur_node = ldns_dnssec_zone_find_nsec3_original(zone,
00882 rr);
00883 if (!cur_node) {
00884 return LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND;
00885 }
00886 } else {
00887 cur_node = ldns_rbtree_search(zone->names, ldns_rr_owner(rr));
00888 }
00889
00890 if (!cur_node) {
00891
00892 cur_name = ldns_dnssec_name_new_frm_rr(rr);
00893 if(!cur_name) return LDNS_STATUS_MEM_ERR;
00894 cur_node = LDNS_MALLOC(ldns_rbnode_t);
00895 if(!cur_node) {
00896 ldns_dnssec_name_free(cur_name);
00897 return LDNS_STATUS_MEM_ERR;
00898 }
00899 cur_node->key = ldns_rr_owner(rr);
00900 cur_node->data = cur_name;
00901 (void)ldns_rbtree_insert(zone->names, cur_node);
00902 } else {
00903 cur_name = (ldns_dnssec_name *) cur_node->data;
00904 result = ldns_dnssec_name_add_rr(cur_name, rr);
00905 }
00906
00907 if (result != LDNS_STATUS_OK) {
00908 fprintf(stderr, "error adding rr: ");
00909 ldns_rr_print(stderr, rr);
00910 }
00911
00912
00913 if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) {
00914 zone->soa = cur_name;
00915 }
00916
00917 return result;
00918 }
00919
00920 void
00921 ldns_dnssec_zone_names_print_fmt(FILE *out, const ldns_output_format *fmt,
00922 ldns_rbtree_t *tree,
00923 bool print_soa)
00924 {
00925 ldns_rbnode_t *node;
00926 ldns_dnssec_name *name;
00927
00928 node = ldns_rbtree_first(tree);
00929 while (node != LDNS_RBTREE_NULL) {
00930 name = (ldns_dnssec_name *) node->data;
00931 ldns_dnssec_name_print_soa_fmt(out, fmt, name, print_soa);
00932 if ((fmt->flags & LDNS_COMMENT_LAYOUT))
00933 fprintf(out, ";\n");
00934 node = ldns_rbtree_next(node);
00935 }
00936 }
00937
00938 void
00939 ldns_dnssec_zone_names_print(FILE *out, ldns_rbtree_t *tree, bool print_soa)
00940 {
00941 ldns_dnssec_zone_names_print_fmt(out, ldns_output_format_default,
00942 tree, print_soa);
00943 }
00944
00945 void
00946 ldns_dnssec_zone_print_fmt(FILE *out, const ldns_output_format *fmt,
00947 ldns_dnssec_zone *zone)
00948 {
00949 if (zone) {
00950 if (zone->soa) {
00951 if ((fmt->flags & LDNS_COMMENT_LAYOUT)) {
00952 fprintf(out, ";; Zone: ");
00953 ldns_rdf_print(out, ldns_dnssec_name_name(
00954 zone->soa));
00955 fprintf(out, "\n;\n");
00956 }
00957 ldns_dnssec_rrsets_print_fmt(out, fmt,
00958 ldns_dnssec_name_find_rrset(
00959 zone->soa,
00960 LDNS_RR_TYPE_SOA),
00961 false);
00962 if ((fmt->flags & LDNS_COMMENT_LAYOUT))
00963 fprintf(out, ";\n");
00964 }
00965
00966 if (zone->names) {
00967 ldns_dnssec_zone_names_print_fmt(out, fmt,
00968 zone->names, false);
00969 }
00970 }
00971 }
00972
00973 void
00974 ldns_dnssec_zone_print(FILE *out, ldns_dnssec_zone *zone)
00975 {
00976 ldns_dnssec_zone_print_fmt(out, ldns_output_format_default, zone);
00977 }
00978
00979 ldns_status
00980 ldns_dnssec_zone_add_empty_nonterminals(ldns_dnssec_zone *zone)
00981 {
00982 ldns_dnssec_name *new_name;
00983 ldns_rdf *cur_name;
00984 ldns_rdf *next_name;
00985 ldns_rbnode_t *cur_node, *next_node, *new_node;
00986
00987
00988 uint16_t i, cur_label_count, next_label_count;
00989 uint16_t soa_label_count = 0;
00990 ldns_rdf *l1, *l2;
00991 int lpos;
00992
00993 if (!zone) {
00994 return LDNS_STATUS_ERR;
00995 }
00996 if (zone->soa && zone->soa->name) {
00997 soa_label_count = ldns_dname_label_count(zone->soa->name);
00998 }
00999
01000 cur_node = ldns_rbtree_first(zone->names);
01001 while (cur_node != LDNS_RBTREE_NULL) {
01002 next_node = ldns_rbtree_next(cur_node);
01003
01004
01005 while (next_node != LDNS_RBTREE_NULL &&
01006 next_node->data &&
01007 ((ldns_dnssec_name *)next_node->data)->is_glue
01008 ) {
01009 next_node = ldns_rbtree_next(next_node);
01010 }
01011
01012 if (next_node == LDNS_RBTREE_NULL) {
01013 next_node = ldns_rbtree_first(zone->names);
01014 }
01015 if (! cur_node->data || ! next_node->data) {
01016 return LDNS_STATUS_ERR;
01017 }
01018 cur_name = ((ldns_dnssec_name *)cur_node->data)->name;
01019 next_name = ((ldns_dnssec_name *)next_node->data)->name;
01020 cur_label_count = ldns_dname_label_count(cur_name);
01021 next_label_count = ldns_dname_label_count(next_name);
01022
01023
01024
01025
01026
01027
01028
01029
01030 for (i = 1; i < next_label_count - soa_label_count; i++) {
01031 lpos = (int)cur_label_count - (int)next_label_count + (int)i;
01032 if (lpos >= 0) {
01033 l1 = ldns_dname_clone_from(cur_name, (uint8_t)lpos);
01034 } else {
01035 l1 = NULL;
01036 }
01037 l2 = ldns_dname_clone_from(next_name, i);
01038
01039 if (!l1 || ldns_dname_compare(l1, l2) != 0) {
01040
01041
01042
01043 new_name = ldns_dnssec_name_new();
01044 if (!new_name) {
01045 return LDNS_STATUS_MEM_ERR;
01046 }
01047 new_name->name = ldns_dname_clone_from(next_name,
01048 i);
01049 if (!new_name->name) {
01050 ldns_dnssec_name_free(new_name);
01051 return LDNS_STATUS_MEM_ERR;
01052 }
01053 new_name->name_alloced = true;
01054 new_node = LDNS_MALLOC(ldns_rbnode_t);
01055 if (!new_node) {
01056 ldns_dnssec_name_free(new_name);
01057 return LDNS_STATUS_MEM_ERR;
01058 }
01059 new_node->key = new_name->name;
01060 new_node->data = new_name;
01061 (void)ldns_rbtree_insert(zone->names, new_node);
01062 }
01063 ldns_rdf_deep_free(l1);
01064 ldns_rdf_deep_free(l2);
01065 }
01066
01067
01068
01069
01070 if (next_node != ldns_rbtree_first(zone->names)) {
01071 cur_node = next_node;
01072 } else {
01073 cur_node = LDNS_RBTREE_NULL;
01074 }
01075 }
01076 return LDNS_STATUS_OK;
01077 }
01078
01079 bool
01080 ldns_dnssec_zone_is_nsec3_optout(ldns_dnssec_zone* zone)
01081 {
01082 ldns_rr* nsec3;
01083 ldns_rbnode_t* node;
01084
01085 if (ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_NSEC3PARAM)) {
01086 node = ldns_rbtree_first(zone->names);
01087 while (node != LDNS_RBTREE_NULL) {
01088 nsec3 = ((ldns_dnssec_name*)node->data)->nsec;
01089 if (nsec3 &&ldns_rr_get_type(nsec3)
01090 == LDNS_RR_TYPE_NSEC3 &&
01091 ldns_nsec3_optout(nsec3)) {
01092 return true;
01093 }
01094 node = ldns_rbtree_next(node);
01095 }
01096 }
01097 return false;
01098 }