#ifndef OPTIONS_H
#define OPTIONS_H
#include <stdarg.h>
#ifdef HAVE_SSL
#include <openssl/ssl.h>
#endif
#include "region-allocator.h"
#include "rbtree.h"
struct query;
struct dname;
struct tsig_key;
struct buffer;
struct nsd;
struct proxy_protocol_port_list;
typedef struct nsd_options nsd_options_type;
typedef struct pattern_options pattern_options_type;
typedef struct zone_options zone_options_type;
typedef struct range_option range_option_type;
typedef struct ip_address_option ip_address_option_type;
typedef struct cpu_option cpu_option_type;
typedef struct cpu_map_option cpu_map_option_type;
typedef struct acl_options acl_options_type;
typedef struct key_options key_options_type;
typedef struct tls_auth_options tls_auth_options_type;
typedef struct config_parser_state config_parser_state_type;
#define VERIFY_ZONE_INHERIT (2)
#define VERIFIER_FEED_ZONE_INHERIT (2)
#define VERIFIER_TIMEOUT_INHERIT (-1)
#define CATALOG_ROLE_INHERIT (0)
#define CATALOG_ROLE_CONSUMER (1)
#define CATALOG_ROLE_PRODUCER (2)
struct nsd_options {
char* configfile;
rbtree_type* zone_options;
rbtree_type* patterns;
rbtree_type* zonefree;
size_t zonefree_number;
FILE* zonelist;
off_t zonelist_off;
rbtree_type* zonestatnames;
rbtree_type* keys;
rbtree_type* tls_auths;
struct ip_address_option* ip_addresses;
int ip_transparent;
int ip_freebind;
int send_buffer_size;
int receive_buffer_size;
int debug_mode;
int verbosity;
int hide_version;
int hide_identity;
int drop_updates;
int do_ip4;
int do_ip6;
const char* identity;
const char* version;
const char* logfile;
int log_only_syslog;
int server_count;
struct cpu_option* cpu_affinity;
struct cpu_map_option* service_cpu_affinity;
int tcp_count;
int tcp_reject_overflow;
int confine_to_zone;
int tcp_query_count;
int tcp_timeout;
int tcp_mss;
int outgoing_tcp_mss;
int tcp_listen_queue;
size_t ipv4_edns_size;
size_t ipv6_edns_size;
const char* pidfile;
const char* port;
int statistics;
const char* chroot;
const char* username;
const char* zonesdir;
const char* xfrdfile;
const char* xfrdir;
const char* zonelistfile;
const char* nsid;
int xfrd_reload_timeout;
int reload_config;
int zonefiles_check;
int zonefiles_write;
int log_time_ascii;
int log_time_iso;
int round_robin;
int minimal_responses;
int refuse_any;
int reuseport;
int xfrd_tcp_max;
int xfrd_tcp_pipeline;
char* tls_service_key;
char* tls_service_ocsp;
char* tls_service_pem;
const char* tls_port;
const char* tls_auth_port;
const char* tls_cert_bundle;
int tls_auth_xfr_only;
struct proxy_protocol_port_list* proxy_protocol_port;
int control_enable;
struct ip_address_option* control_interface;
int control_port;
char* server_key_file;
char* server_cert_file;
char* control_key_file;
char* control_cert_file;
#ifdef USE_XDP
const char* xdp_interface;
const char* xdp_program_path;
int xdp_program_load;
const char* xdp_bpffs_path;
int xdp_force_copy;
#endif
#ifdef USE_METRICS
int metrics_enable;
struct ip_address_option* metrics_interface;
int metrics_port;
char* metrics_path;
#endif
#ifdef RATELIMIT
size_t rrl_size;
size_t rrl_ratelimit;
size_t rrl_slip;
size_t rrl_ipv4_prefix_length;
size_t rrl_ipv6_prefix_length;
size_t rrl_whitelist_ratelimit;
#endif
int dnstap_enable;
char* dnstap_socket_path;
char* dnstap_ip;
int dnstap_tls;
char* dnstap_tls_server_name;
char* dnstap_tls_cert_bundle;
char* dnstap_tls_client_key_file;
char* dnstap_tls_client_cert_file;
int dnstap_send_identity;
int dnstap_send_version;
char* dnstap_identity;
char* dnstap_version;
int dnstap_log_auth_query_messages;
int dnstap_log_auth_response_messages;
int answer_cookie;
char *cookie_secret;
char *cookie_staging_secret;
char *cookie_secret_file;
uint8_t cookie_secret_file_is_default;
int verify_enable;
struct ip_address_option* verify_ip_addresses;
char *verify_port;
int verify_zones;
char **verifier;
int verifier_count;
uint8_t verifier_feed_zone;
uint32_t verifier_timeout;
region_type* region;
};
struct range_option {
struct range_option* next;
int first;
int last;
};
struct ip_address_option {
struct ip_address_option* next;
char* address;
struct range_option* servers;
int dev;
int fib;
};
struct cpu_option {
struct cpu_option* next;
int cpu;
};
struct cpu_map_option {
struct cpu_map_option* next;
int service;
int cpu;
};
#define EXPIRE_TIME_HAS_VALUE 0
#define EXPIRE_TIME_IS_DEFAULT 1
#define REFRESHPLUSRETRYPLUS1 2
#define REFRESHPLUSRETRYPLUS1_STR "refresh+retry+1"
#define expire_time_is_default(x) (!( (x) == REFRESHPLUSRETRYPLUS1 \
|| (x) == EXPIRE_TIME_HAS_VALUE ))
struct pattern_options {
rbnode_type node;
const char* pname;
const char* zonefile;
struct acl_options* allow_notify;
struct acl_options* request_xfr;
struct acl_options* notify;
struct acl_options* provide_xfr;
struct acl_options* allow_query;
struct acl_options* outgoing_interface;
const char* zonestats;
#ifdef RATELIMIT
uint16_t rrl_whitelist;
#endif
uint8_t allow_axfr_fallback;
uint8_t allow_axfr_fallback_is_default;
uint8_t notify_retry;
uint8_t notify_retry_is_default;
uint8_t implicit;
uint8_t xfrd_flags;
uint32_t max_refresh_time;
uint8_t max_refresh_time_is_default;
uint32_t min_refresh_time;
uint8_t min_refresh_time_is_default;
uint32_t max_retry_time;
uint8_t max_retry_time_is_default;
uint32_t min_retry_time;
uint8_t min_retry_time_is_default;
uint32_t min_expire_time;
uint8_t min_expire_time_expr;
uint64_t size_limit_xfr;
uint8_t multi_primary_check;
uint8_t store_ixfr;
uint8_t store_ixfr_is_default;
uint64_t ixfr_size;
uint8_t ixfr_size_is_default;
uint32_t ixfr_number;
uint8_t ixfr_number_is_default;
uint8_t create_ixfr;
uint8_t create_ixfr_is_default;
uint8_t verify_zone;
uint8_t verify_zone_is_default;
char **verifier;
uint8_t verifier_feed_zone;
uint8_t verifier_feed_zone_is_default;
int32_t verifier_timeout;
uint8_t verifier_timeout_is_default;
uint8_t catalog_role;
uint8_t catalog_role_is_default;
const char* catalog_member_pattern;
const char* catalog_producer_zone;
} ATTR_PACKED;
#define PATTERN_IMPLICIT_MARKER "_implicit_"
struct zone_options {
rbnode_type node;
const char* name;
off_t off;
int linesize;
struct pattern_options* pattern;
unsigned part_of_config : 1;
unsigned is_catalog_member_zone: 1;
} ATTR_PACKED;
struct catalog_member_zone {
struct zone_options options;
const struct dname* member_id;
rbnode_type node;
} ATTR_PACKED;
typedef void (*new_member_id_type)(struct catalog_member_zone* zone);
union acl_addr_storage {
#ifdef INET6
struct in_addr addr;
struct in6_addr addr6;
#else
struct in_addr addr;
#endif
};
struct acl_options {
struct acl_options* next;
time_t ixfr_disabled;
int bad_xfr_count;
uint8_t use_axfr_only;
uint8_t allow_udp;
const char* ip_address_spec;
uint8_t is_ipv6;
unsigned int port;
union acl_addr_storage addr;
union acl_addr_storage range_mask;
enum {
acl_range_single = 0,
acl_range_mask = 1,
acl_range_subnet = 2,
acl_range_minmax = 3
} rangetype;
uint8_t nokey;
uint8_t blocked;
const char* key_name;
struct key_options* key_options;
const char* tls_auth_name;
struct tls_auth_options* tls_auth_options;
} ATTR_PACKED;
struct key_options {
rbnode_type node;
char* name;
char* algorithm;
char* secret;
struct tsig_key* tsig_key;
} ATTR_PACKED;
struct tls_auth_options {
rbnode_type node;
char* name;
char* auth_domain_name;
char* client_cert;
char* client_key;
char* client_key_pw;
};
struct proxy_protocol_port_list {
struct proxy_protocol_port_list* next;
int port;
};
struct zonelist_free {
struct zonelist_free* next;
off_t off;
};
struct zonelist_bucket {
rbnode_type node;
int linesize;
struct zonelist_free* list;
};
#define ZONEFILES_WRITE_INTERVAL 3600
struct zonestatname {
rbnode_type node;
unsigned id;
};
struct config_parser_state {
char* filename;
const char* chroot;
int line;
int errors;
struct nsd_options* opt;
struct pattern_options *pattern;
struct zone_options *zone;
struct key_options *key;
struct tls_auth_options *tls_auth;
struct ip_address_option *ip;
void (*err)(void*,const char*);
void* err_arg;
};
extern config_parser_state_type* cfg_parser;
struct nsd_options* nsd_options_create(region_type* region);
static inline size_t nsd_options_num_zones(struct nsd_options* opt)
{ return opt->zone_options->count; }
int nsd_options_insert_zone(struct nsd_options* opt, struct zone_options* zone);
int nsd_options_insert_pattern(struct nsd_options* opt,
struct pattern_options* pat);
int parse_options_file(struct nsd_options* opt, const char* file,
void (*err)(void*,const char*), void* err_arg,
struct nsd_options* old_opts);
struct zone_options* zone_options_create(region_type* region);
void zone_options_delete(struct nsd_options* opt, struct zone_options* zone);
struct catalog_member_zone* catalog_member_zone_create(region_type* region);
static inline struct catalog_member_zone* as_catalog_member_zone(struct zone_options* zopt)
{ return zopt && zopt->is_catalog_member_zone ? (struct catalog_member_zone*)zopt : NULL; }
struct zone_options* zone_options_find(struct nsd_options* opt,
const struct dname* apex);
struct pattern_options* pattern_options_create(region_type* region);
struct pattern_options* pattern_options_find(struct nsd_options* opt, const char* name);
int pattern_options_equal(struct pattern_options* p, struct pattern_options* q);
void pattern_options_remove(struct nsd_options* opt, const char* name);
void pattern_options_add_modify(struct nsd_options* opt,
struct pattern_options* p);
void pattern_options_marshal(struct buffer* buffer, struct pattern_options* p);
struct pattern_options* pattern_options_unmarshal(region_type* r,
struct buffer* b);
struct key_options* key_options_create(region_type* region);
void key_options_insert(struct nsd_options* opt, struct key_options* key);
struct key_options* key_options_find(struct nsd_options* opt, const char* name);
void key_options_remove(struct nsd_options* opt, const char* name);
int key_options_equal(struct key_options* p, struct key_options* q);
void key_options_add_modify(struct nsd_options* opt, struct key_options* key);
void key_options_setup(region_type* region, struct key_options* key);
void key_options_desetup(region_type* region, struct key_options* key);
struct tls_auth_options* tls_auth_options_create(region_type* region);
void tls_auth_options_insert(struct nsd_options* opt, struct tls_auth_options* auth);
struct tls_auth_options* tls_auth_options_find(struct nsd_options* opt, const char* name);
int parse_zone_list_file(struct nsd_options* opt);
struct zone_options* zone_list_add_or_cat(struct nsd_options* opt,
const char* zname, const char* pname, new_member_id_type new_member_id);
static inline struct zone_options* zone_list_add(struct nsd_options* opt,
const char* zname, const char* pname)
{ return zone_list_add_or_cat(opt, zname, pname, NULL); }
struct zone_options* zone_list_zone_insert(struct nsd_options* opt,
const char* nm, const char* patnm);
void zone_list_del(struct nsd_options* opt, struct zone_options* zone);
void zone_list_compact(struct nsd_options* opt);
void zone_list_close(struct nsd_options* opt);
void options_zonestatnames_create(struct nsd_options* opt);
unsigned getzonestatid(struct nsd_options* opt, struct zone_options* zopt);
const char* config_cook_string(struct zone_options* zone, const char* input);
int options_remote_is_address(struct nsd_options* cfg);
#if defined(HAVE_SSL)
void key_options_tsig_add(struct nsd_options* opt);
#endif
int acl_check_incoming(struct acl_options* acl, struct query* q,
struct acl_options** reason);
int acl_addr_matches_host(struct acl_options* acl, struct acl_options* host);
int acl_addr_matches(struct acl_options* acl, struct query* q);
int acl_addr_matches_proxy(struct acl_options* acl, struct query* q);
#ifdef HAVE_SSL
int acl_tls_hostname_matches(SSL* ssl, const char* acl_cert_cn);
#endif
int acl_key_matches(struct acl_options* acl, struct query* q);
int acl_addr_match_mask(uint32_t* a, uint32_t* b, uint32_t* mask, size_t sz);
int acl_addr_match_range_v6(uint32_t* minval, uint32_t* x, uint32_t* maxval, size_t sz);
int acl_addr_match_range_v4(uint32_t* minval, uint32_t* x, uint32_t* maxval, size_t sz);
int acl_check_incoming_block_proxy(struct acl_options* acl, struct query* q,
struct acl_options** reason);
int acl_same_host(struct acl_options* a, struct acl_options* b);
struct acl_options* acl_find_num(struct acl_options* acl, int num);
int acl_list_equal(struct acl_options* p, struct acl_options* q);
int acl_equal(struct acl_options* p, struct acl_options* q);
int zone_is_slave(struct zone_options* opt);
static inline int zone_is_catalog_consumer(struct zone_options* opt)
{ return opt && opt->pattern
&& opt->pattern->catalog_role == CATALOG_ROLE_CONSUMER; }
static inline int zone_is_catalog_producer(struct zone_options* opt)
{ return opt && opt->pattern
&& opt->pattern->catalog_role == CATALOG_ROLE_PRODUCER; }
static inline int zone_is_catalog_member(struct zone_options* opt)
{ return opt && opt->is_catalog_member_zone; }
static inline const char* zone_is_catalog_producer_member(struct zone_options* opt)
{ return opt && opt->pattern && opt->pattern->catalog_producer_zone
? opt->pattern->catalog_producer_zone : NULL; }
static inline int zone_is_catalog_consumer_member(struct zone_options* opt)
{ return zone_is_catalog_member(opt) && !zone_is_catalog_producer_member(opt); }
const char* config_make_zonefile(struct zone_options* zone, struct nsd* nsd);
#define ZONEC_PCT_TIME 5
#define ZONEC_PCT_COUNT 100000
void c_error(const char* msg, ...) ATTR_FORMAT(printf, 1,2);
int c_wrap(void);
struct acl_options* parse_acl_info(region_type* region, char* ip,
const char* key);
int parse_acl_is_ipv6(const char* p);
int parse_acl_range_type(char* ip, char** mask);
void parse_acl_range_subnet(char* p, void* addr, int maxbits);
void nsd_options_destroy(struct nsd_options* opt);
void replace_str(char* buf, size_t len, const char* one, const char* two);
void config_apply_pattern(struct pattern_options *dest, const char* name);
void warn_if_directory(const char* filetype, FILE* f, const char* fname);
void resolve_interface_names(struct nsd_options* options);
int sockaddr_uses_proxy_protocol_port(struct nsd_options* options,
struct sockaddr* addr);
#endif