-e 's,@nsdconfigfile\@,$(nsdconfigfile),g' \
-e 's,@shell\@,$(SHELL),g' \
-e 's,@ratelimit_default\@,@ratelimit_default@,g' \
+ -e 's,@dnstap_socket_path\@,@opt_dnstap_socket_path@,g' \
-e 's,@user\@,$(user),g'
TARGETS=nsd nsd-checkconf nsd-checkzone nsd-control nsd.conf.sample nsd-control-setup.sh
configlexer.c: $(srcdir)/configlexer.lex
if test "$(LEX)" != ":"; then rm -f $@ ;\
- echo '#include "configyyrename.h"' > $@ ;\
- $(LEX) -i -t $(srcdir)/configlexer.lex >> $@ ;\
+ echo '#include "config.h"' > $@ ;\
+ $(LEX) -P c_ -i -t $(srcdir)/configlexer.lex >> $@ ;\
fi
@if test ! -f $@; then echo "No $@ : need flex and bison to compile from source repository"; exit 1; fi
configparser.c configparser.h: $(srcdir)/configparser.y
- $(YACC) -d -o configparser.c $(srcdir)/configparser.y
+ $(YACC) -d -p c_ -o configparser.c $(srcdir)/configparser.y
# dnstap
dnstap.o: $(srcdir)/dnstap/dnstap.c config.h dnstap/dnstap_config.h \
$(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/query.h $(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/radtree.h $(srcdir)/rbtree.h \
$(srcdir)/packet.h $(srcdir)/tsig.h $(srcdir)/options.h
buffer.o: $(srcdir)/buffer.c config.h $(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/util.h
-configlexer.o: configlexer.c $(srcdir)/configyyrename.h config.h $(srcdir)/options.h \
+configlexer.o: configlexer.c config.h $(srcdir)/options.h \
$(srcdir)/region-allocator.h $(srcdir)/rbtree.h configparser.h
configparser.o: configparser.c config.h $(srcdir)/options.h $(srcdir)/region-allocator.h \
$(srcdir)/rbtree.h $(srcdir)/util.h $(srcdir)/dname.h $(srcdir)/buffer.h $(srcdir)/tsig.h $(srcdir)/rrl.h $(srcdir)/query.h $(srcdir)/namedb.h $(srcdir)/dns.h \
- $(srcdir)/radtree.h $(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/packet.h $(srcdir)/configyyrename.h
+ $(srcdir)/radtree.h $(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/packet.h
dbaccess.o: $(srcdir)/dbaccess.c config.h $(srcdir)/dns.h $(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/buffer.h \
$(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/radtree.h $(srcdir)/rbtree.h $(srcdir)/options.h $(srcdir)/rdata.h $(srcdir)/udb.h \
$(srcdir)/udbradtree.h $(srcdir)/udbzone.h $(srcdir)/zonec.h $(srcdir)/nsec3.h $(srcdir)/difffile.h $(srcdir)/nsd.h $(srcdir)/edns.h
$(srcdir)/answer.h $(srcdir)/packet.h $(srcdir)/query.h $(srcdir)/tsig.h $(srcdir)/udbzone.h $(srcdir)/udb.h $(srcdir)/udbradtree.h $(srcdir)/options.h
options.o: $(srcdir)/options.c config.h $(srcdir)/options.h $(srcdir)/region-allocator.h $(srcdir)/rbtree.h \
$(srcdir)/query.h $(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/buffer.h $(srcdir)/util.h $(srcdir)/dns.h $(srcdir)/radtree.h $(srcdir)/nsd.h $(srcdir)/edns.h \
- $(srcdir)/packet.h $(srcdir)/tsig.h $(srcdir)/difffile.h $(srcdir)/udb.h $(srcdir)/rrl.h $(srcdir)/configyyrename.h configparser.h
+ $(srcdir)/packet.h $(srcdir)/tsig.h $(srcdir)/difffile.h $(srcdir)/udb.h $(srcdir)/rrl.h configparser.h
packet.o: $(srcdir)/packet.c config.h $(srcdir)/packet.h $(srcdir)/dns.h $(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/buffer.h \
$(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/radtree.h $(srcdir)/rbtree.h $(srcdir)/query.h $(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/tsig.h \
$(srcdir)/rdata.h
# Copyright 2009, Wouter Wijngaards, NLnet Labs.
# BSD licensed.
#
-# Version 35
+# Version 38
+# 2021-03-24 fix ACX_FUNC_DEPRECATED to use CPPFLAGS and CFLAGS.
+# 2021-01-05 fix defun for aclocal
+# 2021-01-05 autoconf 2.70 autoupdate and fixes, no AC_TRY_COMPILE
# 2020-08-24 Use EVP_sha256 instead of HMAC_Update (for openssl-3.0.0).
# 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).
AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "format" attribute)
AC_CACHE_VAL(ac_cv_c_format_attribute,
[ac_cv_c_format_attribute=no
-AC_TRY_COMPILE(
-[#include <stdio.h>
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdio.h>
void f (char *format, ...) __attribute__ ((format (printf, 1, 2)));
void (*pf) (char *format, ...) __attribute__ ((format (printf, 1, 2)));
-], [
+]], [[
f ("%s", "str");
-],
-[ac_cv_c_format_attribute="yes"],
-[ac_cv_c_format_attribute="no"])
+]])],[ac_cv_c_format_attribute="yes"],[ac_cv_c_format_attribute="no"])
])
AC_MSG_RESULT($ac_cv_c_format_attribute)
AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "unused" attribute)
AC_CACHE_VAL(ac_cv_c_unused_attribute,
[ac_cv_c_unused_attribute=no
-AC_TRY_COMPILE(
-[#include <stdio.h>
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdio.h>
void f (char *u __attribute__((unused)));
-], [
+]], [[
f ("x");
-],
-[ac_cv_c_unused_attribute="yes"],
-[ac_cv_c_unused_attribute="no"])
+]])],[ac_cv_c_unused_attribute="yes"],[ac_cv_c_unused_attribute="no"])
])
dnl Setup ATTR_UNUSED config.h parts.
dnl because libtools 'AC_REQUIRE' names are right after this one, before
dnl this function contents.
AC_REQUIRE([ACX_LIBTOOL_C_PRE])
-AC_PROG_LIBTOOL
+LT_INIT
])
dnl Detect if u_char type is defined, otherwise define it.
AC_MSG_CHECKING([for EVP_sha256 in -lcrypto])
LIBS="$LIBS -lcrypto"
LIBSSL_LIBS="$LIBSSL_LIBS -lcrypto"
- AC_TRY_LINK(, [
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
int EVP_sha256(void);
(void)EVP_sha256();
- ], [
+ ]])],[
AC_MSG_RESULT(yes)
AC_DEFINE([HAVE_EVP_SHA256], 1,
[If you have EVP_sha256])
- ], [
+ ],[
AC_MSG_RESULT(no)
# check if -lwsock32 or -lgdi32 are needed.
BAKLIBS="$LIBS"
LIBS="$LIBS -lgdi32 -lws2_32"
LIBSSL_LIBS="$LIBSSL_LIBS -lgdi32 -lws2_32"
AC_MSG_CHECKING([if -lcrypto needs -lgdi32])
- AC_TRY_LINK([], [
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
int EVP_sha256(void);
(void)EVP_sha256();
- ],[
+ ]])],[
AC_DEFINE([HAVE_EVP_SHA256], 1,
[If you have EVP_sha256])
AC_MSG_RESULT(yes)
LIBS="$LIBS -ldl"
LIBSSL_LIBS="$LIBSSL_LIBS -ldl"
AC_MSG_CHECKING([if -lcrypto needs -ldl])
- AC_TRY_LINK([], [
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
int EVP_sha256(void);
(void)EVP_sha256();
- ],[
+ ]])],[
AC_DEFINE([HAVE_EVP_SHA256], 1,
[If you have EVP_sha256])
AC_MSG_RESULT(yes)
LIBS="$LIBS -ldl -pthread"
LIBSSL_LIBS="$LIBSSL_LIBS -ldl -pthread"
AC_MSG_CHECKING([if -lcrypto needs -ldl -pthread])
- AC_TRY_LINK([], [
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
int EVP_sha256(void);
(void)EVP_sha256();
- ],[
+ ]])],[
AC_DEFINE([HAVE_EVP_SHA256], 1,
[If you have EVP_sha256])
AC_MSG_RESULT(yes)
dnl
AC_DEFUN([ACX_WITH_SSL],
[
-AC_ARG_WITH(ssl, AC_HELP_STRING([--with-ssl=pathname],
- [enable SSL (will check /usr/local/ssl
+AC_ARG_WITH(ssl, AS_HELP_STRING([--with-ssl=pathname],[enable SSL (will check /usr/local/ssl
/usr/lib/ssl /usr/ssl /usr/pkg /usr/local /opt/local /usr/sfw /usr)]),[
],[
withval="yes"
dnl
AC_DEFUN([ACX_WITH_SSL_OPTIONAL],
[
-AC_ARG_WITH(ssl, AC_HELP_STRING([--with-ssl=pathname],
- [enable SSL (will check /usr/local/ssl
+AC_ARG_WITH(ssl, AS_HELP_STRING([--with-ssl=pathname],[enable SSL (will check /usr/local/ssl
/usr/lib/ssl /usr/ssl /usr/pkg /usr/local /opt/local /usr/sfw /usr)]),[
],[
withval="yes"
[
echo '$3' >conftest.c
echo 'void f(){ $2 }' >>conftest.c
-if test -z "`$CC -c conftest.c 2>&1 | grep deprecated`"; then
+if test -z "`$CC $CPPFLAGS $CFLAGS -c conftest.c 2>&1 | grep -e deprecated -e unavailable`"; then
eval "cv_cc_deprecated_$cache=no"
else
eval "cv_cc_deprecated_$cache=yes"
AC_DEFUN([ACX_MKDIR_ONE_ARG],
[
AC_MSG_CHECKING([whether mkdir has one arg])
-AC_TRY_COMPILE([
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <stdio.h>
#include <unistd.h>
#ifdef HAVE_WINSOCK2_H
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
-], [
+]], [[
(void)mkdir("directory");
-],
-AC_MSG_RESULT(yes)
+]])],[AC_MSG_RESULT(yes)
AC_DEFINE(MKDIR_HAS_ONE_ARG, 1, [Define if mkdir has one argument.])
-,
-AC_MSG_RESULT(no)
-)
+],[AC_MSG_RESULT(no)
+])
])dnl end of ACX_MKDIR_ONE_ARG
dnl Check for ioctlsocket function. works on mingw32 too.
RCODE_SET(q->packet, RCODE_NOTAUTH);
} else {
RCODE_SET(q->packet, RCODE_REFUSE);
+ /* RFC8914 - Extended DNS Errors
+ * 4.19. Extended DNS Error Code 18 - Prohibited */
+ q->edns.ede = EDE_PROHIBITED;
}
return QUERY_PROCESSED;
}
/* Define to 1 if you have the `HMAC_CTX_reset' function. */
#undef HAVE_HMAC_CTX_RESET
+/* Define to 1 if you have the <ifaddrs.h> header file. */
+#undef HAVE_IFADDRS_H
+
/* Define to 1 if you have the `inet_aton' function. */
#undef HAVE_INET_ATON
/* If reallocarray needs defines to appear in the headers */
#undef REALLOCARRAY_NEEDS_DEFINES
-/* Define as the return type of signal handlers (`int' or `void'). */
+/* Return type of signal handlers, but autoconf 2.70 says 'your code may
+ safely assume C89 semantics that RETSIGTYPE is void.' */
#undef RETSIGTYPE
/* Define this to configure as a root server. */
#include <sys/types.h>
-#if STDC_HEADERS
#include <stdlib.h>
#include <stddef.h>
-#endif
#ifdef HAVE_TIME_H
#include <time.h>
* See LICENSE for the license.
*
*/
-
-#include "config.h"
-
+/* because flex keeps having sign-unsigned compare problems that are unfixed*/
+#if defined(__clang__)||(defined(__GNUC__)&&((__GNUC__ >4)||(defined(__GNUC_MINOR__)&&(__GNUC__ ==4)&&(__GNUC_MINOR__ >=2))))
+#pragma GCC diagnostic ignored "-Wsign-compare"
+#endif
#include <ctype.h>
#include <errno.h>
#include <string.h>
#endif
#include "options.h"
-#include "configyyrename.h"
#include "configparser.h"
#if 0
struct inc_state* s;
char* nm;
if(inc_depth++ > 10000000) {
- yyerror("too many include files");
+ c_error("too many include files");
return;
}
if(strlen(filename) == 0) {
- yyerror("empty include file name");
+ c_error("empty include file name");
return;
}
s = (struct inc_state*)malloc(sizeof(*s));
if(!s) {
- yyerror("include %s: malloc failure", filename);
+ c_error("include %s: malloc failure", filename);
return;
}
nm = strdup(filename);
if(!nm) {
- yyerror("include %s: strdup failure", filename);
+ c_error("include %s: strdup failure", filename);
free(s);
return;
}
input = fopen(filename, "r");
if(!input) {
- yyerror("cannot open include file '%s': %s",
+ c_error("cannot open include file '%s': %s",
filename, strerror(errno));
free(s);
free(nm);
if (cfg_parser->chroot) {
int l = strlen(cfg_parser->chroot); /* chroot has trailing slash */
if (strncmp(cfg_parser->chroot, filename, l) != 0) {
- yyerror("include file '%s' is not relative to chroot '%s'",
+ c_error("include file '%s' is not relative to chroot '%s'",
filename, cfg_parser->chroot);
return;
}
notify{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_NOTIFY;}
notify-retry{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_NOTIFY_RETRY;}
provide-xfr{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_PROVIDE_XFR;}
+allow-query{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_ALLOW_QUERY;}
outgoing-interface{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_OUTGOING_INTERFACE;}
allow-axfr-fallback{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_ALLOW_AXFR_FALLBACK;}
key{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_KEY;}
while (*str != '\0' && (*str < '0' || *str > '9')) {
str++;
}
- yylval.llng = strtoll(str, NULL, 10);
+ c_lval.llng = strtoll(str, NULL, 10);
return VAR_SERVER_CPU_AFFINITY;
}
/* Quoted strings. Strip leading and ending quotes */
\" { BEGIN(quotedstring); LEXOUT(("QS ")); }
<quotedstring><<EOF>> {
- yyerror("EOF inside quoted string");
+ c_error("EOF inside quoted string");
BEGIN(INITIAL);
}
<quotedstring>{ANY}* { LEXOUT(("STR(%s) ", yytext)); yymore(); }
LEXOUT(("QE "));
BEGIN(INITIAL);
yytext[yyleng - 1] = '\0';
- yylval.str = region_strdup(cfg_parser->opt->region, yytext);
+ c_lval.str = region_strdup(cfg_parser->opt->region, yytext);
return STRING;
}
/* include: directive */
include{COLON} { LEXOUT(("v(%s) ", yytext)); BEGIN(include); }
<include><<EOF>> {
- yyerror("EOF inside include directive");
+ c_error("EOF inside include directive");
BEGIN(INITIAL);
}
<include>{SPACE}* { LEXOUT(("ISP ")); /* ignore */ }
BEGIN(INITIAL);
}
<include_quoted><<EOF>> {
- yyerror("EOF inside quoted string");
+ c_error("EOF inside quoted string");
BEGIN(INITIAL);
}
<include_quoted>{ANY}* { LEXOUT(("ISTR(%s) ", yytext)); yymore(); }
}
{UNQUOTEDLETTER}* { LEXOUT(("unquotedstr(%s) ", yytext));
- yylval.str = region_strdup(cfg_parser->opt->region, yytext); return STRING; }
+ c_lval.str = region_strdup(cfg_parser->opt->region, yytext); return STRING; }
%%
#include "dname.h"
#include "tsig.h"
#include "rrl.h"
-#include "configyyrename.h"
int yylex(void);
%token VAR_ZONEFILE
%token VAR_NOTIFY
%token VAR_PROVIDE_XFR
+%token VAR_ALLOW_QUERY
%token VAR_AXFR
%token VAR_UDP
%token VAR_NOTIFY_RETRY
acl_options_type *acl = parse_acl_info(cfg_parser->opt->region, $2, $3);
append_acl(&cfg_parser->pattern->provide_xfr, acl);
}
+ | VAR_ALLOW_QUERY STRING STRING
+ {
+ acl_options_type *acl = parse_acl_info(cfg_parser->opt->region, $2, $3);
+ append_acl(&cfg_parser->pattern->allow_query, acl);
+ }
| VAR_OUTGOING_INTERFACE STRING
{
acl_options_type *acl = parse_acl_info(cfg_parser->opt->region, $2, "NOKEY");
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for NSD 4.3.4.
+# Generated by GNU Autoconf 2.69 for NSD 4.3.6.
#
# Report bugs to <nsd-bugs@nlnetlabs.nl>.
#
# Identity of this package.
PACKAGE_NAME='NSD'
PACKAGE_TARNAME='nsd'
-PACKAGE_VERSION='4.3.4'
-PACKAGE_STRING='NSD 4.3.4'
+PACKAGE_VERSION='4.3.6'
+PACKAGE_STRING='NSD 4.3.6'
PACKAGE_BUGREPORT='nsd-bugs@nlnetlabs.nl'
PACKAGE_URL=''
# 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.3.4 to adapt to many kinds of systems.
+\`configure' configures NSD 4.3.6 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of NSD 4.3.4:";;
+ short | recursive ) echo "Configuration of NSD 4.3.6:";;
esac
cat <<\_ACEOF
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-NSD configure 4.3.4
+NSD configure 4.3.6
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
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.3.4, which was
+It was created by NSD $as_me 4.3.6, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
$as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h
-
if test "$ac_cv_header_minix_config_h" = "yes"; then
$as_echo "#define _NETBSD_SOURCE 1" >>confdefs.h
fi
# Checks for header files.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
-$as_echo_n "checking for ANSI C header files... " >&6; }
-if ${ac_cv_header_stdc+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <float.h>
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_header_stdc=yes
-else
- ac_cv_header_stdc=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-if test $ac_cv_header_stdc = yes; then
- # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <string.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "memchr" >/dev/null 2>&1; then :
-
-else
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <stdlib.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "free" >/dev/null 2>&1; then :
-
-else
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
- if test "$cross_compiling" = yes; then :
- :
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <ctype.h>
-#include <stdlib.h>
-#if ((' ' & 0x0FF) == 0x020)
-# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
-#else
-# define ISLOWER(c) \
- (('a' <= (c) && (c) <= 'i') \
- || ('j' <= (c) && (c) <= 'r') \
- || ('s' <= (c) && (c) <= 'z'))
-# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
-#endif
-
-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
-int
-main ()
-{
- int i;
- for (i = 0; i < 256; i++)
- if (XOR (islower (i), ISLOWER (i))
- || toupper (i) != TOUPPER (i))
- return 2;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
-
-else
- ac_cv_header_stdc=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
- conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
-fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
-$as_echo "$ac_cv_header_stdc" >&6; }
-if test $ac_cv_header_stdc = yes; then
-
-$as_echo "#define STDC_HEADERS 1" >>confdefs.h
-
-fi
-
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sys/wait.h that is POSIX.1 compatible" >&5
$as_echo_n "checking for sys/wait.h that is POSIX.1 compatible... " >&6; }
if ${ac_cv_header_sys_wait_h+:} false; then :
fi
-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 sys/un.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 sys/random.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 sys/un.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 sys/random.h ifaddrs.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"
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
/* end confdefs.h. */
#include <sys/types.h>
-#if STDC_HEADERS
#include <stdlib.h>
#include <stddef.h>
-#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
/* end confdefs.h. */
#include <sys/types.h>
-#if STDC_HEADERS
#include <stdlib.h>
#include <stddef.h>
-#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
/* end confdefs.h. */
#include <sys/types.h>
-#if STDC_HEADERS
#include <stdlib.h>
#include <stddef.h>
-#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
/* end confdefs.h. */
#include <sys/types.h>
-#if STDC_HEADERS
#include <stdlib.h>
#include <stddef.h>
-#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
/* end confdefs.h. */
#include <sys/types.h>
-#if STDC_HEADERS
#include <stdlib.h>
#include <stddef.h>
-#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
/* end confdefs.h. */
#include <sys/types.h>
-#if STDC_HEADERS
#include <stdlib.h>
#include <stddef.h>
-#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
/* end confdefs.h. */
#include <sys/types.h>
-#if STDC_HEADERS
#include <stdlib.h>
#include <stddef.h>
-#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
/* end confdefs.h. */
#include <sys/types.h>
-#if STDC_HEADERS
#include <stdlib.h>
#include <stddef.h>
-#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
/* end confdefs.h. */
#include <sys/types.h>
-#if STDC_HEADERS
#include <stdlib.h>
#include <stddef.h>
-#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
/* end confdefs.h. */
#include <sys/types.h>
-#if STDC_HEADERS
#include <stdlib.h>
#include <stddef.h>
-#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
/* end confdefs.h. */
#include <sys/types.h>
-#if STDC_HEADERS
#include <stdlib.h>
#include <stddef.h>
-#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
/* end confdefs.h. */
#include <sys/types.h>
-#if STDC_HEADERS
#include <stdlib.h>
#include <stddef.h>
-#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5
-$as_echo_n "checking return type of signal handlers... " >&6; }
-if ${ac_cv_type_signal+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <sys/types.h>
-#include <signal.h>
-
-int
-main ()
-{
-return *(signal (0, 0)) (0) == 1;
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_type_signal=int
-else
- ac_cv_type_signal=void
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_signal" >&5
-$as_echo "$ac_cv_type_signal" >&6; }
-
-cat >>confdefs.h <<_ACEOF
-#define RETSIGTYPE $ac_cv_type_signal
-_ACEOF
+$as_echo "#define RETSIGTYPE void" >>confdefs.h
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGEFILE_SOURCE value needed for large files" >&5
$as_echo_n "checking for _LARGEFILE_SOURCE value needed for large files... " >&6; }
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
for ac_header in login_cap.h
do :
- ac_fn_c_check_header_mongrel "$LINENO" "login_cap.h" "ac_cv_header_login_cap_h" "$ac_includes_default"
+ ac_fn_c_check_header_compile "$LINENO" "login_cap.h" "ac_cv_header_login_cap_h" "$ac_includes_default
+"
if test "x$ac_cv_header_login_cap_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_LOGIN_CAP_H 1
for ac_header in sched.h sys/cpuset.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"
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
yes)
for ac_header in sys/mman.h
do :
- ac_fn_c_check_header_mongrel "$LINENO" "sys/mman.h" "ac_cv_header_sys_mman_h" "$ac_includes_default"
+ ac_fn_c_check_header_compile "$LINENO" "sys/mman.h" "ac_cv_header_sys_mman_h" "$ac_includes_default
+"
if test "x$ac_cv_header_sys_mman_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_SYS_MMAN_H 1
/* end confdefs.h. */
#include <sys/types.h>
-#if STDC_HEADERS
#include <stdlib.h>
#include <stddef.h>
-#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
# 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.3.4, which was
+This file was extended by NSD $as_me 4.3.6, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
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.3.4
+NSD config.status 4.3.6
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
sinclude(acx_nlnetlabs.m4)
sinclude(dnstap/dnstap.m4)
-AC_INIT(NSD,4.3.4,nsd-bugs@nlnetlabs.nl)
-AC_CONFIG_HEADER([config.h])
+AC_INIT([NSD],[4.3.6],[nsd-bugs@nlnetlabs.nl])
+AC_CONFIG_HEADERS([config.h])
#
# Setup the standard programs
AC_DEFINE_UNQUOTED(CONFCMDLINE, ["$cmdln"], [Command line arguments used with configure])
CFLAGS="$CFLAGS"
-AC_AIX
+AC_USE_SYSTEM_EXTENSIONS
if test "$ac_cv_header_minix_config_h" = "yes"; then
AC_DEFINE(_NETBSD_SOURCE,1, [Enable for compile on Minix])
fi
#
configdir=$sysconfdir/nsd
AC_ARG_WITH([configdir],
- AC_HELP_STRING([--with-configdir=dir], [NSD configuration directory]),
+ AS_HELP_STRING([--with-configdir=dir],[NSD configuration directory]),
[configdir=$withval])
AC_DEFINE_UNQUOTED(CONFIGDIR, ["`eval echo $configdir`"], [NSD config dir])
AC_SUBST(configdir)
# Determine configuration file
nsd_conf_file=${configdir}/nsd.conf
AC_ARG_WITH([nsd_conf_file],
- AC_HELP_STRING([--with-nsd_conf_file=path], [Pathname to the NSD configuration file]),
+ AS_HELP_STRING([--with-nsd_conf_file=path],[Pathname to the NSD configuration file]),
[nsd_conf_file=$withval])
AC_SUBST(nsd_conf_file)
# the eval is to evaluate shell expansion twice, once
#
logfile=${localstatedir}/log/nsd.log
AC_ARG_WITH([logfile],
- AC_HELP_STRING([--with-logfile=path], [Pathname to the default log file]),
+ AS_HELP_STRING([--with-logfile=path],[Pathname to the default log file]),
[logfile=$withval])
AC_SUBST(logfile)
pidfile=${dbdir}/nsd.pid
fi
AC_ARG_WITH([pidfile],
- AC_HELP_STRING([--with-pidfile=path], [Pathname to the NSD pidfile]),
+ AS_HELP_STRING([--with-pidfile=path],[Pathname to the NSD pidfile]),
[pidfile=$withval])
AC_SUBST(pidfile)
AC_DEFINE_UNQUOTED(PIDFILE, ["`eval echo $pidfile`"], [Pathname to the NSD pidfile])
#
dbfile=${dbdir}/nsd.db
AC_ARG_WITH([dbfile],
- AC_HELP_STRING([--with-dbfile=path], [Pathname to the NSD database]),
+ AS_HELP_STRING([--with-dbfile=path],[Pathname to the NSD database]),
[dbfile=$withval])
AC_SUBST(dbfile)
AC_DEFINE_UNQUOTED(DBFILE, ["`eval echo $dbfile`"], [Pathname to the NSD database])
#
zonesdir=$configdir
AC_ARG_WITH([zonesdir],
- AC_HELP_STRING([--with-zonesdir=dir], [NSD default location for zone files]),
+ AS_HELP_STRING([--with-zonesdir=dir],[NSD default location for zone files]),
[zonesdir=$withval])
AC_SUBST(zonesdir)
AC_DEFINE_UNQUOTED(ZONESDIR, ["`eval echo $zonesdir`"], [NSD default location for zone files. Empty string or NULL to disable.])
# default xfrd file location.
xfrdfile=${dbdir}/xfrd.state
-AC_ARG_WITH([xfrdfile], AC_HELP_STRING([--with-xfrdfile=path],
- [Pathname to the NSD xfrd zone timer state file]), [xfrdfile=$withval])
+AC_ARG_WITH([xfrdfile], AS_HELP_STRING([--with-xfrdfile=path],[Pathname to the NSD xfrd zone timer state file]), [xfrdfile=$withval])
AC_DEFINE_UNQUOTED(XFRDFILE, ["`eval echo $xfrdfile`"], [Pathname to the NSD xfrd zone timer state file.])
AC_SUBST(xfrdfile)
# default zonelist file location.
zonelistfile=${dbdir}/zone.list
-AC_ARG_WITH([zonelistfile], AC_HELP_STRING([--with-zonelistfile=path],
- [Pathname to the NSD zone list file]), [zonelistfile=$withval])
+AC_ARG_WITH([zonelistfile], AS_HELP_STRING([--with-zonelistfile=path],[Pathname to the NSD zone list file]), [zonelistfile=$withval])
AC_DEFINE_UNQUOTED(ZONELISTFILE, ["`eval echo $zonelistfile`"], [Pathname to the NSD zone list file.])
AC_SUBST(zonelistfile)
# default xfr dir location.
xfrdir="/tmp"
-AC_ARG_WITH([xfrdir], AC_HELP_STRING([--with-xfrdir=path],
- [Pathname to where the NSD transfer dir is created]), [xfrdir=$withval])
+AC_ARG_WITH([xfrdir], AS_HELP_STRING([--with-xfrdir=path],[Pathname to where the NSD transfer dir is created]), [xfrdir=$withval])
AC_DEFINE_UNQUOTED(XFRDIR, ["`eval echo $xfrdir`"], [Pathname to where the NSD transfer dir is created.])
AC_SUBST(xfrdir)
# Determine default chroot directory
#
AC_ARG_WITH([chroot],
- AC_HELP_STRING([--with-chroot=dir], [NSD default chroot directory]),
+ AS_HELP_STRING([--with-chroot=dir],[NSD default chroot directory]),
[
chrootdir=$withval
AC_DEFINE_UNQUOTED(CHROOTDIR, ["`eval echo $chrootdir`"], [NSD default chroot directory])
#
user=nsd
AC_ARG_WITH([user],
- AC_HELP_STRING([--with-user=username], [User name or ID to answer the queries with]),
+ AS_HELP_STRING([--with-user=username],[User name or ID to answer the queries with]),
[user=$withval])
AC_SUBST(user)
AC_DEFINE_UNQUOTED(USER, ["$user"], [the user name to drop privileges to])
AC_PROG_AWK
AC_PROG_GREP
AC_PROG_EGREP
-AC_PROG_LEX
+AC_PROG_LEX([noyywrap])
AC_PROG_YACC
AC_PROG_LN_S
AC_PROG_INSTALL
AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "format" attribute)
AC_CACHE_VAL(ac_cv_c_format_attribute,
[ac_cv_c_format_attribute=no
-AC_TRY_COMPILE(
-[#include <stdio.h>
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdio.h>
void f (char *format, ...) __attribute__ ((format (printf, 1, 2)));
void (*pf) (char *format, ...) __attribute__ ((format (printf, 1, 2)));
-], [
+]], [[
f ("%s", "str");
-],
-[ac_cv_c_format_attribute="yes"],
-[ac_cv_c_format_attribute="no"])
+]])],[ac_cv_c_format_attribute="yes"],[ac_cv_c_format_attribute="no"])
])
AC_MSG_RESULT($ac_cv_c_format_attribute)
AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "unused" attribute)
AC_CACHE_VAL(ac_cv_c_unused_attribute,
[ac_cv_c_unused_attribute=no
-AC_TRY_COMPILE(
-[#include <stdio.h>
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdio.h>
void f (char *u __attribute__((unused)));
-], [
+]], [[
f ("x");
-],
-[ac_cv_c_unused_attribute="yes"],
-[ac_cv_c_unused_attribute="no"])
+]])],[ac_cv_c_unused_attribute="yes"],[ac_cv_c_unused_attribute="no"])
])
AC_MSG_RESULT($ac_cv_c_unused_attribute)
AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "noreturn" attribute)
AC_CACHE_VAL(ac_cv_c_noreturn_attribute,
[ac_cv_c_noreturn_attribute=no
-AC_TRY_COMPILE(
-[ #include <stdio.h>
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <stdio.h>
__attribute__((noreturn)) void f(int x) { printf("%d", x); }
-], [
+]], [[
f(1);
-],
-[ac_cv_c_noreturn_attribute="yes"],
-[ac_cv_c_noreturn_attribute="no"])
+]])],[ac_cv_c_noreturn_attribute="yes"],[ac_cv_c_noreturn_attribute="no"])
])
AC_MSG_RESULT($ac_cv_c_noreturn_attribute)
AC_MSG_CHECKING(whether ctime_r works with two arguments)
AC_CACHE_VAL(ac_cv_c_ctime_c,
[ac_cv_c_ctime_c=no
-AC_TRY_COMPILE(
-[#include <time.h>
-void testing (void) { time_t clock; char current_time[40]; ctime_r(&clock, current_time); }],
-[
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <time.h>
+void testing (void) { time_t clock; char current_time[40]; ctime_r(&clock, current_time); }]], [[
testing();
-],
-[ac_cv_c_ctime_c="yes"],
-[ac_cv_c_ctime_c="no"])
+]])],[ac_cv_c_ctime_c="yes"],[ac_cv_c_ctime_c="no"])
])
AC_MSG_RESULT($ac_cv_c_ctime_c)
# http://www.gnu.org/software/ac-archive/htmldoc/check_ssl.html and
# modified for NSD.
AC_DEFUN([CHECK_SSL], [
- AC_ARG_WITH(ssl, AC_HELP_STRING([--with-ssl=pathname],
- [enable SSL (will check /usr/local/ssl
+ AC_ARG_WITH(ssl, AS_HELP_STRING([--with-ssl=pathname],[enable SSL (will check /usr/local/ssl
/usr/lib/ssl /usr/ssl /usr/pkg /usr/sfw /usr/local /usr /usr/local/opt/openssl)]),[
],[
withval="yes"
fi
done
if test x_$found_ssl != x_yes; then
- AC_MSG_ERROR(Cannot find the SSL libraries in $withval)
+ AC_MSG_ERROR([Cannot find the SSL libraries in $withval])
else
- AC_MSG_RESULT(found in $ssldir)
+ AC_MSG_RESULT([found in $ssldir])
HAVE_SSL=yes
if test x_$ssldir != x_/usr; then
LDFLAGS="$LDFLAGS -L$ssldir/lib";
])dnl
# check for libevent
-AC_ARG_WITH(libevent, AC_HELP_STRING([--with-libevent=pathname],
- [use libevent (will check /usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr /usr/local/opt/libevent or you can specify an explicit path), useful when the zone count is high.]),
+AC_ARG_WITH(libevent, AS_HELP_STRING([--with-libevent=pathname],[use libevent (will check /usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr /usr/local/opt/libevent or you can specify an explicit path), useful when the zone count is high.]),
[ ],[ withval="yes" ])
if test x_$withval = x_yes -o x_$withval != x_no; then
AC_MSG_CHECKING(for libevent)
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 netinet/tcp.h stddef.h sys/param.h sys/socket.h sys/un.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 sys/random.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 sys/un.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 sys/random.h ifaddrs.h],,, [AC_INCLUDES_DEFAULT])
AC_DEFUN([CHECK_VALIST_DEF],
[
if test "$srcdir" != "."; then
CPPFLAGS="$CPPFLAGS -I$srcdir"
if test -f $srcdir/config.h; then
- AC_ERROR([$srcdir/config.h is in the way, please remove it])
+ AC_MSG_ERROR([$srcdir/config.h is in the way, please remove it])
fi
fi
dnl AC_LIBGTOP_CHECK_TYPE(TYPE, DEFAULT)
AC_DEFUN([AC_LIBGTOP_CHECK_TYPE],
-[AC_REQUIRE([AC_HEADER_STDC])dnl
-AC_MSG_CHECKING(for $1)
+[AC_MSG_CHECKING(for $1)
AC_CACHE_VAL(ac_cv_type_$1,
[AC_EGREP_CPP(dnl
changequote(<<,>>)dnl
<<(^|[^a-zA-Z_0-9])$1[^a-zA-Z_0-9]>>dnl
changequote([,]), [
#include <sys/types.h>
-#if STDC_HEADERS
#include <stdlib.h>
#include <stddef.h>
-#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
AC_FUNC_CHOWN
AC_FUNC_FORK
AC_FUNC_MALLOC
-AC_TYPE_SIGNAL
+AC_DEFINE(RETSIGTYPE,void,[Return type of signal handlers, but autoconf 2.70 says 'your code may safely assume C89 semantics that RETSIGTYPE is void.'])
AC_FUNC_FSEEKO
AC_SYS_LARGEFILE
AC_CHECK_SIZEOF(void*)
AC_CHECK_SIZEOF(off_t)
AC_CHECK_FUNCS([getrandom arc4random arc4random_uniform])
-AC_SEARCH_LIBS([setusercontext],[util],[AC_CHECK_HEADERS([login_cap.h])])
+AC_SEARCH_LIBS([setusercontext],[util],[AC_CHECK_HEADERS([login_cap.h],,, [AC_INCLUDES_DEFAULT])])
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 accept4 getifaddrs])
AC_CHECK_TYPE([struct mmsghdr], AC_DEFINE(HAVE_MMSGHDR, 1, [If sys/socket.h has a struct mmsghdr.]), [], [
#include <sys/socket.h>
])
-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]))
+AC_ARG_ENABLE(recvmmsg, AS_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], [
fi
# see comment on _GNU_SOURCE above
-AC_CHECK_HEADERS([sched.h sys/cpuset.h])
+AC_CHECK_HEADERS([sched.h sys/cpuset.h],,, [AC_INCLUDES_DEFAULT])
# Check for cpu_set_t (Linux) and cpuset_t (FreeBSD and NetBSD)
AC_CHECK_TYPES([cpu_set_t, cpuset_t, cpuid_t],,,[
AC_DEFUN([AC_CHECK_CPU_OR],
[AC_REQUIRE([AC_PROG_CC])
AC_MSG_CHECKING(whether CPU_OR works with three arguments)
-AC_TRY_COMPILE(
-[#ifdef HAVE_SCHED_H
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#ifdef HAVE_SCHED_H
# include <sched.h>
#endif
#ifdef HAVE_SYS_CPUSET_H
memset(&a, 0, sizeof(a));
memset(&b, 0, sizeof(b));
CPU_OR(&a, &a, &b);
-}], [
+}]], [[
testing();
-], [
+]])],[
AC_MSG_RESULT(yes)
AC_DEFINE([CPU_OR_THREE_ARGS], 1, [number of arguments for CPU_OR is three])
-], [
+],[
AC_MSG_RESULT(no)
])])
dnl
facility=LOG_DAEMON
AC_ARG_WITH([facility],
- AC_HELP_STRING([--with-facility=name], [Syslog default facility (LOG_DAEMON)]),
+ AS_HELP_STRING([--with-facility=name],[Syslog default facility (LOG_DAEMON)]),
[facility=$withval])
AC_DEFINE_UNQUOTED([FACILITY], $facility, [Define to the default facility for syslog.])
dnl
tcp_timeout=120
AC_ARG_WITH([tcp_timeout],
- AC_HELP_STRING([--with-tcp-timeout=number], [Limit the default tcp timeout]),
+ AS_HELP_STRING([--with-tcp-timeout=number],[Limit the default tcp timeout]),
[tcp_timeout=$withval])
AC_DEFINE_UNQUOTED([TCP_TIMEOUT], $tcp_timeout, [Define to the default tcp timeout.])
dnl
dnl Features
dnl
-AC_ARG_ENABLE(root-server, AC_HELP_STRING([--enable-root-server], [Configure NSD as a root server]))
+AC_ARG_ENABLE(root-server, AS_HELP_STRING([--enable-root-server],[Configure NSD as a root server]))
case "$enable_root_server" in
yes)
AC_DEFINE_UNQUOTED([ROOT_SERVER], [], [Define this to configure as a root server.])
;;
esac
-AC_ARG_ENABLE(ipv6, AC_HELP_STRING([--disable-ipv6], [Disables IPv6 support]))
+AC_ARG_ENABLE(ipv6, AS_HELP_STRING([--disable-ipv6],[Disables IPv6 support]))
case "$enable_ipv6" in
no)
;;
;;
esac
-AC_ARG_ENABLE(bind8-stats, AC_HELP_STRING([--enable-bind8-stats], [Enables BIND8 like NSTATS & XSTATS and statistics in nsd-control]))
+AC_ARG_ENABLE(bind8-stats, AS_HELP_STRING([--enable-bind8-stats],[Enables BIND8 like NSTATS & XSTATS and statistics in nsd-control]))
case "$enable_bind8_stats" in
yes|'')
;;
esac
-AC_ARG_ENABLE(zone-stats, AC_HELP_STRING([--enable-zone-stats], [Enable per-zone statistics gathering (needs --enable-bind8-stats)]))
+AC_ARG_ENABLE(zone-stats, AS_HELP_STRING([--enable-zone-stats],[Enable per-zone statistics gathering (needs --enable-bind8-stats)]))
case "$enable_zone_stats" in
yes)
AC_DEFINE_UNQUOTED([USE_ZONE_STATS], [], [Define this to enable per-zone statistics gathering.])
;;
esac
-AC_ARG_ENABLE(checking, AC_HELP_STRING([--enable-checking], [Enable internal runtime checks]))
+AC_ARG_ENABLE(checking, AS_HELP_STRING([--enable-checking],[Enable internal runtime checks]))
case "$enable_checking" in
yes)
CHECK_COMPILER_FLAG(W, [ CFLAGS="$CFLAGS -W" ])
;;
esac
-AC_ARG_ENABLE(memclean, AC_HELP_STRING([--enable-memclean], [Cleanup memory (at exit) for eg. valgrind, memcheck]))
+AC_ARG_ENABLE(memclean, AS_HELP_STRING([--enable-memclean],[Cleanup memory (at exit) for eg. valgrind, memcheck]))
if test "$enable_memclean" = "yes"; then AC_DEFINE_UNQUOTED([MEMCLEAN], [1], [Define this to cleanup memory at exit (eg. for valgrind, etc.)])
fi
-AC_ARG_ENABLE(ratelimit, AC_HELP_STRING([--enable-ratelimit], [Enable rate limiting]))
+AC_ARG_ENABLE(ratelimit, AS_HELP_STRING([--enable-ratelimit],[Enable rate limiting]))
case "$enable_ratelimit" in
yes)
AC_DEFINE_UNQUOTED([RATELIMIT], [], [Define this to enable rate limiting.])
esac
AC_SUBST(ratelimit)
-AC_ARG_ENABLE(ratelimit-default-is-off, AC_HELP_STRING([--enable-ratelimit-default-is-off], [Enable this to set default of ratelimit to off (enable in nsd.conf), otherwise ratelimit is enabled by default if --enable-ratelimit is enabled]))
+AC_ARG_ENABLE(ratelimit-default-is-off, AS_HELP_STRING([--enable-ratelimit-default-is-off],[Enable this to set default of ratelimit to off (enable in nsd.conf), otherwise ratelimit is enabled by default if --enable-ratelimit is enabled]))
case "$enable_ratelimit_default_is_off" in
yes)
AC_DEFINE_UNQUOTED([RATELIMIT_DEFAULT_OFF], [], [Define this to set ratelimit to off by default.])
# Check for -pthread
BAKLIBS="$LIBS"
LIBS="-lcrypto $LIBS"
- AC_TRY_LINK([], [
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
int EVP_sha256(void);
(void)EVP_sha256();
- ], [],[
+ ]])],[],[
dnl so link fails for EVP_sha256, try with -pthread.
BAKCFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -pthread"
AC_MSG_WARN([No SSL, therefore TLS is disabled])
fi
-AC_ARG_ENABLE(nsec3, AC_HELP_STRING([--disable-nsec3], [Disable NSEC3 support]))
+AC_ARG_ENABLE(nsec3, AS_HELP_STRING([--disable-nsec3],[Disable NSEC3 support]))
case "$enable_nsec3" in
no)
;;
;;
esac
-AC_ARG_ENABLE(minimal-responses, AC_HELP_STRING([--disable-minimal-responses], [Disable response minimization. More truncation.]))
+AC_ARG_ENABLE(minimal-responses, AS_HELP_STRING([--disable-minimal-responses],[Disable response minimization. More truncation.]))
case "$enable_minimal_responses" in
no)
;;
;;
esac
-AC_ARG_ENABLE(mmap, AC_HELP_STRING([--enable-mmap], [Use mmap instead of malloc. Experimental.]))
+AC_ARG_ENABLE(mmap, AS_HELP_STRING([--enable-mmap],[Use mmap instead of malloc. Experimental.]))
case "$enable_mmap" in
yes)
- AC_CHECK_HEADERS([sys/mman.h])
+ AC_CHECK_HEADERS([sys/mman.h],,, [AC_INCLUDES_DEFAULT])
AC_LIBGTOP_CHECK_TYPE(uintptr_t, void*)
AC_CHECK_FUNCS([mmap munmap])
AC_DEFINE_UNQUOTED([USE_MMAP_ALLOC], [], [Define this to enable mmap instead of malloc. Experimental.])
;;
esac
-AC_ARG_ENABLE(radix-tree, AC_HELP_STRING([--disable-radix-tree], [You can disable the radix tree and use the red-black tree for the main lookups, the red-black tree uses less memory, but uses some more CPU.]))
+AC_ARG_ENABLE(radix-tree, AS_HELP_STRING([--disable-radix-tree],[You can disable the radix tree and use the red-black tree for the main lookups, the red-black tree uses less memory, but uses some more CPU.]))
case "$enable_radix_tree" in
no)
;;
;;
esac
-AC_ARG_ENABLE(packed, AC_HELP_STRING([--enable-packed], [Enable packed structure alignment, uses less memory, but unaligned reads.]))
+AC_ARG_ENABLE(packed, AS_HELP_STRING([--enable-packed],[Enable packed structure alignment, uses less memory, but unaligned reads.]))
case "$enable_packed" in
yes)
AC_DEFINE_UNQUOTED([PACKED_STRUCTS], [], [Define this to use packed structure alignment.])
sinclude(systemd.m4)
# Include systemd.m4 - end
-AC_ARG_ENABLE(tcp-fastopen, AC_HELP_STRING([--enable-tcp-fastopen], [Enable TCP Fast Open]))
+AC_ARG_ENABLE(tcp-fastopen, AS_HELP_STRING([--enable-tcp-fastopen],[Enable TCP Fast Open]))
case "$enable_tcp_fastopen" in
yes)
AC_CHECK_DECL([TCP_FASTOPEN], [], [AC_MSG_ERROR([TCP Fast Open is not available: please rerun without --enable-tcp-fastopen])], [AC_INCLUDES_DEFAULT
AH_BOTTOM([
#include <sys/types.h>
-#if STDC_HEADERS
#include <stdlib.h>
#include <stddef.h>
-#endif
#ifdef HAVE_TIME_H
#include <time.h>
return 1;
}
-static int
+int
print_rrs(FILE* out, struct zone* zone)
{
rrset_type *rrset;
apex->name_size)) {
/* out of disk space perhaps */
log_msg(LOG_ERR, "could not udb_create_zone "
- "%s, disk space full?", log_buf);
+ "%s, disk space full?", zone_buf);
return 0;
}
}
++src;
for (j = 0; j < len; ++j) {
uint8_t ch = *src++;
- if (isalnum((unsigned char)ch) || ch == '-' || ch == '_') {
+ if (isalnum((unsigned char)ch) || ch == '-' || ch == '_' || ch == '*') {
*dst++ = ch;
} else if (ch == '.' || ch == '\\') {
*dst++ = '\\';
lablen = *label++;
while(lablen--) {
uint8_t ch = *label++;
- if (isalnum((unsigned char)ch) || ch == '-' || ch == '_') {
+ if (isalnum((unsigned char)ch) || ch == '-' || ch == '_' || ch == '*') {
*p++ = ch;
} else if (ch == '.' || ch == '\\') {
*p++ = '\\';
static void
dt_msg_fill_net(struct dt_msg *dm,
#ifdef INET6
- struct sockaddr_storage *ss,
+ struct sockaddr_storage *rs,
+ struct sockaddr_storage *qs,
#else
- struct sockaddr_in *ss,
+ struct sockaddr_in *rs,
+ struct sockaddr_in *qs,
#endif
int is_tcp,
- ProtobufCBinaryData *addr, protobuf_c_boolean *has_addr,
- uint32_t *port, protobuf_c_boolean *has_port)
+ ProtobufCBinaryData *raddr, protobuf_c_boolean *has_raddr,
+ uint32_t *rport, protobuf_c_boolean *has_rport,
+ ProtobufCBinaryData *qaddr, protobuf_c_boolean *has_qaddr,
+ uint32_t *qport, protobuf_c_boolean *has_qport)
+
{
#ifdef INET6
- assert(ss->ss_family == AF_INET6 || ss->ss_family == AF_INET);
- if (ss->ss_family == AF_INET6) {
- struct sockaddr_in6 *s = (struct sockaddr_in6 *) ss;
+ assert(qs->ss_family == AF_INET6 || qs->ss_family == AF_INET);
+ if (qs->ss_family == AF_INET6) {
+ struct sockaddr_in6 *s = (struct sockaddr_in6 *) qs;
/* socket_family */
dm->m.socket_family = DNSTAP__SOCKET_FAMILY__INET6;
dm->m.has_socket_family = 1;
/* addr: query_address or response_address */
- addr->data = s->sin6_addr.s6_addr;
- addr->len = 16; /* IPv6 */
- *has_addr = 1;
+ qaddr->data = s->sin6_addr.s6_addr;
+ qaddr->len = 16; /* IPv6 */
+ *has_qaddr = 1;
/* port: query_port or response_port */
- *port = ntohs(s->sin6_port);
- *has_port = 1;
- } else if (ss->ss_family == AF_INET) {
+ *qport = ntohs(s->sin6_port);
+ *has_qport = 1;
+ } else if (qs->ss_family == AF_INET) {
#else
- if (ss->sin_family == AF_INET) {
+ if (qs->sin_family == AF_INET) {
#endif /* INET6 */
- struct sockaddr_in *s = (struct sockaddr_in *) ss;
+ struct sockaddr_in *s = (struct sockaddr_in *) qs;
/* socket_family */
dm->m.socket_family = DNSTAP__SOCKET_FAMILY__INET;
dm->m.has_socket_family = 1;
/* addr: query_address or response_address */
- addr->data = (uint8_t *) &s->sin_addr.s_addr;
- addr->len = 4; /* IPv4 */
- *has_addr = 1;
+ qaddr->data = (uint8_t *) &s->sin_addr.s_addr;
+ qaddr->len = 4; /* IPv4 */
+ *has_qaddr = 1;
/* port: query_port or response_port */
- *port = ntohs(s->sin_port);
- *has_port = 1;
+ *qport = ntohs(s->sin_port);
+ *has_qport = 1;
}
+#ifdef INET6
+ assert(rs->ss_family == AF_INET6 || rs->ss_family == AF_INET);
+ if (rs->ss_family == AF_INET6) {
+ struct sockaddr_in6 *s = (struct sockaddr_in6 *) rs;
+
+ /* addr: query_address or response_address */
+ raddr->data = s->sin6_addr.s6_addr;
+ raddr->len = 16; /* IPv6 */
+ *has_raddr = 1;
+
+ /* port: query_port or response_port */
+ *rport = ntohs(s->sin6_port);
+ *has_rport = 1;
+ } else if (rs->ss_family == AF_INET) {
+#else
+ if (rs->sin_family == AF_INET) {
+#endif /* INET6 */
+ struct sockaddr_in *s = (struct sockaddr_in *) rs;
+
+ /* addr: query_address or response_address */
+ raddr->data = (uint8_t *) &s->sin_addr.s_addr;
+ raddr->len = 4; /* IPv4 */
+ *has_raddr = 1;
+
+ /* port: query_port or response_port */
+ *rport = ntohs(s->sin_port);
+ *has_rport = 1;
+ }
+
+
if (!is_tcp) {
/* socket_protocol */
dm->m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__UDP;
void
dt_msg_send_auth_query(struct dt_env *env,
#ifdef INET6
+ struct sockaddr_storage* local_addr,
struct sockaddr_storage* addr,
#else
+ struct sockaddr_in* local_addr,
struct sockaddr_in* addr,
#endif
int is_tcp, uint8_t* zone, size_t zonelen, uint8_t* pkt, size_t pktlen)
/* query_message */
dt_fill_buffer(pkt, pktlen, &dm.m.query_message, &dm.m.has_query_message);
- /* socket_family, socket_protocol, query_address, query_port */
- dt_msg_fill_net(&dm, addr, is_tcp,
+ /* socket_family, socket_protocol, query_address, query_port, reponse_address (local_address), response_port (local_port) */
+ dt_msg_fill_net(&dm, local_addr, addr, is_tcp,
+ &dm.m.response_address, &dm.m.has_response_address,
+ &dm.m.response_port, &dm.m.has_response_port,
&dm.m.query_address, &dm.m.has_query_address,
&dm.m.query_port, &dm.m.has_query_port);
+
if (dt_pack(&dm.d, &dm.buf, &dm.len_buf))
dt_send(env, dm.buf, dm.len_buf);
}
void
dt_msg_send_auth_response(struct dt_env *env,
#ifdef INET6
+ struct sockaddr_storage* local_addr,
struct sockaddr_storage* addr,
#else
+ struct sockaddr_in* local_addr,
struct sockaddr_in* addr,
#endif
int is_tcp, uint8_t* zone, size_t zonelen, uint8_t* pkt, size_t pktlen)
/* response_message */
dt_fill_buffer(pkt, pktlen, &dm.m.response_message, &dm.m.has_response_message);
- /* socket_family, socket_protocol, query_address, query_port */
- dt_msg_fill_net(&dm, addr, is_tcp,
+ /* socket_family, socket_protocol, query_address, query_port, response_address (local_address), response_port (local_port) */
+ dt_msg_fill_net(&dm, local_addr, addr, is_tcp,
+ &dm.m.response_address, &dm.m.has_response_address,
+ &dm.m.response_port, &dm.m.has_response_port,
&dm.m.query_address, &dm.m.has_query_address,
&dm.m.query_port, &dm.m.has_query_port);
/**
* Create and send a new dnstap "Message" event of type AUTH_QUERY.
* @param env: dnstap environment object.
+ * @param local_addr: address/port of server (local address).
* @param addr: address/port of client.
* @param is_tcp: true for tcp, false for udp.
* @param zone: zone name, or NULL. in wireformat.
void
dt_msg_send_auth_query(struct dt_env *env,
#ifdef INET6
+ struct sockaddr_storage* local_addr,
struct sockaddr_storage* addr,
#else
+ struct sockaddr_in* local_addr,
struct sockaddr_in* addr,
#endif
int is_tcp, uint8_t* zone, size_t zonelen, uint8_t* pkt, size_t pktlen);
/**
* Create and send a new dnstap "Message" event of type AUTH_RESPONSE.
* @param env: dnstap environment object.
+ * @param local_addr: address/port of server (local address).
* @param addr: address/port of client.
* @param is_tcp: true for tcp, false for udp.
* @param zone: zone name, or NULL. in wireformat.
void
dt_msg_send_auth_response(struct dt_env *env,
#ifdef INET6
+ struct sockaddr_storage* local_addr,
struct sockaddr_storage* addr,
#else
+ struct sockaddr_in* local_addr,
struct sockaddr_in* addr,
#endif
int is_tcp, uint8_t* zone, size_t zonelen, uint8_t* pkt, size_t pktlen);
if test -z "$PROTOC_C"; then
AC_MSG_ERROR([The protoc-c program was not found. Please install protobuf-c!])
fi
- AC_ARG_WITH([protobuf-c], AC_HELP_STRING([--with-protobuf-c=path],
+ AC_ARG_WITH([protobuf-c], AS_HELP_STRING([--with-protobuf-c=path],
[Path where protobuf-c is installed, for dnstap]), [
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
if test -f $withval/include/google/protobuf-c/protobuf-c.h; then
fi
fi
])
- AC_ARG_WITH([libfstrm], AC_HELP_STRING([--with-libfstrm=path],
+ AC_ARG_WITH([libfstrm], AS_HELP_STRING([--with-libfstrm=path],
[Path where libfstrm is installed, for dnstap]), [
CFLAGS="$CFLAGS -I$withval/include"
LDFLAGS="$LDFLAGS -L$withval/lib"
edns->opt_reserved_space = 0;
edns->dnssec_ok = 0;
edns->nsid = 0;
+ edns->ede = -1; /* -1 means no Extended DNS Error */
+ edns->ede_text = NULL;
+ edns->ede_text_len = 0;
}
/** handle a single edns option in the query */
edns_reserved_space(edns_record_type *edns)
{
/* MIEK; when a pkt is too large?? */
- return edns->status == EDNS_NOT_PRESENT ? 0 : (OPT_LEN + OPT_RDATA + edns->opt_reserved_space);
+ return edns->status == EDNS_NOT_PRESENT ? 0
+ : (OPT_LEN + OPT_RDATA + edns->opt_reserved_space);
}
#define OPT_RDATA 2 /* holds the rdata length comes after OPT_LEN */
#define OPT_HDR 4U /* NSID opt header length */
#define NSID_CODE 3 /* nsid option code */
+#define EDE_CODE 15 /* Extended DNS Errors option code */
#define DNSSEC_OK_MASK 0x8000U /* do bit mask */
struct edns_data
edns_status_type status;
size_t position;
size_t maxlen;
- size_t opt_reserved_space;
+ size_t opt_reserved_space;
int dnssec_ok;
int nsid;
+ int ede; /* RFC 8914 - Extended DNS Errors */
+ char* ede_text; /* RFC 8914 - Extended DNS Errors text*/
+ uint16_t ede_text_len;
};
typedef struct edns_record edns_record_type;
+/* The Extended DNS Error codes (RFC8914) we use */
+#define EDE_OTHER 0
+#define EDE_NOT_READY 14
+#define EDE_PROHIBITED 18
+#define EDE_NOT_AUTHORITATIVE 20
+#define EDE_NOT_SUPPORTED 21
+#define EDE_INVALID_DATA 24
+
+/* ASSIGN_EDE_CODE_AND_STRING_LITERAL may only be used with string literals.
+ * This is guaranteed by concatenating and empty string to LITERAL, which
+ * will make compilation fail if this macro is used with variables.
+ */
+#define ASSIGN_EDE_CODE_AND_STRING_LITERAL(EDE, CODE, LITERAL) \
+ do { \
+ EDE = (CODE); \
+ EDE ## _text = (LITERAL ""); \
+ EDE ## _text_len = sizeof(LITERAL) - 1; \
+ } while (0)
+
void edns_init_data(edns_data_type *data, uint16_t max_length);
void edns_init_record(edns_record_type *data);
int edns_parse_record(edns_record_type *data, buffer_type *packet,
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,
struct timespec* mtime, const char* file_str);
+int print_rrs(FILE* out, struct zone* zone);
/** 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 */
-.TH "nsd\-checkconf" "8" "Dec 1, 2020" "NLnet Labs" "nsd 4.3.4"
+.TH "nsd\-checkconf" "8" "Mar 29, 2021" "NLnet Labs" "nsd 4.3.6rc1"
.\" Copyright (c) 2001\-2008, NLnet Labs. All rights reserved.
.\" See LICENSE for the license.
.SH "NAME"
}
ZONE_GET_BIN(part_of_config, o, zone);
ZONE_GET_PATH(final, zonefile, o, zone->pattern);
+ ZONE_GET_ACL(allow_query, o, zone->pattern);
ZONE_GET_ACL(request_xfr, o, zone->pattern);
ZONE_GET_ACL(provide_xfr, o, zone->pattern);
ZONE_GET_ACL(allow_notify, o, zone->pattern);
}
ZONE_GET_STR(zonefile, o, p);
ZONE_GET_PATH(final, zonefile, o, p);
+ ZONE_GET_ACL(allow_query, o, p);
ZONE_GET_ACL(request_xfr, o, p);
ZONE_GET_ACL(provide_xfr, o, p);
ZONE_GET_ACL(allow_notify, o, p);
#ifdef RATELIMIT
zone_print_rrl_whitelist("\trrl-whitelist: ", pat->rrl_whitelist);
#endif
+ print_acl("allow_query:", pat->allow_query);
print_acl("allow-notify:", pat->allow_notify);
print_acl("request-xfr:", pat->request_xfr);
if(pat->multi_master_check)
-.TH "nsd\-checkzone" "8" "Dec 1, 2020" "NLnet Labs" "nsd 4.3.4"
+.TH "nsd\-checkzone" "8" "Mar 29, 2021" "NLnet Labs" "nsd 4.3.6rc1"
.\" Copyright (c) 2014, NLnet Labs. All rights reserved.
.\" See LICENSE for the license.
.SH "NAME"
static void
usage (void)
{
- fprintf(stderr, "Usage: nsd-checkzone <zone name> <zone file>\n");
+ fprintf(stderr, "Usage: nsd-checkzone [-p] <zone name> <zone file>\n");
+ fprintf(stderr, "\t-p\tprint the zone if the zone is ok\n");
fprintf(stderr, "Version %s. Report bugs to <%s>.\n",
PACKAGE_VERSION, PACKAGE_BUGREPORT);
}
static void
-check_zone(struct nsd* nsd, const char* name, const char* fname)
+check_zone(struct nsd* nsd, const char* name, const char* fname, FILE *out)
{
const dname_type* dname;
zone_options_type* zo;
#endif
exit(1);
}
+ if (out) {
+ print_rrs(out, zone);
+ printf("; ");
+ }
printf("zone %s is ok\n", name);
namedb_close(nsd->db);
}
{
/* Scratch variables... */
int c;
+ int print_zone = 0;
struct nsd nsd;
memset(&nsd, 0, sizeof(nsd));
log_init("nsd-checkzone");
/* Parse the command line... */
- while ((c = getopt(argc, argv, "h")) != -1) {
+ while ((c = getopt(argc, argv, "hp")) != -1) {
switch (c) {
case 'h':
usage();
exit(0);
+ case 'p':
+ print_zone = 1;
+ break;
case '?':
default:
usage();
if (verbosity == 0)
verbosity = nsd.options->verbosity;
- check_zone(&nsd, argv[0], argv[1]);
+ check_zone(&nsd, argv[0], argv[1], print_zone ? stdout : NULL);
region_destroy(nsd.options->region);
/* yylex_destroy(); but, not available in all versions of flex */
-.TH "nsd\-control" "8" "Dec 1, 2020" "NLnet Labs" "nsd 4.3.4"
+.TH "nsd\-control" "8" "Mar 29, 2021" "NLnet Labs" "nsd 4.3.6rc1"
.\" Copyright (c) 2011, NLnet Labs. All rights reserved.
.\" See LICENSE for the license.
.SH "NAME"
#ifdef HAVE_SYS_UN_H
#include <sys/un.h>
#endif
+#include <fcntl.h>
+#ifndef AF_LOCAL
+#define AF_LOCAL AF_UNIX
+#endif
#include "util.h"
#include "tsig.h"
#include "options.h"
static void ssl_err(const char* s) ATTR_NORETURN;
static void ssl_path_err(const char* s, const char *path) ATTR_NORETURN;
+/** timeout to wait for connection over stream, in msec */
+#define NSD_CONTROL_CONNECT_TIMEOUT 5000
+
/** Give nsd-control usage, and exit (1). */
static void
usage()
return ctx;
}
+/** check connect error */
+static void
+checkconnecterr(int err, const char* svr, int port, int statuscmd)
+{
+ if(!port) fprintf(stderr, "error: connect (%s): %s\n", svr,
+ strerror(err));
+ else fprintf(stderr, "error: connect (%s@%d): %s\n", svr, port,
+ strerror(err));
+ if(err == ECONNREFUSED && statuscmd) {
+ printf("nsd is stopped\n");
+ exit(3);
+ }
+ exit(1);
+}
+
/** contact the server with TCP connect */
static int
contact_server(const char* svr, struct nsd_options* cfg, int statuscmd)
fprintf(stderr, "socket: %s\n", strerror(errno));
exit(1);
}
+ if(fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
+ fprintf(stderr, "error: set nonblocking: fcntl: %s",
+ strerror(errno));
+ }
if(connect(fd, (struct sockaddr*)&addr, addrlen) < 0) {
- int err = errno;
- if(!port) fprintf(stderr, "error: connect (%s): %s\n", svr,
- strerror(err));
- else fprintf(stderr, "error: connect (%s@%d): %s\n", svr, port,
- strerror(err));
- if(err == ECONNREFUSED && statuscmd) {
- printf("nsd is stopped\n");
- exit(3);
+ if(errno != EINPROGRESS) {
+ checkconnecterr(errno, svr, port, statuscmd);
}
- exit(1);
+ }
+ while(1) {
+ fd_set rset, wset, eset;
+ struct timeval tv;
+ FD_ZERO(&rset);
+ FD_SET(fd, &rset);
+ FD_ZERO(&wset);
+ FD_SET(fd, &wset);
+ FD_ZERO(&eset);
+ FD_SET(fd, &eset);
+ tv.tv_sec = NSD_CONTROL_CONNECT_TIMEOUT/1000;
+ tv.tv_usec= (NSD_CONTROL_CONNECT_TIMEOUT%1000)*1000;
+ if(select(fd+1, &rset, &wset, &eset, &tv) == -1) {
+ fprintf(stderr, "select: %s\n", strerror(errno));
+ exit(1);
+ }
+ if(!FD_ISSET(fd, &rset) && !FD_ISSET(fd, &wset) &&
+ !FD_ISSET(fd, &eset)) {
+ fprintf(stderr, "timeout: could not connect to server\n");
+ exit(1);
+ } else {
+ /* check nonblocking connect error */
+ int error = 0;
+ socklen_t len = (socklen_t)sizeof(error);
+ if(getsockopt(fd, SOL_SOCKET, SO_ERROR, (void*)&error,
+ &len) < 0) {
+ error = errno; /* on solaris errno is error */
+ }
+ if(error != 0) {
+ if(error == EINPROGRESS || error == EWOULDBLOCK)
+ continue; /* try again later */
+ checkconnecterr(error, svr, port, statuscmd);
+ }
+ }
+ break;
+ }
+ if(fcntl(fd, F_SETFL, 0) == -1) {
+ fprintf(stderr, "error: set blocking: fcntl: %s",
+ strerror(errno));
}
return fd;
}
}
if(!opt->control_enable)
fprintf(stderr, "warning: control-enable is 'no' in the config file.\n");
+ resolve_interface_names(opt);
ctx = setup_ctx(opt);
/* contact server */
int c;
const char* cfgfile = CONFIGFILE;
char* svr = NULL;
-#ifdef USE_WINSOCK
- int r;
- WSADATA wsa_data;
-#endif
log_init("nsd-control");
#ifdef HAVE_ERR_LOAD_CRYPTO_STRINGS
-.TH "NSD" "8" "Dec 1, 2020" "NLnet Labs" "NSD 4.3.4"
+.TH "NSD" "8" "Mar 29, 2021" "NLnet Labs" "NSD 4.3.6rc1"
.\" Copyright (c) 2001\-2008, NLnet Labs. All rights reserved.
.\" See LICENSE for the license.
.SH "NAME"
.B nsd
-\- Name Server Daemon (NSD) version 4.3.4.
+\- Name Server Daemon (NSD) version 4.3.6rc1.
.SH "SYNOPSIS"
.B nsd
.RB [ \-4 ]
#include <string.h>
#include <time.h>
#include <unistd.h>
+#ifdef HAVE_IFADDRS_H
#include <ifaddrs.h>
+#endif
#include "nsd.h"
#include "options.h"
exit(0);
}
-#ifdef HAVE_GETIFADDRS
-static void
-resolve_ifa_name(struct ifaddrs *ifas, const char *search_ifa, char ***ip_addresses, size_t *ip_addresses_size)
-{
- struct ifaddrs *ifa;
- size_t last_ip_addresses_size = *ip_addresses_size;
-
- for(ifa = ifas; ifa != NULL; ifa = ifa->ifa_next) {
- sa_family_t family;
- const char* atsign;
-#ifdef INET6 /* | address ip | % | ifa name | @ | port | nul */
- char addr_buf[INET6_ADDRSTRLEN + 1 + IF_NAMESIZE + 1 + 16 + 1];
-#else
- char addr_buf[INET_ADDRSTRLEN + 1 + 16 + 1];
-#endif
-
- if((atsign=strrchr(search_ifa, '@')) != NULL) {
- if(strlen(ifa->ifa_name) != (size_t)(atsign-search_ifa)
- || strncmp(ifa->ifa_name, search_ifa,
- atsign-search_ifa) != 0)
- continue;
- } else {
- if(strcmp(ifa->ifa_name, search_ifa) != 0)
- continue;
- atsign = "";
- }
-
- if(ifa->ifa_addr == NULL)
- continue;
-
- family = ifa->ifa_addr->sa_family;
- if(family == AF_INET) {
- char a4[INET_ADDRSTRLEN + 1];
- struct sockaddr_in *in4 = (struct sockaddr_in *)
- ifa->ifa_addr;
- if(!inet_ntop(family, &in4->sin_addr, a4, sizeof(a4)))
- error("inet_ntop");
- snprintf(addr_buf, sizeof(addr_buf), "%s%s",
- a4, atsign);
- }
-#ifdef INET6
- else if(family == AF_INET6) {
- struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)
- ifa->ifa_addr;
- char a6[INET6_ADDRSTRLEN + 1];
- char if_index_name[IF_NAMESIZE + 1];
- if_index_name[0] = 0;
- if(!inet_ntop(family, &in6->sin6_addr, a6, sizeof(a6)))
- error("inet_ntop");
- if_indextoname(in6->sin6_scope_id,
- (char *)if_index_name);
- if (strlen(if_index_name) != 0) {
- snprintf(addr_buf, sizeof(addr_buf),
- "%s%%%s%s", a6, if_index_name, atsign);
- } else {
- snprintf(addr_buf, sizeof(addr_buf), "%s%s",
- a6, atsign);
- }
- }
-#endif
- else {
- continue;
- }
- VERBOSITY(4, (LOG_INFO, "interface %s has address %s",
- search_ifa, addr_buf));
-
- *ip_addresses = xrealloc(*ip_addresses, sizeof(char *) * (*ip_addresses_size + 1));
- (*ip_addresses)[*ip_addresses_size] = xstrdup(addr_buf);
- (*ip_addresses_size)++;
- }
-
- if (*ip_addresses_size == last_ip_addresses_size) {
- *ip_addresses = xrealloc(*ip_addresses, sizeof(char *) * (*ip_addresses_size + 1));
- (*ip_addresses)[*ip_addresses_size] = xstrdup(search_ifa);
- (*ip_addresses_size)++;
- }
-}
-#endif /* HAVE_GETIFADDRS */
-
-static void
-resolve_interface_names(struct nsd_options* options)
-{
-#ifdef HAVE_GETIFADDRS
- struct ifaddrs *addrs;
- struct ip_address_option *ip_addr;
- struct ip_address_option *last = NULL;
- struct ip_address_option *first = NULL;
-
- if(getifaddrs(&addrs) == -1)
- error("failed to list interfaces");
-
- /* replace the list of ip_adresses with a new list where the
- * interface names are replaced with their ip-address strings
- * from getifaddrs. An interface can have several addresses. */
- for(ip_addr = options->ip_addresses; ip_addr; ip_addr = ip_addr->next) {
- char **ip_addresses = NULL;
- size_t ip_addresses_size = 0, i;
- resolve_ifa_name(addrs, ip_addr->address, &ip_addresses,
- &ip_addresses_size);
-
- for (i = 0; i < ip_addresses_size; i++) {
- struct ip_address_option *current;
- /* this copies the range_option, dev, and fib from
- * the original ip_address option to the new ones
- * with the addresses spelled out by resolve_ifa_name*/
- current = region_alloc_init(options->region, ip_addr,
- sizeof(*ip_addr));
- current->address = region_strdup(options->region,
- ip_addresses[i]);
- current->next = NULL;
- free(ip_addresses[i]);
-
- if(first == NULL) {
- first = current;
- } else {
- last->next = current;
- }
- last = current;
- }
- free(ip_addresses);
- }
-
- freeifaddrs(addrs);
- options->ip_addresses = first;
-#else
- (void)options;
-#endif /* HAVE_GETIFADDRS */
-}
-
static void
copyaddrinfo(struct nsd_addrinfo *dest, struct addrinfo *src)
{
figure_socket_servers(&(*tcp)[i], NULL);
}
+#ifdef HAVE_GETIFADDRS
static int
find_device(
struct nsd_socket *sock,
return 0;
}
+#endif /* HAVE_GETIFADDRS */
static void
figure_sockets(
size_t i = 0;
struct addrinfo ai = *hints;
struct ip_address_option *ip;
+#ifdef HAVE_GETIFADDRS
struct ifaddrs *ifa = NULL;
+#endif
int bind_device = 0;
if(!ips) {
bind_device |= (ip->dev != 0);
}
+#ifdef HAVE_GETIFADDRS
if(bind_device && getifaddrs(&ifa) == -1) {
error("getifaddrs failed: %s", strerror(errno));
}
+#endif
*udp = xalloc_zero((*ifs + 1) * sizeof(struct nsd_socket));
*tcp = xalloc_zero((*ifs + 1) * sizeof(struct nsd_socket));
(*udp)[i].fib = ip->fib;
(*tcp)[i].fib = ip->fib;
}
+#ifdef HAVE_GETIFADDRS
if(ip->dev != 0) {
(*udp)[i].flags |= NSD_BIND_DEVICE;
(*tcp)[i].flags |= NSD_BIND_DEVICE;
ip->address);
}
}
+#endif
}
assert(i == *ifs);
+#ifdef HAVE_GETIFADDRS
if(ifa != NULL) {
freeifaddrs(ifa);
}
+#endif
}
/* print server affinity for given socket. "*" if socket has no affinity with
-.TH "nsd.conf" "5" "Dec 1, 2020" "NLnet Labs" "nsd 4.3.4"
+.TH "nsd.conf" "5" "Mar 29, 2021" "NLnet Labs" "nsd 4.3.6rc1"
.\" Copyright (c) 2001\-2008, NLnet Labs. All rights reserved.
.\" See LICENSE for the license.
.SH "NAME"
turn on later (typical for certain load-balancing).
.TP
.B interface:\fR <ip4 or ip6>[@port] [servers] [bindtodevice] [setfib]
-Same as ip\-address (for easy of compatibility with unbound.conf).
+Same as ip\-address (for ease of compatibility with unbound.conf).
.TP
.B ip\-transparent:\fR <yes or no>
Allows NSD to bind to non local addresses. This is useful to have NSD
.B control\-enable:\fR <yes or no>
Enable remote control, default is no.
.TP
-.B control\-interface:\fR <ip4 or ip6>
+.B control\-interface:\fR <ip4 or ip6 | interface name | absolute path>
NSD will bind to the listed addresses to service control requests
(on TCP). Can be given multiple times to bind multiple ip\-addresses.
Use 0.0.0.0 and ::0 to service the wildcard interface. If none are given
NSD listens to the localhost 127.0.0.1 and ::1 interfaces for control,
if control is enabled with control\-enable.
.IP
+If an interface name is used instead of ip4 or ip6, the list of IP addresses
+associated with that interface is picked up and used at server start.
+.IP
With an absolute path, a unix local named pipe is used for control. The
file is created with user and group that is configured and access bits
are set to allow members of the group access. Further access can be
.B <zone option>:\fR <value>
The zone options such as
.BR zonefile ,
+.BR allow\-query ,
.BR allow\-notify ,
.BR request\-xfr ,
.BR allow\-axfr\-fallback ,
.IP
.B %x\fR is replaced with the next-next label under the toplevel domain.
.TP
+.B allow\-query:\fR <ip\-spec> <key\-name | NOKEY | BLOCKED>
+Access control list. When at least one \fBallow\-query\fR option is
+specified, then the in the \fBallow\-query\fR options specified addresses
+are are allowed to query the server for the zone. Queries from unlisted or
+specifically BLOCKED addresses are discarded. If NOKEY is given no TSIG
+signature is required. BLOCKED supersedes other entries, other entries are
+scanned for a match in the order of the statements. Without
+\fBallow\-query\fR options, queries are allowed from any IP address
+without TSIG key (which is the default).
+.P
+.RS
+The ip\-spec is either a plain IP address (IPv4 or IPv6), or can be
+a subnet of the form 1.2.3.4/24, or masked like
+1.2.3.4&255.255.255.0 or a range of the form 1.2.3.4\-1.2.3.25.
+Note the ip\-spec ranges do not use spaces around the /, &, @ and \-
+symbols.
+.RE
+.TP
.B allow\-notify:\fR <ip\-spec> <key\-name | NOKEY | BLOCKED>
Access control list. The listed (primary) address is allowed to
send notifies to this (secondary) server. Notifies from unlisted or
The content of the secret is the agreed base64 secret content. To make it
up, enter a password (its length must be a multiple of 4 characters, A\-Za\-z0\-9), or use
dev-random output through a base64 encode filter.
+.SS DNSTAP Logging Options
+DNSTAP support, when compiled in, is enabled in the \fBdnstap:\fR section.
+This starts a collector process that writes the log information to the
+destination.
+.TP
+.B dnstap-enable:\fR <yes or no>
+If dnstap is enabled. Default no. If yes, it connects to the dnstap server
+and if any of the dnstap-log-..-messages options is enabled it sends logs
+for those messages to the server.
+.TP
+.B dnstap-socket-path:\fR <file name>
+Sets the unix socket file name for connecting to the server that is
+listening on that socket. Default is "@dnstap_socket_path@".
+.TP
+.B dnstap-send-identity:\fR <yes or no>
+If enabled, the server identity is included in the log messages.
+Default is no.
+.TP
+.B dnstap-send-version:\fR <yes or no>
+If enabled, the server version if included in the log messages.
+Default is no.
+.TP
+.B dnstap-identity:\fR <string>
+The identity to send with messages, if "" the hostname is used.
+Default is "".
+.TP
+.B dnstap-version:\fR <string>
+The version to send with messages, if "" the package version is used.
+Default is "".
+.TP
+.B dnstap-log-auth-query-messages:\fR <yes or no>
+Enable to log auth query messages. Default is no.
+These are client queries to NSD.
+.TP
+.B dnstap-log-auth-response-messages:\fR <yes or no>
+Enable to log auth response messages. Default is no.
+These are responses from NSD to clients.
.SH "NSD CONFIGURATION FOR BIND9 HACKERS"
BIND9 is a name server implementation with its own configuration
file format, named.conf(5). BIND9 types zones as 'Master' or 'Slave'.
# dnstap:
# set this to yes and set one or more of dnstap-log-..-messages to yes.
# dnstap-enable: no
- # dnstap-socket-path: "/var/run/dnstap.sock"
+ # dnstap-socket-path: "@dnstap_socket_path@"
# dnstap-send-identity: no
# dnstap-send-version: no
# dnstap-identity: ""
# control-enable: no
# what interfaces are listened to for control, default is on localhost.
+ # interfaces can be specified by IP address or interface name.
+ # with an interface name, all IP addresses associated with that
+ # interface are used.
# with an absolute path, a unix local named pipe is used for control
# (and key and cert files are not needed, use directory permissions).
# control-interface: 127.0.0.1
# control-interface: ::1
+ # control-interface: lo
# port number for remote control operations (uses TLS over TCP).
# control-port: 8952
# if label or character does not exist you get a dot '.'.
# for example "%s.zone" or "zones/%1/%2/%3/%s" or "secondary/%z/%s"
#zonefile: "%s.zone"
+
+ # The allow-query allows an access control list to be specified
+ # for a zone to be queried. Without an allow-query option, any
+ # IP address is allowed to send queries for the zone.
+ # This could be useful for example to not leak content from a zone
+ # which is only offered for transfer to secondaries over TLS.
+ #allow-query: 192.0.2.0/24 NOKEY
# If no master and slave access control elements are provided,
# this zone will not be served to/from other servers.
VERBOSITY(3, (LOG_ERR, "nsec3 hash collision for name=%s hash=%s reverse=%s",
dname_to_string(to_prove, NULL), hashbuf, reversebuf));
RCODE_SET(query->packet, RCODE_SERVFAIL);
+ /* RFC 8914 - Extended DNS Errors
+ * 4.21. Extended DNS Error Code 0 - Other */
+ ASSIGN_EDE_CODE_AND_STRING_LITERAL(query->edns.ede,
+ EDE_OTHER, "NSEC3 hash collision");
return;
}
else
/* wildcard exists below the domain */
/* wildcard and nsec3 domain clash. server failure. */
RCODE_SET(query->packet, RCODE_SERVFAIL);
+ /* RFC 8914 - Extended DNS Errors
+ * 4.21. Extended DNS Error Code 0 - Other */
+ ASSIGN_EDE_CODE_AND_STRING_LITERAL(query->edns.ede,
+ EDE_OTHER, "Wildcard and NSEC3 domain clash");
}
return;
}
#include <stdio.h>
#include <sys/stat.h>
#include <errno.h>
+#ifdef HAVE_IFADDRS_H
+#include <ifaddrs.h>
+#endif
#include "options.h"
#include "query.h"
#include "tsig.h"
#include "rrl.h"
#include "bitset.h"
-#include "configyyrename.h"
#include "configparser.h"
config_parser_state_type* cfg_parser = 0;
extern FILE* c_in, *c_out;
c_error("key %s in pattern %s could not be found",
acl->key_name, pat->pname);
}
+ for(acl=pat->allow_query; acl; acl=acl->next)
+ {
+ if(acl->nokey || acl->blocked)
+ continue;
+ acl->key_options = key_options_find(opt, acl->key_name);
+ if(!acl->key_options)
+ c_error("key %s in pattern %s could not be found",
+ acl->key_name, pat->pname);
+ }
}
if(cfg_parser->errors > 0)
p->size_limit_xfr = 0;
p->notify = 0;
p->provide_xfr = 0;
+ p->allow_query = 0;
p->outgoing_interface = 0;
p->notify_retry = 5;
p->notify_retry_is_default = 1;
acl_list_delete(opt->region, p->request_xfr);
acl_list_delete(opt->region, p->notify);
acl_list_delete(opt->region, p->provide_xfr);
+ acl_list_delete(opt->region, p->allow_query);
acl_list_delete(opt->region, p->outgoing_interface);
region_recycle(opt->region, p, sizeof(struct pattern_options));
orig->request_xfr = copy_acl_list(opt, p->request_xfr);
orig->notify = copy_acl_list(opt, p->notify);
orig->provide_xfr = copy_acl_list(opt, p->provide_xfr);
+ orig->allow_query = copy_acl_list(opt, p->allow_query);
orig->outgoing_interface = copy_acl_list(opt,
p->outgoing_interface);
nsd_options_insert_pattern(opt, orig);
copy_changed_acl(opt, &orig->request_xfr, p->request_xfr);
copy_changed_acl(opt, &orig->notify, p->notify);
copy_changed_acl(opt, &orig->provide_xfr, p->provide_xfr);
+ copy_changed_acl(opt, &orig->allow_query, p->allow_query);
copy_changed_acl(opt, &orig->outgoing_interface,
p->outgoing_interface);
}
if(!acl_list_equal(p->request_xfr, q->request_xfr)) return 0;
if(!acl_list_equal(p->notify, q->notify)) return 0;
if(!acl_list_equal(p->provide_xfr, q->provide_xfr)) return 0;
+ if(!acl_list_equal(p->allow_query, q->allow_query)) return 0;
if(!acl_list_equal(p->outgoing_interface, q->outgoing_interface))
return 0;
if(p->max_refresh_time != q->max_refresh_time) return 0;
marshal_acl_list(b, p->request_xfr);
marshal_acl_list(b, p->notify);
marshal_acl_list(b, p->provide_xfr);
+ marshal_acl_list(b, p->allow_query);
marshal_acl_list(b, p->outgoing_interface);
marshal_u32(b, p->max_refresh_time);
marshal_u8(b, p->max_refresh_time_is_default);
p->request_xfr = unmarshal_acl_list(r, b);
p->notify = unmarshal_acl_list(r, b);
p->provide_xfr = unmarshal_acl_list(r, b);
+ p->allow_query = unmarshal_acl_list(r, b);
p->outgoing_interface = unmarshal_acl_list(r, b);
p->max_refresh_time = unmarshal_u32(b);
p->max_refresh_time_is_default = unmarshal_u8(b);
copy_and_append_acls(&dest->request_xfr, pat->request_xfr);
copy_and_append_acls(&dest->notify, pat->notify);
copy_and_append_acls(&dest->provide_xfr, pat->provide_xfr);
+ copy_and_append_acls(&dest->allow_query, pat->allow_query);
copy_and_append_acls(&dest->outgoing_interface, pat->outgoing_interface);
if(pat->multi_master_check)
dest->multi_master_check = pat->multi_master_check;
if(cfg->control_interface->address[0] == 0) return 1;
return (cfg->control_interface->address[0] != '/');
}
+
+#ifdef HAVE_GETIFADDRS
+static void
+resolve_ifa_name(struct ifaddrs *ifas, const char *search_ifa, char ***ip_addresses, size_t *ip_addresses_size)
+{
+ struct ifaddrs *ifa;
+ size_t last_ip_addresses_size = *ip_addresses_size;
+
+ for(ifa = ifas; ifa != NULL; ifa = ifa->ifa_next) {
+ sa_family_t family;
+ const char* atsign;
+#ifdef INET6 /* | address ip | % | ifa name | @ | port | nul */
+ char addr_buf[INET6_ADDRSTRLEN + 1 + IF_NAMESIZE + 1 + 16 + 1];
+#else
+ char addr_buf[INET_ADDRSTRLEN + 1 + 16 + 1];
+#endif
+
+ if((atsign=strrchr(search_ifa, '@')) != NULL) {
+ if(strlen(ifa->ifa_name) != (size_t)(atsign-search_ifa)
+ || strncmp(ifa->ifa_name, search_ifa,
+ atsign-search_ifa) != 0)
+ continue;
+ } else {
+ if(strcmp(ifa->ifa_name, search_ifa) != 0)
+ continue;
+ atsign = "";
+ }
+
+ if(ifa->ifa_addr == NULL)
+ continue;
+
+ family = ifa->ifa_addr->sa_family;
+ if(family == AF_INET) {
+ char a4[INET_ADDRSTRLEN + 1];
+ struct sockaddr_in *in4 = (struct sockaddr_in *)
+ ifa->ifa_addr;
+ if(!inet_ntop(family, &in4->sin_addr, a4, sizeof(a4)))
+ error("inet_ntop");
+ snprintf(addr_buf, sizeof(addr_buf), "%s%s",
+ a4, atsign);
+ }
+#ifdef INET6
+ else if(family == AF_INET6) {
+ struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)
+ ifa->ifa_addr;
+ char a6[INET6_ADDRSTRLEN + 1];
+ char if_index_name[IF_NAMESIZE + 1];
+ if_index_name[0] = 0;
+ if(!inet_ntop(family, &in6->sin6_addr, a6, sizeof(a6)))
+ error("inet_ntop");
+ if_indextoname(in6->sin6_scope_id,
+ (char *)if_index_name);
+ if (strlen(if_index_name) != 0) {
+ snprintf(addr_buf, sizeof(addr_buf),
+ "%s%%%s%s", a6, if_index_name, atsign);
+ } else {
+ snprintf(addr_buf, sizeof(addr_buf), "%s%s",
+ a6, atsign);
+ }
+ }
+#endif
+ else {
+ continue;
+ }
+ VERBOSITY(4, (LOG_INFO, "interface %s has address %s",
+ search_ifa, addr_buf));
+
+ *ip_addresses = xrealloc(*ip_addresses, sizeof(char *) * (*ip_addresses_size + 1));
+ (*ip_addresses)[*ip_addresses_size] = xstrdup(addr_buf);
+ (*ip_addresses_size)++;
+ }
+
+ if (*ip_addresses_size == last_ip_addresses_size) {
+ *ip_addresses = xrealloc(*ip_addresses, sizeof(char *) * (*ip_addresses_size + 1));
+ (*ip_addresses)[*ip_addresses_size] = xstrdup(search_ifa);
+ (*ip_addresses_size)++;
+ }
+}
+
+static void
+resolve_interface_names_for_ref(struct ip_address_option** ip_addresses_ref,
+ struct ifaddrs *addrs, region_type* region)
+{
+ struct ip_address_option *ip_addr;
+ struct ip_address_option *last = NULL;
+ struct ip_address_option *first = NULL;
+
+ /* replace the list of ip_adresses with a new list where the
+ * interface names are replaced with their ip-address strings
+ * from getifaddrs. An interface can have several addresses. */
+ for(ip_addr = *ip_addresses_ref; ip_addr; ip_addr = ip_addr->next) {
+ char **ip_addresses = NULL;
+ size_t ip_addresses_size = 0, i;
+ resolve_ifa_name(addrs, ip_addr->address, &ip_addresses,
+ &ip_addresses_size);
+
+ for (i = 0; i < ip_addresses_size; i++) {
+ struct ip_address_option *current;
+ /* this copies the range_option, dev, and fib from
+ * the original ip_address option to the new ones
+ * with the addresses spelled out by resolve_ifa_name*/
+ current = region_alloc_init(region, ip_addr,
+ sizeof(*ip_addr));
+ current->address = region_strdup(region,
+ ip_addresses[i]);
+ current->next = NULL;
+ free(ip_addresses[i]);
+
+ if(first == NULL) {
+ first = current;
+ } else {
+ last->next = current;
+ }
+ last = current;
+ }
+ free(ip_addresses);
+ }
+ *ip_addresses_ref = first;
+
+}
+#endif /* HAVE_GETIFADDRS */
+
+void
+resolve_interface_names(struct nsd_options* options)
+{
+#ifdef HAVE_GETIFADDRS
+ struct ifaddrs *addrs;
+
+ if(getifaddrs(&addrs) == -1)
+ error("failed to list interfaces");
+
+ resolve_interface_names_for_ref(&options->ip_addresses,
+ addrs, options->region);
+ resolve_interface_names_for_ref(&options->control_interface,
+ addrs, options->region);
+
+ freeifaddrs(addrs);
+#else
+ (void)options;
+#endif /* HAVE_GETIFADDRS */
+}
struct acl_options* request_xfr;
struct acl_options* notify;
struct acl_options* provide_xfr;
+ struct acl_options* allow_query;
struct acl_options* outgoing_interface;
const char* zonestats;
#ifdef RATELIMIT
* when a fileread fails because it is a directory, helps the user figure
* out what just happened */
void warn_if_directory(const char* filetype, FILE* f, const char* fname);
+/* resolve interface names in the options "ip-address:" (or "interface:")
+ * and "control-interface:" into the ip-addresses associated with those
+ * names. */
+void resolve_interface_names(struct nsd_options* options);
#endif /* OPTIONS_H */
ANCOUNT_SET(q->packet, ANCOUNT(q->packet) + 1);
} else {
RCODE_SET(q->packet, RCODE_REFUSE);
+ /* RFC8914 - Extended DNS Errors
+ * 4.19. Extended DNS Error Code 18 - Prohibited */
+ q->edns.ede = EDE_PROHIBITED;
}
} else if ((q->qname->name_size == 16
&& memcmp(dname_name(q->qname), "\007version\006server", 16) == 0) ||
ANCOUNT_SET(q->packet, ANCOUNT(q->packet) + 1);
} else {
RCODE_SET(q->packet, RCODE_REFUSE);
+ /* RFC8914 - Extended DNS Errors
+ * 4.19. Extended DNS Error Code 18 - Prohibited */
+ q->edns.ede = EDE_PROHIBITED;
}
} else {
RCODE_SET(q->packet, RCODE_REFUSE);
+ /* RFC8914 - Extended DNS Errors
+ * 4.22. Extended DNS Error Code 21 - Not Supported */
+ q->edns.ede = EDE_NOT_SUPPORTED;
+
}
break;
default:
RCODE_SET(q->packet, RCODE_REFUSE);
+ /* RFC8914 - Extended DNS Errors
+ * 4.22. Extended DNS Error Code 21 - Not Supported */
+ q->edns.ede = EDE_NOT_SUPPORTED;
break;
}
their (not allocated yet) parents */
/* any domains below src are not_existing (because of DNAME at src) */
int i;
+ size_t j;
domain_type* cname_domain;
domain_type* cname_dest;
rrset_type* rrset;
- /* allocate source part */
domain_type* lastparent = src;
assert(q && answer && from_name && to_name && src && to_closest_encloser);
assert(to_closest_match);
+
+ /* check for loop by duplicate CNAME rrset synthesized */
+ for(j=0; j<answer->rrset_count; ++j) {
+ if(answer->section[j] == ANSWER_SECTION &&
+ answer->rrsets[j]->rr_count == 1 &&
+ answer->rrsets[j]->rrs[0].type == TYPE_CNAME &&
+ dname_compare(domain_dname(answer->rrsets[j]->rrs[0].owner), from_name) == 0 &&
+ answer->rrsets[j]->rrs[0].rdata_count == 1 &&
+ dname_compare(domain_dname(answer->rrsets[j]->rrs[0].rdatas->domain), to_name) == 0) {
+ DEBUG(DEBUG_QUERY,2, (LOG_INFO, "loop for synthesized CNAME rrset for query %s", dname_to_string(q->qname, NULL)));
+ return 0;
+ }
+ }
+
+ /* allocate source part */
for(i=0; i < from_name->label_count - domain_dname(src)->label_count; i++)
{
domain_type* newdom = query_get_tempdomain(q);
rrset->rrs->rdatas->domain = cname_dest;
if(!add_rrset(q, answer, ANSWER_SECTION, cname_domain, rrset)) {
- log_msg(LOG_ERR, "could not add synthesized CNAME rrset to packet");
+ DEBUG(DEBUG_QUERY,2, (LOG_INFO, "could not add synthesized CNAME rrset to packet for query %s", dname_to_string(q->qname, NULL)));
+ /* failure to add CNAME; likely is a loop, the same twice */
+ return 0;
}
return cname_dest->number;
domain_type *match;
domain_type *original = closest_match;
domain_type *dname_ce;
+ domain_type *wildcard_child;
rrset_type *rrset;
#ifdef NSEC3
} else if ((rrset=domain_find_rrset(closest_encloser, q->zone, TYPE_DNAME))) {
/* process DNAME */
const dname_type* name = qname;
+ domain_type* src = closest_encloser;
domain_type *dest = rdata_atom_domain(rrset->rrs[0].rdatas[0]);
- int added;
+ const dname_type* newname;
+ size_t newnum = 0;
+ zone_type* origzone = q->zone;
assert(rrset->rr_count > 0);
if(domain_number != 0) /* we followed CNAMEs or DNAMEs */
name = domain_dname(closest_match);
domain_to_string(closest_encloser)));
DEBUG(DEBUG_QUERY,2, (LOG_INFO, "->dest is %s",
domain_to_string(dest)));
- /* if the DNAME set is not added we have a loop, do not follow */
- added = add_rrset(q, answer, ANSWER_SECTION, closest_encloser, rrset);
- if(added) {
- domain_type* src = closest_encloser;
- const dname_type* newname = dname_replace(q->region, name,
- domain_dname(src), domain_dname(dest));
- size_t newnum = 0;
- zone_type* origzone = q->zone;
- ++q->cname_count;
- if(!newname) { /* newname too long */
- RCODE_SET(q->packet, RCODE_YXDOMAIN);
+ if(!add_rrset(q, answer, ANSWER_SECTION, closest_encloser, rrset)) {
+ /* stop if DNAME loops, when added second time */
+ if(dname_is_subdomain(domain_dname(dest), domain_dname(src))) {
return;
}
- DEBUG(DEBUG_QUERY,2, (LOG_INFO, "->result is %s", dname_to_string(newname, NULL)));
- /* follow the DNAME */
- (void)namedb_lookup(nsd->db, newname, &closest_match, &closest_encloser);
- /* synthesize CNAME record */
- newnum = query_synthesize_cname(q, answer, name, newname,
- src, closest_encloser, &closest_match, rrset->rrs[0].ttl);
- if(!newnum) {
- /* could not synthesize the CNAME. */
- /* return previous CNAMEs to make resolver recurse for us */
- return;
- }
-
- answer_lookup_zone(nsd, q, answer, newnum,
- closest_match == closest_encloser,
- closest_match, closest_encloser, newname);
- q->zone = origzone;
}
- if(!added) /* log the error so operator can find looping recursors */
- log_msg(LOG_INFO, "DNAME processing stopped due to loop, qname %s",
- dname_to_string(q->qname, NULL));
+ newname = dname_replace(q->region, name,
+ domain_dname(src), domain_dname(dest));
+ ++q->cname_count;
+ if(!newname) { /* newname too long */
+ RCODE_SET(q->packet, RCODE_YXDOMAIN);
+ /* RFC 8914 - Extended DNS Errors
+ * 4.21. Extended DNS Error Code 0 - Other */
+ ASSIGN_EDE_CODE_AND_STRING_LITERAL(q->edns.ede,
+ EDE_OTHER, "DNAME expansion became too large");
+ return;
+ }
+ DEBUG(DEBUG_QUERY,2, (LOG_INFO, "->result is %s", dname_to_string(newname, NULL)));
+ /* follow the DNAME */
+ (void)namedb_lookup(nsd->db, newname, &closest_match, &closest_encloser);
+ /* synthesize CNAME record */
+ newnum = query_synthesize_cname(q, answer, name, newname,
+ src, closest_encloser, &closest_match, rrset->rrs[0].ttl);
+ if(!newnum) {
+ /* could not synthesize the CNAME. */
+ /* return previous CNAMEs to make resolver recurse for us */
+ return;
+ }
+ if(q->qtype == TYPE_CNAME) {
+ /* The synthesized CNAME is the answer to
+ * that query, same as BIND does for query
+ * of type CNAME */
+ return;
+ }
+
+ answer_lookup_zone(nsd, q, answer, newnum,
+ closest_match == closest_encloser,
+ closest_match, closest_encloser, newname);
+ q->zone = origzone;
return;
- } else if (domain_wildcard_child(closest_encloser)) {
+ } else if ((wildcard_child=domain_wildcard_child(closest_encloser))!=NULL &&
+ wildcard_child->is_existing) {
/* Generate the domain from the wildcard. */
- domain_type *wildcard_child = domain_wildcard_child(closest_encloser);
#ifdef RATELIMIT
q->wildcard_domain = wildcard_child;
#endif
q->zone = domain_find_zone(nsd->db, closest_encloser);
if (!q->zone) {
/* no zone for this */
- if(q->cname_count == 0)
+ if(q->cname_count == 0) {
RCODE_SET(q->packet, RCODE_REFUSE);
+ /* RFC 8914 - Extended DNS Errors
+ * 4.21. Extended DNS Error Code 20 - Not Authoritative */
+ q->edns.ede = EDE_NOT_AUTHORITATIVE;
+ }
return;
}
assert(closest_encloser); /* otherwise, no q->zone would be found */
+ if(q->zone->opts && q->zone->opts->pattern
+ && q->zone->opts->pattern->allow_query) {
+ struct acl_options *why = NULL;
+
+ /* check if it passes acl */
+ if(acl_check_incoming(
+ q->zone->opts->pattern->allow_query, q, &why) != -1) {
+ assert(why);
+ DEBUG(DEBUG_QUERY,1, (LOG_INFO, "query %s passed acl %s %s",
+ dname_to_string(q->qname, NULL),
+ why->ip_address_spec,
+ why->nokey?"NOKEY":
+ (why->blocked?"BLOCKED":why->key_name)));
+ } else {
+ if (verbosity >= 2) {
+ char address[128];
+ addr2str(&q->addr, address, sizeof(address));
+ VERBOSITY(2, (LOG_INFO, "query %s from %s refused, %s %s",
+ dname_to_string(q->qname, NULL),
+ address,
+ why ? ( why->nokey ? "NOKEY"
+ : why->blocked ? "BLOCKED"
+ : why->key_name )
+ : "no acl matches",
+ why?why->ip_address_spec:"."));
+ }
+ /* no zone for this */
+ if(q->cname_count == 0) {
+ RCODE_SET(q->packet, RCODE_REFUSE);
+ /* RFC8914 - Extended DNS Errors
+ * 4.19. Extended DNS Error Code 18 - Prohibited */
+ q->edns.ede = EDE_PROHIBITED;
+ }
+ return;
+ }
+ }
if(!q->zone->apex || !q->zone->soa_rrset) {
/* zone is configured but not loaded */
- if(q->cname_count == 0)
+ if(q->cname_count == 0) {
RCODE_SET(q->packet, RCODE_SERVFAIL);
+ /* RFC 8914 - Extended DNS Errors
+ * 4.15. Extended DNS Error Code 14 - Not Ready */
+ q->edns.ede = EDE_NOT_READY;
+ ASSIGN_EDE_CODE_AND_STRING_LITERAL(q->edns.ede,
+ EDE_NOT_READY, "Zone is configured but not loaded");
+ }
return;
}
q->zone = zone;
if(!q->zone->apex || !q->zone->soa_rrset) {
/* zone is configured but not loaded */
- if(q->cname_count == 0)
+ if(q->cname_count == 0) {
RCODE_SET(q->packet, RCODE_SERVFAIL);
+ /* RFC 8914 - Extended DNS Errors
+ * 4.15. Extended DNS Error Code 14 - Not Ready */
+ ASSIGN_EDE_CODE_AND_STRING_LITERAL(
+ q->edns.ede, EDE_NOT_READY,
+ "Zone is configured but not loaded");
+ }
return;
}
}
/* see if the zone has expired (for secondary zones) */
if(q->zone && q->zone->opts && q->zone->opts->pattern &&
q->zone->opts->pattern->request_xfr != 0 && !q->zone->is_ok) {
- if(q->cname_count == 0)
+ if(q->cname_count == 0) {
RCODE_SET(q->packet, RCODE_SERVFAIL);
+ /* RFC 8914 - Extended DNS Errors
+ * 4.25. Extended DNS Error Code 24 - Invalid Data */
+ ASSIGN_EDE_CODE_AND_STRING_LITERAL(q->edns.ede,
+ EDE_INVALID_DATA, "Zone has expired");
+ }
return;
}
}
arcount = ARCOUNT(q->packet);
- if (arcount > 0) {
- /* According to draft-ietf-dnsext-rfc2671bis-edns0-10:
- * "The placement flexibility for the OPT RR does not
- * override the need for the TSIG or SIG(0) RRs to be
- * the last in the additional section whenever they are
- * present."
- * So we should not have to check for TSIG RR before
- * OPT RR. Keep the code for backwards compatibility.
- */
-
- /* see if tsig is before edns record */
- if (!tsig_parse_rr(&q->tsig, q->packet))
- return query_formerr(q, nsd);
- if(q->tsig.status != TSIG_NOT_PRESENT)
- --arcount;
- }
+ /* A TSIG RR is not allowed before the EDNS OPT RR.
+ * In RFC6891 (about EDNS) it says:
+ * "The placement flexibility for the OPT RR does not
+ * override the need for the TSIG or SIG(0) RRs to be
+ * the last in the additional section whenever they are
+ * present."
+ * And in RFC8945 (about TSIG) it says:
+ * "If multiple TSIG records are detected or a TSIG record is
+ * present in any other position, the DNS message is dropped
+ * and a response with RCODE 1 (FORMERR) MUST be returned."
+ */
/* See if there is an OPT RR. */
if (arcount > 0) {
if (edns_parse_record(&q->edns, q->packet, q, nsd))
if (q->qclass == CLASS_CH) {
return answer_chaos(nsd, q);
} else {
- return query_error(q, NSD_RC_REFUSE);
+ /* RFC8914 - Extended DNS Errors
+ * 4.22. Extended DNS Error Code 21 - Not Supported */
+ q->edns.ede = EDE_NOT_SUPPORTED;
+ return query_error(q, RCODE_REFUSE);
}
}
-
query_state = answer_axfr_ixfr(nsd, q);
if (query_state == QUERY_PROCESSED || query_state == QUERY_IN_AXFR) {
return query_state;
if (q->edns.dnssec_ok) edns->ok[7] = 0x80;
else edns->ok[7] = 0x00;
buffer_write(q->packet, edns->ok, OPT_LEN);
+
+ /* Add Extended DNS Error (RFC8914)
+ * to verify that we stay in bounds */
+ if (q->edns.ede >= 0)
+ q->edns.opt_reserved_space +=
+ 6 + ( q->edns.ede_text_len
+ ? q->edns.ede_text_len : 0);
+
if(q->edns.opt_reserved_space == 0 || !buffer_available(
q->packet, 2+q->edns.opt_reserved_space)) {
/* fill with NULLs */
/* nsid payload */
buffer_write(q->packet, nsd->nsid, nsd->nsid_len);
}
+ /* Append Extended DNS Error (RFC8914) option if needed */
+ if (q->edns.ede >= 0) { /* < 0 means no EDE */
+ /* OPTION-CODE */
+ buffer_write_u16(q->packet, EDE_CODE);
+ /* OPTION-LENGTH */
+ buffer_write_u16(q->packet,
+ 2 + ( q->edns.ede_text_len
+ ? q->edns.ede_text_len : 0));
+ /* INFO-CODE */
+ buffer_write_u16(q->packet, q->edns.ede);
+ /* EXTRA-TEXT */
+ if (q->edns.ede_text_len)
+ buffer_write(q->packet,
+ q->edns.ede_text,
+ q->edns.ede_text_len);
+ }
}
ARCOUNT_SET(q->packet, ARCOUNT(q->packet) + 1);
STATUP(nsd, edns);
#ifdef HAVE_SYS_UN_H
# include <sys/un.h>
#endif
+#ifndef AF_LOCAL
+#define AF_LOCAL AF_UNIX
+#endif
/** number of seconds timeout on incoming remote control handshake */
#define REMOTE_CONTROL_TCP_TIMEOUT 120
key_opt);
zopt_set_acl_to_tsig(zone->pattern->provide_xfr, region, arg2,
key_opt);
+ zopt_set_acl_to_tsig(zone->pattern->allow_query, region, arg2,
+ key_opt);
task_new_add_pattern(xfrd->nsd->task[xfrd->nsd->mytask],
xfrd->last_task, zone->pattern);
if(acl_contains_tsig_key(zone->pattern->allow_notify, arg) ||
acl_contains_tsig_key(zone->pattern->notify, arg) ||
acl_contains_tsig_key(zone->pattern->request_xfr, arg) ||
- acl_contains_tsig_key(zone->pattern->provide_xfr, arg)) {
+ acl_contains_tsig_key(zone->pattern->provide_xfr, arg) ||
+ acl_contains_tsig_key(zone->pattern->allow_query, arg)) {
if(!ssl_printf(ssl, "zone %s uses key %s\n",
zone->name, arg))
return;
#define RELOAD_SYNC_TIMEOUT 25 /* seconds */
+#ifdef USE_DNSTAP
+/*
+ * log_addr() - the function to print sockaddr_in/sockaddr_in6 structures content
+ * just like its done in Unbound via the same log_addr(VERB_LEVEL, const char*, sockaddr_storage*)
+ */
+static void
+log_addr(const char* descr,
+#ifdef INET6
+ struct sockaddr_storage* addr,
+#else
+ struct sockaddr_in* addr,
+#endif
+ short family)
+{
+ char str_buf[64];
+ if(verbosity < 6)
+ return;
+ if(family == AF_INET) {
+ struct sockaddr_in* s = (struct sockaddr_in*)addr;
+ inet_ntop(AF_INET, &s->sin_addr.s_addr, str_buf, sizeof(str_buf));
+ VERBOSITY(6, (LOG_INFO, "%s: address is: %s, port is: %d", descr, str_buf, ntohs(s->sin_port)));
+#ifdef INET6
+ } else {
+ struct sockaddr_in6* s6 = (struct sockaddr_in6*)addr;
+ inet_ntop(AF_INET6, &s6->sin6_addr.s6_addr, str_buf, sizeof(str_buf));
+ VERBOSITY(6, (LOG_INFO, "%s: address is: %s, port is: %d", descr, str_buf, ntohs(s6->sin6_port)));
+#endif
+ }
+}
+#endif /* USE_DNSTAP */
+
#ifdef USE_TCP_FASTOPEN
#define TCP_FASTOPEN_FILE "/proc/sys/net/ipv4/tcp_fastopen"
#define TCP_FASTOPEN_SERVER_BIT_MASK 0x2
* The timeout in msec for this tcp connection
*/
int tcp_timeout;
+
+ /*
+ * If the connection is allowed to have further queries on it.
+ */
+ int tcp_no_more_queries;
+
+#ifdef USE_DNSTAP
+ /* the socket of the accept socket to find proper service (local) address the socket is bound to. */
+ struct nsd_socket *socket;
+#endif /* USE_DNSTAP */
+
#ifdef HAVE_SSL
/*
* TLS object.
}
#endif
+ p->tcp_no_more_queries = 1;
/* set timeout to 1/10 second */
if(p->tcp_timeout > 100)
p->tcp_timeout = 100;
buffer_skip(q->packet, received);
buffer_flip(q->packet);
#ifdef USE_DNSTAP
- dt_collector_submit_auth_query(data->nsd, &q->addr, q->addrlen,
+ /*
+ * sending UDP-query with server address (local) and client address to dnstap process
+ */
+ log_addr("query from client", &q->addr, data->socket->addr.ai_family);
+ log_addr("to server (local)", &data->socket->addr.ai_addr, data->socket->addr.ai_family);
+ dt_collector_submit_auth_query(data->nsd, &data->socket->addr.ai_addr, &q->addr, q->addrlen,
q->tcp, q->packet);
#endif /* USE_DNSTAP */
}
#endif /* BIND8_STATS */
#ifdef USE_DNSTAP
- dt_collector_submit_auth_response(data->nsd,
+ /*
+ * sending UDP-response with server address (local) and client address to dnstap process
+ */
+ log_addr("from server (local)", &data->socket->addr.ai_addr, data->socket->addr.ai_family);
+ log_addr("response to client", &q->addr, data->socket->addr.ai_family);
+ dt_collector_submit_auth_response(data->nsd, &data->socket->addr.ai_addr,
&q->addr, q->addrlen, q->tcp, q->packet,
q->zone);
#endif /* USE_DNSTAP */
return;
}
- if (data->nsd->tcp_query_count > 0 &&
- data->query_count >= data->nsd->tcp_query_count) {
+ if ((data->nsd->tcp_query_count > 0 &&
+ data->query_count >= data->nsd->tcp_query_count) ||
+ data->tcp_no_more_queries) {
/* No more queries allowed on this tcp connection. */
cleanup_tcp_handler(data);
return;
buffer_flip(data->query->packet);
#ifdef USE_DNSTAP
- dt_collector_submit_auth_query(data->nsd, &data->query->addr,
+ /*
+ * and send TCP-query with found address (local) and client address to dnstap process
+ */
+ log_addr("query from client", &data->query->addr, data->query->addr.ss_family);
+ log_addr("to server (local)", &data->socket->addr.ai_addr, data->query->addr.ss_family);
+ dt_collector_submit_auth_query(data->nsd, &data->socket->addr.ai_addr, &data->query->addr,
data->query->addrlen, data->query->tcp, data->query->packet);
#endif /* USE_DNSTAP */
data->query_state = server_process_query(data->nsd, data->query);
}
#endif /* BIND8_STATS */
#ifdef USE_DNSTAP
- dt_collector_submit_auth_response(data->nsd, &data->query->addr,
+ /*
+ * sending TCP-response with found (earlier) address (local) and client address to dnstap process
+ */
+ log_addr("from server (local)", &data->socket->addr.ai_addr, data->query->addr.ss_family);
+ log_addr("response to client", &data->query->addr, data->query->addr.ss_family);
+ dt_collector_submit_auth_response(data->nsd, &data->socket->addr.ai_addr, &data->query->addr,
data->query->addrlen, data->query->tcp, data->query->packet,
data->query->zone);
#endif /* USE_DNSTAP */
* Done sending, wait for the next request to arrive on the
* TCP socket by installing the TCP read handler.
*/
- if (data->nsd->tcp_query_count > 0 &&
- data->query_count >= data->nsd->tcp_query_count) {
+ if ((data->nsd->tcp_query_count > 0 &&
+ data->query_count >= data->nsd->tcp_query_count) ||
+ data->tcp_no_more_queries) {
(void) shutdown(fd, SHUT_WR);
}
return;
}
- if (data->nsd->tcp_query_count > 0 &&
- data->query_count >= data->nsd->tcp_query_count) {
+ if ((data->nsd->tcp_query_count > 0 &&
+ data->query_count >= data->nsd->tcp_query_count) ||
+ data->tcp_no_more_queries) {
/* No more queries allowed on this tcp connection. */
cleanup_tcp_handler(data);
return;
buffer_flip(data->query->packet);
#ifdef USE_DNSTAP
- dt_collector_submit_auth_query(data->nsd, &data->query->addr,
+ /*
+ * and send TCP-query with found address (local) and client address to dnstap process
+ */
+ log_addr("query from client", &data->query->addr, data->query->addr.ss_family);
+ log_addr("to server (local)", &data->socket->addr.ai_addr, data->query->addr.ss_family);
+ dt_collector_submit_auth_query(data->nsd, &data->socket->addr.ai_addr, &data->query->addr,
data->query->addrlen, data->query->tcp, data->query->packet);
#endif /* USE_DNSTAP */
data->query_state = server_process_query(data->nsd, data->query);
}
#endif /* BIND8_STATS */
#ifdef USE_DNSTAP
- dt_collector_submit_auth_response(data->nsd, &data->query->addr,
+ /*
+ * sending TCP-response with found (earlier) address (local) and client address to dnstap process
+ */
+ log_addr("from server (local)", &data->socket->addr.ai_addr, data->query->addr.ss_family);
+ log_addr("response to client", &data->query->addr, data->query->addr.ss_family);
+ dt_collector_submit_auth_response(data->nsd, &data->socket->addr.ai_addr, &data->query->addr,
data->query->addrlen, data->query->tcp, data->query->packet,
data->query->zone);
#endif /* USE_DNSTAP */
* Done sending, wait for the next request to arrive on the
* TCP socket by installing the TCP read handler.
*/
- if (data->nsd->tcp_query_count > 0 &&
- data->query_count >= data->nsd->tcp_query_count) {
+ if ((data->nsd->tcp_query_count > 0 &&
+ data->query_count >= data->nsd->tcp_query_count) ||
+ data->tcp_no_more_queries) {
(void) shutdown(fd, SHUT_WR);
}
memcpy(&tcp_data->query->addr, &addr, addrlen);
tcp_data->query->addrlen = addrlen;
+ tcp_data->tcp_no_more_queries = 0;
tcp_data->tcp_timeout = data->nsd->tcp_timeout * 1000;
if (data->nsd->current_tcp_count > data->nsd->maximum_tcp_count/2) {
/* very busy, give smaller timeout */
timeout.tv_sec = tcp_data->tcp_timeout / 1000;
timeout.tv_usec = (tcp_data->tcp_timeout % 1000)*1000;
+#ifdef USE_DNSTAP
+ /* save the address of the connection */
+ tcp_data->socket = data->socket;
+#endif /* USE_DNSTAP */
+
#ifdef HAVE_SSL
if (data->tls_accept) {
tcp_data->tls = incoming_ssl_fd(tcp_data->nsd->tls_ctx, s);
xfrd_setup_packet(tcp->packet, TYPE_AXFR, CLASS_IN, zone->apex,
zone->query_id);
+ zone->query_type = TYPE_AXFR;
} else {
DEBUG(DEBUG_XFRD,1, (LOG_INFO, "request incremental zone "
"transfer (IXFR) for %s to %s",
xfrd_setup_packet(tcp->packet, TYPE_IXFR, CLASS_IN, zone->apex,
zone->query_id);
+ zone->query_type = TYPE_IXFR;
NSCOUNT_SET(tcp->packet, 1);
xfrd_write_soa_buffer(tcp->packet, zone->apex, &zone->soa_disk);
}
xfrd_setup_packet(xfrd->packet, TYPE_IXFR, CLASS_IN, zone->apex,
qid_generate());
zone->query_id = ID(xfrd->packet);
+ zone->query_type = TYPE_IXFR;
/* delete old xfr file? */
if(zone->msg_seq_nr)
xfrd_unlink_xfrfile(xfrd->nsd, zone->xfrfilenumber);
(int)zone->msg_new_serial:0,
zone->master->ip_address_spec));
}
- if (res == xfrd_packet_notimpl)
+ if (res == xfrd_packet_notimpl
+ && zone->query_type == TYPE_IXFR)
return res;
else
return xfrd_packet_bad;
/* xfr message handling data */
/* query id */
uint16_t query_id;
+ uint16_t query_type;
uint32_t msg_seq_nr; /* number of messages already handled */
uint32_t msg_old_serial, msg_new_serial; /* host byte order */
size_t msg_rr_count;
* See LICENSE for the license.
*
*/
+/* because flex keeps having sign-unsigned compare problems that are unfixed*/
+#if defined(__clang__)||(defined(__GNUC__)&&((__GNUC__ >4)||(defined(__GNUC_MINOR__)&&(__GNUC__ ==4)&&(__GNUC_MINOR__ >=2))))
+#pragma GCC diagnostic ignored "-Wsign-compare"
+#endif
+/* ignore fallthrough warnings in the generated parse code case statements */
+#if defined(__clang__)||(defined(__GNUC__)&&(__GNUC__ >=7))
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#endif
#include "config.h"
LETTER [a-zA-Z]
NEWLINE [\n\r]
ZONESTR [^ \t\n\r();.\"\$]|\\.|\\\n
-CHARSTR [^ \t\n\r();.]|\\.|\\\n
+CHARSTR [^ \t\n\r();.\"]|\\.|\\\n
QUOTE \"
DOLLAR \$
COMMENT ;
*/
^{DOLLAR}INCLUDE {
BEGIN(incl);
+ /* ignore case statement fallthrough on incl<EOF> flex rule */
}
-<incl>\n |
+<incl>\n |
<incl><<EOF>> {
int error_occurred = parser->error_occurred;
BEGIN(INITIAL);
yyrestart(yyin); /* this is so that lex does not give an internal err */
yyterminate();
}
-<quotedstring>{ANY}* { LEXOUT(("STR ")); yymore(); }
+<quotedstring>{ANY}* { LEXOUT(("QSTR ")); yymore(); }
<quotedstring>\n { ++parser->line; yymore(); }
<quotedstring>{QUOTE} {
LEXOUT(("\" "));
BEGIN(INITIAL);
yytext[yyleng - 1] = '\0';
- return parse_token(STR, yytext, &lexer_state);
+ return parse_token(QSTR, yytext, &lexer_state);
}
{ZONESTR}({CHARSTR})* {
/* other tokens */
%token DOLLAR_TTL DOLLAR_ORIGIN NL SP
-%token <data> STR PREV BITLAB
+%token <data> QSTR STR PREV BITLAB
%token <ttl> T_TTL
%token <klass> T_RRCLASS
%type <domain> owner dname abs_dname
%type <dname> rel_dname label
%type <data> wire_dname wire_abs_dname wire_rel_dname wire_label
-%type <data> concatenated_str_seq str_sp_seq str_dot_seq dotted_str
+%type <data> str concatenated_str_seq str_sp_seq str_dot_seq
+%type <data> unquoted_dotted_str dotted_str
%type <data> nxt_seq nsec_more
%type <unknown> rdata_unknown
| sp SP
;
+str: STR | QSTR;
+
trail: NL
| sp NL
;
-ttl_directive: DOLLAR_TTL sp STR trail
+ttl_directive: DOLLAR_TTL sp str trail
{
parser->default_ttl = zparser_ttl2int($3.str, &(parser->error_occurred));
if (parser->error_occurred == 1) {
}
;
-label: STR
+label: str
{
if ($1.len > MAXLABELLEN) {
zc_error("label exceeds %d character limit", MAXLABELLEN);
}
;
-wire_label: STR
+wire_label: str
{
char *result = (char *) region_alloc(parser->rr_region,
$1.len + 1);
}
;
-str_seq: dotted_str
+str_seq: unquoted_dotted_str
+ {
+ zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $1.str, $1.len), 1);
+ }
+ | QSTR
{
zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $1.str, $1.len), 1);
}
- | str_seq sp dotted_str
+ | QSTR unquoted_dotted_str
{
+ zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $1.str, $1.len), 1);
+ zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $2.str, $2.len), 0);
+ }
+ | str_seq QSTR
+ {
+ zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $2.str, $2.len), 0);
+ }
+ | str_seq QSTR unquoted_dotted_str
+ {
+ zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $2.str, $2.len), 0);
zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $3.str, $3.len), 0);
}
+ | str_seq sp unquoted_dotted_str
+ {
+ zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $3.str, $3.len), 0);
+ }
+ | str_seq sp QSTR
+ {
+ zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $3.str, $3.len), 0);
+ }
+ | str_seq sp QSTR unquoted_dotted_str
+ {
+ zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $3.str, $3.len), 0);
+ zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $4.str, $4.len), 0);
+ }
;
/*
* Generate a single string from multiple STR tokens, separated by
* spaces or dots.
*/
-concatenated_str_seq: STR
+concatenated_str_seq: str
| '.'
{
$$.len = 1;
$$.str = region_strdup(parser->rr_region, ".");
}
- | concatenated_str_seq sp STR
+ | concatenated_str_seq sp str
{
$$.len = $1.len + $3.len + 1;
$$.str = (char *) region_alloc(parser->rr_region, $$.len + 1);
memcpy($$.str + $1.len + 1, $3.str, $3.len);
$$.str[$$.len] = '\0';
}
- | concatenated_str_seq '.' STR
+ | concatenated_str_seq '.' str
{
$$.len = $1.len + $3.len + 1;
$$.str = (char *) region_alloc(parser->rr_region, $$.len + 1);
;
/* used to convert a nxt list of types */
-nxt_seq: STR
+nxt_seq: str
{
uint16_t type = rrtype_from_string($1.str);
if (type != 0 && type < 128) {
zc_error("bad type %d in NXT record", (int) type);
}
}
- | nxt_seq sp STR
+ | nxt_seq sp str
{
uint16_t type = rrtype_from_string($3.str);
if (type != 0 && type < 128) {
| NL
{
}
- | STR nsec_seq
+ | str nsec_seq
{
uint16_t type = rrtype_from_string($1.str);
if (type != 0) {
* Sequence of STR tokens separated by spaces. The spaces are not
* preserved during concatenation.
*/
-str_sp_seq: STR
- | str_sp_seq sp STR
+str_sp_seq: str
+ | str_sp_seq sp str
{
char *result = (char *) region_alloc(parser->rr_region,
$1.len + $3.len + 1);
* Sequence of STR tokens separated by dots. The dots are not
* preserved during concatenation.
*/
-str_dot_seq: STR
- | str_dot_seq '.' STR
+str_dot_seq: str
+ | str_dot_seq '.' str
{
char *result = (char *) region_alloc(parser->rr_region,
$1.len + $3.len + 1);
/*
* A string that can contain dots.
*/
-dotted_str: STR
+unquoted_dotted_str: STR
| '.'
{
$$.str = ".";
$$.len = 1;
}
- | dotted_str '.'
+ | unquoted_dotted_str '.'
{
char *result = (char *) region_alloc(parser->rr_region,
$1.len + 2);
$$.len = $1.len + 1;
$$.str[$$.len] = '\0';
}
- | dotted_str '.' STR
+ | unquoted_dotted_str '.' STR
{
char *result = (char *) region_alloc(parser->rr_region,
$1.len + $3.len + 2);
}
;
+/*
+ * A string that can contain dots or a quoted string.
+ */
+dotted_str: unquoted_dotted_str | QSTR
+
/* define what we can parse */
type_and_rdata:
/*
| 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); }
- | STR error NL
+ | str error NL
{
zc_error_prev_line("unrecognized RR type '%s'", $1.str);
}
}
;
-rdata_soa: dname sp dname sp STR sp STR sp STR sp STR sp STR trail
+rdata_soa: dname sp dname sp str sp str sp str sp str sp str trail
{
/* convert the soa data */
zadd_rdata_domain($1); /* prim. ns */
}
;
-rdata_wks: dotted_str sp STR sp concatenated_str_seq trail
+rdata_wks: dotted_str sp str sp concatenated_str_seq trail
{
zadd_rdata_wireformat(zparser_conv_a(parser->region, $1.str)); /* address */
zadd_rdata_wireformat(zparser_conv_services(parser->region, $3.str, $5.str)); /* protocol and services */
}
;
-rdata_hinfo: STR sp STR trail
+rdata_hinfo: str sp str trail
{
zadd_rdata_wireformat(zparser_conv_text(parser->region, $1.str, $1.len)); /* CPU */
zadd_rdata_wireformat(zparser_conv_text(parser->region, $3.str, $3.len)); /* OS*/
}
;
-rdata_mx: STR sp dname trail
+rdata_mx: str sp dname trail
{
zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* priority */
zadd_rdata_domain($3); /* MX host */
;
/* RFC 1183 */
-rdata_afsdb: STR sp dname trail
+rdata_afsdb: str sp dname trail
{
zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* subtype */
zadd_rdata_domain($3); /* domain name */
;
/* RFC 1183 */
-rdata_x25: STR trail
+rdata_x25: str trail
{
zadd_rdata_wireformat(zparser_conv_text(parser->region, $1.str, $1.len)); /* X.25 address. */
}
;
/* RFC 1183 */
-rdata_isdn: STR trail
+rdata_isdn: str trail
{
zadd_rdata_wireformat(zparser_conv_text(parser->region, $1.str, $1.len)); /* address */
}
- | STR sp STR trail
+ | str sp str trail
{
zadd_rdata_wireformat(zparser_conv_text(parser->region, $1.str, $1.len)); /* address */
zadd_rdata_wireformat(zparser_conv_text(parser->region, $3.str, $3.len)); /* sub-address */
;
/* RFC 1183 */
-rdata_rt: STR sp dname trail
+rdata_rt: str sp dname trail
{
zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* preference */
zadd_rdata_domain($3); /* intermediate host */
;
/* RFC 2163 */
-rdata_px: STR sp dname sp dname trail
+rdata_px: str sp dname sp dname trail
{
zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* preference */
zadd_rdata_domain($3); /* MAP822 */
}
;
-rdata_srv: STR sp STR sp STR sp dname trail
+rdata_srv: str sp str sp str sp dname trail
{
zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* prio */
zadd_rdata_wireformat(zparser_conv_short(parser->region, $3.str)); /* weight */
;
/* RFC 2915 */
-rdata_naptr: STR sp STR sp STR sp STR sp STR sp dname trail
+rdata_naptr: str sp str sp str sp str sp str sp dname trail
{
zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* order */
zadd_rdata_wireformat(zparser_conv_short(parser->region, $3.str)); /* preference */
;
/* RFC 2230 */
-rdata_kx: STR sp dname trail
+rdata_kx: str sp dname trail
{
zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* preference */
zadd_rdata_domain($3); /* exchanger */
;
/* RFC 2538 */
-rdata_cert: STR sp STR sp STR sp str_sp_seq trail
+rdata_cert: str sp str sp str sp str_sp_seq trail
{
zadd_rdata_wireformat(zparser_conv_certificate_type(parser->region, $1.str)); /* type */
zadd_rdata_wireformat(zparser_conv_short(parser->region, $3.str)); /* key tag */
}
;
-rdata_ds: STR sp STR sp STR sp str_sp_seq trail
+rdata_ds: str sp str sp str sp str_sp_seq trail
{
zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* keytag */
zadd_rdata_wireformat(zparser_conv_algorithm(parser->region, $3.str)); /* alg */
}
;
-rdata_dlv: STR sp STR sp STR sp str_sp_seq trail
+rdata_dlv: str sp str sp str sp str_sp_seq trail
{
zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* keytag */
zadd_rdata_wireformat(zparser_conv_algorithm(parser->region, $3.str)); /* alg */
}
;
-rdata_sshfp: STR sp STR sp str_sp_seq trail
+rdata_sshfp: str sp str sp str_sp_seq trail
{
zadd_rdata_wireformat(zparser_conv_byte(parser->region, $1.str)); /* alg */
zadd_rdata_wireformat(zparser_conv_byte(parser->region, $3.str)); /* fp type */
}
;
-rdata_rrsig: STR sp STR sp STR sp STR sp STR sp STR sp STR sp wire_dname sp str_sp_seq trail
+rdata_rrsig: str sp str sp str sp str sp str sp str sp str sp wire_dname sp str_sp_seq trail
{
zadd_rdata_wireformat(zparser_conv_rrtype(parser->region, $1.str)); /* rr covered */
zadd_rdata_wireformat(zparser_conv_algorithm(parser->region, $3.str)); /* alg */
}
;
-rdata_nsec3: STR sp STR sp STR sp STR sp STR nsec_seq
+rdata_nsec3: str sp str sp str sp str sp str nsec_seq
{
#ifdef NSEC3
nsec3_add_params($1.str, $3.str, $5.str, $7.str, $7.len);
}
;
-rdata_nsec3_param: STR sp STR sp STR sp STR trail
+rdata_nsec3_param: str sp str sp str sp str trail
{
#ifdef NSEC3
nsec3_add_params($1.str, $3.str, $5.str, $7.str, $7.len);
}
;
-rdata_tlsa: STR sp STR sp STR sp str_sp_seq trail
+rdata_tlsa: str sp str sp str sp str_sp_seq trail
{
zadd_rdata_wireformat(zparser_conv_byte(parser->region, $1.str)); /* usage */
zadd_rdata_wireformat(zparser_conv_byte(parser->region, $3.str)); /* selector */
}
;
-rdata_smimea: STR sp STR sp STR sp str_sp_seq trail
+rdata_smimea: str sp str sp str sp str_sp_seq trail
{
zadd_rdata_wireformat(zparser_conv_byte(parser->region, $1.str)); /* usage */
zadd_rdata_wireformat(zparser_conv_byte(parser->region, $3.str)); /* selector */
}
;
-rdata_dnskey: STR sp STR sp STR sp str_sp_seq trail
+rdata_dnskey: str sp str sp str sp str_sp_seq trail
{
zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* flags */
zadd_rdata_wireformat(zparser_conv_byte(parser->region, $3.str)); /* proto */
}
;
-rdata_ipsec_base: STR sp STR sp STR sp dotted_str
+rdata_ipsec_base: str sp str sp str sp dotted_str
{
const dname_type* name = 0;
zadd_rdata_wireformat(zparser_conv_byte(parser->region, $1.str)); /* precedence */
;
/* RFC 6742 */
-rdata_nid: STR sp dotted_str trail
+rdata_nid: str sp dotted_str trail
{
zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* preference */
zadd_rdata_wireformat(zparser_conv_ilnp64(parser->region, $3.str)); /* NodeID */
}
;
-rdata_l32: STR sp dotted_str trail
+rdata_l32: str sp dotted_str trail
{
zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* preference */
zadd_rdata_wireformat(zparser_conv_a(parser->region, $3.str)); /* Locator32 */
}
;
-rdata_l64: STR sp dotted_str trail
+rdata_l64: str sp dotted_str trail
{
zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* preference */
zadd_rdata_wireformat(zparser_conv_ilnp64(parser->region, $3.str)); /* Locator64 */
}
;
-rdata_lp: STR sp dname trail
+rdata_lp: str sp dname trail
{
zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* preference */
zadd_rdata_domain($3); /* FQDN */
}
;
-rdata_eui48: STR trail
+rdata_eui48: str trail
{
zadd_rdata_wireformat(zparser_conv_eui(parser->region, $1.str, 48));
}
;
-rdata_eui64: STR trail
+rdata_eui64: str trail
{
zadd_rdata_wireformat(zparser_conv_eui(parser->region, $1.str, 64));
}
;
/* RFC7553 */
-rdata_uri: STR sp STR sp dotted_str trail
+rdata_uri: str sp str sp dotted_str trail
{
zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* priority */
zadd_rdata_wireformat(zparser_conv_short(parser->region, $3.str)); /* weight */
;
/* RFC 6844 */
-rdata_caa: STR sp STR sp dotted_str trail
+rdata_caa: str sp str sp dotted_str trail
{
zadd_rdata_wireformat(zparser_conv_byte(parser->region, $1.str)); /* Flags */
zadd_rdata_wireformat(zparser_conv_tag(parser->region, $3.str, $3.len)); /* Tag */
;
/* RFC7477 */
-rdata_csync: STR sp STR nsec_seq
+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));
;
/* draft-ietf-dnsop-dns-zone-digest */
-rdata_zonemd: STR sp STR sp STR sp str_sp_seq trail
+rdata_zonemd: str sp str sp str sp str_sp_seq trail
{
zadd_rdata_wireformat(zparser_conv_serial(parser->region, $1.str)); /* serial */
zadd_rdata_wireformat(zparser_conv_byte(parser->region, $3.str)); /* scheme */
}
;
-rdata_unknown: URR sp STR sp str_sp_seq trail
+rdata_unknown: URR sp str sp str_sp_seq trail
{
/* $2 is the number of octets, currently ignored */
$$ = zparser_conv_hex(parser->rr_region, $5.str, $5.len);
}
- | URR sp STR trail
+ | URR sp str trail
{
$$ = zparser_conv_hex(parser->rr_region, "", 0);
}