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.
This commit is contained in:
christos 2019-12-15 16:00:52 +00:00
parent 01049ae6d5
commit febe9f0745
46 changed files with 2291 additions and 1498 deletions

View File

@ -0,0 +1,7 @@
steps:
- label: Build
commands:
- autoconf && autoheader
- ./configure --enable-checking --disable-flto
- make
- make cutest && ./cutest

66
external/bsd/nsd/dist/.travis.yml vendored Normal file
View File

@ -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 ]

View File

@ -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

42
external/bsd/nsd/dist/README.md vendored Normal file
View File

@ -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. Dont 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).

View File

@ -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 <endian.h> 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 <openssl/ocsp.h> header file. */
#undef HAVE_OPENSSL_OCSP_H
/* Define to 1 if you have the <openssl/rand.h> 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 <stdarg.h> 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

View File

@ -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 */

File diff suppressed because it is too large Load Diff

View File

@ -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 <nsd-bugs@nlnetlabs.nl>.
#
@ -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 <sys/socket.h>
"
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 <stdlib.h>
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
{ $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 <openssl/err.h>
#endif
#ifdef HAVE_OPENSSL_RAND_H
#include <openssl/rand.h>
#endif
#ifdef HAVE_OPENSSL_CONF_H
#include <openssl/conf.h>
#endif
#ifdef HAVE_OPENSSL_ENGINE_H
#include <openssl/engine.h>
#endif
#include <openssl/ssl.h>
#include <openssl/evp.h>
"
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 <openssl/err.h>
#endif
#ifdef HAVE_OPENSSL_RAND_H
#include <openssl/rand.h>
#endif
#ifdef HAVE_OPENSSL_CONF_H
#include <openssl/conf.h>
#endif
#ifdef HAVE_OPENSSL_ENGINE_H
#include <openssl/engine.h>
#endif
#include <openssl/ssl.h>
#include <openssl/evp.h>
"
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 <netinet/tcp.h>
"
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\\"

View File

@ -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

View File

@ -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 /* <mattthijs> 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;

View File

@ -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 },

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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}

View File

@ -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; i<sizeof(total->rcode)/sizeof(stc_type); i++)
total->rcode[i] += s->rcode[i];
for(i=0; i<sizeof(total->opcode)/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; i<sizeof(total->rcode)/sizeof(stc_type); i++)
total->rcode[i] -= s->rcode[i];
for(i=0; i<sizeof(total->opcode)/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");

View File

@ -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++;
}

View File

@ -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

View File

@ -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"

View File

@ -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();
};

View File

@ -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"

View File

@ -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);

View File

@ -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

View File

@ -42,8 +42,8 @@
*/
#include "config.h"
#include <stdio.h>
#ifdef HAVE_SSL
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
@ -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);

View File

@ -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 ]

View File

@ -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 /* <mattthijs> 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,6 +949,7 @@ main(int argc, char *argv[])
log_msg(LOG_NOTICE, "%s starting (%s)", argv0, PACKAGE_STRING);
/* Do we have a running nsd? */
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",
@ -910,6 +966,7 @@ main(int argc, char *argv[])
(unsigned) oldpid);
}
}
}
/* Setup the signal handling... */
action.sa_handler = sig_handler;
@ -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;

View File

@ -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 <ip4 or ip6>[@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 <number>
Set the send buffer size for query-servicing sockets. Set to 0 to use the default settings.
.TP
.B receive\-buffer\-size:\fR <number>
Set the receive buffer size for query-servicing sockets. Set to 0 to use the default settings.
.TP
.B debug\-mode:\fR <yes or no>
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 <string>
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 <yes or no>
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 <number>
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 <number>
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 <yes or no>
Prevent NSD from replying with the identity string on CHAOS class
queries. Default is no.
.TP
.B log\-time\-ascii:\fR <yes or no>
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 <yes or no>
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 <yes or no>
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 <filename>
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 <filename>
The public key certificate pem file for the tls service. Default is "", turned off.
.TP
.B tls\-service\-ocsp:\fR <filename>
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 <number>
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:

View File

@ -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
@ -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.

View File

@ -11,6 +11,9 @@
#define _NSD_H_
#include <signal.h>
#ifdef HAVE_OPENSSL_SSL_H
#include <openssl/ssl.h>
#endif
#include "dns.h"
#include "edns.h"
@ -107,11 +110,22 @@ 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
@ -211,7 +225,6 @@ struct nsd
/* 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_ */

View File

@ -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,18 +174,10 @@ 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) {
@ -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,33 +712,22 @@ 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;
}
@ -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

View File

@ -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,6 +102,15 @@ struct nsd_options {
int refuse_any;
int reuseport;
/* 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 */
@ -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 */

View File

@ -530,6 +530,7 @@ answer_chaos(struct nsd *nsd, query_type *q)
(q->qname->name_size == 15
&& memcmp(dname_name(q->qname), "\010hostname\004bind", 15) == 0))
{
if(!nsd->options->hide_identity) {
/* Add ID */
query_addtxt(q,
buffer_begin(q->packet) + QHEADERSZ,
@ -537,6 +538,9 @@ answer_chaos(struct nsd *nsd, query_type *q)
0,
nsd->identity);
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 */

View File

@ -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);
}

View File

@ -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<n; i++) {
if(u1[i] == u2[i]) {
/* waste time equal to < and > 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

View File

@ -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)
{

View File

@ -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 &&

View File

@ -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)

View File

@ -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)

View File

@ -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) {
/* 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)

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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_ */

View File

@ -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;