1 /* 2 * util.h -- 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 #ifndef UTIL_H 11 #define UTIL_H 12 13 #include <sys/time.h> 14 #include <stdarg.h> 15 #include <stdio.h> 16 #include <time.h> 17 #include "bitset.h" 18 struct rr; 19 struct buffer; 20 struct region; 21 struct nsd; 22 struct nsd_options; 23 24 #ifdef HAVE_SYSLOG_H 25 # include <syslog.h> 26 #else 27 # define LOG_ERR 3 28 # define LOG_WARNING 4 29 # define LOG_NOTICE 5 30 # define LOG_INFO 6 31 32 /* Unused, but passed to log_open. */ 33 # define LOG_PID 0x01 34 # define LOG_DAEMON (3<<3) 35 #endif 36 37 #define ALIGN_UP(n, alignment) \ 38 (((n) + (alignment) - 1) & (~((alignment) - 1))) 39 #define PADDING(n, alignment) \ 40 (ALIGN_UP((n), (alignment)) - (n)) 41 42 /* 43 * Initialize the logging system. All messages are logged to stderr 44 * until log_open and log_set_log_function are called. 45 */ 46 void log_init(const char *ident); 47 48 #ifdef USE_LOG_PROCESS_ROLE 49 /* 50 * Set the name of the role for the process (for debugging purposes) 51 */ 52 void log_set_process_role(const char* role); 53 #else 54 #define log_set_process_role(role) /* empty */ 55 #endif 56 57 /* 58 * Open the system log. If FILENAME is not NULL, a log file is opened 59 * as well. 60 */ 61 void log_open(int option, int facility, const char *filename); 62 63 /* 64 * Reopen the logfile. 65 */ 66 void log_reopen(const char *filename, uint8_t verbose); 67 68 /* 69 * Finalize the logging system. 70 */ 71 void log_finalize(void); 72 73 /* 74 * Type of function to use for the actual logging. 75 */ 76 typedef void log_function_type(int priority, const char *message); 77 78 /* 79 * The function used to log to the log file. 80 */ 81 log_function_type log_file; 82 83 /* 84 * The function used to log to syslog. The messages are also logged 85 * using log_file. 86 */ 87 log_function_type log_syslog; 88 89 /* 90 * The function used to log to syslog only. 91 */ 92 log_function_type log_only_syslog; 93 94 /* 95 * Set the logging function to use (log_file or log_syslog). 96 */ 97 void log_set_log_function(log_function_type *log_function); 98 99 /* 100 * Log a message using the current log function. 101 */ 102 void log_msg(int priority, const char *format, ...) 103 ATTR_FORMAT(printf, 2, 3); 104 105 /* 106 * Log a message using the current log function. 107 */ 108 void log_vmsg(int priority, const char *format, va_list args); 109 110 /* 111 * Verbose output switch 112 */ 113 extern int verbosity; 114 #define VERBOSITY(level, args) \ 115 do { \ 116 if ((level) <= verbosity) { \ 117 log_msg args ; \ 118 } \ 119 } while (0) 120 121 /* 122 * Set the INDEXth bit of BITS to 1. 123 */ 124 void set_bit(uint8_t bits[], size_t index); 125 126 /* 127 * Set the INDEXth bit of BITS to 0. 128 */ 129 void clear_bit(uint8_t bits[], size_t index); 130 131 /* 132 * Return the value of the INDEXth bit of BITS. 133 */ 134 int get_bit(const uint8_t bits[], size_t index); 135 136 /* A general purpose lookup table */ 137 typedef struct lookup_table lookup_table_type; 138 struct lookup_table { 139 int id; 140 const char *name; 141 }; 142 143 /* 144 * Looks up the table entry by name, returns NULL if not found. 145 */ 146 lookup_table_type *lookup_by_name(lookup_table_type table[], const char *name); 147 148 /* 149 * Looks up the table entry by id, returns NULL if not found. 150 */ 151 lookup_table_type *lookup_by_id(lookup_table_type table[], int id); 152 153 /* 154 * (Re-)allocate SIZE bytes of memory. Report an error if the memory 155 * could not be allocated and exit the program. These functions never 156 * return NULL. 157 */ 158 void *xalloc(size_t size); 159 void *xmallocarray(size_t num, size_t size); 160 void *xalloc_zero(size_t size); 161 void *xalloc_array_zero(size_t num, size_t size); 162 void *xrealloc(void *ptr, size_t size); 163 char *xstrdup(const char *src); 164 165 /* 166 * Mmap allocator routines. 167 * 168 */ 169 #ifdef USE_MMAP_ALLOC 170 void *mmap_alloc(size_t size); 171 void mmap_free(void *ptr); 172 #endif /* USE_MMAP_ALLOC */ 173 174 /* 175 * Write SIZE bytes of DATA to FILE. Report an error on failure. 176 * 177 * Returns 0 on failure, 1 on success. 178 */ 179 int write_data(FILE *file, const void *data, size_t size); 180 181 /* 182 * like write_data, but keeps track of crc 183 */ 184 int write_data_crc(FILE *file, const void *data, size_t size, uint32_t* crc); 185 186 /* 187 * Write the complete buffer to the socket, irrespective of short 188 * writes or interrupts. This function blocks to write the data. 189 * Returns 0 on error, 1 on success. 190 */ 191 int write_socket(int s, const void *data, size_t size); 192 193 /* 194 * Copy data allowing for unaligned accesses in network byte order 195 * (big endian). 196 */ 197 static inline void 198 write_uint16(void *dst, uint16_t data) 199 { 200 #ifdef ALLOW_UNALIGNED_ACCESSES 201 * (uint16_t *) dst = htons(data); 202 #else 203 uint8_t *p = (uint8_t *) dst; 204 p[0] = (uint8_t) ((data >> 8) & 0xff); 205 p[1] = (uint8_t) (data & 0xff); 206 #endif 207 } 208 209 static inline void 210 write_uint32(void *dst, uint32_t data) 211 { 212 #ifdef ALLOW_UNALIGNED_ACCESSES 213 * (uint32_t *) dst = htonl(data); 214 #else 215 uint8_t *p = (uint8_t *) dst; 216 p[0] = (uint8_t) ((data >> 24) & 0xff); 217 p[1] = (uint8_t) ((data >> 16) & 0xff); 218 p[2] = (uint8_t) ((data >> 8) & 0xff); 219 p[3] = (uint8_t) (data & 0xff); 220 #endif 221 } 222 223 static inline void 224 write_uint64(void *dst, uint64_t data) 225 { 226 uint8_t *p = (uint8_t *) dst; 227 p[0] = (uint8_t) ((data >> 56) & 0xff); 228 p[1] = (uint8_t) ((data >> 48) & 0xff); 229 p[2] = (uint8_t) ((data >> 40) & 0xff); 230 p[3] = (uint8_t) ((data >> 32) & 0xff); 231 p[4] = (uint8_t) ((data >> 24) & 0xff); 232 p[5] = (uint8_t) ((data >> 16) & 0xff); 233 p[6] = (uint8_t) ((data >> 8) & 0xff); 234 p[7] = (uint8_t) (data & 0xff); 235 } 236 237 /* 238 * Copy data allowing for unaligned accesses in network byte order 239 * (big endian). 240 */ 241 static inline uint16_t 242 read_uint16(const void *src) 243 { 244 #ifdef ALLOW_UNALIGNED_ACCESSES 245 return ntohs(* (const uint16_t *) src); 246 #else 247 const uint8_t *p = (const uint8_t *) src; 248 return (p[0] << 8) | p[1]; 249 #endif 250 } 251 252 static inline uint32_t 253 read_uint32(const void *src) 254 { 255 #ifdef ALLOW_UNALIGNED_ACCESSES 256 return ntohl(* (const uint32_t *) src); 257 #else 258 const uint8_t *p = (const uint8_t *) src; 259 return ((uint32_t)p[0] << 24) | ((uint32_t)p[1] << 16) | ((uint32_t)p[2] << 8) | (uint32_t)p[3]; 260 #endif 261 } 262 263 static inline uint64_t 264 read_uint64(const void *src) 265 { 266 const uint8_t *p = (const uint8_t *) src; 267 return 268 ((uint64_t)p[0] << 56) | 269 ((uint64_t)p[1] << 48) | 270 ((uint64_t)p[2] << 40) | 271 ((uint64_t)p[3] << 32) | 272 ((uint64_t)p[4] << 24) | 273 ((uint64_t)p[5] << 16) | 274 ((uint64_t)p[6] << 8) | 275 (uint64_t)p[7]; 276 } 277 278 /* 279 * Print debugging information using log_msg, 280 * set the logfile as /dev/stdout or /dev/stderr if you like. 281 * nsd -F 0xFFFF enables all debug facilities. 282 */ 283 #define DEBUG_PARSER 0x0001U 284 #define DEBUG_ZONEC 0x0002U 285 #define DEBUG_QUERY 0x0004U 286 #define DEBUG_DBACCESS 0x0008U 287 #define DEBUG_NAME_COMPRESSION 0x0010U 288 #define DEBUG_XFRD 0x0020U 289 #define DEBUG_IPC 0x0040U 290 291 extern unsigned nsd_debug_facilities; 292 extern int nsd_debug_level; 293 #ifdef NDEBUG 294 #define DEBUG(facility, level, args) /* empty */ 295 #else 296 #define DEBUG(facility, level, args) \ 297 do { \ 298 if ((facility) & nsd_debug_facilities && \ 299 (level) <= nsd_debug_level) { \ 300 log_msg args ; \ 301 } \ 302 } while (0) 303 #endif 304 305 /* set to true to log time prettyprinted, or false to print epoch */ 306 extern int log_time_asc; 307 308 /* set to true to log time in iso format */ 309 extern int log_time_iso; 310 311 /* 312 * Timespec functions. 313 */ 314 int timespec_compare(const struct timespec *left, const struct timespec *right); 315 void timespec_add(struct timespec *left, const struct timespec *right); 316 void timespec_subtract(struct timespec *left, const struct timespec *right); 317 318 static inline void 319 timeval_to_timespec(struct timespec *left, 320 const struct timeval *right) 321 { 322 left->tv_sec = right->tv_sec; 323 left->tv_nsec = 1000 * right->tv_usec; 324 } 325 326 /* get the time */ 327 void get_time(struct timespec* t); 328 329 /* 330 * Convert binary data to a string of hexadecimal characters. 331 */ 332 ssize_t hex_ntop(uint8_t const *src, size_t srclength, char *target, 333 size_t targsize); 334 ssize_t hex_pton(const char* src, uint8_t* target, size_t targsize); 335 336 /* 337 * convert base32 data from and to string. Returns length. 338 * -1 on error. Use (byte count*8)%5==0. 339 */ 340 int b32_pton(char const *src, uint8_t *target, size_t targsize); 341 int b32_ntop(uint8_t const *src, size_t srclength, char *target, 342 size_t targsize); 343 344 /* 345 * Strip trailing and leading whitespace from str. 346 */ 347 void strip_string(char *str); 348 349 /* 350 * Convert a single (hexadecimal) digit to its integer value. 351 */ 352 int hexdigit_to_int(char ch); 353 354 /* 355 * Add bytes to given crc. Returns new CRC sum. 356 * Start crc val with 0xffffffff on first call. XOR crc with 357 * 0xffffffff at the end again to get final POSIX 1003.2 checksum. 358 */ 359 uint32_t compute_crc(uint32_t crc, uint8_t* data, size_t len); 360 361 /* 362 * Compares two 32-bit serial numbers as defined in RFC1982. Returns 363 * <0 if a < b, 0 if a == b, and >0 if a > b. The result is undefined 364 * if a != b but neither is greater or smaller (see RFC1982 section 365 * 3.2.). 366 */ 367 int compare_serial(uint32_t a, uint32_t b); 368 369 /* 370 * Generate a random query ID. 371 */ 372 uint16_t qid_generate(void); 373 /* value between 0 .. (max-1) inclusive */ 374 int random_generate(int max); 375 376 /* 377 * call region_destroy on (region*)data, useful for region_add_cleanup(). 378 */ 379 void cleanup_region(void *data); 380 381 /* 382 * Region used to store owner and origin of previous RR (used 383 * for pretty printing of zone data). 384 * Keep the same between calls to print_rr. 385 */ 386 struct state_pretty_rr { 387 struct region *previous_owner_region; 388 const struct dname *previous_owner; 389 const struct dname *previous_owner_origin; 390 }; 391 struct state_pretty_rr* create_pretty_rr(struct region* region); 392 /* print rr to file, returns 0 on failure(nothing is written) */ 393 int print_rr(FILE *out, struct state_pretty_rr* state, struct rr *record, 394 struct region* tmp_region, struct buffer* tmp_buffer); 395 396 /* 397 * Convert a numeric rcode value to a human readable string 398 */ 399 const char* rcode2str(int rc); 400 401 void addr2str( 402 #ifdef INET6 403 struct sockaddr_storage *addr 404 #else 405 struct sockaddr_in *addr 406 #endif 407 , char* str, size_t len); 408 409 /* print addr@port */ 410 void addrport2str( 411 #ifdef INET6 412 struct sockaddr_storage *addr 413 #else 414 struct sockaddr_in *addr 415 #endif 416 , char* str, size_t len); 417 418 /** copy dirname string and append slash. Previous dirname is leaked, 419 * but it is to be used once, at startup, for chroot */ 420 void append_trailing_slash(const char** dirname, struct region* region); 421 422 /** true if filename starts with chroot or is not absolute */ 423 int file_inside_chroot(const char* fname, const char* chr); 424 425 /** Something went wrong, give error messages and exit. */ 426 void error(const char *format, ...) ATTR_FORMAT(printf, 1, 2) ATTR_NORETURN; 427 428 #if HAVE_CPUSET_T 429 int number_of_cpus(void); 430 int set_cpu_affinity(cpuset_t *set); 431 #endif 432 433 /* Add a cookie secret. If there are no secrets yet, the secret will become 434 * the active secret. Otherwise it will become the staging secret. 435 * Active secrets are used to both verify and create new DNS Cookies. 436 * Staging secrets are only used to verify DNS Cookies. */ 437 void add_cookie_secret(struct nsd* nsd, uint8_t* secret); 438 /* Makes the staging cookie secret active and the active secret staging. */ 439 void activate_cookie_secret(struct nsd* nsd); 440 /* Drop a cookie secret. Drops the staging secret. An active secret will not 441 * be dropped. */ 442 void drop_cookie_secret(struct nsd* nsd); 443 /* Configure nsd struct with how to respond to DNS Cookies based on options */ 444 void reconfig_cookies(struct nsd* nsd, struct nsd_options* options); 445 446 /* print server affinity for given socket's bitset. 447 * o "(all)"; if socket has no affinity with any specific server, 448 * o "(none)"; if no server uses the socket, 449 * o "x-y"; if socket has affinity with 'more than two consecutively' 450 * numbered servers, 451 * o "x"; if socket has affinity with a specific server number, which is 452 * not necessarily just one server. e.g. "1 3" is printed if 453 * socket has affinity with servers number one and three, but not 454 * server number two. Likewise "1 2" is printed if socket has 455 * affinity with servers one and two, but not server number three. 456 */ 457 ssize_t print_socket_servers(struct nsd_bitset *bitset, char *buf, size_t bufsz); 458 459 #endif /* UTIL_H */ 460