#ifndef NSD_H
#define NSD_H
#include <signal.h>
#include <net/if.h>
#ifndef IFNAMSIZ
# ifdef IF_NAMESIZE
# define IFNAMSIZ IF_NAMESIZE
# else
# define IFNAMSIZ 16
# endif
#endif
#ifdef HAVE_OPENSSL_SSL_H
#include <openssl/ssl.h>
#endif
#include "dns.h"
#include "edns.h"
#include "bitset.h"
#ifdef USE_XDP
#include "xdp-server.h"
#endif
struct netio_handler;
struct nsd_options;
struct udb_base;
struct daemon_remote;
#ifdef USE_METRICS
struct daemon_metrics;
#endif
#ifdef USE_DNSTAP
struct dt_collector;
#endif
#define NSD_RUN 0
#define NSD_RELOAD 1
#define NSD_SHUTDOWN 2
#define NSD_STATS 3
#define NSD_REAP_CHILDREN 4
#define NSD_QUIT 5
#define NSD_RELOAD_REQ 7
#define NSD_RELOAD_DONE 8
#define NSD_QUIT_SYNC 9
#define NSD_QUIT_CHILD 11
#define NSD_RELOAD_FAILED 14
#define NSD_SERVER_MAIN 0x0U
#define NSD_SERVER_UDP 0x1U
#define NSD_SERVER_TCP 0x2U
#define NSD_SERVER_BOTH (NSD_SERVER_UDP | NSD_SERVER_TCP)
#ifdef INET6
#define DEFAULT_AI_FAMILY AF_UNSPEC
#else
#define DEFAULT_AI_FAMILY AF_INET
#endif
#ifdef BIND8_STATS
typedef unsigned long stc_type;
#define LASTELEM(arr) (sizeof(arr) / sizeof(arr[0]) - 1)
#define STATUP(nsd, stc) nsd->st->stc++
#define STATUP2(nsd, stc, i) nsd->st->stc[(i) <= (LASTELEM(nsd->st->stc) - 1) ? i : LASTELEM(nsd->st->stc)]++
#else
#define STATUP(nsd, stc)
#define STATUP2(nsd, stc, i)
#endif
#ifdef USE_ZONE_STATS
#define ZTATUP(nsd, zone, stc) ( \
(zone && zone->zonestatid < nsd->zonestatsizenow) ? \
nsd->zonestatnow[zone->zonestatid].stc++ \
: 0)
#define ZTATUP2(nsd, zone, stc, i) ( \
(zone && zone->zonestatid < nsd->zonestatsizenow) ? \
(nsd->zonestatnow[zone->zonestatid].stc[(i) <= (LASTELEM(nsd->zonestatnow[zone->zonestatid].stc) - 1) ? i : LASTELEM(nsd->zonestatnow[zone->zonestatid].stc)]++ ) \
: 0)
#else
#define ZTATUP(nsd, zone, stc)
#define ZTATUP2(nsd, zone, stc, i)
#endif
#ifdef BIND8_STATS
struct nsdst {
time_t boot;
stc_type reloadcount;
stc_type qtype[257];
stc_type qclass[4];
stc_type qudp, qudp6;
stc_type ctcp, ctcp6;
stc_type ctls, ctls6;
stc_type rcode[17], opcode[6];
stc_type dropped, truncated, wrongzone, txerr, rxerr;
stc_type edns, ednserr, raxfr, nona, rixfr;
uint64_t db_disk, db_mem;
};
#endif
#define NSD_SOCKET_IS_OPTIONAL (1<<0)
#define NSD_BIND_DEVICE (1<<1)
struct nsd_addrinfo
{
int ai_flags;
int ai_family;
int ai_socktype;
socklen_t ai_addrlen;
struct sockaddr_storage ai_addr;
};
struct nsd_socket
{
struct nsd_addrinfo addr;
int s;
int flags;
struct nsd_bitset *servers;
char device[IFNAMSIZ];
int fib;
};
struct nsd_child
{
#ifdef HAVE_CPUSET_T
cpuset_t *cpuset;
#endif
int kind;
pid_t pid;
int child_num;
int child_fd;
int parent_fd;
uint8_t need_to_send_STATS, need_to_send_QUIT;
uint8_t need_to_exit, has_exited;
struct netio_handler* handler;
#ifdef BIND8_STATS
stc_type query_count;
#endif
};
#define NSD_COOKIE_HISTORY_SIZE 2
#define NSD_COOKIE_SECRET_SIZE 16
struct cookie_secret {
uint8_t cookie_secret[NSD_COOKIE_SECRET_SIZE];
};
typedef struct cookie_secret cookie_secret_type;
typedef cookie_secret_type cookie_secrets_type[NSD_COOKIE_HISTORY_SIZE];
enum cookie_secrets_source {
COOKIE_SECRETS_NONE = 0,
COOKIE_SECRETS_GENERATED = 1,
COOKIE_SECRETS_FROM_FILE = 2,
COOKIE_SECRETS_FROM_CONFIG = 3
};
typedef enum cookie_secrets_source cookie_secrets_source_type;
typedef struct nsd nsd_type;
struct nsd
{
region_type *region;
pid_t pid;
volatile sig_atomic_t mode;
volatile sig_atomic_t signal_hint_reload_hup;
volatile sig_atomic_t signal_hint_reload;
volatile sig_atomic_t signal_hint_child;
volatile sig_atomic_t signal_hint_quit;
volatile sig_atomic_t signal_hint_shutdown;
volatile sig_atomic_t signal_hint_stats;
volatile sig_atomic_t signal_hint_statsusr;
volatile sig_atomic_t quit_sync_done;
unsigned server_kind;
struct namedb *db;
int debug;
size_t child_count;
struct nsd_child *children;
int restart_children;
int reload_failed;
struct nsd_child *this_child;
struct udb_base* task[2];
int mytask;
struct event_base* event_base;
region_type* server_region;
struct netio_handler* xfrd_listener;
struct daemon_remote* rc;
#ifdef USE_METRICS
struct daemon_metrics* metrics;
#endif
const char *pidfile;
const char *log_filename;
const char *username;
uid_t uid;
gid_t gid;
const char *chrootdir;
const char *version;
const char *identity;
uint16_t nsid_len;
unsigned char *nsid;
uint8_t file_rotation_ok;
#ifdef HAVE_CPUSET_T
int use_cpu_affinity;
cpuset_t* cpuset;
cpuset_t* xfrd_cpuset;
#endif
size_t ifs;
int reuseport;
struct nsd_socket* tcp;
struct nsd_socket* udp;
size_t verify_ifs;
struct nsd_socket *verify_tcp;
struct nsd_socket *verify_udp;
struct zone *next_zone_to_verify;
size_t verifier_count;
size_t verifier_limit;
int verifier_pipe[2];
struct verifier *verifiers;
#ifdef USE_XDP
struct {
struct xdp_server xdp_server;
} xdp;
#endif
edns_data_type edns_ipv4;
#if defined(INET6)
edns_data_type edns_ipv6;
#endif
int maximum_tcp_count;
int current_tcp_count;
int tcp_query_count;
int tcp_timeout;
int tcp_mss;
int outgoing_tcp_mss;
size_t ipv4_edns_size;
size_t ipv6_edns_size;
#ifdef BIND8_STATS
struct nsdst* st;
int st_period;
struct nsdst* zonestat[2];
int zonestatfd[2];
char* zonestatfname[2];
size_t zonestatsize[2], zonestatdesired, zonestatsizenow;
struct nsdst* zonestatnow;
char* statfname;
int statfd;
struct nsdst* stat_map;
struct nsdst* stats_per_child[2];
int stat_current;
struct nsdst stat_proc;
#endif
#ifdef USE_DNSTAP
struct dt_collector* dt_collector;
int *dt_collector_fd_send, *dt_collector_fd_recv;
int *dt_collector_fd_swap;
#endif
int *serve2xfrd_fd_send, *serve2xfrd_fd_recv;
int *serve2xfrd_fd_swap;
time_t err_limit_time;
unsigned int err_limit_count;
int do_answer_cookie;
size_t cookie_count;
cookie_secrets_type cookie_secrets;
cookie_secrets_source_type cookie_secrets_source;
char* cookie_secrets_filename;
struct nsd_options* options;
#ifdef HAVE_SSL
SSL_CTX *tls_ctx;
SSL_CTX *tls_auth_ctx;
#endif
};
extern struct nsd nsd;
pid_t readpid(const char *file);
int writepid(struct nsd *nsd);
void unlinkpid(const char* file, const char* username);
void sig_handler(int sig);
void bind8_stats(struct nsd *nsd);
int server_init(struct nsd *nsd);
int server_prepare(struct nsd *nsd);
void server_main(struct nsd *nsd);
void server_child(struct nsd *nsd);
void server_shutdown(struct nsd *nsd) ATTR_NORETURN;
void server_close_all_sockets(struct nsd_socket sockets[], size_t n);
const char* nsd_event_vs(void);
const char* nsd_event_method(void);
struct event_base* nsd_child_event_base(void);
void service_remaining_tcp(struct nsd* nsd);
#define EXTRA_DOMAIN_NUMBERS 1024
#define SLOW_ACCEPT_TIMEOUT 2
#define ERROR_RATELIMIT 100
void server_zonestat_alloc(struct nsd* nsd);
void zonestat_remap(struct nsd* nsd, int idx, size_t sz);
void server_stat_alloc(struct nsd* nsd);
void server_stat_free(struct nsd* nsd);
void server_prepare_xfrd(struct nsd *nsd);
void server_start_xfrd(struct nsd *nsd, int del_db, int reload_active);
void server_send_soa_xfrd(struct nsd *nsd, int shortsoa);
#ifdef HAVE_SSL
SSL_CTX* server_tls_ctx_setup(char* key, char* pem, char* verifypem);
SSL_CTX* server_tls_ctx_create(struct nsd *nsd, char* verifypem, char* ocspfile);
void perform_openssl_init(void);
#endif
ssize_t block_read(struct nsd* nsd, int s, void* p, ssize_t sz, int timeout);
#endif