#ifndef UTIL_H
#define UTIL_H
#include <sys/time.h>
#include <stdarg.h>
#include <stdio.h>
#include <time.h>
#include "bitset.h"
struct rr;
struct buffer;
struct region;
struct nsd;
struct nsd_options;
#ifdef HAVE_SYSLOG_H
# include <syslog.h>
#else
# define LOG_ERR 3
# define LOG_WARNING 4
# define LOG_NOTICE 5
# define LOG_INFO 6
# define LOG_PID 0x01
# define LOG_DAEMON (3<<3)
#endif
#define ALIGN_UP(n, alignment) \
(((n) + (alignment) - 1) & (~((alignment) - 1)))
#define PADDING(n, alignment) \
(ALIGN_UP((n), (alignment)) - (n))
void log_init(const char *ident);
#ifdef USE_LOG_PROCESS_ROLE
void log_set_process_role(const char* role);
#else
#define log_set_process_role(role)
#endif
void log_open(int option, int facility, const char *filename);
void log_reopen(const char *filename, uint8_t verbose);
void log_finalize(void);
typedef void log_function_type(int priority, const char *message);
log_function_type log_file;
log_function_type log_syslog;
log_function_type log_only_syslog;
void log_set_log_function(log_function_type *log_function);
void log_msg(int priority, const char *format, ...)
ATTR_FORMAT(printf, 2, 3);
void log_vmsg(int priority, const char *format, va_list args);
extern int verbosity;
#define VERBOSITY(level, args) \
do { \
if ((level) <= verbosity) { \
log_msg args ; \
} \
} while (0)
void set_bit(uint8_t bits[], size_t index);
void clear_bit(uint8_t bits[], size_t index);
int get_bit(const uint8_t bits[], size_t index);
typedef struct lookup_table lookup_table_type;
struct lookup_table {
int id;
const char *name;
};
lookup_table_type *lookup_by_name(lookup_table_type table[], const char *name);
lookup_table_type *lookup_by_id(lookup_table_type table[], int id);
void *xalloc(size_t size);
void *xmallocarray(size_t num, size_t size);
void *xalloc_zero(size_t size);
void *xalloc_array_zero(size_t num, size_t size);
void *xrealloc(void *ptr, size_t size);
char *xstrdup(const char *src);
#ifdef USE_MMAP_ALLOC
void *mmap_alloc(size_t size);
void mmap_free(void *ptr);
#endif
int write_data(FILE *file, const void *data, size_t size);
int write_data_crc(FILE *file, const void *data, size_t size, uint32_t* crc);
int write_socket(int s, const void *data, size_t size);
static inline void
write_uint16(void *dst, uint16_t data)
{
#ifdef ALLOW_UNALIGNED_ACCESSES
* (uint16_t *) dst = htons(data);
#else
uint8_t *p = (uint8_t *) dst;
p[0] = (uint8_t) ((data >> 8) & 0xff);
p[1] = (uint8_t) (data & 0xff);
#endif
}
static inline void
write_uint32(void *dst, uint32_t data)
{
#ifdef ALLOW_UNALIGNED_ACCESSES
* (uint32_t *) dst = htonl(data);
#else
uint8_t *p = (uint8_t *) dst;
p[0] = (uint8_t) ((data >> 24) & 0xff);
p[1] = (uint8_t) ((data >> 16) & 0xff);
p[2] = (uint8_t) ((data >> 8) & 0xff);
p[3] = (uint8_t) (data & 0xff);
#endif
}
static inline void
write_uint64(void *dst, uint64_t data)
{
uint8_t *p = (uint8_t *) dst;
p[0] = (uint8_t) ((data >> 56) & 0xff);
p[1] = (uint8_t) ((data >> 48) & 0xff);
p[2] = (uint8_t) ((data >> 40) & 0xff);
p[3] = (uint8_t) ((data >> 32) & 0xff);
p[4] = (uint8_t) ((data >> 24) & 0xff);
p[5] = (uint8_t) ((data >> 16) & 0xff);
p[6] = (uint8_t) ((data >> 8) & 0xff);
p[7] = (uint8_t) (data & 0xff);
}
static inline uint16_t
read_uint16(const void *src)
{
#ifdef ALLOW_UNALIGNED_ACCESSES
return ntohs(* (const uint16_t *) src);
#else
const uint8_t *p = (const uint8_t *) src;
return (p[0] << 8) | p[1];
#endif
}
static inline uint32_t
read_uint32(const void *src)
{
#ifdef ALLOW_UNALIGNED_ACCESSES
return ntohl(* (const uint32_t *) src);
#else
const uint8_t *p = (const uint8_t *) src;
return ((uint32_t)p[0] << 24) | ((uint32_t)p[1] << 16) | ((uint32_t)p[2] << 8) | (uint32_t)p[3];
#endif
}
static inline uint64_t
read_uint64(const void *src)
{
const uint8_t *p = (const uint8_t *) src;
return
((uint64_t)p[0] << 56) |
((uint64_t)p[1] << 48) |
((uint64_t)p[2] << 40) |
((uint64_t)p[3] << 32) |
((uint64_t)p[4] << 24) |
((uint64_t)p[5] << 16) |
((uint64_t)p[6] << 8) |
(uint64_t)p[7];
}
#define DEBUG_PARSER 0x0001U
#define DEBUG_ZONEC 0x0002U
#define DEBUG_QUERY 0x0004U
#define DEBUG_DBACCESS 0x0008U
#define DEBUG_NAME_COMPRESSION 0x0010U
#define DEBUG_XFRD 0x0020U
#define DEBUG_IPC 0x0040U
extern unsigned nsd_debug_facilities;
extern int nsd_debug_level;
#ifdef NDEBUG
#define DEBUG(facility, level, args)
#else
#define DEBUG(facility, level, args) \
do { \
if ((facility) & nsd_debug_facilities && \
(level) <= nsd_debug_level) { \
log_msg args ; \
} \
} while (0)
#endif
extern int log_time_asc;
extern int log_time_iso;
int timespec_compare(const struct timespec *left, const struct timespec *right);
void timespec_add(struct timespec *left, const struct timespec *right);
void timespec_subtract(struct timespec *left, const struct timespec *right);
static inline void
timeval_to_timespec(struct timespec *left,
const struct timeval *right)
{
left->tv_sec = right->tv_sec;
left->tv_nsec = 1000 * right->tv_usec;
}
void get_time(struct timespec* t);
ssize_t hex_ntop(uint8_t const *src, size_t srclength, char *target,
size_t targsize);
ssize_t hex_pton(const char* src, uint8_t* target, size_t targsize);
int b32_pton(char const *src, uint8_t *target, size_t targsize);
int b32_ntop(uint8_t const *src, size_t srclength, char *target,
size_t targsize);
void strip_string(char *str);
int hexdigit_to_int(char ch);
uint32_t compute_crc(uint32_t crc, uint8_t* data, size_t len);
int compare_serial(uint32_t a, uint32_t b);
uint16_t qid_generate(void);
int random_generate(int max);
void cleanup_region(void *data);
struct state_pretty_rr {
struct region *previous_owner_region;
const struct dname *previous_owner;
const struct dname *previous_owner_origin;
};
struct state_pretty_rr* create_pretty_rr(struct region* region);
int print_rr(FILE *out, struct state_pretty_rr* state, struct rr *record,
struct region* tmp_region, struct buffer* tmp_buffer);
const char* rcode2str(int rc);
void addr2str(
#ifdef INET6
struct sockaddr_storage *addr
#else
struct sockaddr_in *addr
#endif
, char* str, size_t len);
void addrport2str(
#ifdef INET6
struct sockaddr_storage *addr
#else
struct sockaddr_in *addr
#endif
, char* str, size_t len);
void append_trailing_slash(const char** dirname, struct region* region);
int file_inside_chroot(const char* fname, const char* chr);
void error(const char *format, ...) ATTR_FORMAT(printf, 1, 2) ATTR_NORETURN;
#if HAVE_CPUSET_T
int number_of_cpus(void);
int set_cpu_affinity(cpuset_t *set);
#endif
void add_cookie_secret(struct nsd* nsd, uint8_t* secret);
void activate_cookie_secret(struct nsd* nsd);
void drop_cookie_secret(struct nsd* nsd);
void reconfig_cookies(struct nsd* nsd, struct nsd_options* options);
ssize_t print_socket_servers(struct nsd_bitset *bitset, char *buf, size_t bufsz);
#endif