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 break;
00712
00713 case LDNS_STATUS_SYNTAX_INCLUDE:
00714 status = LDNS_STATUS_SYNTAX_INCLUDE_ERR_NOTIMPL;
00715 break;
00716
00717 default:
00718 goto error;
00719 }
00720 }
00721
00722 if (ldns_rr_list_rr_count(todo_nsec3s) > 0) {
00723 (void) ldns_dnssec_zone_add_empty_nonterminals(newzone);
00724 for (i = 0; i < ldns_rr_list_rr_count(todo_nsec3s); i++) {
00725 cur_rr = ldns_rr_list_rr(todo_nsec3s, i);
00726 status = ldns_dnssec_zone_add_rr(newzone, cur_rr);
00727 }
00728 for (i = 0; i < ldns_rr_list_rr_count(todo_nsec3_rrsigs); i++){
00729 cur_rr = ldns_rr_list_rr(todo_nsec3_rrsigs, i);
00730 status = ldns_dnssec_zone_add_rr(newzone, cur_rr);
00731 }
00732 } else if (ldns_rr_list_rr_count(todo_nsec3_rrsigs) > 0) {
00733 for (i = 0; i < ldns_rr_list_rr_count(todo_nsec3_rrsigs); i++){
00734 cur_rr = ldns_rr_list_rr(todo_nsec3_rrsigs, i);
00735 status = ldns_dnssec_zone_add_rr(newzone, cur_rr);
00736 }
00737 }
00738
00739 ldns_rr_list_free(todo_nsec3_rrsigs);
00740 ldns_rr_list_free(todo_nsec3s);
00741
00742 if (z) {
00743 *z = newzone;
00744 } else {
00745 ldns_dnssec_zone_free(newzone);
00746 }
00747
00748 return LDNS_STATUS_OK;
00749
00750 error:
00751 #ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP
00752 if (zone) {
00753 ldns_zone_free(zone);
00754 }
00755 #endif
00756 if (my_origin) {
00757 ldns_rdf_deep_free(my_origin);
00758 }
00759 if (my_prev) {
00760 ldns_rdf_deep_free(my_prev);
00761 }
00762 if (newzone) {
00763 ldns_dnssec_zone_free(newzone);
00764 }
00765 return status;
00766 }
00767
00768 ldns_status
00769 ldns_dnssec_zone_new_frm_fp(ldns_dnssec_zone** z, FILE* fp, ldns_rdf* origin,
00770 uint32_t ttl, ldns_rr_class ATTR_UNUSED(c))
00771 {
00772 return ldns_dnssec_zone_new_frm_fp_l(z, fp, origin, ttl, c, NULL);
00773 }
00774
00775 void
00776 ldns_dnssec_name_node_free(ldns_rbnode_t *node, void *arg) {
00777 (void) arg;
00778 ldns_dnssec_name_free((ldns_dnssec_name *)node->data);
00779 LDNS_FREE(node);
00780 }
00781
00782 void
00783 ldns_dnssec_name_node_deep_free(ldns_rbnode_t *node, void *arg) {
00784 (void) arg;
00785 ldns_dnssec_name_deep_free((ldns_dnssec_name *)node->data);
00786 LDNS_FREE(node);
00787 }
00788
00789 void
00790 ldns_dnssec_zone_free(ldns_dnssec_zone *zone)
00791 {
00792 if (zone) {
00793 if (zone->names) {
00794
00795 ldns_traverse_postorder(zone->names,
00796 ldns_dnssec_name_node_free,
00797 NULL);
00798 LDNS_FREE(zone->names);
00799 }
00800 LDNS_FREE(zone);
00801 }
00802 }
00803
00804 void
00805 ldns_dnssec_zone_deep_free(ldns_dnssec_zone *zone)
00806 {
00807 if (zone) {
00808 if (zone->names) {
00809
00810 ldns_traverse_postorder(zone->names,
00811 ldns_dnssec_name_node_deep_free,
00812 NULL);
00813 LDNS_FREE(zone->names);
00814 }
00815 LDNS_FREE(zone);
00816 }
00817 }
00818
00819
00820 int
00821 ldns_dname_compare_v(const void *a, const void *b) {
00822 return ldns_dname_compare((ldns_rdf *)a, (ldns_rdf *)b);
00823 }
00824
00825 #ifdef HAVE_SSL
00826 ldns_rbnode_t *
00827 ldns_dnssec_zone_find_nsec3_original(ldns_dnssec_zone *zone,
00828 ldns_rr *rr) {
00829 ldns_rbnode_t *current_node = ldns_rbtree_first(zone->names);
00830 ldns_dnssec_name *current_name;
00831 ldns_rdf *hashed_name;
00832
00833 hashed_name = ldns_dname_label(ldns_rr_owner(rr), 0);
00834
00835 while (current_node != LDNS_RBTREE_NULL) {
00836 current_name = (ldns_dnssec_name *) current_node->data;
00837 if (!current_name->hashed_name) {
00838 current_name->hashed_name =
00839 ldns_nsec3_hash_name_frm_nsec3(rr, current_name->name);
00840 }
00841 if (ldns_dname_compare(hashed_name,
00842 current_name->hashed_name)
00843 == 0) {
00844 ldns_rdf_deep_free(hashed_name);
00845 return current_node;
00846 }
00847 current_node = ldns_rbtree_next(current_node);
00848 }
00849 ldns_rdf_deep_free(hashed_name);
00850 return NULL;
00851 }
00852
00853 ldns_status
00854 ldns_dnssec_zone_add_rr(ldns_dnssec_zone *zone, ldns_rr *rr)
00855 {
00856 ldns_status result = LDNS_STATUS_OK;
00857 ldns_dnssec_name *cur_name;
00858 ldns_rbnode_t *cur_node;
00859 ldns_rr_type type_covered = 0;
00860
00861 if (!zone || !rr) {
00862 return LDNS_STATUS_ERR;
00863 }
00864
00865 if (!zone->names) {
00866 zone->names = ldns_rbtree_create(ldns_dname_compare_v);
00867 if(!zone->names) return LDNS_STATUS_MEM_ERR;
00868 }
00869
00870
00871
00872 if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG) {
00873 type_covered = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr));
00874 }
00875 if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_NSEC3 ||
00876 type_covered == LDNS_RR_TYPE_NSEC3) {
00877 cur_node = ldns_dnssec_zone_find_nsec3_original(zone,
00878 rr);
00879 if (!cur_node) {
00880 return LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND;
00881 }
00882 } else {
00883 cur_node = ldns_rbtree_search(zone->names, ldns_rr_owner(rr));
00884 }
00885
00886 if (!cur_node) {
00887
00888 cur_name = ldns_dnssec_name_new_frm_rr(rr);
00889 if(!cur_name) return LDNS_STATUS_MEM_ERR;
00890 cur_node = LDNS_MALLOC(ldns_rbnode_t);
00891 if(!cur_node) {
00892 ldns_dnssec_name_free(cur_name);
00893 return LDNS_STATUS_MEM_ERR;
00894 }
00895 cur_node->key = ldns_rr_owner(rr);
00896 cur_node->data = cur_name;
00897 (void)ldns_rbtree_insert(zone->names, cur_node);
00898 } else {
00899 cur_name = (ldns_dnssec_name *) cur_node->data;
00900 result = ldns_dnssec_name_add_rr(cur_name, rr);
00901 }
00902
00903 if (result != LDNS_STATUS_OK) {
00904 fprintf(stderr, "error adding rr: ");
00905 ldns_rr_print(stderr, rr);
00906 }
00907
00908
00909 if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) {
00910 zone->soa = cur_name;
00911 }
00912
00913 return result;
00914 }
00915 #endif
00916
00917 void
00918 ldns_dnssec_zone_names_print_fmt(FILE *out, const ldns_output_format *fmt,
00919 ldns_rbtree_t *tree,
00920 bool print_soa)
00921 {
00922 ldns_rbnode_t *node;
00923 ldns_dnssec_name *name;
00924
00925 node = ldns_rbtree_first(tree);
00926 while (node != LDNS_RBTREE_NULL) {
00927 name = (ldns_dnssec_name *) node->data;
00928 ldns_dnssec_name_print_soa_fmt(out, fmt, name, print_soa);
00929 if ((fmt->flags & LDNS_COMMENT_LAYOUT))
00930 fprintf(out, ";\n");
00931 node = ldns_rbtree_next(node);
00932 }
00933 }
00934
00935 void
00936 ldns_dnssec_zone_names_print(FILE *out, ldns_rbtree_t *tree, bool print_soa)
00937 {
00938 ldns_dnssec_zone_names_print_fmt(out, ldns_output_format_default,
00939 tree, print_soa);
00940 }
00941
00942 void
00943 ldns_dnssec_zone_print_fmt(FILE *out, const ldns_output_format *fmt,
00944 ldns_dnssec_zone *zone)
00945 {
00946 if (zone) {
00947 if (zone->soa) {
00948 if ((fmt->flags & LDNS_COMMENT_LAYOUT)) {
00949 fprintf(out, ";; Zone: ");
00950 ldns_rdf_print(out, ldns_dnssec_name_name(
00951 zone->soa));
00952 fprintf(out, "\n;\n");
00953 }
00954 ldns_dnssec_rrsets_print_fmt(out, fmt,
00955 ldns_dnssec_name_find_rrset(
00956 zone->soa,
00957 LDNS_RR_TYPE_SOA),
00958 false);
00959 if ((fmt->flags & LDNS_COMMENT_LAYOUT))
00960 fprintf(out, ";\n");
00961 }
00962
00963 if (zone->names) {
00964 ldns_dnssec_zone_names_print_fmt(out, fmt,
00965 zone->names, false);
00966 }
00967 }
00968 }
00969
00970 void
00971 ldns_dnssec_zone_print(FILE *out, ldns_dnssec_zone *zone)
00972 {
00973 ldns_dnssec_zone_print_fmt(out, ldns_output_format_default, zone);
00974 }
00975
00976 ldns_status
00977 ldns_dnssec_zone_add_empty_nonterminals(ldns_dnssec_zone *zone)
00978 {
00979 ldns_dnssec_name *new_name;
00980 ldns_rdf *cur_name;
00981 ldns_rdf *next_name;
00982 ldns_rbnode_t *cur_node, *next_node, *new_node;
00983
00984
00985 uint16_t i, cur_label_count, next_label_count;
00986 uint16_t soa_label_count = 0;
00987 ldns_rdf *l1, *l2;
00988 int lpos;
00989
00990 if (!zone) {
00991 return LDNS_STATUS_ERR;
00992 }
00993 if (zone->soa && zone->soa->name) {
00994 soa_label_count = ldns_dname_label_count(zone->soa->name);
00995 }
00996
00997 cur_node = ldns_rbtree_first(zone->names);
00998 while (cur_node != LDNS_RBTREE_NULL) {
00999 next_node = ldns_rbtree_next(cur_node);
01000
01001
01002 while (next_node != LDNS_RBTREE_NULL &&
01003 next_node->data &&
01004 ((ldns_dnssec_name *)next_node->data)->is_glue
01005 ) {
01006 next_node = ldns_rbtree_next(next_node);
01007 }
01008
01009 if (next_node == LDNS_RBTREE_NULL) {
01010 next_node = ldns_rbtree_first(zone->names);
01011 }
01012
01013 cur_name = ((ldns_dnssec_name *)cur_node->data)->name;
01014 next_name = ((ldns_dnssec_name *)next_node->data)->name;
01015 cur_label_count = ldns_dname_label_count(cur_name);
01016 next_label_count = ldns_dname_label_count(next_name);
01017
01018
01019
01020
01021
01022
01023
01024
01025 for (i = 1; i < next_label_count - soa_label_count; i++) {
01026 lpos = (int)cur_label_count - (int)next_label_count + (int)i;
01027 if (lpos >= 0) {
01028 l1 = ldns_dname_clone_from(cur_name, (uint8_t)lpos);
01029 } else {
01030 l1 = NULL;
01031 }
01032 l2 = ldns_dname_clone_from(next_name, i);
01033
01034 if (!l1 || ldns_dname_compare(l1, l2) != 0) {
01035
01036
01037
01038 new_name = ldns_dnssec_name_new();
01039 if (!new_name) {
01040 return LDNS_STATUS_MEM_ERR;
01041 }
01042 new_name->name = ldns_dname_clone_from(next_name,
01043 i);
01044 if (!new_name->name) {
01045 ldns_dnssec_name_free(new_name);
01046 return LDNS_STATUS_MEM_ERR;
01047 }
01048 new_name->name_alloced = true;
01049 new_node = LDNS_MALLOC(ldns_rbnode_t);
01050 if (!new_node) {
01051 ldns_dnssec_name_free(new_name);
01052 return LDNS_STATUS_MEM_ERR;
01053 }
01054 new_node->key = new_name->name;
01055 new_node->data = new_name;
01056 (void)ldns_rbtree_insert(zone->names, new_node);
01057 }
01058 ldns_rdf_deep_free(l1);
01059 ldns_rdf_deep_free(l2);
01060 }
01061
01062
01063
01064
01065 if (next_node != ldns_rbtree_first(zone->names)) {
01066 cur_node = next_node;
01067 } else {
01068 cur_node = LDNS_RBTREE_NULL;
01069 }
01070 }
01071 return LDNS_STATUS_OK;
01072 }
01073
01074 bool
01075 ldns_dnssec_zone_is_nsec3_optout(ldns_dnssec_zone* zone)
01076 {
01077 ldns_rr* nsec3;
01078 ldns_rbnode_t* node;
01079
01080 if (ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_NSEC3PARAM)) {
01081 node = ldns_rbtree_first(zone->names);
01082 while (node != LDNS_RBTREE_NULL) {
01083 nsec3 = ((ldns_dnssec_name*)node->data)->nsec;
01084 if (nsec3 &&ldns_rr_get_type(nsec3)
01085 == LDNS_RR_TYPE_NSEC3 &&
01086 ldns_nsec3_optout(nsec3)) {
01087 return true;
01088 }
01089 node = ldns_rbtree_next(node);
01090 }
01091 }
01092 return false;
01093 }