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