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 new_rrs->rr = NULL;
00015 new_rrs->next = NULL;
00016 return new_rrs;
00017 }
00018
00019 void
00020 ldns_dnssec_rrs_free(ldns_dnssec_rrs *rrs)
00021 {
00022 if (rrs) {
00023 if (rrs->next) {
00024 ldns_dnssec_rrs_free(rrs->next);
00025 }
00026 LDNS_FREE(rrs);
00027 }
00028 }
00029
00030 ldns_status
00031 ldns_dnssec_rrs_add_rr(ldns_dnssec_rrs *rrs, ldns_rr *rr)
00032 {
00033 int cmp;
00034 ldns_dnssec_rrs *new_rrs;
00035 if (!rrs || !rr) {
00036 return LDNS_STATUS_ERR;
00037 }
00038
00039
00040
00041 cmp = ldns_rr_compare(rrs->rr,
00042 rr);
00043
00044 if (cmp <= 0) {
00045 if (rrs->next) {
00046 ldns_dnssec_rrs_add_rr(rrs->next, rr);
00047 } else {
00048 new_rrs = ldns_dnssec_rrs_new();
00049 new_rrs->rr = rr;
00050 rrs->next = new_rrs;
00051 }
00052 } else if (cmp > 0) {
00053
00054
00055 new_rrs = ldns_dnssec_rrs_new();
00056 new_rrs->rr = rrs->rr;
00057 new_rrs->next = rrs->next;
00058 rrs->rr = rr;
00059 rrs->next = new_rrs;
00060 }
00061 return LDNS_STATUS_OK;
00062 }
00063
00064 void
00065 ldns_dnssec_rrs_print(FILE *out, ldns_dnssec_rrs *rrs)
00066 {
00067 if (!rrs) {
00068 fprintf(out, "<void>");
00069 } else {
00070 if (rrs->rr) {
00071 ldns_rr_print(out, rrs->rr);
00072 }
00073 if (rrs->next) {
00074 ldns_dnssec_rrs_print(out, rrs->next);
00075 }
00076 }
00077 }
00078
00079 ldns_dnssec_rrsets *
00080 ldns_dnssec_rrsets_new()
00081 {
00082 ldns_dnssec_rrsets *new_rrsets;
00083 new_rrsets = LDNS_MALLOC(ldns_dnssec_rrsets);
00084 new_rrsets->rrs = NULL;
00085 new_rrsets->type = 0;
00086 new_rrsets->signatures = NULL;
00087 new_rrsets->next = NULL;
00088 return new_rrsets;
00089 }
00090
00091 void
00092 ldns_dnssec_rrsets_free(ldns_dnssec_rrsets *rrsets)
00093 {
00094 if (rrsets) {
00095 if (rrsets->rrs) {
00096 ldns_dnssec_rrs_free(rrsets->rrs);
00097 }
00098 if (rrsets->next) {
00099 ldns_dnssec_rrsets_free(rrsets->next);
00100 }
00101 if (rrsets->signatures) {
00102 ldns_dnssec_rrs_free(rrsets->signatures);
00103 }
00104 LDNS_FREE(rrsets);
00105 }
00106 }
00107
00108 ldns_rr_type
00109 ldns_dnssec_rrsets_type(ldns_dnssec_rrsets *rrsets)
00110 {
00111 if (rrsets) {
00112 return rrsets->type;
00113 } else {
00114 return 0;
00115 }
00116 }
00117
00118 ldns_status
00119 ldns_dnssec_rrsets_set_type(ldns_dnssec_rrsets *rrsets,
00120 ldns_rr_type type)
00121 {
00122 if (rrsets) {
00123 rrsets->type = type;
00124 return LDNS_STATUS_OK;
00125 }
00126 return LDNS_STATUS_ERR;
00127 }
00128
00129
00130 ldns_status
00131 ldns_dnssec_rrsets_add_rr(ldns_dnssec_rrsets *rrsets, ldns_rr *rr)
00132 {
00133 ldns_dnssec_rrsets *new_rrsets;
00134 ldns_rr_type rr_type;
00135 bool rrsig = false;
00136 ldns_status result = LDNS_STATUS_OK;
00137
00138 if (!rrsets || !rr) {
00139 return LDNS_STATUS_ERR;
00140 }
00141
00142 rr_type = ldns_rr_get_type(rr);
00143
00144 if (rr_type == LDNS_RR_TYPE_RRSIG) {
00145 rrsig = true;
00146 rr_type = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr));
00147 }
00148
00149 if (!rrsets->rrs && rrsets->type == 0) {
00150 rrsets->rrs = ldns_dnssec_rrs_new();
00151 rrsets->rrs->rr = rr;
00152 rrsets->type = ldns_rr_get_type(rr);
00153 return LDNS_STATUS_OK;
00154 }
00155
00156 if (rr_type > ldns_dnssec_rrsets_type(rrsets)) {
00157 if (rrsets->next) {
00158 result = ldns_dnssec_rrsets_add_rr(rrsets->next, rr);
00159 } else {
00160 new_rrsets = ldns_dnssec_rrsets_new();
00161 new_rrsets->rrs = ldns_dnssec_rrs_new();
00162 new_rrsets->rrs->rr = rr;
00163 new_rrsets->type = ldns_rr_get_type(rr);
00164 rrsets->next = new_rrsets;
00165 }
00166 } else if (rr_type < ldns_dnssec_rrsets_type(rrsets)) {
00167
00168
00169 new_rrsets = ldns_dnssec_rrsets_new();
00170 new_rrsets->rrs = rrsets->rrs;
00171 new_rrsets->type = rrsets->type;
00172 new_rrsets->signatures = rrsets->signatures;
00173 new_rrsets->next = rrsets->next;
00174 rrsets->rrs = ldns_dnssec_rrs_new();
00175 rrsets->rrs->rr = rr;
00176 rrsets->signatures = NULL;
00177 rrsets->type = ldns_rr_get_type(rr);
00178 rrsets->next = new_rrsets;
00179 } else {
00180
00181 if (rrsig) {
00182 if (rrsets->signatures) {
00183 result = ldns_dnssec_rrs_add_rr(rrsets->signatures, rr);
00184 } else {
00185 rrsets->signatures = ldns_dnssec_rrs_new();
00186 rrsets->signatures->rr = rr;
00187 }
00188 } else {
00189 result = ldns_dnssec_rrs_add_rr(rrsets->rrs, rr);
00190 }
00191 }
00192
00193 return result;
00194 }
00195
00196 void
00197 ldns_dnssec_rrsets_print_soa(FILE *out,
00198 ldns_dnssec_rrsets *rrsets,
00199 bool follow,
00200 bool show_soa)
00201 {
00202 if (!rrsets) {
00203 fprintf(out, "<void>\n");
00204 } else {
00205 if (rrsets->rrs &&
00206 (show_soa ||
00207 ldns_rr_get_type(rrsets->rrs->rr) != LDNS_RR_TYPE_SOA
00208 )
00209 ) {
00210 ldns_dnssec_rrs_print(out, rrsets->rrs);
00211 if (rrsets->signatures) {
00212 ldns_dnssec_rrs_print(out, rrsets->signatures);
00213 }
00214 }
00215 if (follow && rrsets->next) {
00216 ldns_dnssec_rrsets_print_soa(out, rrsets->next, follow, show_soa);
00217 }
00218 }
00219 }
00220
00221 void
00222 ldns_dnssec_rrsets_print(FILE *out, ldns_dnssec_rrsets *rrsets, bool follow)
00223 {
00224 ldns_dnssec_rrsets_print_soa(out, rrsets, follow, true);
00225 }
00226
00227 ldns_dnssec_name *
00228 ldns_dnssec_name_new()
00229 {
00230 ldns_dnssec_name *new_name;
00231
00232 new_name = LDNS_MALLOC(ldns_dnssec_name);
00233 if (!new_name) {
00234 return NULL;
00235 }
00236
00237 new_name->rrsets = NULL;
00238 new_name->name_alloced = false;
00239 new_name->nsec = NULL;
00240 new_name->nsec_signatures = NULL;
00241
00242 return new_name;
00243 }
00244
00245 ldns_dnssec_name *
00246 ldns_dnssec_name_new_frm_rr(ldns_rr *rr)
00247 {
00248 ldns_dnssec_name *new_name = ldns_dnssec_name_new();
00249
00250 new_name->name = ldns_rr_owner(rr);
00251 ldns_dnssec_name_add_rr(new_name, rr);
00252
00253 return new_name;
00254 }
00255
00256 void
00257 ldns_dnssec_name_free(ldns_dnssec_name *name)
00258 {
00259 if (name) {
00260 if (name->name_alloced) {
00261 ldns_rdf_deep_free(name->name);
00262 }
00263 if (name->rrsets) {
00264 ldns_dnssec_rrsets_free(name->rrsets);
00265 }
00266 if (name->nsec_signatures) {
00267 ldns_dnssec_rrs_free(name->nsec_signatures);
00268 }
00269 LDNS_FREE(name);
00270 }
00271 }
00272
00273 ldns_rdf *
00274 ldns_dnssec_name_name(ldns_dnssec_name *name)
00275 {
00276 if (name) {
00277 return name->name;
00278 }
00279 return NULL;
00280 }
00281
00282 void
00283 ldns_dnssec_name_set_name(ldns_dnssec_name *rrset,
00284 ldns_rdf *dname)
00285 {
00286 if (rrset && dname) {
00287 rrset->name = dname;
00288 }
00289 }
00290
00291 ldns_rr *
00292 ldns_dnssec_name_nsec(ldns_dnssec_name *rrset)
00293 {
00294 if (rrset) {
00295 return rrset->nsec;
00296 }
00297 return NULL;
00298 }
00299
00300 void
00301 ldns_dnssec_name_set_nsec(ldns_dnssec_name *rrset, ldns_rr *nsec)
00302 {
00303 if (rrset && nsec) {
00304 rrset->nsec = nsec;
00305 }
00306 }
00307
00308 int
00309 ldns_dnssec_name_cmp(const void *a, const void *b)
00310 {
00311 ldns_dnssec_name *na = (ldns_dnssec_name *) a;
00312 ldns_dnssec_name *nb = (ldns_dnssec_name *) b;
00313
00314 if (na && nb) {
00315 return ldns_dname_compare(ldns_dnssec_name_name(na),
00316 ldns_dnssec_name_name(nb));
00317 } else if (na) {
00318 return 1;
00319 } else if (nb) {
00320 return -1;
00321 } else {
00322 return 0;
00323 }
00324 }
00325
00326
00327 ldns_status
00328 ldns_dnssec_name_add_rr(ldns_dnssec_name *name,
00329 ldns_rr *rr)
00330 {
00331 ldns_status result = LDNS_STATUS_OK;
00332 ldns_rdf *name_name;
00333 bool hashed_name = false;
00334 ldns_rr_type rr_type = ldns_rr_get_type(rr);
00335 ldns_rr_type typecovered = 0;
00336 name = name;
00337 rr = rr;
00338
00339
00340
00341 if (!name || !rr) {
00342 return LDNS_STATUS_ERR;
00343 }
00344
00345 rr_type = ldns_rr_get_type(rr);
00346
00347 if (rr_type == LDNS_RR_TYPE_RRSIG) {
00348 typecovered = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr));
00349 }
00350
00351 if (rr_type == LDNS_RR_TYPE_NSEC3 ||
00352 typecovered == LDNS_RR_TYPE_NSEC3) {
00353 name_name = ldns_nsec3_hash_name_frm_nsec3(rr,
00354 ldns_dnssec_name_name(name));
00355 hashed_name = true;
00356 } else {
00357 name_name = ldns_dnssec_name_name(name);
00358 }
00359
00360 if (rr_type == LDNS_RR_TYPE_NSEC ||
00361 rr_type == LDNS_RR_TYPE_NSEC3) {
00362
00363 name->nsec = rr;
00364 } else if (typecovered == LDNS_RR_TYPE_NSEC ||
00365 typecovered == LDNS_RR_TYPE_NSEC3) {
00366 if (name->nsec_signatures) {
00367 ldns_dnssec_rrs_add_rr(name->nsec_signatures, rr);
00368 } else {
00369 name->nsec_signatures = ldns_dnssec_rrs_new();
00370 name->nsec_signatures->rr = rr;
00371 }
00372 } else {
00373
00374 if (name->rrsets) {
00375 result = ldns_dnssec_rrsets_add_rr(name->rrsets, rr);
00376 } else {
00377 name->rrsets = ldns_dnssec_rrsets_new();
00378 result = ldns_dnssec_rrsets_add_rr(name->rrsets, rr);
00379 }
00380 }
00381
00382 if (hashed_name) {
00383 ldns_rdf_deep_free(name_name);
00384 }
00385
00386 return result;
00387 }
00388
00389 ldns_dnssec_rrsets *
00390 ldns_dnssec_name_find_rrset(ldns_dnssec_name *name,
00391 ldns_rr_type type) {
00392 ldns_dnssec_rrsets *result;
00393
00394 result = name->rrsets;
00395 while (result) {
00396 if (result->type == type) {
00397 return result;
00398 } else {
00399 result = result->next;
00400 }
00401 }
00402 return NULL;
00403 }
00404
00405 ldns_dnssec_rrsets *
00406 ldns_dnssec_zone_find_rrset(ldns_dnssec_zone *zone,
00407 ldns_rdf *dname,
00408 ldns_rr_type type)
00409 {
00410 ldns_rbnode_t *node;
00411
00412 if (!zone || !dname) {
00413 return NULL;
00414 }
00415
00416 node = ldns_rbtree_search(zone->names, dname);
00417 if (node) {
00418 return ldns_dnssec_name_find_rrset((ldns_dnssec_name *)node->data,
00419 type);
00420 } else {
00421 return NULL;
00422 }
00423 }
00424
00425 static inline void
00426 print_indent(FILE *out, int c)
00427 {
00428 int i;
00429 for (i=0; i<c; i++) {
00430 fprintf(out, " ");
00431 }
00432 }
00433
00434 void
00435 ldns_dnssec_name_print_soa(FILE *out, ldns_dnssec_name *name, bool show_soa)
00436 {
00437 if (name) {
00438 if(name->rrsets) {
00439 ldns_dnssec_rrsets_print_soa(out, name->rrsets, true, show_soa);
00440 } else {
00441 fprintf(out, ";; Empty nonterminal: ");
00442 ldns_rdf_print(out, name->name);
00443 fprintf(out, "\n");
00444 }
00445 if(name->nsec) {
00446 ldns_rr_print(out, name->nsec);
00447 }
00448 if (name->nsec_signatures) {
00449 ldns_dnssec_rrs_print(out, name->nsec_signatures);
00450 }
00451 } else {
00452 fprintf(out, "<void>\n");
00453 }
00454 }
00455
00456 void
00457 ldns_dnssec_name_print(FILE *out, ldns_dnssec_name *name)
00458 {
00459 ldns_dnssec_name_print_soa(out, name, true);
00460 }
00461
00462 ldns_dnssec_zone *
00463 ldns_dnssec_zone_new()
00464 {
00465 ldns_dnssec_zone *zone = LDNS_MALLOC(ldns_dnssec_zone);
00466 zone->soa = NULL;
00467 zone->names = NULL;
00468
00469 return zone;
00470 }
00471
00472 void
00473 ldns_dnssec_name_node_free(ldns_rbnode_t *node, void *arg) {
00474 arg = arg;
00475 ldns_dnssec_name_free((ldns_dnssec_name *)node->data);
00476 free(node);
00477 }
00478
00479 void
00480 ldns_dnssec_zone_free(ldns_dnssec_zone *zone)
00481 {
00482 if (zone) {
00483 if (zone->names) {
00484
00485 ldns_traverse_postorder(zone->names,
00486 ldns_dnssec_name_node_free,
00487 NULL);
00488 free(zone->names);
00489 }
00490 LDNS_FREE(zone);
00491 }
00492 }
00493
00494
00495 int
00496 ldns_dname_compare_v(const void *a, const void *b) {
00497 return ldns_dname_compare((ldns_rdf *)a, (ldns_rdf *)b);
00498 }
00499
00500 ldns_status
00501 ldns_dnssec_zone_add_rr(ldns_dnssec_zone *zone, ldns_rr *rr)
00502 {
00503 ldns_status result = LDNS_STATUS_OK;
00504 ldns_dnssec_name *cur_name;
00505 ldns_rbnode_t *cur_node;
00506
00507 if (!zone || !rr) {
00508 return LDNS_STATUS_ERR;
00509 }
00510
00511 if (!zone->names) {
00512 zone->names = ldns_rbtree_create(ldns_dname_compare_v);
00513 }
00514
00515 cur_node = ldns_rbtree_search(zone->names, ldns_rr_owner(rr));
00516
00517 if (!cur_node) {
00518
00519 cur_name = ldns_dnssec_name_new_frm_rr(rr);
00520 cur_node = LDNS_MALLOC(ldns_rbnode_t);
00521 cur_node->key = ldns_rr_owner(rr);
00522 cur_node->data = cur_name;
00523 ldns_rbtree_insert(zone->names, cur_node);
00524 } else {
00525 cur_name = (ldns_dnssec_name *) cur_node->data;
00526 ldns_dnssec_name_add_rr(cur_name, rr);
00527 }
00528
00529 if (result != LDNS_STATUS_OK) {
00530 fprintf(stderr, "error adding rr: ");
00531 ldns_rr_print(stderr, rr);
00532 }
00533
00534
00535 if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) {
00536 zone->soa = cur_name;
00537 }
00538
00539 return result;
00540 }
00541
00542 void
00543 ldns_dnssec_zone_names_print(FILE *out, ldns_rbtree_t *tree, bool print_soa)
00544 {
00545 ldns_rbnode_t *node;
00546 ldns_dnssec_name *name;
00547
00548 node = ldns_rbtree_first(tree);
00549 while (node != LDNS_RBTREE_NULL) {
00550 name = (ldns_dnssec_name *) node->data;
00551 ldns_dnssec_name_print_soa(out, name, print_soa);
00552 fprintf(out, ";\n");
00553 node = ldns_rbtree_next(node);
00554 }
00555 }
00556
00557 void
00558 ldns_dnssec_zone_print(FILE *out, ldns_dnssec_zone *zone)
00559 {
00560 if (zone) {
00561 if (zone->soa) {
00562 fprintf(out, ";; Zone: ");
00563 ldns_rdf_print(out, ldns_dnssec_name_name(zone->soa));
00564 fprintf(out, "\n;\n");
00565 ldns_dnssec_rrsets_print(out,
00566 ldns_dnssec_name_find_rrset(zone->soa,
00567 LDNS_RR_TYPE_SOA),
00568 false);
00569 fprintf(out, ";\n");
00570 }
00571
00572 if (zone->names) {
00573 ldns_dnssec_zone_names_print(out, zone->names, false);
00574 }
00575 }
00576 }
00577
00578 ldns_status
00579 ldns_dnssec_zone_add_empty_nonterminals(ldns_dnssec_zone *zone)
00580 {
00581 ldns_dnssec_name *new_name;
00582 ldns_dnssec_name *cur_name;
00583 ldns_dnssec_name *next_name;
00584 ldns_rbnode_t *cur_node, *next_node, *new_node;
00585
00586
00587 uint16_t j, cur_label_count, next_label_count;
00588 ldns_rdf *l1, *l2, *post, *post2;
00589 bool found_difference = false;
00590
00591 if (!zone) {
00592 return LDNS_STATUS_ERR;
00593 }
00594 cur_node = ldns_rbtree_first(zone->names);
00595 while (cur_node != LDNS_RBTREE_NULL) {
00596 next_node = ldns_rbtree_next(cur_node);
00597 if (next_node == LDNS_RBTREE_NULL) {
00598 next_node = ldns_rbtree_first(zone->names);
00599 }
00600
00601 cur_name = (ldns_dnssec_name *)cur_node->data;
00602 next_name = (ldns_dnssec_name *)next_node->data;
00603
00604 found_difference = false;
00605
00606 cur_label_count = ldns_dname_label_count(cur_name->name);
00607 next_label_count = ldns_dname_label_count(next_name->name);
00608
00609 post = ldns_dname_new_frm_str(".");
00610 for (j = 1 + ldns_dname_label_count(zone->soa->name);
00611 j < cur_label_count &&
00612 j <= next_label_count &&
00613 !found_difference;
00614 j++) {
00615 l1 = ldns_dname_label(cur_name->name, cur_label_count - j);
00616 l2 = ldns_dname_label(next_name->name, next_label_count - j);
00617 post2 = ldns_dname_cat_clone(l2, post);
00618 ldns_rdf_deep_free(post);
00619 post = post2;
00620
00621 if (ldns_dname_compare(l1, l2) != 0 &&
00622 j < next_label_count) {
00623 found_difference = true;
00624
00625 new_name = ldns_dnssec_name_new();
00626 new_name->name = ldns_rdf_clone(post);
00627 new_name->name_alloced = true;
00628 new_node = LDNS_MALLOC(ldns_rbnode_t);
00629 new_node->key = new_name->name;
00630 new_node->data = new_name;
00631 ldns_rbtree_insert(zone->names, new_node);
00632
00633 }
00634 ldns_rdf_deep_free(l1);
00635 ldns_rdf_deep_free(l2);
00636 }
00637
00638
00639 if (!found_difference && j < cur_label_count && j <= next_label_count) {
00640 l2 = ldns_dname_label(next_name->name, next_label_count - j);
00641 post2 = ldns_dname_cat_clone(l2, post);
00642 ldns_rdf_deep_free(post);
00643 post = post2;
00644 j++;
00645 }
00646 while (j < next_label_count) {
00647 l2 = ldns_dname_label(next_name->name, next_label_count - j);
00648 post2 = ldns_dname_cat_clone(l2, post);
00649 ldns_rdf_deep_free(post);
00650 post = post2;
00651
00652
00653
00654
00655
00656 ldns_rdf_deep_free(l2);
00657 j++;
00658 new_name = ldns_dnssec_name_new();
00659 new_name->name = ldns_rdf_clone(post);
00660 new_name->name_alloced = true;
00661 new_node = LDNS_MALLOC(ldns_rbnode_t);
00662 new_node->key = new_name->name;
00663 new_node->data = new_name;
00664 ldns_rbtree_insert(zone->names, new_node);
00665 }
00666 ldns_rdf_deep_free(post);
00667
00668
00669
00670 cur_node = ldns_rbtree_next(cur_node);
00671 }
00672 return LDNS_STATUS_OK;
00673 }