Home | History | Annotate | Line # | Download | only in dist
      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