From 7fc349b740f993e7c0dcdc03904b7d1eaf85d260 Mon Sep 17 00:00:00 2001 From: Stuart Henderson Date: Fri, 2 Mar 2012 08:38:58 +0000 Subject: import nsd 3.2.10, "cool" jakob@, also looked over by Brad --- usr.sbin/nsd/acx_nlnetlabs.m4 | 98 +++++++++++++++++++++++++++++++++++-------- usr.sbin/nsd/compat/pselect.c | 4 +- usr.sbin/nsd/difffile.c | 90 +++++++++++++++++++++++++++++---------- usr.sbin/nsd/edns.c | 3 +- usr.sbin/nsd/namedb.c | 2 + usr.sbin/nsd/namedb.h | 1 + usr.sbin/nsd/xfrd.c | 7 ++-- 7 files changed, 158 insertions(+), 47 deletions(-) diff --git a/usr.sbin/nsd/acx_nlnetlabs.m4 b/usr.sbin/nsd/acx_nlnetlabs.m4 index 10fd9703b60..3a2e350823e 100644 --- a/usr.sbin/nsd/acx_nlnetlabs.m4 +++ b/usr.sbin/nsd/acx_nlnetlabs.m4 @@ -1,8 +1,18 @@ # acx_nlnetlabs.m4 - common macros for configure checks -# Copyright 2009-2011, NLnet Labs, Wouter Wijngaards. +# Copyright 2009, Wouter Wijngaards, NLnet Labs. # BSD licensed. # -# Version 10 +# Version 20 +# 2012-01-20 Fix COMPILER_FLAGS_UNBOUND for gcc 4.6.2 assigned-not-used-warns. +# 2011-12-05 Fix getaddrinfowithincludes on windows with fedora16 mingw32-gcc. +# Fix ACX_MALLOC for redefined malloc error. +# Fix GETADDRINFO_WITH_INCLUDES to add -lws2_32 +# 2011-11-10 Fix FLTO test to not drop a.out in current directory. +# 2011-11-01 Fix FLTO test for llvm on Lion. +# 2011-08-01 Fix nonblock test (broken at v13). +# 2011-08-01 Fix autoconf 2.68 warnings +# 2011-06-23 Add ACX_CHECK_FLTO to check -flto. +# 2010-08-16 Fix FLAG_OMITTED for AS_TR_CPP changes in autoconf-2.66. # 2010-07-02 Add check for ss_family (for minix). # 2010-04-26 Fix to use CPPFLAGS for CHECK_COMPILER_FLAGS. # 2010-03-01 Fix RPATH using CONFIG_COMMANDS to run at the very end. @@ -31,6 +41,7 @@ # ACX_DETERMINE_EXT_FLAGS_UNBOUND - find out which flags enable BSD and POSIX. # ACX_CHECK_FORMAT_ATTRIBUTE - find cc printf format syntax. # ACX_CHECK_UNUSED_ATTRIBUTE - find cc variable unused syntax. +# ACX_CHECK_FLTO - see if cc supports -flto and use it if so. # ACX_LIBTOOL_C_ONLY - create libtool for C only, improved. # ACX_TYPE_U_CHAR - u_char type. # ACX_TYPE_RLIM_T - rlim_t type. @@ -249,6 +260,8 @@ int test() { a = getopt(2, opts, "a"); a = isascii(32); str = gai_strerror(0); + if(str && t && tv.tv_usec && msg.msg_control) + a = 0; return a; } ], [CFLAGS="$CFLAGS $C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED=1 -D_ALL_SOURCE"]) @@ -284,6 +297,8 @@ int test() { a = getopt(2, opts, "a"); a = isascii(32); str = gai_strerror(0); + if(str && t && tv.tv_usec && msg.msg_control) + a = 0; return a; } ], [CFLAGS="$CFLAGS $C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_ALL_SOURCE"]) @@ -350,6 +365,8 @@ int test() { const char* str = NULL; t = ctime_r(&time, buf); str = gai_strerror(0); + if(t && str) + a = 0; return a; } ], [CFLAGS="$CFLAGS -D_POSIX_C_SOURCE=200112"]) @@ -376,12 +393,32 @@ int test() { srandom(32); a = getopt(2, opts, "a"); a = isascii(32); + if(tv.tv_usec) + a = 0; return a; } ], [CFLAGS="$CFLAGS -D__EXTENSIONS__"]) ])dnl End of ACX_DETERMINE_EXT_FLAGS_UNBOUND +dnl Check if CC supports -flto. +dnl in a way that supports clang and suncc (that flag does something else, +dnl but fails to link). It sets it in CFLAGS if it works. +AC_DEFUN([ACX_CHECK_FLTO], +[AC_MSG_CHECKING([if $CC supports -flto]) +BAKCFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -flto" +AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])], [ + if $CC $CFLAGS -o conftest conftest.c 2>&1 | grep "warning: no debug symbols in executable" >/dev/null; then + CFLAGS="$BAKCFLAGS" + AC_MSG_RESULT(no) + else + AC_MSG_RESULT(yes) + fi + rm -f conftest conftest.c conftest.o +], [CFLAGS="$BAKCFLAGS" ; AC_MSG_RESULT(no)]) +]) + dnl Check the printf-format attribute (if any) dnl result in HAVE_ATTR_FORMAT. dnl Make sure you also include the AHX_CONFIG_FORMAT_ATTRIBUTE. @@ -753,7 +790,7 @@ AC_DEFUN([ACX_CHECK_GETADDRINFO_WITH_INCLUDES], AC_MSG_CHECKING(for getaddrinfo) ac_cv_func_getaddrinfo=no AC_LINK_IFELSE( -[ +[AC_LANG_SOURCE([[ #ifdef __cplusplus extern "C" { @@ -767,14 +804,21 @@ int main() { ; return 0; } -], +]])], dnl this case on linux, solaris, bsd -[ac_cv_func_getaddrinfo="yes"], +[ac_cv_func_getaddrinfo="yes" +dnl see if on windows +if test "$ac_cv_header_windows_h" = "yes"; then + AC_DEFINE(USE_WINSOCK, 1, [Whether the windows socket API is used]) + USE_WINSOCK="1" + LIBS="$LIBS -lws2_32" +fi +], dnl no quick getaddrinfo, try mingw32 and winsock2 library. ORIGLIBS="$LIBS" LIBS="$LIBS -lws2_32" AC_LINK_IFELSE( -AC_LANG_PROGRAM( +[AC_LANG_PROGRAM( [ #ifdef HAVE_WS2TCPIP_H #include @@ -783,7 +827,7 @@ AC_LANG_PROGRAM( [ (void)getaddrinfo(NULL, NULL, NULL, NULL); ] -), +)], [ ac_cv_func_getaddrinfo="yes" dnl already: LIBS="$LIBS -lws2_32" @@ -847,7 +891,8 @@ if echo $target | grep mingw32 >/dev/null; then AC_MSG_RESULT([no (windows)]) AC_DEFINE([NONBLOCKING_IS_BROKEN], 1, [Define if the network stack does not fully support nonblocking io (causes lower performance).]) else -AC_RUN_IFELSE(AC_LANG_PROGRAM([ +AC_RUN_IFELSE([ +AC_LANG_SOURCE([[ #include #include #include @@ -871,7 +916,9 @@ AC_RUN_IFELSE(AC_LANG_PROGRAM([ #ifdef HAVE_TIME_H #include #endif -],[[ + +int main(void) +{ int port; int sfd, cfd; int num = 10; @@ -964,7 +1011,9 @@ AC_RUN_IFELSE(AC_LANG_PROGRAM([ close(sfd); close(cfd); -]]), [ + return 0; +} +]])], [ AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) @@ -1004,13 +1053,13 @@ AC_DEFUN([ACX_FUNC_IOCTLSOCKET], [ # check ioctlsocket AC_MSG_CHECKING(for ioctlsocket) -AC_LINK_IFELSE(AC_LANG_PROGRAM([ +AC_LINK_IFELSE([AC_LANG_PROGRAM([ #ifdef HAVE_WINSOCK2_H #include #endif ], [ (void)ioctlsocket(0, 0, NULL); -]), [ +])], [ AC_MSG_RESULT(yes) AC_DEFINE(HAVE_IOCTLSOCKET, 1, [if the function 'ioctlsocket' is available]) ],[AC_MSG_RESULT(no)]) @@ -1020,10 +1069,23 @@ dnl detect malloc and provide malloc compat prototype. dnl $1: unique name for compat code AC_DEFUN([ACX_FUNC_MALLOC], [ - AC_FUNC_MALLOC - if test "$ac_cv_func_malloc_0_nonnull" = no; then - AC_DEFINE_UNQUOTED([malloc], [rpl_malloc_$1], [Define if replacement function should be used.]) - fi + AC_MSG_CHECKING([for GNU libc compatible malloc]) + AC_RUN_IFELSE([AC_LANG_PROGRAM( +[[#if defined STDC_HEADERS || defined HAVE_STDLIB_H +#include +#else +char *malloc (); +#endif +]], [ if(malloc(0) != 0) return 1;]) +], + [AC_MSG_RESULT([no]) + AC_LIBOBJ(malloc) + AC_DEFINE_UNQUOTED([malloc], [rpl_malloc_$1], [Define if replacement function should be used.])] , + [AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE_MALLOC], 1, [If have GNU libc compatible malloc])], + [AC_MSG_RESULT([no (crosscompile)]) + AC_LIBOBJ(malloc) + AC_DEFINE_UNQUOTED([malloc], [rpl_malloc_$1], [Define if replacement function should be used.])] ) ]) dnl Define fallback for fseeko and ftello if needed. @@ -1192,7 +1254,7 @@ AC_DEFUN([ACX_CFLAGS_STRIP], [ if echo $CFLAGS | grep " $1" >/dev/null 2>&1; then CFLAGS="`echo $CFLAGS | sed -e 's/ $1//g'`" - AC_DEFINE(AS_TR_CPP(OMITTED_$1), 1, Put $1 define in config.h) + AC_DEFINE(m4_bpatsubst(OMITTED_$1,[[-=]],_), 1, Put $1 define in config.h) fi ]) @@ -1223,7 +1285,7 @@ AC_DEFUN([AHX_CONFIG_FLAG_OMITTED], dnl Wrapper for AHX_CONFIG_FLAG_OMITTED for -D style flags dnl $1: the -DNAME or -DNAME=value string. AC_DEFUN([AHX_CONFIG_FLAG_EXT], -[AHX_CONFIG_FLAG_OMITTED(AS_TR_CPP(OMITTED_$1),m4_bpatsubst(m4_bpatsubst($1,-D,),=.*$,),m4_if(m4_bregexp($1,=),-1,1,m4_bpatsubst($1,^.*=,))) +[AHX_CONFIG_FLAG_OMITTED(m4_bpatsubst(OMITTED_$1,[[-=]],_),m4_bpatsubst(m4_bpatsubst($1,-D,),=.*$,),m4_if(m4_bregexp($1,=),-1,1,m4_bpatsubst($1,^.*=,))) ]) dnl config.h part to define omitted cflags, use with ACX_STRIP_EXT_FLAGS. diff --git a/usr.sbin/nsd/compat/pselect.c b/usr.sbin/nsd/compat/pselect.c index 524cf2837a0..848a698c9fc 100644 --- a/usr.sbin/nsd/compat/pselect.c +++ b/usr.sbin/nsd/compat/pselect.c @@ -1,6 +1,6 @@ /* * Like select(2) but set the signals to block while waiting in - * select. This version is not entirely race condition safe. Only + * select. This version is not entirely race condition safe. Only * operating system support can make it so. */ @@ -36,7 +36,7 @@ pselect (int n, } else { result = select(n, readfds, writefds, exceptfds, NULL); } - + if (sigmask && sigprocmask(SIG_SETMASK, &saved_sigmask, NULL) == -1) return -1; diff --git a/usr.sbin/nsd/difffile.c b/usr.sbin/nsd/difffile.c index 8ed816d065a..1052b2f9718 100644 --- a/usr.sbin/nsd/difffile.c +++ b/usr.sbin/nsd/difffile.c @@ -268,7 +268,35 @@ has_data_below(domain_type* top) return 0; } -static void + +/* this routine makes empty terminals non-existent. + * @domain the lowest empty terminal + * @ce the closest encloser + */ +static domain_type* +rrset_delete_empty_terminals(domain_type* domain, domain_type* ce) +{ + assert(domain); + if (domain->rrsets == 0) { + /* if there is no data below it, it becomes non existing. + also empty nonterminals above it become nonexisting */ + /* check for data below this node. */ + if(!has_data_below(domain)) { + /* nonexist this domain and all parent empty nonterminals */ + domain_type* p = domain; + while(p != NULL && p->rrsets == 0) { + if(p == ce || has_data_below(p)) + return p; + p->is_existing = 0; + p = p->parent; + } + } + } + return NULL; +} + + +static domain_type* rrset_delete(namedb_type* db, domain_type* domain, rrset_type* rrset) { int i; @@ -279,7 +307,7 @@ rrset_delete(namedb_type* db, domain_type* domain, rrset_type* rrset) } if(!*pp) { /* rrset does not exist for domain */ - return; + return NULL; } *pp = rrset->next; @@ -318,25 +346,14 @@ rrset_delete(namedb_type* db, domain_type* domain, rrset_type* rrset) add_rdata_to_recyclebin(db, &rrset->rrs[i]); region_recycle(db->region, rrset->rrs, sizeof(rr_type) * rrset->rr_count); + rrset->rr_count = 0; region_recycle(db->region, rrset, sizeof(rrset_type)); /* is the node now an empty node (completely deleted) */ - if(domain->rrsets == 0) { - /* if there is no data below it, it becomes non existing. - also empty nonterminals above it become nonexisting */ - /* check for data below this node. */ - if(!has_data_below(domain)) { - /* nonexist this domain and all parent empty nonterminals */ - domain_type* p = domain; - while(p != NULL && p->rrsets == 0) { - if(has_data_below(p)) - break; - p->is_existing = 0; - p = p->parent; - } - } + if (domain->rrsets == 0) { + return domain; } - rrset->rr_count = 0; + return NULL; } static int @@ -384,6 +401,7 @@ find_rr_num(rrset_type* rrset, static int delete_RR(namedb_type* db, const dname_type* dname, uint16_t type, uint16_t klass, + domain_type* prevdomain, buffer_type* packet, size_t rdatalen, zone_type *zone, region_type* temp_region, int is_axfr) { @@ -437,12 +455,18 @@ delete_RR(namedb_type* db, const dname_type* dname, parent = parent->parent; } while (parent != zone->apex->parent); } +#else + (void)is_axfr; #endif /* !FULL_PREHASH */ #endif /* NSEC3 */ if(rrset->rr_count == 1) { /* delete entire rrset */ - rrset_delete(db, domain, rrset); + domain = rrset_delete(db, domain, rrset); + if (domain && domain != prevdomain && !domain->nextdiff) { + /* this domain is not yet in the diff chain */ + prevdomain->nextdiff = domain; + } } else { /* swap out the bad RR and decrease the count */ rr_type* rrs_orig = rrset->rrs; @@ -598,6 +622,8 @@ add_RR(namedb_type* db, const dname_type* dname, parent = parent->parent; } while (parent != zone->apex->parent); } +#else + (void)is_axfr; #endif /* !FULL_PREHASH */ #endif /* NSEC3 */ @@ -683,6 +709,7 @@ delete_zone_rrs(namedb_type* db, zone_type* zone) { rrset_type *rrset; domain_type *domain = zone->apex; + domain_type *next = NULL; zone->updated = 1; #ifdef NSEC3 #ifndef FULL_PREHASH @@ -698,9 +725,11 @@ delete_zone_rrs(namedb_type* db, zone_type* zone) dname_to_string(domain_dname(domain),0))); /* delete all rrsets of the zone */ while((rrset = domain_find_any_rrset(domain, zone))) { - rrset_delete(db, domain, rrset); + (void)rrset_delete(db, domain, rrset); } - domain = domain_next(domain); + next = domain_next(domain); + domain->nextdiff = next; + domain = next; } #ifdef NSEC3 #ifndef FULL_PREHASH @@ -727,6 +756,19 @@ delete_zone_rrs(namedb_type* db, zone_type* zone) assert(zone->updated == 1); } +/* fix empty terminals */ +static void +fix_empty_terminals(zone_type* zone_db) +{ + domain_type* domain = zone_db->apex, *ce = NULL, *next = NULL; + while (domain) { + ce = rrset_delete_empty_terminals(domain, ce); + next = domain->nextdiff; + domain->nextdiff = NULL; + domain = next; + } +} + /* return value 0: syntaxerror,badIXFR, 1:OK, 2:done_and_skip_it */ static int apply_ixfr(namedb_type* db, FILE *in, const off_t* startpos, @@ -743,6 +785,7 @@ apply_ixfr(namedb_type* db, FILE *in, const off_t* startpos, uint16_t rrlen; const dname_type *dname_zone, *dname; zone_type* zone_db; + domain_type* last_in_list; char file_zone_name[3072]; uint32_t file_serial, file_seq_nr; uint16_t file_id; @@ -893,6 +936,7 @@ apply_ixfr(namedb_type* db, FILE *in, const off_t* startpos, } else counter = 0; + last_in_list = zone_db->apex; for(; counter < ancount; ++counter,++(*rr_count)) { uint16_t type, klass; @@ -985,11 +1029,14 @@ apply_ixfr(namedb_type* db, FILE *in, const off_t* startpos, && seq_nr == seq_total-1) { continue; /* do not delete final SOA RR for IXFR */ } - if(!delete_RR(db, dname, type, klass, packet, + if(!delete_RR(db, dname, type, klass, last_in_list, packet, rrlen, zone_db, region, *is_axfr)) { region_destroy(region); return 0; } + if (!*is_axfr && last_in_list->nextdiff) { + last_in_list = last_in_list->nextdiff; + } } else { @@ -1001,6 +1048,7 @@ apply_ixfr(namedb_type* db, FILE *in, const off_t* startpos, } } } + fix_empty_terminals(zone_db); region_destroy(region); return 1; } diff --git a/usr.sbin/nsd/edns.c b/usr.sbin/nsd/edns.c index 49f8678c914..3ece1220118 100644 --- a/usr.sbin/nsd/edns.c +++ b/usr.sbin/nsd/edns.c @@ -64,7 +64,6 @@ edns_parse_record(edns_record_type *edns, buffer_type *packet) uint8_t opt_owner; uint16_t opt_type; uint16_t opt_class; - uint8_t opt_extended_rcode; uint8_t opt_version; uint16_t opt_flags; uint16_t opt_rdlen; @@ -84,7 +83,7 @@ edns_parse_record(edns_record_type *edns, buffer_type *packet) } opt_class = buffer_read_u16(packet); - opt_extended_rcode = buffer_read_u8(packet); + (void)buffer_read_u8(packet); /* opt_extended_rcode */ opt_version = buffer_read_u8(packet); opt_flags = buffer_read_u16(packet); opt_rdlen = buffer_read_u16(packet); diff --git a/usr.sbin/nsd/namedb.c b/usr.sbin/nsd/namedb.c index 573cb536cc9..39ce3e17c1f 100644 --- a/usr.sbin/nsd/namedb.c +++ b/usr.sbin/nsd/namedb.c @@ -37,6 +37,7 @@ allocate_domain_info(domain_table_type *table, result->node.key = dname_partial_copy( table->region, dname, domain_dname(parent)->label_count + 1); result->parent = parent; + result->nextdiff = NULL; result->wildcard_child_closest_match = result; result->rrsets = NULL; result->number = 0; @@ -71,6 +72,7 @@ domain_table_create(region_type *region) root = (domain_type *) region_alloc(region, sizeof(domain_type)); root->node.key = origin; root->parent = NULL; + root->nextdiff = NULL; root->wildcard_child_closest_match = root; root->rrsets = NULL; root->number = 1; /* 0 is used for after header */ diff --git a/usr.sbin/nsd/namedb.h b/usr.sbin/nsd/namedb.h index 963b05c8bdc..63cc9a656d6 100644 --- a/usr.sbin/nsd/namedb.h +++ b/usr.sbin/nsd/namedb.h @@ -43,6 +43,7 @@ struct domain { rbnode_t node; domain_type *parent; + domain_type *nextdiff; domain_type *wildcard_child_closest_match; rrset_type *rrsets; #ifdef NSEC3 diff --git a/usr.sbin/nsd/xfrd.c b/usr.sbin/nsd/xfrd.c index 59ddf31c45a..9c04dc8e85e 100644 --- a/usr.sbin/nsd/xfrd.c +++ b/usr.sbin/nsd/xfrd.c @@ -1066,8 +1066,7 @@ xfrd_xfr_check_rrs(xfrd_zone_t* zone, buffer_type* packet, size_t count, int *done, xfrd_soa_t* soa) { /* first RR has already been checked */ - uint16_t type, klass, rrlen; - uint32_t ttl; + uint16_t type, rrlen; size_t i, soapos; for(i=0; imsg_rr_count) { @@ -1077,8 +1076,8 @@ xfrd_xfr_check_rrs(xfrd_zone_t* zone, buffer_type* packet, size_t count, return 0; soapos = buffer_position(packet); type = buffer_read_u16(packet); - klass = buffer_read_u16(packet); - ttl = buffer_read_u32(packet); + (void)buffer_read_u16(packet); /* class */ + (void)buffer_read_u32(packet); /* ttl */ rrlen = buffer_read_u16(packet); if(!buffer_available(packet, rrlen)) return 0; -- cgit v1.2.3