Lightly tested, I will test AXFR with tsig tomorrow.
tests / OKs?
diff --git Makefile.in Makefile.in
index 9103291..3fbd01b 100644
--- Makefile.in
+++ 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 acx_nlnetlabs.m4 acx_nlnetlabs.m4
index 26513e4..a6c174f 100644
--- acx_nlnetlabs.m4
+++ 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 <stdlib.h>
@@ -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 <stdlib.h>
@@ -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 <ctype.h>
@@ -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 answer.c answer.c
index be43c4c..c7b86fb 100644
--- answer.c
+++ 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 axfr.c axfr.c
index f7e0caa..09eb082 100644
--- axfr.c
+++ 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 config.h.in config.h.in
index 2a2e5b6..8a3f47f 100644
--- config.h.in
+++ config.h.in
@@ -58,6 +58,9 @@
/* Define to 1 if you have the `chroot' function. */
#undef HAVE_CHROOT
+/* Define to 1 if you have the `clock_gettime' function. */
+#undef HAVE_CLOCK_GETTIME
+
/* if time.h provides ctime_r prototype */
#undef HAVE_CTIME_R_PROTO
@@ -127,6 +130,12 @@
/* Define to 1 if you have the <grp.h> header file. */
#undef HAVE_GRP_H
+/* Define to 1 if you have the `HMAC_CTX_new' function. */
+#undef HAVE_HMAC_CTX_NEW
+
+/* Define to 1 if you have the `HMAC_CTX_reset' function. */
+#undef HAVE_HMAC_CTX_RESET
+
/* Define to 1 if you have the `inet_aton' function. */
#undef HAVE_INET_ATON
@@ -179,6 +188,9 @@
/* Define to 1 if you have the <netinet/in.h> header file. */
#undef HAVE_NETINET_IN_H
+/* Define to 1 if you have the <netinet/tcp.h> header file. */
+#undef HAVE_NETINET_TCP_H
+
/* Define to 1 if you have the <openssl/err.h> header file. */
#undef HAVE_OPENSSL_ERR_H
@@ -290,6 +302,12 @@
/* Define to 1 if you have the `strtol' function. */
#undef HAVE_STRTOL
+/* Define to 1 if `st_mtimensec' is a member of `struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_MTIMENSEC
+
+/* Define to 1 if `st_mtim.tv_nsec' is a member of `struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
+
/* If time.h has a struct timespec (for pselect). */
#undef HAVE_STRUCT_TIMESPEC
@@ -625,6 +643,9 @@
# ifndef _BSD_SOURCE
# define _BSD_SOURCE 1
# endif
+# ifndef _DEFAULT_SOURCE
+# define _DEFAULT_SOURCE 1
+# endif
# ifndef __EXTENSIONS__
# define __EXTENSIONS__ 1
# endif
@@ -669,6 +690,10 @@
#include <netinet/in.h>
#endif
+#ifdef HAVE_NETINET_TCP_H
+#include <netinet/tcp.h>
+#endif
+
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
diff --git configlexer.lex configlexer.lex
index 20304b7..113fa22 100644
--- configlexer.lex
+++ 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 configparser.y configparser.y
index 36a3ddd..1d824d1 100644
--- configparser.y
+++ 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 configure configure
index 68bdc87..a525e08 100644
--- configure
+++ configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for NSD 4.1.7.
+# Generated by GNU Autoconf 2.69 for NSD 4.1.10.
#
# Report bugs to <[email protected]>.
#
@@ -580,8 +580,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='NSD'
PACKAGE_TARNAME='nsd'
-PACKAGE_VERSION='4.1.7'
-PACKAGE_STRING='NSD 4.1.7'
+PACKAGE_VERSION='4.1.10'
+PACKAGE_STRING='NSD 4.1.10'
PACKAGE_BUGREPORT='[email protected]'
PACKAGE_URL=''
@@ -1283,7 +1283,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.7 to adapt to many kinds of systems.
+\`configure' configures NSD 4.1.10 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1344,7 +1344,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of NSD 4.1.7:";;
+ short | recursive ) echo "Configuration of NSD 4.1.10:";;
esac
cat <<\_ACEOF
@@ -1360,7 +1360,7 @@ Optional Features:
--disable-largefile omit support for large files
--enable-recvmmsg Enable recvmmsg and sendmmsg compilation, faster but
some kernel versions may have implementation
- problems
+ problems for IPv6
--enable-root-server Configure NSD as a root server
--disable-ipv6 Disables IPv6 support
--enable-bind8-stats Enables BIND8 like NSTATS & XSTATS and statistics in
@@ -1487,7 +1487,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-NSD configure 4.1.7
+NSD configure 4.1.10
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2196,7 +2196,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.7, which was
+It was created by NSD $as_me 4.1.10, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -5067,7 +5067,7 @@ main ()
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
- 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"
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
@@ -6027,7 +6027,7 @@ $as_echo "#define HAVE_SYS_WAIT_H 1" >>confdefs.h
fi
-for ac_header in 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
+for ac_header in 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
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header"
"$ac_includes_default"
@@ -7195,6 +7195,25 @@ fi
fi
+ac_fn_c_check_member "$LINENO" "struct stat" "st_mtimensec"
"ac_cv_member_struct_stat_st_mtimensec" "$ac_includes_default"
+if test "x$ac_cv_member_struct_stat_st_mtimensec" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_STAT_ST_MTIMENSEC 1
+_ACEOF
+
+
+fi
+ac_fn_c_check_member "$LINENO" "struct stat" "st_mtim.tv_nsec"
"ac_cv_member_struct_stat_st_mtim_tv_nsec" "$ac_includes_default"
+if test "x$ac_cv_member_struct_stat_st_mtim_tv_nsec" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC 1
+_ACEOF
+
+
+fi
+
# Checks for library functions.
for ac_header in unistd.h
@@ -7921,7 +7940,7 @@ _ACEOF
fi
done
-for ac_func in 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
+for ac_func in 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
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"
@@ -8803,10 +8822,74 @@ fi
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
+
+ # Check for -pthread
+ BAKLIBS="$LIBS"
+ LIBS="-lcrypto $LIBS"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ int HMAC_Update(void);
+ (void)HMAC_Update();
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+else
+
+ BAKCFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -pthread"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libcrypto
needs -pthread" >&5
+$as_echo_n "checking if libcrypto needs -pthread... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char HMAC_Update ();
+int
+main ()
+{
+return HMAC_Update ();
+ ;
+ 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; }
+
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ CFLAGS="$BAKCFLAGS"
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LIBS="$BAKLIBS"
+
if test -n "$ssldir"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for
HMAC_CTX_init in -lcrypto" >&5
-$as_echo_n "checking for HMAC_CTX_init in -lcrypto... " >&6; }
-if ${ac_cv_lib_crypto_HMAC_CTX_init+:} false; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for HMAC_Update
in -lcrypto" >&5
+$as_echo_n "checking for HMAC_Update in -lcrypto... " >&6; }
+if ${ac_cv_lib_crypto_HMAC_Update+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
@@ -8820,27 +8903,27 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
#ifdef __cplusplus
extern "C"
#endif
-char HMAC_CTX_init ();
+char HMAC_Update ();
int
main ()
{
-return HMAC_CTX_init ();
+return HMAC_Update ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_crypto_HMAC_CTX_init=yes
+ ac_cv_lib_crypto_HMAC_Update=yes
else
- ac_cv_lib_crypto_HMAC_CTX_init=no
+ ac_cv_lib_crypto_HMAC_Update=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result:
$ac_cv_lib_crypto_HMAC_CTX_init" >&5
-$as_echo "$ac_cv_lib_crypto_HMAC_CTX_init" >&6; }
-if test "x$ac_cv_lib_crypto_HMAC_CTX_init" = xyes; then :
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result:
$ac_cv_lib_crypto_HMAC_Update" >&5
+$as_echo "$ac_cv_lib_crypto_HMAC_Update" >&6; }
+if test "x$ac_cv_lib_crypto_HMAC_Update" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_LIBCRYPTO 1
_ACEOF
@@ -8895,6 +8978,18 @@ fi
done
+ for ac_func in HMAC_CTX_reset HMAC_CTX_new
+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"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+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;}
@@ -9586,7 +9681,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.7, which was
+This file was extended by NSD $as_me 4.1.10, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -9648,7 +9743,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.7
+NSD config.status 4.1.10
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git configure.ac configure.ac
index c04deac..4c451bd 100644
--- configure.ac
+++ configure.ac
@@ -4,7 +4,7 @@ dnl
sinclude(acx_nlnetlabs.m4)
-AC_INIT(NSD,4.1.7,[email protected])
+AC_INIT(NSD,4.1.10,[email protected])
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 <netinet/in.h>
#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 <netinet/in.h>
#endif
+#ifdef HAVE_NETINET_TCP_H
+#include <netinet/tcp.h>
+#endif
+
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
diff --git dbaccess.c dbaccess.c
index 86891f2..cc49a51 100644
--- dbaccess.c
+++ 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 dbcreate.c dbcreate.c
index 24866af..ce21491 100644
--- dbcreate.c
+++ 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 difffile.c difffile.c
index 4196f79..b2325c5 100644
--- difffile.c
+++ 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 dns.c dns.c
index 2ba99d3..037cd4c 100644
--- dns.c
+++ 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 dns.h dns.h
index 3e9e88c..810cd70 100644
--- dns.h
+++ 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 namedb.c namedb.c
index 96aec38..db90965 100644
--- namedb.c
+++ 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 namedb.h namedb.h
index d264c68..ca46477 100644
--- namedb.h
+++ 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 nsd-4.1.10.tar.gz nsd-4.1.10.tar.gz
new file mode 100644
index 0000000..53f0de4
Binary files /dev/null and nsd-4.1.10.tar.gz differ
diff --git nsd-checkconf.8.in nsd-checkconf.8.in
index 9bf8306..2425e69 100644
--- nsd-checkconf.8.in
+++ 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 nsd-checkconf.c nsd-checkconf.c
index 6cbe71e..e5f669f 100644
--- nsd-checkconf.c
+++ 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 nsd-checkzone.8.in nsd-checkzone.8.in
index f58e0da..2be9443 100644
--- nsd-checkzone.8.in
+++ 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 nsd-control.8.in nsd-control.8.in
index 4f6a590..bf8d90d 100644
--- nsd-control.8.in
+++ 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 nsd.8.in nsd.8.in
index 0ef0cfa..89afd9c 100644
--- nsd.8.in
+++ 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 nsd.c nsd.c
index 3f35f11..f964386 100644
--- nsd.c
+++ 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 nsd.conf.5.in nsd.conf.5.in
index 2fe1bf4..44493c7 100644
--- nsd.conf.5.in
+++ 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 <yes or no>
+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 <yes or no>
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 <filename>
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 <number>
Overrides the default TCP timeout. This also affects zone transfers over TCP.
.TP
+.B tcp-mss:\fR <number>
+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 <number>
+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 <number>
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 nsd.conf.sample.in nsd.conf.sample.in
index a78548e..48eef14 100644
--- nsd.conf.sample.in
+++ 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 nsd.h nsd.h
index 8ebf1a2..290b065 100644
--- nsd.h
+++ 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 nsec3.c nsec3.c
index 92802bd..d4fd1a2 100644
--- nsec3.c
+++ 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 options.c options.c
index 8896851..349e271 100644
--- options.c
+++ 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 options.h options.h
index 34ed295..ceba624 100644
--- options.h
+++ 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 query.c query.c
index 4f26112..f8a429c 100644
--- query.c
+++ 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 rrl.c rrl.c
index 8358ea5..2a7ca4f 100644
--- rrl.c
+++ 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 server.c server.c
index 2b3be10..530b443 100644
--- server.c
+++ 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 tsig-openssl.c tsig-openssl.c
index 1088573..62203dc 100644
--- tsig-openssl.c
+++ 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 udb.h udb.h
index 049760d..4cbe403 100644
--- udb.h
+++ 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 udbzone.c udbzone.c
index 67de2db..30f1c4b 100644
--- udbzone.c
+++ 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 udbzone.h udbzone.h
index eb81675..8169857 100644
--- udbzone.h
+++ 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 util.c util.c
index ff54eda..db3d7ce 100644
--- util.c
+++ 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 util.h util.h
index 5c572e3..702674f 100644
--- util.h
+++ 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 xfrd-tcp.c xfrd-tcp.c
index 2949e5a..9bc01d3 100644
--- xfrd-tcp.c
+++ xfrd-tcp.c
@@ -13,6 +13,7 @@
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
+#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 xfrd.c xfrd.c
index 0413f4e..c2c75ed 100644
--- xfrd.c
+++ 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 zparser.y zparser.y
index 6640400..d823478 100644
--- zparser.y
+++ zparser.y
@@ -68,6 +68,7 @@ nsec3_add_params(const char* hash_algo_str, const char*
flag_str,
%token <type> T_AXFR T_MAILB T_MAILA T_DS T_DLV T_SSHFP T_RRSIG T_NSEC T_DNSKEY
%token <type> T_SPF T_NSEC3 T_IPSECKEY T_DHCID T_NSEC3PARAM T_TLSA T_URI
%token <type> T_NID T_L32 T_L64 T_LP T_EUI48 T_EUI64 T_CAA T_CDS T_CDNSKEY
+%token <type> 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 */
--
I'm not entirely sure you are real.