summaryrefslogtreecommitdiffstats
path: root/usr.sbin/nsd
diff options
context:
space:
mode:
authorsthen <sthen@openbsd.org>2018-03-06 21:01:56 +0000
committersthen <sthen@openbsd.org>2018-03-06 21:01:56 +0000
commitb90bb40ec7347ca2da354e4585275903879368db (patch)
tree5073bf2a9be3f17a9aacd721c909ddf791786454 /usr.sbin/nsd
parentFix a small mistake from r1.229 causing sysctl(8) to print "newval -> newval" (diff)
downloadwireguard-openbsd-b90bb40ec7347ca2da354e4585275903879368db.tar.xz
wireguard-openbsd-b90bb40ec7347ca2da354e4585275903879368db.zip
update to NSD 4.1.20, ok florian@
- Fix memory leak in zone file read of unknown rr formatted RRs. - Fix memory leak when rehashing nsec3 after axfr or zonefile read, in the selectively allocated precompiled nsec3 hashes.
Diffstat (limited to 'usr.sbin/nsd')
-rw-r--r--usr.sbin/nsd/Makefile.in12
-rw-r--r--usr.sbin/nsd/configure32
-rw-r--r--usr.sbin/nsd/configure.ac6
-rw-r--r--usr.sbin/nsd/difffile.c1
-rw-r--r--usr.sbin/nsd/ipc.c10
-rw-r--r--usr.sbin/nsd/namedb.c10
-rw-r--r--usr.sbin/nsd/nsd.c14
-rw-r--r--usr.sbin/nsd/nsd.h6
-rw-r--r--usr.sbin/nsd/nsec3.c2
-rw-r--r--usr.sbin/nsd/options.c37
-rw-r--r--usr.sbin/nsd/query.c2
-rw-r--r--usr.sbin/nsd/rrl.c28
-rw-r--r--usr.sbin/nsd/rrl.h8
-rw-r--r--usr.sbin/nsd/server.c23
-rw-r--r--usr.sbin/nsd/xfrd.c50
-rw-r--r--usr.sbin/nsd/zonec.c7
-rw-r--r--usr.sbin/nsd/zparser.y6
17 files changed, 210 insertions, 44 deletions
diff --git a/usr.sbin/nsd/Makefile.in b/usr.sbin/nsd/Makefile.in
index 3468101c19d..5bd2364579c 100644
--- a/usr.sbin/nsd/Makefile.in
+++ b/usr.sbin/nsd/Makefile.in
@@ -373,7 +373,8 @@ edns.o: $(srcdir)/edns.c config.h $(srcdir)/dns.h $(srcdir)/edns.h $(srcdir)/buf
$(srcdir)/nsd.h $(srcdir)/query.h $(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/radtree.h $(srcdir)/rbtree.h $(srcdir)/packet.h $(srcdir)/tsig.h
ipc.o: $(srcdir)/ipc.c config.h $(srcdir)/ipc.h $(srcdir)/netio.h $(srcdir)/region-allocator.h $(srcdir)/buffer.h $(srcdir)/util.h \
$(srcdir)/xfrd-tcp.h $(srcdir)/xfrd.h $(srcdir)/rbtree.h $(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/dns.h $(srcdir)/radtree.h $(srcdir)/options.h \
- $(srcdir)/tsig.h $(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/xfrd-notify.h $(srcdir)/difffile.h $(srcdir)/udb.h
+ $(srcdir)/tsig.h $(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/xfrd-notify.h $(srcdir)/difffile.h $(srcdir)/udb.h $(srcdir)/rrl.h $(srcdir)/query.h \
+ $(srcdir)/packet.h
iterated_hash.o: $(srcdir)/iterated_hash.c config.h $(srcdir)/iterated_hash.h
lookup3.o: $(srcdir)/lookup3.c config.h $(srcdir)/lookup3.h
mini_event.o: $(srcdir)/mini_event.c config.h
@@ -436,7 +437,7 @@ util.o: $(srcdir)/util.c config.h $(srcdir)/util.h $(srcdir)/region-allocator.h
xfrd.o: $(srcdir)/xfrd.c config.h $(srcdir)/xfrd.h $(srcdir)/rbtree.h $(srcdir)/region-allocator.h $(srcdir)/namedb.h \
$(srcdir)/dname.h $(srcdir)/buffer.h $(srcdir)/util.h $(srcdir)/dns.h $(srcdir)/radtree.h $(srcdir)/options.h $(srcdir)/tsig.h $(srcdir)/xfrd-tcp.h \
$(srcdir)/xfrd-disk.h $(srcdir)/xfrd-notify.h $(srcdir)/netio.h $(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/packet.h $(srcdir)/rdata.h \
- $(srcdir)/difffile.h $(srcdir)/udb.h $(srcdir)/ipc.h $(srcdir)/remote.h
+ $(srcdir)/difffile.h $(srcdir)/udb.h $(srcdir)/ipc.h $(srcdir)/remote.h $(srcdir)/rrl.h $(srcdir)/query.h
xfrd-disk.o: $(srcdir)/xfrd-disk.c config.h $(srcdir)/xfrd-disk.h $(srcdir)/xfrd.h $(srcdir)/rbtree.h \
$(srcdir)/region-allocator.h $(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/buffer.h $(srcdir)/util.h $(srcdir)/dns.h $(srcdir)/radtree.h \
$(srcdir)/options.h $(srcdir)/tsig.h $(srcdir)/nsd.h $(srcdir)/edns.h
@@ -446,6 +447,9 @@ xfrd-notify.o: $(srcdir)/xfrd-notify.c config.h $(srcdir)/xfrd-notify.h $(srcdir
xfrd-tcp.o: $(srcdir)/xfrd-tcp.c config.h $(srcdir)/nsd.h $(srcdir)/dns.h $(srcdir)/edns.h $(srcdir)/buffer.h \
$(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/xfrd-tcp.h $(srcdir)/xfrd.h $(srcdir)/rbtree.h $(srcdir)/namedb.h $(srcdir)/dname.h \
$(srcdir)/radtree.h $(srcdir)/options.h $(srcdir)/tsig.h $(srcdir)/packet.h $(srcdir)/xfrd-disk.h
+xfr-inspect.o: $(srcdir)/xfr-inspect.c config.h $(srcdir)/udbzone.h $(srcdir)/udb.h $(srcdir)/dns.h $(srcdir)/udbradtree.h \
+ $(srcdir)/util.h $(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/packet.h $(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/radtree.h \
+ $(srcdir)/rbtree.h $(srcdir)/rdata.h $(srcdir)/difffile.h $(srcdir)/options.h
zlexer.o: zlexer.c config.h $(srcdir)/zonec.h $(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/buffer.h \
$(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/dns.h $(srcdir)/radtree.h $(srcdir)/rbtree.h zparser.h
zonec.o: $(srcdir)/zonec.c config.h $(srcdir)/zonec.h $(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/buffer.h \
@@ -513,7 +517,3 @@ udb-inspect.o: $(srcdir)/tpkg/cutest/udb-inspect.c config.h $(srcdir)/udb.h $(sr
$(srcdir)/udb.h $(srcdir)/udbzone.h $(srcdir)/dns.h $(srcdir)/udbradtree.h $(srcdir)/util.h $(srcdir)/buffer.h $(srcdir)/region-allocator.h \
$(srcdir)/util.h $(srcdir)/packet.h $(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/buffer.h $(srcdir)/radtree.h $(srcdir)/rbtree.h $(srcdir)/rdata.h \
$(srcdir)/namedb.h $(srcdir)/difffile.h $(srcdir)/options.h config.h
-xfr-inspect.o: $(srcdir)/xfr-inspect.c config.h $(srcdir)/udbzone.h $(srcdir)/udb.h $(srcdir)/dns.h \
- $(srcdir)/udbradtree.h $(srcdir)/util.h $(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/packet.h $(srcdir)/namedb.h \
- $(srcdir)/dname.h $(srcdir)/buffer.h $(srcdir)/radtree.h $(srcdir)/rbtree.h $(srcdir)/rdata.h $(srcdir)/namedb.h $(srcdir)/difffile.h \
- $(srcdir)/options.h config.h
diff --git a/usr.sbin/nsd/configure b/usr.sbin/nsd/configure
index e73ca9121cd..8050504dd46 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.1.19.
+# Generated by GNU Autoconf 2.69 for NSD 4.1.20.
#
# 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.1.19'
-PACKAGE_STRING='NSD 4.1.19'
+PACKAGE_VERSION='4.1.20'
+PACKAGE_STRING='NSD 4.1.20'
PACKAGE_BUGREPORT='nsd-bugs@nlnetlabs.nl'
PACKAGE_URL=''
@@ -725,6 +725,7 @@ enable_ipv6
enable_bind8_stats
enable_zone_stats
enable_checking
+enable_memclean
enable_ratelimit
enable_ratelimit_default_is_off
with_ssl
@@ -1285,7 +1286,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures NSD 4.1.19 to adapt to many kinds of systems.
+\`configure' configures NSD 4.1.20 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1346,7 +1347,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of NSD 4.1.19:";;
+ short | recursive ) echo "Configuration of NSD 4.1.20:";;
esac
cat <<\_ACEOF
@@ -1370,6 +1371,7 @@ Optional Features:
--enable-zone-stats Enable per-zone statistics gathering (needs
--enable-bind8-stats)
--enable-checking Enable internal runtime checks
+ --enable-memclean Cleanup memory (at exit) for eg. valgrind, memcheck
--enable-ratelimit Enable rate limiting
--enable-ratelimit-default-is-off
Enable this to set default of ratelimit to off
@@ -1494,7 +1496,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-NSD configure 4.1.19
+NSD configure 4.1.20
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2203,7 +2205,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by NSD $as_me 4.1.19, which was
+It was created by NSD $as_me 4.1.20, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -8644,6 +8646,18 @@ $as_echo "#define NDEBUG /**/" >>confdefs.h
;;
esac
+# Check whether --enable-memclean was given.
+if test "${enable_memclean+set}" = set; then :
+ enableval=$enable_memclean;
+fi
+
+if test "$enable_memclean" = "yes"; then
+cat >>confdefs.h <<_ACEOF
+#define MEMCLEAN 1
+_ACEOF
+
+fi
+
# Check whether --enable-ratelimit was given.
if test "${enable_ratelimit+set}" = set; then :
enableval=$enable_ratelimit;
@@ -9770,7 +9784,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by NSD $as_me 4.1.19, which was
+This file was extended by NSD $as_me 4.1.20, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -9832,7 +9846,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-NSD config.status 4.1.19
+NSD config.status 4.1.20
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 7dd787eaed5..8c11b400c6a 100644
--- a/usr.sbin/nsd/configure.ac
+++ b/usr.sbin/nsd/configure.ac
@@ -4,7 +4,7 @@ dnl
sinclude(acx_nlnetlabs.m4)
-AC_INIT(NSD,4.1.19,nsd-bugs@nlnetlabs.nl)
+AC_INIT(NSD,4.1.20,nsd-bugs@nlnetlabs.nl)
AC_CONFIG_HEADER([config.h])
CFLAGS="$CFLAGS"
@@ -800,6 +800,10 @@ case "$enable_checking" in
;;
esac
+AC_ARG_ENABLE(memclean, AC_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]))
case "$enable_ratelimit" in
yes)
diff --git a/usr.sbin/nsd/difffile.c b/usr.sbin/nsd/difffile.c
index 1fb5bda0003..3bcfba6d6e1 100644
--- a/usr.sbin/nsd/difffile.c
+++ b/usr.sbin/nsd/difffile.c
@@ -1333,6 +1333,7 @@ apply_ixfr_for_zone(nsd_type* nsd, zone_type* zonedb, FILE* in,
udb_ptr z;
DEBUG(DEBUG_XFRD,1, (LOG_INFO, "processing xfr: %s", zone_buf));
+ memset(&z, 0, sizeof(z)); /* if udb==NULL, have &z defined */
if(nsd->db->udb) {
if(udb_base_get_userflags(nsd->db->udb) != 0) {
log_msg(LOG_ERR, "database corrupted, cannot update");
diff --git a/usr.sbin/nsd/ipc.c b/usr.sbin/nsd/ipc.c
index 5466239265a..ff5bf07db1a 100644
--- a/usr.sbin/nsd/ipc.c
+++ b/usr.sbin/nsd/ipc.c
@@ -20,6 +20,7 @@
#include "xfrd.h"
#include "xfrd-notify.h"
#include "difffile.h"
+#include "rrl.h"
/* attempt to send NSD_STATS command to child fd */
static void send_stat_to_child(struct main_ipc_handler_data* data, int fd);
@@ -39,9 +40,12 @@ ipc_child_quit(struct nsd* nsd)
bind8_stats(nsd);
#endif /* BIND8_STATS */
-#if 0 /* OS collects memory pages */
- event_base_free(event_base);
- region_destroy(server_region);
+#ifdef MEMCLEAN /* OS collects memory pages */
+#ifdef RATELIMIT
+ rrl_deinit(nsd->this_child->child_num);
+#endif
+ event_base_free(nsd->event_base);
+ region_destroy(nsd->server_region);
#endif
server_shutdown(nsd);
exit(0);
diff --git a/usr.sbin/nsd/namedb.c b/usr.sbin/nsd/namedb.c
index bc7690d87b6..4528b6e4f15 100644
--- a/usr.sbin/nsd/namedb.c
+++ b/usr.sbin/nsd/namedb.c
@@ -242,6 +242,16 @@ do_deldomain(namedb_type* db, domain_type* domain)
if(domain->nsec3->ds_parent_hash && domain->nsec3->ds_parent_hash->node.key)
zone_del_domain_in_hash_tree(nsec3_tree_dszone(db, domain)
->dshashtree, &domain->nsec3->ds_parent_hash->node);
+ if(domain->nsec3->hash_wc) {
+ region_recycle(db->domains->region,
+ domain->nsec3->hash_wc,
+ sizeof(nsec3_hash_wc_node_type));
+ }
+ if(domain->nsec3->ds_parent_hash) {
+ region_recycle(db->domains->region,
+ domain->nsec3->ds_parent_hash,
+ sizeof(nsec3_hash_node_type));
+ }
region_recycle(db->domains->region, domain->nsec3,
sizeof(struct nsec3_domain_data));
}
diff --git a/usr.sbin/nsd/nsd.c b/usr.sbin/nsd/nsd.c
index dfbc58696b3..44be84a9149 100644
--- a/usr.sbin/nsd/nsd.c
+++ b/usr.sbin/nsd/nsd.c
@@ -177,6 +177,9 @@ add_interface(char*** nodes, struct nsd* nsd, char* ip)
nsd->udp = xalloc_zero(sizeof(*nsd->udp));
nsd->tcp = xalloc_zero(sizeof(*nsd->udp));
} else {
+ region_remove_cleanup(nsd->region, free, *nodes);
+ region_remove_cleanup(nsd->region, free, nsd->udp);
+ region_remove_cleanup(nsd->region, free, nsd->tcp);
*nodes = xrealloc(*nodes, (nsd->ifs+1)*sizeof(*nodes));
nsd->udp = xrealloc(nsd->udp, (nsd->ifs+1)*sizeof(*nsd->udp));
nsd->tcp = xrealloc(nsd->tcp, (nsd->ifs+1)*sizeof(*nsd->udp));
@@ -184,6 +187,9 @@ add_interface(char*** nodes, struct nsd* nsd, char* ip)
memset(&nsd->udp[nsd->ifs], 0, sizeof(*nsd->udp));
memset(&nsd->tcp[nsd->ifs], 0, sizeof(*nsd->tcp));
}
+ region_add_cleanup(nsd->region, free, *nodes);
+ region_add_cleanup(nsd->region, free, nsd->udp);
+ region_add_cleanup(nsd->region, free, nsd->tcp);
/* add it */
(*nodes)[nsd->ifs] = ip;
@@ -595,7 +601,7 @@ main(int argc, char *argv[])
}
}
argc -= optind;
- argv += optind;
+ /* argv += optind; */
/* Commandline parse error */
if (argc != 0) {
@@ -763,6 +769,9 @@ main(int argc, char *argv[])
nsd.children[i].need_to_send_QUIT = 0;
nsd.children[i].need_to_exit = 0;
nsd.children[i].has_exited = 0;
+#ifdef BIND8_STATS
+ nsd.children[i].query_count = 0;
+#endif
}
nsd.this_child = NULL;
@@ -799,6 +808,7 @@ main(int argc, char *argv[])
}
/* Set up the address info structures with real interface/port data */
+ assert(nodes);
for (i = 0; i < nsd.ifs; ++i) {
int r;
const char* node = NULL;
@@ -1134,6 +1144,8 @@ main(int argc, char *argv[])
/* xfrd forks this before reading database, so it does not get
* the memory size of the database */
server_start_xfrd(&nsd, 0, 0);
+ /* close zonelistfile in non-xfrd processes */
+ zone_list_close(nsd.options);
}
if (server_prepare(&nsd) != 0) {
unlinkpid(nsd.pidfile);
diff --git a/usr.sbin/nsd/nsd.h b/usr.sbin/nsd/nsd.h
index 0090100d00b..5133b1b7918 100644
--- a/usr.sbin/nsd/nsd.h
+++ b/usr.sbin/nsd/nsd.h
@@ -184,7 +184,11 @@ struct nsd
/* mmaps with data exchange from xfrd and reload */
struct udb_base* task[2];
- int mytask; /* the base used by this process */
+ int mytask;
+ /* the base used by this (child)process */
+ struct event_base* event_base;
+ /* the server_region used by this (child)process */
+ region_type* server_region;
struct netio_handler* xfrd_listener;
struct daemon_remote* rc;
diff --git a/usr.sbin/nsd/nsec3.c b/usr.sbin/nsd/nsec3.c
index dad4f23d7bf..716d2e72a62 100644
--- a/usr.sbin/nsd/nsec3.c
+++ b/usr.sbin/nsd/nsec3.c
@@ -537,7 +537,7 @@ nsec3_precompile_domain(struct namedb* db, struct domain* domain,
else domain->nsec3->nsec3_is_exact = 0;
/* find cover for *.domain for wildcard denial */
- exact = nsec3_find_cover(zone, domain->nsec3->hash_wc->wc.hash,
+ (void)nsec3_find_cover(zone, domain->nsec3->hash_wc->wc.hash,
sizeof(domain->nsec3->hash_wc->wc.hash), &result);
domain->nsec3->nsec3_wcard_child_cover = result;
}
diff --git a/usr.sbin/nsd/options.c b/usr.sbin/nsd/options.c
index 026f8b91fac..dd6d29b446a 100644
--- a/usr.sbin/nsd/options.c
+++ b/usr.sbin/nsd/options.c
@@ -23,6 +23,7 @@ extern FILE* c_in, *c_out;
int c_parse(void);
int c_lex(void);
int c_wrap(void);
+int c_lex_destroy(void);
void c_error(const char *message);
extern char* c_text;
@@ -280,9 +281,9 @@ void options_zonestatnames_create(struct nsd_options* opt)
/* allocate "" as zonestat 0, for zones without a zonestat */
if(!rbtree_search(opt->zonestatnames, "")) {
struct zonestatname* n;
- n = (struct zonestatname*)xalloc(sizeof(*n));
- memset(n, 0, sizeof(*n));
- n->node.key = strdup("");
+ n = (struct zonestatname*)region_alloc_zero(opt->region,
+ sizeof(*n));
+ n->node.key = region_strdup(opt->region, "");
if(!n->node.key) {
log_msg(LOG_ERR, "malloc failed: %s", strerror(errno));
exit(1);
@@ -692,8 +693,10 @@ zone_list_compact(struct nsd_options* opt)
void
zone_list_close(struct nsd_options* opt)
{
- fclose(opt->zonelist);
- opt->zonelist = NULL;
+ if(opt->zonelist) {
+ fclose(opt->zonelist);
+ opt->zonelist = NULL;
+ }
}
void
@@ -1887,11 +1890,15 @@ parse_acl_info(region_type* region, char* ip, const char* key)
#ifdef INET6
if(inet_pton(AF_INET6, ip, &acl->addr.addr6) != 1)
c_error_msg("Bad ip6 address '%s'", ip);
- if(acl->rangetype==acl_range_mask || acl->rangetype==acl_range_minmax)
+ if(acl->rangetype==acl_range_mask || acl->rangetype==acl_range_minmax) {
+ assert(p);
if(inet_pton(AF_INET6, p, &acl->range_mask.addr6) != 1)
c_error_msg("Bad ip6 address mask '%s'", p);
- if(acl->rangetype==acl_range_subnet)
+ }
+ if(acl->rangetype==acl_range_subnet) {
+ assert(p);
parse_acl_range_subnet(p, &acl->range_mask.addr6, 128);
+ }
#else
c_error_msg("encountered IPv6 address '%s'.", ip);
#endif /* INET6 */
@@ -1899,11 +1906,15 @@ parse_acl_info(region_type* region, char* ip, const char* key)
acl->is_ipv6 = 0;
if(inet_pton(AF_INET, ip, &acl->addr.addr) != 1)
c_error_msg("Bad ip4 address '%s'", ip);
- if(acl->rangetype==acl_range_mask || acl->rangetype==acl_range_minmax)
+ if(acl->rangetype==acl_range_mask || acl->rangetype==acl_range_minmax) {
+ assert(p);
if(inet_pton(AF_INET, p, &acl->range_mask.addr) != 1)
c_error_msg("Bad ip4 address mask '%s'", p);
- if(acl->rangetype==acl_range_subnet)
+ }
+ if(acl->rangetype==acl_range_subnet) {
+ assert(p);
parse_acl_range_subnet(p, &acl->range_mask.addr, 32);
+ }
}
/* key */
@@ -2005,6 +2016,9 @@ void
nsd_options_destroy(struct nsd_options* opt)
{
region_destroy(opt->region);
+#ifdef MEMCLEAN /* OS collects memory pages */
+ c_lex_destroy();
+#endif
}
unsigned getzonestatid(struct nsd_options* opt, struct zone_options* zopt)
@@ -2021,9 +2035,8 @@ unsigned getzonestatid(struct nsd_options* opt, struct zone_options* zopt)
if(res)
return ((struct zonestatname*)res)->id;
/* create it */
- n = (struct zonestatname*)xalloc(sizeof(*n));
- memset(n, 0, sizeof(*n));
- n->node.key = strdup(statname);
+ n = (struct zonestatname*)region_alloc_zero(opt->region, sizeof(*n));
+ n->node.key = region_strdup(opt->region, statname);
if(!n->node.key) {
log_msg(LOG_ERR, "malloc failed: %s", strerror(errno));
exit(1);
diff --git a/usr.sbin/nsd/query.c b/usr.sbin/nsd/query.c
index 7b862a45bc7..834104e0761 100644
--- a/usr.sbin/nsd/query.c
+++ b/usr.sbin/nsd/query.c
@@ -1085,7 +1085,7 @@ answer_authoritative(struct nsd *nsd,
}
DEBUG(DEBUG_QUERY,2, (LOG_INFO, "->result is %s", dname_to_string(newname, NULL)));
/* follow the DNAME */
- exact = namedb_lookup(nsd->db, newname, &closest_match, &closest_encloser);
+ (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);
diff --git a/usr.sbin/nsd/rrl.c b/usr.sbin/nsd/rrl.c
index c8dec3fc908..69232a95f4a 100644
--- a/usr.sbin/nsd/rrl.c
+++ b/usr.sbin/nsd/rrl.c
@@ -100,6 +100,27 @@ void rrl_mmap_init(int numch, size_t numbuck, size_t lm, size_t wlm, size_t sm,
#endif
}
+void rrl_mmap_deinit(void)
+{
+#ifdef HAVE_MMAP
+ size_t i;
+ for(i=0; i<rrl_maps_num; i++) {
+ munmap(rrl_maps[i], sizeof(struct rrl_bucket)*rrl_array_size);
+ rrl_maps[i] = NULL;
+ }
+ free(rrl_maps);
+ rrl_maps = NULL;
+#endif
+}
+
+void rrl_mmap_deinit_keep_mmap(void)
+{
+#ifdef HAVE_MMAP
+ free(rrl_maps);
+ rrl_maps = NULL;
+#endif
+}
+
void rrl_set_limit(size_t lm, size_t wlm, size_t sm)
{
rrl_ratelimit = lm*2;
@@ -117,6 +138,13 @@ void rrl_init(size_t ch)
#endif
}
+void rrl_deinit(size_t ch)
+{
+ if(!rrl_maps || ch >= rrl_maps_num)
+ free(rrl_array);
+ rrl_array = NULL;
+}
+
/** return the source netblock of the query, this is the genuine source
* for genuine queries and the target for reflected packets */
static uint64_t rrl_get_source(query_type* query, uint16_t* c2)
diff --git a/usr.sbin/nsd/rrl.h b/usr.sbin/nsd/rrl.h
index 1ffd841664b..8dbc3184d1a 100644
--- a/usr.sbin/nsd/rrl.h
+++ b/usr.sbin/nsd/rrl.h
@@ -51,6 +51,14 @@ void rrl_mmap_init(int numch, size_t numbuck, size_t lm, size_t wlm, size_t sm,
*/
void rrl_init(size_t ch);
+/** deinit (for this child server processs) */
+void rrl_deinit(size_t ch);
+
+/** deinit mmaps for n children */
+void rrl_mmap_deinit(void);
+/** frees memory but keeps mmap in place (for other processes) */
+void rrl_mmap_deinit_keep_mmap(void);
+
/**
* Process query that happens, the query structure contains the
* information about the query and the answer.
diff --git a/usr.sbin/nsd/server.c b/usr.sbin/nsd/server.c
index fe74f9a1b56..2531ff6424b 100644
--- a/usr.sbin/nsd/server.c
+++ b/usr.sbin/nsd/server.c
@@ -308,6 +308,9 @@ restart_child_servers(struct nsd *nsd, region_type* region, netio_type* netio,
/* the child need not be able to access the
* nsd.db file */
namedb_close_udb(nsd->db);
+#ifdef MEMCLEAN /* OS collects memory pages */
+ region_destroy(region);
+#endif
if (pledge("stdio rpath inet", NULL) == -1) {
log_msg(LOG_ERR, "pledge");
@@ -1079,7 +1082,14 @@ server_shutdown(struct nsd *nsd)
daemon_remote_delete(nsd->rc); /* ssl-delete secret keys */
#endif
-#if 0 /* OS collects memory pages */
+#ifdef MEMCLEAN /* OS collects memory pages */
+#ifdef RATELIMIT
+ rrl_mmap_deinit_keep_mmap();
+#endif
+ udb_base_free_keep_mmap(nsd->task[0]);
+ udb_base_free_keep_mmap(nsd->task[1]);
+ namedb_close_udb(nsd->db); /* keeps mmap */
+ namedb_close(nsd->db);
nsd_options_destroy(nsd->options);
region_destroy(nsd->region);
#endif
@@ -1847,7 +1857,7 @@ server_main(struct nsd *nsd)
/* only quit children after xfrd has acked */
send_children_quit(nsd);
-#if 0 /* OS collects memory pages */
+#ifdef MEMCLEAN /* OS collects memory pages */
region_destroy(server_region);
#endif
server_shutdown(nsd);
@@ -1926,7 +1936,7 @@ server_main(struct nsd *nsd)
(void)kill(nsd->pid, SIGTERM);
}
-#if 0 /* OS collects memory pages */
+#ifdef MEMCLEAN /* OS collects memory pages */
region_destroy(server_region);
#endif
/* write the nsd.db to disk, wait for it to complete */
@@ -1996,6 +2006,8 @@ server_child(struct nsd *nsd)
log_msg(LOG_ERR, "nsd server could not create event base");
exit(1);
}
+ nsd->event_base = event_base;
+ nsd->server_region = server_region;
#ifdef RATELIMIT
rrl_init(nsd->this_child->child_num);
@@ -2162,7 +2174,10 @@ server_child(struct nsd *nsd)
bind8_stats(nsd);
#endif /* BIND8_STATS */
-#if 0 /* OS collects memory pages */
+#ifdef MEMCLEAN /* OS collects memory pages */
+#ifdef RATELIMIT
+ rrl_deinit(nsd->this_child->child_num);
+#endif
event_base_free(event_base);
region_destroy(server_region);
#endif
diff --git a/usr.sbin/nsd/xfrd.c b/usr.sbin/nsd/xfrd.c
index 3520f5d3b1b..14fec35a28a 100644
--- a/usr.sbin/nsd/xfrd.c
+++ b/usr.sbin/nsd/xfrd.c
@@ -29,6 +29,7 @@
#include "difffile.h"
#include "ipc.h"
#include "remote.h"
+#include "rrl.h"
#define XFRD_UDP_TIMEOUT 10 /* seconds, before a udp request times out */
#define XFRD_NO_IXFR_CACHE 172800 /* 48h before retrying ixfr's after notimpl */
@@ -98,11 +99,15 @@ xfrd_signal_callback(int sig, short event, void* ATTR_UNUSED(arg))
sig_handler(sig);
}
+static struct event* xfrd_sig_evs[10];
+static int xfrd_sig_num = 0;
+
static void
xfrd_sigsetup(int sig)
{
- /* no need to remember the event ; dealloc on process exit */
struct event *ev = xalloc_zero(sizeof(*ev));
+ assert(xfrd_sig_num <= (int)(sizeof(xfrd_sig_evs)/sizeof(ev)));
+ xfrd_sig_evs[xfrd_sig_num++] = ev;
signal_set(ev, sig, xfrd_signal_callback, NULL);
if(event_base_set(xfrd->event_base, ev) != 0) {
log_msg(LOG_ERR, "xfrd sig handler: event_base_set failed");
@@ -321,6 +326,7 @@ xfrd_shutdown()
DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd shutdown"));
event_del(&xfrd->ipc_handler);
close(xfrd->ipc_handler.ev_fd); /* notifies parent we stop */
+ zone_list_close(nsd.options);
if(xfrd->nsd->options->xfrdfile != NULL && xfrd->nsd->options->xfrdfile[0]!=0)
xfrd_write_state(xfrd);
if(xfrd->reload_added) {
@@ -379,9 +385,49 @@ xfrd_shutdown()
/* unlink xfr files in not-yet-done task file */
xfrd_clean_pending_tasks(xfrd->nsd, xfrd->nsd->task[xfrd->nsd->mytask]);
xfrd_del_tempdir(xfrd->nsd);
+#ifdef HAVE_SSL
+ daemon_remote_delete(xfrd->nsd->rc); /* ssl-delete secret keys */
+#endif
/* process-exit cleans up memory used by xfrd process */
DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd shutdown complete"));
+#ifdef MEMCLEAN /* OS collects memory pages */
+ if(xfrd->zones) {
+ xfrd_zone_type* z;
+ RBTREE_FOR(z, xfrd_zone_type*, xfrd->zones) {
+ tsig_delete_record(&z->tsig, NULL);
+ }
+ }
+ if(xfrd->notify_zones) {
+ struct notify_zone* n;
+ RBTREE_FOR(n, struct notify_zone*, xfrd->notify_zones) {
+ tsig_delete_record(&n->notify_tsig, NULL);
+ }
+ }
+ if(xfrd_sig_num > 0) {
+ int i;
+ for(i=0; i<xfrd_sig_num; i++) {
+ signal_del(xfrd_sig_evs[i]);
+ free(xfrd_sig_evs[i]);
+ }
+ for(i=0; i<(int)nsd.ifs; i++) {
+ if(nsd.udp[i].s != -1 && nsd.udp[i].addr)
+ freeaddrinfo(nsd.udp[i].addr);
+ if(nsd.tcp[i].s != -1 && nsd.tcp[i].addr)
+ freeaddrinfo(nsd.tcp[i].addr);
+ }
+ }
+#ifdef RATELIMIT
+ rrl_mmap_deinit();
+#endif
+ udb_base_free(nsd.task[0]);
+ udb_base_free(nsd.task[1]);
+ event_base_free(xfrd->event_base);
+ region_destroy(xfrd->region);
+ nsd_options_destroy(nsd.options);
+ region_destroy(nsd.region);
+ log_finalize();
+#endif
exit(0);
}
@@ -521,7 +567,7 @@ xfrd_process_soa_info_task(struct task_list_d* task)
memmove(&soa.expire, p, sizeof(uint32_t));
p += sizeof(uint32_t);
memmove(&soa.minimum, p, sizeof(uint32_t));
- p += sizeof(uint32_t);
+ /* p += sizeof(uint32_t); if we wanted to read further */
DEBUG(DEBUG_IPC,1, (LOG_INFO, "SOAINFO for %s %u",
dname_to_string(task->zname,0),
(unsigned)ntohl(soa.serial)));
diff --git a/usr.sbin/nsd/zonec.c b/usr.sbin/nsd/zonec.c
index de0a03ca4cd..0938c35a573 100644
--- a/usr.sbin/nsd/zonec.c
+++ b/usr.sbin/nsd/zonec.c
@@ -1260,6 +1260,8 @@ parse_unknown_rdata(uint16_t type, uint16_t *wireformat)
zadd_rdata_wireformat(rdatas[i].data);
}
}
+ region_recycle(parser->region, rdatas,
+ rdata_count*sizeof(rdata_atom_type));
}
@@ -1626,6 +1628,7 @@ zonec_read(const char* name, const char* zonefile, zone_type* zone)
name, domain_to_string(
parser->current_zone->soa_rrset->rrs[0].owner));
}
+ region_free_all(parser->rr_region);
parser_flush();
fclose(yyin);
@@ -1667,6 +1670,9 @@ zonec_desetup_parser(void)
* region_recycle(parser->region, (void*)error_domain, 1); */
/* clear memory for exit, but this is not portable to
* other versions of lex. yylex_destroy(); */
+#ifdef MEMCLEAN /* OS collects memory pages */
+ yylex_destroy();
+#endif
}
}
@@ -1719,6 +1725,7 @@ zonec_parse_string(region_type* region, domain_table_type* domains,
/* remove origin if it was not used during the parse */
if(parser->origin != error_domain)
domain_table_deldomain(parser->db, parser->origin);
+ region_free_all(parser->rr_region);
zonec_desetup_string_parser();
parser_flush();
return errors;
diff --git a/usr.sbin/nsd/zparser.y b/usr.sbin/nsd/zparser.y
index 542142ea6d5..831ef39c51e 100644
--- a/usr.sbin/nsd/zparser.y
+++ b/usr.sbin/nsd/zparser.y
@@ -1078,16 +1078,16 @@ rdata_csync: STR sp STR nsec_seq
rdata_unknown: URR sp STR sp str_sp_seq trail
{
/* $2 is the number of octets, currently ignored */
- $$ = zparser_conv_hex(parser->region, $5.str, $5.len);
+ $$ = zparser_conv_hex(parser->rr_region, $5.str, $5.len);
}
| URR sp STR trail
{
- $$ = zparser_conv_hex(parser->region, "", 0);
+ $$ = zparser_conv_hex(parser->rr_region, "", 0);
}
| URR error NL
{
- $$ = zparser_conv_hex(parser->region, "", 0);
+ $$ = zparser_conv_hex(parser->rr_region, "", 0);
}
;
%%