diff --git a/external/bsd/nsd/dist/.buildkite/pipeline.yml b/external/bsd/nsd/dist/.buildkite/pipeline.yml new file mode 100644 index 000000000000..4322223ed7d4 --- /dev/null +++ b/external/bsd/nsd/dist/.buildkite/pipeline.yml @@ -0,0 +1,7 @@ +steps: + - label: Build + commands: + - autoconf && autoheader + - ./configure --enable-checking --disable-flto + - make + - make cutest && ./cutest diff --git a/external/bsd/nsd/dist/.travis.yml b/external/bsd/nsd/dist/.travis.yml new file mode 100644 index 000000000000..a01410d4bbb6 --- /dev/null +++ b/external/bsd/nsd/dist/.travis.yml @@ -0,0 +1,66 @@ +sudo: false +language: c + +linux_gcc: &linux_gcc + os: linux + dist: xenial + compiler: gcc + addons: + apt: + update: true + sources: [ ubuntu-toolchain-r-test ] + packages: [ autoconf bison flex libssl-dev libevent-dev clang gcc-9 ] + before_install: + - eval "export CC=gcc-9" + - eval "export COV_COMPTYPE=gcc COV_PLATFORM=linux64" + +install_coverity: &install_coverity + if [ "${COVERITY_SCAN}" = "true" ]; then + COV_DIR="/tmp/coverity-scan-analysis"; + COV_ARC="/tmp/cov-analysis-${COV_PLATFORM}.tgz"; + test ! -d "${COV_DIR}" && + mkdir -p "${COV_DIR}" && + curl -s -S -F project="${TRAVIS_REPO_SLUG}" + -F token="${COVERITY_SCAN_TOKEN}" + -o "${COV_ARC}" + "https://scan.coverity.com/download/cxx/${COV_PLATFORM}" && + tar -xzf "${COV_ARC}" -C "${COV_DIR}"; + COV_ANALYSIS=$(find "${COV_DIR}" -type d -name "cov-analysis*"); + eval "export PATH=\"${PATH}:${COV_ANALYSIS}/bin\""; + eval "export SCAN_BUILD=\"cov-build --dir cov-int\""; + cov-configure --comptype ${COV_COMPTYPE} --compiler ${CC} --template; + fi + +submit_to_coverity_scan: &submit_to_coverity_scan + if [ "${COVERITY_SCAN}" = "true" ]; then + tar -czf analysis-results.tgz cov-int && + curl -s -S -F project="${TRAVIS_REPO_SLUG}" + -F token="${COVERITY_SCAN_TOKEN}" + -F file=@analysis-results.tgz + -F version=$(git rev-parse --short HEAD) + -F description="Travis CI build" + -F email="${COVERITY_EMAIL:=spam@nlnetlabs.nl}" + "https://scan.coverity.com/builds"; + fi + +install: + - *install_coverity + +script: + - autoconf && autoheader + - ./configure --enable-checking --disable-flto + - ${SCAN_BUILD} make + - make cutest && ./cutest + - (cd tpkg; cd clang-analysis.tdir; bash clang-analysis.test) + +after_success: + - *submit_to_coverity_scan + +jobs: + include: + - <<: *linux_gcc + env: [ COVERITY_SCAN=true ] + if: type = cron + - <<: *linux_gcc + env: [ COVERITY_SCAN=false ] + diff --git a/external/bsd/nsd/dist/Makefile.in b/external/bsd/nsd/dist/Makefile.in index 4165f42969ac..128d54858e12 100644 --- a/external/bsd/nsd/dist/Makefile.in +++ b/external/bsd/nsd/dist/Makefile.in @@ -176,12 +176,16 @@ xfr-inspect: xfr-inspect.o $(COMMON_OBJ) $(LIBOBJS) clean: rm -f *.o $(TARGETS) $(MANUALS) cutest udb-inspect xfr-inspect nsd-mem -realclean: clean - rm -f Makefile config.h config.log config.status +distclean: clean + rm -f Makefile config.h config.log config.status dnstap/dnstap_config.h + +realclean: distclean rm -rf autom4te* rm -f zlexer.c zparser.h zparser.c zparser.stamp rm -f configlexer.c configparser.h configparser.c configparser.stamp +maintainer-clean: realclean + devclean: realclean rm -f config.h.in configure diff --git a/external/bsd/nsd/dist/README.md b/external/bsd/nsd/dist/README.md new file mode 100644 index 000000000000..b457bb7b82b8 --- /dev/null +++ b/external/bsd/nsd/dist/README.md @@ -0,0 +1,42 @@ +# NSD + +[![Travis Build Status](https://travis-ci.org/NLnetLabs/nsd.svg?branch=master)](https://travis-ci.org/NLnetLabs/nsd) +[![Packaging status](https://repology.org/badge/tiny-repos/nsd.svg)](https://repology.org/project/nsd/versions) +[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/1462/badge)](https://bestpractices.coreinfrastructure.org/projects/1462) + +The NLnet Labs Name Server Daemon (NSD) is an authoritative DNS name server. +It has been developed for operations in environments where speed, +reliability, stability and security are of high importance. If you +have any feedback, we would love to hear from you. Don’t hesitate to +[create an issue on Github](https://github.com/NLnetLabs/nsd/issues/new) +or post a message on the +[NSD mailing list](https://nlnetlabs.nl/mailman/listinfo/nsd-users). +You can lean more about NSD by reading our +[documentation](https://nlnetlabs.nl/documentation/nsd/). + +## Compiling + +Make sure you have the C toolchain, OpenSSL and its include files, and +libevent with its include files and flex and bison installed. +The repository does not contain ./configure and you can generate it like +this (./configure is included in release tarballs, and then you do not +have to generate it first): + +``` +aclocal && autoconf && autoheader +``` + +NSD can be compiled and installed using: + +``` +./configure && make && make install +``` + +## NSD configuration + +The configuration options for NSD are described in the man pages, which are +installed (use `man nsd.conf`) and are available on the NSD +[documentation page](https://nlnetlabs.nl/documentation/nsd/). + +An example configuration file is located in +[nsd.conf.sample](https://github.com/NLnetLabs/nsd/blob/master/nsd.conf.sample.in). diff --git a/external/bsd/nsd/dist/config.h.in b/external/bsd/nsd/dist/config.h.in index 04a4ab145fcb..fbb44e267246 100644 --- a/external/bsd/nsd/dist/config.h.in +++ b/external/bsd/nsd/dist/config.h.in @@ -73,12 +73,26 @@ /* Define to 1 if you have the `clock_gettime' function. */ #undef HAVE_CLOCK_GETTIME +/* Define to 1 if you have the `CRYPTO_memcmp' function. */ +#undef HAVE_CRYPTO_MEMCMP + /* if time.h provides ctime_r prototype */ #undef HAVE_CTIME_R_PROTO +/* Define to 1 if you have the declaration of `SSL_CTX_set_ecdh_auto', and to + 0 if you don't. */ +#undef HAVE_DECL_SSL_CTX_SET_ECDH_AUTO + +/* Define to 1 if you have the declaration of `SSL_CTX_set_tmp_ecdh', and to 0 + if you don't. */ +#undef HAVE_DECL_SSL_CTX_SET_TMP_ECDH + /* Define to 1 if you have the `dup2' function. */ #undef HAVE_DUP2 +/* Define to 1 if you have the `EC_KEY_new_by_curve_name' function. */ +#undef HAVE_EC_KEY_NEW_BY_CURVE_NAME + /* Define to 1 if you have the header file. */ #undef HAVE_ENDIAN_H @@ -200,6 +214,9 @@ /* Define to 1 if you have the `mmap' function. */ #undef HAVE_MMAP +/* If sys/socket.h has a struct mmsghdr. */ +#undef HAVE_MMSGHDR + /* Define to 1 if you have the `munmap' function. */ #undef HAVE_MUNMAP @@ -221,6 +238,9 @@ /* Define to 1 if you have the `OPENSSL_init_ssl' function. */ #undef HAVE_OPENSSL_INIT_SSL +/* Define to 1 if you have the header file. */ +#undef HAVE_OPENSSL_OCSP_H + /* Define to 1 if you have the header file. */ #undef HAVE_OPENSSL_RAND_H @@ -239,7 +259,7 @@ /* Define to 1 if you have the `pwrite' function. */ #undef HAVE_PWRITE -/* Define to 1 if you have the `reallocarray' function. */ +/* If we have reallocarray(3) */ #undef HAVE_REALLOCARRAY /* Define if recvmmsg is implemented */ @@ -281,6 +301,9 @@ /* Define if you have the SSL libraries installed. */ #undef HAVE_SSL +/* Define to 1 if you have the `SSL_CTX_set_security_level' function. */ +#undef HAVE_SSL_CTX_SET_SECURITY_LEVEL + /* Define to 1 if you have the header file. */ #undef HAVE_STDARG_H @@ -507,6 +530,9 @@ /* Define to the default tcp timeout. */ #undef TCP_TIMEOUT +/* Define to the default DNS over TLS port. */ +#undef TLS_PORT + /* Define to the default maximum udp message length. */ #undef UDP_MAX_MESSAGE_LEN @@ -550,6 +576,9 @@ #endif +/* Define this to enable TCP fast open. */ +#undef USE_TCP_FASTOPEN + /* Define this to enable per-zone statistics gathering. */ #undef USE_ZONE_STATS @@ -688,6 +717,9 @@ # ifndef _BSD_SOURCE # define _BSD_SOURCE 1 # endif +# ifndef _OPENBSD_SOURCE +# define _OPENBSD_SOURCE 1 +# endif # ifndef _DEFAULT_SOURCE # define _DEFAULT_SOURCE 1 # endif diff --git a/external/bsd/nsd/dist/configlexer.lex b/external/bsd/nsd/dist/configlexer.lex index d9178b84eef8..d405cc68a31a 100644 --- a/external/bsd/nsd/dist/configlexer.lex +++ b/external/bsd/nsd/dist/configlexer.lex @@ -25,7 +25,6 @@ #include "options.h" #include "configyyrename.h" #include "configparser.h" -void c_error(const char *message); #if 0 #define LEXOUT(s) printf s /* used ONLY when debugging */ @@ -58,27 +57,27 @@ static void config_start_include(const char* filename) struct inc_state* s; char* nm; if(inc_depth++ > 10000000) { - c_error_msg("too many include files"); + yyerror("too many include files"); return; } if(strlen(filename) == 0) { - c_error_msg("empty include file name"); + yyerror("empty include file name"); return; } s = (struct inc_state*)malloc(sizeof(*s)); if(!s) { - c_error_msg("include %s: malloc failure", filename); + yyerror("include %s: malloc failure", filename); return; } nm = strdup(filename); if(!nm) { - c_error_msg("include %s: strdup failure", filename); + yyerror("include %s: strdup failure", filename); free(s); return; } input = fopen(filename, "r"); if(!input) { - c_error_msg("cannot open include file '%s': %s", + yyerror("cannot open include file '%s': %s", filename, strerror(errno)); free(s); free(nm); @@ -101,13 +100,12 @@ static void config_start_include_glob(const char* filename) /* check for wildcards */ #ifdef HAVE_GLOB glob_t g; - size_t i; - int r, flags; + int i, r, flags; #endif /* HAVE_GLOB */ if (cfg_parser->chroot) { int l = strlen(cfg_parser->chroot); /* chroot has trailing slash */ if (strncmp(cfg_parser->chroot, filename, l) != 0) { - c_error_msg("include file '%s' is not relative to chroot '%s'", + yyerror("include file '%s' is not relative to chroot '%s'", filename, cfg_parser->chroot); return; } @@ -141,7 +139,7 @@ static void config_start_include_glob(const char* filename) return; } /* process files found, if any */ - for(i=0; i<(size_t)g.gl_pathc; i++) { + for(i=(int)g.gl_pathc-1; i>=0; i--) { config_start_include(g.gl_pathv[i]); } globfree(&g); @@ -205,9 +203,12 @@ ip-address{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_IP_ADDRESS;} interface{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_IP_ADDRESS;} ip-transparent{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_IP_TRANSPARENT;} ip-freebind{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_IP_FREEBIND;} +send-buffer-size{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_SEND_BUFFER_SIZE;} +receive-buffer-size{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_RECEIVE_BUFFER_SIZE;} debug-mode{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_DEBUG_MODE;} use-systemd{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_USE_SYSTEMD;} hide-version{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_HIDE_VERSION;} +hide-identity{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_HIDE_IDENTITY;} ip4-only{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_IP4_ONLY;} ip6-only{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_IP6_ONLY;} do-ip4{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_DO_IP4;} @@ -219,6 +220,7 @@ nsid{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_NSID;} logfile{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_LOGFILE;} server-count{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_SERVER_COUNT;} tcp-count{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_TCP_COUNT;} +tcp-reject-overflow{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_TCP_REJECT_OVERFLOW;} tcp-query-count{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_TCP_QUERY_COUNT;} tcp-timeout{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_TCP_TIMEOUT;} tcp-mss{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_TCP_MSS;} @@ -253,7 +255,7 @@ key{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_KEY;} algorithm{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_ALGORITHM;} secret{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_SECRET;} pattern{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_PATTERN;} -include-pattern{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_INCLUDEPATTERN;} +include-pattern{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_INCLUDE_PATTERN;} remote-control{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_REMOTE_CONTROL;} control-enable{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_CONTROL_ENABLE;} control-interface{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_CONTROL_INTERFACE;} @@ -285,12 +287,17 @@ dnstap-log-auth-response-messages{COLON} { LEXOUT(("v(%s) ", yytext)); return VA log-time-ascii{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_LOG_TIME_ASCII;} round-robin{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_ROUND_ROBIN;} minimal-responses{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_MINIMAL_RESPONSES;} +confine-to-zone{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_CONFINE_TO_ZONE;} refuse-any{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_REFUSE_ANY;} max-refresh-time{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_MAX_REFRESH_TIME;} min-refresh-time{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_MIN_REFRESH_TIME;} max-retry-time{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_MAX_RETRY_TIME;} min-retry-time{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_MIN_RETRY_TIME;} multi-master-check{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_MULTI_MASTER_CHECK;} +tls-service-key{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_TLS_SERVICE_KEY;} +tls-service-ocsp{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_TLS_SERVICE_OCSP;} +tls-service-pem{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_TLS_SERVICE_PEM;} +tls-port{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_TLS_PORT;} {NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++;} /* Quoted strings. Strip leading and ending quotes */ diff --git a/external/bsd/nsd/dist/configparser.y b/external/bsd/nsd/dist/configparser.y index d1e17b21b24d..37fe39e00592 100644 --- a/external/bsd/nsd/dist/configparser.y +++ b/external/bsd/nsd/dist/configparser.y @@ -1,7 +1,7 @@ /* * configparser.y -- yacc grammar for NSD configuration files * - * Copyright (c) 2001-2006, NLnet Labs. All rights reserved. + * Copyright (c) 2001-2019, NLnet Labs. All rights reserved. * * See LICENSE for the license. * @@ -10,11 +10,10 @@ %{ #include "config.h" -#include +#include +#include #include #include -#include -#include #include "options.h" #include "util.h" @@ -22,1038 +21,758 @@ #include "tsig.h" #include "rrl.h" #include "configyyrename.h" -int c_lex(void); -void c_error(const char *message); + +int yylex(void); #ifdef __cplusplus extern "C" -#endif /* __cplusplus */ +#endif /* these need to be global, otherwise they cannot be used inside yacc */ -extern config_parser_state_type* cfg_parser; - -#if 0 -#define OUTYY(s) printf s /* used ONLY when debugging */ -#else -#define OUTYY(s) -#endif +extern config_parser_state_type *cfg_parser; +static void append_acl(struct acl_options **list, struct acl_options *acl); %} + %union { - char* str; + char *str; + long long llng; + int bln; + struct ip_address_option *ip; } -%token SPACE LETTER NEWLINE COMMENT COLON ANY ZONESTR %token STRING -%token VAR_SERVER VAR_NAME VAR_IP_ADDRESS VAR_IP_TRANSPARENT VAR_DEBUG_MODE -%token VAR_IP4_ONLY VAR_IP6_ONLY VAR_DATABASE VAR_IDENTITY VAR_NSID VAR_LOGFILE -%token VAR_SERVER_COUNT VAR_TCP_COUNT VAR_PIDFILE VAR_PORT VAR_STATISTICS -%token VAR_CHROOT VAR_USERNAME VAR_ZONESDIR VAR_XFRDFILE VAR_DIFFFILE -%token VAR_XFRD_RELOAD_TIMEOUT VAR_TCP_QUERY_COUNT VAR_TCP_TIMEOUT -%token VAR_IPV4_EDNS_SIZE VAR_IPV6_EDNS_SIZE VAR_DO_IP4 VAR_DO_IP6 -%token VAR_TCP_MSS VAR_OUTGOING_TCP_MSS VAR_IP_FREEBIND -%token VAR_ZONEFILE -%token VAR_ZONE -%token VAR_ALLOW_NOTIFY VAR_REQUEST_XFR VAR_NOTIFY VAR_PROVIDE_XFR VAR_SIZE_LIMIT_XFR -%token VAR_NOTIFY_RETRY VAR_OUTGOING_INTERFACE VAR_ALLOW_AXFR_FALLBACK -%token VAR_KEY -%token VAR_ALGORITHM VAR_SECRET -%token VAR_AXFR VAR_UDP -%token VAR_VERBOSITY VAR_HIDE_VERSION -%token VAR_PATTERN VAR_INCLUDEPATTERN VAR_ZONELISTFILE -%token VAR_REMOTE_CONTROL VAR_CONTROL_ENABLE VAR_CONTROL_INTERFACE -%token VAR_CONTROL_PORT VAR_SERVER_KEY_FILE VAR_SERVER_CERT_FILE -%token VAR_CONTROL_KEY_FILE VAR_CONTROL_CERT_FILE VAR_XFRDIR -%token VAR_RRL_SIZE VAR_RRL_RATELIMIT VAR_RRL_SLIP -%token VAR_RRL_IPV4_PREFIX_LENGTH VAR_RRL_IPV6_PREFIX_LENGTH -%token VAR_RRL_WHITELIST_RATELIMIT VAR_RRL_WHITELIST -%token VAR_ZONEFILES_CHECK VAR_ZONEFILES_WRITE VAR_LOG_TIME_ASCII -%token VAR_ROUND_ROBIN VAR_ZONESTATS VAR_REUSEPORT VAR_VERSION -%token VAR_MAX_REFRESH_TIME VAR_MIN_REFRESH_TIME -%token VAR_MAX_RETRY_TIME VAR_MIN_RETRY_TIME -%token VAR_MULTI_MASTER_CHECK VAR_MINIMAL_RESPONSES VAR_REFUSE_ANY -%token VAR_USE_SYSTEMD VAR_DNSTAP VAR_DNSTAP_ENABLE VAR_DNSTAP_SOCKET_PATH -%token VAR_DNSTAP_SEND_IDENTITY VAR_DNSTAP_SEND_VERSION VAR_DNSTAP_IDENTITY -%token VAR_DNSTAP_VERSION VAR_DNSTAP_LOG_AUTH_QUERY_MESSAGES +%type number +%type boolean +%type ip_address + +/* server */ +%token VAR_SERVER +%token VAR_SERVER_COUNT +%token VAR_IP_ADDRESS +%token VAR_IP_TRANSPARENT +%token VAR_IP_FREEBIND +%token VAR_REUSEPORT +%token VAR_SEND_BUFFER_SIZE +%token VAR_RECEIVE_BUFFER_SIZE +%token VAR_DEBUG_MODE +%token VAR_IP4_ONLY +%token VAR_IP6_ONLY +%token VAR_DO_IP4 +%token VAR_DO_IP6 +%token VAR_PORT +%token VAR_USE_SYSTEMD +%token VAR_VERBOSITY +%token VAR_USERNAME +%token VAR_CHROOT +%token VAR_ZONESDIR +%token VAR_ZONELISTFILE +%token VAR_DATABASE +%token VAR_LOGFILE +%token VAR_PIDFILE +%token VAR_DIFFFILE +%token VAR_XFRDFILE +%token VAR_XFRDIR +%token VAR_HIDE_VERSION +%token VAR_HIDE_IDENTITY +%token VAR_VERSION +%token VAR_IDENTITY +%token VAR_NSID +%token VAR_TCP_COUNT +%token VAR_TCP_REJECT_OVERFLOW +%token VAR_TCP_QUERY_COUNT +%token VAR_TCP_TIMEOUT +%token VAR_TCP_MSS +%token VAR_OUTGOING_TCP_MSS +%token VAR_IPV4_EDNS_SIZE +%token VAR_IPV6_EDNS_SIZE +%token VAR_STATISTICS +%token VAR_XFRD_RELOAD_TIMEOUT +%token VAR_LOG_TIME_ASCII +%token VAR_ROUND_ROBIN +%token VAR_MINIMAL_RESPONSES +%token VAR_CONFINE_TO_ZONE +%token VAR_REFUSE_ANY +%token VAR_ZONEFILES_CHECK +%token VAR_ZONEFILES_WRITE +%token VAR_RRL_SIZE +%token VAR_RRL_RATELIMIT +%token VAR_RRL_SLIP +%token VAR_RRL_IPV4_PREFIX_LENGTH +%token VAR_RRL_IPV6_PREFIX_LENGTH +%token VAR_RRL_WHITELIST_RATELIMIT +%token VAR_TLS_SERVICE_KEY +%token VAR_TLS_SERVICE_PEM +%token VAR_TLS_SERVICE_OCSP +%token VAR_TLS_PORT + +/* dnstap */ +%token VAR_DNSTAP +%token VAR_DNSTAP_ENABLE +%token VAR_DNSTAP_SOCKET_PATH +%token VAR_DNSTAP_SEND_IDENTITY +%token VAR_DNSTAP_SEND_VERSION +%token VAR_DNSTAP_IDENTITY +%token VAR_DNSTAP_VERSION +%token VAR_DNSTAP_LOG_AUTH_QUERY_MESSAGES %token VAR_DNSTAP_LOG_AUTH_RESPONSE_MESSAGES -%% -toplevelvars: /* empty */ | toplevelvars toplevelvar ; -toplevelvar: serverstart contents_server | zonestart contents_zone | - keystart contents_key | patternstart contents_pattern | - rcstart contents_rc | dtstart contents_dt; +/* remote-control */ +%token VAR_REMOTE_CONTROL +%token VAR_CONTROL_ENABLE +%token VAR_CONTROL_INTERFACE +%token VAR_CONTROL_PORT +%token VAR_SERVER_KEY_FILE +%token VAR_SERVER_CERT_FILE +%token VAR_CONTROL_KEY_FILE +%token VAR_CONTROL_CERT_FILE -/* server: declaration */ -serverstart: VAR_SERVER - { OUTYY(("\nP(server:)\n")); - if(cfg_parser->server_settings_seen) { - yyerror("duplicate server: element."); - } - cfg_parser->server_settings_seen = 1; - } - ; -contents_server: contents_server content_server | ; -content_server: server_ip_address | server_ip_transparent | server_debug_mode | server_ip4_only | - server_ip6_only | server_database | server_identity | server_nsid | server_logfile | - server_server_count | server_tcp_count | server_pidfile | server_port | - server_statistics | server_chroot | server_username | server_zonesdir | - server_difffile | server_xfrdfile | server_xfrd_reload_timeout | - server_tcp_query_count | server_tcp_timeout | server_ipv4_edns_size | - server_ipv6_edns_size | server_verbosity | server_hide_version | - server_zonelistfile | server_xfrdir | - server_tcp_mss | server_outgoing_tcp_mss | - server_rrl_size | server_rrl_ratelimit | server_rrl_slip | - server_rrl_ipv4_prefix_length | server_rrl_ipv6_prefix_length | server_rrl_whitelist_ratelimit | - server_zonefiles_check | server_do_ip4 | server_do_ip6 | - server_zonefiles_write | server_log_time_ascii | server_round_robin | - server_reuseport | server_version | server_ip_freebind | - server_minimal_responses | server_refuse_any | server_use_systemd; -server_ip_address: VAR_IP_ADDRESS STRING - { - OUTYY(("P(server_ip_address:%s)\n", $2)); - if(cfg_parser->current_ip_address_option) { - cfg_parser->current_ip_address_option->next = - (ip_address_option_type*)region_alloc( - cfg_parser->opt->region, sizeof(ip_address_option_type)); - cfg_parser->current_ip_address_option = - cfg_parser->current_ip_address_option->next; - cfg_parser->current_ip_address_option->next=0; - } else { - cfg_parser->current_ip_address_option = - (ip_address_option_type*)region_alloc( - cfg_parser->opt->region, sizeof(ip_address_option_type)); - cfg_parser->current_ip_address_option->next=0; - cfg_parser->opt->ip_addresses = cfg_parser->current_ip_address_option; - } +/* key */ +%token VAR_KEY +%token VAR_ALGORITHM +%token VAR_SECRET - cfg_parser->current_ip_address_option->address = - region_strdup(cfg_parser->opt->region, $2); - } - ; -server_ip_transparent: VAR_IP_TRANSPARENT STRING - { - OUTYY(("P(server_ip_transparent:%s)\n", $2)); - if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) - yyerror("expected yes or no."); - else cfg_parser->opt->ip_transparent = (strcmp($2, "yes")==0); - } - ; -server_ip_freebind: VAR_IP_FREEBIND STRING - { - OUTYY(("P(server_ip_freebind:%s)\n", $2)); - if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) - yyerror("expected yes or no."); - else cfg_parser->opt->ip_freebind = (strcmp($2, "yes")==0); - } - ; -server_debug_mode: VAR_DEBUG_MODE STRING - { - OUTYY(("P(server_debug_mode:%s)\n", $2)); - if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) - yyerror("expected yes or no."); - else cfg_parser->opt->debug_mode = (strcmp($2, "yes")==0); - } - ; -server_use_systemd: VAR_USE_SYSTEMD STRING - { - OUTYY(("P(server_use_systemd:%s)\n", $2)); - } - ; -server_verbosity: VAR_VERBOSITY STRING - { - OUTYY(("P(server_verbosity:%s)\n", $2)); - if(atoi($2) == 0 && strcmp($2, "0") != 0) - yyerror("number expected"); - else cfg_parser->opt->verbosity = atoi($2); - } - ; -server_hide_version: VAR_HIDE_VERSION STRING - { - OUTYY(("P(server_hide_version:%s)\n", $2)); - if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) - yyerror("expected yes or no."); - else cfg_parser->opt->hide_version = (strcmp($2, "yes")==0); - } - ; -server_ip4_only: VAR_IP4_ONLY STRING - { - /* for backwards compatibility in config file with NSD3 */ - OUTYY(("P(server_ip4_only:%s)\n", $2)); - if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) - yyerror("expected yes or no."); - else if(strcmp($2, "yes")==0) { - cfg_parser->opt->do_ip4 = 1; - cfg_parser->opt->do_ip6 = 0; - } - } - ; -server_ip6_only: VAR_IP6_ONLY STRING - { - /* for backwards compatibility in config file with NSD3 */ - OUTYY(("P(server_ip6_only:%s)\n", $2)); - if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) - yyerror("expected yes or no."); - else if(strcmp($2, "yes")==0) { - cfg_parser->opt->do_ip6 = 1; - cfg_parser->opt->do_ip4 = 0; - } - } - ; -server_do_ip4: VAR_DO_IP4 STRING - { - OUTYY(("P(server_do_ip4:%s)\n", $2)); - if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) - yyerror("expected yes or no."); - else cfg_parser->opt->do_ip4 = (strcmp($2, "yes")==0); - } - ; -server_do_ip6: VAR_DO_IP6 STRING - { - OUTYY(("P(server_do_ip6:%s)\n", $2)); - if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) - yyerror("expected yes or no."); - else cfg_parser->opt->do_ip6 = (strcmp($2, "yes")==0); - } - ; -server_reuseport: VAR_REUSEPORT STRING - { - OUTYY(("P(server_reuseport:%s)\n", $2)); - if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) - yyerror("expected yes or no."); - else cfg_parser->opt->reuseport = (strcmp($2, "yes")==0); - } - ; -server_database: VAR_DATABASE STRING - { - OUTYY(("P(server_database:%s)\n", $2)); - cfg_parser->opt->database = region_strdup(cfg_parser->opt->region, $2); - if(cfg_parser->opt->database[0] == 0 && - cfg_parser->opt->zonefiles_write == 0) - cfg_parser->opt->zonefiles_write = ZONEFILES_WRITE_INTERVAL; - } - ; -server_identity: VAR_IDENTITY STRING - { - OUTYY(("P(server_identity:%s)\n", $2)); - cfg_parser->opt->identity = region_strdup(cfg_parser->opt->region, $2); - } - ; -server_version: VAR_VERSION STRING - { - OUTYY(("P(server_version:%s)\n", $2)); - cfg_parser->opt->version = region_strdup(cfg_parser->opt->region, $2); - } - ; -server_nsid: VAR_NSID STRING - { - unsigned char* nsid = 0; - size_t nsid_len = 0; +/* pattern */ +%token VAR_PATTERN +%token VAR_NAME +%token VAR_ZONEFILE +%token VAR_NOTIFY +%token VAR_PROVIDE_XFR +%token VAR_AXFR +%token VAR_UDP +%token VAR_NOTIFY_RETRY +%token VAR_ALLOW_NOTIFY +%token VAR_REQUEST_XFR +%token VAR_ALLOW_AXFR_FALLBACK +%token VAR_OUTGOING_INTERFACE +%token VAR_MAX_REFRESH_TIME +%token VAR_MIN_REFRESH_TIME +%token VAR_MAX_RETRY_TIME +%token VAR_MIN_RETRY_TIME +%token VAR_MULTI_MASTER_CHECK +%token VAR_SIZE_LIMIT_XFR +%token VAR_ZONESTATS +%token VAR_INCLUDE_PATTERN - OUTYY(("P(server_nsid:%s)\n", $2)); - - if (strncasecmp($2, "ascii_", 6) == 0) { - nsid_len = strlen($2+6); - if(nsid_len < 65535) { - cfg_parser->opt->nsid = region_alloc(cfg_parser->opt->region, nsid_len*2+1); - hex_ntop((uint8_t*)$2+6, nsid_len, (char*)cfg_parser->opt->nsid, nsid_len*2+1); - } else - yyerror("NSID too long"); - } else if (strlen($2) % 2 != 0) { - yyerror("the NSID must be a hex string of an even length."); - } else { - nsid_len = strlen($2) / 2; - if(nsid_len < 65535) { - nsid = xalloc(nsid_len); - if (hex_pton($2, nsid, nsid_len) == -1) - yyerror("hex string cannot be parsed in NSID."); - else - cfg_parser->opt->nsid = region_strdup(cfg_parser->opt->region, $2); - free(nsid); - } else - yyerror("NSID too long"); - } - } - ; -server_logfile: VAR_LOGFILE STRING - { - OUTYY(("P(server_logfile:%s)\n", $2)); - cfg_parser->opt->logfile = region_strdup(cfg_parser->opt->region, $2); - } - ; -server_log_time_ascii: VAR_LOG_TIME_ASCII STRING - { - OUTYY(("P(server_log_time_ascii:%s)\n", $2)); - if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) - yyerror("expected yes or no."); - else { - cfg_parser->opt->log_time_ascii = (strcmp($2, "yes")==0); - log_time_asc = cfg_parser->opt->log_time_ascii; - } - } - ; -server_round_robin: VAR_ROUND_ROBIN STRING - { - OUTYY(("P(server_round_robin:%s)\n", $2)); - if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) - yyerror("expected yes or no."); - else { - cfg_parser->opt->round_robin = (strcmp($2, "yes")==0); - round_robin = cfg_parser->opt->round_robin; - } - } - ; -server_minimal_responses: VAR_MINIMAL_RESPONSES STRING - { - OUTYY(("P(server_minimal_responses:%s)\n", $2)); - if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) - yyerror("expected yes or no."); - else { - cfg_parser->opt->minimal_responses = (strcmp($2, "yes")==0); - minimal_responses = cfg_parser->opt->minimal_responses; - } - } - ; -server_refuse_any: VAR_REFUSE_ANY STRING - { - OUTYY(("P(server_refuse_any:%s)\n", $2)); - if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) - yyerror("expected yes or no."); - else { - cfg_parser->opt->refuse_any = (strcmp($2, "yes")==0); - } - } - ; -server_server_count: VAR_SERVER_COUNT STRING - { - OUTYY(("P(server_server_count:%s)\n", $2)); - if(atoi($2) <= 0) - yyerror("number greater than zero expected"); - else cfg_parser->opt->server_count = atoi($2); - } - ; -server_tcp_count: VAR_TCP_COUNT STRING - { - OUTYY(("P(server_tcp_count:%s)\n", $2)); - if(atoi($2) <= 0) - yyerror("number greater than zero expected"); - else cfg_parser->opt->tcp_count = atoi($2); - } - ; -server_pidfile: VAR_PIDFILE STRING - { - OUTYY(("P(server_pidfile:%s)\n", $2)); - cfg_parser->opt->pidfile = region_strdup(cfg_parser->opt->region, $2); - } - ; -server_port: VAR_PORT STRING - { - OUTYY(("P(server_port:%s)\n", $2)); - cfg_parser->opt->port = region_strdup(cfg_parser->opt->region, $2); - } - ; -server_statistics: VAR_STATISTICS STRING - { - OUTYY(("P(server_statistics:%s)\n", $2)); - if(atoi($2) == 0 && strcmp($2, "0") != 0) - yyerror("number expected"); - else cfg_parser->opt->statistics = atoi($2); - } - ; -server_chroot: VAR_CHROOT STRING - { - OUTYY(("P(server_chroot:%s)\n", $2)); - cfg_parser->opt->chroot = region_strdup(cfg_parser->opt->region, $2); - } - ; -server_username: VAR_USERNAME STRING - { - OUTYY(("P(server_username:%s)\n", $2)); - cfg_parser->opt->username = region_strdup(cfg_parser->opt->region, $2); - } - ; -server_zonesdir: VAR_ZONESDIR STRING - { - OUTYY(("P(server_zonesdir:%s)\n", $2)); - cfg_parser->opt->zonesdir = region_strdup(cfg_parser->opt->region, $2); - } - ; -server_zonelistfile: VAR_ZONELISTFILE STRING - { - OUTYY(("P(server_zonelistfile:%s)\n", $2)); - cfg_parser->opt->zonelistfile = region_strdup(cfg_parser->opt->region, $2); - } - ; -server_xfrdir: VAR_XFRDIR STRING - { - OUTYY(("P(server_xfrdir:%s)\n", $2)); - cfg_parser->opt->xfrdir = region_strdup(cfg_parser->opt->region, $2); - } - ; -server_difffile: VAR_DIFFFILE STRING - { - OUTYY(("P(server_difffile:%s)\n", $2)); - /* ignore the value for backwards compatibility in config file*/ - } - ; -server_xfrdfile: VAR_XFRDFILE STRING - { - OUTYY(("P(server_xfrdfile:%s)\n", $2)); - cfg_parser->opt->xfrdfile = region_strdup(cfg_parser->opt->region, $2); - } - ; -server_xfrd_reload_timeout: VAR_XFRD_RELOAD_TIMEOUT STRING - { - OUTYY(("P(server_xfrd_reload_timeout:%s)\n", $2)); - if(atoi($2) == 0 && strcmp($2, "0") != 0) - yyerror("number expected"); - cfg_parser->opt->xfrd_reload_timeout = atoi($2); - } - ; -server_tcp_query_count: VAR_TCP_QUERY_COUNT STRING - { - OUTYY(("P(server_tcp_query_count:%s)\n", $2)); - if(atoi($2) == 0 && strcmp($2, "0") != 0) - yyerror("number expected"); - cfg_parser->opt->tcp_query_count = atoi($2); - } - ; -server_tcp_timeout: VAR_TCP_TIMEOUT STRING - { - OUTYY(("P(server_tcp_timeout:%s)\n", $2)); - if(atoi($2) == 0 && strcmp($2, "0") != 0) - yyerror("number expected"); - cfg_parser->opt->tcp_timeout = atoi($2); - } - ; -server_tcp_mss: VAR_TCP_MSS STRING - { - OUTYY(("P(server_tcp_mss:%s)\n", $2)); - if(atoi($2) == 0 && strcmp($2, "0") != 0) - yyerror("number expected"); - cfg_parser->opt->tcp_mss = atoi($2); - } - ; -server_outgoing_tcp_mss: VAR_OUTGOING_TCP_MSS STRING - { - OUTYY(("P(server_outgoing_tcp_mss:%s)\n", $2)); - if(atoi($2) == 0 && strcmp($2, "0") != 0) - yyerror("number expected"); - cfg_parser->opt->outgoing_tcp_mss = atoi($2); - } - ; -server_ipv4_edns_size: VAR_IPV4_EDNS_SIZE STRING - { - OUTYY(("P(server_ipv4_edns_size:%s)\n", $2)); - if(atoi($2) == 0 && strcmp($2, "0") != 0) - yyerror("number expected"); - cfg_parser->opt->ipv4_edns_size = atoi($2); - } - ; -server_ipv6_edns_size: VAR_IPV6_EDNS_SIZE STRING - { - OUTYY(("P(server_ipv6_edns_size:%s)\n", $2)); - if(atoi($2) == 0 && strcmp($2, "0") != 0) - yyerror("number expected"); - cfg_parser->opt->ipv6_edns_size = atoi($2); - } - ; -server_rrl_size: VAR_RRL_SIZE STRING - { - OUTYY(("P(server_rrl_size:%s)\n", $2)); -#ifdef RATELIMIT - if(atoi($2) <= 0) - yyerror("number greater than zero expected"); - cfg_parser->opt->rrl_size = atoi($2); -#endif - } - ; -server_rrl_ratelimit: VAR_RRL_RATELIMIT STRING - { - OUTYY(("P(server_rrl_ratelimit:%s)\n", $2)); -#ifdef RATELIMIT - cfg_parser->opt->rrl_ratelimit = atoi($2); -#endif - } - ; -server_rrl_slip: VAR_RRL_SLIP STRING - { - OUTYY(("P(server_rrl_slip:%s)\n", $2)); -#ifdef RATELIMIT - if(atoi($2) < 0) - yyerror("number equal or greater than zero expected"); - cfg_parser->opt->rrl_slip = atoi($2); -#endif - } - ; -server_rrl_ipv4_prefix_length: VAR_RRL_IPV4_PREFIX_LENGTH STRING - { - OUTYY(("P(server_rrl_ipv4_prefix_length:%s)\n", $2)); -#ifdef RATELIMIT - if(atoi($2) < 0 || atoi($2) > 32) - yyerror("invalid IPv4 prefix length"); - cfg_parser->opt->rrl_ipv4_prefix_length = atoi($2); -#endif - } - ; -server_rrl_ipv6_prefix_length: VAR_RRL_IPV6_PREFIX_LENGTH STRING - { - OUTYY(("P(server_rrl_ipv6_prefix_length:%s)\n", $2)); -#ifdef RATELIMIT - if(atoi($2) < 0 || atoi($2) > 64) - yyerror("invalid IPv6 prefix length"); - cfg_parser->opt->rrl_ipv6_prefix_length = atoi($2); -#endif - } - ; -server_rrl_whitelist_ratelimit: VAR_RRL_WHITELIST_RATELIMIT STRING - { - OUTYY(("P(server_rrl_whitelist_ratelimit:%s)\n", $2)); -#ifdef RATELIMIT - cfg_parser->opt->rrl_whitelist_ratelimit = atoi($2); -#endif - } - ; -server_zonefiles_check: VAR_ZONEFILES_CHECK STRING - { - OUTYY(("P(server_zonefiles_check:%s)\n", $2)); - if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) - yyerror("expected yes or no."); - else cfg_parser->opt->zonefiles_check = (strcmp($2, "yes")==0); - } - ; -server_zonefiles_write: VAR_ZONEFILES_WRITE STRING - { - OUTYY(("P(server_zonefiles_write:%s)\n", $2)); - if(atoi($2) == 0 && strcmp($2, "0") != 0) - yyerror("number expected"); - else cfg_parser->opt->zonefiles_write = atoi($2); - } - ; - -rcstart: VAR_REMOTE_CONTROL - { - OUTYY(("\nP(remote-control:)\n")); - } - ; -contents_rc: contents_rc content_rc - | ; -content_rc: rc_control_enable | rc_control_interface | rc_control_port | - rc_server_key_file | rc_server_cert_file | rc_control_key_file | - rc_control_cert_file - ; -rc_control_enable: VAR_CONTROL_ENABLE STRING - { - OUTYY(("P(control_enable:%s)\n", $2)); - if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) - yyerror("expected yes or no."); - else cfg_parser->opt->control_enable = (strcmp($2, "yes")==0); - } - ; -rc_control_port: VAR_CONTROL_PORT STRING - { - OUTYY(("P(control_port:%s)\n", $2)); - if(atoi($2) == 0) - yyerror("control port number expected"); - else cfg_parser->opt->control_port = atoi($2); - } - ; -rc_control_interface: VAR_CONTROL_INTERFACE STRING - { - ip_address_option_type* last = NULL; - ip_address_option_type* o = (ip_address_option_type*)region_alloc( - cfg_parser->opt->region, sizeof(ip_address_option_type)); - OUTYY(("P(control_interface:%s)\n", $2)); - /* append at end */ - last = cfg_parser->opt->control_interface; - while(last && last->next) - last = last->next; - if(last == NULL) - cfg_parser->opt->control_interface = o; - else last->next = o; - o->next = NULL; - o->address = region_strdup(cfg_parser->opt->region, $2); - } - ; -rc_server_key_file: VAR_SERVER_KEY_FILE STRING - { - OUTYY(("P(rc_server_key_file:%s)\n", $2)); - cfg_parser->opt->server_key_file = region_strdup(cfg_parser->opt->region, $2); - } - ; -rc_server_cert_file: VAR_SERVER_CERT_FILE STRING - { - OUTYY(("P(rc_server_cert_file:%s)\n", $2)); - cfg_parser->opt->server_cert_file = region_strdup(cfg_parser->opt->region, $2); - } - ; -rc_control_key_file: VAR_CONTROL_KEY_FILE STRING - { - OUTYY(("P(rc_control_key_file:%s)\n", $2)); - cfg_parser->opt->control_key_file = region_strdup(cfg_parser->opt->region, $2); - } - ; -rc_control_cert_file: VAR_CONTROL_CERT_FILE STRING - { - OUTYY(("P(rc_control_cert_file:%s)\n", $2)); - cfg_parser->opt->control_cert_file = region_strdup(cfg_parser->opt->region, $2); - } - ; - -/* dnstap: declaration */ -dtstart: VAR_DNSTAP - { - OUTYY(("\nP(dnstap:)\n")); - } - ; -contents_dt: contents_dt content_dt - | ; -content_dt: dt_dnstap_enable | dt_dnstap_socket_path | - dt_dnstap_send_identity | dt_dnstap_send_version | - dt_dnstap_identity | dt_dnstap_version | - dt_dnstap_log_auth_query_messages | - dt_dnstap_log_auth_response_messages - ; -dt_dnstap_enable: VAR_DNSTAP_ENABLE STRING - { - OUTYY(("P(dt_dnstap_enable:%s)\n", $2)); - if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) - yyerror("expected yes or no."); - else cfg_parser->opt->dnstap_enable = (strcmp($2, "yes")==0); - } - ; -dt_dnstap_socket_path: VAR_DNSTAP_SOCKET_PATH STRING - { - OUTYY(("P(dt_dnstap_socket_path:%s)\n", $2)); - cfg_parser->opt->dnstap_socket_path = region_strdup(cfg_parser->opt->region, $2); - } - ; -dt_dnstap_send_identity: VAR_DNSTAP_SEND_IDENTITY STRING - { - OUTYY(("P(dt_dnstap_send_identity:%s)\n", $2)); - if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) - yyerror("expected yes or no."); - else cfg_parser->opt->dnstap_send_identity = (strcmp($2, "yes")==0); - } - ; -dt_dnstap_send_version: VAR_DNSTAP_SEND_VERSION STRING - { - OUTYY(("P(dt_dnstap_send_version:%s)\n", $2)); - if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) - yyerror("expected yes or no."); - else cfg_parser->opt->dnstap_send_version = (strcmp($2, "yes")==0); - } - ; -dt_dnstap_identity: VAR_DNSTAP_IDENTITY STRING - { - OUTYY(("P(dt_dnstap_identity:%s)\n", $2)); - cfg_parser->opt->dnstap_identity = region_strdup(cfg_parser->opt->region, $2); - } - ; -dt_dnstap_version: VAR_DNSTAP_VERSION STRING - { - OUTYY(("P(dt_dnstap_version:%s)\n", $2)); - cfg_parser->opt->dnstap_version = region_strdup(cfg_parser->opt->region, $2); - } - ; -dt_dnstap_log_auth_query_messages: VAR_DNSTAP_LOG_AUTH_QUERY_MESSAGES STRING - { - OUTYY(("P(dt_dnstap_log_auth_query_messages:%s)\n", $2)); - if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) - yyerror("expected yes or no."); - else cfg_parser->opt->dnstap_log_auth_query_messages = (strcmp($2, "yes")==0); - } - ; -dt_dnstap_log_auth_response_messages: VAR_DNSTAP_LOG_AUTH_RESPONSE_MESSAGES STRING - { - OUTYY(("P(dt_dnstap_log_auth_response_messages:%s)\n", $2)); - if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) - yyerror("expected yes or no."); - else cfg_parser->opt->dnstap_log_auth_response_messages = (strcmp($2, "yes")==0); - } - ; - -/* pattern: declaration */ -patternstart: VAR_PATTERN - { - OUTYY(("\nP(pattern:)\n")); - if(cfg_parser->current_zone) { - if(!cfg_parser->current_zone->name) - c_error("previous zone has no name"); - else { - if(!nsd_options_insert_zone(cfg_parser->opt, - cfg_parser->current_zone)) - c_error("duplicate zone"); - } - if(!cfg_parser->current_zone->pattern) - c_error("previous zone has no pattern"); - cfg_parser->current_zone = NULL; - } - if(cfg_parser->current_pattern) { - if(!cfg_parser->current_pattern->pname) - c_error("previous pattern has no name"); - else { - if(!nsd_options_insert_pattern(cfg_parser->opt, - cfg_parser->current_pattern)) - c_error_msg("duplicate pattern %s", - cfg_parser->current_pattern->pname); - } - } - cfg_parser->current_pattern = pattern_options_create( - cfg_parser->opt->region); - cfg_parser->current_allow_notify = 0; - cfg_parser->current_request_xfr = 0; - cfg_parser->current_notify = 0; - cfg_parser->current_provide_xfr = 0; - cfg_parser->current_outgoing_interface = 0; - } - ; -contents_pattern: contents_pattern content_pattern | content_pattern; -content_pattern: pattern_name | zone_config_item; -zone_config_item: zone_zonefile | zone_allow_notify | zone_request_xfr | - zone_notify | zone_notify_retry | zone_provide_xfr | - zone_outgoing_interface | zone_allow_axfr_fallback | include_pattern | - zone_rrl_whitelist | zone_zonestats | zone_max_refresh_time | - zone_min_refresh_time | zone_max_retry_time | zone_min_retry_time | - zone_size_limit_xfr | zone_multi_master_check; -pattern_name: VAR_NAME STRING - { - OUTYY(("P(pattern_name:%s)\n", $2)); -#ifndef NDEBUG - assert(cfg_parser->current_pattern); -#endif - if(strchr($2, ' ')) - c_error_msg("space is not allowed in pattern name: " - "'%s'", $2); - cfg_parser->current_pattern->pname = region_strdup(cfg_parser->opt->region, $2); - } - ; -include_pattern: VAR_INCLUDEPATTERN STRING - { - OUTYY(("P(include-pattern:%s)\n", $2)); -#ifndef NDEBUG - assert(cfg_parser->current_pattern); -#endif - config_apply_pattern($2); - } - ; - -/* zone: declaration */ -zonestart: VAR_ZONE - { - OUTYY(("\nP(zone:)\n")); - if(cfg_parser->current_zone) { - if(!cfg_parser->current_zone->name) - c_error("previous zone has no name"); - else { - if(!nsd_options_insert_zone(cfg_parser->opt, - cfg_parser->current_zone)) - c_error("duplicate zone"); - } - if(!cfg_parser->current_zone->pattern) - c_error("previous zone has no pattern"); - } - if(cfg_parser->current_pattern) { - if(!cfg_parser->current_pattern->pname) - c_error("previous pattern has no name"); - else { - if(!nsd_options_insert_pattern(cfg_parser->opt, - cfg_parser->current_pattern)) - c_error_msg("duplicate pattern %s", - cfg_parser->current_pattern->pname); - } - } - cfg_parser->current_zone = zone_options_create(cfg_parser->opt->region); - cfg_parser->current_zone->part_of_config = 1; - cfg_parser->current_pattern = pattern_options_create( - cfg_parser->opt->region); - cfg_parser->current_pattern->implicit = 1; - cfg_parser->current_zone->pattern = cfg_parser->current_pattern; - cfg_parser->current_allow_notify = 0; - cfg_parser->current_request_xfr = 0; - cfg_parser->current_notify = 0; - cfg_parser->current_provide_xfr = 0; - cfg_parser->current_outgoing_interface = 0; - } - ; -contents_zone: contents_zone content_zone | content_zone; -content_zone: zone_name | zone_config_item; -zone_name: VAR_NAME STRING - { - char* s; - OUTYY(("P(zone_name:%s)\n", $2)); -#ifndef NDEBUG - assert(cfg_parser->current_zone); - assert(cfg_parser->current_pattern); -#endif - cfg_parser->current_zone->name = region_strdup(cfg_parser->opt->region, $2); - s = (char*)region_alloc(cfg_parser->opt->region, - strlen($2)+strlen(PATTERN_IMPLICIT_MARKER)+1); - memmove(s, PATTERN_IMPLICIT_MARKER, - strlen(PATTERN_IMPLICIT_MARKER)); - memmove(s+strlen(PATTERN_IMPLICIT_MARKER), $2, strlen($2)+1); - if(pattern_options_find(cfg_parser->opt, s)) - c_error_msg("zone %s cannot be created because " - "implicit pattern %s already exists", $2, s); - cfg_parser->current_pattern->pname = s; - } - ; -zone_zonefile: VAR_ZONEFILE STRING - { - OUTYY(("P(zonefile:%s)\n", $2)); -#ifndef NDEBUG - assert(cfg_parser->current_pattern); -#endif - cfg_parser->current_pattern->zonefile = region_strdup(cfg_parser->opt->region, $2); - } - ; -zone_zonestats: VAR_ZONESTATS STRING - { - OUTYY(("P(zonestats:%s)\n", $2)); -#ifndef NDEBUG - assert(cfg_parser->current_pattern); -#endif - cfg_parser->current_pattern->zonestats = region_strdup(cfg_parser->opt->region, $2); - } - ; -zone_allow_notify: VAR_ALLOW_NOTIFY STRING STRING - { - acl_options_type* acl = parse_acl_info(cfg_parser->opt->region, $2, $3); - OUTYY(("P(allow_notify:%s %s)\n", $2, $3)); - if(cfg_parser->current_allow_notify) - cfg_parser->current_allow_notify->next = acl; - else - cfg_parser->current_pattern->allow_notify = acl; - cfg_parser->current_allow_notify = acl; - } - ; -zone_request_xfr: VAR_REQUEST_XFR zone_request_xfr_data - { - } - ; -zone_size_limit_xfr: VAR_SIZE_LIMIT_XFR STRING - { - OUTYY(("P(size_limit_xfr:%s)\n", $2)); - if(atoll($2) < 0) - yyerror("number >= 0 expected"); - else cfg_parser->current_pattern->size_limit_xfr = atoll($2); - } - ; -zone_request_xfr_data: STRING STRING - { - acl_options_type* acl = parse_acl_info(cfg_parser->opt->region, $1, $2); - OUTYY(("P(request_xfr:%s %s)\n", $1, $2)); - if(acl->blocked) c_error("blocked address used for request-xfr"); - if(acl->rangetype!=acl_range_single) c_error("address range used for request-xfr"); - if(cfg_parser->current_request_xfr) - cfg_parser->current_request_xfr->next = acl; - else - cfg_parser->current_pattern->request_xfr = acl; - cfg_parser->current_request_xfr = acl; - } - | VAR_AXFR STRING STRING - { - acl_options_type* acl = parse_acl_info(cfg_parser->opt->region, $2, $3); - acl->use_axfr_only = 1; - OUTYY(("P(request_xfr:%s %s)\n", $2, $3)); - if(acl->blocked) c_error("blocked address used for request-xfr"); - if(acl->rangetype!=acl_range_single) c_error("address range used for request-xfr"); - if(cfg_parser->current_request_xfr) - cfg_parser->current_request_xfr->next = acl; - else - cfg_parser->current_pattern->request_xfr = acl; - cfg_parser->current_request_xfr = acl; - } - | VAR_UDP STRING STRING - { - acl_options_type* acl = parse_acl_info(cfg_parser->opt->region, $2, $3); - acl->allow_udp = 1; - OUTYY(("P(request_xfr:%s %s)\n", $2, $3)); - if(acl->blocked) c_error("blocked address used for request-xfr"); - if(acl->rangetype!=acl_range_single) c_error("address range used for request-xfr"); - if(cfg_parser->current_request_xfr) - cfg_parser->current_request_xfr->next = acl; - else - cfg_parser->current_pattern->request_xfr = acl; - cfg_parser->current_request_xfr = acl; - } - ; -zone_notify: VAR_NOTIFY STRING STRING - { - acl_options_type* acl = parse_acl_info(cfg_parser->opt->region, $2, $3); - OUTYY(("P(notify:%s %s)\n", $2, $3)); - if(acl->blocked) c_error("blocked address used for notify"); - if(acl->rangetype!=acl_range_single) c_error("address range used for notify"); - if(cfg_parser->current_notify) - cfg_parser->current_notify->next = acl; - else - cfg_parser->current_pattern->notify = acl; - cfg_parser->current_notify = acl; - } - ; -zone_notify_retry: VAR_NOTIFY_RETRY STRING - { - OUTYY(("P(notify_retry:%s)\n", $2)); - if(atoi($2) == 0 && strcmp($2, "0") != 0) - yyerror("number expected"); - else { - cfg_parser->current_pattern->notify_retry = atoi($2); - cfg_parser->current_pattern->notify_retry_is_default=0; - } - } - ; -zone_provide_xfr: VAR_PROVIDE_XFR STRING STRING - { - acl_options_type* acl = parse_acl_info(cfg_parser->opt->region, $2, $3); - OUTYY(("P(provide_xfr:%s %s)\n", $2, $3)); - if(cfg_parser->current_provide_xfr) - cfg_parser->current_provide_xfr->next = acl; - else - cfg_parser->current_pattern->provide_xfr = acl; - cfg_parser->current_provide_xfr = acl; - } - ; -zone_outgoing_interface: VAR_OUTGOING_INTERFACE STRING - { - acl_options_type* acl = parse_acl_info(cfg_parser->opt->region, $2, "NOKEY"); - OUTYY(("P(outgoing_interface:%s)\n", $2)); - if(acl->rangetype!=acl_range_single) c_error("address range used for outgoing interface"); - if(cfg_parser->current_outgoing_interface) - cfg_parser->current_outgoing_interface->next = acl; - else - cfg_parser->current_pattern->outgoing_interface = acl; - cfg_parser->current_outgoing_interface = acl; - } - ; -zone_allow_axfr_fallback: VAR_ALLOW_AXFR_FALLBACK STRING - { - OUTYY(("P(allow_axfr_fallback:%s)\n", $2)); - if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) - yyerror("expected yes or no."); - else { - cfg_parser->current_pattern->allow_axfr_fallback = (strcmp($2, "yes")==0); - cfg_parser->current_pattern->allow_axfr_fallback_is_default = 0; - } - } - ; -zone_rrl_whitelist: VAR_RRL_WHITELIST STRING - { - OUTYY(("P(zone_rrl_whitelist:%s)\n", $2)); -#ifdef RATELIMIT - cfg_parser->current_pattern->rrl_whitelist |= rrlstr2type($2); -#endif - } - ; -zone_max_refresh_time: VAR_MAX_REFRESH_TIME STRING -{ - OUTYY(("P(zone_max_refresh_time:%s)\n", $2)); - if(atoi($2) == 0 && strcmp($2, "0") != 0) - yyerror("number expected"); - else { - cfg_parser->current_pattern->max_refresh_time = atoi($2); - cfg_parser->current_pattern->max_refresh_time_is_default = 0; - } -}; -zone_min_refresh_time: VAR_MIN_REFRESH_TIME STRING -{ - OUTYY(("P(zone_min_refresh_time:%s)\n", $2)); - if(atoi($2) == 0 && strcmp($2, "0") != 0) - yyerror("number expected"); - else { - cfg_parser->current_pattern->min_refresh_time = atoi($2); - cfg_parser->current_pattern->min_refresh_time_is_default = 0; - } -}; -zone_max_retry_time: VAR_MAX_RETRY_TIME STRING -{ - OUTYY(("P(zone_max_retry_time:%s)\n", $2)); - if(atoi($2) == 0 && strcmp($2, "0") != 0) - yyerror("number expected"); - else { - cfg_parser->current_pattern->max_retry_time = atoi($2); - cfg_parser->current_pattern->max_retry_time_is_default = 0; - } -}; -zone_min_retry_time: VAR_MIN_RETRY_TIME STRING -{ - OUTYY(("P(zone_min_retry_time:%s)\n", $2)); - if(atoi($2) == 0 && strcmp($2, "0") != 0) - yyerror("number expected"); - else { - cfg_parser->current_pattern->min_retry_time = atoi($2); - cfg_parser->current_pattern->min_retry_time_is_default = 0; - } -}; -zone_multi_master_check: VAR_MULTI_MASTER_CHECK STRING - { - OUTYY(("P(zone_multi_master_check:%s)\n", $2)); - if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) - yyerror("expected yes or no."); - else cfg_parser->current_pattern->multi_master_check = (strcmp($2, "yes")==0); - } - -/* key: declaration */ -keystart: VAR_KEY - { - OUTYY(("\nP(key:)\n")); - if(cfg_parser->current_key) { - if(!cfg_parser->current_key->name) c_error("previous key has no name"); - if(!cfg_parser->current_key->algorithm) c_error("previous key has no algorithm"); - if(!cfg_parser->current_key->secret) c_error("previous key has no secret blob"); - key_options_insert(cfg_parser->opt, cfg_parser->current_key); - } - cfg_parser->current_key = key_options_create(cfg_parser->opt->region); - cfg_parser->current_key->algorithm = region_strdup(cfg_parser->opt->region, "sha256"); - } - ; -contents_key: contents_key content_key | content_key; -content_key: key_name | key_algorithm | key_secret; -key_name: VAR_NAME STRING - { - const dname_type* d; - OUTYY(("P(key_name:%s)\n", $2)); -#ifndef NDEBUG - assert(cfg_parser->current_key); -#endif - cfg_parser->current_key->name = region_strdup(cfg_parser->opt->region, $2); - d = dname_parse(cfg_parser->opt->region, $2); - if(!d) c_error_msg("Failed to parse tsig key name %s", $2); - else region_recycle(cfg_parser->opt->region, (void*)d, - dname_total_size(d)); - } - ; -key_algorithm: VAR_ALGORITHM STRING - { - OUTYY(("P(key_algorithm:%s)\n", $2)); -#ifndef NDEBUG - assert(cfg_parser->current_key); -#endif - if(cfg_parser->current_key->algorithm) - region_recycle(cfg_parser->opt->region, cfg_parser->current_key->algorithm, strlen(cfg_parser->current_key->algorithm)+1); - cfg_parser->current_key->algorithm = region_strdup(cfg_parser->opt->region, $2); - if(tsig_get_algorithm_by_name($2) == NULL) - c_error_msg("Bad tsig algorithm %s", $2); - } - ; -key_secret: VAR_SECRET STRING - { - uint8_t data[16384]; - int size; - OUTYY(("key_secret:%s)\n", $2)); -#ifndef NDEBUG - assert(cfg_parser->current_key); -#endif - cfg_parser->current_key->secret = region_strdup(cfg_parser->opt->region, $2); - size = b64_pton($2, data, sizeof(data)); - if(size == -1) { - c_error_msg("Cannot base64 decode tsig secret %s", - cfg_parser->current_key->name? - cfg_parser->current_key->name:""); - } else if(size != 0) { - memset(data, 0xdd, size); /* wipe secret */ - } - } - ; +/* zone */ +%token VAR_ZONE +%token VAR_RRL_WHITELIST %% -/* parse helper routines could be here */ +blocks: + /* may be empty */ + | blocks block ; + +block: + server + | dnstap + | remote_control + | key + | pattern + | zone ; + +server: + VAR_SERVER server_block ; + +server_block: + server_block server_option | ; + +server_option: + VAR_IP_ADDRESS ip_address + { + struct ip_address_option *ip = cfg_parser->opt->ip_addresses; + if(ip == NULL) { + cfg_parser->opt->ip_addresses = $2; + } else { + while(ip->next) { ip = ip->next; } + ip->next = $2; + } + } + | VAR_SERVER_COUNT number + { + if ($2 > 0) { + cfg_parser->opt->server_count = (int)$2; + } else { + yyerror("expected a number greater than zero"); + } + } + | VAR_IP_TRANSPARENT boolean + { cfg_parser->opt->ip_transparent = (int)$2; } + | VAR_IP_FREEBIND boolean + { cfg_parser->opt->ip_freebind = $2; } + | VAR_SEND_BUFFER_SIZE number + { cfg_parser->opt->send_buffer_size = (int)$2; } + | VAR_RECEIVE_BUFFER_SIZE number + { cfg_parser->opt->receive_buffer_size = (int)$2; } + | VAR_DEBUG_MODE boolean + { cfg_parser->opt->debug_mode = $2; } + | VAR_USE_SYSTEMD boolean + { /* ignored, deprecated */ } + | VAR_HIDE_VERSION boolean + { cfg_parser->opt->hide_version = $2; } + | VAR_HIDE_IDENTITY boolean + { cfg_parser->opt->hide_identity = $2; } + | VAR_IP4_ONLY boolean + { if($2) { cfg_parser->opt->do_ip4 = 1; cfg_parser->opt->do_ip6 = 0; } } + | VAR_IP6_ONLY boolean + { if($2) { cfg_parser->opt->do_ip4 = 0; cfg_parser->opt->do_ip6 = 1; } } + | VAR_DO_IP4 boolean + { cfg_parser->opt->do_ip4 = $2; } + | VAR_DO_IP6 boolean + { cfg_parser->opt->do_ip6 = $2; } + | VAR_DATABASE STRING + { + cfg_parser->opt->database = region_strdup(cfg_parser->opt->region, $2); + if(cfg_parser->opt->database[0] == 0 && + cfg_parser->opt->zonefiles_write == 0) + { + cfg_parser->opt->zonefiles_write = ZONEFILES_WRITE_INTERVAL; + } + } + | VAR_IDENTITY STRING + { cfg_parser->opt->identity = region_strdup(cfg_parser->opt->region, $2); } + | VAR_VERSION STRING + { cfg_parser->opt->version = region_strdup(cfg_parser->opt->region, $2); } + | VAR_NSID STRING + { + unsigned char* nsid = 0; + size_t nsid_len = strlen($2); + + if (strncasecmp($2, "ascii_", 6) == 0) { + nsid_len -= 6; /* discard "ascii_" */ + if(nsid_len < 65535) { + cfg_parser->opt->nsid = region_alloc(cfg_parser->opt->region, nsid_len*2+1); + hex_ntop((uint8_t*)$2+6, nsid_len, (char*)cfg_parser->opt->nsid, nsid_len*2+1); + } else { + yyerror("NSID too long"); + } + } else if (nsid_len % 2 != 0) { + yyerror("the NSID must be a hex string of an even length."); + } else { + nsid_len = nsid_len / 2; + if(nsid_len < 65535) { + nsid = xalloc(nsid_len); + if (hex_pton($2, nsid, nsid_len) == -1) { + yyerror("hex string cannot be parsed in NSID."); + } else { + cfg_parser->opt->nsid = region_strdup(cfg_parser->opt->region, $2); + } + free(nsid); + } else { + yyerror("NSID too long"); + } + } + } + | VAR_LOGFILE STRING + { cfg_parser->opt->logfile = region_strdup(cfg_parser->opt->region, $2); } + | VAR_TCP_COUNT number + { + if ($2 > 0) { + cfg_parser->opt->tcp_count = (int)$2; + } else { + yyerror("expected a number greater than zero"); + } + } + | VAR_TCP_REJECT_OVERFLOW boolean + { cfg_parser->opt->tcp_reject_overflow = $2; } + | VAR_TCP_QUERY_COUNT number + { cfg_parser->opt->tcp_query_count = (int)$2; } + | VAR_TCP_TIMEOUT number + { cfg_parser->opt->tcp_timeout = (int)$2; } + | VAR_TCP_MSS number + { cfg_parser->opt->tcp_mss = (int)$2; } + | VAR_OUTGOING_TCP_MSS number + { cfg_parser->opt->outgoing_tcp_mss = (int)$2; } + | VAR_IPV4_EDNS_SIZE number + { cfg_parser->opt->ipv4_edns_size = (size_t)$2; } + | VAR_IPV6_EDNS_SIZE number + { cfg_parser->opt->ipv6_edns_size = (size_t)$2; } + | VAR_PIDFILE STRING + { cfg_parser->opt->pidfile = region_strdup(cfg_parser->opt->region, $2); } + | VAR_PORT number + { + /* port number, stored as a string */ + char buf[16]; + (void)snprintf(buf, sizeof(buf), "%lld", $2); + cfg_parser->opt->port = region_strdup(cfg_parser->opt->region, buf); + } + | VAR_REUSEPORT boolean + { cfg_parser->opt->reuseport = $2; } + | VAR_STATISTICS number + { cfg_parser->opt->statistics = (int)$2; } + | VAR_CHROOT STRING + { cfg_parser->opt->chroot = region_strdup(cfg_parser->opt->region, $2); } + | VAR_USERNAME STRING + { cfg_parser->opt->username = region_strdup(cfg_parser->opt->region, $2); } + | VAR_ZONESDIR STRING + { cfg_parser->opt->zonesdir = region_strdup(cfg_parser->opt->region, $2); } + | VAR_ZONELISTFILE STRING + { cfg_parser->opt->zonelistfile = region_strdup(cfg_parser->opt->region, $2); } + | VAR_DIFFFILE STRING + { /* ignored, deprecated */ } + | VAR_XFRDFILE STRING + { cfg_parser->opt->xfrdfile = region_strdup(cfg_parser->opt->region, $2); } + | VAR_XFRDIR STRING + { cfg_parser->opt->xfrdir = region_strdup(cfg_parser->opt->region, $2); } + | VAR_XFRD_RELOAD_TIMEOUT number + { cfg_parser->opt->xfrd_reload_timeout = (int)$2; } + | VAR_VERBOSITY number + { cfg_parser->opt->verbosity = (int)$2; } + | VAR_RRL_SIZE number + { +#ifdef RATELIMIT + if ($2 > 0) { + cfg_parser->opt->rrl_size = (size_t)$2; + } else { + yyerror("expected a number greater than zero"); + } +#endif + } + | VAR_RRL_RATELIMIT number + { +#ifdef RATELIMIT + cfg_parser->opt->rrl_ratelimit = (size_t)$2; +#endif + } + | VAR_RRL_SLIP number + { +#ifdef RATELIMIT + cfg_parser->opt->rrl_slip = (size_t)$2; +#endif + } + | VAR_RRL_IPV4_PREFIX_LENGTH number + { +#ifdef RATELIMIT + if ($2 > 32) { + yyerror("invalid IPv4 prefix length"); + } else { + cfg_parser->opt->rrl_ipv4_prefix_length = (size_t)$2; + } +#endif + } + | VAR_RRL_IPV6_PREFIX_LENGTH number + { +#ifdef RATELIMIT + if ($2 > 64) { + yyerror("invalid IPv6 prefix length"); + } else { + cfg_parser->opt->rrl_ipv6_prefix_length = (size_t)$2; + } +#endif + } + | VAR_RRL_WHITELIST_RATELIMIT number + { +#ifdef RATELIMIT + cfg_parser->opt->rrl_whitelist_ratelimit = (size_t)$2; +#endif + } + | VAR_ZONEFILES_CHECK boolean + { cfg_parser->opt->zonefiles_check = $2; } + | VAR_ZONEFILES_WRITE number + { cfg_parser->opt->zonefiles_write = (int)$2; } + | VAR_LOG_TIME_ASCII boolean + { + cfg_parser->opt->log_time_ascii = $2; + log_time_asc = cfg_parser->opt->log_time_ascii; + } + | VAR_ROUND_ROBIN boolean + { + cfg_parser->opt->round_robin = $2; + round_robin = cfg_parser->opt->round_robin; + } + | VAR_MINIMAL_RESPONSES boolean + { + cfg_parser->opt->minimal_responses = $2; + minimal_responses = cfg_parser->opt->minimal_responses; + } + | VAR_CONFINE_TO_ZONE boolean + { cfg_parser->opt->confine_to_zone = $2; } + | VAR_REFUSE_ANY boolean + { cfg_parser->opt->refuse_any = $2; } + | VAR_TLS_SERVICE_KEY STRING + { cfg_parser->opt->tls_service_key = region_strdup(cfg_parser->opt->region, $2); } + | VAR_TLS_SERVICE_OCSP STRING + { cfg_parser->opt->tls_service_ocsp = region_strdup(cfg_parser->opt->region, $2); } + | VAR_TLS_SERVICE_PEM STRING + { cfg_parser->opt->tls_service_pem = region_strdup(cfg_parser->opt->region, $2); } + | VAR_TLS_PORT number + { + /* port number, stored as string */ + char buf[16]; + (void)snprintf(buf, sizeof(buf), "%lld", $2); + cfg_parser->opt->tls_port = region_strdup(cfg_parser->opt->region, buf); + } + ; + +dnstap: + VAR_DNSTAP dnstap_block ; + +dnstap_block: + dnstap_block dnstap_option | ; + +dnstap_option: + VAR_DNSTAP_ENABLE boolean + { cfg_parser->opt->dnstap_enable = $2; } + | VAR_DNSTAP_SOCKET_PATH STRING + { cfg_parser->opt->dnstap_socket_path = region_strdup(cfg_parser->opt->region, $2); } + | VAR_DNSTAP_SEND_IDENTITY boolean + { cfg_parser->opt->dnstap_send_identity = $2; } + | VAR_DNSTAP_SEND_VERSION boolean + { cfg_parser->opt->dnstap_send_version = $2; } + | VAR_DNSTAP_IDENTITY STRING + { cfg_parser->opt->dnstap_identity = region_strdup(cfg_parser->opt->region, $2); } + | VAR_DNSTAP_VERSION STRING + { cfg_parser->opt->dnstap_version = region_strdup(cfg_parser->opt->region, $2); } + | VAR_DNSTAP_LOG_AUTH_QUERY_MESSAGES boolean + { cfg_parser->opt->dnstap_log_auth_query_messages = $2; } + | VAR_DNSTAP_LOG_AUTH_RESPONSE_MESSAGES boolean + { cfg_parser->opt->dnstap_log_auth_response_messages = $2; } + ; + +remote_control: + VAR_REMOTE_CONTROL remote_control_block ; + +remote_control_block: + remote_control_block remote_control_option | ; + +remote_control_option: + VAR_CONTROL_ENABLE boolean + { cfg_parser->opt->control_enable = $2; } + | VAR_CONTROL_INTERFACE ip_address + { + struct ip_address_option *ip = cfg_parser->opt->control_interface; + if(ip == NULL) { + cfg_parser->opt->control_interface = $2; + } else { + while(ip->next != NULL) { ip = ip->next; } + ip->next = $2; + } + } + | VAR_CONTROL_PORT number + { + if($2 == 0) { + yyerror("control port number expected"); + } else { + cfg_parser->opt->control_port = (int)$2; + } + } + | VAR_SERVER_KEY_FILE STRING + { cfg_parser->opt->server_key_file = region_strdup(cfg_parser->opt->region, $2); } + | VAR_SERVER_CERT_FILE STRING + { cfg_parser->opt->server_cert_file = region_strdup(cfg_parser->opt->region, $2); } + | VAR_CONTROL_KEY_FILE STRING + { cfg_parser->opt->control_key_file = region_strdup(cfg_parser->opt->region, $2); } + | VAR_CONTROL_CERT_FILE STRING + { cfg_parser->opt->control_cert_file = region_strdup(cfg_parser->opt->region, $2); } + ; + +key: + VAR_KEY + { + key_options_type *key = key_options_create(cfg_parser->opt->region); + key->algorithm = region_strdup(cfg_parser->opt->region, "sha256"); + assert(cfg_parser->key == NULL); + cfg_parser->key = key; + } + key_block + { + struct key_options *key = cfg_parser->key; + if(key->name == NULL) { + yyerror("tsig key has no name"); + } else if(key->algorithm == NULL) { + yyerror("tsig key %s has no algorithm", key->name); + } else if(key->secret == NULL) { + yyerror("tsig key %s has no secret blob", key->name); + } else if(key_options_find(cfg_parser->opt, key->name)) { + yyerror("duplicate tsig key %s", key->name); + } else { + key_options_insert(cfg_parser->opt, key); + cfg_parser->key = NULL; + } + } ; + +key_block: + key_block key_option | ; + +key_option: + VAR_NAME STRING + { + dname_type *dname; + + dname = (dname_type *)dname_parse(cfg_parser->opt->region, $2); + cfg_parser->key->name = region_strdup(cfg_parser->opt->region, $2); + if(dname == NULL) { + yyerror("bad tsig key name %s", $2); + } else { + region_recycle(cfg_parser->opt->region, dname, dname_total_size(dname)); + } + } + | VAR_ALGORITHM STRING + { + if(tsig_get_algorithm_by_name($2) == NULL) { + yyerror("bad tsig key algorithm %s", $2); + } else { + cfg_parser->key->algorithm = region_strdup(cfg_parser->opt->region, $2); + } + } + | VAR_SECRET STRING + { + uint8_t data[16384]; + int size; + + cfg_parser->key->secret = region_strdup(cfg_parser->opt->region, $2); + size = b64_pton($2, data, sizeof(data)); + if(size == -1) { + yyerror("cannot base64 decode tsig secret %s", + cfg_parser->key->name? + cfg_parser->key->name:""); + } else if(size != 0) { + memset(data, 0xdd, size); /* wipe secret */ + } + } ; + + +zone: + VAR_ZONE + { + assert(cfg_parser->pattern == NULL); + assert(cfg_parser->zone == NULL); + cfg_parser->zone = zone_options_create(cfg_parser->opt->region); + cfg_parser->zone->part_of_config = 1; + cfg_parser->zone->pattern = cfg_parser->pattern = + pattern_options_create(cfg_parser->opt->region); + cfg_parser->zone->pattern->implicit = 1; + } + zone_block + { + assert(cfg_parser->zone != NULL); + if(cfg_parser->zone->name == NULL) { + yyerror("zone has no name"); + } else if(!nsd_options_insert_zone(cfg_parser->opt, cfg_parser->zone)) { + yyerror("duplicate zone %s", cfg_parser->zone->name); + } else if(!nsd_options_insert_pattern(cfg_parser->opt, cfg_parser->zone->pattern)) { + yyerror("duplicate pattern %s", cfg_parser->zone->pattern->pname); + } + cfg_parser->pattern = NULL; + cfg_parser->zone = NULL; + } ; + +zone_block: + zone_block zone_option | ; + +zone_option: + VAR_NAME STRING + { + const char *marker = PATTERN_IMPLICIT_MARKER; + char *pname = region_alloc(cfg_parser->opt->region, strlen($2) + strlen(marker) + 1); + memmove(pname, marker, strlen(marker)); + memmove(pname + strlen(marker), $2, strlen($2) + 1); + cfg_parser->zone->pattern->pname = pname; + cfg_parser->zone->name = region_strdup(cfg_parser->opt->region, $2); + if(pattern_options_find(cfg_parser->opt, pname)) { + yyerror("zone %s cannot be created because implicit pattern %s " + "already exists", $2, pname); + } + } + | pattern_or_zone_option ; + +pattern: + VAR_PATTERN + { + assert(cfg_parser->pattern == NULL); + cfg_parser->pattern = pattern_options_create(cfg_parser->opt->region); + } + pattern_block + { + pattern_options_type *pattern = cfg_parser->pattern; + if(pattern->pname == NULL) { + yyerror("pattern has no name"); + } else if(!nsd_options_insert_pattern(cfg_parser->opt, pattern)) { + yyerror("duplicate pattern %s", pattern->pname); + } + cfg_parser->pattern = NULL; + } ; + +pattern_block: + pattern_block pattern_option | ; + +pattern_option: + VAR_NAME STRING + { + if(strchr($2, ' ')) { + yyerror("space is not allowed in pattern name: '%s'", $2); + } + cfg_parser->pattern->pname = region_strdup(cfg_parser->opt->region, $2); + } + | pattern_or_zone_option ; + +pattern_or_zone_option: + VAR_RRL_WHITELIST STRING + { +#ifdef RATELIMIT + cfg_parser->pattern->rrl_whitelist |= rrlstr2type($2); +#endif + } + | VAR_ZONEFILE STRING + { cfg_parser->pattern->zonefile = region_strdup(cfg_parser->opt->region, $2); } + | VAR_ZONESTATS STRING + { cfg_parser->pattern->zonestats = region_strdup(cfg_parser->opt->region, $2); } + | VAR_SIZE_LIMIT_XFR number + { + if($2 > 0) { + cfg_parser->pattern->size_limit_xfr = (int)$2; + } else { + yyerror("expected a number greater than zero"); + } + } + | VAR_MULTI_MASTER_CHECK boolean + { cfg_parser->pattern->multi_master_check = (int)$2; } + | VAR_INCLUDE_PATTERN STRING + { config_apply_pattern(cfg_parser->pattern, $2); } + | VAR_REQUEST_XFR STRING STRING + { + acl_options_type *acl = parse_acl_info(cfg_parser->opt->region, $2, $3); + if(acl->blocked) + yyerror("blocked address used for request-xfr"); + if(acl->rangetype != acl_range_single) + yyerror("address range used for request-xfr"); + append_acl(&cfg_parser->pattern->request_xfr, acl); + } + | VAR_REQUEST_XFR VAR_AXFR STRING STRING + { + acl_options_type *acl = parse_acl_info(cfg_parser->opt->region, $3, $4); + acl->use_axfr_only = 1; + if(acl->blocked) + yyerror("blocked address used for request-xfr"); + if(acl->rangetype != acl_range_single) + yyerror("address range used for request-xfr"); + append_acl(&cfg_parser->pattern->request_xfr, acl); + } + | VAR_REQUEST_XFR VAR_UDP STRING STRING + { + acl_options_type *acl = parse_acl_info(cfg_parser->opt->region, $3, $4); + acl->allow_udp = 1; + if(acl->blocked) + yyerror("blocked address used for request-xfr"); + if(acl->rangetype != acl_range_single) + yyerror("address range used for request-xfr"); + append_acl(&cfg_parser->pattern->request_xfr, acl); + } + | VAR_ALLOW_NOTIFY STRING STRING + { + acl_options_type *acl = parse_acl_info(cfg_parser->opt->region, $2, $3); + append_acl(&cfg_parser->pattern->allow_notify, acl); + } + | VAR_NOTIFY STRING STRING + { + acl_options_type *acl = parse_acl_info(cfg_parser->opt->region, $2, $3); + if(acl->blocked) + yyerror("blocked address used for notify"); + if(acl->rangetype != acl_range_single) + yyerror("address range used for notify"); + append_acl(&cfg_parser->pattern->notify, acl); + } + | VAR_PROVIDE_XFR STRING STRING + { + acl_options_type *acl = parse_acl_info(cfg_parser->opt->region, $2, $3); + append_acl(&cfg_parser->pattern->provide_xfr, acl); + } + | VAR_OUTGOING_INTERFACE STRING + { + acl_options_type *acl = parse_acl_info(cfg_parser->opt->region, $2, "NOKEY"); + append_acl(&cfg_parser->pattern->outgoing_interface, acl); + } + | VAR_ALLOW_AXFR_FALLBACK boolean + { + cfg_parser->pattern->allow_axfr_fallback = $2; + cfg_parser->pattern->allow_axfr_fallback_is_default = 0; + } + | VAR_NOTIFY_RETRY number + { + cfg_parser->pattern->notify_retry = $2; + cfg_parser->pattern->notify_retry_is_default = 0; + } + | VAR_MAX_REFRESH_TIME number + { + cfg_parser->pattern->max_refresh_time = $2; + cfg_parser->pattern->max_refresh_time_is_default = 0; + } + | VAR_MIN_REFRESH_TIME number + { + cfg_parser->pattern->min_refresh_time = $2; + cfg_parser->pattern->min_refresh_time_is_default = 0; + } + | VAR_MAX_RETRY_TIME number + { + cfg_parser->pattern->max_retry_time = $2; + cfg_parser->pattern->max_retry_time_is_default = 0; + } + | VAR_MIN_RETRY_TIME number + { + cfg_parser->pattern->min_retry_time = $2; + cfg_parser->pattern->min_retry_time_is_default = 0; + } ; + +ip_address: + STRING + { + struct ip_address_option *ip = region_alloc_zero( + cfg_parser->opt->region, sizeof(*ip)); + ip->address = region_strdup(cfg_parser->opt->region, $1); + $$ = ip; + } ; + +number: + STRING + { + /* ensure string consists entirely of digits */ + const char *str = $1; + size_t pos = 0; + while(str[pos] >= '0' && str[pos] <= '9') { + pos++; + } + + $$ = 0; + if(pos > 0 && str[pos] == '\0') { + int err = errno; + errno = 0; + $$ = strtoll(str, NULL, 10); + errno = err; + } else { + yyerror("expected a number"); + YYABORT; /* trigger a parser error */ + } + } ; + +boolean: + STRING + { + $$ = 0; + if(strcmp($1, "yes") == 0) { + $$ = 1; + } else if(strcmp($1, "no") == 0) { + $$ = 0; + } else { + yyerror("expected yes or no"); + YYABORT; /* trigger a parser error */ + } + } ; + +%% + +static void +append_acl(struct acl_options **list, struct acl_options *acl) +{ + assert(list != NULL); + + if(*list == NULL) { + *list = acl; + } else { + struct acl_options *tail = *list; + while(tail->next != NULL) + tail = tail->next; + tail->next = acl; + } +} + diff --git a/external/bsd/nsd/dist/configure b/external/bsd/nsd/dist/configure index 27ad356267dc..77ba6dee7446 100755 --- a/external/bsd/nsd/dist/configure +++ b/external/bsd/nsd/dist/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for NSD 4.1.27. +# Generated by GNU Autoconf 2.69 for NSD 4.2.4. # # Report bugs to . # @@ -580,8 +580,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='NSD' PACKAGE_TARNAME='nsd' -PACKAGE_VERSION='4.1.27' -PACKAGE_STRING='NSD 4.1.27' +PACKAGE_VERSION='4.2.4' +PACKAGE_STRING='NSD 4.2.4' PACKAGE_BUGREPORT='nsd-bugs@nlnetlabs.nl' PACKAGE_URL='' @@ -744,6 +744,7 @@ with_dnstap_socket_path with_protobuf_c with_libfstrm enable_systemd +enable_tcp_fastopen ' ac_precious_vars='build_alias host_alias @@ -1296,7 +1297,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures NSD 4.1.27 to adapt to many kinds of systems. +\`configure' configures NSD 4.2.4 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1357,7 +1358,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of NSD 4.1.27:";; + short | recursive ) echo "Configuration of NSD 4.2.4:";; esac cat <<\_ACEOF @@ -1398,6 +1399,7 @@ Optional Features: but unaligned reads. --enable-dnstap Enable dnstap support (requires fstrm, protobuf-c) --enable-systemd compile with systemd support + --enable-tcp-fastopen Enable TCP Fast Open Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] @@ -1512,7 +1514,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -NSD configure 4.1.27 +NSD configure 4.2.4 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2221,7 +2223,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by NSD $as_me 4.1.27, which was +It was created by NSD $as_me 4.2.4, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -8105,6 +8107,18 @@ fi done +ac_fn_c_check_type "$LINENO" "struct mmsghdr" "ac_cv_type_struct_mmsghdr" " +$ac_includes_default +#include + +" +if test "x$ac_cv_type_struct_mmsghdr" = xyes; then : + +$as_echo "#define HAVE_MMSGHDR 1" >>confdefs.h + +fi + + # Check whether --enable-recvmmsg was given. if test "${enable_recvmmsg+set}" = set; then : enableval=$enable_recvmmsg; @@ -8368,20 +8382,44 @@ esac fi -ac_fn_c_check_func "$LINENO" "reallocarray" "ac_cv_func_reallocarray" -if test "x$ac_cv_func_reallocarray" = xyes; then : - $as_echo "#define HAVE_REALLOCARRAY 1" >>confdefs.h +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for reallocarray" >&5 +$as_echo_n "checking for reallocarray... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default + +#ifndef _OPENBSD_SOURCE +#define _OPENBSD_SOURCE 1 +#endif +#include +int main(void) { + void* p = reallocarray(NULL, 10, 100); + free(p); + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE_REALLOCARRAY 1" >>confdefs.h + else - case " $LIBOBJS " in + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + case " $LIBOBJS " in *" reallocarray.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS reallocarray.$ac_objext" ;; esac + fi - - +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pselect prototype in sys/select.h" >&5 $as_echo_n "checking for pselect prototype in sys/select.h... " >&6; } @@ -8481,6 +8519,11 @@ cat >>confdefs.h <<_ACEOF _ACEOF +cat >>confdefs.h <<_ACEOF +#define TLS_PORT "853" +_ACEOF + + cat >>confdefs.h <<_ACEOF #define MAXSYSLOGMSGLEN 512 _ACEOF @@ -9050,46 +9093,21 @@ fi fi SSL_LIBS="-lssl" - for ac_header in openssl/ssl.h + for ac_header in openssl/ssl.h openssl/err.h openssl/rand.h openssl/ocsp.h do : - ac_fn_c_check_header_compile "$LINENO" "openssl/ssl.h" "ac_cv_header_openssl_ssl_h" "$ac_includes_default + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " -if test "x$ac_cv_header_openssl_ssl_h" = xyes; then : +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF -#define HAVE_OPENSSL_SSL_H 1 +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done - for ac_header in openssl/err.h -do : - ac_fn_c_check_header_compile "$LINENO" "openssl/err.h" "ac_cv_header_openssl_err_h" "$ac_includes_default -" -if test "x$ac_cv_header_openssl_err_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_OPENSSL_ERR_H 1 -_ACEOF - -fi - -done - - for ac_header in openssl/rand.h -do : - ac_fn_c_check_header_compile "$LINENO" "openssl/rand.h" "ac_cv_header_openssl_rand_h" "$ac_includes_default -" -if test "x$ac_cv_header_openssl_rand_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_OPENSSL_RAND_H 1 -_ACEOF - -fi - -done - - for ac_func in HMAC_CTX_reset HMAC_CTX_new EVP_cleanup ERR_load_crypto_strings OPENSSL_init_crypto + for ac_func in HMAC_CTX_reset HMAC_CTX_new EVP_cleanup ERR_load_crypto_strings OPENSSL_init_crypto SSL_CTX_set_security_level CRYPTO_memcmp EC_KEY_new_by_curve_name do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -9101,6 +9119,68 @@ _ACEOF fi done + ac_fn_c_check_decl "$LINENO" "SSL_CTX_set_ecdh_auto" "ac_cv_have_decl_SSL_CTX_set_ecdh_auto" " +$ac_includes_default +#ifdef HAVE_OPENSSL_ERR_H +#include +#endif + +#ifdef HAVE_OPENSSL_RAND_H +#include +#endif + +#ifdef HAVE_OPENSSL_CONF_H +#include +#endif + +#ifdef HAVE_OPENSSL_ENGINE_H +#include +#endif +#include +#include + +" +if test "x$ac_cv_have_decl_SSL_CTX_set_ecdh_auto" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_SSL_CTX_SET_ECDH_AUTO $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "SSL_CTX_set_tmp_ecdh" "ac_cv_have_decl_SSL_CTX_set_tmp_ecdh" " +$ac_includes_default +#ifdef HAVE_OPENSSL_ERR_H +#include +#endif + +#ifdef HAVE_OPENSSL_RAND_H +#include +#endif + +#ifdef HAVE_OPENSSL_CONF_H +#include +#endif + +#ifdef HAVE_OPENSSL_ENGINE_H +#include +#endif +#include +#include + +" +if test "x$ac_cv_have_decl_SSL_CTX_set_tmp_ecdh" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_SSL_CTX_SET_TMP_ECDH $ac_have_decl +_ACEOF + + BAKLIBS="$LIBS" LIBS="-lssl $LIBS" @@ -9120,6 +9200,8 @@ done else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: No SSL, therefore remote-control is disabled" >&5 $as_echo "$as_me: WARNING: No SSL, therefore remote-control is disabled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: No SSL, therefore TLS is disabled" >&5 +$as_echo "$as_me: WARNING: No SSL, therefore TLS is disabled" >&2;} fi # Check whether --enable-nsec3 was given. @@ -9594,6 +9676,33 @@ fi # Include systemd.m4 - end +# Check whether --enable-tcp-fastopen was given. +if test "${enable_tcp_fastopen+set}" = set; then : + enableval=$enable_tcp_fastopen; +fi + +case "$enable_tcp_fastopen" in + yes) + ac_fn_c_check_decl "$LINENO" "TCP_FASTOPEN" "ac_cv_have_decl_TCP_FASTOPEN" "$ac_includes_default +#include + +" +if test "x$ac_cv_have_decl_TCP_FASTOPEN" = xyes; then : + +else + as_fn_error $? "TCP Fast Open is not available: please rerun without --enable-tcp-fastopen" "$LINENO" 5 +fi + + +cat >>confdefs.h <<_ACEOF +#define USE_TCP_FASTOPEN 1 +_ACEOF + + ;; + no|*) + ;; +esac + @@ -10139,7 +10248,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by NSD $as_me 4.1.27, which was +This file was extended by NSD $as_me 4.2.4, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -10201,7 +10310,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -NSD config.status 4.1.27 +NSD config.status 4.2.4 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/external/bsd/nsd/dist/contrib/README b/external/bsd/nsd/dist/contrib/README index e13e594d9e3b..0f677dd2bb06 100644 --- a/external/bsd/nsd/dist/contrib/README +++ b/external/bsd/nsd/dist/contrib/README @@ -30,3 +30,7 @@ USE AT YOUR OWN RISK. * nsd.socket and nsd.service : example systemd service scripts for NSD. They are copies from Unbound's service files, edited for NSD. + +* patch_for_s6_startup_and_other_service_supervisors.diff : patch to + use -r option for nsd to signal readiness with READY_FD, from Cameron Nemo. + Apply with patch -p0 < contrib/patch_for_s6_startup_and_other_service_supervisors.diff diff --git a/external/bsd/nsd/dist/contrib/patch_for_s6_startup_and_other_service_supervisors.diff b/external/bsd/nsd/dist/contrib/patch_for_s6_startup_and_other_service_supervisors.diff new file mode 100644 index 000000000000..b89c268ccc73 --- /dev/null +++ b/external/bsd/nsd/dist/contrib/patch_for_s6_startup_and_other_service_supervisors.diff @@ -0,0 +1,89 @@ +diff --git nsd.c nsd.c +index 98dec613..e9d7b2cc 100644 +--- nsd.c ++++ nsd.c +@@ -91,6 +91,9 @@ usage (void) + " -n tcp-count The maximum number of TCP connections per server.\n" + " -P pidfile Specify the PID file to write.\n" + " -p port Specify the port to listen to.\n" ++ " -r Print a newline into the file descriptor index\n" ++ " described in the READY_FD environment variable to\n" ++ " indicate that nsd is ready to accept connections.\n" + " -s seconds Dump statistics every SECONDS seconds.\n" + " -t chrootdir Change root to specified directory on startup.\n" + ); +@@ -323,6 +326,24 @@ sig_handler(int sig) + } + } + ++/* ++ * Parse envvar as a positive integer. ++ * ++ */ ++int ++get_fd_from_env(const char* key) ++{ ++ char *env = getenv(key); ++ if (!env || env[0] == '\0') ++ return -1; ++ errno = 0; ++ char *endptr; ++ int fd = (int)strtol(env, &endptr, 10); ++ if (errno != 0 || endptr[0] != '\0') ++ return -1; ++ return fd; ++} ++ + /* + * Statistic output... + * +@@ -450,7 +471,7 @@ main(int argc, char *argv[]) + } + + /* Parse the command line... */ +- while ((c = getopt(argc, argv, "46a:c:df:hi:I:l:N:n:P:p:s:u:t:X:V:v" ++ while ((c = getopt(argc, argv, "46a:c:df:hi:I:l:N:n:P:p:rs:u:t:X:V:v" + #ifndef NDEBUG /* only when configured with --enable-checking */ + "F:L:" + #endif /* NDEBUG */ +@@ -533,6 +554,9 @@ main(int argc, char *argv[]) + tcp_port = optarg; + udp_port = optarg; + break; ++ case 'r': ++ nsd.readyfd = 1; ++ break; + case 's': + #ifdef BIND8_STATS + nsd.st.period = atoi(optarg); +@@ -965,6 +989,18 @@ main(int argc, char *argv[]) + } + #endif /* HAVE_SSL */ + ++ /* When asked to notify readiness via REⒶDY_FD, do so. */ ++ if (nsd.readyfd) { ++ int readyfd = get_fd_from_env("READY_FD"); ++ if (readyfd < 0) ++ error("READY_FD unset or contains garbage"); ++ unsetenv("READY_FD"); ++ int ret = dprintf(readyfd, "\n"); ++ close(readyfd); ++ if (ret < 0) ++ error("could not write to READY_FD index"); ++ } ++ + /* Unless we're debugging, fork... */ + if (!nsd.debug) { + int fd; +diff --git nsd.h nsd.h +index de3ae8e1..ff27b798 100644 +--- nsd.h ++++ nsd.h +@@ -179,6 +179,7 @@ struct nsd + unsigned server_kind; + struct namedb *db; + int debug; ++ int readyfd; + + size_t child_count; + struct nsd_child *children; diff --git a/external/bsd/nsd/dist/dns.c b/external/bsd/nsd/dist/dns.c index ad0d9245d492..a5e4ad4c9a0a 100644 --- a/external/bsd/nsd/dist/dns.c +++ b/external/bsd/nsd/dist/dns.c @@ -121,10 +121,10 @@ static rrtype_descriptor_type rrtype_descriptors[(RRTYPE_DESCRIPTORS_LENGTH+1)] { TYPE_SIG, "SIG", T_SIG, 9, 9, { RDATA_WF_SHORT, RDATA_WF_BYTE, RDATA_WF_BYTE, RDATA_WF_LONG, RDATA_WF_LONG, RDATA_WF_LONG, RDATA_WF_SHORT, - RDATA_WF_UNCOMPRESSED_DNAME, RDATA_WF_BINARY }, - { RDATA_ZF_RRTYPE, RDATA_ZF_BYTE, RDATA_ZF_BYTE, RDATA_ZF_PERIOD, - RDATA_ZF_TIME, RDATA_ZF_TIME, RDATA_ZF_SHORT, RDATA_ZF_DNAME, - RDATA_ZF_BASE64 } }, + RDATA_WF_LITERAL_DNAME, RDATA_WF_BINARY }, + { RDATA_ZF_RRTYPE, RDATA_ZF_ALGORITHM, RDATA_ZF_BYTE, RDATA_ZF_PERIOD, + RDATA_ZF_TIME, RDATA_ZF_TIME, RDATA_ZF_SHORT, + RDATA_ZF_LITERAL_DNAME, RDATA_ZF_BASE64 } }, /* 25 */ { TYPE_KEY, "KEY", T_KEY, 4, 4, { RDATA_WF_SHORT, RDATA_WF_BYTE, RDATA_WF_BYTE, RDATA_WF_BINARY }, diff --git a/external/bsd/nsd/dist/doc/CREDITS b/external/bsd/nsd/dist/doc/CREDITS index c2bc91eae799..5b9097f36612 100644 --- a/external/bsd/nsd/dist/doc/CREDITS +++ b/external/bsd/nsd/dist/doc/CREDITS @@ -24,6 +24,7 @@ Aaron Glenn - DragonflyBSD, BSD/sparc64 test Ben Laurie - NSEC3 patch. Bin Zhang - NSD 3 prerelease testing. Colm MacCárthaigh, - IPv6 binding and cleanups. +Greg Bock - confine-to-zone feature. Farkas Levente - rpm specfile improvements. Jakob Schlyter, Kirei - chroot and several other patches Jun-ichiro itojun Hagino, IIJLab - IPv6 transport diff --git a/external/bsd/nsd/dist/doc/ChangeLog b/external/bsd/nsd/dist/doc/ChangeLog index fc24d99eadc8..5070b61afc60 100644 --- a/external/bsd/nsd/dist/doc/ChangeLog +++ b/external/bsd/nsd/dist/doc/ChangeLog @@ -1,5 +1,271 @@ +3 December 2019: Wouter + - Fix #52: do not log transient network full errors unless higher + verbosity is set. + - Fix checkconf test for new error output string. + - tag for 4.2.4rc1 release. + +27 November 2017 Jeroen + - Fix regressions in configparser.y + +22 November 2019: Wouter + - Fix #48: Add make distclean that removes config.h made by configure. + And add maintainer-clean that removes bison and flex output. + +18 November 2019: Wouter + - Detect fixed time memcmp for openssl 0.9.8 compatibility. + - Detect EC_KEY_new_by_curve_name for openssl 0.9.8. + - include limits.h for UINT_MAX. + - If no recvmmsg, dont use msg_flags member, but errno for error, + where our fallback function left it, msg_flags also does not exist + on some systems. + - Remove unused variable warning for portability. + +14 November 2019: Wouter + - Fix checkconf test with filenames that sort in the same order. + - Tag for 4.2.3rc1. Branch master is 4.2.4 in development. + +11 November 2019: Wouter + - Fix #44: document that remote-control is a top-level nsd.conf + attribute. + - Fix compile on OSX. + - Fix for #44: nicer top-level clause documentation. + +22 October 2019: Jeroen + - Number of different UDP handlers has been reduced to one. recvmmsg + and sendmmsg implementations are now used on all platforms. + Compatible implementations are in place for systems that lack the + system calls. + - Socket options are now set in designated functions for easy reuse. + - Socket setup has been simplified for easy reuse. + - Configuration parser is now aware of the context in which an option + was specified. + +21 October 2019: Wouter + - For #21 add + contrib/patch_for_s6_startup_and_other_service_supervisors.diff + that adds support for readiness notification with READY_FD from + Cameron Nemo. + +17 October 2019: Jeroen + - Fix #40: Merge small fixes for confine-to-zone by Greg Bock. + +15 October 2019: Jeroen + - For #39: Merge confine-to-zone feature contributes by Greg Bock. + +26 September 2019: Wouter + - Fix #38: log address and failure reason with tls handshake errors, + squelches (the same as unbound) some unless high verbosity is used. + - Fixup clang analysis warning in xfrd_parse_received_xfr_packet + master dereference. + +25 September 2019: Wouter + - The nsd.conf includes are sorted ascending, for include statements + with a '*' from glob. + +16 September 2019: Wouter + - Fixup warnings during --disable-ipv6 compile. + - Fixup unit test executable to run without IPv6. + +4 September 2019: Wouter + - Fix #35: excessive logging of ixfr failures, it stops the log when + fallback to axfr is possible. log is enabled at high verbosity. + +2 September 2019: Wouter + - For #21: pidfile "" allows to run NSD without a pidfile, for + startup management tools like daemontools. + +28 August 2019: Wouter + - In tests check for tls test tool availability. + +19 August 2019: Wouter + - Tag for 4.2.2 release. Git master contains 4.2.3 in development. + +13 August 2019: Wouter + - Fix error message for out of zone data to have more information. + - Tag for 4.2.2rc2. + +12 August 2019: Wouter + - Fix #33: Fix segfault in service of remaining streams on exit. + +6 August 2019: Wouter + - Tag for 4.2.2rc1. + +5 August 2019: Wouter + - PR #31: nsd-control: Add missing stdio header. + - PR #32: tsig: Fix compilation without HAVE_SSL. + - Cleanup tls context on xfrd exit. + +31 July 2019: Wouter + - Fix #29: SSHFP check NULL pointer dereference. + - Fix #30: SSHFP check failure due to missing domain name. + - Fix to timeval_add in minievent for remaining second in microseconds. + +22 July 2019: Wouter + - Set timeout for refetch immediately, only spread load when there + are retries. + +19 July 2019: Wouter + - Set no renegotiation on the SSL context to stop client + session renegotiation. + +18 July 2019: Wouter + - Fix #25: NSD doesn't refresh zones after extended downtime, + it refreshes the old zones, with a random delay of a couple of + seconds to spread the load. + - Fix so that expired zones stay expired when server is down a + long time. + +17 July 2019: Wouter + - Fix that NSD warns for wrong length of the hash in SSHFP records. + +15 July 2019: Wouter + - PR #23: Fix typo in nsd.conf man-page. + +4 July 2019: Wouter + - Set version to 4.2.2 in development. + - clean memory on exit of nsd-checkzone for memory debug. + - Fix #20: CVE-2019-13207 Stack-based Buffer Overflow in the + dname_concatenate() function. Reported by Frederic Cambus. + It causes the zone parser to crash on a malformed zone file, + with assertions enabled, an assertion catches it. + - Fix #19: Out-of-bounds read caused by improper validation of + array index. Reported by Frederic Cambus. The zone parser + fails on type SIG because of mismatched definition with RRSIG. + +2 July 2019: Wouter + - Tag for 4.2.1rc1 + +27 June 2019: Wouter + - Fix unit test for added options and no dot after zone updated + log message. + - Fix compile without accept4. + +21 June 2019: Wouter + - Omit remaining tcp processing if the list is empty. + - Fix output of nsd-checkconf -h. + +20 June 2019: Wouter + - Initialize event structures before event_set, to stop uninitialized + values from setting event library lists and assertions, that would + sometimes also show after event_del. + - Added num.tls and num.tls6 stat counters. + - PR #12: send-buffer-size, receive-buffer-size, + tcp-reject-overflow options for nsd.conf, from Jeroen Koekkoek. + - Do not use symbol from libc, instead use own replacement, if not + available, for accept4. + - Fix #14, tcp connections have 1/10 to be active and have to work + every second, and then they get time to complete during a reload, + this is a process that lingers with the old version during a version + update. + +19 June 2019: Wouter + - Fix tls handshake event callback function mistake, reported + by Mykhailo Danylenko. + +18 June 2019: Wouter + - Fix #15: crash in SSL library, initialize variables for TCP access + when TLS is configured. + +14 June 2019: Wouter + - Fix to init event not pointer, in reassignment. + +12 June 2019: Wouter + - Fix to init event structure for reassignment. + +11 June 2019: Wouter + - NSD 4.2.0 release. Current development is 4.2.1. + - Fixup of RELNOTES, corrected RFC reference for 4892. + - Fix #13: Stray dot at the end of some log entries, removes dot + after updated serial number in log entry. + - Fix TLS cipher selection, the previous was redundant, prefers + CHACHA20-POLY1305 over AESGCM and was not as readable as it could be. + - Consolidate server tls context create and remote control context + create, with hardening for the remote control tls context too. + +6 June 2019: Wouter + - NSD 4.2.0rc1 tag. + +4 June 2019: Wouter + - Fix unit test for outgoing interface to use random port numbers for + the outgoing interface config. + +29 May 2019: Wouter + - Fix to guard _OPENBSD_SOURCE from redefinition. + +28 May 2019: Wouter + - Fix to define _OPENBSD_SOURCE to get reallocarray on NetBSD. + +16 May 2019: Wouter + - Fix #10: Fix memory leaks caused by duplicate rr and include + instructions. + +6 May 2019: Wouter + - Note CII best practices badge for NSD on the README.md. + +2 May 2019: Wouter + - Fix .gitignore for unit test generated files. + - Fix checkconf unit test for hide-identity and tls. + +1 May 2019: Wouter + - Fix makedist.sh for use with git. + - Nicer output on travis for clang analysis. + - Add .gitignore file to exclude built files from version tracking. + - Add README.md file in repository with compile instructions. + - Fix .gitignore for dnstap files and aclocal temp. + - Add aclocal to README.md for pkgconfig for some configure options. + +25 April 2019: Wouter + - Add tls.tpkg unit test for DNS over TLS functionality. + +18 April 2019: Wouter + - Fix to avoid buffer alloc with global buffer in tls write handler. + - Fix to initialize event structure when accepting TCP connection. + - Use travis for build check, initial unit test and clang analysis. + - Disable SSLv2,3,TLSv1.0,1.1 if TLS1.2 is available in libssl. + - Disable weak ciphers, enable CIPHER_SERVER_PREFERENCE. + - further setup ssl ctx after the keys are loaded, for ECDH. + - TLS OCSP stapling support, enabled with tls-service-ocsp: filename, + patch from Andreas Schulze. + +17 April 2019: Wouter + - Fix to share openssl init code, and perform it once. + +16 April 2019: Andreas via Sara + - Patch to add support for TCP Fast Open + - Patch to add support for tls service on a specified tls port + +16 April 2019: Wouter + - Fix #4249: The option hide-identity: yes stops NSD from responding + with the hostname for chaos class queries. Implements the RFC4829 + security considerations. + - Remove starttls, this signalling method was not standardized. + - Remove TO bit, this signalling method was not standardized. + - Remove unused first_query and tls_ok states. + - Remove sign-compare warning in tls packet send code. + - Fix spelling in comment and log printout. + - Fix potential uninitialized variable. + - Fix documentation for DNS over TLS, and set default port 853. + - Fix to add missing comment. + - Fix that the TLS handshake routine sets the correct event to + continue when done. + - Fix that TLS renegotiation calls the read and write routines again + with the same parameters when the desired event has been satisfied. + - Fix that TCP Fastopen has better error message and supports OSX. + - Fix log for fastopen with verbosity. + - Squelch TLS handshake failure log until verbosity 3. + - Add per-zone statistics for TLS queries, and dnstap for TLS queries, + and rcode and TCflag statistics for TCP and TLS queries. + +25 March 2019: Wouter + - Print IP address when bind socket fails with error. + +21 March 2019: Wouter + - Fix spelling error in release notes. + - Fix to delete unused zparser.default_apex member. + 19 March 2019: Wouter - - tag 4.1.27rc1 + - tag 4.1.27rc1. This became 4.1.27 on 25 March 2019 and trunk has + 4.1.28 in development. 18 March 2019: Wouter - Fix unit test bug013_truncate for new truncation with EDNS size, diff --git a/external/bsd/nsd/dist/doc/README b/external/bsd/nsd/dist/doc/README index 4775b232f431..d4c32f62c042 100644 --- a/external/bsd/nsd/dist/doc/README +++ b/external/bsd/nsd/dist/doc/README @@ -19,7 +19,7 @@ 1.0 Introduction -This is NSD Name Server Daemon (NSD) version 4.1.27. +This is NSD Name Server Daemon (NSD) version 4.2.4. The NLnet Labs Name Server Daemon (NSD) is an authoritative RFC compliant DNS nameserver. It was first conceived to allow for more genetic @@ -55,7 +55,7 @@ and uses a simple configuration file 'nsd.conf'. 1.2 Quick build and install -Step 1: Unpack the source with gtar -xzvf nsd-4.1.27.tar.gz +Step 1: Unpack the source with gtar -xzvf nsd-4.2.4.tar.gz Step 2: Create user nsd or any other unprivileged user of your choice. In case of later make sure to use @@ -109,9 +109,9 @@ Step 11: If desired add 'nsd-control write' to your superuser crontab to Use your favorite combination of tar and gnu zip to unpack the source, for example -$ gtar -xzvf nsd-4.1.27.tar.gz +$ gtar -xzvf nsd-4.2.4.tar.gz -will unpack the source into the ./nsd-4.1.27 directory... +will unpack the source into the ./nsd-4.2.4 directory... 2.2 Configuring NSD @@ -756,4 +756,4 @@ larger and regular donations please contact us at users@NLnetLabs.nl. Also see http://www.nlnetlabs.nl/labs/contributors/. -$Id: README,v 1.1.1.5 2019/05/25 19:44:44 christos Exp $ +Id diff --git a/external/bsd/nsd/dist/doc/RELNOTES b/external/bsd/nsd/dist/doc/RELNOTES index a2025d477b48..d4f1dc66b8e2 100644 --- a/external/bsd/nsd/dist/doc/RELNOTES +++ b/external/bsd/nsd/dist/doc/RELNOTES @@ -1,12 +1,154 @@ NSD RELEASE NOTES +4.2.4 +================ +FEATURES: + - Fix #48: Add make distclean that removes config.h made by configure. + And add maintainer-clean that removes bison and flex output. +BUG FIXES: + - Detect fixed time memcmp for openssl 0.9.8 compatibility. + - Detect EC_KEY_new_by_curve_name for openssl 0.9.8. + - include limits.h for UINT_MAX. + - If no recvmmsg, dont use msg_flags member, but errno for error, + where our fallback function left it, msg_flags also does not exist + on some systems. + - Remove unused variable warning for portability. + - Fix #52: do not log transient network full errors unless higher + verbosity is set. + - Fix regressions in configparser.y where global variables were not + set for minimal-responses, round-robin and log-time-ascii. + + +4.2.3 +================ +FEATURES: + - For #39: confine-to-zone configures NSD to not return out-of-zone + additional information. Contributed by Greg Bock. + - For #21: pidfile "" allows to run NSD without a pidfile, for + startup management tools like daemontools. + - For #21 add + contrib/patch_for_s6_startup_and_other_service_supervisors.diff + that adds support for readiness notification with READY_FD from + Cameron Nemo. +BUG FIXES: + - Fix #35: excessive logging of ixfr failures, it stops the log when + fallback to axfr is possible. log is enabled at high verbosity. + - Fixup warnings during --disable-ipv6 compile. + - The nsd.conf includes are sorted ascending, for include statements + with a '*' from glob. + - Fix #38: log address and failure reason with tls handshake errors, + squelches (the same as unbound) some unless high verbosity is used. + - Fixup clang analysis warning in xfrd_parse_received_xfr_packet + master dereference. +CHANGES: + - Number of different UDP handlers has been reduced to one. recvmmsg + and sendmmsg implementations are now used on all platforms. + Compatible implementations are in place for systems that lack the + system calls. + - Socket options are now set in designated functions for easy reuse. + - Socket setup has been simplified for easy reuse. + - Configuration parser is now aware of the context in which an option + was specified. + - Fix #44: document that remote-control is a top-level nsd.conf + attribute. + + +4.2.2 +================ +BUG FIXES: + - Fix #20: CVE-2019-13207 Stack-based Buffer Overflow in the + dname_concatenate() function. Reported by Frederic Cambus. + It causes the zone parser to crash on a malformed zone file, + with assertions enabled, an assertion catches it. + - Fix #19: Out-of-bounds read caused by improper validation of + array index. Reported by Frederic Cambus. The zone parser + fails on type SIG because of mismatched definition with RRSIG. + - PR #23: Fix typo in nsd.conf man-page. + - Fix that NSD warns for wrong length of the hash in SSHFP records. + - Fix #25: NSD doesn't refresh zones after extended downtime, + it refreshes the old zones. + - Set no renegotiation on the SSL context to stop client + session renegotiation. + - Fix #29: SSHFP check NULL pointer dereference. + - Fix #30: SSHFP check failure due to missing domain name. + - Fix to timeval_add in minievent for remaining second in microseconds. + - PR #31: nsd-control: Add missing stdio header. + - PR #32: tsig: Fix compilation without HAVE_SSL. + - Cleanup tls context on xfrd exit. + - Fix #33: Fix segfault in service of remaining streams on exit. + - Fix error message for out of zone data to have more information. + + +4.2.1 +================ +FEATURES: + - Added num.tls and num.tls6 stat counters. + - PR #12: send-buffer-size, receive-buffer-size, + tcp-reject-overflow options for nsd.conf, from Jeroen Koekkoek. + - Fix #14, tcp connections have 1/10 to be active and have to work + every second, and then they get time to complete during a reload, + this is a process that lingers with the old version during a version + update. +BUG FIXES: + - Fix #13: Stray dot at the end of some log entries, removes dot + after updated serial number in log entry. + - Fix TLS cipher selection, the previous was redundant, prefers + CHACHA20-POLY1305 over AESGCM and was not as readable as it + could be. + - Consolidate server tls context create and remote control context + create, with hardening for the remote control tls context too. + - Fix to init event structure for reassignment. + - Fix to init event not pointer, in reassignment. + - Fix #15: crash in SSL library, initialize variables for TCP access + when TLS is configured. + - Fix tls handshake event callback function mistake, reported + by Mykhailo Danylenko. + - Initialize event structures before event_set, to stop uninitialized + values from setting event library lists and assertions, that would + sometimes also show after event_del. + - Do not use symbol from libc, instead use own replacement, if not + available, for accept4. + - Fix output of nsd-checkconf -h. + + +4.2.0 +================ +FEATURES: + - Print IP address when bind socket fails with error. + - Fix #4249: The option hide-identity: yes stops NSD from responding + with the hostname for chaos class queries. Implements the RFC4892 + security considerations. + - Patch to add support for TCP Fast Open, from Sara + Dickinson (Sinodun). + - Patch to add support for tls service on a specified tls port, + from Sara Dickinson (Sinodun). + - Use travis for build check, initial unit test and clang analysis. + - TLS OCSP stapling support, enabled with tls-service-ocsp: filename, + patch from Andreas Schulze. +BUG FIXES: + - Fix to delete unused zparser.default_apex member. + - Fix that the TLS handshake routine sets the correct event to + continue when done. + - Fix that TLS renegotiation calls the read and write routines again + with the same parameters when the desired event has been satisfied. + - Fix that TCP Fastopen has better error message and supports OSX. + - Fix to avoid buffer alloc with global buffer in tls write handler. + - Fix to initialize event structure when accepting TCP connection. + - Disable TLS1.0, TLS1.1 and weak ciphers, enable + CIPHER_SERVER_PREFERENCE, patch from Andreas Schulze. + - further setup ssl ctx after the keys are loaded, for ECDH. + - Fix #10: Fix memory leaks caused by duplicate rr and include + instructions. + - Fix to define _OPENBSD_SOURCE to get reallocarray on NetBSD. + + 4.1.27 ================ FEATURES: - Deny ANY with only one RR in response, by default. Patch from Daisuke Higashi. The deny-any statement in nsd.conf sets ANY queries over UDP to be further moved to TCP as well. - Also no additional section processig for type ANY, reducing + Also no additional section processing for type ANY, reducing the response size. - Fix #4215: on-the-fly change of TSIG keys with patch from Igor, adds nsd-control print_tsig, update_tsig, add_tsig, assoc_tsig diff --git a/external/bsd/nsd/dist/doc/REQUIREMENTS b/external/bsd/nsd/dist/doc/REQUIREMENTS index 53ab142c75f9..8eb142014274 100644 --- a/external/bsd/nsd/dist/doc/REQUIREMENTS +++ b/external/bsd/nsd/dist/doc/REQUIREMENTS @@ -1,4 +1,4 @@ -$Id: REQUIREMENTS,v 1.1.1.4 2019/05/25 19:44:44 christos Exp $ +Id NSD Requirements and Specifications @@ -1053,5 +1053,5 @@ Appendix D. Changes to this file. - KEY->DNSKEY, SIG->RRSIG in the text, dnssec-bis style. ______________________________________________________________________ -$Id: REQUIREMENTS,v 1.1.1.4 2019/05/25 19:44:44 christos Exp $ +Id diff --git a/external/bsd/nsd/dist/doc/TODO b/external/bsd/nsd/dist/doc/TODO index 55259bde5f92..79843af3d5d8 100644 --- a/external/bsd/nsd/dist/doc/TODO +++ b/external/bsd/nsd/dist/doc/TODO @@ -1,4 +1,4 @@ -$Id: TODO,v 1.1.1.4 2019/05/25 19:44:44 christos Exp $ +Id AUTOCONF - check/translate arguments to --with-facility diff --git a/external/bsd/nsd/dist/doc/differences.tex b/external/bsd/nsd/dist/doc/differences.tex index 597deb0f527d..85a9dfbd1030 100644 --- a/external/bsd/nsd/dist/doc/differences.tex +++ b/external/bsd/nsd/dist/doc/differences.tex @@ -4,7 +4,7 @@ \def\nlnetlabsno{2006-004} -\rcsdetails{$Id: differences.tex,v 1.1.1.4 2019/05/25 19:44:44 christos Exp $} +\rcsdetails{Id} % Prints RCS details at the bottom of the page. \title{Response Differences between\\ NSD and other DNS Servers} diff --git a/external/bsd/nsd/dist/ipc.c b/external/bsd/nsd/dist/ipc.c index 46feb0a01293..190e30a0cf03 100644 --- a/external/bsd/nsd/dist/ipc.c +++ b/external/bsd/nsd/dist/ipc.c @@ -37,6 +37,7 @@ ipc_child_quit(struct nsd* nsd) { /* call shutdown and quit routines */ nsd->mode = NSD_QUIT; + service_remaining_tcp(nsd); #ifdef BIND8_STATS bind8_stats(nsd); #endif /* BIND8_STATS */ @@ -267,6 +268,8 @@ stats_add(struct nsdst* total, struct nsdst* s) total->qudp6 += s->qudp6; total->ctcp += s->ctcp; total->ctcp6 += s->ctcp6; + total->ctls += s->ctls; + total->ctls6 += s->ctls6; for(i=0; ircode)/sizeof(stc_type); i++) total->rcode[i] += s->rcode[i]; for(i=0; iopcode)/sizeof(stc_type); i++) @@ -298,6 +301,8 @@ stats_subtract(struct nsdst* total, struct nsdst* s) total->qudp6 -= s->qudp6; total->ctcp -= s->ctcp; total->ctcp6 -= s->ctcp6; + total->ctls -= s->ctls; + total->ctls6 -= s->ctls6; for(i=0; ircode)/sizeof(stc_type); i++) total->rcode[i] -= s->rcode[i]; for(i=0; iopcode)/sizeof(stc_type); i++) @@ -324,7 +329,8 @@ read_child_stats(struct nsd* nsd, struct nsd_child* child, int fd) "%d: %s", (int)child->pid, strerror(errno)); } else { stats_add(&nsd->st, &s); - child->query_count = s.qudp + s.qudp6 + s.ctcp + s.ctcp6; + child->query_count = s.qudp + s.qudp6 + s.ctcp + s.ctcp6 + + s.ctls + s.ctls6; /* we know that the child is going to close the connection * now (this is an ACK of the QUIT_W_STATS so we know the * child is done, no longer sending e.g. NOTIFY contents) */ @@ -593,6 +599,7 @@ ipc_xfrd_set_listening(struct xfrd_state* xfrd, short mode) int fd = xfrd->ipc_handler.ev_fd; struct event_base* base = xfrd->event_base; event_del(&xfrd->ipc_handler); + memset(&xfrd->ipc_handler, 0, sizeof(xfrd->ipc_handler)); event_set(&xfrd->ipc_handler, fd, mode, xfrd_handle_ipc, xfrd); if(event_base_set(base, &xfrd->ipc_handler) != 0) log_msg(LOG_ERR, "ipc: cannot set event_base"); diff --git a/external/bsd/nsd/dist/mini_event.c b/external/bsd/nsd/dist/mini_event.c index a39d682cc514..2478a6dcd1a9 100644 --- a/external/bsd/nsd/dist/mini_event.c +++ b/external/bsd/nsd/dist/mini_event.c @@ -304,8 +304,7 @@ event_base_free(struct event_base* base) { if(!base) return; - if(base->times) - free(base->times); + /* base->times is allocated in region and is freed with the region */ if(base->fds) free(base->fds); if(base->signals) @@ -362,7 +361,7 @@ event_add(struct event* ev, struct timeval* tv) struct timeval* now = ev->ev_base->time_tv; ev->ev_timeout.tv_sec = tv->tv_sec + now->tv_sec; ev->ev_timeout.tv_usec = tv->tv_usec + now->tv_usec; - while(ev->ev_timeout.tv_usec > 1000000) { + while(ev->ev_timeout.tv_usec >= 1000000) { ev->ev_timeout.tv_usec -= 1000000; ev->ev_timeout.tv_sec++; } diff --git a/external/bsd/nsd/dist/mkinstalldirs b/external/bsd/nsd/dist/mkinstalldirs index 373edc54e51b..4bdc36ab63f5 100644 --- a/external/bsd/nsd/dist/mkinstalldirs +++ b/external/bsd/nsd/dist/mkinstalldirs @@ -4,7 +4,7 @@ # Created: 1993-05-16 # Public domain -# $Id: mkinstalldirs,v 1.1.1.4 2019/05/25 19:44:43 christos Exp $ +# Id errstatus=0 diff --git a/external/bsd/nsd/dist/nsd-checkconf.8.in b/external/bsd/nsd/dist/nsd-checkconf.8.in index 18d669750e5a..748cc25dec51 100644 --- a/external/bsd/nsd/dist/nsd-checkconf.8.in +++ b/external/bsd/nsd/dist/nsd-checkconf.8.in @@ -1,4 +1,4 @@ -.TH "nsd\-checkconf" "8" "Mar 25, 2019" "NLnet Labs" "nsd 4.1.27" +.TH "nsd\-checkconf" "8" "Dec 10, 2019" "NLnet Labs" "nsd 4.2.4" .\" Copyright (c) 2001\-2008, NLnet Labs. All rights reserved. .\" See LICENSE for the license. .SH "NAME" diff --git a/external/bsd/nsd/dist/nsd-checkconf.c b/external/bsd/nsd/dist/nsd-checkconf.c index 20eb42a8cf1f..731a74fab40f 100644 --- a/external/bsd/nsd/dist/nsd-checkconf.c +++ b/external/bsd/nsd/dist/nsd-checkconf.c @@ -366,11 +366,14 @@ config_print_zone(nsd_options_type* opt, const char* k, int s, const char *o, SERV_GET_BIN(do_ip6, o); SERV_GET_BIN(reuseport, o); SERV_GET_BIN(hide_version, o); + SERV_GET_BIN(hide_identity, o); SERV_GET_BIN(zonefiles_check, o); SERV_GET_BIN(log_time_ascii, o); SERV_GET_BIN(round_robin, o); SERV_GET_BIN(minimal_responses, o); + SERV_GET_BIN(confine_to_zone, o); SERV_GET_BIN(refuse_any, o); + SERV_GET_BIN(tcp_reject_overflow, o); /* str */ SERV_GET_PATH(final, database, o); SERV_GET_STR(identity, o); @@ -385,6 +388,10 @@ config_print_zone(nsd_options_type* opt, const char* k, int s, const char *o, SERV_GET_PATH(final, xfrdir, o); SERV_GET_PATH(final, zonelistfile, o); SERV_GET_STR(port, o); + SERV_GET_STR(tls_service_key, o); + SERV_GET_STR(tls_service_ocsp, o); + SERV_GET_STR(tls_service_pem, o); + SERV_GET_STR(tls_port, o); /* int */ SERV_GET_INT(server_count, o); SERV_GET_INT(tcp_count, o); @@ -397,6 +404,8 @@ config_print_zone(nsd_options_type* opt, const char* k, int s, const char *o, SERV_GET_INT(statistics, o); SERV_GET_INT(xfrd_reload_timeout, o); SERV_GET_INT(verbosity, o); + SERV_GET_INT(send_buffer_size, o); + SERV_GET_INT(receive_buffer_size, o); #ifdef RATELIMIT SERV_GET_INT(rrl_size, o); SERV_GET_INT(rrl_ratelimit, o); @@ -493,7 +502,12 @@ config_test_print_server(nsd_options_type* opt) printf("\treuseport: %s\n", opt->reuseport?"yes":"no"); printf("\tdo-ip4: %s\n", opt->do_ip4?"yes":"no"); printf("\tdo-ip6: %s\n", opt->do_ip6?"yes":"no"); + printf("\tsend-buffer-size: %d\n", opt->send_buffer_size); + printf("\treceive-buffer-size: %d\n", opt->receive_buffer_size); printf("\thide-version: %s\n", opt->hide_version?"yes":"no"); + printf("\thide-identity: %s\n", opt->hide_identity?"yes":"no"); + printf("\ttcp-reject-overflow: %s\n", + opt->tcp_reject_overflow ? "yes" : "no"); print_string_var("database:", opt->database); print_string_var("identity:", opt->identity); print_string_var("version:", opt->version); @@ -520,6 +534,8 @@ config_test_print_server(nsd_options_type* opt) printf("\tlog-time-ascii: %s\n", opt->log_time_ascii?"yes":"no"); printf("\tround-robin: %s\n", opt->round_robin?"yes":"no"); printf("\tminimal-responses: %s\n", opt->minimal_responses?"yes":"no"); + printf("\tconfine-to-zone: %s\n", + opt->confine_to_zone ? "yes" : "no"); printf("\trefuse-any: %s\n", opt->refuse_any?"yes":"no"); printf("\tverbosity: %d\n", opt->verbosity); for(ip = opt->ip_addresses; ip; ip=ip->next) @@ -536,6 +552,10 @@ config_test_print_server(nsd_options_type* opt) #endif printf("\tzonefiles-check: %s\n", opt->zonefiles_check?"yes":"no"); printf("\tzonefiles-write: %d\n", opt->zonefiles_write); + print_string_var("tls-service-key:", opt->tls_service_key); + print_string_var("tls-service-pem:", opt->tls_service_pem); + print_string_var("tls-service-ocsp:", opt->tls_service_ocsp); + print_string_var("tls-port:", opt->tls_port); #ifdef USE_DNSTAP printf("\ndnstap:\n"); @@ -581,7 +601,6 @@ config_test_print_server(nsd_options_type* opt) print_string_var("name:", zone->name); print_zone_content_elems(zone->pattern); } - } static int @@ -720,7 +739,7 @@ main(int argc, char* argv[]) log_init("nsd-checkconf"); /* Parse the command line... */ - while ((c = getopt(argc, argv, "vfo:a:p:s:z:")) != -1) { + while ((c = getopt(argc, argv, "vfho:a:p:s:z:")) != -1) { switch (c) { case 'v': verbose = 1; @@ -753,6 +772,7 @@ main(int argc, char* argv[]) case 'z': conf_zone = optarg; break; + case 'h': default: usage(); }; diff --git a/external/bsd/nsd/dist/nsd-checkzone.8.in b/external/bsd/nsd/dist/nsd-checkzone.8.in index b6e2499b1a6f..227da662c071 100644 --- a/external/bsd/nsd/dist/nsd-checkzone.8.in +++ b/external/bsd/nsd/dist/nsd-checkzone.8.in @@ -1,4 +1,4 @@ -.TH "nsd\-checkzone" "8" "Mar 25, 2019" "NLnet Labs" "nsd 4.1.27" +.TH "nsd\-checkzone" "8" "Dec 10, 2019" "NLnet Labs" "nsd 4.2.4" .\" Copyright (c) 2014, NLnet Labs. All rights reserved. .\" See LICENSE for the license. .SH "NAME" diff --git a/external/bsd/nsd/dist/nsd-checkzone.c b/external/bsd/nsd/dist/nsd-checkzone.c index 21b8ce5648d2..9bf74fd6538f 100644 --- a/external/bsd/nsd/dist/nsd-checkzone.c +++ b/external/bsd/nsd/dist/nsd-checkzone.c @@ -61,6 +61,10 @@ check_zone(struct nsd* nsd, const char* name, const char* fname) errors = zonec_read(name, fname, zone); if(errors > 0) { printf("zone %s file %s has %u errors\n", name, fname, errors); +#ifdef MEMCLEAN /* otherwise, the OS collects memory pages */ + namedb_close(nsd->db); + region_destroy(nsd->options->region); +#endif exit(1); } printf("zone %s is ok\n", name); diff --git a/external/bsd/nsd/dist/nsd-control.8.in b/external/bsd/nsd/dist/nsd-control.8.in index b6fe680b89bb..20e27a4fb099 100644 --- a/external/bsd/nsd/dist/nsd-control.8.in +++ b/external/bsd/nsd/dist/nsd-control.8.in @@ -1,4 +1,4 @@ -.TH "nsd\-control" "8" "Mar 25, 2019" "NLnet Labs" "nsd 4.1.27" +.TH "nsd\-control" "8" "Dec 10, 2019" "NLnet Labs" "nsd 4.2.4" .\" Copyright (c) 2011, NLnet Labs. All rights reserved. .\" See LICENSE for the license. .SH "NAME" @@ -192,7 +192,7 @@ After running the script as root, turn on \fBcontrol\-enable\fR in The \fIstats\fR command shows a number of statistic counters. .TP .I num.queries -number of queries received (the tcp and udp queries added up). +number of queries received (the tls, tcp and udp queries added up). .TP .I serverX.queries number of queries handled by the server process. The number of @@ -253,6 +253,12 @@ number of connections over TCP ip4. .I num.tcp6 number of connections over TCP ip6. .TP +.I num.tls +number of connections over TLS ip4. TLS queries are not part of num.tcp. +.TP +.I num.tls6 +number of connections over TLS ip6. TLS queries are not part of num.tcp6. +.TP .I num.answer_wo_aa number of answers with NOERROR rcode and without AA flag, this includes the referrals. .TP diff --git a/external/bsd/nsd/dist/nsd-control.c b/external/bsd/nsd/dist/nsd-control.c index efac9ac530db..649320eefa1d 100644 --- a/external/bsd/nsd/dist/nsd-control.c +++ b/external/bsd/nsd/dist/nsd-control.c @@ -42,8 +42,8 @@ */ #include "config.h" +#include #ifdef HAVE_SSL - #include #include #include @@ -163,6 +163,12 @@ setup_ctx(struct nsd_options* cfg) if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3) != SSL_OP_NO_SSLv3) ssl_err("could not set SSL_OP_NO_SSLv3"); +#if defined(SSL_OP_NO_RENEGOTIATION) + /* disable client renegotiation */ + if((SSL_CTX_set_options(ctx, SSL_OP_NO_RENEGOTIATION) & + SSL_OP_NO_RENEGOTIATION) != SSL_OP_NO_RENEGOTIATION) + ssl_err("could not set SSL_OP_NO_RENEGOTIATION"); +#endif if(!SSL_CTX_use_certificate_file(ctx,c_cert,SSL_FILETYPE_PEM)) ssl_path_err("Error setting up SSL_CTX client cert", c_cert); if(!SSL_CTX_use_PrivateKey_file(ctx,c_key,SSL_FILETYPE_PEM)) @@ -229,6 +235,7 @@ contact_server(const char* svr, struct nsd_options* cfg, int statuscmd) addrfamily = AF_LOCAL; port = 0; #endif +#ifdef INET6 } else if(strchr(svr, ':')) { struct sockaddr_in6 sa; addrlen = (socklen_t)sizeof(struct sockaddr_in6); @@ -241,6 +248,7 @@ contact_server(const char* svr, struct nsd_options* cfg, int statuscmd) } memcpy(&addr, &sa, addrlen); addrfamily = AF_INET6; +#endif } else { /* ip4 */ struct sockaddr_in sa; addrlen = (socklen_t)sizeof(struct sockaddr_in); diff --git a/external/bsd/nsd/dist/nsd.8.in b/external/bsd/nsd/dist/nsd.8.in index 1d58c5ad8779..cdba544f2979 100644 --- a/external/bsd/nsd/dist/nsd.8.in +++ b/external/bsd/nsd/dist/nsd.8.in @@ -1,9 +1,9 @@ -.TH "NSD" "8" "Mar 25, 2019" "NLnet Labs" "NSD 4.1.27" +.TH "NSD" "8" "Dec 10, 2019" "NLnet Labs" "NSD 4.2.4" .\" Copyright (c) 2001\-2008, NLnet Labs. All rights reserved. .\" See LICENSE for the license. .SH "NAME" .B nsd -\- Name Server Daemon (NSD) version 4.1.27. +\- Name Server Daemon (NSD) version 4.2.4. .SH "SYNOPSIS" .B nsd .RB [ \-4 ] diff --git a/external/bsd/nsd/dist/nsd.c b/external/bsd/nsd/dist/nsd.c index 1075ef953cd4..ee87ce6343c5 100644 --- a/external/bsd/nsd/dist/nsd.c +++ b/external/bsd/nsd/dist/nsd.c @@ -119,50 +119,170 @@ version(void) exit(0); } -void -get_ip_port_frm_str(const char* arg, const char** hostname, - const char** port) +static void +copyaddrinfo(struct nsd_addrinfo *dest, struct addrinfo *src) { - /* parse src[@port] option */ - char* delim = NULL; - if (arg) { - delim = strchr(arg, '@'); - } - - if (delim) { - *delim = '\0'; - *port = delim+1; - } - *hostname = arg; + dest->ai_flags = src->ai_flags; + dest->ai_family = src->ai_family; + dest->ai_socktype = src->ai_socktype; + dest->ai_addrlen = src->ai_addrlen; + memcpy(&dest->ai_addr, src->ai_addr, src->ai_addrlen); } -/* append interface to interface array (names, udp, tcp) */ -void -add_interface(char*** nodes, struct nsd* nsd, char* ip) +static void +setup_socket(struct nsd_socket *sock, const char *node, const char *port, struct addrinfo *hints) { - /* realloc the arrays */ - if(nsd->ifs == 0) { - *nodes = xalloc_zero(sizeof(*nodes)); - nsd->udp = xalloc_zero(sizeof(*nsd->udp)); - nsd->tcp = xalloc_zero(sizeof(*nsd->udp)); - } else { - region_remove_cleanup(nsd->region, free, *nodes); - region_remove_cleanup(nsd->region, free, nsd->udp); - region_remove_cleanup(nsd->region, free, nsd->tcp); - *nodes = xrealloc(*nodes, (nsd->ifs+1)*sizeof(*nodes)); - nsd->udp = xrealloc(nsd->udp, (nsd->ifs+1)*sizeof(*nsd->udp)); - nsd->tcp = xrealloc(nsd->tcp, (nsd->ifs+1)*sizeof(*nsd->udp)); - (*nodes)[nsd->ifs] = NULL; - memset(&nsd->udp[nsd->ifs], 0, sizeof(*nsd->udp)); - memset(&nsd->tcp[nsd->ifs], 0, sizeof(*nsd->tcp)); - } - region_add_cleanup(nsd->region, free, *nodes); - region_add_cleanup(nsd->region, free, nsd->udp); - region_add_cleanup(nsd->region, free, nsd->tcp); + int ret; + char *sep = NULL; + char *host, host_buf[INET6_ADDRSTRLEN + 1 /* '\0' */]; + const char *service; + char service_buf[6 + 1 /* '\0' */]; /* 65535 */ + struct addrinfo *addr = NULL; - /* add it */ - (*nodes)[nsd->ifs] = ip; - ++nsd->ifs; + if(node) { + host = host_buf; + sep = strchr(node, '@'); + if(sep) { + size_t len = (sep - node) + 1; + if (len > sizeof(host_buf)) { + len = sizeof(host_buf); + } + strlcpy(host_buf, node, len); + strlcpy(service_buf, sep + 1, sizeof(service_buf)); + service = service_buf; + } else { + strlcpy(host_buf, node, sizeof(host_buf)); + service = port; + } + } else { + host = NULL; + service = port; + } + + if((ret = getaddrinfo(host, service, hints, &addr)) == 0) { + copyaddrinfo(&sock->addr, addr); + freeaddrinfo(addr); + } else { + error("cannot parse address '%s': getaddrinfo: %s %s", + host ? host : "(null)", + gai_strerror(ret), + ret==EAI_SYSTEM ? strerror(errno) : ""); + } +} + +static void +figure_default_sockets( + struct nsd_socket **udp, struct nsd_socket **tcp, size_t *ifs, + const char *udp_port, const char *tcp_port, + const struct addrinfo *hints) +{ + int r; + size_t i = 0, n = 1; + struct addrinfo ai[2] = { *hints, *hints }; + + assert(udp != NULL); + assert(tcp != NULL); + assert(ifs != NULL); + + ai[0].ai_socktype = SOCK_DGRAM; + ai[1].ai_socktype = SOCK_STREAM; + +#ifdef INET6 +#ifdef IPV6_V6ONLY + if (hints->ai_family == AF_UNSPEC) { + ai[0].ai_family = AF_INET6; + ai[1].ai_family = AF_INET6; + n++; + } +#endif /* IPV6_V6ONLY */ +#endif /* INET6 */ + + *udp = xalloc_zero((n + 1) * sizeof(struct nsd_socket)); + *tcp = xalloc_zero((n + 1) * sizeof(struct nsd_socket)); + region_add_cleanup(nsd.region, free, *udp); + region_add_cleanup(nsd.region, free, *tcp); + +#ifdef INET6 + if(hints->ai_family == AF_UNSPEC) { + /* + * With IPv6 we'd like to open two separate sockets, + * one for IPv4 and one for IPv6, both listening to + * the wildcard address (unless the -4 or -6 flags are + * specified). + * + * However, this is only supported on platforms where + * we can turn the socket option IPV6_V6ONLY _on_. + * Otherwise we just listen to a single IPv6 socket + * and any incoming IPv4 connections will be + * automatically mapped to our IPv6 socket. + */ +#ifdef IPV6_V6ONLY + struct addrinfo *addrs[2] = { NULL, NULL }; + + if((r = getaddrinfo(NULL, udp_port, &ai[0], &addrs[0])) == 0 && + (r = getaddrinfo(NULL, tcp_port, &ai[1], &addrs[1])) == 0) + { + (*udp)[i].flags |= NSD_SOCKET_IS_OPTIONAL; + copyaddrinfo(&(*udp)[i].addr, addrs[0]); + (*tcp)[i].flags |= NSD_SOCKET_IS_OPTIONAL; + copyaddrinfo(&(*tcp)[i].addr, addrs[1]); + i++; + } else { + log_msg(LOG_WARNING, "No IPv6, fallback to IPv4. getaddrinfo: %s", + r == EAI_SYSTEM ? strerror(errno) : gai_strerror(r)); + } + + if(addrs[0]) + freeaddrinfo(addrs[0]); + if(addrs[1]) + freeaddrinfo(addrs[1]); + + ai[0].ai_family = AF_INET; + ai[1].ai_family = AF_INET; +#endif /* IPV6_V6ONLY */ + } +#endif /* INET6 */ + + *ifs = i + 1; + setup_socket(&(*udp)[i], NULL, udp_port, &ai[0]); + setup_socket(&(*tcp)[i], NULL, tcp_port, &ai[1]); +} + +static void +figure_sockets( + struct nsd_socket **udp, struct nsd_socket **tcp, size_t *ifs, + struct ip_address_option *ips, + const char *udp_port, const char *tcp_port, + const struct addrinfo *hints) +{ + size_t i = 0; + struct addrinfo ai = *hints; + struct ip_address_option *ip; + + if(!ips) { + figure_default_sockets(udp, tcp, ifs, udp_port, tcp_port, hints); + return; + } + + *ifs = 0; + for(ip = ips; ip; ip = ip->next) { + (*ifs)++; + } + + *udp = xalloc_zero((*ifs + 1) * sizeof(struct nsd_socket)); + *tcp = xalloc_zero((*ifs + 1) * sizeof(struct nsd_socket)); + region_add_cleanup(nsd.region, free, *udp); + region_add_cleanup(nsd.region, free, *tcp); + + ai.ai_flags |= AI_NUMERICHOST; + for(ip = ips, i = 0; ip; ip = ip->next, i++) { + ai.ai_socktype = SOCK_DGRAM; + setup_socket(&(*udp)[i], ip->address, udp_port, &ai); + ai.ai_socktype = SOCK_STREAM; + setup_socket(&(*tcp)[i], ip->address, tcp_port, &ai); + } + + assert(i == *ifs); } /* @@ -212,6 +332,8 @@ writepid(struct nsd *nsd) { FILE * fd; char pidbuf[32]; + if(!nsd->pidfile || !nsd->pidfile[0]) + return 0; snprintf(pidbuf, sizeof(pidbuf), "%lu\n", (unsigned long) nsd->pid); @@ -244,7 +366,7 @@ unlinkpid(const char* file) { int fd = -1; - if (file) { + if (file && file[0]) { /* truncate pidfile */ fd = open(file, O_WRONLY | O_TRUNC, 0644); if (fd == -1) { @@ -401,9 +523,8 @@ main(int argc, char *argv[]) struct passwd *pwd = NULL; #endif /* HAVE_GETPWNAM */ - struct addrinfo hints[2]; - int hints_in_use = 1; - char** nodes = NULL; /* array of address strings, size nsd.ifs */ + struct ip_address_option *ip; + struct addrinfo hints; const char *udp_port = 0; const char *tcp_port = 0; @@ -419,11 +540,9 @@ main(int argc, char *argv[]) nsd.dbfile = 0; nsd.pidfile = 0; nsd.server_kind = NSD_SERVER_MAIN; - memset(&hints, 0, sizeof(*hints)*2); - hints[0].ai_family = DEFAULT_AI_FAMILY; - hints[0].ai_flags = AI_PASSIVE; - hints[1].ai_family = DEFAULT_AI_FAMILY; - hints[1].ai_flags = AI_PASSIVE; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = DEFAULT_AI_FAMILY; + hints.ai_flags = AI_PASSIVE; nsd.identity = 0; nsd.version = VERSION; nsd.username = 0; @@ -434,7 +553,6 @@ main(int argc, char *argv[]) nsd.child_count = 0; nsd.maximum_tcp_count = 0; nsd.current_tcp_count = 0; - nsd.grab_ip6_optional = 0; nsd.file_rotation_ok = 0; /* Set up our default identity to gethostname(2) */ @@ -447,6 +565,11 @@ main(int argc, char *argv[]) nsd.identity = IDENTITY; } + /* Create region where options will be stored and set defaults */ + nsd.options = nsd_options_create(region_create_custom(xalloc, free, + DEFAULT_CHUNK_SIZE, DEFAULT_LARGE_OBJECT_SIZE, + DEFAULT_INITIAL_CLEANUP_SIZE, 1)); + /* Parse the command line... */ while ((c = getopt(argc, argv, "46a:c:df:hi:I:l:N:n:P:p:s:u:t:X:V:v" #ifndef NDEBUG /* only when configured with --enable-checking */ @@ -455,17 +578,22 @@ main(int argc, char *argv[]) )) != -1) { switch (c) { case '4': - hints[0].ai_family = AF_INET; + hints.ai_family = AF_INET; break; case '6': #ifdef INET6 - hints[0].ai_family = AF_INET6; + hints.ai_family = AF_INET6; #else /* !INET6 */ error("IPv6 support not enabled."); #endif /* INET6 */ break; case 'a': - add_interface(&nodes, &nsd, optarg); + ip = region_alloc_zero( + nsd.options->region, sizeof(*ip)); + ip->address = region_strdup( + nsd.options->region, optarg); + ip->next = nsd.options->ip_addresses; + nsd.options->ip_addresses = ip; break; case 'c': configfile = optarg; @@ -586,9 +714,6 @@ main(int argc, char *argv[]) error("init tsig failed"); /* Read options */ - nsd.options = nsd_options_create(region_create_custom(xalloc, free, - DEFAULT_CHUNK_SIZE, DEFAULT_LARGE_OBJECT_SIZE, - DEFAULT_INITIAL_CLEANUP_SIZE, 1)); if(!parse_options_file(nsd.options, configfile, NULL, NULL)) { error("could not read config: %s\n", configfile); } @@ -597,21 +722,13 @@ main(int argc, char *argv[]) nsd.options->zonelistfile); } if(nsd.options->do_ip4 && !nsd.options->do_ip6) { - hints[0].ai_family = AF_INET; + hints.ai_family = AF_INET; } #ifdef INET6 if(nsd.options->do_ip6 && !nsd.options->do_ip4) { - hints[0].ai_family = AF_INET6; + hints.ai_family = AF_INET6; } #endif /* INET6 */ - if(nsd.options->ip_addresses) - { - ip_address_option_type* ip = nsd.options->ip_addresses; - while(ip) { - add_interface(&nodes, &nsd, ip->address); - ip = ip->next; - } - } if (verbosity == 0) verbosity = nsd.options->verbosity; #ifndef NDEBUG @@ -661,6 +778,9 @@ main(int argc, char *argv[]) nsd.outgoing_tcp_mss = nsd.options->outgoing_tcp_mss; nsd.ipv4_edns_size = nsd.options->ipv4_edns_size; nsd.ipv6_edns_size = nsd.options->ipv6_edns_size; +#ifdef HAVE_SSL + nsd.tls_ctx = NULL; +#endif if(udp_port == 0) { @@ -745,73 +865,8 @@ main(int argc, char *argv[]) nsd.this_child = NULL; - /* We need at least one active interface */ - if (nsd.ifs == 0) { - add_interface(&nodes, &nsd, NULL); - - /* - * With IPv6 we'd like to open two separate sockets, - * one for IPv4 and one for IPv6, both listening to - * the wildcard address (unless the -4 or -6 flags are - * specified). - * - * However, this is only supported on platforms where - * we can turn the socket option IPV6_V6ONLY _on_. - * Otherwise we just listen to a single IPv6 socket - * and any incoming IPv4 connections will be - * automatically mapped to our IPv6 socket. - */ -#ifdef INET6 - if (hints[0].ai_family == AF_UNSPEC) { -#ifdef IPV6_V6ONLY - add_interface(&nodes, &nsd, NULL); - hints[0].ai_family = AF_INET6; - hints[1].ai_family = AF_INET; - hints_in_use = 2; - nsd.grab_ip6_optional = 1; -#else /* !IPV6_V6ONLY */ - hints[0].ai_family = AF_INET6; -#endif /* IPV6_V6ONLY */ - } -#endif /* INET6 */ - } - - /* Set up the address info structures with real interface/port data */ - assert(nodes); - for (i = 0; i < nsd.ifs; ++i) { - int r; - const char* node = NULL; - const char* service = NULL; - int h = ((hints_in_use == 1)?0:i%hints_in_use); - - /* We don't perform name-lookups */ - if (nodes[i] != NULL) - hints[h].ai_flags |= AI_NUMERICHOST; - get_ip_port_frm_str(nodes[i], &node, &service); - - hints[h].ai_socktype = SOCK_DGRAM; - if ((r=getaddrinfo(node, (service?service:udp_port), &hints[h], &nsd.udp[i].addr)) != 0) { -#ifdef INET6 - if(nsd.grab_ip6_optional && hints[0].ai_family == AF_INET6) { - log_msg(LOG_WARNING, "No IPv6, fallback to IPv4. getaddrinfo: %s", - r==EAI_SYSTEM?strerror(errno):gai_strerror(r)); - continue; - } -#endif - error("cannot parse address '%s': getaddrinfo: %s %s", - nodes[i]?nodes[i]:"(null)", - gai_strerror(r), - r==EAI_SYSTEM?strerror(errno):""); - } - - hints[h].ai_socktype = SOCK_STREAM; - if ((r=getaddrinfo(node, (service?service:tcp_port), &hints[h], &nsd.tcp[i].addr)) != 0) { - error("cannot parse address '%s': getaddrinfo: %s %s", - nodes[i]?nodes[i]:"(null)", - gai_strerror(r), - r==EAI_SYSTEM?strerror(errno):""); - } - } + figure_sockets(&nsd.udp, &nsd.tcp, &nsd.ifs, + nsd.options->ip_addresses, udp_port, tcp_port, &hints); /* Parse the username into uid and gid */ nsd.gid = getgid(); @@ -894,20 +949,22 @@ main(int argc, char *argv[]) log_msg(LOG_NOTICE, "%s starting (%s)", argv0, PACKAGE_STRING); /* Do we have a running nsd? */ - if ((oldpid = readpid(nsd.pidfile)) == -1) { - if (errno != ENOENT) { - log_msg(LOG_ERR, "can't read pidfile %s: %s", - nsd.pidfile, strerror(errno)); - } - } else { - if (kill(oldpid, 0) == 0 || errno == EPERM) { - log_msg(LOG_WARNING, - "%s is already running as %u, continuing", - argv0, (unsigned) oldpid); + if(nsd.pidfile && nsd.pidfile[0]) { + if ((oldpid = readpid(nsd.pidfile)) == -1) { + if (errno != ENOENT) { + log_msg(LOG_ERR, "can't read pidfile %s: %s", + nsd.pidfile, strerror(errno)); + } } else { - log_msg(LOG_ERR, - "...stale pid file from process %u", - (unsigned) oldpid); + if (kill(oldpid, 0) == 0 || errno == EPERM) { + log_msg(LOG_WARNING, + "%s is already running as %u, continuing", + argv0, (unsigned) oldpid); + } else { + log_msg(LOG_ERR, + "...stale pid file from process %u", + (unsigned) oldpid); + } } } @@ -942,11 +999,20 @@ main(int argc, char *argv[]) "not be started", argv0); } #if defined(HAVE_SSL) + if(nsd.options->control_enable || (nsd.options->tls_service_key && nsd.options->tls_service_key[0])) { + perform_openssl_init(); + } if(nsd.options->control_enable) { /* read ssl keys while superuser and outside chroot */ if(!(nsd.rc = daemon_remote_create(nsd.options))) error("could not perform remote control setup"); } + if(nsd.options->tls_service_key && nsd.options->tls_service_key[0] + && nsd.options->tls_service_pem && nsd.options->tls_service_pem[0]) { + if(!(nsd.tls_ctx = server_tls_ctx_create(&nsd, NULL, + nsd.options->tls_service_ocsp))) + error("could not set up tls SSL_CTX"); + } #endif /* HAVE_SSL */ /* Unless we're debugging, fork... */ @@ -1014,7 +1080,7 @@ main(int argc, char *argv[]) if (nsd.log_filename[0] == '/') nsd.log_filename += l; } - if (nsd.pidfile[0] == '/') + if (nsd.pidfile && nsd.pidfile[0] == '/') nsd.pidfile += l; if (nsd.dbfile[0] == '/') nsd.dbfile += l; diff --git a/external/bsd/nsd/dist/nsd.conf.5.in b/external/bsd/nsd/dist/nsd.conf.5.in index 7fe13d7a61ad..297414b27b43 100644 --- a/external/bsd/nsd/dist/nsd.conf.5.in +++ b/external/bsd/nsd/dist/nsd.conf.5.in @@ -1,4 +1,4 @@ -.TH "nsd.conf" "5" "Mar 25, 2019" "NLnet Labs" "nsd 4.1.27" +.TH "nsd.conf" "5" "Dec 10, 2019" "NLnet Labs" "nsd 4.2.4" .\" Copyright (c) 2001\-2008, NLnet Labs. All rights reserved. .\" See LICENSE for the license. .SH "NAME" @@ -100,23 +100,13 @@ with a colon ':'. An attribute is followed by its containing attributes, or a value. .P At the top level only -.B server: +.BR server: , +.BR key: , +.BR pattern: , +.BR zone: , and -.B key: -and -.B pattern: -and -.B zone: -are allowed. These are followed by their attributes or the start of -a new -.B server: -or -.B key: -or -.B pattern: -or -.B zone: -clause. The +.B remote-control: +are allowed. These are followed by their attributes or a new top-level keyword. The .B zone: attribute is followed by zone options. The .B server: @@ -149,7 +139,7 @@ clause. There may only be one clause. .TP .B ip\-address:\fR [@port] -NSD will bind to the listed ip\-address. Can be give multiple times +NSD will bind to the listed ip\-address. Can be given multiple times to bind multiple ip\-addresses. Optionally, a port number can be given. If none are given NSD listens to the wildcard interface. Same as commandline option .BR \-a. @@ -181,6 +171,12 @@ than 1 (such as, equal to the number of cpus). The default is no. It works on Linux, but does not work on FreeBSD, and likely does not work on other systems. .TP +.B send\-buffer\-size:\fR +Set the send buffer size for query-servicing sockets. Set to 0 to use the default settings. +.TP +.B receive\-buffer\-size:\fR +Set the receive buffer size for query-servicing sockets. Set to 0 to use the default settings. +.TP .B debug\-mode:\fR Turns on debugging mode for nsd, does not fork a daemon process. Default is no. Same as commandline option @@ -217,6 +213,7 @@ Returns the specified identity when asked for CH TXT ID.SERVER. Default is the name as returned by gethostname(3). Same as commandline option .BR \-i . +See hide\-identity to set the server to not respond to such queries. .TP .B version:\fR Returns the specified version string when asked for CH TXT version.server, @@ -244,6 +241,10 @@ The maximum number of concurrent, active TCP connections by each server. Default is 100. Same as commandline option .BR \-n . .TP +.B tcp\-reject\-overflow:\fR +If set to yes, TCP connections made beyond the maximum set by tcp-count will +be dropped immediately (accepted and closed). Default is no. +.TP .B tcp\-query\-count:\fR The maximum number of queries served on a single TCP connection. Default is 0, meaning there is no maximum. @@ -279,6 +280,8 @@ Use the pid file instead of the platform specific default, usually .IR @pidfile@. Same as commandline option .BR \-P . +With "" there is no pidfile, for some startup management setups, +where a pidfile is not useful to have. .TP .B port:\fR Answer queries on the specified port. Default is 53. Same as @@ -359,6 +362,10 @@ And notify refusal, and axfr request refusals. Prevent NSD from replying with the version string on CHAOS class queries. Default is no. .TP +.B hide\-identity:\fR +Prevent NSD from replying with the identity string on CHAOS class +queries. Default is no. +.TP .B log\-time\-ascii:\fR Log time in ascii, if "no" then in seconds epoch. Default is yes. This chooses the format when logging to file. The printout via syslog @@ -377,6 +384,11 @@ that reduces packets, but exactly to the fragmentation length, the nsd.conf option reduces packets as small as possible. The default is no. .TP +.B confine\-to\-zone:\fR +If set to yes, additional information will not be added to the response if the +apex zone of the additional information does not match the apex zone of the +initial query (E.G. CNAME resolution). Default is no. +.TP .B refuse\-any:\fR Refuse queries of type ANY. This is useful to stop query floods trying to get large responses. Note that rrl ratelimiting also has type ANY as @@ -436,6 +448,38 @@ whitelisted. Default @ratelimit_default@ (with a suggested 2000 qps). With the r specific queries to receive this qps limit instead of the normal limit. With the value 0 the rate is unlimited. .\" rrlend +.TP +.B tls\-service\-key:\fR +If enabled, the server provides TLS service on TCP sockets with the TLS +service port number. The port number (853) is configured with tls\-port. +To turn it on, create an interface: option line in config with @port +appended to the IP-address. This creates the extra socket on which the +DNS over TLS service is provided. +.IP +The file is the private key for the TLS session. The public certificate is +in the tls-service-pem file. Default is "", turned off. Requires a +restart (a reload is not enough) if changed, because the private key is +read while root permissions are held and before chroot (if any). +.TP +.B tls\-service\-pem:\fR +The public key certificate pem file for the tls service. Default is "", turned off. +.TP +.B tls\-service\-ocsp:\fR +The ocsp pem file for the tls service, for OCSP stapling. Default is "", +turned off. An external process prepares and updates the OCSP stapling data. +Like this, +.RS 9 +openssl ocsp -no_nonce \\ + -respout /path/to/ocsp.pem \\ + -CAfile /path/to/ca_and_any_intermediate.pem \\ + -issuer /path/to/direct_issuer.pem \\ + -cert /path/to/cert.pem \\ + -url "$( openssl x509 -noout -text -in /path/to/cert.pem | grep 'OCSP - URI:' | cut -d: -f2,3 )" +.RE +.TP +.B tls\-port:\fR +The port number on which to provide TCP TLS service, default is 853, only +interfaces configured with that port number as @number get DNS over TLS service. .SS "Remote Control" The .B remote\-control: diff --git a/external/bsd/nsd/dist/nsd.conf.sample.in b/external/bsd/nsd/dist/nsd.conf.sample.in index bd3a6e89cab7..e6886fd8f1e0 100644 --- a/external/bsd/nsd/dist/nsd.conf.sample.in +++ b/external/bsd/nsd/dist/nsd.conf.sample.in @@ -33,6 +33,14 @@ server: # use the reuseport socket option for performance. Default no. # reuseport: no + # override maximum socket send buffer size. Default of 0 results in + # send buffer size being set to 1048576 (bytes). + # send-buffer-size: 1048576 + + # override maximum socket receive buffer size. Default of 0 results in + # receive buffer size being set to 1048576 (bytes). + # receive-buffer-size: 1048576 + # enable debug mode, does not fork daemon process into the background. # debug-mode: no @@ -59,7 +67,7 @@ server: # The directory for zonefile: files. The daemon chdirs here. # zonesdir: "@zonesdir@" - + # the list of dynamically added zones. # zonelistfile: "@zonelistfile@" @@ -85,6 +93,9 @@ server: # don't answer VERSION.BIND and VERSION.SERVER CHAOS class queries # hide-version: no + # don't answer HOSTNAME.BIND and ID.SERVER CHAOS class queries + # hide-identity: no + # version string the server responds with for chaos queries. # default is 'NSD x.y.z' with the server's version number. # version: "NSD" @@ -98,6 +109,11 @@ server: # Maximum number of concurrent TCP connections per server. # tcp-count: 100 + # Accept (and immediately close) TCP connections after maximum number + # of connections is reached to prevent kernel connection queue from + # growing. + # tcp-reject-overflow: no + # Maximum number of queries served on a single TCP connection. # By default 0, which means no maximum. # tcp-query-count: 0 @@ -135,6 +151,11 @@ server: # minimal-responses only emits extra data for referrals. # minimal-responses: no + # Do not return additional information if the apex zone of the + # additional information is configured but does not match the apex zone + # of the initial query. + # confine-to-zone: no + # refuse queries of type ANY. For stopping floods. # refuse-any: no @@ -177,6 +198,14 @@ server: # rrl-whitelist-ratelimit: 2000 # RRLend + # Service clients over TLS (on the TCP sockets), with plain DNS inside + # the TLS stream. Give the certificate to use and private key. + # Default is "" (disabled). Requires restart to take effect. + # tls-service-key: "path/to/privatekeyfile.key" + # tls-service-pem: "path/to/publiccertfile.pem" + # tls-service-ocsp: "path/to/ocsp.pem" + # tls-port: 853 + # DNSTAP config section, if compiled with that # dnstap: # set this to yes and set one or more of dnstap-log-..-messages to yes. diff --git a/external/bsd/nsd/dist/nsd.h b/external/bsd/nsd/dist/nsd.h index c900ca6cbaa8..0cee8c87fc6d 100644 --- a/external/bsd/nsd/dist/nsd.h +++ b/external/bsd/nsd/dist/nsd.h @@ -11,6 +11,9 @@ #define _NSD_H_ #include +#ifdef HAVE_OPENSSL_SSL_H +#include +#endif #include "dns.h" #include "edns.h" @@ -107,17 +110,28 @@ typedef unsigned long stc_type; #define ZTATUP2(nsd, zone, stc, i) /* Nothing */ #endif /* USE_ZONE_STATS */ +#define NSD_SOCKET_IS_OPTIONAL (1<<0) + +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 addrinfo * addr; + struct nsd_addrinfo addr; int s; - int fam; + int flags; }; struct nsd_child { /* The type of child process (UDP or TCP handler). */ - int kind; + int kind; /* The child's process id. */ pid_t pid; @@ -206,12 +220,11 @@ struct nsd const char *version; const char *identity; uint16_t nsid_len; - unsigned char *nsid; + unsigned char *nsid; uint8_t file_rotation_ok; /* number of interfaces */ size_t ifs; - uint8_t grab_ip6_optional; /* non0 if so_reuseport is in use, if so, tcp, udp array increased */ int reuseport; @@ -244,6 +257,7 @@ struct nsd stc_type qclass[4]; /* Class IN or Class CH or other */ stc_type qudp, qudp6; /* Number of queries udp and udp6 */ stc_type ctcp, ctcp6; /* Number of tcp and tcp6 connections */ + stc_type ctls, ctls6; /* Number of tls and tls6 connections */ stc_type rcode[17], opcode[6]; /* Rcodes & opcodes */ /* Dropped, truncated, queries for nonconfigured zone, tx errors */ stc_type dropped, truncated, wrongzone, txerr, rxerr; @@ -276,6 +290,11 @@ struct nsd unsigned int err_limit_count; struct nsd_options* options; + +#ifdef HAVE_SSL + /* TLS specific configuration */ + SSL_CTX *tls_ctx; +#endif }; extern struct nsd nsd; @@ -295,6 +314,7 @@ 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); struct event_base* nsd_child_event_base(void); +void service_remaining_tcp(struct nsd* nsd); /* extra domain numbers for temporary domains */ #define EXTRA_DOMAIN_NUMBERS 1024 #define SLOW_ACCEPT_TIMEOUT 2 /* in seconds */ @@ -311,6 +331,11 @@ void server_prepare_xfrd(struct nsd *nsd); void server_start_xfrd(struct nsd *nsd, int del_db, int reload_active); /* send SOA serial numbers to xfrd */ 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 /* _NSD_H_ */ diff --git a/external/bsd/nsd/dist/options.c b/external/bsd/nsd/dist/options.c index 7d1fde98c834..df6adef527df 100644 --- a/external/bsd/nsd/dist/options.c +++ b/external/bsd/nsd/dist/options.c @@ -24,7 +24,6 @@ int c_parse(void); int c_lex(void); int c_wrap(void); int c_lex_destroy(void); -void c_error(const char *message); extern char* c_text; static int @@ -52,9 +51,12 @@ nsd_options_create(region_type* region) opt->ip_addresses = NULL; opt->ip_transparent = 0; opt->ip_freebind = 0; + opt->send_buffer_size = 0; + opt->receive_buffer_size = 0; opt->debug_mode = 0; opt->verbosity = 0; opt->hide_version = 0; + opt->hide_identity = 0; opt->do_ip4 = 1; opt->do_ip6 = 1; opt->database = DBFILE; @@ -65,9 +67,11 @@ nsd_options_create(region_type* region) opt->log_time_ascii = 1; opt->round_robin = 0; /* also packet.h::round_robin */ opt->minimal_responses = 0; /* also packet.h::minimal_responses */ + opt->confine_to_zone = 0; opt->refuse_any = 0; opt->server_count = 1; opt->tcp_count = 100; + opt->tcp_reject_overflow = 0; opt->tcp_query_count = 0; opt->tcp_timeout = TCP_TIMEOUT; opt->tcp_mss = 0; @@ -113,6 +117,10 @@ nsd_options_create(region_type* region) opt->zonefiles_write = ZONEFILES_WRITE_INTERVAL; else opt->zonefiles_write = 0; opt->xfrd_reload_timeout = 1; + opt->tls_service_key = NULL; + opt->tls_service_ocsp = NULL; + opt->tls_service_pem = NULL; + opt->tls_port = TLS_PORT; opt->control_enable = 0; opt->control_interface = NULL; opt->control_port = NSD_CONTROL_PORT; @@ -166,19 +174,11 @@ parse_options_file(struct nsd_options* opt, const char* file, cfg_parser->filename = (char*)file; cfg_parser->line = 1; cfg_parser->errors = 0; - cfg_parser->server_settings_seen = 0; cfg_parser->opt = opt; - cfg_parser->current_pattern = 0; - cfg_parser->current_zone = 0; - cfg_parser->current_key = 0; - cfg_parser->current_ip_address_option = opt->ip_addresses; - while(cfg_parser->current_ip_address_option && cfg_parser->current_ip_address_option->next) - cfg_parser->current_ip_address_option = cfg_parser->current_ip_address_option->next; - cfg_parser->current_allow_notify = 0; - cfg_parser->current_request_xfr = 0; - cfg_parser->current_notify = 0; - cfg_parser->current_provide_xfr = 0; - + cfg_parser->pattern = NULL; + cfg_parser->zone = NULL; + cfg_parser->key = NULL; + in = fopen(cfg_parser->filename, "r"); if(!in) { if(err) { @@ -197,36 +197,7 @@ parse_options_file(struct nsd_options* opt, const char* file, fclose(in); opt->configfile = region_strdup(opt->region, file); - if(cfg_parser->current_pattern) { - if(!cfg_parser->current_pattern->pname) - c_error("last pattern has no name"); - else { - if(!nsd_options_insert_pattern(cfg_parser->opt, - cfg_parser->current_pattern)) - c_error("duplicate pattern"); - } - } - if(cfg_parser->current_zone) { - if(!cfg_parser->current_zone->name) - c_error("last zone has no name"); - else { - if(!nsd_options_insert_zone(opt, - cfg_parser->current_zone)) - c_error("duplicate zone"); - } - if(!cfg_parser->current_zone->pattern) - c_error("last zone has no pattern"); - } - if(cfg_parser->current_key) - { - if(!cfg_parser->current_key->name) - c_error("last key has no name"); - if(!cfg_parser->current_key->algorithm) - c_error("last key has no algorithm"); - if(!cfg_parser->current_key->secret) - c_error("last key has no secret blob"); - key_options_insert(opt, cfg_parser->current_key); - } + RBTREE_FOR(pat, struct pattern_options*, opt->patterns) { /* lookup keys for acls */ @@ -236,7 +207,7 @@ parse_options_file(struct nsd_options* opt, const char* file, continue; acl->key_options = key_options_find(opt, acl->key_name); if(!acl->key_options) - c_error_msg("key %s in pattern %s could not be found", + c_error("key %s in pattern %s could not be found", acl->key_name, pat->pname); } for(acl=pat->notify; acl; acl=acl->next) @@ -245,7 +216,7 @@ parse_options_file(struct nsd_options* opt, const char* file, continue; acl->key_options = key_options_find(opt, acl->key_name); if(!acl->key_options) - c_error_msg("key %s in pattern %s could not be found", + c_error("key %s in pattern %s could not be found", acl->key_name, pat->pname); } for(acl=pat->request_xfr; acl; acl=acl->next) @@ -254,7 +225,7 @@ parse_options_file(struct nsd_options* opt, const char* file, continue; acl->key_options = key_options_find(opt, acl->key_name); if(!acl->key_options) - c_error_msg("key %s in pattern %s could not be found", + c_error("key %s in pattern %s could not be found", acl->key_name, pat->pname); } for(acl=pat->provide_xfr; acl; acl=acl->next) @@ -263,7 +234,7 @@ parse_options_file(struct nsd_options* opt, const char* file, continue; acl->key_options = key_options_find(opt, acl->key_name); if(!acl->key_options) - c_error_msg("key %s in pattern %s could not be found", + c_error("key %s in pattern %s could not be found", acl->key_name, pat->pname); } } @@ -710,7 +681,7 @@ zone_list_close(struct nsd_options* opt) } } -void +static void c_error_va_list_pos(int showpos, const char* fmt, va_list args) { char* at = NULL; @@ -741,35 +712,24 @@ c_error_va_list_pos(int showpos, const char* fmt, va_list args) } void -c_error_msg_pos(int showpos, const char* fmt, ...) +c_error(const char *fmt, ...) { - va_list args; - va_start(args, fmt); - c_error_va_list_pos(showpos, fmt, args); - va_end(args); -} + va_list ap; + int showpos = 0; -void -c_error_msg(const char* fmt, ...) -{ - va_list args; - va_start(args, fmt); - c_error_va_list_pos(0, fmt, args); - va_end(args); -} + if (strcmp(fmt, "syntax error") == 0 || strcmp(fmt, "parse error") == 0) { + showpos = 1; + } -void -c_error(const char* str) -{ - if((strcmp(str, "syntax error")==0 || strcmp(str, "parse error")==0)) - c_error_msg_pos(1, "%s", str); - else c_error_msg("%s", str); + va_start(ap, fmt); + c_error_va_list_pos(showpos, fmt, ap); + va_end(ap); } int -c_wrap() +c_wrap(void) { - return 1; + return 1; } struct zone_options* @@ -1854,11 +1814,11 @@ parse_acl_range_subnet(char* p, void* addr, int maxbits) int subnet_bits = atoi(p); uint8_t* addr_bytes = (uint8_t*)addr; if(subnet_bits == 0 && strcmp(p, "0")!=0) { - c_error_msg("bad subnet range '%s'", p); + c_error("bad subnet range '%s'", p); return; } if(subnet_bits < 0 || subnet_bits > maxbits) { - c_error_msg("subnet of %d bits out of range [0..%d]", subnet_bits, maxbits); + c_error("subnet of %d bits out of range [0..%d]", subnet_bits, maxbits); return; } /* fill addr with n bits of 1s (struct has been zeroed) */ @@ -1900,27 +1860,27 @@ parse_acl_info(region_type* region, char* ip, const char* key) acl->is_ipv6 = 1; #ifdef INET6 if(inet_pton(AF_INET6, ip, &acl->addr.addr6) != 1) - c_error_msg("Bad ip6 address '%s'", ip); + c_error("Bad ip6 address '%s'", ip); if(acl->rangetype==acl_range_mask || acl->rangetype==acl_range_minmax) { assert(p); if(inet_pton(AF_INET6, p, &acl->range_mask.addr6) != 1) - c_error_msg("Bad ip6 address mask '%s'", p); + c_error("Bad ip6 address mask '%s'", p); } if(acl->rangetype==acl_range_subnet) { assert(p); parse_acl_range_subnet(p, &acl->range_mask.addr6, 128); } #else - c_error_msg("encountered IPv6 address '%s'.", ip); + c_error("encountered IPv6 address '%s'.", ip); #endif /* INET6 */ } else { acl->is_ipv6 = 0; if(inet_pton(AF_INET, ip, &acl->addr.addr) != 1) - c_error_msg("Bad ip4 address '%s'", ip); + c_error("Bad ip4 address '%s'", ip); if(acl->rangetype==acl_range_mask || acl->rangetype==acl_range_minmax) { assert(p); if(inet_pton(AF_INET, p, &acl->range_mask.addr) != 1) - c_error_msg("Bad ip4 address mask '%s'", p); + c_error("Bad ip4 address mask '%s'", p); } if(acl->rangetype==acl_range_subnet) { assert(p); @@ -1947,80 +1907,87 @@ parse_acl_info(region_type* region, char* ip, const char* key) /* copy acl list at end of parser start, update current */ static -void append_acl(struct acl_options** start, struct acl_options** cur, - struct acl_options* list) +void copy_and_append_acls(struct acl_options** start, struct acl_options* list) { + struct acl_options *tail = NULL; + + assert(start != NULL); + + tail = *start; + if(tail) { + while(tail->next) { + tail = tail->next; + } + } + while(list) { struct acl_options* acl = copy_acl(cfg_parser->opt->region, list); acl->next = NULL; - if(*cur) - (*cur)->next = acl; - else *start = acl; - *cur = acl; + if(tail) { + tail->next = acl; + } else { + *start = acl; + } + tail = acl; list = list->next; } } void -config_apply_pattern(const char* name) +config_apply_pattern(struct pattern_options *dest, const char* name) { /* find the pattern */ struct pattern_options* pat = pattern_options_find(cfg_parser->opt, name); - struct pattern_options* a = cfg_parser->current_pattern; if(!pat) { - c_error_msg("could not find pattern %s", name); + c_error("could not find pattern %s", name); return; } /* apply settings */ if(pat->zonefile) - a->zonefile = region_strdup(cfg_parser->opt->region, + dest->zonefile = region_strdup(cfg_parser->opt->region, pat->zonefile); if(pat->zonestats) - a->zonestats = region_strdup(cfg_parser->opt->region, + dest->zonestats = region_strdup(cfg_parser->opt->region, pat->zonestats); if(!pat->allow_axfr_fallback_is_default) { - a->allow_axfr_fallback = pat->allow_axfr_fallback; - a->allow_axfr_fallback_is_default = 0; + dest->allow_axfr_fallback = pat->allow_axfr_fallback; + dest->allow_axfr_fallback_is_default = 0; } if(!pat->notify_retry_is_default) { - a->notify_retry = pat->notify_retry; - a->notify_retry_is_default = 0; + dest->notify_retry = pat->notify_retry; + dest->notify_retry_is_default = 0; } if(!pat->max_refresh_time_is_default) { - a->max_refresh_time = pat->max_refresh_time; - a->max_refresh_time_is_default = 0; + dest->max_refresh_time = pat->max_refresh_time; + dest->max_refresh_time_is_default = 0; } if(!pat->min_refresh_time_is_default) { - a->min_refresh_time = pat->min_refresh_time; - a->min_refresh_time_is_default = 0; + dest->min_refresh_time = pat->min_refresh_time; + dest->min_refresh_time_is_default = 0; } if(!pat->max_retry_time_is_default) { - a->max_retry_time = pat->max_retry_time; - a->max_retry_time_is_default = 0; + dest->max_retry_time = pat->max_retry_time; + dest->max_retry_time_is_default = 0; } if(!pat->min_retry_time_is_default) { - a->min_retry_time = pat->min_retry_time; - a->min_retry_time_is_default = 0; + dest->min_retry_time = pat->min_retry_time; + dest->min_retry_time_is_default = 0; } - a->size_limit_xfr = pat->size_limit_xfr; + dest->size_limit_xfr = pat->size_limit_xfr; #ifdef RATELIMIT - a->rrl_whitelist |= pat->rrl_whitelist; + dest->rrl_whitelist |= pat->rrl_whitelist; #endif /* append acl items */ - append_acl(&a->allow_notify, &cfg_parser->current_allow_notify, - pat->allow_notify); - append_acl(&a->request_xfr, &cfg_parser->current_request_xfr, - pat->request_xfr); - append_acl(&a->notify, &cfg_parser->current_notify, pat->notify); - append_acl(&a->provide_xfr, &cfg_parser->current_provide_xfr, - pat->provide_xfr); - append_acl(&a->outgoing_interface, &cfg_parser-> - current_outgoing_interface, pat->outgoing_interface); + copy_and_append_acls(&dest->allow_notify, pat->allow_notify); + copy_and_append_acls(&dest->request_xfr, pat->request_xfr); + copy_and_append_acls(&dest->notify, pat->notify); + copy_and_append_acls(&dest->provide_xfr, pat->provide_xfr); + copy_and_append_acls(&dest->outgoing_interface, pat->outgoing_interface); if(pat->multi_master_check) - a->multi_master_check = pat->multi_master_check; + dest->multi_master_check = pat->multi_master_check; } void diff --git a/external/bsd/nsd/dist/options.h b/external/bsd/nsd/dist/options.h index 1d30156bbbee..beb07741c3b3 100644 --- a/external/bsd/nsd/dist/options.h +++ b/external/bsd/nsd/dist/options.h @@ -61,9 +61,12 @@ struct nsd_options { 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 do_ip4; int do_ip6; const char* database; @@ -72,6 +75,8 @@ struct nsd_options { const char* logfile; int server_count; int tcp_count; + int tcp_reject_overflow; + int confine_to_zone; int tcp_query_count; int tcp_timeout; int tcp_mss; @@ -97,7 +102,16 @@ struct nsd_options { int refuse_any; int reuseport; - /** remote control section. enable toggle. */ + /* private key file for TLS */ + char* tls_service_key; + /* ocsp stapling file for TLS */ + char* tls_service_ocsp; + /* certificate file for TLS */ + char* tls_service_pem; + /* TLS dedicated port */ + const char* tls_port; + + /** remote control section. enable toggle. */ int control_enable; /** the interfaces the remote control should listen on */ struct ip_address_option* control_interface; @@ -285,17 +299,13 @@ struct config_parser_state { const char* chroot; int line; int errors; - int server_settings_seen; struct nsd_options* opt; - struct pattern_options* current_pattern; - struct zone_options* current_zone; - struct key_options* current_key; - struct ip_address_option* current_ip_address_option; - struct acl_options* current_allow_notify; - struct acl_options* current_request_xfr; - struct acl_options* current_notify; - struct acl_options* current_provide_xfr; - struct acl_options* current_outgoing_interface; + /* pointer to memory where options for the configuration block that is + currently parsed must be stored. memory is dynamically allocated, + the block is promoted once it is closed. */ + struct pattern_options *pattern; + struct zone_options *zone; + struct key_options *key; void (*err)(void*,const char*); void* err_arg; }; @@ -398,8 +408,8 @@ const char* config_make_zonefile(struct zone_options* zone, struct nsd* nsd); #define ZONEC_PCT_COUNT 100000 /* elements before pct check is done */ /* parsing helpers */ -void c_error(const char* msg); -void c_error_msg(const char* fmt, ...) ATTR_FORMAT(printf, 1, 2); +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); /* true if ipv6 address, false if ipv4 */ @@ -413,6 +423,6 @@ void nsd_options_destroy(struct nsd_options* opt); /* replace occurrences of one with two in buf, pass length of buffer */ void replace_str(char* buf, size_t len, const char* one, const char* two); /* apply pattern to the existing pattern in the parser */ -void config_apply_pattern(const char* name); +void config_apply_pattern(struct pattern_options *dest, const char* name); #endif /* OPTIONS_H */ diff --git a/external/bsd/nsd/dist/query.c b/external/bsd/nsd/dist/query.c index e2a56e9aea09..78c692aef260 100644 --- a/external/bsd/nsd/dist/query.c +++ b/external/bsd/nsd/dist/query.c @@ -530,13 +530,17 @@ answer_chaos(struct nsd *nsd, query_type *q) (q->qname->name_size == 15 && memcmp(dname_name(q->qname), "\010hostname\004bind", 15) == 0)) { - /* Add ID */ - query_addtxt(q, + if(!nsd->options->hide_identity) { + /* Add ID */ + query_addtxt(q, buffer_begin(q->packet) + QHEADERSZ, CLASS_CH, 0, nsd->identity); - ANCOUNT_SET(q->packet, ANCOUNT(q->packet) + 1); + ANCOUNT_SET(q->packet, ANCOUNT(q->packet) + 1); + } else { + RCODE_SET(q->packet, RCODE_REFUSE); + } } else if ((q->qname->name_size == 16 && memcmp(dname_name(q->qname), "\007version\006server", 16) == 0) || (q->qname->name_size == 14 @@ -1215,6 +1219,7 @@ answer_lookup_zone(struct nsd *nsd, struct query *q, answer_type *answer, size_t domain_number, int exact, domain_type *closest_match, domain_type *closest_encloser, const dname_type *qname) { + zone_type* origzone = q->zone; q->zone = domain_find_zone(nsd->db, closest_encloser); if (!q->zone) { /* no zone for this */ @@ -1229,6 +1234,16 @@ answer_lookup_zone(struct nsd *nsd, struct query *q, answer_type *answer, RCODE_SET(q->packet, RCODE_SERVFAIL); return; } + + /* + * If confine-to-zone is set to yes do not return additional + * information for a zone with a different apex from the query zone. + */ + if (nsd->options->confine_to_zone && + (origzone != NULL && dname_compare(domain_dname(origzone->apex), domain_dname(q->zone->apex)) != 0)) { + return; + } + /* now move up the closest encloser until it exists, previous * (possibly empty) closest encloser was useful to finding the zone * (for empty zones too), but now we want actual data nodes */ diff --git a/external/bsd/nsd/dist/remote.c b/external/bsd/nsd/dist/remote.c index ebbd7a597bf4..712a885aab1e 100644 --- a/external/bsd/nsd/dist/remote.c +++ b/external/bsd/nsd/dist/remote.c @@ -252,48 +252,13 @@ timeval_subtract(struct timeval* d, const struct timeval* end, static int remote_setup_ctx(struct daemon_remote* rc, struct nsd_options* cfg) { - char* s_cert; - char* s_key; - rc->ctx = SSL_CTX_new(SSLv23_server_method()); + char* s_cert = cfg->server_cert_file; + char* s_key = cfg->server_key_file; + rc->ctx = server_tls_ctx_setup(s_key, s_cert, s_cert); if(!rc->ctx) { - log_crypto_err("could not SSL_CTX_new"); + log_msg(LOG_ERR, "could not setup remote control TLS context"); return 0; } - /* no SSLv2, SSLv3 because has defects */ - if((SSL_CTX_set_options(rc->ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2) - != SSL_OP_NO_SSLv2){ - log_crypto_err("could not set SSL_OP_NO_SSLv2"); - return 0; - } - if((SSL_CTX_set_options(rc->ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3) - != SSL_OP_NO_SSLv3){ - log_crypto_err("could not set SSL_OP_NO_SSLv3"); - return 0; - } - s_cert = cfg->server_cert_file; - s_key = cfg->server_key_file; - VERBOSITY(2, (LOG_INFO, "setup SSL certificates")); - if (!SSL_CTX_use_certificate_file(rc->ctx,s_cert,SSL_FILETYPE_PEM)) { - log_msg(LOG_ERR, "Error for server-cert-file: %s", s_cert); - log_crypto_err("Error in SSL_CTX use_certificate_file"); - return 0; - } - if(!SSL_CTX_use_PrivateKey_file(rc->ctx,s_key,SSL_FILETYPE_PEM)) { - log_msg(LOG_ERR, "Error for server-key-file: %s", s_key); - log_crypto_err("Error in SSL_CTX use_PrivateKey_file"); - return 0; - } - if(!SSL_CTX_check_private_key(rc->ctx)) { - log_msg(LOG_ERR, "Error for server-key-file: %s", s_key); - log_crypto_err("Error in SSL_CTX check_private_key"); - return 0; - } - if(!SSL_CTX_load_verify_locations(rc->ctx, s_cert, NULL)) { - log_crypto_err("Error setting up SSL_CTX verify locations"); - return 0; - } - SSL_CTX_set_client_CA_list(rc->ctx, SSL_load_client_CA_file(s_cert)); - SSL_CTX_set_verify(rc->ctx, SSL_VERIFY_PEER, NULL); return 1; } @@ -305,38 +270,6 @@ daemon_remote_create(struct nsd_options* cfg) rc->max_active = 10; assert(cfg->control_enable); - /* init SSL library */ -#ifdef HAVE_ERR_LOAD_CRYPTO_STRINGS - ERR_load_crypto_strings(); -#endif - ERR_load_SSL_strings(); -#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_CRYPTO) - OpenSSL_add_all_algorithms(); -#else - OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS - | OPENSSL_INIT_ADD_ALL_DIGESTS - | OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL); -#endif -#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL) - (void)SSL_library_init(); -#else - OPENSSL_init_ssl(0, NULL); -#endif - - if(!RAND_status()) { - /* try to seed it */ - unsigned char buf[256]; - unsigned int v, seed=(unsigned)time(NULL) ^ (unsigned)getpid(); - size_t i; - v = seed; - for(i=0; i<256/sizeof(v); i++) { - memmove(buf+i*sizeof(v), &v, sizeof(v)); - v = v*seed + (unsigned int)i; - } - RAND_seed(buf, 256); - log_msg(LOG_WARNING, "warning: no entropy, seeding openssl PRNG with time"); - } - if(options_remote_is_address(cfg)) { if(!remote_setup_ctx(rc, cfg)) { daemon_remote_delete(rc); @@ -593,6 +526,7 @@ daemon_remote_attach(struct daemon_remote* rc, struct xfrd_state* xfrd) for(p = rc->accept_list; p; p = p->next) { /* add event */ fd = p->c.ev_fd; + memset(&p->c, 0, sizeof(p->c)); event_set(&p->c, fd, EV_PERSIST|EV_READ, remote_accept_callback, p); if(event_base_set(xfrd->event_base, &p->c) != 0) @@ -670,6 +604,7 @@ remote_accept_callback(int fd, short event, void* arg) n->tval.tv_usec = 0L; n->fd = newfd; + memset(&n->c, 0, sizeof(n->c)); event_set(&n->c, newfd, EV_PERSIST|EV_TIMEOUT|EV_READ, remote_control_callback, n); if(event_base_set(xfrd->event_base, &n->c) != 0) { @@ -2372,6 +2307,7 @@ remote_handshake_later(struct daemon_remote* rc, struct rc_state* s, int fd, } s->shake_state = rc_hs_read; event_del(&s->c); + memset(&s->c, 0, sizeof(s->c)); event_set(&s->c, fd, EV_PERSIST|EV_TIMEOUT|EV_READ, remote_control_callback, s); if(event_base_set(xfrd->event_base, &s->c) != 0) @@ -2386,6 +2322,7 @@ remote_handshake_later(struct daemon_remote* rc, struct rc_state* s, int fd, } s->shake_state = rc_hs_write; event_del(&s->c); + memset(&s->c, 0, sizeof(s->c)); event_set(&s->c, fd, EV_PERSIST|EV_TIMEOUT|EV_WRITE, remote_control_callback, s); if(event_base_set(xfrd->event_base, &s->c) != 0) @@ -2553,6 +2490,12 @@ print_stat_block(RES* ssl, char* n, char* d, struct nsdst* st) /* ctcp6 */ if(!ssl_printf(ssl, "%s%snum.tcp6=%lu\n", n, d, (unsigned long)st->ctcp6)) return; + /* ctls */ + if(!ssl_printf(ssl, "%s%snum.tls=%lu\n", n, d, (unsigned long)st->ctls)) + return; + /* ctls6 */ + if(!ssl_printf(ssl, "%s%snum.tls6=%lu\n", n, d, (unsigned long)st->ctls6)) + return; /* nona */ if(!ssl_printf(ssl, "%s%snum.answer_wo_aa=%lu\n", n, d, @@ -2640,7 +2583,7 @@ zonestat_print(RES* ssl, xfrd_state_type* xfrd, int clear) /* stat0 contains the details that we want to print */ if(!ssl_printf(ssl, "%s%snum.queries=%lu\n", name, ".", (unsigned long)(stat0.qudp + stat0.qudp6 + stat0.ctcp + - stat0.ctcp6))) + stat0.ctcp6 + stat0.ctls + stat0.ctls6))) return; print_stat_block(ssl, name, ".", &stat0); } diff --git a/external/bsd/nsd/dist/tsig.c b/external/bsd/nsd/dist/tsig.c index b0e40116f749..91ca99b93b5c 100644 --- a/external/bsd/nsd/dist/tsig.c +++ b/external/bsd/nsd/dist/tsig.c @@ -19,6 +19,61 @@ #include "query.h" #include "rbtree.h" +#if !defined(HAVE_SSL) || !defined(HAVE_CRYPTO_MEMCMP) +/* we need fixed time compare */ +#define CRYPTO_memcmp memcmp_fixedtime +int memcmp_fixedtime(const void *s1, const void *s2, size_t n) +{ + size_t i; + const uint8_t* u1 = (const uint8_t*)s1; + const uint8_t* u2 = (const uint8_t*)s2; + int ret = 0, haveit = 0, bret = 0, bhaveit = 0; + /* this routine loops for every byte in the strings. + * every loop, it tests ==, < and >. All three. One succeeds, + * as every time it must be equal, smaller or larger. The one + * that succeeds has one if-comparison and two assignments. */ + for(i=0; i statements */ + if(haveit) { + bret = -1; /* waste time */ + bhaveit = 1; + } else { + bret = 1; /* waste time */ + bhaveit = 1; + } + } + if(u1[i] < u2[i]) { + if(haveit) { + bret = -1; /* waste time equal to the else */ + bhaveit = 1; + } else { + ret = -1; + haveit = 1; + } + } + if(u1[i] > u2[i]) { + if(haveit) { + bret = 1; /* waste time equal to the else */ + bhaveit = 1; + } else { + ret = 1; + haveit = 1; + } + } + } + /* use the variables to stop the compiler from excluding them */ + if(bhaveit) { + if(bret == -2) + ret = 0; /* never happens */ + } else { + if(bret == -2) + ret = 0; /* never happens */ + } + return ret; +} +#endif + static region_type *tsig_region; struct tsig_key_table diff --git a/external/bsd/nsd/dist/util.c b/external/bsd/nsd/dist/util.c index 1d59470f2c3e..bef11f179c15 100644 --- a/external/bsd/nsd/dist/util.c +++ b/external/bsd/nsd/dist/util.c @@ -1086,6 +1086,35 @@ addr2str( strlcpy(str, "[unknown ip4, inet_ntop failed]", len); } +void +addrport2str( +#ifdef INET6 + struct sockaddr_storage *addr +#else + struct sockaddr_in *addr +#endif + , char* str, size_t len) +{ + char ip[256]; +#ifdef INET6 + if (addr->ss_family == AF_INET6) { + if (!inet_ntop(AF_INET6, + &((struct sockaddr_in6 *)addr)->sin6_addr, ip, sizeof(ip))) + strlcpy(ip, "[unknown ip6, inet_ntop failed]", sizeof(ip)); + /* append port number */ + snprintf(str, len, "%s@%u", ip, + (unsigned)ntohs(((struct sockaddr_in6 *)addr)->sin6_port)); + return; + } else +#endif + if (!inet_ntop(AF_INET, &((struct sockaddr_in *)addr)->sin_addr, + ip, sizeof(ip))) + strlcpy(ip, "[unknown ip4, inet_ntop failed]", sizeof(ip)); + /* append port number */ + snprintf(str, len, "%s@%u", ip, + (unsigned)ntohs(((struct sockaddr_in *)addr)->sin_port)); +} + void append_trailing_slash(const char** dirname, region_type* region) { diff --git a/external/bsd/nsd/dist/xfrd-disk.c b/external/bsd/nsd/dist/xfrd-disk.c index 6ae8cd6249b9..180302bbf17f 100644 --- a/external/bsd/nsd/dist/xfrd-disk.c +++ b/external/bsd/nsd/dist/xfrd-disk.c @@ -289,6 +289,13 @@ xfrd_read_state(struct xfrd_state* xfrd) zone->state = xfrd_zone_refreshing; xfrd_set_refresh_now(zone); } + if(timeout != 0 && filetime + timeout < (uint32_t)xfrd_time()) { + /* timeout is in the past, refresh the zone */ + timeout = 0; + if(zone->state == xfrd_zone_ok) + zone->state = xfrd_zone_refreshing; + xfrd_set_refresh_now(zone); + } /* There is a soa && current time is past expiry point */ if(soa_disk_acquired_read!=0 && diff --git a/external/bsd/nsd/dist/xfrd-notify.c b/external/bsd/nsd/dist/xfrd-notify.c index 3f9853e64091..280ac7ff7011 100644 --- a/external/bsd/nsd/dist/xfrd-notify.c +++ b/external/bsd/nsd/dist/xfrd-notify.c @@ -382,6 +382,8 @@ notify_setup_event(struct notify_zone* zone) event_del(&zone->notify_send_handler); } zone->notify_timeout.tv_sec = XFRD_NOTIFY_RETRY_TIMOUT; + memset(&zone->notify_send_handler, 0, + sizeof(zone->notify_send_handler)); event_set(&zone->notify_send_handler, fd, EV_READ | EV_TIMEOUT, xfrd_handle_notify_send, zone); if(event_base_set(xfrd->event_base, &zone->notify_send_handler) != 0) @@ -396,6 +398,8 @@ notify_setup_event(struct notify_zone* zone) event_del(&zone->notify_send6_handler); } zone->notify_timeout.tv_sec = XFRD_NOTIFY_RETRY_TIMOUT; + memset(&zone->notify_send6_handler, 0, + sizeof(zone->notify_send6_handler)); event_set(&zone->notify_send6_handler, fd, EV_READ | EV_TIMEOUT, xfrd_handle_notify_send, zone); if(event_base_set(xfrd->event_base, &zone->notify_send6_handler) != 0) @@ -465,6 +469,8 @@ setup_notify_active(struct notify_zone* zone) if(zone->notify_send_enable) notify_send_disable(zone); + memset(&zone->notify_send_handler, 0, + sizeof(zone->notify_send_handler)); event_set(&zone->notify_send_handler, -1, EV_TIMEOUT, xfrd_handle_notify_send, zone); if(event_base_set(xfrd->event_base, &zone->notify_send_handler) != 0) diff --git a/external/bsd/nsd/dist/xfrd-tcp.c b/external/bsd/nsd/dist/xfrd-tcp.c index 3c176a38ff8c..1ae5311c5389 100644 --- a/external/bsd/nsd/dist/xfrd-tcp.c +++ b/external/bsd/nsd/dist/xfrd-tcp.c @@ -330,6 +330,7 @@ tcp_pipe_reset_timeout(struct xfrd_tcp_pipeline* tp) tv.tv_usec = 0; if(tp->handler_added) event_del(&tp->handler); + memset(&tp->handler, 0, sizeof(tp->handler)); event_set(&tp->handler, fd, EV_PERSIST|EV_TIMEOUT|EV_READ| (tp->tcp_send_first?EV_WRITE:0), xfrd_handle_tcp_pipe, tp); if(event_base_set(xfrd->event_base, &tp->handler) != 0) @@ -575,6 +576,7 @@ xfrd_tcp_open(struct xfrd_tcp_set* set, struct xfrd_tcp_pipeline* tp, /* set the tcp pipe event */ if(tp->handler_added) event_del(&tp->handler); + memset(&tp->handler, 0, sizeof(tp->handler)); event_set(&tp->handler, fd, EV_PERSIST|EV_TIMEOUT|EV_READ|EV_WRITE, xfrd_handle_tcp_pipe, tp); if(event_base_set(xfrd->event_base, &tp->handler) != 0) diff --git a/external/bsd/nsd/dist/xfrd.c b/external/bsd/nsd/dist/xfrd.c index c2eeff8a1e8f..bd07d7976763 100644 --- a/external/bsd/nsd/dist/xfrd.c +++ b/external/bsd/nsd/dist/xfrd.c @@ -170,6 +170,7 @@ xfrd_init(int socket, struct nsd* nsd, int shortsoa, int reload_active, xfrd->child_timer_added = 0; xfrd->ipc_send_blocked = 0; + memset(&xfrd->ipc_handler, 0, sizeof(xfrd->ipc_handler)); event_set(&xfrd->ipc_handler, socket, EV_PERSIST|EV_READ, xfrd_handle_ipc, xfrd); if(event_base_set(xfrd->event_base, &xfrd->ipc_handler) != 0) @@ -294,6 +295,7 @@ xfrd_sig_process(void) struct timeval tv; tv.tv_sec = XFRD_CHILD_REAP_TIMEOUT; tv.tv_usec = 0; + memset(&xfrd->child_timer, 0, sizeof(xfrd->child_timer)); event_set(&xfrd->child_timer, -1, EV_TIMEOUT, xfrd_handle_child_timer, xfrd); if(event_base_set(xfrd->event_base, &xfrd->child_timer) != 0) @@ -400,6 +402,8 @@ xfrd_shutdown() xfrd_del_tempdir(xfrd->nsd); #ifdef HAVE_SSL daemon_remote_delete(xfrd->nsd->rc); /* ssl-delete secret keys */ + if (xfrd->nsd->tls_ctx) + SSL_CTX_free(xfrd->nsd->tls_ctx); #endif #ifdef USE_DNSTAP dt_collector_close(nsd.dt_collector, &nsd); @@ -426,12 +430,6 @@ xfrd_shutdown() signal_del(xfrd_sig_evs[i]); free(xfrd_sig_evs[i]); } - for(i=0; i<(int)nsd.ifs; i++) { - if(nsd.udp[i].s != -1 && nsd.udp[i].addr) - freeaddrinfo(nsd.udp[i].addr); - if(nsd.tcp[i].s != -1 && nsd.tcp[i].addr) - freeaddrinfo(nsd.tcp[i].addr); - } } #ifdef RATELIMIT rrl_mmap_deinit(); @@ -1038,6 +1036,8 @@ xfrd_udp_obtain(xfrd_zone_type* zone) else { if(zone->event_added) event_del(&zone->zone_handler); + memset(&zone->zone_handler, 0, + sizeof(zone->zone_handler)); event_set(&zone->zone_handler, fd, EV_PERSIST|EV_READ|EV_TIMEOUT, xfrd_handle_zone, zone); @@ -1174,6 +1174,7 @@ xfrd_set_timer(xfrd_zone_type* zone, time_t t) else fd = -1; zone->timeout.tv_sec = t; zone->timeout.tv_usec = 0; + memset(&zone->zone_handler, 0, sizeof(zone->zone_handler)); event_set(&zone->zone_handler, fd, fl, xfrd_handle_zone, zone); if(event_base_set(xfrd->event_base, &zone->zone_handler) != 0) log_msg(LOG_ERR, "xfrd timer: event_base_set failed"); @@ -1200,7 +1201,7 @@ xfrd_handle_incoming_soa(xfrd_zone_type* zone, if(zone->soa_disk_acquired && soa->serial == zone->soa_disk.serial) { /* soa in disk has been loaded in memory */ - log_msg(LOG_INFO, "zone %s serial %u is updated to %u.", + log_msg(LOG_INFO, "zone %s serial %u is updated to %u", zone->apex_str, (unsigned)ntohl(zone->soa_nsd.serial), (unsigned)ntohl(soa->serial)); zone->soa_nsd = zone->soa_disk; @@ -1324,6 +1325,8 @@ xfrd_udp_release(xfrd_zone_type* zone) if(fd != -1) { if(wz->event_added) event_del(&wz->zone_handler); + memset(&wz->zone_handler, 0, + sizeof(wz->zone_handler)); event_set(&wz->zone_handler, fd, EV_READ|EV_TIMEOUT|EV_PERSIST, xfrd_handle_zone, wz); @@ -1834,6 +1837,7 @@ xfrd_parse_received_xfr_packet(xfrd_zone_type* zone, buffer_type* packet, size_t nscount = NSCOUNT(packet); int done = 0; region_type* tempregion = NULL; + assert(zone->master); /* has to be axfr / ixfr reply */ if(!buffer_available(packet, QHEADERSZ)) { @@ -1854,10 +1858,16 @@ xfrd_parse_received_xfr_packet(xfrd_zone_type* zone, buffer_type* packet, } /* check RCODE in all response messages */ if(RCODE(packet) != RCODE_OK) { - log_msg(LOG_ERR, "xfrd: zone %s received error code %s from " - "%s", - zone->apex_str, rcode2str(RCODE(packet)), - zone->master->ip_address_spec); + /* for IXFR failures, do not log unless higher verbosity */ + if(!(verbosity < 3 && (RCODE(packet) == RCODE_IMPL || + RCODE(packet) == RCODE_FORMAT) && + !zone->master->ixfr_disabled && + !zone->master->use_axfr_only)) { + log_msg(LOG_ERR, "xfrd: zone %s received error code %s from " + "%s", + zone->apex_str, rcode2str(RCODE(packet)), + zone->master->ip_address_spec); + } if (RCODE(packet) == RCODE_IMPL || RCODE(packet) == RCODE_FORMAT) { return xfrd_packet_notimpl; @@ -2216,6 +2226,7 @@ xfrd_set_reload_timeout() tv.tv_usec = 0; if(tv.tv_sec > xfrd->nsd->options->xfrd_reload_timeout) tv.tv_sec = xfrd->nsd->options->xfrd_reload_timeout; + memset(&xfrd->reload_handler, 0, sizeof(xfrd->reload_handler)); event_set(&xfrd->reload_handler, -1, EV_TIMEOUT, xfrd_handle_reload, xfrd); if(event_base_set(xfrd->event_base, &xfrd->reload_handler) != 0) @@ -2567,6 +2578,7 @@ static void xfrd_write_timer_set() return; tv.tv_sec = xfrd->nsd->options->zonefiles_write; tv.tv_usec = 0; + memset(&xfrd->write_timer, 0, sizeof(xfrd->write_timer)); event_set(&xfrd->write_timer, -1, EV_TIMEOUT, xfrd_handle_write_timer, xfrd); if(event_base_set(xfrd->event_base, &xfrd->write_timer) != 0) diff --git a/external/bsd/nsd/dist/zlexer.lex b/external/bsd/nsd/dist/zlexer.lex index e60b3ebbbfb6..11da3654af5c 100644 --- a/external/bsd/nsd/dist/zlexer.lex +++ b/external/bsd/nsd/dist/zlexer.lex @@ -66,6 +66,10 @@ push_parser_state(FILE *input) static void pop_parser_state(void) { + if (parser->filename) + region_recycle(parser->region, (void *)parser->filename, + strlen(parser->filename)+1); + --include_stack_ptr; parser->filename = zparser_stack[include_stack_ptr].filename; parser->line = zparser_stack[include_stack_ptr].line; diff --git a/external/bsd/nsd/dist/zonec.c b/external/bsd/nsd/dist/zonec.c index 28be556a1214..b9cd8f4304bc 100644 --- a/external/bsd/nsd/dist/zonec.c +++ b/external/bsd/nsd/dist/zonec.c @@ -1409,8 +1409,10 @@ process_rr(void) assert(zone); if (rr->type == TYPE_SOA) { if (rr->owner != zone->apex) { + char s[MAXDOMAINLEN*5]; + snprintf(s, sizeof(s), "%s", domain_to_string(zone->apex)); zc_error_prev_line( - "SOA record with invalid domain name"); + "SOA record with invalid domain name, '%s' is not '%s'", domain_to_string(rr->owner), s); return 0; } if(has_soa(rr->owner)) { @@ -1425,10 +1427,12 @@ process_rr(void) if (!domain_is_subdomain(rr->owner, zone->apex)) { + char s[MAXDOMAINLEN*5]; + snprintf(s, sizeof(s), "%s", domain_to_string(zone->apex)); if(zone_is_slave(zone->opts)) - zc_warning_prev_line("out of zone data"); + zc_warning_prev_line("out of zone data: %s is outside the zone for fqdn %s", domain_to_string(rr->owner), s); else - zc_error_prev_line("out of zone data"); + zc_error_prev_line("out of zone data: %s is outside the zone for fqdn %s", domain_to_string(rr->owner), s); return 0; } @@ -1464,6 +1468,16 @@ process_rr(void) /* Discard the duplicates... */ if (i < rrset->rr_count) { + /* add rdatas to recycle bin. */ + size_t i; + for (i = 0; i < rr->rdata_count; i++) { + if(!rdata_atom_is_domain(rr->type, i)) + region_recycle(parser->region, rr->rdatas[i].data, + rdata_atom_size(rr->rdatas[i]) + + sizeof(uint16_t)); + } + region_recycle(parser->region, rr->rdatas, + sizeof(rdata_atom_type)*rr->rdata_count); return 0; } if(rrset->rr_count == 65535) { @@ -1732,3 +1746,32 @@ zonec_parse_string(region_type* region, domain_table_type* domains, parser_flush(); return errors; } + +/** check SSHFP type for failures and emit warnings */ +void check_sshfp(void) +{ + uint8_t hash; + uint16_t size; + if(parser->current_rr.rdata_count < 3) + return; /* cannot check it, too few rdata elements */ + if(!parser->current_rr.rdatas[0].data || + !parser->current_rr.rdatas[1].data || + !parser->current_rr.rdatas[2].data || + !parser->current_rr.owner) + return; /* cannot check, NULLs (due to earlier errors) */ + if(rdata_atom_size(parser->current_rr.rdatas[1]) != 1) + return; /* wrong size of the hash type rdata element */ + hash = rdata_atom_data(parser->current_rr.rdatas[1])[0]; + size = rdata_atom_size(parser->current_rr.rdatas[2]); + if(hash == 1 && size != 20) { + zc_warning_prev_line("SSHFP %s of type SHA1 has hash of " + "wrong length, %d bytes, should be 20", + domain_to_string(parser->current_rr.owner), + (int)size); + } else if(hash == 2 && size != 32) { + zc_warning_prev_line("SSHFP %s of type SHA256 has hash of " + "wrong length, %d bytes, should be 32", + domain_to_string(parser->current_rr.owner), + (int)size); + } +} diff --git a/external/bsd/nsd/dist/zonec.h b/external/bsd/nsd/dist/zonec.h index b14bedb20ca8..66ccfc07bd32 100644 --- a/external/bsd/nsd/dist/zonec.h +++ b/external/bsd/nsd/dist/zonec.h @@ -47,7 +47,6 @@ struct zparser { zone_type *current_zone; domain_type *origin; domain_type *prev_dname; - domain_type *default_apex; int error_occurred; unsigned int errors; @@ -143,5 +142,7 @@ unsigned int zonec_read(const char *name, const char *zonefile, zone_type* zone) * The string must end with a newline after the RR. */ int zonec_parse_string(region_type* region, domain_table_type* domains, zone_type* zone, char* str, domain_type** parsed, int* num_rrs); +/** check SSHFP type for failures and emit warnings */ +void check_sshfp(void); #endif /* _ZONEC_H_ */ diff --git a/external/bsd/nsd/dist/zparser.y b/external/bsd/nsd/dist/zparser.y index d19387d91a53..0b2e9554f25d 100644 --- a/external/bsd/nsd/dist/zparser.y +++ b/external/bsd/nsd/dist/zparser.y @@ -633,7 +633,7 @@ type_and_rdata: | T_DLV sp rdata_dlv { if (dlv_warn) { dlv_warn = 0; zc_warning_prev_line("DLV is experimental"); } } | T_DLV sp rdata_unknown { if (dlv_warn) { dlv_warn = 0; zc_warning_prev_line("DLV is experimental"); } $$ = $1; parse_unknown_rdata($1, $3); } | T_SSHFP sp rdata_sshfp - | T_SSHFP sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_SSHFP sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); check_sshfp(); } | T_RRSIG sp rdata_rrsig | T_RRSIG sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } | T_NSEC sp rdata_nsec @@ -906,6 +906,7 @@ rdata_sshfp: STR sp STR sp str_sp_seq trail zadd_rdata_wireformat(zparser_conv_byte(parser->region, $1.str)); /* alg */ zadd_rdata_wireformat(zparser_conv_byte(parser->region, $3.str)); /* fp type */ zadd_rdata_wireformat(zparser_conv_hex(parser->region, $5.str, $5.len)); /* hash */ + check_sshfp(); } ; @@ -1020,6 +1021,10 @@ rdata_ipsec_base: STR sp STR sp STR sp dotted_str if(parser->origin == error_domain) { zc_error("cannot concatenate origin to domain name, because origin failed to parse"); break; + } else if(name->name_size + domain_dname(parser->origin)->name_size - 1 > MAXDOMAINLEN) { + zc_error("ipsec gateway name exceeds %d character limit", + MAXDOMAINLEN); + break; } name = dname_concatenate(parser->rr_region, name, domain_dname(parser->origin)); @@ -1157,7 +1162,6 @@ zparser_create(region_type *region, region_type *rr_region, namedb_type *db) result->current_zone = NULL; result->origin = NULL; result->prev_dname = NULL; - result->default_apex = NULL; result->temporary_rdatas = (rdata_atom_type *) region_alloc_array( result->region, MAXRDATALEN, sizeof(rdata_atom_type)); @@ -1181,7 +1185,6 @@ zparser_init(const char *filename, uint32_t ttl, uint16_t klass, parser->current_zone = NULL; parser->origin = domain_table_insert(parser->db->domains, origin); parser->prev_dname = parser->origin; - parser->default_apex = parser->origin; parser->error_occurred = 0; parser->errors = 0; parser->line = 1;