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