merge NSD 4.3.6rc1
authorsthen <sthen@openbsd.org>
Thu, 1 Apr 2021 09:56:11 +0000 (09:56 +0000)
committersthen <sthen@openbsd.org>
Thu, 1 Apr 2021 09:56:11 +0000 (09:56 +0000)
38 files changed:
usr.sbin/nsd/Makefile.in
usr.sbin/nsd/acx_nlnetlabs.m4
usr.sbin/nsd/axfr.c
usr.sbin/nsd/config.h.in
usr.sbin/nsd/configlexer.lex
usr.sbin/nsd/configparser.y
usr.sbin/nsd/configure
usr.sbin/nsd/configure.ac
usr.sbin/nsd/dbcreate.c
usr.sbin/nsd/difffile.c
usr.sbin/nsd/dname.c
usr.sbin/nsd/dnstap/dnstap.c
usr.sbin/nsd/dnstap/dnstap.h
usr.sbin/nsd/dnstap/dnstap.m4
usr.sbin/nsd/edns.c
usr.sbin/nsd/edns.h
usr.sbin/nsd/namedb.h
usr.sbin/nsd/nsd-checkconf.8.in
usr.sbin/nsd/nsd-checkconf.c
usr.sbin/nsd/nsd-checkzone.8.in
usr.sbin/nsd/nsd-checkzone.c
usr.sbin/nsd/nsd-control.8.in
usr.sbin/nsd/nsd-control.c
usr.sbin/nsd/nsd.8.in
usr.sbin/nsd/nsd.c
usr.sbin/nsd/nsd.conf.5.in
usr.sbin/nsd/nsd.conf.sample.in
usr.sbin/nsd/nsec3.c
usr.sbin/nsd/options.c
usr.sbin/nsd/options.h
usr.sbin/nsd/query.c
usr.sbin/nsd/remote.c
usr.sbin/nsd/server.c
usr.sbin/nsd/xfrd-tcp.c
usr.sbin/nsd/xfrd.c
usr.sbin/nsd/xfrd.h
usr.sbin/nsd/zlexer.lex
usr.sbin/nsd/zparser.y

index 0fb1b23..e27708f 100644 (file)
@@ -73,6 +73,7 @@ EDIT          = $(SED) \
                        -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
@@ -344,13 +345,13 @@ zparser.c zparser.h: $(srcdir)/zparser.y
 
 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 \
@@ -417,11 +418,11 @@ axfr.o: $(srcdir)/axfr.c config.h $(srcdir)/axfr.h $(srcdir)/nsd.h $(srcdir)/dns
  $(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
@@ -467,7 +468,7 @@ nsec3.o: $(srcdir)/nsec3.c config.h $(srcdir)/nsec3.h $(srcdir)/iterated_hash.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
index 31e43d6..dd8d8c3 100644 (file)
@@ -2,7 +2,10 @@
 # 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).
@@ -447,15 +450,12 @@ AC_DEFUN([ACX_CHECK_FORMAT_ATTRIBUTE],
 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)
@@ -484,14 +484,11 @@ AC_DEFUN([ACX_CHECK_UNUSED_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.
@@ -548,7 +545,7 @@ dnl as a requirement so that is gets called before LIBTOOL
 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.
@@ -677,14 +674,14 @@ AC_DEFUN([ACX_SSL_CHECKS], [
             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"
@@ -692,10 +689,10 @@ AC_DEFUN([ACX_SSL_CHECKS], [
                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) 
@@ -706,10 +703,10 @@ AC_DEFUN([ACX_SSL_CHECKS], [
                     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) 
@@ -720,10 +717,10 @@ AC_DEFUN([ACX_SSL_CHECKS], [
                         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) 
@@ -750,8 +747,7 @@ dnl Checks main header files of SSL.
 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"
@@ -769,8 +765,7 @@ dnl Checks main header files of SSL.
 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"
@@ -894,7 +889,7 @@ AC_CACHE_VAL(cv_cc_deprecated_$cache,
 [
 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"
@@ -1062,7 +1057,7 @@ dnl defines MKDIR_HAS_ONE_ARG
 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
@@ -1071,14 +1066,12 @@ AC_TRY_COMPILE([
 #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.
index 50c1ea2..cd96bd1 100644 (file)
@@ -191,6 +191,9 @@ answer_axfr_ixfr(struct nsd *nsd, struct query *q)
                                        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;
                        }
index c528729..1454787 100644 (file)
 /* 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>
index 7ed3deb..99c045d 100644 (file)
@@ -7,9 +7,10 @@
  * 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>
@@ -19,7 +20,6 @@
 #endif
 
 #include "options.h"
-#include "configyyrename.h"
 #include "configparser.h"
 
 #if 0
@@ -43,27 +43,27 @@ static void config_start_include(const char* filename)
        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);
@@ -91,7 +91,7 @@ static void config_start_include_glob(const char* filename)
        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;
                }
@@ -237,6 +237,7 @@ request-xfr{COLON}  { LEXOUT(("v(%s) ", yytext)); return VAR_REQUEST_XFR;}
 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;}
@@ -314,14 +315,14 @@ server-[1-9][0-9]*-cpu-affinity{COLON}    {
                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(); }
@@ -330,14 +331,14 @@ server-[1-9][0-9]*-cpu-affinity{COLON}    {
         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 */ }
@@ -349,7 +350,7 @@ include{COLON}              { LEXOUT(("v(%s) ", yytext)); BEGIN(include); }
        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(); }
@@ -371,6 +372,6 @@ include{COLON}              { LEXOUT(("v(%s) ", yytext)); BEGIN(include); }
 }
 
 {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; }
 
 %%
index 2834e66..9ffda88 100644 (file)
@@ -20,7 +20,6 @@
 #include "dname.h"
 #include "tsig.h"
 #include "rrl.h"
-#include "configyyrename.h"
 
 int yylex(void);
 
@@ -151,6 +150,7 @@ static int parse_range(const char *str, long long *low, long long *high);
 %token VAR_ZONEFILE
 %token VAR_NOTIFY
 %token VAR_PROVIDE_XFR
+%token VAR_ALLOW_QUERY
 %token VAR_AXFR
 %token VAR_UDP
 %token VAR_NOTIFY_RETRY
@@ -825,6 +825,11 @@ pattern_or_zone_option:
       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");
index 349068f..4de35b0 100644 (file)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for NSD 4.3.4.
+# Generated by GNU Autoconf 2.69 for NSD 4.3.6.
 #
 # Report bugs to <nsd-bugs@nlnetlabs.nl>.
 #
@@ -580,8 +580,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='NSD'
 PACKAGE_TARNAME='nsd'
-PACKAGE_VERSION='4.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=''
 
@@ -1314,7 +1314,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures NSD 4.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]...
 
@@ -1376,7 +1376,7 @@ fi
 
 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
 
@@ -1536,7 +1536,7 @@ fi
 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.
@@ -2245,7 +2245,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by NSD $as_me 4.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 $@
@@ -3863,7 +3863,6 @@ $as_echo "$ac_cv_safe_to_define___extensions__" >&6; }
   $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
@@ -6201,118 +6200,6 @@ $as_echo "#define USE_MINI_EVENT 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 :
@@ -6354,10 +6241,11 @@ $as_echo "#define HAVE_SYS_WAIT_H 1" >>confdefs.h
 
 fi
 
-for ac_header in time.h arpa/inet.h signal.h string.h strings.h fcntl.h limits.h netinet/in.h 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
@@ -6833,10 +6721,8 @@ else
 /* end confdefs.h.  */
 
 #include <sys/types.h>
-#if STDC_HEADERS
 #include <stdlib.h>
 #include <stddef.h>
-#endif
 
 #ifdef HAVE_STDINT_H
 #include <stdint.h>
@@ -6886,10 +6772,8 @@ else
 /* end confdefs.h.  */
 
 #include <sys/types.h>
-#if STDC_HEADERS
 #include <stdlib.h>
 #include <stddef.h>
-#endif
 
 #ifdef HAVE_STDINT_H
 #include <stdint.h>
@@ -6939,10 +6823,8 @@ else
 /* end confdefs.h.  */
 
 #include <sys/types.h>
-#if STDC_HEADERS
 #include <stdlib.h>
 #include <stddef.h>
-#endif
 
 #ifdef HAVE_STDINT_H
 #include <stdint.h>
@@ -6992,10 +6874,8 @@ else
 /* end confdefs.h.  */
 
 #include <sys/types.h>
-#if STDC_HEADERS
 #include <stdlib.h>
 #include <stddef.h>
-#endif
 
 #ifdef HAVE_STDINT_H
 #include <stdint.h>
@@ -7045,10 +6925,8 @@ else
 /* end confdefs.h.  */
 
 #include <sys/types.h>
-#if STDC_HEADERS
 #include <stdlib.h>
 #include <stddef.h>
-#endif
 
 #ifdef HAVE_STDINT_H
 #include <stdint.h>
@@ -7098,10 +6976,8 @@ else
 /* end confdefs.h.  */
 
 #include <sys/types.h>
-#if STDC_HEADERS
 #include <stdlib.h>
 #include <stddef.h>
-#endif
 
 #ifdef HAVE_STDINT_H
 #include <stdint.h>
@@ -7151,10 +7027,8 @@ else
 /* end confdefs.h.  */
 
 #include <sys/types.h>
-#if STDC_HEADERS
 #include <stdlib.h>
 #include <stddef.h>
-#endif
 
 #ifdef HAVE_STDINT_H
 #include <stdint.h>
@@ -7204,10 +7078,8 @@ else
 /* end confdefs.h.  */
 
 #include <sys/types.h>
-#if STDC_HEADERS
 #include <stdlib.h>
 #include <stddef.h>
-#endif
 
 #ifdef HAVE_STDINT_H
 #include <stdint.h>
@@ -7257,10 +7129,8 @@ else
 /* end confdefs.h.  */
 
 #include <sys/types.h>
-#if STDC_HEADERS
 #include <stdlib.h>
 #include <stddef.h>
-#endif
 
 #ifdef HAVE_STDINT_H
 #include <stdint.h>
@@ -7310,10 +7180,8 @@ else
 /* end confdefs.h.  */
 
 #include <sys/types.h>
-#if STDC_HEADERS
 #include <stdlib.h>
 #include <stddef.h>
-#endif
 
 #ifdef HAVE_STDINT_H
 #include <stdint.h>
@@ -7363,10 +7231,8 @@ else
 /* end confdefs.h.  */
 
 #include <sys/types.h>
-#if STDC_HEADERS
 #include <stdlib.h>
 #include <stddef.h>
-#endif
 
 #ifdef HAVE_STDINT_H
 #include <stdint.h>
@@ -7416,10 +7282,8 @@ else
 /* end confdefs.h.  */
 
 #include <sys/types.h>
-#if STDC_HEADERS
 #include <stdlib.h>
 #include <stddef.h>
-#endif
 
 #ifdef HAVE_STDINT_H
 #include <stdint.h>
@@ -7904,38 +7768,8 @@ $as_echo "#define malloc rpl_malloc" >>confdefs.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; }
@@ -8338,7 +8172,8 @@ if test "$ac_res" != no; then :
   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
@@ -8477,7 +8312,8 @@ fi
 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
@@ -9845,7 +9681,8 @@ case "$enable_mmap" in
         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
@@ -9864,10 +9701,8 @@ else
 /* end confdefs.h.  */
 
 #include <sys/types.h>
-#if STDC_HEADERS
 #include <stdlib.h>
 #include <stddef.h>
-#endif
 
 #ifdef HAVE_STDINT_H
 #include <stdint.h>
@@ -10835,7 +10670,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by NSD $as_me 4.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
@@ -10897,7 +10732,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-NSD config.status 4.3.4
+NSD config.status 4.3.6
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
index 06e2f0e..4f9946e 100644 (file)
@@ -5,8 +5,8 @@ dnl
 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
@@ -23,7 +23,7 @@ cmdln="`echo $@ | sed -e 's/\\\\/\\\\\\\\/g' | sed -e 's/"/\\\\"/'g`"
 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
@@ -51,7 +51,7 @@ esac
 #
 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)
@@ -60,7 +60,7 @@ 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
@@ -72,7 +72,7 @@ AC_DEFINE_UNQUOTED(CONFIGFILE, ["`eval echo $nsd_conf_file`"], [Pathname to the
 #
 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)
 
@@ -91,7 +91,7 @@ else
        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])
@@ -101,7 +101,7 @@ AC_DEFINE_UNQUOTED(PIDFILE, ["`eval echo $pidfile`"], [Pathname to the NSD pidfi
 #
 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])
@@ -119,29 +119,26 @@ AC_SUBST(piddir)
 #
 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)
 
@@ -160,7 +157,7 @@ AC_DEFINE_UNQUOTED(NSD_START_PATH, ["$nsd_start_path"], [Pathname to start nsd f
 # 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])
@@ -172,7 +169,7 @@ AC_SUBST(chrootdir)
 #
 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])
@@ -182,7 +179,7 @@ AC_PROG_SED
 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
@@ -222,15 +219,12 @@ AC_DEFUN([AC_CHECK_FORMAT_ATTRIBUTE],
 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)
@@ -244,14 +238,11 @@ AC_DEFUN([AC_CHECK_UNUSED_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)
@@ -265,14 +256,11 @@ AC_DEFUN([CHECK_NORETURN_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)
@@ -313,14 +301,10 @@ AC_DEFUN([AC_CHECK_CTIME_R],
 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)
@@ -358,8 +342,7 @@ AC_CHECK_CTIME_R
 # 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"
@@ -381,9 +364,9 @@ AC_DEFUN([CHECK_SSL], [
             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";
@@ -397,8 +380,7 @@ AC_DEFUN([CHECK_SSL], [
 ])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)
@@ -466,9 +448,8 @@ else
 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],
 [
@@ -565,7 +546,7 @@ fi
 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
 
@@ -577,18 +558,15 @@ dnl systems to get some types.
 
 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>
@@ -650,13 +628,13 @@ AC_INCLUDES_DEFAULT
 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.]), [], [
@@ -664,7 +642,7 @@ AC_INCLUDES_DEFAULT
 #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], [
@@ -716,7 +694,7 @@ if echo $target_os | $EGREP -i 'linux|hurd' > /dev/null; then
 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],,,[
@@ -732,8 +710,7 @@ AC_INCLUDES_DEFAULT
 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
@@ -751,12 +728,12 @@ void testing (void) {
        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)
 ])])
 
@@ -919,7 +896,7 @@ dnl Determine the syslog facility to use
 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.])
 
@@ -928,14 +905,14 @@ dnl Determine the default tcp timeout
 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.])
@@ -944,7 +921,7 @@ case "$enable_root_server" in
                 ;;
 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)
                 ;;
@@ -953,7 +930,7 @@ case "$enable_ipv6" in
                ;;
 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|'')
@@ -963,7 +940,7 @@ case "$enable_bind8_stats" in
                ;;
 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.])
@@ -973,7 +950,7 @@ case "$enable_zone_stats" in
                ;;
 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" ])
@@ -986,11 +963,11 @@ case "$enable_checking" in
                 ;;
 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.])
@@ -1003,7 +980,7 @@ case "$enable_ratelimit" in
 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.])
@@ -1025,10 +1002,10 @@ if test x$HAVE_SSL = x"yes"; then
        # 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"
@@ -1084,7 +1061,7 @@ else
        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)
                ;;
@@ -1100,7 +1077,7 @@ case "$enable_nsec3" in
                 ;;
 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)
                ;;
@@ -1109,10 +1086,10 @@ case "$enable_minimal_responses" in
                 ;;
 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.])
@@ -1121,7 +1098,7 @@ case "$enable_mmap" in
                 ;;
 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)
        ;;
@@ -1130,7 +1107,7 @@ case "$enable_radix_tree" in
        ;;
 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.])
@@ -1164,7 +1141,7 @@ dt_DNSTAP([${localstatedir}/run/nsd-dnstap.sock],
 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
@@ -1219,10 +1196,8 @@ AH_BOTTOM([
 
 AH_BOTTOM([
 #include <sys/types.h>
-#if STDC_HEADERS
 #include <stdlib.h>
 #include <stddef.h>
-#endif
 
 #ifdef HAVE_TIME_H
 #include <time.h>
index b80d240..13d4e9d 100644 (file)
@@ -180,7 +180,7 @@ write_zone_to_udb(udb_base* udb, zone_type* zone, struct timespec* mtime,
        return 1;
 }
 
-static int
+int
 print_rrs(FILE* out, struct zone* zone)
 {
        rrset_type *rrset;
index 445745d..09ab8b7 100644 (file)
@@ -1349,7 +1349,7 @@ apply_ixfr_for_zone(nsd_type* nsd, zone_type* zonedb, FILE* in,
                                        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;
                                }
                        }
index 6b9e964..6b8c812 100644 (file)
@@ -416,7 +416,7 @@ dname_to_string(const dname_type *dname, const dname_type *origin)
                ++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++ = '\\';
@@ -512,7 +512,7 @@ char* wirelabel2str(const uint8_t* label)
        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++ = '\\';
index 8286441..1f4dabf 100644 (file)
@@ -292,51 +292,86 @@ dt_fill_buffer(uint8_t* pkt, size_t pktlen, ProtobufCBinaryData *p, protobuf_c_b
 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;
@@ -351,8 +386,10 @@ dt_msg_fill_net(struct dt_msg *dm,
 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)
@@ -380,11 +417,14 @@ dt_msg_send_auth_query(struct dt_env *env,
        /* 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);
 }
@@ -392,8 +432,10 @@ dt_msg_send_auth_query(struct dt_env *env,
 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)
@@ -421,8 +463,10 @@ dt_msg_send_auth_response(struct dt_env *env,
        /* 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);
 
index 05b1bd0..e5eaa2a 100644 (file)
@@ -108,6 +108,7 @@ dt_delete(struct dt_env *env);
 /**
  * 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.
@@ -118,8 +119,10 @@ dt_delete(struct dt_env *env);
 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);
@@ -127,6 +130,7 @@ dt_msg_send_auth_query(struct dt_env *env,
 /**
  * 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.
@@ -137,8 +141,10 @@ dt_msg_send_auth_query(struct dt_env *env,
 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);
index 5b78b3e..11b6de3 100644 (file)
@@ -20,7 +20,7 @@ AC_DEFUN([dt_DNSTAP],
     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
@@ -40,7 +40,7 @@ AC_DEFUN([dt_DNSTAP],
            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"
index c6012b2..15e468f 100644 (file)
@@ -58,6 +58,9 @@ edns_init_record(edns_record_type *edns)
        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 */
@@ -156,5 +159,6 @@ size_t
 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);
 }
index 9325beb..c230a33 100644 (file)
@@ -18,6 +18,7 @@ struct query;
 #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
@@ -44,12 +45,34 @@ struct edns_record
        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,
index ad43da8..089a858 100644 (file)
@@ -369,6 +369,7 @@ int udb_write_rr(struct udb_base* udb, struct udb_ptr* z, rr_type* rr);
 void udb_del_rr(struct udb_base* udb, struct udb_ptr* z, rr_type* rr);
 int write_zone_to_udb(struct udb_base* udb, zone_type* zone,
        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 */
index 5355b40..3e27214 100644 (file)
@@ -1,4 +1,4 @@
-.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"
index b392c71..28fba0d 100644 (file)
@@ -305,6 +305,7 @@ config_print_zone(nsd_options_type* opt, const char* k, int s, const char *o,
                }
                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);
@@ -337,6 +338,7 @@ config_print_zone(nsd_options_type* opt, const char* k, int s, const char *o,
                }
                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);
@@ -463,6 +465,7 @@ static void print_zone_content_elems(pattern_options_type* pat)
 #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)
index 27195a6..e80603a 100644 (file)
@@ -1,4 +1,4 @@
-.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"
index 9bf74fd..701e7f6 100644 (file)
@@ -31,13 +31,14 @@ struct nsd nsd;
 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;
@@ -67,6 +68,10 @@ check_zone(struct nsd* nsd, const char* name, const char* fname)
 #endif
                exit(1);
        }
+       if (out) {
+               print_rrs(out, zone);
+               printf("; ");
+       }
        printf("zone %s is ok\n", name);
        namedb_close(nsd->db);
 }
@@ -95,17 +100,21 @@ main(int argc, char *argv[])
 {
        /* 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();
@@ -128,7 +137,7 @@ main(int argc, char *argv[])
        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 */
 
index 56ef193..81fd57a 100644 (file)
@@ -1,4 +1,4 @@
-.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"
index 1216e24..3d77790 100644 (file)
 #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"
@@ -67,6 +71,9 @@ static void usage(void) ATTR_NORETURN;
 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()
@@ -185,6 +192,21 @@ setup_ctx(struct nsd_options* cfg)
        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)
@@ -270,17 +292,53 @@ 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;
 }
@@ -437,6 +495,7 @@ go(const char* cfgfile, char* svr, int argc, char* argv[])
        }
        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 */
@@ -464,10 +523,6 @@ int main(int argc, char* argv[])
        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
index cec7a97..cfddfd0 100644 (file)
@@ -1,9 +1,9 @@
-.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 ] 
index 28b294e..860a76e 100644 (file)
@@ -41,7 +41,9 @@
 #include <string.h>
 #include <time.h>
 #include <unistd.h>
+#ifdef HAVE_IFADDRS_H
 #include <ifaddrs.h>
+#endif
 
 #include "nsd.h"
 #include "options.h"
@@ -145,135 +147,6 @@ version(void)
        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)
 {
@@ -465,6 +338,7 @@ figure_default_sockets(
        figure_socket_servers(&(*tcp)[i], NULL);
 }
 
+#ifdef HAVE_GETIFADDRS
 static int
 find_device(
        struct nsd_socket *sock,
@@ -513,6 +387,7 @@ find_device(
 
        return 0;
 }
+#endif /* HAVE_GETIFADDRS */
 
 static void
 figure_sockets(
@@ -524,7 +399,9 @@ 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) {
@@ -539,9 +416,11 @@ figure_sockets(
                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));
@@ -560,6 +439,7 @@ figure_sockets(
                        (*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;
@@ -570,13 +450,16 @@ figure_sockets(
                                      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
index bd8589d..d03471d 100644 (file)
@@ -1,4 +1,4 @@
-.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"
@@ -161,7 +161,7 @@ anycast instances.  Use ip-transparent to be able to list addresses that
 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
@@ -534,13 +534,16 @@ the chroot and readable by the superuser only.
 .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
@@ -593,6 +596,7 @@ this pattern.  The referenced pattern must be defined above this one.
 .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 ,
@@ -647,6 +651,24 @@ third character in a two letter domain name).
 .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 
@@ -812,6 +834,43 @@ file, which may have different security policies, can be split apart.
 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'. 
index 0570626..61eedef 100644 (file)
@@ -255,7 +255,7 @@ server:
 # 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: ""
@@ -270,10 +270,14 @@ remote-control:
        # 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
@@ -319,6 +323,13 @@ remote-control:
        # 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.
index c490140..3139236 100644 (file)
@@ -977,6 +977,10 @@ nsec3_add_nonexist_proof(struct query* query, struct answer* answer,
                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
@@ -1187,6 +1191,10 @@ nsec3_answer_authoritative(struct domain** match, struct query *query,
                        /* 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;
        }
index 4de8333..b5dd5fe 100644 (file)
@@ -11,6 +11,9 @@
 #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"
@@ -18,7 +21,6 @@
 #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;
@@ -258,6 +260,15 @@ parse_options_file(struct nsd_options* opt, const char* file,
                                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)
@@ -828,6 +839,7 @@ pattern_options_create(region_type* region)
        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;
@@ -897,6 +909,7 @@ pattern_options_remove(struct nsd_options* opt, const char* name)
        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));
@@ -997,6 +1010,7 @@ pattern_options_add_modify(struct nsd_options* opt, struct pattern_options* p)
                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);
@@ -1014,6 +1028,7 @@ pattern_options_add_modify(struct nsd_options* opt, struct pattern_options* p)
                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);
        }
@@ -1050,6 +1065,7 @@ pattern_options_equal(struct pattern_options* p, struct pattern_options* q)
        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;
@@ -1222,6 +1238,7 @@ pattern_options_marshal(struct buffer* b, struct pattern_options* p)
        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);
@@ -1256,6 +1273,7 @@ pattern_options_unmarshal(region_type* r, struct buffer* b)
        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);
@@ -2050,6 +2068,7 @@ config_apply_pattern(struct pattern_options *dest, const char* name)
        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;
@@ -2104,3 +2123,144 @@ options_remote_is_address(struct nsd_options* cfg)
        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 */
+}
index 14a7f88..2bda9aa 100644 (file)
@@ -213,6 +213,7 @@ struct pattern_options {
        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
@@ -471,5 +472,9 @@ void config_apply_pattern(struct pattern_options *dest, const char* name);
  * 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 */
index 5cdc877..7092968 100644 (file)
@@ -540,6 +540,9 @@ answer_chaos(struct nsd *nsd, query_type *q)
                                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) ||
@@ -556,13 +559,23 @@ answer_chaos(struct nsd *nsd, query_type *q)
                                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;
        }
 
@@ -771,14 +784,29 @@ query_synthesize_cname(struct query* q, struct answer* answer, const dname_type*
           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);
@@ -844,7 +872,9 @@ query_synthesize_cname(struct query* q, struct answer* answer, const dname_type*
        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;
@@ -1074,6 +1104,7 @@ answer_authoritative(struct nsd   *nsd,
        domain_type *match;
        domain_type *original = closest_match;
        domain_type *dname_ce;
+       domain_type *wildcard_child;
        rrset_type *rrset;
 
 #ifdef NSEC3
@@ -1094,8 +1125,11 @@ answer_authoritative(struct nsd   *nsd,
        } 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);
@@ -1104,43 +1138,49 @@ answer_authoritative(struct nsd   *nsd,
                        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
@@ -1248,15 +1288,61 @@ answer_lookup_zone(struct nsd *nsd, struct query *q, answer_type *answer,
        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;
        }
 
@@ -1293,8 +1379,14 @@ answer_lookup_zone(struct nsd *nsd, struct query *q, answer_type *answer,
                        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;
                        }
                }
@@ -1303,8 +1395,13 @@ answer_lookup_zone(struct nsd *nsd, struct query *q, answer_type *answer,
        /* 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;
        }
 
@@ -1493,22 +1590,17 @@ query_process(query_type *q, nsd_type *nsd)
        }
 
        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))
@@ -1566,10 +1658,12 @@ query_process(query_type *q, nsd_type *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;
@@ -1603,6 +1697,14 @@ query_add_optional(query_type *q, nsd_type *nsd)
                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 */
@@ -1617,6 +1719,22 @@ query_add_optional(query_type *q, nsd_type *nsd)
                                /* 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);
index f677d94..4cea312 100644 (file)
@@ -91,6 +91,9 @@
 #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
@@ -2096,6 +2099,8 @@ do_assoc_tsig(RES* ssl, xfrd_state_type* xfrd, char* arg)
                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);
@@ -2137,7 +2142,8 @@ do_del_tsig(RES* ssl, xfrd_state_type* xfrd, char* arg) {
                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;
index b666d0c..52e6eca 100644 (file)
 
 #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
@@ -209,6 +240,17 @@ struct tcp_handler_data
         * 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.
@@ -3102,6 +3144,7 @@ service_remaining_tcp(struct nsd* nsd)
                }
 #endif
 
+               p->tcp_no_more_queries = 1;
                /* set timeout to 1/10 second */
                if(p->tcp_timeout > 100)
                        p->tcp_timeout = 100;
@@ -3299,7 +3342,12 @@ handle_udp(int fd, short event, void* arg)
                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 */
 
@@ -3333,7 +3381,12 @@ handle_udp(int fd, short event, void* arg)
                        }
 #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 */
@@ -3493,8 +3546,9 @@ handle_tcp_reading(int fd, short event, void* arg)
                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;
@@ -3634,7 +3688,12 @@ handle_tcp_reading(int fd, short event, void* arg)
 
        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);
@@ -3682,7 +3741,12 @@ handle_tcp_reading(int fd, short event, void* arg)
        }
 #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 */
@@ -3846,8 +3910,9 @@ handle_tcp_writing(int fd, short event, void* arg)
         * 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);
        }
@@ -3971,8 +4036,9 @@ handle_tls_reading(int fd, short event, void* arg)
                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;
@@ -4110,7 +4176,12 @@ handle_tls_reading(int fd, short event, void* arg)
 
        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);
@@ -4158,7 +4229,12 @@ handle_tls_reading(int fd, short event, void* arg)
        }
 #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 */
@@ -4286,8 +4362,9 @@ handle_tls_writing(int fd, short event, void* arg)
         * 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);
        }
@@ -4432,6 +4509,7 @@ handle_tcp_accept(int fd, short event, void* arg)
        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 */
@@ -4441,6 +4519,11 @@ handle_tcp_accept(int fd, short event, void* arg)
        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);
index d00c13b..4e3a6a4 100644 (file)
@@ -607,6 +607,7 @@ xfrd_tcp_setup_write_packet(struct xfrd_tcp_pipeline* tp, xfrd_zone_type* zone)
 
                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",
@@ -614,6 +615,7 @@ xfrd_tcp_setup_write_packet(struct xfrd_tcp_pipeline* tp, xfrd_zone_type* zone)
 
                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);
        }
index 65d6d95..8d2b109 100644 (file)
@@ -1586,6 +1586,7 @@ xfrd_send_ixfr_request_udp(xfrd_zone_type* zone)
        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);
@@ -2093,7 +2094,8 @@ xfrd_handle_received_xfr_packet(xfrd_zone_type* zone, buffer_type* packet)
                                        (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;
index 4890ce0..a3e68ff 100644 (file)
@@ -210,6 +210,7 @@ struct xfrd_zone {
        /* 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;
index 14dfbf3..98635cc 100644 (file)
@@ -7,6 +7,14 @@
  * 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"
 
@@ -122,7 +130,7 @@ SPACE   [ \t]
 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 ;
@@ -143,8 +151,9 @@ ANY     [^\"\n\\]|\\.
         */
 ^{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);
@@ -302,13 +311,13 @@ ANY     [^\"\n\\]|\\.
        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})* {
index 7306ac1..89aca35 100644 (file)
@@ -72,7 +72,7 @@ nsec3_add_params(const char* hash_algo_str, const char* flag_str,
 
 /* 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
 
@@ -84,7 +84,8 @@ nsec3_add_params(const char* hash_algo_str, const char* flag_str,
 %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
 
@@ -140,11 +141,13 @@ sp:       SP
     |  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) {
@@ -256,7 +259,7 @@ abs_dname:  '.'
     }
     ;
 
-label: STR
+label: str
     {
            if ($1.len > MAXLABELLEN) {
                    zc_error("label exceeds %d character limit", MAXLABELLEN);
@@ -352,7 +355,7 @@ wire_abs_dname:     '.'
     }
     ;
 
-wire_label:    STR
+wire_label:    str
     {
            char *result = (char *) region_alloc(parser->rr_region,
                                                 $1.len + 1);
@@ -382,27 +385,54 @@ wire_rel_dname:   wire_label
     }
     ;
 
-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);
@@ -411,7 +441,7 @@ concatenated_str_seq:       STR
            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);
@@ -423,7 +453,7 @@ concatenated_str_seq:       STR
     ;
 
 /* 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) {
@@ -432,7 +462,7 @@ nxt_seq:    STR
                    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) {
@@ -449,7 +479,7 @@ nsec_more:  SP nsec_more
     |  NL
     {
     }
-    |  STR nsec_seq
+    |  str nsec_seq
     {
            uint16_t type = rrtype_from_string($1.str);
            if (type != 0) {
@@ -471,8 +501,8 @@ nsec_seq:   NL
  * 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);
@@ -488,8 +518,8 @@ str_sp_seq: STR
  * 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);
@@ -504,13 +534,13 @@ str_dot_seq:      STR
 /*
  * 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);
@@ -520,7 +550,7 @@ dotted_str: STR
            $$.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);
@@ -533,6 +563,11 @@ dotted_str:        STR
     }
     ;
 
+/*
+ * A string that can contain dots or a quoted string.
+ */
+dotted_str:    unquoted_dotted_str | QSTR
+
 /* define what we can parse */
 type_and_rdata:
     /*
@@ -675,7 +710,7 @@ 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);
     }
@@ -700,7 +735,7 @@ rdata_domain_name:  dname trail
     }
     ;
 
-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 */
@@ -713,14 +748,14 @@ rdata_soa:        dname sp dname sp STR sp STR sp STR sp STR sp STR trail
     }
     ;
 
-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*/
@@ -735,7 +770,7 @@ rdata_minfo:        dname sp dname trail
     }
     ;
 
-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 */
@@ -757,7 +792,7 @@ rdata_rp:   dname sp dname trail
     ;
 
 /* 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 */
@@ -765,18 +800,18 @@ rdata_afsdb:      STR sp dname trail
     ;
 
 /* 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 */
@@ -784,7 +819,7 @@ rdata_isdn: STR trail
     ;
 
 /* 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 */
@@ -804,7 +839,7 @@ rdata_nsap: str_dot_seq trail
     ;
 
 /* 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 */
@@ -832,7 +867,7 @@ rdata_nxt:  dname sp nxt_seq trail
     }
     ;
 
-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 */
@@ -842,7 +877,7 @@ rdata_srv:  STR sp STR sp STR sp dname trail
     ;
 
 /* 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 */
@@ -854,7 +889,7 @@ rdata_naptr:        STR sp STR sp STR sp STR sp STR sp dname trail
     ;
 
 /* 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 */
@@ -862,7 +897,7 @@ rdata_kx:   STR sp dname trail
     ;
 
 /* 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 */
@@ -885,7 +920,7 @@ rdata_apl_seq:      dotted_str
     }
     ;
 
-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 */
@@ -894,7 +929,7 @@ rdata_ds:   STR sp STR sp STR sp str_sp_seq trail
     }
     ;
 
-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 */
@@ -903,7 +938,7 @@ rdata_dlv:  STR sp STR sp STR sp str_sp_seq trail
     }
     ;
 
-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 */
@@ -918,7 +953,7 @@ rdata_dhcid:        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
+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 */
@@ -943,7 +978,7 @@ rdata_nsec: wire_dname nsec_seq
     }
     ;
 
-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);
@@ -958,7 +993,7 @@ rdata_nsec3:   STR sp STR sp STR sp STR sp STR nsec_seq
     }
     ;
 
-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);
@@ -968,7 +1003,7 @@ rdata_nsec3_param:   STR sp STR sp STR sp STR trail
     }
     ;
 
-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 */
@@ -977,7 +1012,7 @@ rdata_tlsa:        STR sp STR sp STR sp str_sp_seq trail
     }
     ;
 
-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 */
@@ -986,7 +1021,7 @@ rdata_smimea:      STR sp STR sp STR sp str_sp_seq trail
     }
     ;
 
-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 */
@@ -995,7 +1030,7 @@ rdata_dnskey:      STR sp STR sp STR sp str_sp_seq trail
     }
     ;
 
-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 */
@@ -1048,48 +1083,48 @@ rdata_ipseckey: rdata_ipsec_base sp str_sp_seq trail
     ;
 
 /* 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 */
@@ -1098,7 +1133,7 @@ rdata_uri:        STR sp STR sp dotted_str trail
     ;
 
 /* 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 */
@@ -1114,7 +1149,7 @@ rdata_openpgpkey: str_sp_seq trail
     ;
 
 /* 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));
@@ -1125,7 +1160,7 @@ rdata_csync:      STR sp STR nsec_seq
     ;
 
 /* 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 */
@@ -1134,13 +1169,13 @@ rdata_zonemd:   STR sp STR sp STR sp str_sp_seq trail
     }
     ;
 
-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);
     }