summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/nsd/Makefile.in13
-rw-r--r--usr.sbin/nsd/acx_nlnetlabs.m463
-rw-r--r--usr.sbin/nsd/axfr.c3
-rw-r--r--usr.sbin/nsd/config.h.in8
-rw-r--r--usr.sbin/nsd/configlexer.lex33
-rw-r--r--usr.sbin/nsd/configparser.y7
-rw-r--r--usr.sbin/nsd/configure203
-rw-r--r--usr.sbin/nsd/configure.ac147
-rw-r--r--usr.sbin/nsd/dbcreate.c2
-rw-r--r--usr.sbin/nsd/difffile.c2
-rw-r--r--usr.sbin/nsd/dname.c4
-rw-r--r--usr.sbin/nsd/dnstap/dnstap.c92
-rw-r--r--usr.sbin/nsd/dnstap/dnstap.h6
-rw-r--r--usr.sbin/nsd/dnstap/dnstap.m44
-rw-r--r--usr.sbin/nsd/dnstap/dnstap_collector.c45
-rw-r--r--usr.sbin/nsd/dnstap/dnstap_collector.h4
-rw-r--r--usr.sbin/nsd/edns.c6
-rw-r--r--usr.sbin/nsd/edns.h25
-rw-r--r--usr.sbin/nsd/namedb.h1
-rw-r--r--usr.sbin/nsd/nsd-checkconf.8.in2
-rw-r--r--usr.sbin/nsd/nsd-checkconf.c3
-rw-r--r--usr.sbin/nsd/nsd-checkzone.8.in2
-rw-r--r--usr.sbin/nsd/nsd-checkzone.c17
-rw-r--r--usr.sbin/nsd/nsd-control.8.in2
-rw-r--r--usr.sbin/nsd/nsd-control.c81
-rw-r--r--usr.sbin/nsd/nsd.8.in4
-rw-r--r--usr.sbin/nsd/nsd.c141
-rw-r--r--usr.sbin/nsd/nsd.conf.5.in65
-rw-r--r--usr.sbin/nsd/nsd.conf.sample.in13
-rw-r--r--usr.sbin/nsd/nsec3.c8
-rw-r--r--usr.sbin/nsd/options.c162
-rw-r--r--usr.sbin/nsd/options.h5
-rw-r--r--usr.sbin/nsd/query.c232
-rw-r--r--usr.sbin/nsd/remote.c8
-rw-r--r--usr.sbin/nsd/server.c111
-rw-r--r--usr.sbin/nsd/xfrd-tcp.c2
-rw-r--r--usr.sbin/nsd/xfrd.c4
-rw-r--r--usr.sbin/nsd/xfrd.h1
-rw-r--r--usr.sbin/nsd/zlexer.lex17
-rw-r--r--usr.sbin/nsd/zparser.y149
40 files changed, 1029 insertions, 668 deletions
diff --git a/usr.sbin/nsd/Makefile.in b/usr.sbin/nsd/Makefile.in
index 0fb1b23b6bb..e27708f8ae3 100644
--- a/usr.sbin/nsd/Makefile.in
+++ b/usr.sbin/nsd/Makefile.in
@@ -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
diff --git a/usr.sbin/nsd/acx_nlnetlabs.m4 b/usr.sbin/nsd/acx_nlnetlabs.m4
index 31e43d67e87..dd8d8c32985 100644
--- a/usr.sbin/nsd/acx_nlnetlabs.m4
+++ b/usr.sbin/nsd/acx_nlnetlabs.m4
@@ -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.
diff --git a/usr.sbin/nsd/axfr.c b/usr.sbin/nsd/axfr.c
index 50c1ea2eb60..cd96bd1cfd7 100644
--- a/usr.sbin/nsd/axfr.c
+++ b/usr.sbin/nsd/axfr.c
@@ -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;
}
diff --git a/usr.sbin/nsd/config.h.in b/usr.sbin/nsd/config.h.in
index c528729cc75..1454787bab4 100644
--- a/usr.sbin/nsd/config.h.in
+++ b/usr.sbin/nsd/config.h.in
@@ -199,6 +199,9 @@
/* 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
@@ -552,7 +555,8 @@
/* 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. */
@@ -824,10 +828,8 @@
#include <sys/types.h>
-#if STDC_HEADERS
#include <stdlib.h>
#include <stddef.h>
-#endif
#ifdef HAVE_TIME_H
#include <time.h>
diff --git a/usr.sbin/nsd/configlexer.lex b/usr.sbin/nsd/configlexer.lex
index 7ed3deb2f1f..99c045dac26 100644
--- a/usr.sbin/nsd/configlexer.lex
+++ b/usr.sbin/nsd/configlexer.lex
@@ -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; }
%%
diff --git a/usr.sbin/nsd/configparser.y b/usr.sbin/nsd/configparser.y
index 2834e66e38f..9ffda88c5f5 100644
--- a/usr.sbin/nsd/configparser.y
+++ b/usr.sbin/nsd/configparser.y
@@ -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");
diff --git a/usr.sbin/nsd/configure b/usr.sbin/nsd/configure
index 349068f5d0c..4de35b0a222 100644
--- a/usr.sbin/nsd/configure
+++ b/usr.sbin/nsd/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for NSD 4.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\\"
diff --git a/usr.sbin/nsd/configure.ac b/usr.sbin/nsd/configure.ac
index 06e2f0e3b7e..4f9946e9595 100644
--- a/usr.sbin/nsd/configure.ac
+++ b/usr.sbin/nsd/configure.ac
@@ -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>
diff --git a/usr.sbin/nsd/dbcreate.c b/usr.sbin/nsd/dbcreate.c
index b80d24083f1..13d4e9d444c 100644
--- a/usr.sbin/nsd/dbcreate.c
+++ b/usr.sbin/nsd/dbcreate.c
@@ -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;
diff --git a/usr.sbin/nsd/difffile.c b/usr.sbin/nsd/difffile.c
index 445745d2d5f..09ab8b7ebfb 100644
--- a/usr.sbin/nsd/difffile.c
+++ b/usr.sbin/nsd/difffile.c
@@ -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;
}
}
diff --git a/usr.sbin/nsd/dname.c b/usr.sbin/nsd/dname.c
index 6b9e964e147..6b8c812e5a6 100644
--- a/usr.sbin/nsd/dname.c
+++ b/usr.sbin/nsd/dname.c
@@ -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++ = '\\';
diff --git a/usr.sbin/nsd/dnstap/dnstap.c b/usr.sbin/nsd/dnstap/dnstap.c
index 8286441c2d8..1f4dabff1f3 100644
--- a/usr.sbin/nsd/dnstap/dnstap.c
+++ b/usr.sbin/nsd/dnstap/dnstap.c
@@ -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);
diff --git a/usr.sbin/nsd/dnstap/dnstap.h b/usr.sbin/nsd/dnstap/dnstap.h
index 05b1bd049f3..e5eaa2a1345 100644
--- a/usr.sbin/nsd/dnstap/dnstap.h
+++ b/usr.sbin/nsd/dnstap/dnstap.h
@@ -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);
diff --git a/usr.sbin/nsd/dnstap/dnstap.m4 b/usr.sbin/nsd/dnstap/dnstap.m4
index 5b78b3e267c..11b6de36509 100644
--- a/usr.sbin/nsd/dnstap/dnstap.m4
+++ b/usr.sbin/nsd/dnstap/dnstap.m4
@@ -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"
diff --git a/usr.sbin/nsd/dnstap/dnstap_collector.c b/usr.sbin/nsd/dnstap/dnstap_collector.c
index 091113fc45f..c582205579d 100644
--- a/usr.sbin/nsd/dnstap/dnstap_collector.c
+++ b/usr.sbin/nsd/dnstap/dnstap_collector.c
@@ -42,12 +42,12 @@ struct dt_collector* dt_collector_create(struct nsd* nsd)
dt_col->dt_env = NULL;
dt_col->region = region_create(xalloc, free);
dt_col->send_buffer = buffer_create(dt_col->region,
- /* msglen + is_response + addrlen + is_tcp + packetlen + packet + zonelen + zone + spare + addr */
+ /* msglen + is_response + addrlen + is_tcp + packetlen + packet + zonelen + zone + spare + local_addr + addr */
4+1+4+1+4+TCP_MAX_MESSAGE_LEN+4+MAXHOSTNAMELEN + 32 +
#ifdef INET6
- sizeof(struct sockaddr_storage)
+ sizeof(struct sockaddr_storage) + sizeof(struct sockaddr_storage)
#else
- sizeof(struct sockaddr_in)
+ sizeof(struct sockaddr_in) + sizeof(struct sockaddr_in)
#endif
);
@@ -190,9 +190,9 @@ dt_submit_content(struct dt_env* dt_env, struct buffer* buf)
{
uint8_t is_response, is_tcp;
#ifdef INET6
- struct sockaddr_storage addr;
+ struct sockaddr_storage local_addr, addr;
#else
- struct sockaddr_in addr;
+ struct sockaddr_in local_addr, addr;
#endif
socklen_t addrlen;
size_t pktlen;
@@ -205,8 +205,9 @@ dt_submit_content(struct dt_env* dt_env, struct buffer* buf)
buffer_skip(buf, 4); /* skip msglen */
is_response = buffer_read_u8(buf);
addrlen = buffer_read_u32(buf);
- if(addrlen > sizeof(addr)) return;
- if(!buffer_available(buf, addrlen)) return;
+ if(addrlen > sizeof(local_addr) || addrlen > sizeof(addr)) return;
+ if(!buffer_available(buf, 2*addrlen)) return;
+ buffer_read(buf, &local_addr, addrlen);
buffer_read(buf, &addr, addrlen);
if(!buffer_available(buf, 1+4)) return;
is_tcp = buffer_read_u8(buf);
@@ -227,10 +228,10 @@ dt_submit_content(struct dt_env* dt_env, struct buffer* buf)
/* submit it */
if(is_response) {
- dt_msg_send_auth_response(dt_env, &addr, is_tcp, zone,
+ dt_msg_send_auth_response(dt_env, &local_addr, &addr, is_tcp, zone,
zonelen, data, pktlen);
} else {
- dt_msg_send_auth_query(dt_env, &addr, is_tcp, zone,
+ dt_msg_send_auth_query(dt_env, &local_addr, &addr, is_tcp, zone,
zonelen, data, pktlen);
}
}
@@ -341,12 +342,12 @@ static void dt_attach_events(struct dt_collector* dt_col, struct nsd* nsd)
log_msg(LOG_ERR, "dnstap collector: event_add failed");
dt_col->inputs[i].buffer = buffer_create(dt_col->region,
- /* msglen + is_response + addrlen + is_tcp + packetlen + packet + zonelen + zone + spare + addr */
+ /* msglen + is_response + addrlen + is_tcp + packetlen + packet + zonelen + zone + spare + local_addr + addr */
4+1+4+1+4+TCP_MAX_MESSAGE_LEN+4+MAXHOSTNAMELEN + 32 +
#ifdef INET6
- sizeof(struct sockaddr_storage)
+ sizeof(struct sockaddr_storage) + sizeof(struct sockaddr_storage)
#else
- sizeof(struct sockaddr_in)
+ sizeof(struct sockaddr_in) + sizeof(struct sockaddr_in)
#endif
);
assert(buffer_capacity(dt_col->inputs[i].buffer) ==
@@ -400,19 +401,29 @@ void dt_collector_start(struct dt_collector* dt_col, struct nsd* nsd)
static int
prep_send_data(struct buffer* buf, uint8_t is_response,
#ifdef INET6
+ struct sockaddr_storage* local_addr,
struct sockaddr_storage* addr,
#else
+ struct sockaddr_in* local_addr,
struct sockaddr_in* addr,
#endif
socklen_t addrlen, int is_tcp, struct buffer* packet,
struct zone* zone)
{
buffer_clear(buf);
- if(!buffer_available(buf, 4+1+4+addrlen+1+4+buffer_remaining(packet)))
+#ifdef INET6
+ if(local_addr->ss_family != addr->ss_family)
+ return 0; /* must be same length to send */
+#else
+ if(local_addr->sin_family != addr->sin_family)
+ return 0; /* must be same length to send */
+#endif
+ if(!buffer_available(buf, 4+1+4+2*addrlen+1+4+buffer_remaining(packet)))
return 0; /* does not fit in send_buffer, log is dropped */
buffer_skip(buf, 4); /* the length of the message goes here */
buffer_write_u8(buf, is_response);
buffer_write_u32(buf, addrlen);
+ buffer_write(buf, local_addr, (size_t)addrlen);
buffer_write(buf, addr, (size_t)addrlen);
buffer_write_u8(buf, (is_tcp?1:0));
buffer_write_u32(buf, buffer_remaining(packet));
@@ -470,8 +481,10 @@ static void attempt_to_write(int s, uint8_t* data, size_t len)
void dt_collector_submit_auth_query(struct nsd* nsd,
#ifdef INET6
+ struct sockaddr_storage* local_addr,
struct sockaddr_storage* addr,
#else
+ struct sockaddr_in* local_addr,
struct sockaddr_in* addr,
#endif
socklen_t addrlen, int is_tcp, struct buffer* packet)
@@ -481,7 +494,7 @@ void dt_collector_submit_auth_query(struct nsd* nsd,
VERBOSITY(4, (LOG_INFO, "dnstap submit auth query"));
/* marshal data into send buffer */
- if(!prep_send_data(nsd->dt_collector->send_buffer, 0, addr, addrlen,
+ if(!prep_send_data(nsd->dt_collector->send_buffer, 0, local_addr, addr, addrlen,
is_tcp, packet, NULL))
return; /* probably did not fit in buffer */
@@ -493,8 +506,10 @@ void dt_collector_submit_auth_query(struct nsd* nsd,
void dt_collector_submit_auth_response(struct nsd* nsd,
#ifdef INET6
+ struct sockaddr_storage* local_addr,
struct sockaddr_storage* addr,
#else
+ struct sockaddr_in* local_addr,
struct sockaddr_in* addr,
#endif
socklen_t addrlen, int is_tcp, struct buffer* packet,
@@ -505,7 +520,7 @@ void dt_collector_submit_auth_response(struct nsd* nsd,
VERBOSITY(4, (LOG_INFO, "dnstap submit auth response"));
/* marshal data into send buffer */
- if(!prep_send_data(nsd->dt_collector->send_buffer, 1, addr, addrlen,
+ if(!prep_send_data(nsd->dt_collector->send_buffer, 1, local_addr, addr, addrlen,
is_tcp, packet, zone))
return; /* probably did not fit in buffer */
diff --git a/usr.sbin/nsd/dnstap/dnstap_collector.h b/usr.sbin/nsd/dnstap/dnstap_collector.h
index 4e0825bbaea..8a7352fe5f7 100644
--- a/usr.sbin/nsd/dnstap/dnstap_collector.h
+++ b/usr.sbin/nsd/dnstap/dnstap_collector.h
@@ -70,8 +70,10 @@ void dt_collector_start(struct dt_collector* dt_col, struct nsd* nsd);
*/
void dt_collector_submit_auth_query(struct nsd* nsd,
#ifdef INET6
+ struct sockaddr_storage* local_addr,
struct sockaddr_storage* addr,
#else
+ struct sockaddr_in* local_addr,
struct sockaddr_in* addr,
#endif
socklen_t addrlen, int is_tcp, struct buffer* packet);
@@ -82,8 +84,10 @@ void dt_collector_submit_auth_query(struct nsd* nsd,
*/
void dt_collector_submit_auth_response(struct nsd* nsd,
#ifdef INET6
+ struct sockaddr_storage* local_addr,
struct sockaddr_storage* addr,
#else
+ struct sockaddr_in* local_addr,
struct sockaddr_in* addr,
#endif
socklen_t addrlen, int is_tcp, struct buffer* packet,
diff --git a/usr.sbin/nsd/edns.c b/usr.sbin/nsd/edns.c
index c6012b21111..15e468fc2ba 100644
--- a/usr.sbin/nsd/edns.c
+++ b/usr.sbin/nsd/edns.c
@@ -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);
}
diff --git a/usr.sbin/nsd/edns.h b/usr.sbin/nsd/edns.h
index 9325beb244c..c230a332940 100644
--- a/usr.sbin/nsd/edns.h
+++ b/usr.sbin/nsd/edns.h
@@ -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,
diff --git a/usr.sbin/nsd/namedb.h b/usr.sbin/nsd/namedb.h
index ad43da86751..089a8580217 100644
--- a/usr.sbin/nsd/namedb.h
+++ b/usr.sbin/nsd/namedb.h
@@ -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 */
diff --git a/usr.sbin/nsd/nsd-checkconf.8.in b/usr.sbin/nsd/nsd-checkconf.8.in
index 5355b408580..3e272147138 100644
--- a/usr.sbin/nsd/nsd-checkconf.8.in
+++ b/usr.sbin/nsd/nsd-checkconf.8.in
@@ -1,4 +1,4 @@
-.TH "nsd\-checkconf" "8" "Dec 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"
diff --git a/usr.sbin/nsd/nsd-checkconf.c b/usr.sbin/nsd/nsd-checkconf.c
index b392c71113b..28fba0dbf7f 100644
--- a/usr.sbin/nsd/nsd-checkconf.c
+++ b/usr.sbin/nsd/nsd-checkconf.c
@@ -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)
diff --git a/usr.sbin/nsd/nsd-checkzone.8.in b/usr.sbin/nsd/nsd-checkzone.8.in
index 27195a65517..e80603a9b8e 100644
--- a/usr.sbin/nsd/nsd-checkzone.8.in
+++ b/usr.sbin/nsd/nsd-checkzone.8.in
@@ -1,4 +1,4 @@
-.TH "nsd\-checkzone" "8" "Dec 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"
diff --git a/usr.sbin/nsd/nsd-checkzone.c b/usr.sbin/nsd/nsd-checkzone.c
index 9bf74fd6538..701e7f62db8 100644
--- a/usr.sbin/nsd/nsd-checkzone.c
+++ b/usr.sbin/nsd/nsd-checkzone.c
@@ -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 */
diff --git a/usr.sbin/nsd/nsd-control.8.in b/usr.sbin/nsd/nsd-control.8.in
index 56ef19386a9..81fd57a45bc 100644
--- a/usr.sbin/nsd/nsd-control.8.in
+++ b/usr.sbin/nsd/nsd-control.8.in
@@ -1,4 +1,4 @@
-.TH "nsd\-control" "8" "Dec 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"
diff --git a/usr.sbin/nsd/nsd-control.c b/usr.sbin/nsd/nsd-control.c
index 1216e248ae9..3d77790446f 100644
--- a/usr.sbin/nsd/nsd-control.c
+++ b/usr.sbin/nsd/nsd-control.c
@@ -59,6 +59,10 @@
#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
diff --git a/usr.sbin/nsd/nsd.8.in b/usr.sbin/nsd/nsd.8.in
index cec7a9761eb..cfddfd04164 100644
--- a/usr.sbin/nsd/nsd.8.in
+++ b/usr.sbin/nsd/nsd.8.in
@@ -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 ]
diff --git a/usr.sbin/nsd/nsd.c b/usr.sbin/nsd/nsd.c
index 28b294e8903..860a76e0553 100644
--- a/usr.sbin/nsd/nsd.c
+++ b/usr.sbin/nsd/nsd.c
@@ -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
diff --git a/usr.sbin/nsd/nsd.conf.5.in b/usr.sbin/nsd/nsd.conf.5.in
index bd8589d6978..d03471ddd30 100644
--- a/usr.sbin/nsd/nsd.conf.5.in
+++ b/usr.sbin/nsd/nsd.conf.5.in
@@ -1,4 +1,4 @@
-.TH "nsd.conf" "5" "Dec 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'.
diff --git a/usr.sbin/nsd/nsd.conf.sample.in b/usr.sbin/nsd/nsd.conf.sample.in
index 05706265964..61eedef3db4 100644
--- a/usr.sbin/nsd/nsd.conf.sample.in
+++ b/usr.sbin/nsd/nsd.conf.sample.in
@@ -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.
diff --git a/usr.sbin/nsd/nsec3.c b/usr.sbin/nsd/nsec3.c
index c49014016cd..3139236af20 100644
--- a/usr.sbin/nsd/nsec3.c
+++ b/usr.sbin/nsd/nsec3.c
@@ -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;
}
diff --git a/usr.sbin/nsd/options.c b/usr.sbin/nsd/options.c
index 4de83334bad..b5dd5fe0ae9 100644
--- a/usr.sbin/nsd/options.c
+++ b/usr.sbin/nsd/options.c
@@ -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 */
+}
diff --git a/usr.sbin/nsd/options.h b/usr.sbin/nsd/options.h
index 14a7f88bfef..2bda9aa341e 100644
--- a/usr.sbin/nsd/options.h
+++ b/usr.sbin/nsd/options.h
@@ -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 */
diff --git a/usr.sbin/nsd/query.c b/usr.sbin/nsd/query.c
index 5cdc877753d..7092968a19c 100644
--- a/usr.sbin/nsd/query.c
+++ b/usr.sbin/nsd/query.c
@@ -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);
diff --git a/usr.sbin/nsd/remote.c b/usr.sbin/nsd/remote.c
index f677d9495e3..4cea3122113 100644
--- a/usr.sbin/nsd/remote.c
+++ b/usr.sbin/nsd/remote.c
@@ -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;
diff --git a/usr.sbin/nsd/server.c b/usr.sbin/nsd/server.c
index b666d0c63d9..52e6ecaadf4 100644
--- a/usr.sbin/nsd/server.c
+++ b/usr.sbin/nsd/server.c
@@ -87,6 +87,37 @@
#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);
diff --git a/usr.sbin/nsd/xfrd-tcp.c b/usr.sbin/nsd/xfrd-tcp.c
index d00c13b756a..4e3a6a48c28 100644
--- a/usr.sbin/nsd/xfrd-tcp.c
+++ b/usr.sbin/nsd/xfrd-tcp.c
@@ -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);
}
diff --git a/usr.sbin/nsd/xfrd.c b/usr.sbin/nsd/xfrd.c
index 65d6d955af6..8d2b1091452 100644
--- a/usr.sbin/nsd/xfrd.c
+++ b/usr.sbin/nsd/xfrd.c
@@ -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;
diff --git a/usr.sbin/nsd/xfrd.h b/usr.sbin/nsd/xfrd.h
index 4890ce0b53f..a3e68ffa135 100644
--- a/usr.sbin/nsd/xfrd.h
+++ b/usr.sbin/nsd/xfrd.h
@@ -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;
diff --git a/usr.sbin/nsd/zlexer.lex b/usr.sbin/nsd/zlexer.lex
index 14dfbf3c7fd..98635ccbe35 100644
--- a/usr.sbin/nsd/zlexer.lex
+++ b/usr.sbin/nsd/zlexer.lex
@@ -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})* {
diff --git a/usr.sbin/nsd/zparser.y b/usr.sbin/nsd/zparser.y
index 7306ac13216..89aca35211a 100644
--- a/usr.sbin/nsd/zparser.y
+++ b/usr.sbin/nsd/zparser.y
@@ -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);
}