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