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