1 /* 2 * difffile.c - DIFF file handling source code. Read and write diff files. 3 * 4 * Copyright (c) 2001-2006, NLnet Labs. All rights reserved. 5 * 6 * See LICENSE for the license. 7 * 8 */ 9 10 #include "config.h" 11 #include <assert.h> 12 #include <string.h> 13 #include <unistd.h> 14 #include <stdlib.h> 15 #include <errno.h> 16 #include <inttypes.h> 17 #include "difffile.h" 18 #include "xfrd-disk.h" 19 #include "util.h" 20 #include "packet.h" 21 #include "rdata.h" 22 #include "udb.h" 23 #include "nsec3.h" 24 #include "nsd.h" 25 #include "rrl.h" 26 #include "ixfr.h" 27 #include "zonec.h" 28 #include "xfrd-catalog-zones.h" 29 30 static int 31 write_64(FILE *out, uint64_t val) 32 { 33 return write_data(out, &val, sizeof(val)); 34 } 35 36 static int 37 write_32(FILE *out, uint32_t val) 38 { 39 val = htonl(val); 40 return write_data(out, &val, sizeof(val)); 41 } 42 43 static int 44 write_8(FILE *out, uint8_t val) 45 { 46 return write_data(out, &val, sizeof(val)); 47 } 48 49 static int 50 write_str(FILE *out, const char* str) 51 { 52 uint32_t len = strlen(str); 53 if(!write_32(out, len)) 54 return 0; 55 return write_data(out, str, len); 56 } 57 58 void 59 diff_write_packet(const char* zone, const char* pat, uint32_t old_serial, 60 uint32_t new_serial, uint32_t seq_nr, uint8_t* data, size_t len, 61 struct nsd* nsd, uint64_t filenumber) 62 { 63 FILE* df = xfrd_open_xfrfile(nsd, filenumber, seq_nr?"a":"w"); 64 if(!df) { 65 log_msg(LOG_ERR, "could not open transfer %s file %lld: %s", 66 zone, (long long)filenumber, strerror(errno)); 67 return; 68 } 69 70 /* if first part, first write the header */ 71 if(seq_nr == 0) { 72 struct timeval tv; 73 if (gettimeofday(&tv, NULL) != 0) { 74 log_msg(LOG_ERR, "could not get timestamp for %s: %s", 75 zone, strerror(errno)); 76 } 77 if(!write_32(df, DIFF_PART_XFRF) || 78 !write_8(df, 0) /* notcommitted(yet) */ || 79 !write_32(df, 0) /* numberofparts when done */ || 80 !write_64(df, (uint64_t) tv.tv_sec) || 81 !write_32(df, (uint32_t) tv.tv_usec) || 82 !write_32(df, old_serial) || 83 !write_32(df, new_serial) || 84 !write_64(df, (uint64_t) tv.tv_sec) || 85 !write_32(df, (uint32_t) tv.tv_usec) || 86 !write_str(df, zone) || 87 !write_str(df, pat)) { 88 log_msg(LOG_ERR, "could not write transfer %s file %lld: %s", 89 zone, (long long)filenumber, strerror(errno)); 90 fclose(df); 91 return; 92 } 93 } 94 95 if(!write_32(df, DIFF_PART_XXFR) || 96 !write_32(df, len) || 97 !write_data(df, data, len) || 98 !write_32(df, len)) 99 { 100 log_msg(LOG_ERR, "could not write transfer %s file %lld: %s", 101 zone, (long long)filenumber, strerror(errno)); 102 } 103 fclose(df); 104 } 105 106 void 107 diff_write_commit(const char* zone, uint32_t old_serial, uint32_t new_serial, 108 uint32_t num_parts, uint8_t commit, const char* log_str, 109 struct nsd* nsd, uint64_t filenumber) 110 { 111 struct timeval tv; 112 FILE* df; 113 114 if (gettimeofday(&tv, NULL) != 0) { 115 log_msg(LOG_ERR, "could not set timestamp for %s: %s", 116 zone, strerror(errno)); 117 } 118 119 /* overwrite the first part of the file with 'committed = 1', 120 * as well as the end_time and number of parts. 121 * also write old_serial and new_serial, so that a bad file mixup 122 * will result in unusable serial numbers. */ 123 124 df = xfrd_open_xfrfile(nsd, filenumber, "r+"); 125 if(!df) { 126 log_msg(LOG_ERR, "could not open transfer %s file %lld: %s", 127 zone, (long long)filenumber, strerror(errno)); 128 return; 129 } 130 if(!write_32(df, DIFF_PART_XFRF) || 131 !write_8(df, commit) /* committed */ || 132 !write_32(df, num_parts) || 133 !write_64(df, (uint64_t) tv.tv_sec) || 134 !write_32(df, (uint32_t) tv.tv_usec) || 135 !write_32(df, old_serial) || 136 !write_32(df, new_serial)) 137 { 138 log_msg(LOG_ERR, "could not write transfer %s file %lld: %s", 139 zone, (long long)filenumber, strerror(errno)); 140 fclose(df); 141 return; 142 } 143 144 /* append the log_str to the end of the file */ 145 if(fseek(df, 0, SEEK_END) == -1) { 146 log_msg(LOG_ERR, "could not fseek transfer %s file %lld: %s", 147 zone, (long long)filenumber, strerror(errno)); 148 fclose(df); 149 return; 150 } 151 if(!write_str(df, log_str)) { 152 log_msg(LOG_ERR, "could not write transfer %s file %lld: %s", 153 zone, (long long)filenumber, strerror(errno)); 154 fclose(df); 155 return; 156 157 } 158 fflush(df); 159 fclose(df); 160 } 161 162 void 163 diff_update_commit( 164 const char* zone, uint8_t commit, struct nsd* nsd, uint64_t filenumber) 165 { 166 FILE *df; 167 168 assert(zone != NULL); 169 assert(nsd != NULL); 170 assert(commit == DIFF_NOT_COMMITTED || 171 commit == DIFF_COMMITTED || 172 commit == DIFF_CORRUPT || 173 commit == DIFF_INCONSISTENT || 174 commit == DIFF_VERIFIED); 175 176 df = xfrd_open_xfrfile(nsd, filenumber, "r+"); 177 if(!df) { 178 log_msg(LOG_ERR, "could not open transfer %s file %lld: %s", 179 zone, (long long)filenumber, strerror(errno)); 180 return; 181 } 182 if(!write_32(df, DIFF_PART_XFRF) || !write_8(df, commit)) { 183 log_msg(LOG_ERR, "could not write transfer %s file %lld: %s", 184 zone, (long long)filenumber, strerror(errno)); 185 fclose(df); 186 return; 187 } 188 fflush(df); 189 fclose(df); 190 } 191 192 int 193 diff_read_64(FILE *in, uint64_t* result) 194 { 195 if (fread(result, sizeof(*result), 1, in) == 1) { 196 return 1; 197 } else { 198 return 0; 199 } 200 } 201 202 int 203 diff_read_32(FILE *in, uint32_t* result) 204 { 205 if (fread(result, sizeof(*result), 1, in) == 1) { 206 *result = ntohl(*result); 207 return 1; 208 } else { 209 return 0; 210 } 211 } 212 213 int 214 diff_read_8(FILE *in, uint8_t* result) 215 { 216 if (fread(result, sizeof(*result), 1, in) == 1) { 217 return 1; 218 } else { 219 return 0; 220 } 221 } 222 223 int 224 diff_read_str(FILE* in, char* buf, size_t len) 225 { 226 uint32_t disklen; 227 if(!diff_read_32(in, &disklen)) 228 return 0; 229 if(disklen >= len) 230 return 0; 231 if(fread(buf, disklen, 1, in) != 1) 232 return 0; 233 buf[disklen] = 0; 234 return 1; 235 } 236 237 static void 238 add_rr_to_recyclebin(namedb_type* db, rr_type* rr) 239 { 240 /* add rr and rdata to recycle bin. */ 241 region_recycle(db->region, rr, sizeof(rr_type) + rr->rdlength); 242 } 243 244 /* this routine determines if below a domain there exist names with 245 * data (is_existing) or no names below the domain have data. 246 */ 247 static int 248 has_data_below(domain_type* top) 249 { 250 domain_type* d = top; 251 assert(d != NULL); 252 /* in the canonical ordering subdomains are after this name */ 253 d = domain_next(d); 254 while(d != NULL && domain_is_subdomain(d, top)) { 255 if(d->is_existing) 256 return 1; 257 d = domain_next(d); 258 } 259 return 0; 260 } 261 262 /** check if domain with 0 rrsets has become empty (nonexist) */ 263 static domain_type* 264 rrset_zero_nonexist_check(domain_type* domain, domain_type* ce) 265 { 266 /* is the node now an empty node (completely deleted) */ 267 if(domain->rrsets == 0) { 268 /* if there is no data below it, it becomes non existing. 269 also empty nonterminals above it become nonexisting */ 270 /* check for data below this node. */ 271 if(!has_data_below(domain)) { 272 /* nonexist this domain and all parent empty nonterminals */ 273 domain_type* p = domain; 274 while(p != NULL && p->rrsets == 0) { 275 if(p == ce || has_data_below(p)) 276 return p; 277 p->is_existing = 0; 278 /* fixup wildcard child of parent */ 279 if(p->parent && 280 p->parent->wildcard_child_closest_match == p) 281 p->parent->wildcard_child_closest_match = domain_previous_existing_child(p); 282 p = p->parent; 283 } 284 } 285 } 286 return NULL; 287 } 288 289 /** remove rrset. Adjusts zone params. Does not remove domain */ 290 static void 291 rrset_delete(namedb_type* db, domain_type* domain, rrset_type* rrset) 292 { 293 int i; 294 /* find previous */ 295 rrset_type** pp = &domain->rrsets; 296 while(*pp && *pp != rrset) { 297 pp = &( (*pp)->next ); 298 } 299 if(!*pp) { 300 /* rrset does not exist for domain */ 301 return; 302 } 303 *pp = rrset->next; 304 305 DEBUG(DEBUG_XFRD,2, (LOG_INFO, "delete rrset of %s type %s", 306 domain_to_string(domain), 307 rrtype_to_string(rrset_rrtype(rrset)))); 308 309 /* is this a SOA rrset ? */ 310 if(rrset->zone->soa_rrset == rrset) { 311 rrset->zone->soa_rrset = 0; 312 } 313 if(rrset->zone->ns_rrset == rrset) { 314 rrset->zone->ns_rrset = 0; 315 } 316 if(domain == rrset->zone->apex && rrset_rrtype(rrset) == TYPE_RRSIG) { 317 for (i = 0; i < rrset->rr_count; ++i) { 318 if(rr_rrsig_type_covered(rrset->rrs[i])==TYPE_DNSKEY) { 319 rrset->zone->is_secure = 0; 320 break; 321 } 322 } 323 } 324 /* recycle the memory space of the rrset */ 325 for (i = 0; i < rrset->rr_count; ++i) 326 add_rr_to_recyclebin(db, rrset->rrs[i]); 327 #ifndef PACKED_STRUCTS 328 region_recycle(db->region, rrset->rrs, sizeof(rr_type*) * rrset->rr_count); 329 rrset->rr_count = 0; 330 #endif 331 region_recycle(db->region, rrset, sizeof(rrset_type) 332 #ifdef PACKED_STRUCTS 333 + rrset->rr_count*sizeof(rr_type*) 334 #endif 335 ); 336 } 337 338 static int 339 rdatas_equal(const rr_type *rr1, const rr_type *rr2, uint16_t type, 340 int* rdnum, char** reason) 341 { 342 size_t offset = 0; 343 const nsd_type_descriptor_type *descriptor; 344 345 if(rr1->rdlength != rr2->rdlength) { 346 *rdnum = 0; 347 *reason = "rr length different"; 348 return 0; 349 } 350 assert(rr1->rdlength == rr2->rdlength); 351 352 /** 353 * SOA RDATA comparisons in XFR are more lenient, 354 * only serial rdata is checked. 355 **/ 356 if (type == TYPE_SOA) { 357 offset = 2 * sizeof(void*); 358 if(rr1->rdlength != offset + 20) { 359 *rdnum = 0; 360 *reason = "invalid SOA length"; 361 return 0; 362 } 363 assert(rr1->rdlength == offset + 20); 364 if (memcmp(rr1->rdata + offset, rr2->rdata + offset, 4) == 0) 365 return 1; 366 *rdnum = 2; 367 *reason = "rdata data"; 368 return 0; 369 } 370 371 if (memcmp(rr1->rdata, rr2->rdata, rr1->rdlength) == 0) 372 return 1; 373 374 descriptor = nsd_type_descriptor(type); 375 for (size_t i=0; i < descriptor->rdata.length && offset < rr1->rdlength; i++) { 376 uint16_t field_len1, field_len2; 377 struct domain *domain1, *domain2; 378 if(offset == rr1->rdlength && 379 descriptor->rdata.fields[i].is_optional) 380 break; 381 if(!lookup_rdata_field_entry(descriptor, i, rr1, offset, 382 &field_len1, &domain1)) { 383 *rdnum = i; 384 *reason = "malformed field rr1"; 385 return 0; 386 } 387 if(!lookup_rdata_field_entry(descriptor, i, rr2, offset, 388 &field_len2, &domain2)) { 389 *rdnum = i; 390 *reason = "malformed field rr2"; 391 return 0; 392 } 393 if(domain1 && domain2) { 394 const struct dname *dname1, *dname2; 395 dname1 = domain_dname(domain1); 396 dname2 = domain_dname(domain2); 397 if (dname_compare(dname1, dname2) != 0) { 398 *rdnum = i; 399 *reason = "dname data"; 400 return 0; 401 } 402 offset += field_len1; 403 continue; 404 } else if(descriptor->rdata.fields[i].length == 405 RDATA_LITERAL_DNAME) { 406 uint8_t length1, length2; 407 const uint8_t *name1 = rr1->rdata + offset; 408 const uint8_t *name2 = rr2->rdata + offset; 409 if(field_len1 != field_len2) { 410 *rdnum = i; 411 *reason = "literal dname field len"; 412 return 0; 413 } 414 length1 = buf_dname_length(name1, rr1->rdlength - offset); 415 length2 = buf_dname_length(name2, rr2->rdlength - offset); 416 417 if (!length1 || !length2 || length1 != length2) { 418 *rdnum = i; 419 *reason = "literal dname len"; 420 return 0; 421 } 422 if (!dname_equal_nocase((uint8_t*)name1, (uint8_t*)name2, length1)) { 423 *rdnum = i; 424 *reason = "literal dname data"; 425 return 0; 426 } 427 offset += field_len1; 428 continue; 429 } 430 if(field_len1 != field_len2) { 431 *rdnum = i; 432 *reason = "rdata len"; 433 return 0; 434 } 435 if(memcmp(rr1->rdata+offset, rr2->rdata+offset, field_len1) != 0) { 436 *rdnum = i; 437 *reason = "rdata data"; 438 return 0; 439 } 440 offset += field_len1; 441 } 442 443 return 1; 444 } 445 446 static void 447 debug_find_rr_num(rrset_type* rrset, uint16_t type, uint16_t klass, 448 rr_type *rr) 449 { 450 int i, rd; 451 char* reason = ""; 452 453 for(i=0; i < rrset->rr_count; ++i) { 454 if (rrset->rrs[i]->type != type) { 455 log_msg(LOG_WARNING, "diff: RR <%s, %s> does not match " 456 "RR num %d type %s", 457 dname_to_string(domain_dname(rrset->rrs[i]->owner),0), 458 rrtype_to_string(type), i, 459 rrtype_to_string(rrset->rrs[i]->type)); 460 continue; /* rdata equality needs same type. */ 461 } 462 if (rrset->rrs[i]->klass != klass) { 463 log_msg(LOG_WARNING, "diff: RR <%s, %s> class %d " 464 "does not match RR num %d class %d", 465 dname_to_string(domain_dname(rrset->rrs[i]->owner),0), 466 rrtype_to_string(type), 467 klass, i, 468 rrset->rrs[i]->klass); 469 continue; 470 } 471 if (rrset->rrs[i]->rdlength != rr->rdlength) { 472 log_msg(LOG_WARNING, "diff: RR <%s, %s> rdlen %u " 473 "does not match RR num %d rdlen %d", 474 dname_to_string(domain_dname(rrset->rrs[i]->owner),0), 475 rrtype_to_string(type), 476 (unsigned) rr->rdlength, i, 477 (unsigned) rrset->rrs[i]->rdlength); 478 } 479 if (!rdatas_equal(rr, rrset->rrs[i], type, 480 &rd, &reason)) { 481 log_msg(LOG_WARNING, "diff: RR <%s, %s> rdata element " 482 "%d differs from RR num %d rdata (%s)", 483 dname_to_string(domain_dname(rrset->rrs[i]->owner),0), 484 rrtype_to_string(type), 485 rd, i, reason); 486 } 487 } 488 } 489 490 static int 491 find_rr_num(rrset_type* rrset, uint16_t type, uint16_t klass, 492 rr_type *rr, int add) 493 { 494 int i, rd; 495 char* reason; 496 497 for(i=0; i < rrset->rr_count; ++i) { 498 if(rrset->rrs[i]->type == type && 499 rrset->rrs[i]->klass == klass && 500 rrset->rrs[i]->rdlength == rr->rdlength && 501 rdatas_equal(rrset->rrs[i], rr, type, 502 &rd, &reason)) 503 { 504 return i; 505 } 506 } 507 /* this is odd. Log why rr cannot be found. */ 508 if (!add) { 509 debug_find_rr_num(rrset, type, klass, rr); 510 } 511 return -1; 512 } 513 514 #ifdef NSEC3 515 /* see if nsec3 deletion triggers need action */ 516 static void 517 nsec3_delete_rr_trigger(namedb_type* db, rr_type* rr, zone_type* zone) 518 { 519 /* the RR has not actually been deleted yet, so we can inspect it */ 520 if(!zone->nsec3_param) 521 return; 522 /* see if the domain was an NSEC3-domain in the chain, but no longer */ 523 if(rr->type == TYPE_NSEC3 && rr->owner->nsec3 && 524 rr->owner->nsec3->nsec3_node.key && 525 nsec3_rr_uses_params(rr, zone) && 526 nsec3_in_chain_count(rr->owner, zone) <= 1) { 527 domain_type* prev = nsec3_chain_find_prev(zone, rr->owner); 528 /* remove from prehash because no longer an NSEC3 domain */ 529 if(domain_is_prehash(db->domains, rr->owner)) 530 prehash_del(db->domains, rr->owner); 531 /* fixup the last in the zone */ 532 if(rr->owner == zone->nsec3_last) 533 zone->nsec3_last = prev; 534 /* unlink from the nsec3tree */ 535 zone_del_domain_in_hash_tree(zone->nsec3tree, 536 &rr->owner->nsec3->nsec3_node); 537 /* add previous NSEC3 to the prehash list */ 538 if(prev && prev != rr->owner) 539 prehash_add(db->domains, prev); 540 else nsec3_clear_precompile(db, zone); 541 /* this domain becomes ordinary data domain: done later */ 542 } 543 /* see if the rr was NSEC3PARAM that we were using */ 544 else if(rr->type == TYPE_NSEC3PARAM && rr == zone->nsec3_param) { 545 /* clear trees, wipe hashes, wipe precompile */ 546 nsec3_clear_precompile(db, zone); 547 /* pick up new nsec3param (from udb, or avoid deleted rr) */ 548 nsec3_find_zone_param(db, zone, rr, 0); 549 /* if no more NSEC3, done */ 550 if(!zone->nsec3_param) 551 return; 552 nsec3_precompile_newparam(db, zone); 553 } 554 } 555 556 /* see if nsec3 prehash can be removed with new rrset content */ 557 static void 558 nsec3_rrsets_changed_remove_prehash(domain_type* domain, zone_type* zone) 559 { 560 /* deletion of rrset already done, we can check if conditions apply */ 561 /* see if the domain is no longer precompiled */ 562 /* it has a hash_node, but no longer fulfills conditions */ 563 if(nsec3_domain_part_of_zone(domain, zone) && domain->nsec3 && 564 domain->nsec3->hash_wc && 565 domain->nsec3->hash_wc->hash.node.key && 566 !nsec3_condition_hash(domain, zone)) { 567 /* remove precompile */ 568 domain->nsec3->nsec3_cover = NULL; 569 domain->nsec3->nsec3_wcard_child_cover = NULL; 570 domain->nsec3->nsec3_is_exact = 0; 571 /* remove it from the hash tree */ 572 zone_del_domain_in_hash_tree(zone->hashtree, 573 &domain->nsec3->hash_wc->hash.node); 574 zone_del_domain_in_hash_tree(zone->wchashtree, 575 &domain->nsec3->hash_wc->wc.node); 576 } 577 if(domain != zone->apex && domain->nsec3 && 578 domain->nsec3->ds_parent_hash && 579 domain->nsec3->ds_parent_hash->node.key && 580 (!domain->parent || nsec3_domain_part_of_zone(domain->parent, zone)) && 581 !nsec3_condition_dshash(domain, zone)) { 582 /* remove precompile */ 583 domain->nsec3->nsec3_ds_parent_cover = NULL; 584 domain->nsec3->nsec3_ds_parent_is_exact = 0; 585 /* remove it from the hash tree */ 586 zone_del_domain_in_hash_tree(zone->dshashtree, 587 &domain->nsec3->ds_parent_hash->node); 588 } 589 } 590 591 /* see if domain needs to get precompiled info */ 592 static void 593 nsec3_rrsets_changed_add_prehash(namedb_type* db, domain_type* domain, 594 zone_type* zone) 595 { 596 if(!zone->nsec3_param) 597 return; 598 if((!domain->nsec3 || !domain->nsec3->hash_wc 599 || !domain->nsec3->hash_wc->hash.node.key) 600 && nsec3_condition_hash(domain, zone)) { 601 region_type* tmpregion = region_create(xalloc, free); 602 nsec3_precompile_domain(db, domain, zone, tmpregion); 603 region_destroy(tmpregion); 604 } 605 if((!domain->nsec3 || !domain->nsec3->ds_parent_hash 606 || !domain->nsec3->ds_parent_hash->node.key) 607 && nsec3_condition_dshash(domain, zone)) { 608 nsec3_precompile_domain_ds(db, domain, zone); 609 } 610 } 611 612 /* see if nsec3 rrset-deletion triggers need action */ 613 static void 614 nsec3_delete_rrset_trigger(namedb_type* db, domain_type* domain, 615 zone_type* zone, uint16_t type) 616 { 617 if(!zone->nsec3_param) 618 return; 619 nsec3_rrsets_changed_remove_prehash(domain, zone); 620 /* for type nsec3, or a delegation, the domain may have become a 621 * 'normal' domain with its remaining data now */ 622 if(type == TYPE_NSEC3 || type == TYPE_NS || type == TYPE_DS) 623 nsec3_rrsets_changed_add_prehash(db, domain, zone); 624 /* for type DNAME or a delegation, obscured data may be revealed */ 625 if(type == TYPE_NS || type == TYPE_DS || type == TYPE_DNAME) { 626 /* walk over subdomains and check them each */ 627 domain_type *d; 628 for(d=domain_next(domain); d && domain_is_subdomain(d, domain); 629 d=domain_next(d)) { 630 nsec3_rrsets_changed_add_prehash(db, d, zone); 631 } 632 } 633 } 634 635 /* see if nsec3 addition triggers need action */ 636 static void 637 nsec3_add_rr_trigger(namedb_type* db, rr_type* rr, zone_type* zone) 638 { 639 /* the RR has been added in full, also to UDB (and thus NSEC3PARAM 640 * in the udb has been adjusted) */ 641 if(zone->nsec3_param && rr->type == TYPE_NSEC3 && 642 (!rr->owner->nsec3 || !rr->owner->nsec3->nsec3_node.key) 643 && nsec3_rr_uses_params(rr, zone)) { 644 if(!zone->nsec3_last) { 645 /* all nsec3s have previously been deleted, but 646 * we have nsec3 parameters, set it up again from 647 * being cleared. */ 648 nsec3_precompile_newparam(db, zone); 649 } 650 /* added NSEC3 into the chain */ 651 nsec3_precompile_nsec3rr(db, rr->owner, zone); 652 /* the domain has become an NSEC3-domain, if it was precompiled 653 * previously, remove that, neatly done in routine above */ 654 nsec3_rrsets_changed_remove_prehash(rr->owner, zone); 655 /* set this NSEC3 to prehash */ 656 prehash_add(db->domains, rr->owner); 657 } else if(!zone->nsec3_param && rr->type == TYPE_NSEC3PARAM) { 658 /* see if this means NSEC3 chain can be used */ 659 nsec3_find_zone_param(db, zone, NULL, 0); 660 if(!zone->nsec3_param) 661 return; 662 nsec3_zone_trees_create(db->region, zone); 663 nsec3_precompile_newparam(db, zone); 664 } 665 } 666 667 /* see if nsec3 rrset-addition triggers need action */ 668 static void 669 nsec3_add_rrset_trigger(namedb_type* db, domain_type* domain, zone_type* zone, 670 uint16_t type) 671 { 672 /* the rrset has been added so we can inspect it */ 673 if(!zone->nsec3_param) 674 return; 675 /* because the rrset is added we can check conditions easily. 676 * check if domain needs to become precompiled now */ 677 nsec3_rrsets_changed_add_prehash(db, domain, zone); 678 /* if a delegation, it changes from normal name to unhashed referral */ 679 if(type == TYPE_NS || type == TYPE_DS) { 680 nsec3_rrsets_changed_remove_prehash(domain, zone); 681 } 682 /* if delegation or DNAME added, then some RRs may get obscured */ 683 if(type == TYPE_NS || type == TYPE_DS || type == TYPE_DNAME) { 684 /* walk over subdomains and check them each */ 685 domain_type *d; 686 for(d=domain_next(domain); d && domain_is_subdomain(d, domain); 687 d=domain_next(d)) { 688 nsec3_rrsets_changed_remove_prehash(d, zone); 689 } 690 } 691 } 692 #endif /* NSEC3 */ 693 694 static void 695 rrset_lower_usage(namedb_type* db, rrset_type* rrset) 696 { 697 unsigned i; 698 for(i=0; i<rrset->rr_count; i++) 699 rr_lower_usage(db, rrset->rrs[i]); 700 } 701 702 int 703 delete_RR(namedb_type* db, const dname_type* dname, 704 uint16_t type, uint16_t klass, uint32_t ttl, 705 buffer_type* packet, size_t rdatalen, zone_type *zone, 706 region_type* temp_region, int* softfail, struct ixfr_store* ixfr_store) 707 { 708 domain_type *domain; 709 rrset_type *rrset; 710 #ifdef PACKED_STRUCTS 711 rrset_type* rrset_prev; 712 #endif 713 const nsd_type_descriptor_type *descriptor = nsd_type_descriptor(type); 714 domain = domain_table_find(db->domains, dname); 715 if(!domain) { 716 log_msg(LOG_WARNING, "diff: domain %s does not exist", 717 dname_to_string(dname,0)); 718 buffer_skip(packet, rdatalen); 719 *softfail = 1; 720 return 1; /* not fatal error */ 721 } 722 #ifndef PACKED_STRUCTS 723 rrset = domain_find_rrset(domain, zone, type); 724 #else 725 rrset = domain_find_rrset_and_prev(domain, zone, type, &rrset_prev); 726 #endif 727 if(!rrset) { 728 log_msg(LOG_WARNING, "diff: rrset %s does not exist", 729 dname_to_string(dname,0)); 730 buffer_skip(packet, rdatalen); 731 *softfail = 1; 732 return 1; /* not fatal error */ 733 } else { 734 /* find the RR in the rrset */ 735 domain_table_type *temptable; 736 int32_t rrnum, code; 737 struct rr *rr; 738 temptable = domain_table_create(temp_region); 739 /* This will ensure that the dnames in rdata are 740 * normalized, conform RFC 4035, section 6.2 741 */ 742 code = descriptor->read_rdata(temptable, rdatalen, packet, &rr); 743 if(code < 0) { 744 log_msg(LOG_ERR, "diff: could not read rdata for " 745 "%s %s %s", dname_to_string(dname,0), 746 rrtype_to_string(type), 747 read_rdata_fail_str(code)); 748 } 749 rr->owner = domain; 750 rr->type = type; 751 rr->klass = klass; 752 rr->ttl = ttl; 753 754 /* Now that the RR has been read with its RRtype specific read 755 * routine, store the read data and rdata, for an ixfr store. 756 * Store the delete RR information, for the softfail cases, the 757 * IXFR is stopped and an AXFR is attempted, so it would not 758 * need to be stored as the transfer is rejected. */ 759 if(ixfr_store) 760 ixfr_store_delrr(ixfr_store, rr); 761 762 rrnum = find_rr_num(rrset, type, klass, rr, 0); 763 if(rrnum == -1 && type == TYPE_SOA && domain == zone->apex 764 && rrset->rr_count != 0) 765 rrnum = 0; /* replace existing SOA if no match */ 766 if(rrnum == -1) { 767 log_msg(LOG_WARNING, "diff: RR <%s, %s> does not exist", 768 dname_to_string(dname,0), rrtype_to_string(type)); 769 *softfail = 1; 770 return 1; /* not fatal error */ 771 } 772 #ifdef NSEC3 773 /* process triggers for RR deletions */ 774 nsec3_delete_rr_trigger(db, rrset->rrs[rrnum], zone); 775 #endif 776 /* lower usage (possibly deleting other domains, and thus 777 * invalidating the current RR's domain pointers) */ 778 rr_lower_usage(db, rrset->rrs[rrnum]); 779 if(rrset->rr_count == 1) { 780 /* delete entire rrset */ 781 rrset_delete(db, domain, rrset); 782 /* check if domain is now nonexisting (or parents) */ 783 rrset_zero_nonexist_check(domain, NULL); 784 #ifdef NSEC3 785 /* cleanup nsec3 */ 786 nsec3_delete_rrset_trigger(db, domain, zone, type); 787 #endif 788 /* see if the domain can be deleted (and inspect parents) */ 789 domain_table_deldomain(db, domain); 790 } else { 791 /* swap out the bad RR and decrease the count */ 792 #ifndef PACKED_STRUCTS 793 rr_type** rrs_orig = rrset->rrs; 794 #else 795 rrset_type* rrset_orig = rrset; 796 #endif 797 add_rr_to_recyclebin(db, rrset->rrs[rrnum]); 798 if(rrnum < rrset->rr_count-1) 799 rrset->rrs[rrnum] = rrset->rrs[rrset->rr_count-1]; 800 rrset->rrs[rrset->rr_count-1] = NULL; 801 /* realloc the rrs array one smaller */ 802 #ifndef PACKED_STRUCTS 803 rrset->rrs = region_alloc_array_init(db->region, rrs_orig, 804 (rrset->rr_count-1), sizeof(rr_type*)); 805 if(!rrset->rrs) { 806 log_msg(LOG_ERR, "out of memory, %s:%d", __FILE__, __LINE__); 807 exit(1); 808 } 809 region_recycle(db->region, rrs_orig, 810 sizeof(rr_type*) * rrset->rr_count); 811 #else 812 rrset = region_alloc_init(db->region, rrset_orig, 813 sizeof(rrset_type) + 814 (rrset_orig->rr_count-1)*sizeof(rr_type*)); 815 if(!rrset) { 816 log_msg(LOG_ERR, "out of memory, %s:%d", __FILE__, __LINE__); 817 exit(1); 818 } 819 if(rrset_prev) 820 rrset_prev->next = rrset; 821 else domain->rrsets = rrset; 822 region_recycle(db->region, rrset_orig, 823 sizeof(rrset_type) + 824 rrset_orig->rr_count*sizeof(rr_type*)); 825 if(domain == zone->apex) { 826 /* Because the rrset struct is reallocated, 827 * a pointer to it may need to be set again. */ 828 if(type == TYPE_SOA) { 829 zone->soa_rrset = rrset; 830 } else if(type == TYPE_NS) { 831 zone->ns_rrset = rrset; 832 } 833 } 834 #endif /* PACKED_STRUCTS */ 835 rrset->rr_count --; 836 #ifdef NSEC3 837 /* for type nsec3, the domain may have become a 838 * 'normal' domain with its remaining data now */ 839 if(type == TYPE_NSEC3) 840 nsec3_rrsets_changed_add_prehash(db, domain, 841 zone); 842 #endif /* NSEC3 */ 843 } 844 } 845 return 1; 846 } 847 848 int 849 add_RR(namedb_type* db, const dname_type* dname, 850 uint16_t type, uint16_t klass, uint32_t ttl, 851 buffer_type* packet, size_t rdatalen, zone_type *zone, 852 int* softfail, struct ixfr_store* ixfr_store) 853 { 854 domain_type* domain; 855 rrset_type* rrset; 856 #ifndef PACKED_STRUCTS 857 rr_type **rrs_old; 858 #else 859 rrset_type* rrset_prev; 860 #endif 861 rr_type *rr; 862 int32_t code; 863 int rrnum; 864 const nsd_type_descriptor_type *descriptor; 865 #ifdef NSEC3 866 int rrset_added = 0; 867 #endif 868 domain = domain_table_find(db->domains, dname); 869 if(!domain) { 870 /* create the domain */ 871 domain = domain_table_insert(db->domains, dname); 872 } 873 #ifndef PACKED_STRUCTS 874 rrset = domain_find_rrset(domain, zone, type); 875 #else 876 rrset = domain_find_rrset_and_prev(domain, zone, type, &rrset_prev); 877 #endif 878 if(!rrset) { 879 /* create the rrset */ 880 rrset = region_alloc(db->region, sizeof(rrset_type) 881 #ifdef PACKED_STRUCTS 882 + sizeof(rr_type*) /* ready for add of one RR */ 883 #endif 884 ); 885 if(!rrset) { 886 log_msg(LOG_ERR, "out of memory, %s:%d", __FILE__, __LINE__); 887 exit(1); 888 } 889 rrset->zone = zone; 890 #ifndef PACKED_STRUCTS 891 rrset->rrs = 0; 892 #endif 893 rrset->rr_count = 0; 894 domain_add_rrset(domain, rrset); 895 #ifdef NSEC3 896 rrset_added = 1; 897 #endif 898 } 899 900 /* dnames in rdata are normalized, conform RFC 4035, 901 * Section 6.2 902 */ 903 descriptor = nsd_type_descriptor(type); 904 code = descriptor->read_rdata( 905 db->domains, rdatalen, packet, &rr); 906 if(code < 0) { 907 log_msg(LOG_ERR, "diff: could not read rdata for %s %s %s", 908 dname_to_string(dname,0), rrtype_to_string(type), 909 read_rdata_fail_str(code)); 910 return 0; 911 } 912 rr->owner = domain; 913 rr->type = type; 914 rr->klass = klass; 915 rr->ttl = ttl; 916 917 /* Now that the RR has been read with its RRtype specific read 918 * routine, store the read data and rdata, for an ixfr store. */ 919 if (ixfr_store) 920 ixfr_store_addrr(ixfr_store, rr); 921 922 rrnum = find_rr_num(rrset, type, klass, rr, 1); 923 if(rrnum != -1) { 924 DEBUG(DEBUG_XFRD, 2, (LOG_ERR, "diff: RR <%s, %s> already exists", 925 dname_to_string(dname,0), rrtype_to_string(type))); 926 /* ignore already existing RR: lenient accepting of messages */ 927 *softfail = 1; 928 return 1; 929 } 930 if(rrset->rr_count == 65535) { 931 log_msg(LOG_ERR, "diff: too many RRs at %s", 932 dname_to_string(dname,0)); 933 return 0; 934 } 935 936 /* re-alloc the rrs and add the new */ 937 #ifndef PACKED_STRUCTS 938 rrs_old = rrset->rrs; 939 rrset->rrs = region_alloc_array(db->region, 940 (rrset->rr_count+1), sizeof(rr_type*)); 941 if(!rrset->rrs) { 942 log_msg(LOG_ERR, "out of memory, %s:%d", __FILE__, __LINE__); 943 exit(1); 944 } 945 if(rrs_old) 946 memcpy(rrset->rrs, rrs_old, rrset->rr_count * sizeof(rr_type*)); 947 region_recycle(db->region, rrs_old, sizeof(rr_type*) * rrset->rr_count); 948 rrset->rr_count ++; 949 rrset->rrs[rrset->rr_count - 1] = rr; 950 #else 951 if(rrset->rr_count == 0) { 952 /* It was allocated with space for one RR. */ 953 rrset->rr_count = 1; 954 rrset->rrs[0] = rr; 955 } else { 956 rrset_type* rrset_old = rrset; 957 rrset = region_alloc(db->region, sizeof(rrset_type) + 958 (rrset_old->rr_count+1)*sizeof(rr_type*)); 959 if(!rrset) { 960 log_msg(LOG_ERR, "out of memory, %s:%d", __FILE__, __LINE__); 961 exit(1); 962 } 963 memcpy(rrset, rrset_old, sizeof(rrset_type) + 964 rrset_old->rr_count * sizeof(rr_type*)); 965 if(rrset_prev) 966 rrset_prev->next = rrset; 967 else domain->rrsets = rrset; 968 region_recycle(db->region, rrset_old, sizeof(rrset_type) + 969 rrset_old->rr_count * sizeof(rr_type*)); 970 rrset->rr_count ++; 971 rrset->rrs[rrset->rr_count - 1] = rr; 972 } 973 #endif /* PACKED_STRUCTS */ 974 975 /* see if it is a SOA */ 976 if(domain == zone->apex) { 977 apex_rrset_checks(db, rrset, domain); 978 } 979 980 #ifdef NSEC3 981 if(rrset_added) { 982 domain_type* p = domain->parent; 983 nsec3_add_rrset_trigger(db, domain, zone, type); 984 /* go up and process (possibly created) empty nonterminals, 985 * until we hit the apex or root */ 986 while(p && p->rrsets == NULL && !p->is_apex) { 987 nsec3_rrsets_changed_add_prehash(db, p, zone); 988 p = p->parent; 989 } 990 } 991 nsec3_add_rr_trigger(db, rrset->rrs[rrset->rr_count - 1], zone); 992 #endif /* NSEC3 */ 993 return 1; 994 } 995 996 static zone_type* 997 find_or_create_zone(namedb_type* db, const dname_type* zone_name, 998 struct nsd_options* opt, const char* zstr, const char* patname) 999 { 1000 zone_type* zone; 1001 struct zone_options* zopt; 1002 zone = namedb_find_zone(db, zone_name); 1003 if(zone) { 1004 return zone; 1005 } 1006 zopt = zone_options_find(opt, zone_name); 1007 if(!zopt) { 1008 /* if _implicit_ then insert as _part_of_config */ 1009 if(strncmp(patname, PATTERN_IMPLICIT_MARKER, 1010 strlen(PATTERN_IMPLICIT_MARKER)) == 0) { 1011 zopt = zone_options_create(opt->region); 1012 if(!zopt) return 0; 1013 zopt->part_of_config = 1; 1014 zopt->name = region_strdup(opt->region, zstr); 1015 zopt->pattern = pattern_options_find(opt, patname); 1016 if(!zopt->name || !zopt->pattern) return 0; 1017 if(!nsd_options_insert_zone(opt, zopt)) { 1018 log_msg(LOG_ERR, "bad domain name or duplicate zone '%s' " 1019 "pattern %s", zstr, patname); 1020 } 1021 } else { 1022 /* create zone : presumably already added to zonelist 1023 * by xfrd, who wrote the AXFR or IXFR to disk, so we only 1024 * need to add it to our config. 1025 * This process does not need linesize and offset zonelist */ 1026 zopt = zone_list_zone_insert(opt, zstr, patname); 1027 if(!zopt) 1028 return 0; 1029 } 1030 } 1031 zone = namedb_zone_create(db, zone_name, zopt); 1032 return zone; 1033 } 1034 1035 void 1036 delete_zone_rrs(namedb_type* db, zone_type* zone) 1037 { 1038 rrset_type *rrset; 1039 domain_type *domain = zone->apex, *next; 1040 int nonexist_check = 0; 1041 /* go through entire tree below the zone apex (incl subzones) */ 1042 while(domain && domain_is_subdomain(domain, zone->apex)) 1043 { 1044 DEBUG(DEBUG_XFRD,2, (LOG_INFO, "delete zone visit %s", 1045 domain_to_string(domain))); 1046 /* delete all rrsets of the zone */ 1047 while((rrset = domain_find_any_rrset(domain, zone))) { 1048 /* lower usage can delete other domains */ 1049 rrset_lower_usage(db, rrset); 1050 /* rrset del does not delete our domain(yet) */ 1051 rrset_delete(db, domain, rrset); 1052 /* no rrset_zero_nonexist_check, do that later */ 1053 if(domain->rrsets == 0) 1054 nonexist_check = 1; 1055 } 1056 /* the delete upcoming could delete parents, but nothing next 1057 * or after the domain so store next ptr */ 1058 next = domain_next(domain); 1059 /* see if the domain can be deleted (and inspect parents) */ 1060 domain_table_deldomain(db, domain); 1061 domain = next; 1062 } 1063 1064 /* check if data deletions have created nonexisting domain entries, 1065 * but after deleting domains so the checks are faster */ 1066 if(nonexist_check) { 1067 domain_type* ce = NULL; /* for speeding up has_data_below */ 1068 DEBUG(DEBUG_XFRD, 1, (LOG_INFO, "axfrdel: zero rrset check")); 1069 domain = zone->apex; 1070 while(domain && domain_is_subdomain(domain, zone->apex)) 1071 { 1072 /* the interesting domains should be existing==1 1073 * and rrsets==0, speeding up out processing of 1074 * sub-zones, since we only spuriously check empty 1075 * nonterminals */ 1076 if(domain->is_existing) 1077 ce = rrset_zero_nonexist_check(domain, ce); 1078 domain = domain_next(domain); 1079 } 1080 } 1081 1082 DEBUG(DEBUG_XFRD, 1, (LOG_INFO, "axfrdel: recyclebin holds %lu bytes", 1083 (unsigned long) region_get_recycle_size(db->region))); 1084 #ifndef NDEBUG 1085 if(nsd_debug_level >= 2) 1086 region_log_stats(db->region); 1087 #endif 1088 1089 assert(zone->soa_rrset == 0); 1090 /* keep zone->soa_nx_rrset alloced: it is reused */ 1091 assert(zone->ns_rrset == 0); 1092 assert(zone->is_secure == 0); 1093 } 1094 1095 /* return value 0: syntaxerror,badIXFR, 1:OK, 2:done_and_skip_it */ 1096 static int 1097 apply_ixfr(nsd_type* nsd, FILE *in, uint32_t serialno, 1098 uint32_t seq_nr, uint32_t seq_total, 1099 int* is_axfr, int* delete_mode, int* rr_count, 1100 struct zone* zone, uint64_t* bytes, 1101 int* softfail, struct ixfr_store* ixfr_store) 1102 { 1103 uint32_t msglen, checklen, pkttype; 1104 int qcount, ancount; 1105 buffer_type* packet; 1106 region_type* region; 1107 1108 /* note that errors could not really happen due to format of the 1109 * packet since xfrd has checked all dnames and RRs before commit, 1110 * this is why the errors are fatal (exit process), it must be 1111 * something internal or a bad disk or something. */ 1112 1113 /* read ixfr packet RRs and apply to in memory db */ 1114 if(!diff_read_32(in, &pkttype) || pkttype != DIFF_PART_XXFR) { 1115 log_msg(LOG_ERR, "could not read type or wrong type"); 1116 return 0; 1117 } 1118 1119 if(!diff_read_32(in, &msglen)) { 1120 log_msg(LOG_ERR, "could not read len"); 1121 return 0; 1122 } 1123 1124 if(msglen < QHEADERSZ) { 1125 log_msg(LOG_ERR, "msg too short"); 1126 return 0; 1127 } 1128 1129 region = region_create(xalloc, free); 1130 if(!region) { 1131 log_msg(LOG_ERR, "out of memory"); 1132 return 0; 1133 } 1134 packet = buffer_create(region, QIOBUFSZ); 1135 if(msglen > QIOBUFSZ) { 1136 log_msg(LOG_ERR, "msg too long"); 1137 region_destroy(region); 1138 return 0; 1139 } 1140 buffer_clear(packet); 1141 if(fread(buffer_begin(packet), msglen, 1, in) != 1) { 1142 log_msg(LOG_ERR, "short fread: %s", strerror(errno)); 1143 region_destroy(region); 1144 return 0; 1145 } 1146 buffer_set_limit(packet, msglen); 1147 1148 /* see if check on data fails: checks that we are not reading 1149 * random garbage */ 1150 if(!diff_read_32(in, &checklen) || checklen != msglen) { 1151 log_msg(LOG_ERR, "transfer part has incorrect checkvalue"); 1152 return 0; 1153 } 1154 *bytes += msglen; 1155 1156 /* only answer section is really used, question, additional and 1157 authority section RRs are skipped */ 1158 qcount = QDCOUNT(packet); 1159 ancount = ANCOUNT(packet); 1160 buffer_skip(packet, QHEADERSZ); 1161 /* qcount should be 0 or 1 really, ancount limited by 64k packet */ 1162 if(qcount > 64 || ancount > 65530) { 1163 log_msg(LOG_ERR, "RR count impossibly high"); 1164 region_destroy(region); 1165 return 0; 1166 } 1167 1168 /* skip queries */ 1169 for(int i=0; i < qcount; ++i) { 1170 if(!packet_skip_rr(packet, 1)) { 1171 log_msg(LOG_ERR, "bad RR in question section"); 1172 region_destroy(region); 1173 return 0; 1174 } 1175 } 1176 1177 DEBUG(DEBUG_XFRD, 2, (LOG_INFO, "diff: started packet for zone %s", 1178 domain_to_string(zone->apex))); 1179 1180 for(int i=0; i < ancount; ++i, ++(*rr_count)) { 1181 const dname_type *owner; 1182 uint16_t type, klass, rrlen; 1183 uint32_t ttl; 1184 1185 owner = dname_make_from_packet(region, packet, 1, 1); 1186 if(!owner) { 1187 log_msg(LOG_ERR, "bad xfr RR dname %d", *rr_count); 1188 region_destroy(region); 1189 return 0; 1190 } 1191 if(!buffer_available(packet, 10)) { 1192 log_msg(LOG_ERR, "bad xfr RR format %d", *rr_count); 1193 region_destroy(region); 1194 return 0; 1195 } 1196 type = buffer_read_u16(packet); 1197 klass = buffer_read_u16(packet); 1198 ttl = buffer_read_u32(packet); 1199 rrlen = buffer_read_u16(packet); 1200 if(!buffer_available(packet, rrlen)) { 1201 log_msg(LOG_ERR, "bad xfr RR rdata %d, len %d have %d", 1202 *rr_count, rrlen, (int)buffer_remaining(packet)); 1203 region_destroy(region); 1204 return 0; 1205 } 1206 1207 DEBUG(DEBUG_XFRD,2, (LOG_INFO, "diff: %s parsed count %d, ax %d, delmode %d", 1208 domain_to_string(zone->apex), *rr_count, *is_axfr, *delete_mode)); 1209 1210 if (type == TYPE_SOA) { 1211 size_t position; 1212 uint32_t serial; 1213 position = buffer_position(packet); 1214 if (!packet_skip_dname(packet) || 1215 !packet_skip_dname(packet) || 1216 buffer_remaining(packet) < sizeof(uint32_t) * 5) 1217 { 1218 log_msg(LOG_ERR, "bad xfr SOA RR formerr."); 1219 region_destroy(region); 1220 return 0; 1221 } 1222 1223 serial = buffer_read_u32(packet); 1224 buffer_set_position(packet, position); 1225 1226 /* first RR: check if SOA and correct zone & serialno */ 1227 if (*rr_count == 0) { 1228 assert(!*is_axfr); 1229 assert(!*delete_mode); 1230 if (klass != CLASS_IN) { 1231 log_msg(LOG_ERR, "first RR not SOA IN"); 1232 region_destroy(region); 1233 return 0; 1234 } 1235 if(dname_compare(domain_dname(zone->apex), owner) != 0) { 1236 log_msg(LOG_ERR, "SOA dname not equal to zone %s", 1237 domain_to_string(zone->apex)); 1238 region_destroy(region); 1239 return 0; 1240 } 1241 if(serial != serialno) { 1242 log_msg(LOG_ERR, "SOA serial %u different from commit %u", 1243 (unsigned)serial, (unsigned)serialno); 1244 region_destroy(region); 1245 return 0; 1246 } 1247 buffer_skip(packet, rrlen); 1248 1249 if(ixfr_store) 1250 ixfr_store_add_newsoa(ixfr_store, ttl, packet, rrlen); 1251 1252 continue; 1253 } else if (*rr_count == 1) { 1254 assert(!*is_axfr); 1255 assert(!*delete_mode); 1256 /* if the serial no of the SOA equals the serialno, then AXFR */ 1257 if (serial == serialno) 1258 goto axfr; 1259 *delete_mode = 1; 1260 /* must have stuff in memory for a successful IXFR, 1261 * the serial number of the SOA has been checked 1262 * previously (by check_for_bad_serial) if it exists */ 1263 if(!domain_find_rrset(zone->apex, zone, TYPE_SOA)) { 1264 log_msg(LOG_ERR, "%s SOA serial %u is not " 1265 "in memory, skip IXFR", domain_to_string(zone->apex), serialno); 1266 region_destroy(region); 1267 /* break out and stop the IXFR, ignore it */ 1268 return 2; 1269 } 1270 1271 if(ixfr_store) 1272 ixfr_store_add_oldsoa(ixfr_store, ttl, packet, rrlen); 1273 } else if (!*is_axfr) { 1274 /* do not delete final SOA RR for IXFR */ 1275 if (i == ancount - 1 && seq_nr == seq_total - 1) { 1276 if (ixfr_store) { 1277 ixfr_store_add_newsoa(ixfr_store, ttl, packet, rrlen); 1278 } 1279 *delete_mode = 0; 1280 buffer_skip(packet, rrlen); 1281 continue; 1282 } else 1283 *delete_mode = !*delete_mode; 1284 1285 if (ixfr_store && *delete_mode) { 1286 ixfr_store_add_newsoa(ixfr_store, ttl, packet, rrlen); 1287 ixfr_store_finish(ixfr_store, nsd, NULL); 1288 ixfr_store_start(zone, ixfr_store); 1289 ixfr_store_add_oldsoa(ixfr_store, ttl, packet, rrlen); 1290 } 1291 /* switch from delete-part to add-part and back again, 1292 just before soa - so it gets deleted and added too */ 1293 DEBUG(DEBUG_XFRD,2, (LOG_INFO, "diff: %s IXFRswapdel count %d, ax %d, delmode %d", 1294 domain_to_string(zone->apex), *rr_count, *is_axfr, *delete_mode)); 1295 } 1296 } else { 1297 if (*rr_count == 0) { 1298 log_msg(LOG_ERR, "first RR not SOA IN"); 1299 region_destroy(region); 1300 return 0; 1301 /* second RR: if not SOA: this is an AXFR; delete all zone contents */ 1302 } else if (*rr_count == 1) { 1303 axfr: 1304 *is_axfr = 1; 1305 #ifdef NSEC3 1306 nsec3_clear_precompile(nsd->db, zone); 1307 zone->nsec3_param = NULL; 1308 #endif 1309 delete_zone_rrs(nsd->db, zone); 1310 if(ixfr_store) { 1311 ixfr_store_cancel(ixfr_store); 1312 ixfr_store_delixfrs(zone); 1313 } 1314 DEBUG(DEBUG_XFRD,2, (LOG_INFO, "diff: %s sawAXFR count %d, ax %d, delmode %d", 1315 domain_to_string(zone->apex), *rr_count, *is_axfr, *delete_mode)); 1316 } 1317 } 1318 1319 if(type == TYPE_TSIG || type == TYPE_OPT) { 1320 /* ignore pseudo RRs */ 1321 buffer_skip(packet, rrlen); 1322 continue; 1323 } 1324 1325 DEBUG(DEBUG_XFRD,2, (LOG_INFO, "xfr %s RR dname is %s type %s", 1326 *delete_mode?"del":"add", 1327 dname_to_string(owner, 0), rrtype_to_string(type))); 1328 if(*delete_mode) { 1329 assert(!*is_axfr); 1330 /* delete this rr */ 1331 if(!delete_RR(nsd->db, owner, type, klass, ttl, packet, 1332 rrlen, zone, region, softfail, ixfr_store)) { 1333 region_destroy(region); 1334 return 0; 1335 } 1336 } else { 1337 /* add this rr */ 1338 if(!(add_RR(nsd->db, owner, type, klass, ttl, packet, 1339 rrlen, zone, softfail, ixfr_store))) { 1340 region_destroy(region); 1341 return 0; 1342 } 1343 } 1344 } 1345 region_destroy(region); 1346 return 1; 1347 } 1348 1349 static int 1350 check_for_bad_serial(namedb_type* db, const char* zone_str, uint32_t old_serial) 1351 { 1352 /* see if serial OK with in-memory serial */ 1353 domain_type* domain; 1354 region_type* region = region_create(xalloc, free); 1355 const dname_type* zone_name = dname_parse(region, zone_str); 1356 zone_type* zone = 0; 1357 domain = domain_table_find(db->domains, zone_name); 1358 if(domain) 1359 zone = domain_find_zone(db, domain); 1360 if(zone && zone->apex == domain && zone->soa_rrset && old_serial) 1361 { 1362 uint32_t memserial = 0; 1363 retrieve_soa_rdata_serial(zone->soa_rrset->rrs[0], &memserial); 1364 if(old_serial != memserial) { 1365 region_destroy(region); 1366 return 1; 1367 } 1368 } 1369 region_destroy(region); 1370 return 0; 1371 } 1372 1373 int 1374 apply_ixfr_for_zone(nsd_type* nsd, zone_type* zone, FILE* in, 1375 struct nsd_options* ATTR_UNUSED(opt), udb_base* taskudb, uint32_t xfrfilenr) 1376 { 1377 char zone_buf[3072]; 1378 char log_buf[5120]; 1379 char patname_buf[2048]; 1380 1381 uint32_t old_serial, new_serial, num_parts, type; 1382 uint64_t time_end_0, time_start_0; 1383 uint32_t time_end_1, time_start_1; 1384 uint8_t committed; 1385 uint32_t i; 1386 uint64_t num_bytes = 0; 1387 assert(zone); 1388 1389 /* read zone name and serial */ 1390 if(!diff_read_32(in, &type)) { 1391 log_msg(LOG_ERR, "diff file too short"); 1392 return 0; 1393 } 1394 if(type != DIFF_PART_XFRF) { 1395 log_msg(LOG_ERR, "xfr file has wrong format"); 1396 return 0; 1397 1398 } 1399 /* committed and num_parts are first because they need to be 1400 * updated once the rest is written. The log buf is not certain 1401 * until its done, so at end of file. The patname is in case a 1402 * new zone is created, we know what the options-pattern is */ 1403 if(!diff_read_8(in, &committed) || 1404 !diff_read_32(in, &num_parts) || 1405 !diff_read_64(in, &time_end_0) || 1406 !diff_read_32(in, &time_end_1) || 1407 !diff_read_32(in, &old_serial) || 1408 !diff_read_32(in, &new_serial) || 1409 !diff_read_64(in, &time_start_0) || 1410 !diff_read_32(in, &time_start_1) || 1411 !diff_read_str(in, zone_buf, sizeof(zone_buf)) || 1412 !diff_read_str(in, patname_buf, sizeof(patname_buf))) { 1413 log_msg(LOG_ERR, "diff file bad commit part"); 1414 return 0; 1415 } 1416 1417 /* has been read in completely */ 1418 if(strcmp(zone_buf, domain_to_string(zone->apex)) != 0) { 1419 log_msg(LOG_ERR, "file %s does not match task %s", 1420 zone_buf, domain_to_string(zone->apex)); 1421 return 0; 1422 } 1423 switch(committed) { 1424 case DIFF_NOT_COMMITTED: 1425 log_msg(LOG_ERR, "diff file %s was not committed", zone_buf); 1426 return 0; 1427 case DIFF_CORRUPT: 1428 log_msg(LOG_ERR, "diff file %s was corrupt", zone_buf); 1429 return 0; 1430 case DIFF_INCONSISTENT: 1431 log_msg(LOG_ERR, "diff file %s was inconsistent", zone_buf); 1432 return 0; 1433 case DIFF_VERIFIED: 1434 log_msg(LOG_INFO, "diff file %s already verified", zone_buf); 1435 break; 1436 default: 1437 break; 1438 } 1439 if(num_parts == 0) { 1440 log_msg(LOG_ERR, "diff file %s was not completed", zone_buf); 1441 return 0; 1442 } 1443 if(check_for_bad_serial(nsd->db, zone_buf, old_serial)) { 1444 DEBUG(DEBUG_XFRD,1, (LOG_ERR, 1445 "skipping diff file commit with bad serial")); 1446 return -2; /* Success in "main" process, failure in "xfrd" */ 1447 } 1448 1449 if(!zone->is_skipped) 1450 { 1451 int is_axfr=0, delete_mode=0, rr_count=0, softfail=0; 1452 struct ixfr_store* ixfr_store = NULL, ixfr_store_mem; 1453 1454 DEBUG(DEBUG_XFRD,1, (LOG_INFO, "processing xfr: %s", zone_buf)); 1455 if(zone_is_ixfr_enabled(zone)) 1456 ixfr_store = ixfr_store_start(zone, &ixfr_store_mem); 1457 /* read and apply all of the parts */ 1458 for(i=0; i<num_parts; i++) { 1459 int ret; 1460 DEBUG(DEBUG_XFRD,2, (LOG_INFO, "processing xfr: apply part %d", (int)i)); 1461 ret = apply_ixfr(nsd, in, new_serial, 1462 i, num_parts, &is_axfr, &delete_mode, 1463 &rr_count, zone, 1464 &num_bytes, &softfail, ixfr_store); 1465 if(ret == 0) { 1466 log_msg(LOG_ERR, "bad ixfr packet part %d in diff file for %s", (int)i, zone_buf); 1467 diff_update_commit( 1468 zone_buf, DIFF_CORRUPT, nsd, xfrfilenr); 1469 /* the udb is still dirty, it is bad */ 1470 return -1; /* Fatal! */ 1471 } else if(ret == 2) { 1472 break; 1473 } 1474 } 1475 /* read the final log_str: but do not fail on it */ 1476 if(!diff_read_str(in, log_buf, sizeof(log_buf))) { 1477 log_msg(LOG_ERR, "could not read log for transfer %s", 1478 zone_buf); 1479 snprintf(log_buf, sizeof(log_buf), "error reading log"); 1480 } 1481 #ifdef NSEC3 1482 prehash_zone(nsd->db, zone); 1483 #endif /* NSEC3 */ 1484 zone->is_changed = 1; 1485 zone->is_updated = 1; 1486 zone->is_checked = (committed == DIFF_VERIFIED); 1487 zone->mtime.tv_sec = time_end_0; 1488 zone->mtime.tv_nsec = time_end_1*1000; 1489 if(zone->logstr) 1490 region_recycle(nsd->db->region, zone->logstr, 1491 strlen(zone->logstr)+1); 1492 zone->logstr = region_strdup(nsd->db->region, log_buf); 1493 namedb_zone_free_filenames(nsd->db, zone); 1494 if(softfail && taskudb && !is_axfr) { 1495 log_msg(LOG_ERR, "Failed to apply IXFR cleanly " 1496 "(deletes nonexistent RRs, adds existing RRs). " 1497 "Zone %s contents is different from primary, " 1498 "starting AXFR. Transfer %s", zone_buf, log_buf); 1499 /* add/del failures in IXFR, get an AXFR */ 1500 diff_update_commit( 1501 zone_buf, DIFF_INCONSISTENT, nsd, xfrfilenr); 1502 return -1; /* Fatal! */ 1503 } 1504 if(ixfr_store) 1505 ixfr_store_finish(ixfr_store, nsd, log_buf); 1506 1507 if(1 <= verbosity) { 1508 double elapsed = (double)(time_end_0 - time_start_0)+ 1509 (double)((double)time_end_1 1510 -(double)time_start_1) / 1000000.0; 1511 VERBOSITY(1, (LOG_INFO, "zone %s %s of %"PRIu64" bytes in %g seconds", 1512 zone_buf, log_buf, num_bytes, elapsed)); 1513 } 1514 } 1515 else { 1516 DEBUG(DEBUG_XFRD,1, (LOG_INFO, "skipping xfr: %s", zone_buf)); 1517 } 1518 return 1; 1519 } 1520 1521 static void udb_task_walk_chunk(void* base, void* d, uint64_t s, udb_walk_relptr_cb* cb, void *arg) 1522 { 1523 struct task_list_d* p = (struct task_list_d*)d; 1524 assert(s >= p->size); 1525 (void)s; 1526 (*cb)(base, &p->next, arg); 1527 } 1528 1529 void udb_walkfunc(void* base, void* warg, uint8_t t, void* d, uint64_t s, 1530 udb_walk_relptr_cb* cb, void *arg) 1531 { 1532 (void)warg; 1533 switch(t) { 1534 case udb_chunk_type_task: 1535 udb_task_walk_chunk(base, d, s, cb, arg); 1536 break; 1537 default: 1538 /* no rel ptrs */ 1539 break; 1540 } 1541 } 1542 1543 struct udb_base* task_file_create(const char* file) 1544 { 1545 return udb_base_create_new(file, &udb_walkfunc, NULL); 1546 } 1547 1548 static int 1549 task_create_new_elem(struct udb_base* udb, udb_ptr* last, udb_ptr* e, 1550 size_t sz, const dname_type* zname) 1551 { 1552 if(!udb_ptr_alloc_space(e, udb, udb_chunk_type_task, sz)) { 1553 return 0; 1554 } 1555 if(udb_ptr_is_null(last)) { 1556 udb_base_set_userdata(udb, e->data); 1557 } else { 1558 udb_rptr_set_ptr(&TASKLIST(last)->next, udb, e); 1559 } 1560 udb_ptr_set_ptr(last, udb, e); 1561 1562 /* fill in tasklist item */ 1563 udb_rel_ptr_init(&TASKLIST(e)->next); 1564 TASKLIST(e)->size = sz; 1565 TASKLIST(e)->oldserial = 0; 1566 TASKLIST(e)->newserial = 0; 1567 TASKLIST(e)->yesno = 0; 1568 1569 if(zname) { 1570 memmove(TASKLIST(e)->zname, zname, dname_total_size(zname)); 1571 } 1572 return 1; 1573 } 1574 1575 void task_new_soainfo(struct udb_base* udb, udb_ptr* last, struct zone* z, 1576 enum soainfo_hint hint) 1577 { 1578 /* calculate size */ 1579 udb_ptr e; 1580 size_t sz; 1581 const dname_type* apex, *ns, *em; 1582 if(!z || !z->apex || !domain_dname(z->apex)) 1583 return; /* safety check */ 1584 1585 DEBUG(DEBUG_IPC,1, (LOG_INFO, "nsd: add soa info for zone %s", 1586 domain_to_string(z->apex))); 1587 apex = domain_dname(z->apex); 1588 sz = sizeof(struct task_list_d) + dname_total_size(apex); 1589 if(z->soa_rrset && hint == soainfo_ok) { 1590 ns = domain_dname(rdata_domain_ref(z->soa_rrset->rrs[0])); 1591 em = domain_dname(rdata_domain_ref_offset( 1592 z->soa_rrset->rrs[0], sizeof(void*))); 1593 sz += sizeof(uint32_t)*6 + sizeof(uint8_t)*2 1594 + ns->name_size + em->name_size; 1595 } else { 1596 ns = NULL; 1597 em = NULL; 1598 } 1599 1600 /* create new task_list item */ 1601 if(!task_create_new_elem(udb, last, &e, sz, apex)) { 1602 log_msg(LOG_ERR, "tasklist: out of space, cannot add SOAINFO"); 1603 return; 1604 } 1605 TASKLIST(&e)->task_type = task_soa_info; 1606 TASKLIST(&e)->yesno = (uint64_t)hint; 1607 1608 if(z->soa_rrset && hint == soainfo_ok) { 1609 uint32_t ttl = htonl(z->soa_rrset->rrs[0]->ttl); 1610 uint8_t* p = (uint8_t*)TASKLIST(&e)->zname; 1611 p += dname_total_size(apex); 1612 memmove(p, &ttl, sizeof(uint32_t)); 1613 p += sizeof(uint32_t); 1614 memmove(p, &ns->name_size, sizeof(uint8_t)); 1615 p += sizeof(uint8_t); 1616 memmove(p, dname_name(ns), ns->name_size); 1617 p += ns->name_size; 1618 memmove(p, &em->name_size, sizeof(uint8_t)); 1619 p += sizeof(uint8_t); 1620 memmove(p, dname_name(em), em->name_size); 1621 p += em->name_size; 1622 memmove(p, z->soa_rrset->rrs[0]->rdata + sizeof(void*)*2, 1623 sizeof(uint32_t)*5); 1624 } 1625 udb_ptr_unlink(&e, udb); 1626 } 1627 1628 void task_process_sync(struct udb_base* taskudb) 1629 { 1630 /* need to sync before other process uses the mmap? */ 1631 DEBUG(DEBUG_IPC,1, (LOG_INFO, "task procsync %s size %d", 1632 taskudb->fname, (int)taskudb->base_size)); 1633 (void)taskudb; 1634 } 1635 1636 void task_remap(struct udb_base* taskudb) 1637 { 1638 DEBUG(DEBUG_IPC,1, (LOG_INFO, "task remap %s size %d", 1639 taskudb->fname, (int)taskudb->glob_data->fsize)); 1640 udb_base_remap_process(taskudb); 1641 } 1642 1643 void task_clear(struct udb_base* taskudb) 1644 { 1645 udb_ptr t, n; 1646 udb_ptr_new(&t, taskudb, udb_base_get_userdata(taskudb)); 1647 udb_base_set_userdata(taskudb, 0); 1648 udb_ptr_init(&n, taskudb); 1649 while(!udb_ptr_is_null(&t)) { 1650 udb_ptr_set_rptr(&n, taskudb, &TASKLIST(&t)->next); 1651 udb_rptr_zero(&TASKLIST(&t)->next, taskudb); 1652 udb_ptr_free_space(&t, taskudb, TASKLIST(&t)->size); 1653 udb_ptr_set_ptr(&t, taskudb, &n); 1654 } 1655 udb_ptr_unlink(&t, taskudb); 1656 udb_ptr_unlink(&n, taskudb); 1657 } 1658 1659 void task_new_expire(struct udb_base* udb, udb_ptr* last, 1660 const struct dname* z, int expired) 1661 { 1662 udb_ptr e; 1663 if(!z) return; 1664 DEBUG(DEBUG_IPC,1, (LOG_INFO, "add expire info for zone %s", 1665 dname_to_string(z,NULL))); 1666 if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d)+ 1667 dname_total_size(z), z)) { 1668 log_msg(LOG_ERR, "tasklist: out of space, cannot add expire"); 1669 return; 1670 } 1671 TASKLIST(&e)->task_type = task_expire; 1672 TASKLIST(&e)->yesno = expired; 1673 udb_ptr_unlink(&e, udb); 1674 } 1675 1676 void task_new_check_zonefiles(udb_base* udb, udb_ptr* last, 1677 const dname_type* zone) 1678 { 1679 udb_ptr e; 1680 xfrd_check_catalog_consumer_zonefiles(zone); 1681 DEBUG(DEBUG_IPC,1, (LOG_INFO, "add task checkzonefiles")); 1682 if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d) + 1683 (zone?dname_total_size(zone):0), zone)) { 1684 log_msg(LOG_ERR, "tasklist: out of space, cannot add check_zones"); 1685 return; 1686 } 1687 TASKLIST(&e)->task_type = task_check_zonefiles; 1688 TASKLIST(&e)->yesno = (zone!=NULL); 1689 udb_ptr_unlink(&e, udb); 1690 } 1691 1692 void task_new_write_zonefiles(udb_base* udb, udb_ptr* last, 1693 const dname_type* zone) 1694 { 1695 udb_ptr e; 1696 DEBUG(DEBUG_IPC,1, (LOG_INFO, "add task writezonefiles")); 1697 if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d) + 1698 (zone?dname_total_size(zone):0), zone)) { 1699 log_msg(LOG_ERR, "tasklist: out of space, cannot add writezones"); 1700 return; 1701 } 1702 TASKLIST(&e)->task_type = task_write_zonefiles; 1703 TASKLIST(&e)->yesno = (zone!=NULL); 1704 udb_ptr_unlink(&e, udb); 1705 } 1706 1707 void task_new_set_verbosity(udb_base* udb, udb_ptr* last, int v) 1708 { 1709 udb_ptr e; 1710 DEBUG(DEBUG_IPC,1, (LOG_INFO, "add task set_verbosity")); 1711 if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d), 1712 NULL)) { 1713 log_msg(LOG_ERR, "tasklist: out of space, cannot add set_v"); 1714 return; 1715 } 1716 TASKLIST(&e)->task_type = task_set_verbosity; 1717 TASKLIST(&e)->yesno = v; 1718 udb_ptr_unlink(&e, udb); 1719 } 1720 1721 void 1722 task_new_add_zone(udb_base* udb, udb_ptr* last, const char* zone, 1723 const char* pattern, unsigned zonestatid) 1724 { 1725 size_t zlen = strlen(zone); 1726 size_t plen = strlen(pattern); 1727 void *p; 1728 udb_ptr e; 1729 DEBUG(DEBUG_IPC,1, (LOG_INFO, "add task addzone %s %s", zone, pattern)); 1730 if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d)+ 1731 zlen + 1 + plen + 1, NULL)) { 1732 log_msg(LOG_ERR, "tasklist: out of space, cannot add addz"); 1733 return; 1734 } 1735 TASKLIST(&e)->task_type = task_add_zone; 1736 TASKLIST(&e)->yesno = zonestatid; 1737 p = TASKLIST(&e)->zname; 1738 memcpy(p, zone, zlen+1); 1739 memmove((char*)p+zlen+1, pattern, plen+1); 1740 udb_ptr_unlink(&e, udb); 1741 } 1742 1743 void 1744 task_new_del_zone(udb_base* udb, udb_ptr* last, const dname_type* dname) 1745 { 1746 udb_ptr e; 1747 DEBUG(DEBUG_IPC,1, (LOG_INFO, "add task delzone %s", dname_to_string(dname, 0))); 1748 if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d) 1749 +dname_total_size(dname), dname)) { 1750 log_msg(LOG_ERR, "tasklist: out of space, cannot add delz"); 1751 return; 1752 } 1753 TASKLIST(&e)->task_type = task_del_zone; 1754 udb_ptr_unlink(&e, udb); 1755 } 1756 1757 void task_new_add_key(udb_base* udb, udb_ptr* last, struct key_options* key) 1758 { 1759 char* p; 1760 udb_ptr e; 1761 assert(key->name && key->algorithm && key->secret); 1762 DEBUG(DEBUG_IPC,1, (LOG_INFO, "add task addkey")); 1763 if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d) 1764 +strlen(key->name)+1+strlen(key->algorithm)+1+ 1765 strlen(key->secret)+1, NULL)) { 1766 log_msg(LOG_ERR, "tasklist: out of space, cannot add addk"); 1767 return; 1768 } 1769 TASKLIST(&e)->task_type = task_add_key; 1770 p = (char*)TASKLIST(&e)->zname; 1771 memmove(p, key->name, strlen(key->name)+1); 1772 p+=strlen(key->name)+1; 1773 memmove(p, key->algorithm, strlen(key->algorithm)+1); 1774 p+=strlen(key->algorithm)+1; 1775 memmove(p, key->secret, strlen(key->secret)+1); 1776 udb_ptr_unlink(&e, udb); 1777 } 1778 1779 void task_new_del_key(udb_base* udb, udb_ptr* last, const char* name) 1780 { 1781 char* p; 1782 udb_ptr e; 1783 DEBUG(DEBUG_IPC,1, (LOG_INFO, "add task delkey")); 1784 if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d) 1785 +strlen(name)+1, NULL)) { 1786 log_msg(LOG_ERR, "tasklist: out of space, cannot add delk"); 1787 return; 1788 } 1789 TASKLIST(&e)->task_type = task_del_key; 1790 p = (char*)TASKLIST(&e)->zname; 1791 memmove(p, name, strlen(name)+1); 1792 udb_ptr_unlink(&e, udb); 1793 } 1794 1795 void task_new_cookies(udb_base* udb, udb_ptr* last, int answer_cookie, 1796 size_t cookie_count, void* cookie_secrets) { 1797 udb_ptr e; 1798 char* p; 1799 size_t const secrets_size = sizeof(cookie_secrets_type); 1800 1801 DEBUG(DEBUG_IPC, 1, (LOG_INFO, "add task cookies")); 1802 1803 if(!task_create_new_elem(udb, last, &e, 1804 sizeof(struct task_list_d) + secrets_size, NULL)) { 1805 log_msg(LOG_ERR, "tasklist: out of space, cannot add cookies"); 1806 return; 1807 } 1808 TASKLIST(&e)->task_type = task_cookies; 1809 TASKLIST(&e)->newserial = (uint32_t) answer_cookie; 1810 TASKLIST(&e)->yesno = (uint64_t) cookie_count; 1811 p = (char*)TASKLIST(&e)->zname; 1812 memmove(p, cookie_secrets, secrets_size); 1813 1814 udb_ptr_unlink(&e, udb); 1815 } 1816 1817 void task_new_add_pattern(udb_base* udb, udb_ptr* last, 1818 struct pattern_options* p) 1819 { 1820 region_type* temp; 1821 buffer_type* buffer; 1822 udb_ptr e; 1823 DEBUG(DEBUG_IPC,1, (LOG_INFO, "add task addpattern %s", p->pname)); 1824 temp = region_create(xalloc, free); 1825 buffer = buffer_create(temp, 4096); 1826 pattern_options_marshal(buffer, p); 1827 buffer_flip(buffer); 1828 if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d) 1829 + buffer_limit(buffer), NULL)) { 1830 log_msg(LOG_ERR, "tasklist: out of space, cannot add addp"); 1831 region_destroy(temp); 1832 return; 1833 } 1834 TASKLIST(&e)->task_type = task_add_pattern; 1835 TASKLIST(&e)->yesno = buffer_limit(buffer); 1836 memmove(TASKLIST(&e)->zname, buffer_begin(buffer), 1837 buffer_limit(buffer)); 1838 udb_ptr_unlink(&e, udb); 1839 region_destroy(temp); 1840 } 1841 1842 void task_new_del_pattern(udb_base* udb, udb_ptr* last, const char* name) 1843 { 1844 char* p; 1845 udb_ptr e; 1846 DEBUG(DEBUG_IPC,1, (LOG_INFO, "add task delpattern %s", name)); 1847 if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d) 1848 +strlen(name)+1, NULL)) { 1849 log_msg(LOG_ERR, "tasklist: out of space, cannot add delp"); 1850 return; 1851 } 1852 TASKLIST(&e)->task_type = task_del_pattern; 1853 p = (char*)TASKLIST(&e)->zname; 1854 memmove(p, name, strlen(name)+1); 1855 udb_ptr_unlink(&e, udb); 1856 } 1857 1858 void task_new_opt_change(udb_base* udb, udb_ptr* last, struct nsd_options* opt) 1859 { 1860 udb_ptr e; 1861 DEBUG(DEBUG_IPC,1, (LOG_INFO, "add task opt_change")); 1862 if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d), 1863 NULL)) { 1864 log_msg(LOG_ERR, "tasklist: out of space, cannot add o_c"); 1865 return; 1866 } 1867 TASKLIST(&e)->task_type = task_opt_change; 1868 #ifdef RATELIMIT 1869 TASKLIST(&e)->oldserial = opt->rrl_ratelimit; 1870 TASKLIST(&e)->newserial = opt->rrl_whitelist_ratelimit; 1871 TASKLIST(&e)->yesno = (uint64_t) opt->rrl_slip; 1872 #else 1873 (void)opt; 1874 #endif 1875 udb_ptr_unlink(&e, udb); 1876 } 1877 1878 void task_new_zonestat_inc(udb_base* udb, udb_ptr* last, unsigned sz) 1879 { 1880 udb_ptr e; 1881 DEBUG(DEBUG_IPC,1, (LOG_INFO, "add task zonestat_inc")); 1882 if(sz == 0) 1883 return; /* no need to decrease to 0 */ 1884 if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d), 1885 NULL)) { 1886 log_msg(LOG_ERR, "tasklist: out of space, cannot add z_i"); 1887 return; 1888 } 1889 TASKLIST(&e)->task_type = task_zonestat_inc; 1890 TASKLIST(&e)->oldserial = (uint32_t)sz; 1891 udb_ptr_unlink(&e, udb); 1892 } 1893 1894 int 1895 task_new_apply_xfr(udb_base* udb, udb_ptr* last, const dname_type* dname, 1896 uint32_t old_serial, uint32_t new_serial, uint64_t filenumber) 1897 { 1898 udb_ptr e; 1899 DEBUG(DEBUG_IPC,1, (LOG_INFO, "add task apply_xfr")); 1900 if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d) 1901 +dname_total_size(dname), dname)) { 1902 log_msg(LOG_ERR, "tasklist: out of space, cannot add applyxfr"); 1903 return 0; 1904 } 1905 TASKLIST(&e)->oldserial = old_serial; 1906 TASKLIST(&e)->newserial = new_serial; 1907 TASKLIST(&e)->yesno = filenumber; 1908 TASKLIST(&e)->task_type = task_apply_xfr; 1909 udb_ptr_unlink(&e, udb); 1910 return 1; 1911 } 1912 1913 void 1914 task_process_expire(namedb_type* db, struct task_list_d* task) 1915 { 1916 uint8_t ok; 1917 zone_type* z = namedb_find_zone(db, task->zname); 1918 assert(task->task_type == task_expire); 1919 if(!z) { 1920 DEBUG(DEBUG_IPC, 1, (LOG_WARNING, "zone %s %s but not in zonetree", 1921 dname_to_string(task->zname, NULL), 1922 task->yesno?"expired":"unexpired")); 1923 return; 1924 } 1925 DEBUG(DEBUG_IPC,1, (LOG_INFO, "xfrd: expire task zone %s %s", 1926 dname_to_string(task->zname,0), 1927 task->yesno?"expired":"unexpired")); 1928 /* find zone, set expire flag */ 1929 ok = !task->yesno; 1930 /* only update zone->is_ok if needed to minimize copy-on-write 1931 * of memory pages shared after fork() */ 1932 if(ok && !z->is_ok) 1933 z->is_ok = 1; 1934 else if(!ok && z->is_ok) 1935 z->is_ok = 0; 1936 } 1937 1938 static void 1939 task_process_set_verbosity(struct task_list_d* task) 1940 { 1941 DEBUG(DEBUG_IPC,1, (LOG_INFO, "verbosity task %d", (int)task->yesno)); 1942 verbosity = task->yesno; 1943 } 1944 1945 static void 1946 task_process_checkzones(struct nsd* nsd, udb_base* taskudb, udb_ptr* last_task, 1947 struct task_list_d* task) 1948 { 1949 /* on SIGHUP check if zone-text-files changed and if so, 1950 * reread. When from xfrd-reload, no need to fstat the files */ 1951 if(task->yesno) { 1952 struct zone_options* zo = zone_options_find(nsd->options, 1953 task->zname); 1954 if(zo) 1955 namedb_check_zonefile(nsd, taskudb, last_task, zo); 1956 } else { 1957 /* check all zones */ 1958 namedb_check_zonefiles(nsd, nsd->options, taskudb, last_task); 1959 } 1960 } 1961 1962 static void 1963 task_process_writezones(struct nsd* nsd, struct task_list_d* task) 1964 { 1965 if(task->yesno) { 1966 struct zone_options* zo = zone_options_find(nsd->options, 1967 task->zname); 1968 if(zo) 1969 namedb_write_zonefile(nsd, zo); 1970 } else { 1971 namedb_write_zonefiles(nsd, nsd->options); 1972 } 1973 } 1974 1975 static void 1976 task_process_add_zone(struct nsd* nsd, udb_base* udb, udb_ptr* last_task, 1977 struct task_list_d* task) 1978 { 1979 zone_type* z; 1980 const dname_type* zdname; 1981 const char* zname = (const char*)task->zname; 1982 const char* pname = zname + strlen(zname)+1; 1983 DEBUG(DEBUG_IPC,1, (LOG_INFO, "addzone task %s %s", zname, pname)); 1984 zdname = dname_parse(nsd->db->region, zname); 1985 if(!zdname) { 1986 log_msg(LOG_ERR, "can not parse zone name %s", zname); 1987 return; 1988 } 1989 /* create zone */ 1990 z = find_or_create_zone(nsd->db, zdname, nsd->options, zname, pname); 1991 if(!z) { 1992 region_recycle(nsd->db->region, (void*)zdname, 1993 dname_total_size(zdname)); 1994 log_msg(LOG_ERR, "can not add zone %s %s", zname, pname); 1995 return; 1996 } 1997 /* zdname is not used by the zone allocation. */ 1998 region_recycle(nsd->db->region, (void*)zdname, 1999 dname_total_size(zdname)); 2000 z->zonestatid = (unsigned)task->yesno; 2001 /* if zone is empty, attempt to read the zonefile from disk (if any) */ 2002 if(!z->soa_rrset && z->opts->pattern->zonefile) { 2003 namedb_read_zonefile(nsd, z, udb, last_task); 2004 } 2005 } 2006 2007 static void 2008 task_process_del_zone(struct nsd* nsd, struct task_list_d* task) 2009 { 2010 zone_type* zone; 2011 struct zone_options* zopt; 2012 DEBUG(DEBUG_IPC,1, (LOG_INFO, "delzone task %s", dname_to_string( 2013 task->zname, NULL))); 2014 zone = namedb_find_zone(nsd->db, task->zname); 2015 if(!zone) 2016 return; 2017 2018 #ifdef NSEC3 2019 nsec3_clear_precompile(nsd->db, zone); 2020 zone->nsec3_param = NULL; 2021 #endif 2022 delete_zone_rrs(nsd->db, zone); 2023 2024 /* remove from zonetree, apex, soa */ 2025 zopt = zone->opts; 2026 namedb_zone_delete(nsd->db, zone); 2027 /* remove from options (zone_list already edited by xfrd) */ 2028 zone_options_delete(nsd->options, zopt); 2029 } 2030 2031 static void 2032 task_process_add_key(struct nsd* nsd, struct task_list_d* task) 2033 { 2034 struct key_options key; 2035 key.name = (char*)task->zname; 2036 DEBUG(DEBUG_IPC,1, (LOG_INFO, "addkey task %s", key.name)); 2037 key.algorithm = key.name + strlen(key.name)+1; 2038 key.secret = key.algorithm + strlen(key.algorithm)+1; 2039 key_options_add_modify(nsd->options, &key); 2040 memset(key.secret, 0xdd, strlen(key.secret)); /* wipe secret */ 2041 } 2042 2043 static void 2044 task_process_del_key(struct nsd* nsd, struct task_list_d* task) 2045 { 2046 char* name = (char*)task->zname; 2047 DEBUG(DEBUG_IPC,1, (LOG_INFO, "delkey task %s", name)); 2048 /* this is reload and nothing is using the TSIG key right now */ 2049 key_options_remove(nsd->options, name); 2050 } 2051 2052 static void 2053 task_process_cookies(struct nsd* nsd, struct task_list_d* task) { 2054 DEBUG(DEBUG_IPC, 1, (LOG_INFO, "cookies task answer: %s, count: %d", 2055 task->newserial ? "yes" : "no", (int)task->yesno)); 2056 2057 nsd->do_answer_cookie = (int) task->newserial; 2058 nsd->cookie_count = (size_t) task->yesno; 2059 memmove(nsd->cookie_secrets, task->zname, sizeof(nsd->cookie_secrets)); 2060 explicit_bzero(task->zname, sizeof(nsd->cookie_secrets)); 2061 } 2062 2063 static void 2064 task_process_add_pattern(struct nsd* nsd, struct task_list_d* task) 2065 { 2066 region_type* temp = region_create(xalloc, free); 2067 buffer_type buffer; 2068 struct pattern_options *pat; 2069 buffer_create_from(&buffer, task->zname, task->yesno); 2070 pat = pattern_options_unmarshal(temp, &buffer); 2071 DEBUG(DEBUG_IPC,1, (LOG_INFO, "addpattern task %s", pat->pname)); 2072 pattern_options_add_modify(nsd->options, pat); 2073 region_destroy(temp); 2074 } 2075 2076 static void 2077 task_process_del_pattern(struct nsd* nsd, struct task_list_d* task) 2078 { 2079 char* name = (char*)task->zname; 2080 DEBUG(DEBUG_IPC,1, (LOG_INFO, "delpattern task %s", name)); 2081 pattern_options_remove(nsd->options, name); 2082 } 2083 2084 static void 2085 task_process_opt_change(struct nsd* nsd, struct task_list_d* task) 2086 { 2087 DEBUG(DEBUG_IPC,1, (LOG_INFO, "optchange task")); 2088 #ifdef RATELIMIT 2089 nsd->options->rrl_ratelimit = task->oldserial; 2090 nsd->options->rrl_whitelist_ratelimit = task->newserial; 2091 nsd->options->rrl_slip = task->yesno; 2092 rrl_set_limit(nsd->options->rrl_ratelimit, nsd->options->rrl_whitelist_ratelimit, 2093 nsd->options->rrl_slip); 2094 #else 2095 (void)nsd; (void)task; 2096 #endif 2097 } 2098 2099 #ifdef USE_ZONE_STATS 2100 static void 2101 task_process_zonestat_inc(struct nsd* nsd, udb_base* udb, udb_ptr *last_task, 2102 struct task_list_d* task) 2103 { 2104 DEBUG(DEBUG_IPC,1, (LOG_INFO, "zonestat_inc task %u", (unsigned)task->oldserial)); 2105 nsd->zonestatdesired = (unsigned)task->oldserial; 2106 /* send echo to xfrd to increment on its end */ 2107 task_new_zonestat_inc(udb, last_task, nsd->zonestatdesired); 2108 } 2109 #endif 2110 2111 void 2112 task_process_apply_xfr(struct nsd* nsd, udb_base* udb, udb_ptr* task) 2113 { 2114 /* we have to use an udb_ptr task here, because the apply_xfr procedure 2115 * appends soa_info which may remap and change the pointer. */ 2116 zone_type* zone; 2117 FILE* df; 2118 DEBUG(DEBUG_IPC,1, (LOG_INFO, "applyxfr task %s", dname_to_string( 2119 TASKLIST(task)->zname, NULL))); 2120 zone = namedb_find_zone(nsd->db, TASKLIST(task)->zname); 2121 if(!zone) { 2122 /* assume the zone has been deleted and a zone transfer was 2123 * still waiting to be processed */ 2124 udb_ptr_free_space(task, udb, TASKLIST(task)->size); 2125 return; 2126 } 2127 2128 /* apply the XFR */ 2129 /* oldserial, newserial, yesno is filenumber */ 2130 df = xfrd_open_xfrfile(nsd, TASKLIST(task)->yesno, "r"); 2131 if(!df) { 2132 /* could not open file to update */ 2133 /* soainfo_gone will be communicated from server_reload, unless 2134 preceding updates have been applied */ 2135 zone->is_skipped = 1; 2136 udb_ptr_free_space(task, udb, TASKLIST(task)->size); 2137 return; 2138 } 2139 /* read and apply zone transfer */ 2140 switch(apply_ixfr_for_zone(nsd, zone, df, nsd->options, udb, 2141 TASKLIST(task)->yesno)) { 2142 case 1: /* Success */ 2143 break; 2144 2145 case 0: /* Failure */ 2146 /* soainfo_gone will be communicated from server_reload, unless 2147 preceding updates have been applied */ 2148 zone->is_skipped = 1; 2149 break; 2150 2151 case -1:/* Fatal */ 2152 exit(1); 2153 break; 2154 2155 default:break; 2156 } 2157 fclose(df); 2158 udb_ptr_free_space(task, udb, TASKLIST(task)->size); 2159 } 2160 2161 2162 void task_process_in_reload(struct nsd* nsd, udb_base* udb, udb_ptr *last_task, 2163 udb_ptr* task) 2164 { 2165 switch(TASKLIST(task)->task_type) { 2166 case task_expire: 2167 task_process_expire(nsd->db, TASKLIST(task)); 2168 break; 2169 case task_check_zonefiles: 2170 task_process_checkzones(nsd, udb, last_task, TASKLIST(task)); 2171 break; 2172 case task_write_zonefiles: 2173 task_process_writezones(nsd, TASKLIST(task)); 2174 break; 2175 case task_set_verbosity: 2176 task_process_set_verbosity(TASKLIST(task)); 2177 break; 2178 case task_add_zone: 2179 task_process_add_zone(nsd, udb, last_task, TASKLIST(task)); 2180 break; 2181 case task_del_zone: 2182 task_process_del_zone(nsd, TASKLIST(task)); 2183 break; 2184 case task_add_key: 2185 task_process_add_key(nsd, TASKLIST(task)); 2186 break; 2187 case task_del_key: 2188 task_process_del_key(nsd, TASKLIST(task)); 2189 break; 2190 case task_add_pattern: 2191 task_process_add_pattern(nsd, TASKLIST(task)); 2192 break; 2193 case task_del_pattern: 2194 task_process_del_pattern(nsd, TASKLIST(task)); 2195 break; 2196 case task_opt_change: 2197 task_process_opt_change(nsd, TASKLIST(task)); 2198 break; 2199 #ifdef USE_ZONE_STATS 2200 case task_zonestat_inc: 2201 task_process_zonestat_inc(nsd, udb, last_task, TASKLIST(task)); 2202 break; 2203 #endif 2204 case task_cookies: 2205 task_process_cookies(nsd, TASKLIST(task)); 2206 break; 2207 default: 2208 log_msg(LOG_WARNING, "unhandled task in reload type %d", 2209 (int)TASKLIST(task)->task_type); 2210 break; 2211 } 2212 udb_ptr_free_space(task, udb, TASKLIST(task)->size); 2213 } 2214