1 /* 2 * util.c -- set of various support routines. 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 12 #include <assert.h> 13 #include <ctype.h> 14 #include <errno.h> 15 #include <stdarg.h> 16 #include <stdio.h> 17 #include <stdlib.h> 18 #include <string.h> 19 #ifdef HAVE_SCHED_H 20 #include <sched.h> 21 #endif /* HAVE_SCHED_H */ 22 #ifdef HAVE_SYS_CPUSET_H 23 #include <sys/cpuset.h> 24 #endif /* HAVE_SYS_CPUSET_H */ 25 #ifdef HAVE_SYSLOG_H 26 #include <syslog.h> 27 #endif /* HAVE_SYSLOG_H */ 28 #include <unistd.h> 29 #ifdef HAVE_SYS_RANDOM_H 30 #include <sys/random.h> 31 #endif 32 33 #include "util.h" 34 #include "region-allocator.h" 35 #include "dname.h" 36 #include "namedb.h" 37 #include "rdata.h" 38 #include "zonec.h" 39 40 #ifdef USE_MMAP_ALLOC 41 #include <sys/mman.h> 42 43 #if defined(MAP_ANON) && !defined(MAP_ANONYMOUS) 44 #define MAP_ANONYMOUS MAP_ANON 45 #elif defined(MAP_ANONYMOUS) && !defined(MAP_ANON) 46 #define MAP_ANON MAP_ANONYMOUS 47 #endif 48 49 #endif /* USE_MMAP_ALLOC */ 50 51 #ifndef NDEBUG 52 unsigned nsd_debug_facilities = 0xffff; 53 int nsd_debug_level = 0; 54 #endif 55 56 #define MSB_32 0x80000000 57 58 int verbosity = 0; 59 60 static const char *global_ident = NULL; 61 static log_function_type *current_log_function = log_file; 62 static FILE *current_log_file = NULL; 63 int log_time_asc = 1; 64 65 void 66 log_init(const char *ident) 67 { 68 global_ident = ident; 69 current_log_file = stderr; 70 } 71 72 void 73 log_open(int option, int facility, const char *filename) 74 { 75 #ifdef HAVE_SYSLOG_H 76 openlog(global_ident, option, facility); 77 #endif /* HAVE_SYSLOG_H */ 78 if (filename) { 79 FILE *file = fopen(filename, "a"); 80 if (!file) { 81 log_msg(LOG_ERR, "Cannot open %s for appending (%s), " 82 "logging to stderr", 83 filename, strerror(errno)); 84 } else { 85 current_log_file = file; 86 } 87 } 88 } 89 90 void 91 log_reopen(const char *filename, uint8_t verbose) 92 { 93 if (filename) { 94 FILE *file; 95 if(strcmp(filename, "/dev/stdout")==0 || strcmp(filename, "/dev/stderr")==0) 96 return; 97 file = fopen(filename, "a"); 98 if (!file) { 99 if (verbose) 100 VERBOSITY(2, (LOG_WARNING, 101 "Cannot reopen %s for appending (%s), " 102 "keeping old logfile", 103 filename, strerror(errno))); 104 } else { 105 if (current_log_file && current_log_file != stderr) 106 fclose(current_log_file); 107 current_log_file = file; 108 } 109 } 110 } 111 112 void 113 log_finalize(void) 114 { 115 #ifdef HAVE_SYSLOG_H 116 closelog(); 117 #endif /* HAVE_SYSLOG_H */ 118 if (current_log_file && current_log_file != stderr) { 119 fclose(current_log_file); 120 } 121 current_log_file = NULL; 122 } 123 124 static lookup_table_type log_priority_table[] = { 125 { LOG_ERR, "error" }, 126 { LOG_WARNING, "warning" }, 127 { LOG_NOTICE, "notice" }, 128 { LOG_INFO, "info" }, 129 { 0, NULL } 130 }; 131 132 void 133 log_file(int priority, const char *message) 134 { 135 size_t length; 136 lookup_table_type *priority_info; 137 const char *priority_text = "unknown"; 138 139 assert(global_ident); 140 assert(current_log_file); 141 142 priority_info = lookup_by_id(log_priority_table, priority); 143 if (priority_info) { 144 priority_text = priority_info->name; 145 } 146 147 /* Bug #104, add time_t timestamp */ 148 #if defined(HAVE_STRFTIME) && defined(HAVE_LOCALTIME_R) 149 if(log_time_asc) { 150 struct timeval tv; 151 char tmbuf[32]; 152 tmbuf[0]=0; 153 tv.tv_usec = 0; 154 if(gettimeofday(&tv, NULL) == 0) { 155 struct tm tm; 156 time_t now = (time_t)tv.tv_sec; 157 strftime(tmbuf, sizeof(tmbuf), "%Y-%m-%d %H:%M:%S", 158 localtime_r(&now, &tm)); 159 } 160 fprintf(current_log_file, "[%s.%3.3d] %s[%d]: %s: %s", 161 tmbuf, (int)tv.tv_usec/1000, 162 global_ident, (int) getpid(), priority_text, message); 163 } else 164 #endif /* have time functions */ 165 fprintf(current_log_file, "[%d] %s[%d]: %s: %s", 166 (int)time(NULL), global_ident, (int) getpid(), priority_text, message); 167 length = strlen(message); 168 if (length == 0 || message[length - 1] != '\n') { 169 fprintf(current_log_file, "\n"); 170 } 171 fflush(current_log_file); 172 } 173 174 void 175 log_syslog(int priority, const char *message) 176 { 177 #ifdef HAVE_SYSLOG_H 178 syslog(priority, "%s", message); 179 #endif /* !HAVE_SYSLOG_H */ 180 log_file(priority, message); 181 } 182 183 void 184 log_only_syslog(int priority, const char *message) 185 { 186 #ifdef HAVE_SYSLOG_H 187 syslog(priority, "%s", message); 188 #else /* !HAVE_SYSLOG_H */ 189 /* no syslog, use stderr */ 190 log_file(priority, message); 191 #endif 192 } 193 194 void 195 log_set_log_function(log_function_type *log_function) 196 { 197 current_log_function = log_function; 198 } 199 200 void 201 log_msg(int priority, const char *format, ...) 202 { 203 va_list args; 204 va_start(args, format); 205 log_vmsg(priority, format, args); 206 va_end(args); 207 } 208 209 void 210 log_vmsg(int priority, const char *format, va_list args) 211 { 212 char message[MAXSYSLOGMSGLEN]; 213 vsnprintf(message, sizeof(message), format, args); 214 current_log_function(priority, message); 215 } 216 217 void 218 set_bit(uint8_t bits[], size_t index) 219 { 220 /* 221 * The bits are counted from left to right, so bit #0 is the 222 * left most bit. 223 */ 224 bits[index / 8] |= (1 << (7 - index % 8)); 225 } 226 227 void 228 clear_bit(uint8_t bits[], size_t index) 229 { 230 /* 231 * The bits are counted from left to right, so bit #0 is the 232 * left most bit. 233 */ 234 bits[index / 8] &= ~(1 << (7 - index % 8)); 235 } 236 237 int 238 get_bit(uint8_t bits[], size_t index) 239 { 240 /* 241 * The bits are counted from left to right, so bit #0 is the 242 * left most bit. 243 */ 244 return bits[index / 8] & (1 << (7 - index % 8)); 245 } 246 247 lookup_table_type * 248 lookup_by_name(lookup_table_type *table, const char *name) 249 { 250 while (table->name != NULL) { 251 if (strcasecmp(name, table->name) == 0) 252 return table; 253 table++; 254 } 255 return NULL; 256 } 257 258 lookup_table_type * 259 lookup_by_id(lookup_table_type *table, int id) 260 { 261 while (table->name != NULL) { 262 if (table->id == id) 263 return table; 264 table++; 265 } 266 return NULL; 267 } 268 269 char * 270 xstrdup(const char *src) 271 { 272 char *result = strdup(src); 273 274 if(!result) { 275 log_msg(LOG_ERR, "strdup failed: %s", strerror(errno)); 276 exit(1); 277 } 278 279 return result; 280 } 281 282 void * 283 xalloc(size_t size) 284 { 285 void *result = malloc(size); 286 287 if (!result) { 288 log_msg(LOG_ERR, "malloc failed: %s", strerror(errno)); 289 exit(1); 290 } 291 return result; 292 } 293 294 void * 295 xmallocarray(size_t num, size_t size) 296 { 297 void *result = reallocarray(NULL, num, size); 298 299 if (!result) { 300 log_msg(LOG_ERR, "reallocarray failed: %s", strerror(errno)); 301 exit(1); 302 } 303 return result; 304 } 305 306 void * 307 xalloc_zero(size_t size) 308 { 309 void *result = calloc(1, size); 310 if (!result) { 311 log_msg(LOG_ERR, "calloc failed: %s", strerror(errno)); 312 exit(1); 313 } 314 return result; 315 } 316 317 void * 318 xalloc_array_zero(size_t num, size_t size) 319 { 320 void *result = calloc(num, size); 321 if (!result) { 322 log_msg(LOG_ERR, "calloc failed: %s", strerror(errno)); 323 exit(1); 324 } 325 return result; 326 } 327 328 void * 329 xrealloc(void *ptr, size_t size) 330 { 331 ptr = realloc(ptr, size); 332 if (!ptr) { 333 log_msg(LOG_ERR, "realloc failed: %s", strerror(errno)); 334 exit(1); 335 } 336 return ptr; 337 } 338 339 #ifdef USE_MMAP_ALLOC 340 341 void * 342 mmap_alloc(size_t size) 343 { 344 void *base; 345 346 size += MMAP_ALLOC_HEADER_SIZE; 347 #ifdef HAVE_MMAP 348 base = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 349 if (base == MAP_FAILED) { 350 log_msg(LOG_ERR, "mmap failed: %s", strerror(errno)); 351 exit(1); 352 } 353 #else /* !HAVE_MMAP */ 354 log_msg(LOG_ERR, "mmap failed: don't have mmap"); 355 exit(1); 356 #endif /* HAVE_MMAP */ 357 358 *((size_t*) base) = size; 359 return (void*)((uintptr_t)base + MMAP_ALLOC_HEADER_SIZE); 360 } 361 362 363 void 364 mmap_free(void *ptr) 365 { 366 void *base; 367 size_t size; 368 369 if (!ptr) return; 370 371 base = (void*)((uintptr_t)ptr - MMAP_ALLOC_HEADER_SIZE); 372 size = *((size_t*) base); 373 374 #ifdef HAVE_MUNMAP 375 if (munmap(base, size) == -1) { 376 log_msg(LOG_ERR, "munmap failed: %s", strerror(errno)); 377 exit(1); 378 } 379 #else /* !HAVE_MUNMAP */ 380 log_msg(LOG_ERR, "munmap failed: don't have munmap"); 381 exit(1); 382 #endif /* HAVE_MUNMAP */ 383 } 384 385 #endif /* USE_MMAP_ALLOC */ 386 387 int 388 write_data(FILE *file, const void *data, size_t size) 389 { 390 size_t result; 391 392 if (size == 0) 393 return 1; 394 395 result = fwrite(data, 1, size, file); 396 397 if (result == 0) { 398 log_msg(LOG_ERR, "write failed: %s", strerror(errno)); 399 return 0; 400 } else if (result < size) { 401 log_msg(LOG_ERR, "short write (disk full?)"); 402 return 0; 403 } else { 404 return 1; 405 } 406 } 407 408 int 409 write_socket(int s, const void *buf, size_t size) 410 { 411 const char* data = (const char*)buf; 412 size_t total_count = 0; 413 414 while (total_count < size) { 415 ssize_t count 416 = write(s, data + total_count, size - total_count); 417 if (count == -1) { 418 if (errno != EAGAIN && errno != EINTR) { 419 return 0; 420 } else { 421 continue; 422 } 423 } 424 total_count += count; 425 } 426 return 1; 427 } 428 429 void get_time(struct timespec* t) 430 { 431 struct timeval tv; 432 #ifdef HAVE_CLOCK_GETTIME 433 /* first try nanosecond precision */ 434 if(clock_gettime(CLOCK_REALTIME, t)>=0) { 435 return; /* success */ 436 } 437 log_msg(LOG_ERR, "clock_gettime: %s", strerror(errno)); 438 #endif 439 /* try millisecond precision */ 440 if(gettimeofday(&tv, NULL)>=0) { 441 t->tv_sec = tv.tv_sec; 442 t->tv_nsec = tv.tv_usec*1000; 443 return; /* success */ 444 } 445 log_msg(LOG_ERR, "gettimeofday: %s", strerror(errno)); 446 /* whole seconds precision */ 447 t->tv_sec = time(0); 448 t->tv_nsec = 0; 449 } 450 451 int 452 timespec_compare(const struct timespec *left, 453 const struct timespec *right) 454 { 455 /* Compare seconds. */ 456 if (left->tv_sec < right->tv_sec) { 457 return -1; 458 } else if (left->tv_sec > right->tv_sec) { 459 return 1; 460 } else { 461 /* Seconds are equal, compare nanoseconds. */ 462 if (left->tv_nsec < right->tv_nsec) { 463 return -1; 464 } else if (left->tv_nsec > right->tv_nsec) { 465 return 1; 466 } else { 467 return 0; 468 } 469 } 470 } 471 472 473 /* One second is 1e9 nanoseconds. */ 474 #define NANOSECONDS_PER_SECOND 1000000000L 475 476 void 477 timespec_add(struct timespec *left, 478 const struct timespec *right) 479 { 480 left->tv_sec += right->tv_sec; 481 left->tv_nsec += right->tv_nsec; 482 if (left->tv_nsec >= NANOSECONDS_PER_SECOND) { 483 /* Carry. */ 484 ++left->tv_sec; 485 left->tv_nsec -= NANOSECONDS_PER_SECOND; 486 } 487 } 488 489 void 490 timespec_subtract(struct timespec *left, 491 const struct timespec *right) 492 { 493 left->tv_sec -= right->tv_sec; 494 left->tv_nsec -= right->tv_nsec; 495 if (left->tv_nsec < 0L) { 496 /* Borrow. */ 497 --left->tv_sec; 498 left->tv_nsec += NANOSECONDS_PER_SECOND; 499 } 500 } 501 502 uint32_t 503 strtoserial(const char* nptr, const char** endptr) 504 { 505 uint32_t i = 0; 506 uint32_t serial = 0; 507 508 for(*endptr = nptr; **endptr; (*endptr)++) { 509 switch (**endptr) { 510 case ' ': 511 case '\t': 512 break; 513 case '0': 514 case '1': 515 case '2': 516 case '3': 517 case '4': 518 case '5': 519 case '6': 520 case '7': 521 case '8': 522 case '9': 523 if((i*10)/10 != i) 524 /* number too large, return i 525 * with *endptr != 0 as a failure*/ 526 return i; 527 i *= 10; 528 i += (**endptr - '0'); 529 break; 530 default: 531 break; 532 } 533 } 534 serial += i; 535 return serial; 536 } 537 538 uint32_t 539 strtottl(const char *nptr, const char **endptr) 540 { 541 uint32_t i = 0; 542 uint32_t seconds = 0; 543 544 for(*endptr = nptr; **endptr; (*endptr)++) { 545 switch (**endptr) { 546 case ' ': 547 case '\t': 548 break; 549 case 's': 550 case 'S': 551 seconds += i; 552 i = 0; 553 break; 554 case 'm': 555 case 'M': 556 seconds += i * 60; 557 i = 0; 558 break; 559 case 'h': 560 case 'H': 561 seconds += i * 60 * 60; 562 i = 0; 563 break; 564 case 'd': 565 case 'D': 566 seconds += i * 60 * 60 * 24; 567 i = 0; 568 break; 569 case 'w': 570 case 'W': 571 seconds += i * 60 * 60 * 24 * 7; 572 i = 0; 573 break; 574 case '0': 575 case '1': 576 case '2': 577 case '3': 578 case '4': 579 case '5': 580 case '6': 581 case '7': 582 case '8': 583 case '9': 584 i *= 10; 585 i += (**endptr - '0'); 586 break; 587 default: 588 seconds += i; 589 /** 590 * According to RFC2308, Section 8, the MSB 591 * (sign bit) should be set to zero. 592 * If we encounter a value larger than 2^31 -1, 593 * we fall back to the default TTL. 594 */ 595 if ((seconds & MSB_32)) { 596 seconds = DEFAULT_TTL; 597 } 598 return seconds; 599 } 600 } 601 seconds += i; 602 if ((seconds & MSB_32)) { 603 seconds = DEFAULT_TTL; 604 } 605 return seconds; 606 } 607 608 609 ssize_t 610 hex_ntop(uint8_t const *src, size_t srclength, char *target, size_t targsize) 611 { 612 static char hexdigits[] = { 613 '0', '1', '2', '3', '4', '5', '6', '7', 614 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' 615 }; 616 size_t i; 617 618 if (targsize < srclength * 2 + 1) { 619 return -1; 620 } 621 622 for (i = 0; i < srclength; ++i) { 623 *target++ = hexdigits[src[i] >> 4U]; 624 *target++ = hexdigits[src[i] & 0xfU]; 625 } 626 *target = '\0'; 627 return 2 * srclength; 628 } 629 630 ssize_t 631 hex_pton(const char* src, uint8_t* target, size_t targsize) 632 { 633 uint8_t *t = target; 634 if(strlen(src) % 2 != 0 || strlen(src)/2 > targsize) { 635 return -1; 636 } 637 while(*src) { 638 if(!isxdigit((unsigned char)src[0]) || 639 !isxdigit((unsigned char)src[1])) 640 return -1; 641 *t++ = hexdigit_to_int(src[0]) * 16 + 642 hexdigit_to_int(src[1]) ; 643 src += 2; 644 } 645 return t-target; 646 } 647 648 int 649 b32_ntop(uint8_t const *src, size_t srclength, char *target, size_t targsize) 650 { 651 static char b32[]="0123456789abcdefghijklmnopqrstuv"; 652 char buf[9]; 653 ssize_t len=0; 654 655 while(srclength > 0) 656 { 657 int t; 658 memset(buf,'\0',sizeof buf); 659 660 /* xxxxx000 00000000 00000000 00000000 00000000 */ 661 buf[0]=b32[src[0] >> 3]; 662 663 /* 00000xxx xx000000 00000000 00000000 00000000 */ 664 t=(src[0]&7) << 2; 665 if(srclength > 1) 666 t+=src[1] >> 6; 667 buf[1]=b32[t]; 668 if(srclength == 1) 669 break; 670 671 /* 00000000 00xxxxx0 00000000 00000000 00000000 */ 672 buf[2]=b32[(src[1] >> 1)&0x1f]; 673 674 /* 00000000 0000000x xxxx0000 00000000 00000000 */ 675 t=(src[1]&1) << 4; 676 if(srclength > 2) 677 t+=src[2] >> 4; 678 buf[3]=b32[t]; 679 if(srclength == 2) 680 break; 681 682 /* 00000000 00000000 0000xxxx x0000000 00000000 */ 683 t=(src[2]&0xf) << 1; 684 if(srclength > 3) 685 t+=src[3] >> 7; 686 buf[4]=b32[t]; 687 if(srclength == 3) 688 break; 689 690 /* 00000000 00000000 00000000 0xxxxx00 00000000 */ 691 buf[5]=b32[(src[3] >> 2)&0x1f]; 692 693 /* 00000000 00000000 00000000 000000xx xxx00000 */ 694 t=(src[3]&3) << 3; 695 if(srclength > 4) 696 t+=src[4] >> 5; 697 buf[6]=b32[t]; 698 if(srclength == 4) 699 break; 700 701 /* 00000000 00000000 00000000 00000000 000xxxxx */ 702 buf[7]=b32[src[4]&0x1f]; 703 704 if(targsize < 8) 705 return -1; 706 707 src += 5; 708 srclength -= 5; 709 710 memcpy(target,buf,8); 711 target += 8; 712 targsize -= 8; 713 len += 8; 714 } 715 if(srclength) 716 { 717 size_t tlen = strlcpy(target, buf, targsize); 718 if (tlen >= targsize) 719 return -1; 720 len += tlen; 721 } 722 else if(targsize < 1) 723 return -1; 724 else 725 *target='\0'; 726 return len; 727 } 728 729 int 730 b32_pton(const char *src, uint8_t *target, size_t tsize) 731 { 732 char ch; 733 size_t p=0; 734 735 memset(target,'\0',tsize); 736 while((ch = *src++)) { 737 uint8_t d; 738 size_t b; 739 size_t n; 740 741 if(p+5 >= tsize*8) 742 return -1; 743 744 if(isspace((unsigned char)ch)) 745 continue; 746 747 if(ch >= '0' && ch <= '9') 748 d=ch-'0'; 749 else if(ch >= 'A' && ch <= 'V') 750 d=ch-'A'+10; 751 else if(ch >= 'a' && ch <= 'v') 752 d=ch-'a'+10; 753 else 754 return -1; 755 756 b=7-p%8; 757 n=p/8; 758 759 if(b >= 4) 760 target[n]|=d << (b-4); 761 else { 762 target[n]|=d >> (4-b); 763 target[n+1]|=d << (b+4); 764 } 765 p+=5; 766 } 767 return (p+7)/8; 768 } 769 770 void 771 strip_string(char *str) 772 { 773 char *start = str; 774 char *end = str + strlen(str) - 1; 775 776 while (isspace((unsigned char)*start)) 777 ++start; 778 if (start > end) { 779 /* Completely blank. */ 780 str[0] = '\0'; 781 } else { 782 while (isspace((unsigned char)*end)) 783 --end; 784 *++end = '\0'; 785 786 if (str != start) 787 memmove(str, start, end - start + 1); 788 } 789 } 790 791 int 792 hexdigit_to_int(char ch) 793 { 794 switch (ch) { 795 case '0': return 0; 796 case '1': return 1; 797 case '2': return 2; 798 case '3': return 3; 799 case '4': return 4; 800 case '5': return 5; 801 case '6': return 6; 802 case '7': return 7; 803 case '8': return 8; 804 case '9': return 9; 805 case 'a': case 'A': return 10; 806 case 'b': case 'B': return 11; 807 case 'c': case 'C': return 12; 808 case 'd': case 'D': return 13; 809 case 'e': case 'E': return 14; 810 case 'f': case 'F': return 15; 811 default: 812 abort(); 813 } 814 } 815 816 /* Number of days per month (except for February in leap years). */ 817 static const int mdays[] = { 818 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 819 }; 820 821 static int 822 is_leap_year(int year) 823 { 824 return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0); 825 } 826 827 static int 828 leap_days(int y1, int y2) 829 { 830 --y1; 831 --y2; 832 return (y2/4 - y1/4) - (y2/100 - y1/100) + (y2/400 - y1/400); 833 } 834 835 /* 836 * Code adapted from Python 2.4.1 sources (Lib/calendar.py). 837 */ 838 time_t 839 mktime_from_utc(const struct tm *tm) 840 { 841 int year = 1900 + tm->tm_year; 842 time_t days = 365 * (year - 1970) + leap_days(1970, year); 843 time_t hours; 844 time_t minutes; 845 time_t seconds; 846 int i; 847 848 for (i = 0; i < tm->tm_mon; ++i) { 849 days += mdays[i]; 850 } 851 if (tm->tm_mon > 1 && is_leap_year(year)) { 852 ++days; 853 } 854 days += tm->tm_mday - 1; 855 856 hours = days * 24 + tm->tm_hour; 857 minutes = hours * 60 + tm->tm_min; 858 seconds = minutes * 60 + tm->tm_sec; 859 860 return seconds; 861 } 862 863 /* code to calculate CRC. Lifted from BSD 4.4 crc.c in cksum(1). BSD license. 864 http://www.tsfr.org/~orc/Code/bsd/bsd-current/cksum/crc.c. 865 or http://gobsd.com/code/freebsd/usr.bin/cksum/crc.c 866 The polynomial is 0x04c11db7L. */ 867 static uint32_t crctab[] = { 868 0x0, 869 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, 870 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 871 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 872 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac, 873 0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f, 874 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 875 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, 876 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 877 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 878 0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe, 879 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95, 880 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4, 881 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0, 882 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 883 0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 884 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07, 885 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c, 886 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 887 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, 888 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 889 0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 890 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d, 891 0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, 892 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f, 893 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, 894 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 895 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 896 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a, 897 0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629, 898 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c, 899 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, 900 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 901 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 902 0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 903 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3, 904 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2, 905 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71, 906 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 907 0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 908 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21, 909 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a, 910 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087, 911 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, 912 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 913 0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 914 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 915 0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, 916 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09, 917 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, 918 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 919 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 920 }; 921 922 #define COMPUTE(var, ch) (var) = (var) << 8 ^ crctab[(var) >> 24 ^ (ch)] 923 924 uint32_t 925 compute_crc(uint32_t crc, uint8_t* data, size_t len) 926 { 927 size_t i; 928 for(i=0; i<len; ++i) 929 COMPUTE(crc, data[i]); 930 return crc; 931 } 932 933 int 934 write_data_crc(FILE *file, const void *data, size_t size, uint32_t* crc) 935 { 936 int ret = write_data(file, data, size); 937 *crc = compute_crc(*crc, (uint8_t*)data, size); 938 return ret; 939 } 940 941 #define SERIAL_BITS 32 942 int 943 compare_serial(uint32_t a, uint32_t b) 944 { 945 const uint32_t cutoff = ((uint32_t) 1 << (SERIAL_BITS - 1)); 946 947 if (a == b) { 948 return 0; 949 } else if ((a < b && b - a < cutoff) || (a > b && a - b > cutoff)) { 950 return -1; 951 } else { 952 return 1; 953 } 954 } 955 956 uint16_t 957 qid_generate(void) 958 { 959 #ifdef HAVE_GETRANDOM 960 uint16_t r; 961 if(getrandom(&r, sizeof(r), 0) == -1) { 962 log_msg(LOG_ERR, "getrandom failed: %s", strerror(errno)); 963 exit(1); 964 } 965 return r; 966 #elif defined(HAVE_ARC4RANDOM) 967 /* arc4random_uniform not needed because range is a power of 2 */ 968 return (uint16_t) arc4random(); 969 #else 970 return (uint16_t) random(); 971 #endif 972 } 973 974 int 975 random_generate(int max) 976 { 977 #ifdef HAVE_GETRANDOM 978 int r; 979 if(getrandom(&r, sizeof(r), 0) == -1) { 980 log_msg(LOG_ERR, "getrandom failed: %s", strerror(errno)); 981 exit(1); 982 } 983 return (int)(((unsigned)r)%max); 984 #elif defined(HAVE_ARC4RANDOM_UNIFORM) 985 return (int) arc4random_uniform(max); 986 #elif defined(HAVE_ARC4RANDOM) 987 return (int) (arc4random() % max); 988 #else 989 return (int) ((unsigned)random() % max); 990 #endif 991 } 992 993 void 994 cleanup_region(void *data) 995 { 996 region_type *region = (region_type *) data; 997 region_destroy(region); 998 } 999 1000 struct state_pretty_rr* 1001 create_pretty_rr(struct region* region) 1002 { 1003 struct state_pretty_rr* state = (struct state_pretty_rr*) 1004 region_alloc(region, sizeof(struct state_pretty_rr)); 1005 state->previous_owner_region = region_create(xalloc, free); 1006 state->previous_owner = NULL; 1007 state->previous_owner_origin = NULL; 1008 region_add_cleanup(region, cleanup_region, 1009 state->previous_owner_region); 1010 return state; 1011 } 1012 1013 static void 1014 set_previous_owner(struct state_pretty_rr *state, const dname_type *dname) 1015 { 1016 region_free_all(state->previous_owner_region); 1017 state->previous_owner = dname_copy(state->previous_owner_region, dname); 1018 state->previous_owner_origin = dname_origin( 1019 state->previous_owner_region, state->previous_owner); 1020 } 1021 1022 int 1023 print_rr(FILE *out, 1024 struct state_pretty_rr *state, 1025 rr_type *record, 1026 region_type* rr_region, 1027 buffer_type* output) 1028 { 1029 rrtype_descriptor_type *descriptor 1030 = rrtype_descriptor_by_type(record->type); 1031 int result; 1032 const dname_type *owner = domain_dname(record->owner); 1033 buffer_clear(output); 1034 if (state) { 1035 if (!state->previous_owner 1036 || dname_compare(state->previous_owner, owner) != 0) { 1037 const dname_type *owner_origin 1038 = dname_origin(rr_region, owner); 1039 int origin_changed = (!state->previous_owner_origin 1040 || dname_compare(state->previous_owner_origin, 1041 owner_origin) != 0); 1042 if (origin_changed) { 1043 buffer_printf(output, "$ORIGIN %s\n", 1044 dname_to_string(owner_origin, NULL)); 1045 } 1046 1047 set_previous_owner(state, owner); 1048 buffer_printf(output, "%s", 1049 dname_to_string(owner, 1050 state->previous_owner_origin)); 1051 region_free_all(rr_region); 1052 } 1053 } else { 1054 buffer_printf(output, "%s", dname_to_string(owner, NULL)); 1055 } 1056 1057 buffer_printf(output, "\t%lu\t%s\t%s", 1058 (unsigned long) record->ttl, 1059 rrclass_to_string(record->klass), 1060 rrtype_to_string(record->type)); 1061 1062 result = print_rdata(output, descriptor, record); 1063 if (!result) { 1064 /* 1065 * Some RDATA failed to print, so print the record's 1066 * RDATA in unknown format. 1067 */ 1068 result = rdata_atoms_to_unknown_string(output, 1069 descriptor, record->rdata_count, record->rdatas); 1070 } 1071 1072 if (result) { 1073 buffer_printf(output, "\n"); 1074 buffer_flip(output); 1075 result = write_data(out, buffer_current(output), 1076 buffer_remaining(output)); 1077 } 1078 return result; 1079 } 1080 1081 const char* 1082 rcode2str(int rc) 1083 { 1084 switch(rc) { 1085 case RCODE_OK: 1086 return "NO ERROR"; 1087 case RCODE_FORMAT: 1088 return "FORMAT ERROR"; 1089 case RCODE_SERVFAIL: 1090 return "SERVFAIL"; 1091 case RCODE_NXDOMAIN: 1092 return "NAME ERROR"; 1093 case RCODE_IMPL: 1094 return "NOT IMPL"; 1095 case RCODE_REFUSE: 1096 return "REFUSED"; 1097 case RCODE_YXDOMAIN: 1098 return "YXDOMAIN"; 1099 case RCODE_YXRRSET: 1100 return "YXRRSET"; 1101 case RCODE_NXRRSET: 1102 return "NXRRSET"; 1103 case RCODE_NOTAUTH: 1104 return "SERVER NOT AUTHORITATIVE FOR ZONE"; 1105 case RCODE_NOTZONE: 1106 /* Name not contained in zone */ 1107 return "NOTZONE"; 1108 default: 1109 return "UNKNOWN ERROR"; 1110 } 1111 return NULL; /* ENOREACH */ 1112 } 1113 1114 void 1115 addr2str( 1116 #ifdef INET6 1117 struct sockaddr_storage *addr 1118 #else 1119 struct sockaddr_in *addr 1120 #endif 1121 , char* str, size_t len) 1122 { 1123 #ifdef INET6 1124 if (addr->ss_family == AF_INET6) { 1125 if (!inet_ntop(AF_INET6, 1126 &((struct sockaddr_in6 *)addr)->sin6_addr, str, len)) 1127 strlcpy(str, "[unknown ip6, inet_ntop failed]", len); 1128 return; 1129 } 1130 #endif 1131 if (!inet_ntop(AF_INET, &((struct sockaddr_in *)addr)->sin_addr, 1132 str, len)) 1133 strlcpy(str, "[unknown ip4, inet_ntop failed]", len); 1134 } 1135 1136 void 1137 addrport2str( 1138 #ifdef INET6 1139 struct sockaddr_storage *addr 1140 #else 1141 struct sockaddr_in *addr 1142 #endif 1143 , char* str, size_t len) 1144 { 1145 char ip[256]; 1146 #ifdef INET6 1147 if (addr->ss_family == AF_INET6) { 1148 if (!inet_ntop(AF_INET6, 1149 &((struct sockaddr_in6 *)addr)->sin6_addr, ip, sizeof(ip))) 1150 strlcpy(ip, "[unknown ip6, inet_ntop failed]", sizeof(ip)); 1151 /* append port number */ 1152 snprintf(str, len, "%s@%u", ip, 1153 (unsigned)ntohs(((struct sockaddr_in6 *)addr)->sin6_port)); 1154 return; 1155 } else 1156 #endif 1157 if (!inet_ntop(AF_INET, &((struct sockaddr_in *)addr)->sin_addr, 1158 ip, sizeof(ip))) 1159 strlcpy(ip, "[unknown ip4, inet_ntop failed]", sizeof(ip)); 1160 /* append port number */ 1161 snprintf(str, len, "%s@%u", ip, 1162 (unsigned)ntohs(((struct sockaddr_in *)addr)->sin_port)); 1163 } 1164 1165 void 1166 append_trailing_slash(const char** dirname, region_type* region) 1167 { 1168 int l = strlen(*dirname); 1169 if (l>0 && (*dirname)[l-1] != '/' && l < 0xffffff) { 1170 char *dirname_slash = region_alloc(region, l+2); 1171 memcpy(dirname_slash, *dirname, l+1); 1172 strlcat(dirname_slash, "/", l+2); 1173 /* old dirname is leaked, this is only used for chroot, once */ 1174 *dirname = dirname_slash; 1175 } 1176 } 1177 1178 int 1179 file_inside_chroot(const char* fname, const char* chr) 1180 { 1181 /* true if filename starts with chroot or is not absolute */ 1182 return ((fname && fname[0] && strncmp(fname, chr, strlen(chr)) == 0) || 1183 (fname && fname[0] != '/')); 1184 } 1185 1186 /* 1187 * Something went wrong, give error messages and exit. 1188 */ 1189 void 1190 error(const char *format, ...) 1191 { 1192 va_list args; 1193 va_start(args, format); 1194 log_vmsg(LOG_ERR, format, args); 1195 va_end(args); 1196 exit(1); 1197 } 1198 1199 #ifdef HAVE_CPUSET_T 1200 #if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_CONF) 1201 /* exists on Linux and FreeBSD */ 1202 int number_of_cpus(void) 1203 { 1204 return (int)sysconf(_SC_NPROCESSORS_CONF); 1205 } 1206 #else 1207 int number_of_cpus(void) 1208 { 1209 return -1; 1210 } 1211 #endif 1212 #ifdef __gnu_hurd__ 1213 /* HURD has no sched_setaffinity implementation, but links an always fail, 1214 * with a linker error, we print an error when it is used */ 1215 int set_cpu_affinity(cpuset_t *ATTR_UNUSED(set)) 1216 { 1217 log_err("sched_setaffinity: not available on this system"); 1218 return -1; 1219 } 1220 #elif defined(HAVE_SCHED_SETAFFINITY) 1221 /* Linux */ 1222 int set_cpu_affinity(cpuset_t *set) 1223 { 1224 assert(set != NULL); 1225 return sched_setaffinity(getpid(), sizeof(*set), set); 1226 } 1227 #else 1228 /* FreeBSD */ 1229 int set_cpu_affinity(cpuset_t *set) 1230 { 1231 assert(set != NULL); 1232 return cpuset_setaffinity( 1233 CPU_LEVEL_WHICH, CPU_WHICH_PID, -1, sizeof(*set), set); 1234 } 1235 #endif 1236 #endif /* HAVE_CPUSET_T */ 1237