From 275a8d899e6ba7e61052b65d3c7abe38db9a32dc Mon Sep 17 00:00:00 2001 From: florian Date: Fri, 24 Jun 2016 08:34:02 +0000 Subject: [PATCH] Update to 4.1.10 Testing by millert@, sthen@ and me. came up with the same diff & OK sthen@ --- usr.sbin/nsd/Makefile.in | 6 +-- usr.sbin/nsd/acx_nlnetlabs.m4 | 65 ++++++++++++++++++++++----------- usr.sbin/nsd/answer.c | 5 +++ usr.sbin/nsd/axfr.c | 10 ++--- usr.sbin/nsd/configlexer.lex | 3 ++ usr.sbin/nsd/configparser.y | 28 +++++++++++++- usr.sbin/nsd/configure.ac | 41 ++++++++++++++++++--- usr.sbin/nsd/dbaccess.c | 38 +++++++++++++------ usr.sbin/nsd/dbcreate.c | 16 ++++++-- usr.sbin/nsd/difffile.c | 4 +- usr.sbin/nsd/dns.c | 3 +- usr.sbin/nsd/dns.h | 1 + usr.sbin/nsd/namedb.c | 12 ++++++ usr.sbin/nsd/namedb.h | 9 +++-- usr.sbin/nsd/nsd-checkconf.8.in | 2 +- usr.sbin/nsd/nsd-checkconf.c | 16 +++++--- usr.sbin/nsd/nsd-checkzone.8.in | 2 +- usr.sbin/nsd/nsd-control.8.in | 2 +- usr.sbin/nsd/nsd.8.in | 8 ++-- usr.sbin/nsd/nsd.c | 3 ++ usr.sbin/nsd/nsd.conf.5.in | 27 ++++++++++++-- usr.sbin/nsd/nsd.conf.sample.in | 11 ++++++ usr.sbin/nsd/nsd.h | 2 + usr.sbin/nsd/nsec3.c | 16 +++++++- usr.sbin/nsd/options.c | 3 ++ usr.sbin/nsd/options.h | 3 ++ usr.sbin/nsd/query.c | 42 +++++++++++++-------- usr.sbin/nsd/rrl.c | 4 +- usr.sbin/nsd/server.c | 40 +++++++++++++++++++- usr.sbin/nsd/tsig-openssl.c | 16 +++++++- usr.sbin/nsd/udb.h | 2 +- usr.sbin/nsd/udbzone.c | 13 +++++-- usr.sbin/nsd/udbzone.h | 5 ++- usr.sbin/nsd/util.c | 22 +++++++++++ usr.sbin/nsd/util.h | 2 + usr.sbin/nsd/xfrd-tcp.c | 14 +++++++ usr.sbin/nsd/xfrd.c | 13 +++++-- usr.sbin/nsd/zparser.y | 14 +++++++ 38 files changed, 418 insertions(+), 105 deletions(-) diff --git a/usr.sbin/nsd/Makefile.in b/usr.sbin/nsd/Makefile.in index 91032915ada..3fbd01b6814 100644 --- a/usr.sbin/nsd/Makefile.in +++ b/usr.sbin/nsd/Makefile.in @@ -439,9 +439,9 @@ xfrd-disk.o: $(srcdir)/xfrd-disk.c config.h $(srcdir)/xfrd-disk.h $(srcdir)/xfrd xfrd-notify.o: $(srcdir)/xfrd-notify.c config.h $(srcdir)/xfrd-notify.h $(srcdir)/tsig.h $(srcdir)/buffer.h \ $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/dname.h $(srcdir)/rbtree.h $(srcdir)/xfrd.h $(srcdir)/namedb.h $(srcdir)/dns.h \ $(srcdir)/radtree.h $(srcdir)/options.h $(srcdir)/xfrd-tcp.h $(srcdir)/packet.h -xfrd-tcp.o: $(srcdir)/xfrd-tcp.c config.h $(srcdir)/xfrd-tcp.h $(srcdir)/xfrd.h $(srcdir)/rbtree.h \ - $(srcdir)/region-allocator.h $(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/buffer.h $(srcdir)/util.h $(srcdir)/dns.h $(srcdir)/radtree.h \ - $(srcdir)/options.h $(srcdir)/tsig.h $(srcdir)/packet.h $(srcdir)/xfrd-disk.h +xfrd-tcp.o: $(srcdir)/xfrd-tcp.c config.h $(srcdir)/nsd.h $(srcdir)/dns.h $(srcdir)/edns.h $(srcdir)/buffer.h \ + $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/xfrd-tcp.h $(srcdir)/xfrd.h $(srcdir)/rbtree.h $(srcdir)/namedb.h $(srcdir)/dname.h \ + $(srcdir)/radtree.h $(srcdir)/options.h $(srcdir)/tsig.h $(srcdir)/packet.h $(srcdir)/xfrd-disk.h zlexer.o: zlexer.c config.h $(srcdir)/zonec.h $(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/buffer.h \ $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/dns.h $(srcdir)/radtree.h $(srcdir)/rbtree.h zparser.h zonec.o: $(srcdir)/zonec.c config.h $(srcdir)/zonec.h $(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/buffer.h \ diff --git a/usr.sbin/nsd/acx_nlnetlabs.m4 b/usr.sbin/nsd/acx_nlnetlabs.m4 index 26513e4ff67..a6c174f1c42 100644 --- a/usr.sbin/nsd/acx_nlnetlabs.m4 +++ b/usr.sbin/nsd/acx_nlnetlabs.m4 @@ -2,7 +2,11 @@ # Copyright 2009, Wouter Wijngaards, NLnet Labs. # BSD licensed. # -# Version 30 +# Version 34 +# 2016-03-21 Check -ldl -pthread for libcrypto for ldns and openssl 1.1.0. +# 2016-03-21 Use HMAC_Update instead of HMAC_CTX_Init (for openssl-1.1.0). +# 2016-01-04 -D_DEFAULT_SOURCE defined with -D_BSD_SOURCE for Linux glibc 2.20 +# 2015-12-11 FLTO check for new OSX, clang. # 2015-11-18 spelling check fix. # 2015-11-05 ACX_SSL_CHECKS no longer adds -ldl needlessly. # 2015-08-28 ACX_CHECK_PIE and ACX_CHECK_RELRO_NOW added. @@ -241,7 +245,7 @@ ACX_CHECK_COMPILER_FLAG(xc99, [C99FLAG="-xc99"]) AC_CHECK_HEADERS([getopt.h time.h],,, [AC_INCLUDES_DEFAULT]) -ACX_CHECK_COMPILER_FLAG_NEEDED($C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED=1 -D_ALL_SOURCE, +ACX_CHECK_COMPILER_FLAG_NEEDED($C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED=1 -D_ALL_SOURCE, [ #include "confdefs.h" #include @@ -276,9 +280,9 @@ int test() { a = 0; return a; } -], [CFLAGS="$CFLAGS $C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED=1 -D_ALL_SOURCE"]) +], [CFLAGS="$CFLAGS $C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED=1 -D_ALL_SOURCE"]) -ACX_CHECK_COMPILER_FLAG_NEEDED($C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_ALL_SOURCE, +ACX_CHECK_COMPILER_FLAG_NEEDED($C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_ALL_SOURCE, [ #include "confdefs.h" #include @@ -313,7 +317,7 @@ int test() { a = 0; return a; } -], [CFLAGS="$CFLAGS $C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_ALL_SOURCE"]) +], [CFLAGS="$CFLAGS $C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_ALL_SOURCE"]) ACX_CHECK_COMPILER_FLAG_NEEDED($C99FLAG, [ @@ -325,7 +329,7 @@ int test() { } ], [CFLAGS="$CFLAGS $C99FLAG"]) -ACX_CHECK_COMPILER_FLAG_NEEDED(-D_BSD_SOURCE, +ACX_CHECK_COMPILER_FLAG_NEEDED(-D_BSD_SOURCE -D_DEFAULT_SOURCE, [ #include @@ -334,7 +338,7 @@ int test() { a = isascii(32); return a; } -], [CFLAGS="$CFLAGS -D_BSD_SOURCE"]) +], [CFLAGS="$CFLAGS -D_BSD_SOURCE -D_DEFAULT_SOURCE"]) ACX_CHECK_COMPILER_FLAG_NEEDED(-D_GNU_SOURCE, [ @@ -423,7 +427,7 @@ AC_DEFUN([ACX_CHECK_FLTO], [ BAKCFLAGS="$CFLAGS" CFLAGS="$CFLAGS -flto" AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])], [ - if $CC $CFLAGS -o conftest conftest.c 2>&1 | grep "warning: no debug symbols in executable" >/dev/null; then + if $CC $CFLAGS -o conftest conftest.c 2>&1 | $GREP -e "warning: no debug symbols in executable" -e "warning: object" >/dev/null; then CFLAGS="$BAKCFLAGS" AC_MSG_RESULT(no) else @@ -669,16 +673,16 @@ AC_DEFUN([ACX_SSL_CHECKS], [ ACX_RUNTIME_PATH_ADD([$ssldir/lib]) fi - AC_MSG_CHECKING([for HMAC_CTX_init in -lcrypto]) + AC_MSG_CHECKING([for HMAC_Update in -lcrypto]) LIBS="$LIBS -lcrypto" LIBSSL_LIBS="$LIBSSL_LIBS -lcrypto" AC_TRY_LINK(, [ - int HMAC_CTX_init(void); - (void)HMAC_CTX_init(); + int HMAC_Update(void); + (void)HMAC_Update(); ], [ AC_MSG_RESULT(yes) - AC_DEFINE([HAVE_HMAC_CTX_INIT], 1, - [If you have HMAC_CTX_init]) + AC_DEFINE([HAVE_HMAC_UPDATE], 1, + [If you have HMAC_Update]) ], [ AC_MSG_RESULT(no) # check if -lwsock32 or -lgdi32 are needed. @@ -688,11 +692,11 @@ AC_DEFUN([ACX_SSL_CHECKS], [ LIBSSL_LIBS="$LIBSSL_LIBS -lgdi32" AC_MSG_CHECKING([if -lcrypto needs -lgdi32]) AC_TRY_LINK([], [ - int HMAC_CTX_init(void); - (void)HMAC_CTX_init(); + int HMAC_Update(void); + (void)HMAC_Update(); ],[ - AC_DEFINE([HAVE_HMAC_CTX_INIT], 1, - [If you have HMAC_CTX_init]) + AC_DEFINE([HAVE_HMAC_UPDATE], 1, + [If you have HMAC_Update]) AC_MSG_RESULT(yes) ],[ AC_MSG_RESULT(no) @@ -702,15 +706,30 @@ AC_DEFUN([ACX_SSL_CHECKS], [ LIBSSL_LIBS="$LIBSSL_LIBS -ldl" AC_MSG_CHECKING([if -lcrypto needs -ldl]) AC_TRY_LINK([], [ - int HMAC_CTX_init(void); - (void)HMAC_CTX_init(); + int HMAC_Update(void); + (void)HMAC_Update(); ],[ - AC_DEFINE([HAVE_HMAC_CTX_INIT], 1, - [If you have HMAC_CTX_init]) + AC_DEFINE([HAVE_HMAC_UPDATE], 1, + [If you have HMAC_Update]) AC_MSG_RESULT(yes) ],[ AC_MSG_RESULT(no) - AC_MSG_ERROR([OpenSSL found in $ssldir, but version 0.9.7 or higher is required]) + LIBS="$BAKLIBS" + LIBSSL_LIBS="$BAKSSLLIBS" + LIBS="$LIBS -ldl -pthread" + LIBSSL_LIBS="$LIBSSL_LIBS -ldl -pthread" + AC_MSG_CHECKING([if -lcrypto needs -ldl -pthread]) + AC_TRY_LINK([], [ + int HMAC_Update(void); + (void)HMAC_Update(); + ],[ + AC_DEFINE([HAVE_HMAC_UPDATE], 1, + [If you have HMAC_Update]) + AC_MSG_RESULT(yes) + ],[ + AC_MSG_RESULT(no) + AC_MSG_ERROR([OpenSSL found in $ssldir, but version 0.9.7 or higher is required]) + ]) ]) ]) ]) @@ -1284,6 +1303,7 @@ AC_DEFUN([ACX_STRIP_EXT_FLAGS], AC_MSG_NOTICE([Stripping extension flags...]) ACX_CFLAGS_STRIP(-D_GNU_SOURCE) ACX_CFLAGS_STRIP(-D_BSD_SOURCE) + ACX_CFLAGS_STRIP(-D_DEFAULT_SOURCE) ACX_CFLAGS_STRIP(-D__EXTENSIONS__) ACX_CFLAGS_STRIP(-D_POSIX_C_SOURCE=200112) ACX_CFLAGS_STRIP(-D_XOPEN_SOURCE=600) @@ -1311,6 +1331,7 @@ dnl config.h part to define omitted cflags, use with ACX_STRIP_EXT_FLAGS. AC_DEFUN([AHX_CONFIG_EXT_FLAGS], [AHX_CONFIG_FLAG_EXT(-D_GNU_SOURCE) AHX_CONFIG_FLAG_EXT(-D_BSD_SOURCE) +AHX_CONFIG_FLAG_EXT(-D_DEFAULT_SOURCE) AHX_CONFIG_FLAG_EXT(-D__EXTENSIONS__) AHX_CONFIG_FLAG_EXT(-D_POSIX_C_SOURCE=200112) AHX_CONFIG_FLAG_EXT(-D_XOPEN_SOURCE=600) diff --git a/usr.sbin/nsd/answer.c b/usr.sbin/nsd/answer.c index be43c4c6cd1..c7b86fb2072 100644 --- a/usr.sbin/nsd/answer.c +++ b/usr.sbin/nsd/answer.c @@ -95,6 +95,11 @@ encode_answer(query_type *q, const answer_type *answer) * sections. */ if (done) { + /* delegations should have a usable address in it */ + if(section == ADDITIONAL_A_SECTION && + counts[ADDITIONAL_A_SECTION] == 0 && + q->delegation_domain) + TC_SET(q->packet); break; } #endif diff --git a/usr.sbin/nsd/axfr.c b/usr.sbin/nsd/axfr.c index f7e0caacea2..09eb0823cb4 100644 --- a/usr.sbin/nsd/axfr.c +++ b/usr.sbin/nsd/axfr.c @@ -95,9 +95,10 @@ query_axfr(struct nsd *nsd, struct query *query) } /* Add zone RRs until answer is full. */ - assert(query->axfr_current_domain); - - do { + while (query->axfr_current_domain != NULL && + domain_is_subdomain(query->axfr_current_domain, + query->axfr_zone->apex)) + { if (!query->axfr_current_rrset) { query->axfr_current_rrset = domain_find_any_rrset( query->axfr_current_domain, @@ -128,9 +129,6 @@ query_axfr(struct nsd *nsd, struct query *query) query->axfr_current_domain = domain_next(query->axfr_current_domain); } - while (query->axfr_current_domain != NULL && - domain_is_subdomain(query->axfr_current_domain, - query->axfr_zone->apex)); /* Add terminating SOA RR. */ assert(query->axfr_zone->soa_rrset->rr_count == 1); diff --git a/usr.sbin/nsd/configlexer.lex b/usr.sbin/nsd/configlexer.lex index 20304b7be5b..113fa2284c1 100644 --- a/usr.sbin/nsd/configlexer.lex +++ b/usr.sbin/nsd/configlexer.lex @@ -199,6 +199,7 @@ name{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_NAME;} 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;} debug-mode{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_DEBUG_MODE;} hide-version{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_HIDE_VERSION;} ip4-only{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_IP4_ONLY;} @@ -214,6 +215,8 @@ server-count{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_SERVER_COUNT;} tcp-count{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_TCP_COUNT;} 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;} +outgoing-tcp-mss{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_OUTGOING_TCP_MSS;} ipv4-edns-size{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_IPV4_EDNS_SIZE;} ipv6-edns-size{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_IPV6_EDNS_SIZE;} pidfile{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_PIDFILE;} diff --git a/usr.sbin/nsd/configparser.y b/usr.sbin/nsd/configparser.y index 36a3dddd3b8..1d824d10b05 100644 --- a/usr.sbin/nsd/configparser.y +++ b/usr.sbin/nsd/configparser.y @@ -51,6 +51,7 @@ extern config_parser_state_t* cfg_parser; %token VAR_CHROOT VAR_USERNAME VAR_ZONESDIR VAR_XFRDFILE VAR_DIFFFILE %token VAR_XFRD_RELOAD_TIMEOUT VAR_TCP_QUERY_COUNT VAR_TCP_TIMEOUT %token VAR_IPV4_EDNS_SIZE VAR_IPV6_EDNS_SIZE VAR_DO_IP4 VAR_DO_IP6 +%token VAR_TCP_MSS VAR_OUTGOING_TCP_MSS VAR_IP_FREEBIND %token VAR_ZONEFILE %token VAR_ZONE %token VAR_ALLOW_NOTIFY VAR_REQUEST_XFR VAR_NOTIFY VAR_PROVIDE_XFR @@ -93,11 +94,12 @@ content_server: server_ip_address | server_ip_transparent | server_debug_mode | server_tcp_query_count | server_tcp_timeout | server_ipv4_edns_size | server_ipv6_edns_size | server_verbosity | server_hide_version | server_zonelistfile | server_xfrdir | + server_tcp_mss | server_outgoing_tcp_mss | server_rrl_size | server_rrl_ratelimit | server_rrl_slip | server_rrl_ipv4_prefix_length | server_rrl_ipv6_prefix_length | server_rrl_whitelist_ratelimit | server_zonefiles_check | server_do_ip4 | server_do_ip6 | server_zonefiles_write | server_log_time_ascii | server_round_robin | - server_reuseport | server_version; + server_reuseport | server_version | server_ip_freebind; server_ip_address: VAR_IP_ADDRESS STRING { OUTYY(("P(server_ip_address:%s)\n", $2)); @@ -128,6 +130,14 @@ server_ip_transparent: VAR_IP_TRANSPARENT STRING else cfg_parser->opt->ip_transparent = (strcmp($2, "yes")==0); } ; +server_ip_freebind: VAR_IP_FREEBIND STRING + { + OUTYY(("P(server_ip_freebind:%s)\n", $2)); + if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) + yyerror("expected yes or no."); + else cfg_parser->opt->ip_freebind = (strcmp($2, "yes")==0); + } + ; server_debug_mode: VAR_DEBUG_MODE STRING { OUTYY(("P(server_debug_mode:%s)\n", $2)); @@ -381,6 +391,22 @@ server_tcp_timeout: VAR_TCP_TIMEOUT STRING cfg_parser->opt->tcp_timeout = atoi($2); } ; +server_tcp_mss: VAR_TCP_MSS STRING + { + OUTYY(("P(server_tcp_mss:%s)\n", $2)); + if(atoi($2) == 0 && strcmp($2, "0") != 0) + yyerror("number expected"); + cfg_parser->opt->tcp_mss = atoi($2); + } + ; +server_outgoing_tcp_mss: VAR_OUTGOING_TCP_MSS STRING + { + OUTYY(("P(server_outgoing_tcp_mss:%s)\n", $2)); + if(atoi($2) == 0 && strcmp($2, "0") != 0) + yyerror("number expected"); + cfg_parser->opt->outgoing_tcp_mss = atoi($2); + } + ; server_ipv4_edns_size: VAR_IPV4_EDNS_SIZE STRING { OUTYY(("P(server_ipv4_edns_size:%s)\n", $2)); diff --git a/usr.sbin/nsd/configure.ac b/usr.sbin/nsd/configure.ac index c04deacc25e..4c451bd01b3 100644 --- a/usr.sbin/nsd/configure.ac +++ b/usr.sbin/nsd/configure.ac @@ -4,7 +4,7 @@ dnl sinclude(acx_nlnetlabs.m4) -AC_INIT(NSD,4.1.7,nsd-bugs@nlnetlabs.nl) +AC_INIT(NSD,4.1.10,nsd-bugs@nlnetlabs.nl) AC_CONFIG_HEADER([config.h]) CFLAGS="$CFLAGS" @@ -415,7 +415,7 @@ fi # Checks for header files. AC_HEADER_STDC AC_HEADER_SYS_WAIT -AC_CHECK_HEADERS([time.h arpa/inet.h signal.h string.h strings.h fcntl.h limits.h netinet/in.h stddef.h sys/param.h sys/socket.h syslog.h unistd.h sys/select.h stdarg.h stdint.h netdb.h sys/bitypes.h tcpd.h glob.h grp.h endian.h]) +AC_CHECK_HEADERS([time.h arpa/inet.h signal.h string.h strings.h fcntl.h limits.h netinet/in.h netinet/tcp.h stddef.h sys/param.h sys/socket.h syslog.h unistd.h sys/select.h stdarg.h stdint.h netdb.h sys/bitypes.h tcpd.h glob.h grp.h endian.h]) AC_DEFUN([CHECK_VALIST_DEF], [ @@ -585,6 +585,7 @@ AC_CHECK_TYPE(in_addr_t, [], [AC_DEFINE([in_addr_t], [uint32_t], [in_addr_t])], # include #endif]) ACX_CHECK_SS_FAMILY +AC_CHECK_MEMBERS([struct stat.st_mtimensec, struct stat.st_mtim.tv_nsec]) # Checks for library functions. AC_FUNC_CHOWN @@ -596,9 +597,9 @@ AC_SYS_LARGEFILE AC_CHECK_SIZEOF(void*) AC_CHECK_SIZEOF(off_t) AC_CHECK_FUNCS([arc4random arc4random_uniform]) -AC_CHECK_FUNCS([tzset alarm chroot dup2 endpwent gethostname memset memcpy pwrite socket strcasecmp strchr strdup strerror strncasecmp strtol writev getaddrinfo getnameinfo freeaddrinfo gai_strerror sigaction sigprocmask strptime strftime localtime_r setusercontext glob initgroups setresuid setreuid setresgid setregid getpwnam mmap ppoll]) +AC_CHECK_FUNCS([tzset alarm chroot dup2 endpwent gethostname memset memcpy pwrite socket strcasecmp strchr strdup strerror strncasecmp strtol writev getaddrinfo getnameinfo freeaddrinfo gai_strerror sigaction sigprocmask strptime strftime localtime_r setusercontext glob initgroups setresuid setreuid setresgid setregid getpwnam mmap ppoll clock_gettime]) -AC_ARG_ENABLE(recvmmsg, AC_HELP_STRING([--enable-recvmmsg], [Enable recvmmsg and sendmmsg compilation, faster but some kernel versions may have implementation problems])) +AC_ARG_ENABLE(recvmmsg, AC_HELP_STRING([--enable-recvmmsg], [Enable recvmmsg and sendmmsg compilation, faster but some kernel versions may have implementation problems for IPv6])) case "$enable_recvmmsg" in yes) AC_CHECK_FUNC([recvmmsg], [ @@ -829,8 +830,30 @@ AC_SUBST(ratelimit_default) CHECK_SSL if test x$HAVE_SSL = x"yes"; then ACX_LIB_SSL + + # Check for -pthread + BAKLIBS="$LIBS" + LIBS="-lcrypto $LIBS" + AC_TRY_LINK([], [ + int HMAC_Update(void); + (void)HMAC_Update(); + ], [],[ + dnl so link fails for HMAC_Update, try with -pthread. + BAKCFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -pthread" + AC_MSG_CHECKING([if libcrypto needs -pthread]) + AC_TRY_LINK_FUNC([HMAC_Update], [ + AC_MSG_RESULT([yes]) + ] , [ + AC_MSG_RESULT([no]) + dnl restore the nonpthread value + CFLAGS="$BAKCFLAGS" + ]) + ]) + LIBS="$BAKLIBS" + if test -n "$ssldir"; then - AC_CHECK_LIB(crypto, HMAC_CTX_init,, [ + AC_CHECK_LIB(crypto, HMAC_Update,, [ AC_MSG_ERROR([OpenSSL found in $ssldir, but version 0.9.7 or higher is required]) ]) fi @@ -839,6 +862,7 @@ if test x$HAVE_SSL = x"yes"; then AC_CHECK_HEADERS([openssl/ssl.h],,, [AC_INCLUDES_DEFAULT]) AC_CHECK_HEADERS([openssl/err.h],,, [AC_INCLUDES_DEFAULT]) AC_CHECK_HEADERS([openssl/rand.h],,, [AC_INCLUDES_DEFAULT]) + AC_CHECK_FUNCS([HMAC_CTX_reset HMAC_CTX_new]) else AC_MSG_WARN([No SSL, therefore remote-control is disabled]) fi @@ -894,6 +918,9 @@ AH_BOTTOM([ # ifndef _BSD_SOURCE # define _BSD_SOURCE 1 # endif +# ifndef _DEFAULT_SOURCE +# define _DEFAULT_SOURCE 1 +# endif # ifndef __EXTENSIONS__ # define __EXTENSIONS__ 1 # endif @@ -938,6 +965,10 @@ AH_BOTTOM([ #include #endif +#ifdef HAVE_NETINET_TCP_H +#include +#endif + #ifdef HAVE_ARPA_INET_H #include #endif diff --git a/usr.sbin/nsd/dbaccess.c b/usr.sbin/nsd/dbaccess.c index 86891f2f635..cc49a51a3e3 100644 --- a/usr.sbin/nsd/dbaccess.c +++ b/usr.sbin/nsd/dbaccess.c @@ -271,7 +271,8 @@ namedb_zone_create(namedb_type* db, const dname_type* dname, zone->opts = zo; zone->filename = NULL; zone->logstr = NULL; - zone->mtime = 0; + zone->mtime.tv_sec = 0; + zone->mtime.tv_nsec = 0; zone->zonestatid = 0; zone->is_secure = 0; zone->is_changed = 0; @@ -491,17 +492,25 @@ namedb_open (const char* filename, nsd_options_t* opt) } /** the the file mtime stat (or nonexist or error) */ -static int -file_get_mtime(const char* file, time_t* mtime, int* nonexist) +int +file_get_mtime(const char* file, struct timespec* mtime, int* nonexist) { struct stat s; if(stat(file, &s) != 0) { - *mtime = 0; + mtime->tv_sec = 0; + mtime->tv_nsec = 0; *nonexist = (errno == ENOENT); return 0; } *nonexist = 0; - *mtime = s.st_mtime; + mtime->tv_sec = s.st_mtime; +#ifdef HAVE_STRUCT_STAT_ST_MTIMENSEC + mtime->tv_nsec = s.st_mtimensec; +#elif defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC) + mtime->tv_nsec = s.st_mtim.tv_nsec; +#else + mtime->tv_nsec = 0; +#endif return 1; } @@ -509,12 +518,14 @@ void namedb_read_zonefile(struct nsd* nsd, struct zone* zone, udb_base* taskudb, udb_ptr* last_task) { - time_t mtime = 0; + struct timespec mtime; int nonexist = 0; unsigned int errors; const char* fname; if(!nsd->db || !zone || !zone->opts || !zone->opts->pattern->zonefile) return; + mtime.tv_sec = 0; + mtime.tv_nsec = 0; fname = config_make_zonefile(zone->opts, nsd); if(!file_get_mtime(fname, &mtime, &nonexist)) { if(nonexist) { @@ -527,20 +538,21 @@ namedb_read_zonefile(struct nsd* nsd, struct zone* zone, udb_base* taskudb, return; } else { const char* zone_fname = zone->filename; - time_t zone_mtime = zone->mtime; + struct timespec zone_mtime = zone->mtime; if(nsd->db->udb) { zone_fname = udb_zone_get_file_str(nsd->db->udb, dname_name(domain_dname(zone->apex)), domain_dname(zone->apex)->name_size); - zone_mtime = (time_t)udb_zone_get_mtime(nsd->db->udb, + udb_zone_get_mtime(nsd->db->udb, dname_name(domain_dname(zone->apex)), - domain_dname(zone->apex)->name_size); + domain_dname(zone->apex)->name_size, + &zone_mtime); } /* if no zone_fname, then it was acquired in zone transfer, * see if the file is newer than the zone transfer * (regardless if this is a different file), because the * zone transfer is a different content source too */ - if(!zone_fname && zone_mtime >= mtime) { + if(!zone_fname && timespec_compare(&zone_mtime, &mtime) >= 0) { VERBOSITY(3, (LOG_INFO, "zonefile %s is older than " "zone transfer in memory", fname)); return; @@ -548,7 +560,8 @@ namedb_read_zonefile(struct nsd* nsd, struct zone* zone, udb_base* taskudb, /* if zone_fname, then the file was acquired from reading it, * and see if filename changed or mtime newer to read it */ } else if(zone_fname && fname && - strcmp(zone_fname, fname) == 0 && zone_mtime >= mtime) { + strcmp(zone_fname, fname) == 0 && + timespec_compare(&zone_mtime, &mtime) == 0) { VERBOSITY(3, (LOG_INFO, "zonefile %s is not modified", fname)); return; @@ -614,7 +627,8 @@ namedb_read_zonefile(struct nsd* nsd, struct zone* zone, udb_base* taskudb, zone->is_changed = 0; /* store zone into udb */ if(nsd->db->udb) { - if(!write_zone_to_udb(nsd->db->udb, zone, mtime, fname)) { + if(!write_zone_to_udb(nsd->db->udb, zone, &mtime, + fname)) { log_msg(LOG_ERR, "failed to store zone in db"); } else { VERBOSITY(2, (LOG_INFO, "zone %s written to db", diff --git a/usr.sbin/nsd/dbcreate.c b/usr.sbin/nsd/dbcreate.c index 24866af774b..ce2149138ed 100644 --- a/usr.sbin/nsd/dbcreate.c +++ b/usr.sbin/nsd/dbcreate.c @@ -146,7 +146,7 @@ write_zone(udb_base* udb, udb_ptr* z, zone_type* zone) /** create and write a zone */ int -write_zone_to_udb(udb_base* udb, zone_type* zone, time_t mtime, +write_zone_to_udb(udb_base* udb, zone_type* zone, struct timespec* mtime, const char* file_str) { udb_ptr z; @@ -165,7 +165,8 @@ write_zone_to_udb(udb_base* udb, zone_type* zone, time_t mtime, } } /* set mtime */ - ZONE(&z)->mtime = (uint64_t)mtime; + ZONE(&z)->mtime = (uint64_t)mtime->tv_sec; + ZONE(&z)->mtime_nsec = (uint64_t)mtime->tv_nsec; ZONE(&z)->is_changed = 0; udb_zone_set_log_str(udb, &z, NULL); udb_zone_set_file_str(udb, &z, file_str); @@ -350,6 +351,7 @@ namedb_write_zonefile(struct nsd* nsd, zone_options_t* zopt) if(notexist || zone->is_changed) { char logs[4096]; char bakfile[4096]; + struct timespec mtime; udb_ptr zudb; if(nsd->db->udb) { if(!udb_zone_search(nsd->db->udb, &zudb, @@ -384,13 +386,19 @@ namedb_write_zonefile(struct nsd* nsd, zone_options_t* zopt) return; } zone->is_changed = 0; + /* fetch the mtime of the just created zonefile so we + * do not waste effort reading it back in */ + if(!file_get_mtime(zfile, &mtime, ¬exist)) { + get_time(&mtime); + } if(nsd->db->udb) { - ZONE(&zudb)->mtime = (uint64_t)time(0); + ZONE(&zudb)->mtime = (uint64_t)mtime.tv_sec; + ZONE(&zudb)->mtime_nsec = (uint64_t)mtime.tv_nsec; ZONE(&zudb)->is_changed = 0; udb_zone_set_log_str(nsd->db->udb, &zudb, NULL); udb_ptr_unlink(&zudb, nsd->db->udb); } else { - zone->mtime = time(0); + zone->mtime = mtime; if(zone->filename) region_recycle(nsd->db->region, zone->filename, strlen(zone->filename)+1); diff --git a/usr.sbin/nsd/difffile.c b/usr.sbin/nsd/difffile.c index 4196f79e066..b2325c5b81b 100644 --- a/usr.sbin/nsd/difffile.c +++ b/usr.sbin/nsd/difffile.c @@ -1378,11 +1378,13 @@ apply_ixfr_for_zone(nsd_type* nsd, zone_type* zonedb, FILE* in, if(nsd->db->udb) { ZONE(&z)->is_changed = 1; ZONE(&z)->mtime = time_end_0; + ZONE(&z)->mtime_nsec = time_end_1*1000; udb_zone_set_log_str(nsd->db->udb, &z, log_buf); udb_zone_set_file_str(nsd->db->udb, &z, NULL); udb_ptr_unlink(&z, nsd->db->udb); } else { - zonedb->mtime = time_end_0; + zonedb->mtime.tv_sec = time_end_0; + zonedb->mtime.tv_nsec = time_end_1*1000; if(zonedb->logstr) region_recycle(nsd->db->region, zonedb->logstr, strlen(zonedb->logstr)+1); diff --git a/usr.sbin/nsd/dns.c b/usr.sbin/nsd/dns.c index 2ba99d3fd91..037cd4cbb6a 100644 --- a/usr.sbin/nsd/dns.c +++ b/usr.sbin/nsd/dns.c @@ -300,7 +300,8 @@ static rrtype_descriptor_type rrtype_descriptors[(RRTYPE_DESCRIPTORS_LENGTH+1)] /* 61 */ { 61, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 62 */ - { 62, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { TYPE_CSYNC, "CSYNC", T_CSYNC, 3, 3, { RDATA_WF_LONG, RDATA_WF_SHORT, + RDATA_WF_BINARY }, { RDATA_ZF_LONG, RDATA_ZF_SHORT, RDATA_ZF_NSEC } }, /* 63 */ { 63, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 64 */ diff --git a/usr.sbin/nsd/dns.h b/usr.sbin/nsd/dns.h index 3e9e88c92ca..810cd7010b3 100644 --- a/usr.sbin/nsd/dns.h +++ b/usr.sbin/nsd/dns.h @@ -138,6 +138,7 @@ typedef enum nsd_rc nsd_rc_type; #define TYPE_TLSA 52 /* RFC 6698 */ #define TYPE_CDS 59 /* RFC 7344 */ #define TYPE_CDNSKEY 60 /* RFC 7344 */ +#define TYPE_CSYNC 62 /* RFC 7477 */ #define TYPE_SPF 99 /* RFC 4408 */ diff --git a/usr.sbin/nsd/namedb.c b/usr.sbin/nsd/namedb.c index 96aec38c1dd..db90965c2d3 100644 --- a/usr.sbin/nsd/namedb.c +++ b/usr.sbin/nsd/namedb.c @@ -561,6 +561,18 @@ domain_find_ns_rrsets(domain_type* domain, zone_type* zone, rrset_type **ns) return NULL; } +domain_type * +find_dname_above(domain_type* domain, zone_type* zone) +{ + domain_type* d = domain->parent; + while(d && d != zone->apex) { + if(domain_find_rrset(d, zone, TYPE_DNAME)) + return d; + d = d->parent; + } + return NULL; +} + int domain_is_glue(domain_type* domain, zone_type* zone) { diff --git a/usr.sbin/nsd/namedb.h b/usr.sbin/nsd/namedb.h index d264c685679..ca46477ae20 100644 --- a/usr.sbin/nsd/namedb.h +++ b/usr.sbin/nsd/namedb.h @@ -127,7 +127,7 @@ struct zone struct zone_options* opts; char* filename; /* set if read from file, which file */ char* logstr; /* set for zone xfer, the log string */ - time_t mtime; /* time of last modification */ + struct timespec mtime; /* time of last modification */ unsigned zonestatid; /* array index for zone stats */ unsigned is_secure : 1; /* zone uses DNSSEC */ unsigned is_ok : 1; /* zone has not expired. */ @@ -235,6 +235,8 @@ zone_type* domain_find_zone(namedb_type* db, domain_type* domain); zone_type* domain_find_parent_zone(zone_type* zone); domain_type* domain_find_ns_rrsets(domain_type* domain, zone_type* zone, rrset_type **ns); +/* find DNAME rrset in domain->parent or higher and return that domain */ +domain_type * find_dname_above(domain_type* domain, zone_type* zone); int domain_is_glue(domain_type* domain, zone_type* zone); @@ -326,8 +328,8 @@ void domain_table_deldomain(namedb_type* db, domain_type* domain); /** dbcreate.c */ int udb_write_rr(struct udb_base* udb, struct udb_ptr* z, rr_type* rr); void udb_del_rr(struct udb_base* udb, struct udb_ptr* z, rr_type* rr); -int write_zone_to_udb(struct udb_base* udb, zone_type* zone, time_t mtime, - const char* file_str); +int write_zone_to_udb(struct udb_base* udb, zone_type* zone, + struct timespec* mtime, const char* file_str); /** marshal rdata into buffer, must be MAX_RDLENGTH in size */ size_t rr_marshal_rdata(rr_type* rr, uint8_t* rdata, size_t sz); /* dbaccess.c */ @@ -354,6 +356,7 @@ void namedb_zone_delete(namedb_type* db, zone_type* zone); void namedb_write_zonefile(struct nsd* nsd, struct zone_options* zopt); void namedb_write_zonefiles(struct nsd* nsd, struct nsd_options* options); int create_dirs(const char* path); +int file_get_mtime(const char* file, struct timespec* mtime, int* nonexist); void allocate_domain_nsec3(domain_table_type *table, domain_type *result); static inline int diff --git a/usr.sbin/nsd/nsd-checkconf.8.in b/usr.sbin/nsd/nsd-checkconf.8.in index 9bf830647a1..2425e69e4fe 100644 --- a/usr.sbin/nsd/nsd-checkconf.8.in +++ b/usr.sbin/nsd/nsd-checkconf.8.in @@ -1,4 +1,4 @@ -.TH "nsd\-checkconf" "8" "Dec 10, 2015" "NLnet Labs" "nsd 4.1.7" +.TH "nsd\-checkconf" "8" "Jun 14, 2016" "NLnet Labs" "nsd 4.1.10" .\" Copyright (c) 2001\-2008, NLnet Labs. All rights reserved. .\" See LICENSE for the license. .SH "NAME" diff --git a/usr.sbin/nsd/nsd-checkconf.c b/usr.sbin/nsd/nsd-checkconf.c index 6cbe71e55c6..e5f669f967b 100644 --- a/usr.sbin/nsd/nsd-checkconf.c +++ b/usr.sbin/nsd/nsd-checkconf.c @@ -341,6 +341,7 @@ config_print_zone(nsd_options_t* opt, const char* k, int s, const char *o, SERV_GET_IP(ip_address, ip_addresses, o); /* bin */ SERV_GET_BIN(ip_transparent, o); + SERV_GET_BIN(ip_freebind, o); SERV_GET_BIN(debug_mode, o); SERV_GET_BIN(do_ip4, o); SERV_GET_BIN(do_ip6, o); @@ -368,6 +369,8 @@ config_print_zone(nsd_options_t* opt, const char* k, int s, const char *o, SERV_GET_INT(tcp_count, o); SERV_GET_INT(tcp_query_count, o); SERV_GET_INT(tcp_timeout, o); + SERV_GET_INT(tcp_mss, o); + SERV_GET_INT(outgoing_tcp_mss, o); SERV_GET_INT(ipv4_edns_size, o); SERV_GET_INT(ipv6_edns_size, o); SERV_GET_INT(statistics, o); @@ -442,6 +445,7 @@ config_test_print_server(nsd_options_t* opt) printf("server:\n"); printf("\tdebug-mode: %s\n", opt->debug_mode?"yes":"no"); printf("\tip-transparent: %s\n", opt->ip_transparent?"yes":"no"); + printf("\tip-freebind: %s\n", opt->ip_freebind?"yes":"no"); 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"); @@ -451,10 +455,12 @@ config_test_print_server(nsd_options_t* opt) print_string_var("version:", opt->version); print_string_var("nsid:", opt->nsid); print_string_var("logfile:", opt->logfile); - printf("\tserver_count: %d\n", opt->server_count); - printf("\ttcp_count: %d\n", opt->tcp_count); - printf("\ttcp_query_count: %d\n", opt->tcp_query_count); - printf("\ttcp_timeout: %d\n", opt->tcp_timeout); + printf("\tserver-count: %d\n", opt->server_count); + printf("\ttcp-count: %d\n", opt->tcp_count); + printf("\ttcp-query-count: %d\n", opt->tcp_query_count); + printf("\ttcp-timeout: %d\n", opt->tcp_timeout); + printf("\ttcp-mss: %d\n", opt->tcp_mss); + printf("\toutgoing-tcp-mss: %d\n", opt->outgoing_tcp_mss); printf("\tipv4-edns-size: %d\n", (int) opt->ipv4_edns_size); printf("\tipv6-edns-size: %d\n", (int) opt->ipv6_edns_size); print_string_var("pidfile:", opt->pidfile); @@ -466,7 +472,7 @@ config_test_print_server(nsd_options_t* opt) print_string_var("xfrdfile:", opt->xfrdfile); print_string_var("zonelistfile:", opt->zonelistfile); print_string_var("xfrdir:", opt->xfrdir); - printf("\txfrd_reload_timeout: %d\n", opt->xfrd_reload_timeout); + printf("\txfrd-reload-timeout: %d\n", opt->xfrd_reload_timeout); printf("\tlog-time-ascii: %s\n", opt->log_time_ascii?"yes":"no"); printf("\tround-robin: %s\n", opt->round_robin?"yes":"no"); printf("\tverbosity: %d\n", opt->verbosity); diff --git a/usr.sbin/nsd/nsd-checkzone.8.in b/usr.sbin/nsd/nsd-checkzone.8.in index f58e0daa6e1..2be9443d388 100644 --- a/usr.sbin/nsd/nsd-checkzone.8.in +++ b/usr.sbin/nsd/nsd-checkzone.8.in @@ -1,4 +1,4 @@ -.TH "nsd\-checkzone" "8" "Dec 10, 2015" "NLnet Labs" "nsd 4.1.7" +.TH "nsd\-checkzone" "8" "Jun 14, 2016" "NLnet Labs" "nsd 4.1.10" .\" Copyright (c) 2014, NLnet Labs. All rights reserved. .\" See LICENSE for the license. .SH "NAME" diff --git a/usr.sbin/nsd/nsd-control.8.in b/usr.sbin/nsd/nsd-control.8.in index 4f6a59024cd..bf8d90d2fc0 100644 --- a/usr.sbin/nsd/nsd-control.8.in +++ b/usr.sbin/nsd/nsd-control.8.in @@ -1,4 +1,4 @@ -.TH "nsd\-control" "8" "Dec 10, 2015" "NLnet Labs" "nsd 4.1.7" +.TH "nsd\-control" "8" "Jun 14, 2016" "NLnet Labs" "nsd 4.1.10" .\" Copyright (c) 2011, NLnet Labs. All rights reserved. .\" See LICENSE for the license. .SH "NAME" diff --git a/usr.sbin/nsd/nsd.8.in b/usr.sbin/nsd/nsd.8.in index 0ef0cfa09bb..89afd9ca159 100644 --- a/usr.sbin/nsd/nsd.8.in +++ b/usr.sbin/nsd/nsd.8.in @@ -1,9 +1,9 @@ -.TH "NSD" "8" "Dec 10, 2015" "NLnet Labs" "NSD 4.1.7" +.TH "NSD" "8" "Jun 14, 2016" "NLnet Labs" "NSD 4.1.10" .\" 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.7. +\- Name Server Daemon (NSD) version 4.1.10. .SH "SYNOPSIS" .B nsd .RB [ \-4 ] @@ -115,7 +115,7 @@ Do not fork, stay in the foreground. Use the specified .I database instead of the default of -.IR @dbfile@ . +.IR '@dbfile@' . If a .B zonesdir: is specified in the config file this path can be relative to that @@ -224,7 +224,7 @@ SIGUSR1 Dump BIND8\-style statistics into the log. Ignored otherwise. .SH "FILES" .TP -@dbfile@ +"@dbfile@" default .B NSD database diff --git a/usr.sbin/nsd/nsd.c b/usr.sbin/nsd/nsd.c index 3f35f1132f6..f9643862a44 100644 --- a/usr.sbin/nsd/nsd.c +++ b/usr.sbin/nsd/nsd.c @@ -681,6 +681,8 @@ main(int argc, char *argv[]) } nsd.tcp_timeout = nsd.options->tcp_timeout; nsd.tcp_query_count = nsd.options->tcp_query_count; + nsd.tcp_mss = nsd.options->tcp_mss; + 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; @@ -909,6 +911,7 @@ main(int argc, char *argv[]) VERBOSITY(2, (LOG_WARNING, "chown %s failed: %s", nsd.log_filename, strerror(errno))); } + log_msg(LOG_NOTICE, "%s starting (%s)", argv0, PACKAGE_STRING); /* Do we have a running nsd? */ if ((oldpid = readpid(nsd.pidfile)) == -1) { diff --git a/usr.sbin/nsd/nsd.conf.5.in b/usr.sbin/nsd/nsd.conf.5.in index 2fe1bf4ddad..44493c722cd 100644 --- a/usr.sbin/nsd/nsd.conf.5.in +++ b/usr.sbin/nsd/nsd.conf.5.in @@ -1,4 +1,4 @@ -.TH "nsd.conf" "5" "Dec 10, 2015" "NLnet Labs" "nsd 4.1.7" +.TH "nsd.conf" "5" "Jun 14, 2016" "NLnet Labs" "nsd 4.1.10" .\" Copyright (c) 2001\-2008, NLnet Labs. All rights reserved. .\" See LICENSE for the license. .SH "NAME" @@ -169,6 +169,10 @@ Allows NSD to bind to non local addresses. This is useful to have NSD listen to IP addresses that are not (yet) added to the network interface, so that it can answer immediately when the address is added. Default is no. .TP +.B ip\-freebind:\fR +Set the IP_FREEBIND option to bind to nonlocal addresses and interfaces +that are down. Similar to ip\-transparent. Default is no. +.TP .B reuseport:\fR Use the SO_REUSEPORT socket option, and create file descriptors for every server in the server\-count. This improves performance of the network @@ -193,7 +197,7 @@ If yes, NSD listens to IPv6 connections. Default yes. .TP .B database:\fR By default -.I @dbfile@ +.I '@dbfile@' is used. The specified file is used to store the compiled zone information. Same as commandline option .BR \-f. @@ -247,6 +251,23 @@ Default is 0, meaning there is no maximum. .B tcp\-timeout:\fR Overrides the default TCP timeout. This also affects zone transfers over TCP. .TP +.B tcp-mss:\fR +Maximum segment size (MSS) of TCP socket on which the server responds +to queries. Value lower than common MSS on Ethernet +(1220 for example) will address path MTU problem. +Note that not all platform supports socket option to set MSS (TCP_MAXSEG). +Default is system default MSS determined by interface MTU and +negotiation between server and client. +.TP +.B outgoing\-tcp\-mss:\fR +Maximum segment size (MSS) of TCP socket for outgoing XFR request +to other namesevers. Value lower than +common MSS on Ethernet (1220 for example) will +address path MTU problem. +Note that not all platform supports socket option to set MSS (TCP_MAXSEG). +Default is system default MSS determined by interface MTU and +negotiation between NSD and other servers. +.TP .B ipv4\-edns\-size:\fR Preferred EDNS buffer size for IPv4. Default 4096. .TP @@ -795,7 +816,7 @@ also function as a resolver or cache. The configuration options that BIND9 has for the resolver or caching thus have no equivalents for NSD. .SH "FILES" .TP -@dbfile@ +"@dbfile@" default .B NSD database diff --git a/usr.sbin/nsd/nsd.conf.sample.in b/usr.sbin/nsd/nsd.conf.sample.in index a78548e0fc8..48eef14ff9e 100644 --- a/usr.sbin/nsd/nsd.conf.sample.in +++ b/usr.sbin/nsd/nsd.conf.sample.in @@ -27,6 +27,9 @@ server: # Allow binding to non local addresses. Default no. # ip-transparent: no + # Allow binding to addresses that are down. Default no. + # ip-freebind: no + # use the reuseport socket option for performance. Default no. # reuseport: no @@ -102,6 +105,14 @@ server: # Override the default (120 seconds) TCP timeout. # tcp-timeout: 120 + # Maximum segment size (MSS) of TCP socket on which the server + # responds to queries. Default is 0, system default MSS. + # tcp-mss: 0 + + # Maximum segment size (MSS) of TCP socket for outgoing AXFR request. + # Default is 0, system default MSS. + # outgoing-tcp-mss: 0 + # Preferred EDNS buffer size for IPv4. # ipv4-edns-size: 4096 diff --git a/usr.sbin/nsd/nsd.h b/usr.sbin/nsd/nsd.h index 8ebf1a2bae8..290b06552b3 100644 --- a/usr.sbin/nsd/nsd.h +++ b/usr.sbin/nsd/nsd.h @@ -223,6 +223,8 @@ struct nsd int current_tcp_count; int tcp_query_count; int tcp_timeout; + int tcp_mss; + int outgoing_tcp_mss; size_t ipv4_edns_size; size_t ipv6_edns_size; diff --git a/usr.sbin/nsd/nsec3.c b/usr.sbin/nsd/nsec3.c index 92802bd2b00..d4fd1a2d336 100644 --- a/usr.sbin/nsd/nsec3.c +++ b/usr.sbin/nsd/nsec3.c @@ -965,9 +965,20 @@ nsec3_answer_nodata(struct query* query, struct answer* answer, original->nsec3->nsec3_cover); } else { /* add nsec3 to prove rrset does not exist */ - if(original->nsec3 && original->nsec3->nsec3_is_exact) { + if(original->nsec3) { + if(!original->nsec3->nsec3_is_exact) { + /* go up to an existing parent */ + while(original->parent && original->parent->nsec3 && !original->parent->nsec3->nsec3_is_exact) + original = original->parent; + } nsec3_add_rrset(query, answer, AUTHORITY_SECTION, original->nsec3->nsec3_cover); + if(!original->nsec3->nsec3_is_exact) { + if(original->parent && original->parent->nsec3 && original->parent->nsec3->nsec3_is_exact) + nsec3_add_rrset(query, answer, AUTHORITY_SECTION, + original->parent->nsec3->nsec3_cover); + + } } } } @@ -1041,7 +1052,8 @@ nsec3_answer_authoritative(struct domain** match, struct query *query, #if 0 query->qtype != TYPE_NSEC3 && #endif - domain_has_only_NSEC3(*match, query->zone)) + (domain_has_only_NSEC3(*match, query->zone) || + !domain_find_any_rrset(*match, query->zone))) { /* this looks like a NSEC3 domain, but is actually an empty non-terminal. */ nsec3_answer_nodata(query, answer, *match); diff --git a/usr.sbin/nsd/options.c b/usr.sbin/nsd/options.c index 88968518a86..349e271b422 100644 --- a/usr.sbin/nsd/options.c +++ b/usr.sbin/nsd/options.c @@ -49,6 +49,7 @@ nsd_options_create(region_type* region) opt->keys = rbtree_create(region, rbtree_strcmp); opt->ip_addresses = NULL; opt->ip_transparent = 0; + opt->ip_freebind = 0; opt->debug_mode = 0; opt->verbosity = 0; opt->hide_version = 0; @@ -65,6 +66,8 @@ nsd_options_create(region_type* region) opt->tcp_count = 100; opt->tcp_query_count = 0; opt->tcp_timeout = TCP_TIMEOUT; + opt->tcp_mss = 0; + opt->outgoing_tcp_mss = 0; opt->ipv4_edns_size = EDNS_MAX_MESSAGE_LEN; opt->ipv6_edns_size = EDNS_MAX_MESSAGE_LEN; opt->pidfile = PIDFILE; diff --git a/usr.sbin/nsd/options.h b/usr.sbin/nsd/options.h index 34ed295eb4a..ceba624fe3f 100644 --- a/usr.sbin/nsd/options.h +++ b/usr.sbin/nsd/options.h @@ -60,6 +60,7 @@ struct nsd_options { ip_address_option_t* ip_addresses; int ip_transparent; + int ip_freebind; int debug_mode; int verbosity; int hide_version; @@ -73,6 +74,8 @@ struct nsd_options { int tcp_count; int tcp_query_count; int tcp_timeout; + int tcp_mss; + int outgoing_tcp_mss; size_t ipv4_edns_size; size_t ipv6_edns_size; const char* pidfile; diff --git a/usr.sbin/nsd/query.c b/usr.sbin/nsd/query.c index 4f26112adc1..f8a429c4a98 100644 --- a/usr.sbin/nsd/query.c +++ b/usr.sbin/nsd/query.c @@ -609,6 +609,12 @@ struct additional_rr_types default_additional_rr_types[] = { { 0, (rr_section_type) 0 } }; +struct additional_rr_types swap_aaaa_additional_rr_types[] = { + { TYPE_AAAA, ADDITIONAL_A_SECTION }, + { TYPE_A, ADDITIONAL_AAAA_SECTION }, + { 0, (rr_section_type) 0 } +}; + struct additional_rr_types rt_additional_rr_types[] = { { TYPE_A, ADDITIONAL_A_SECTION }, { TYPE_AAAA, ADDITIONAL_AAAA_SECTION }, @@ -698,8 +704,11 @@ add_rrset(struct query *query, result = answer_add_rrset(answer, section, owner, rrset); switch (rrset_rrtype(rrset)) { case TYPE_NS: + /* if query over IPv6, swap A and AAAA; put AAAA first */ add_additional_rrsets(query, answer, rrset, 0, 1, - default_additional_rr_types); + (query->addr.ss_family == AF_INET6)? + swap_aaaa_additional_rr_types: + default_additional_rr_types); break; case TYPE_MB: add_additional_rrsets(query, answer, rrset, 0, 0, @@ -960,9 +969,6 @@ answer_domain(struct nsd* nsd, struct query *q, answer_type *answer, zone_type* origzone = q->zone; ++q->cname_count; - while (!closest_encloser->is_existing) - closest_encloser = closest_encloser->parent; - answer_lookup_zone(nsd, q, answer, closest_match->number, closest_match == closest_encloser, closest_match, closest_encloser, @@ -1003,6 +1009,7 @@ answer_authoritative(struct nsd *nsd, { domain_type *match; domain_type *original = closest_match; + domain_type *dname_ce; rrset_type *rrset; #ifdef NSEC3 @@ -1012,6 +1019,11 @@ answer_authoritative(struct nsd *nsd, closest_encloser = closest_encloser->parent; } #endif /* NSEC3 */ + if((dname_ce = find_dname_above(closest_encloser, q->zone)) != NULL) { + /* occlude the found data, the DNAME is closest_encloser */ + closest_encloser = dname_ce; + exact = 0; + } if (exact) { match = closest_match; @@ -1053,8 +1065,6 @@ answer_authoritative(struct nsd *nsd, return; } - while (closest_encloser && !closest_encloser->is_existing) - closest_encloser = closest_encloser->parent; answer_lookup_zone(nsd, q, answer, newnum, closest_match == closest_encloser, closest_match, closest_encloser, newname); @@ -1176,6 +1186,14 @@ answer_lookup_zone(struct nsd *nsd, struct query *q, answer_type *answer, RCODE_SET(q->packet, RCODE_SERVFAIL); 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 */ + if (closest_encloser && !closest_encloser->is_existing) { + exact = 0; + while (closest_encloser != NULL && !closest_encloser->is_existing) + closest_encloser = closest_encloser->parent; + } /* * See RFC 4035 (DNSSEC protocol) section 3.1.4.1 Responding @@ -1214,6 +1232,9 @@ answer_lookup_zone(struct nsd *nsd, struct query *q, answer_type *answer, } else { q->delegation_domain = domain_find_ns_rrsets( closest_encloser, q->zone, &q->delegation_rrset); + if(q->delegation_domain && find_dname_above(q->delegation_domain, q->zone)) { + q->delegation_domain = NULL; /* use higher DNAME */ + } if (!q->delegation_domain || (exact && q->qtype == TYPE_DS && closest_encloser == q->delegation_domain)) @@ -1244,15 +1265,6 @@ answer_query(struct nsd *nsd, struct query *q) answer_init(&answer); exact = namedb_lookup(nsd->db, q->qname, &closest_match, &closest_encloser); - if (!closest_encloser->is_existing) { - exact = 0; - while (closest_encloser != NULL && !closest_encloser->is_existing) - closest_encloser = closest_encloser->parent; - } - if(!closest_encloser) { - RCODE_SET(q->packet, RCODE_SERVFAIL); - return; - } answer_lookup_zone(nsd, q, &answer, 0, exact, closest_match, closest_encloser, q->qname); diff --git a/usr.sbin/nsd/rrl.c b/usr.sbin/nsd/rrl.c index 8358ea57d70..2a7ca4f05b7 100644 --- a/usr.sbin/nsd/rrl.c +++ b/usr.sbin/nsd/rrl.c @@ -449,7 +449,9 @@ int rrl_process_query(query_type* query) query_state_type rrl_slip(query_type* query) { /* discard number the packets, randomly */ -#ifdef HAVE_ARC4RANDOM +#ifdef HAVE_ARC4RANDOM_UNIFORM + if((rrl_slip_ratio > 0) && ((rrl_slip_ratio == 1) || ((arc4random_uniform(rrl_slip_ratio)) == 0))) { +#elif HAVE_ARC4RANDOM if((rrl_slip_ratio > 0) && ((rrl_slip_ratio == 1) || ((arc4random() % rrl_slip_ratio) == 0))) { #else if((rrl_slip_ratio > 0) && ((rrl_slip_ratio == 1) || ((random() % rrl_slip_ratio) == 0))) { diff --git a/usr.sbin/nsd/server.c b/usr.sbin/nsd/server.c index 2b3be10618f..530b443de8c 100644 --- a/usr.sbin/nsd/server.c +++ b/usr.sbin/nsd/server.c @@ -560,7 +560,7 @@ server_init_ifs(struct nsd *nsd, size_t from, size_t to, int* reuseport_works) { struct addrinfo* addr; size_t i; -#if defined(SO_REUSEPORT) || defined(SO_REUSEADDR) || (defined(INET6) && (defined(IPV6_V6ONLY) || defined(IPV6_USE_MIN_MTU) || defined(IPV6_MTU) || defined(IP_TRANSPARENT))) +#if defined(SO_REUSEPORT) || defined(SO_REUSEADDR) || (defined(INET6) && (defined(IPV6_V6ONLY) || defined(IPV6_USE_MIN_MTU) || defined(IPV6_MTU) || defined(IP_TRANSPARENT)) || defined(IP_FREEBIND)) int on = 1; #endif @@ -734,6 +734,15 @@ server_init_ifs(struct nsd *nsd, size_t from, size_t to, int* reuseport_works) } /* Bind it... */ + if (nsd->options->ip_freebind) { +#ifdef IP_FREEBIND + if (setsockopt(nsd->udp[i].s, IPPROTO_IP, IP_FREEBIND, &on, sizeof(on)) < 0) { + log_msg(LOG_ERR, "setsockopt(...,IP_FREEBIND, ...) failed for udp: %s", + strerror(errno)); + } +#endif /* IP_FREEBIND */ + } + if (nsd->options->ip_transparent) { #ifdef IP_TRANSPARENT if (setsockopt(nsd->udp[i].s, IPPROTO_IP, IP_TRANSPARENT, &on, sizeof(on)) < 0) { @@ -832,6 +841,21 @@ server_init_ifs(struct nsd *nsd, size_t from, size_t to, int* reuseport_works) # endif } #endif + /* set maximum segment size to tcp socket */ + if(nsd->tcp_mss > 0) { +#if defined(IPPROTO_TCP) && defined(TCP_MAXSEG) + if(setsockopt(nsd->tcp[i].s, IPPROTO_TCP, TCP_MAXSEG, + (void*)&nsd->tcp_mss, + sizeof(nsd->tcp_mss)) < 0) { + log_msg(LOG_ERR, + "setsockopt(...,TCP_MAXSEG,...)" + " failed for tcp: %s", strerror(errno)); + } +#else + log_msg(LOG_ERR, "setsockopt(TCP_MAXSEG) unsupported"); +#endif /* defined(IPPROTO_TCP) && defined(TCP_MAXSEG) */ + } + /* set it nonblocking */ /* (StevensUNP p463), if tcp listening socket is blocking, then it may block in accept, even if select() says readable. */ @@ -840,6 +864,15 @@ server_init_ifs(struct nsd *nsd, size_t from, size_t to, int* reuseport_works) } /* Bind it... */ + if (nsd->options->ip_freebind) { +#ifdef IP_FREEBIND + if (setsockopt(nsd->tcp[i].s, IPPROTO_IP, IP_FREEBIND, &on, sizeof(on)) < 0) { + log_msg(LOG_ERR, "setsockopt(...,IP_FREEBIND, ...) failed for tcp: %s", + strerror(errno)); + } +#endif /* IP_FREEBIND */ + } + if (nsd->options->ip_transparent) { #ifdef IP_TRANSPARENT if (setsockopt(nsd->tcp[i].s, IPPROTO_IP, IP_TRANSPARENT, &on, sizeof(on)) < 0) { @@ -2395,7 +2428,10 @@ cleanup_tcp_handler(struct tcp_handler_data* data) */ if (slowaccept || data->nsd->current_tcp_count == data->nsd->maximum_tcp_count) { configure_handler_event_types(EV_READ|EV_PERSIST); - slowaccept = 0; + if(slowaccept) { + event_del(&slowaccept_event); + slowaccept = 0; + } } --data->nsd->current_tcp_count; assert(data->nsd->current_tcp_count >= 0); diff --git a/usr.sbin/nsd/tsig-openssl.c b/usr.sbin/nsd/tsig-openssl.c index 1088573a048..62203dc3525 100644 --- a/usr.sbin/nsd/tsig-openssl.c +++ b/usr.sbin/nsd/tsig-openssl.c @@ -83,16 +83,28 @@ static void cleanup_context(void *data) { HMAC_CTX *context = (HMAC_CTX *) data; +#ifdef HAVE_HMAC_CTX_NEW + HMAC_CTX_free(context); +#else HMAC_CTX_cleanup(context); + free(context); +#endif } static void * create_context(region_type *region) { - HMAC_CTX *context - = (HMAC_CTX *) region_alloc(region, sizeof(HMAC_CTX)); +#ifdef HAVE_HMAC_CTX_NEW + HMAC_CTX *context = HMAC_CTX_new(); +#else + HMAC_CTX *context = (HMAC_CTX *) malloc(sizeof(HMAC_CTX)); +#endif region_add_cleanup(region, cleanup_context, context); +#ifdef HAVE_HMAC_CTX_RESET + HMAC_CTX_reset(context); +#else HMAC_CTX_init(context); +#endif return context; } diff --git a/usr.sbin/nsd/udb.h b/usr.sbin/nsd/udb.h index 049760dd961..4cbe4031880 100644 --- a/usr.sbin/nsd/udb.h +++ b/usr.sbin/nsd/udb.h @@ -342,7 +342,7 @@ struct udb_alloc { /** magic string that starts an UDB file, uint64_t, note first byte=0, to mark * header start as a chunk. */ #define UDB_MAGIC (((uint64_t)'u'<<48)|((uint64_t)'d'<<40)|((uint64_t)'b' \ - <<32)|((uint64_t)'v'<<24)|((uint64_t)'0'<<16)|((uint64_t)'a'<<8)) + <<32)|((uint64_t)'v'<<24)|((uint64_t)'0'<<16)|((uint64_t)'b'<<8)) /* UDB BASE */ /** diff --git a/usr.sbin/nsd/udbzone.c b/usr.sbin/nsd/udbzone.c index 67de2db94d1..30f1c4beb61 100644 --- a/usr.sbin/nsd/udbzone.c +++ b/usr.sbin/nsd/udbzone.c @@ -95,6 +95,7 @@ udb_zone_create(udb_base* udb, udb_ptr* result, const uint8_t* dname, ZONE(&z)->rr_count = 0; ZONE(&z)->expired = 0; ZONE(&z)->mtime = 0; + ZONE(&z)->mtime_nsec = 0; ZONE(&z)->namelen = dlen; memmove(ZONE(&z)->name, dname, dlen); if(!udb_radix_tree_create(udb, &dtree)) { @@ -222,6 +223,7 @@ udb_zone_clear(udb_base* udb, udb_ptr* zone) ZONE(zone)->rr_count = 0; ZONE(zone)->expired = 0; ZONE(zone)->mtime = 0; + ZONE(zone)->mtime_nsec = 0; udb_ptr_unlink(&dtree, udb); } @@ -255,15 +257,18 @@ udb_zone_search(udb_base* udb, udb_ptr* result, const uint8_t* dname, return 0; } -uint64_t udb_zone_get_mtime(udb_base* udb, const uint8_t* dname, size_t dlen) +void udb_zone_get_mtime(udb_base* udb, const uint8_t* dname, size_t dlen, + struct timespec* mtime) { udb_ptr z; if(udb_zone_search(udb, &z, dname, dlen)) { - uint64_t t = ZONE(&z)->mtime; + mtime->tv_sec = ZONE(&z)->mtime; + mtime->tv_nsec = ZONE(&z)->mtime_nsec; udb_ptr_unlink(&z, udb); - return t; + return; } - return 0; + mtime->tv_sec = 0; + mtime->tv_nsec = 0; } void udb_zone_set_log_str(udb_base* udb, udb_ptr* zone, const char* str) diff --git a/usr.sbin/nsd/udbzone.h b/usr.sbin/nsd/udbzone.h index eb81675a18b..8169857a795 100644 --- a/usr.sbin/nsd/udbzone.h +++ b/usr.sbin/nsd/udbzone.h @@ -39,6 +39,8 @@ struct zone_d { udb_rel_ptr file_str; /** modification time, time when the zone data was changed */ uint64_t mtime; + /** modification time, nsecs */ + uint64_t mtime_nsec; /** number of RRsets in the zone */ uint64_t rrset_count; /** number of RRs in the zone */ @@ -107,7 +109,8 @@ void udb_zone_delete(udb_base* udb, udb_ptr* zone); int udb_zone_search(udb_base* udb, udb_ptr* result, const uint8_t* dname, size_t dlen); /** get modification time for zone or 0 */ -uint64_t udb_zone_get_mtime(udb_base* udb, const uint8_t* dname, size_t dlen); +void udb_zone_get_mtime(udb_base* udb, const uint8_t* dname, size_t dlen, + struct timespec* mtime); /** set log str in udb, or remove it */ void udb_zone_set_log_str(udb_base* udb, udb_ptr* zone, const char* str); /** set file str in udb, or remove it */ diff --git a/usr.sbin/nsd/util.c b/usr.sbin/nsd/util.c index ff54eda72b2..db3d7ceddce 100644 --- a/usr.sbin/nsd/util.c +++ b/usr.sbin/nsd/util.c @@ -393,6 +393,28 @@ write_socket(int s, const void *buf, size_t size) return 1; } +void get_time(struct timespec* t) +{ + struct timeval tv; +#ifdef HAVE_CLOCK_GETTIME + /* first try nanosecond precision */ + if(clock_gettime(CLOCK_REALTIME, t)>=0) { + return; /* success */ + } + log_msg(LOG_ERR, "clock_gettime: %s", strerror(errno)); +#endif + /* try millisecond precision */ + if(gettimeofday(&tv, NULL)>=0) { + t->tv_sec = tv.tv_sec; + t->tv_nsec = tv.tv_usec*1000; + return; /* success */ + } + log_msg(LOG_ERR, "gettimeofday: %s", strerror(errno)); + /* whole seconds precision */ + t->tv_sec = time(0); + t->tv_nsec = 0; +} + int timespec_compare(const struct timespec *left, const struct timespec *right) diff --git a/usr.sbin/nsd/util.h b/usr.sbin/nsd/util.h index 5c572e3e107..702674fc411 100644 --- a/usr.sbin/nsd/util.h +++ b/usr.sbin/nsd/util.h @@ -269,6 +269,8 @@ timeval_to_timespec(struct timespec *left, left->tv_nsec = 1000 * right->tv_usec; } +/* get the time */ +void get_time(struct timespec* t); /* * Converts a string representation of a period of time into diff --git a/usr.sbin/nsd/xfrd-tcp.c b/usr.sbin/nsd/xfrd-tcp.c index 2949e5a4d0b..9bc01d3ed72 100644 --- a/usr.sbin/nsd/xfrd-tcp.c +++ b/usr.sbin/nsd/xfrd-tcp.c @@ -13,6 +13,7 @@ #include #include #include +#include "nsd.h" #include "xfrd-tcp.h" #include "buffer.h" #include "packet.h" @@ -524,6 +525,19 @@ xfrd_tcp_open(xfrd_tcp_set_t* set, struct xfrd_tcp_pipeline* tp, return 0; } + if(xfrd->nsd->outgoing_tcp_mss > 0) { +#if defined(IPPROTO_TCP) && defined(TCP_MAXSEG) + if(setsockopt(fd, IPPROTO_TCP, TCP_MAXSEG, + (void*)&xfrd->nsd->outgoing_tcp_mss, + sizeof(xfrd->nsd->outgoing_tcp_mss)) < 0) { + log_msg(LOG_ERR, "xfrd: setsockopt(TCP_MAXSEG)" + "failed: %s", strerror(errno)); + } +#else + log_msg(LOG_ERR, "setsockopt(TCP_MAXSEG) unsupported"); +#endif + } + tp->ip_len = xfrd_acl_sockaddr_to(zone->master, &tp->ip); /* bind it */ diff --git a/usr.sbin/nsd/xfrd.c b/usr.sbin/nsd/xfrd.c index 0413f4e3ab4..c2c75eda4df 100644 --- a/usr.sbin/nsd/xfrd.c +++ b/usr.sbin/nsd/xfrd.c @@ -724,9 +724,12 @@ xfrd_set_timer_retry(xfrd_zone_t* zone) /* if no information, use reasonable timeout */ if(zone->fresh_xfr_timeout == 0) zone->fresh_xfr_timeout = XFRD_TRANSFER_TIMEOUT_START; -#ifdef HAVE_ARC4RANDOM +#ifdef HAVE_ARC4RANDOM_UNIFORM xfrd_set_timer(zone, zone->fresh_xfr_timeout - + arc4random()%zone->fresh_xfr_timeout); + + arc4random_uniform(zone->fresh_xfr_timeout)); +#elif HAVE_ARC4RANDOM + xfrd_set_timer(zone, zone->fresh_xfr_timeout + + arc4random() % zone->fresh_xfr_timeout); #else xfrd_set_timer(zone, zone->fresh_xfr_timeout + random()%zone->fresh_xfr_timeout); @@ -1045,8 +1048,10 @@ xfrd_set_timer(xfrd_zone_t* zone, time_t t) /* only for times far in the future */ if(t > 10) { time_t base = t*9/10; -#ifdef HAVE_ARC4RANDOM - t = base + arc4random()%(t-base); +#ifdef HAVE_ARC4RANDOM_UNIFORM + t = base + arc4random_uniform(t-base); +#elif HAVE_ARC4RANDOM + t = base + arc4random() % (t-base); #else t = base + random()%(t-base); #endif diff --git a/usr.sbin/nsd/zparser.y b/usr.sbin/nsd/zparser.y index 664040071d1..d82347893bc 100644 --- a/usr.sbin/nsd/zparser.y +++ b/usr.sbin/nsd/zparser.y @@ -68,6 +68,7 @@ nsec3_add_params(const char* hash_algo_str, const char* flag_str, %token T_AXFR T_MAILB T_MAILA T_DS T_DLV T_SSHFP T_RRSIG T_NSEC T_DNSKEY %token T_SPF T_NSEC3 T_IPSECKEY T_DHCID T_NSEC3PARAM T_TLSA T_URI %token T_NID T_L32 T_L64 T_LP T_EUI48 T_EUI64 T_CAA T_CDS T_CDNSKEY +%token T_CSYNC /* other tokens */ %token DOLLAR_TTL DOLLAR_ORIGIN NL SP @@ -632,6 +633,8 @@ type_and_rdata: | T_CDS sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } | T_CDNSKEY sp rdata_dnskey | T_CDNSKEY sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_CSYNC sp rdata_csync + | T_CSYNC sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } | T_URI sp rdata_uri | T_URI sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } | T_UTYPE sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } @@ -1050,6 +1053,17 @@ rdata_caa: STR sp STR sp STR trail } ; +/* RFC7477 */ +rdata_csync: STR sp STR nsec_seq + { + zadd_rdata_wireformat(zparser_conv_serial(parser->region, $1.str)); + zadd_rdata_wireformat(zparser_conv_short(parser->region, $3.str)); + zadd_rdata_wireformat(zparser_conv_nsec(parser->region, nsecbits)); /* nsec bitlist */ + memset(nsecbits, 0, sizeof(nsecbits)); + nsec_highest_rcode = 0; + } + ; + rdata_unknown: URR sp STR sp str_sp_seq trail { /* $2 is the number of octets, currently ignored */ -- 2.20.1