#1 Simple bump of unbound to 1.13.1
Opened 3 years ago by malmond. Modified 3 years ago

file modified
+1 -1
@@ -1,1 +1,1 @@ 

- SOURCES/unbound-1.7.3.tar.gz

+ SOURCES/unbound-1.13.1.tar.gz

file modified
+1 -1
@@ -1,1 +1,1 @@ 

- 106789bdca173d033d769c67be3441b47611612a SOURCES/unbound-1.7.3.tar.gz

+ 561522b06943f6d1c33bd78132db1f7020fc4fd1 SOURCES/unbound-1.13.1.tar.gz

@@ -1,320 +0,0 @@ 

- From b5aab36d41f374eddb0f66f28f251588f53a1e1e Mon Sep 17 00:00:00 2001

- From: Wouter Wijngaards <wouter@nlnetlabs.nl>

- Date: Wed, 27 Jun 2018 05:46:36 +0000

- Subject: [PATCH 1/2] - #4109: Fix that package config depends on python

-  unconditionally.

- 

- git-svn-id: file:///svn/unbound/trunk@4757 be551aaa-1e26-0410-a405-d3ace91eadb9

- ---

-  configure    | 257 +++++++++++++++++++++++++++++++----------------------------

-  configure.ac |   5 +-

-  2 files changed, 137 insertions(+), 125 deletions(-)

- 

- diff --git a/configure b/configure

- index 3f1c372a..2a1687ae 100755

- --- a/configure

- +++ b/configure

- @@ -670,9 +670,6 @@ SYSTEMD_DAEMON_LIBS

-  SYSTEMD_DAEMON_CFLAGS

-  SYSTEMD_LIBS

-  SYSTEMD_CFLAGS

- -PKG_CONFIG_LIBDIR

- -PKG_CONFIG_PATH

- -PKG_CONFIG

-  staticexe

-  PC_LIBEVENT_DEPENDENCY

-  UNBOUND_EVENT_UNINSTALL

- @@ -697,6 +694,9 @@ swig

-  SWIG_LIB

-  SWIG

-  PC_PY_DEPENDENCY

- +PKG_CONFIG_LIBDIR

- +PKG_CONFIG_PATH

- +PKG_CONFIG

-  PY_MAJOR_VERSION

-  PYTHON_SITE_PKG

-  PYTHON_LDFLAGS

- @@ -16930,7 +16930,136 @@ $as_echo "#define HAVE_PYTHON 1" >>confdefs.h

-          CPPFLAGS="$PYTHON_CPPFLAGS"

-        fi

-        ub_have_python=yes

- -      PC_PY_DEPENDENCY="python"

- +

- +

- +

- +

- +

- +

- +

- +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then

- +	if test -n "$ac_tool_prefix"; then

- +  # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.

- +set dummy ${ac_tool_prefix}pkg-config; ac_word=$2

- +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5

- +$as_echo_n "checking for $ac_word... " >&6; }

- +if ${ac_cv_path_PKG_CONFIG+:} false; then :

- +  $as_echo_n "(cached) " >&6

- +else

- +  case $PKG_CONFIG in

- +  [\\/]* | ?:[\\/]*)

- +  ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.

- +  ;;

- +  *)

- +  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR

- +for as_dir in $PATH

- +do

- +  IFS=$as_save_IFS

- +  test -z "$as_dir" && as_dir=.

- +    for ac_exec_ext in '' $ac_executable_extensions; do

- +  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then

- +    ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"

- +    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5

- +    break 2

- +  fi

- +done

- +  done

- +IFS=$as_save_IFS

- +

- +  ;;

- +esac

- +fi

- +PKG_CONFIG=$ac_cv_path_PKG_CONFIG

- +if test -n "$PKG_CONFIG"; then

- +  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5

- +$as_echo "$PKG_CONFIG" >&6; }

- +else

- +  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5

- +$as_echo "no" >&6; }

- +fi

- +

- +

- +fi

- +if test -z "$ac_cv_path_PKG_CONFIG"; then

- +  ac_pt_PKG_CONFIG=$PKG_CONFIG

- +  # Extract the first word of "pkg-config", so it can be a program name with args.

- +set dummy pkg-config; ac_word=$2

- +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5

- +$as_echo_n "checking for $ac_word... " >&6; }

- +if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then :

- +  $as_echo_n "(cached) " >&6

- +else

- +  case $ac_pt_PKG_CONFIG in

- +  [\\/]* | ?:[\\/]*)

- +  ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path.

- +  ;;

- +  *)

- +  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR

- +for as_dir in $PATH

- +do

- +  IFS=$as_save_IFS

- +  test -z "$as_dir" && as_dir=.

- +    for ac_exec_ext in '' $ac_executable_extensions; do

- +  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then

- +    ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"

- +    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5

- +    break 2

- +  fi

- +done

- +  done

- +IFS=$as_save_IFS

- +

- +  ;;

- +esac

- +fi

- +ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG

- +if test -n "$ac_pt_PKG_CONFIG"; then

- +  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5

- +$as_echo "$ac_pt_PKG_CONFIG" >&6; }

- +else

- +  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5

- +$as_echo "no" >&6; }

- +fi

- +

- +  if test "x$ac_pt_PKG_CONFIG" = x; then

- +    PKG_CONFIG=""

- +  else

- +    case $cross_compiling:$ac_tool_warned in

- +yes:)

- +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5

- +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}

- +ac_tool_warned=yes ;;

- +esac

- +    PKG_CONFIG=$ac_pt_PKG_CONFIG

- +  fi

- +else

- +  PKG_CONFIG="$ac_cv_path_PKG_CONFIG"

- +fi

- +

- +fi

- +if test -n "$PKG_CONFIG"; then

- +	_pkg_min_version=0.9.0

- +	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5

- +$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; }

- +	if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then

- +		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5

- +$as_echo "yes" >&6; }

- +	else

- +		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5

- +$as_echo "no" >&6; }

- +		PKG_CONFIG=""

- +	fi

- +fi

- +      if test -n "$PKG_CONFIG" && \

- +    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\"python\${PY_MAJOR_VERSION}\"\""; } >&5

- +  ($PKG_CONFIG --exists --print-errors ""python${PY_MAJOR_VERSION}"") 2>&5

- +  ac_status=$?

- +  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5

- +  test $ac_status = 0; }; then

- +  PC_PY_DEPENDENCY="python${PY_MAJOR_VERSION}"

- +else

- +  PC_PY_DEPENDENCY="python"

- +fi

-  

-  

-        # Check for SWIG

- @@ -18960,126 +19089,6 @@ else

-  fi

-  

-  have_systemd=no

- -

- -

- -

- -

- -

- -

- -

- -if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then

- -	if test -n "$ac_tool_prefix"; then

- -  # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.

- -set dummy ${ac_tool_prefix}pkg-config; ac_word=$2

- -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5

- -$as_echo_n "checking for $ac_word... " >&6; }

- -if ${ac_cv_path_PKG_CONFIG+:} false; then :

- -  $as_echo_n "(cached) " >&6

- -else

- -  case $PKG_CONFIG in

- -  [\\/]* | ?:[\\/]*)

- -  ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.

- -  ;;

- -  *)

- -  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR

- -for as_dir in $PATH

- -do

- -  IFS=$as_save_IFS

- -  test -z "$as_dir" && as_dir=.

- -    for ac_exec_ext in '' $ac_executable_extensions; do

- -  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then

- -    ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"

- -    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5

- -    break 2

- -  fi

- -done

- -  done

- -IFS=$as_save_IFS

- -

- -  ;;

- -esac

- -fi

- -PKG_CONFIG=$ac_cv_path_PKG_CONFIG

- -if test -n "$PKG_CONFIG"; then

- -  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5

- -$as_echo "$PKG_CONFIG" >&6; }

- -else

- -  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5

- -$as_echo "no" >&6; }

- -fi

- -

- -

- -fi

- -if test -z "$ac_cv_path_PKG_CONFIG"; then

- -  ac_pt_PKG_CONFIG=$PKG_CONFIG

- -  # Extract the first word of "pkg-config", so it can be a program name with args.

- -set dummy pkg-config; ac_word=$2

- -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5

- -$as_echo_n "checking for $ac_word... " >&6; }

- -if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then :

- -  $as_echo_n "(cached) " >&6

- -else

- -  case $ac_pt_PKG_CONFIG in

- -  [\\/]* | ?:[\\/]*)

- -  ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path.

- -  ;;

- -  *)

- -  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR

- -for as_dir in $PATH

- -do

- -  IFS=$as_save_IFS

- -  test -z "$as_dir" && as_dir=.

- -    for ac_exec_ext in '' $ac_executable_extensions; do

- -  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then

- -    ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"

- -    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5

- -    break 2

- -  fi

- -done

- -  done

- -IFS=$as_save_IFS

- -

- -  ;;

- -esac

- -fi

- -ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG

- -if test -n "$ac_pt_PKG_CONFIG"; then

- -  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5

- -$as_echo "$ac_pt_PKG_CONFIG" >&6; }

- -else

- -  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5

- -$as_echo "no" >&6; }

- -fi

- -

- -  if test "x$ac_pt_PKG_CONFIG" = x; then

- -    PKG_CONFIG=""

- -  else

- -    case $cross_compiling:$ac_tool_warned in

- -yes:)

- -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5

- -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}

- -ac_tool_warned=yes ;;

- -esac

- -    PKG_CONFIG=$ac_pt_PKG_CONFIG

- -  fi

- -else

- -  PKG_CONFIG="$ac_cv_path_PKG_CONFIG"

- -fi

- -

- -fi

- -if test -n "$PKG_CONFIG"; then

- -	_pkg_min_version=0.9.0

- -	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5

- -$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; }

- -	if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then

- -		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5

- -$as_echo "yes" >&6; }

- -	else

- -		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5

- -$as_echo "no" >&6; }

- -		PKG_CONFIG=""

- -	fi

- -fi

-  if test "x$enable_systemd" != xno; then :

-  

-  

- diff --git a/configure.ac b/configure.ac

- index 1828253c..b2c95d1a 100644

- --- a/configure.ac

- +++ b/configure.ac

- @@ -586,7 +586,10 @@ if test x_$ub_test_python != x_no; then

-          CPPFLAGS="$PYTHON_CPPFLAGS"

-        fi

-        ub_have_python=yes

- -      PC_PY_DEPENDENCY="python"

- +      PKG_PROG_PKG_CONFIG

- +      PKG_CHECK_EXISTS(["python${PY_MAJOR_VERSION}"],

- +                       [PC_PY_DEPENDENCY="python${PY_MAJOR_VERSION}"],

- +                       [PC_PY_DEPENDENCY="python"])

-        AC_SUBST(PC_PY_DEPENDENCY)

-  

-        # Check for SWIG

- -- 

- 2.14.4

- 

@@ -1,31 +0,0 @@ 

- From bca54a8b252d4a75e940424dc761c6a4e487eb84 Mon Sep 17 00:00:00 2001

- From: Wouter Wijngaards <wouter@nlnetlabs.nl>

- Date: Wed, 27 Jun 2018 06:07:31 +0000

- Subject: [PATCH 2/2] =?UTF-8?q?-=20Patch,=20do=20not=20export=20python=20f?=

-  =?UTF-8?q?rom=20pkg-config,=20from=20Petr=20Men=C5=A1=C3=ADk.?=

- MIME-Version: 1.0

- Content-Type: text/plain; charset=UTF-8

- Content-Transfer-Encoding: 8bit

- 

- git-svn-id: file:///svn/unbound/trunk@4758 be551aaa-1e26-0410-a405-d3ace91eadb9

- ---

-  contrib/libunbound.pc.in | 3 ++-

-  1 file changed, 2 insertions(+), 1 deletion(-)

- 

- diff --git a/contrib/libunbound.pc.in b/contrib/libunbound.pc.in

- index 0cb9f875..810c5713 100644

- --- a/contrib/libunbound.pc.in

- +++ b/contrib/libunbound.pc.in

- @@ -7,7 +7,8 @@ Name: unbound

-  Description: Library with validating, recursive, and caching DNS resolver

-  URL: http://www.unbound.net

-  Version: @PACKAGE_VERSION@

- -Requires: @PC_LIBEVENT_DEPENDENCY@ @PC_PY_DEPENDENCY@

- +Requires: libcrypto libssl @PC_LIBEVENT_DEPENDENCY@

- +Requires.private: @PC_PY_DEPENDENCY@

-  Libs: -L${libdir} -lunbound -lssl -lcrypto

-  Libs.private: @SSLLIB@ @LIBS@

-  Cflags: -I${includedir} 

- -- 

- 2.14.4

- 

@@ -1,36 +0,0 @@ 

- From 377d5b426a30fc915cf7905786f93c0ec89845b7 Mon Sep 17 00:00:00 2001

- From: Wouter Wijngaards <wouter@nlnetlabs.nl>

- Date: Tue, 25 Sep 2018 09:01:13 +0000

- Subject: [PATCH] - Add SSL cleanup for tcp timeout.

- 

- git-svn-id: file:///svn/unbound/trunk@4915 be551aaa-1e26-0410-a405-d3ace91eadb9

- ---

-  services/outside_network.c | 11 +++++++++++

-  1 files changed, 9 insertions(+)

- diff --git a/services/outside_network.c b/services/outside_network.c

- index 5700ef8..b52cdab 100644

- --- a/services/outside_network.c

- +++ b/services/outside_network.c

- @@ -373,6 +373,8 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)

-                          if(!SSL_set1_host(pend->c->ssl, w->tls_auth_name)) {

-                                  log_err("SSL_set1_host failed");

-  				pend->c->fd = s;

- +				SSL_free(pend->c->ssl);

- +				pend->c->ssl = NULL;

-  				comm_point_close(pend->c);

-  				return 0;

-  			}

- @@ -1258,6 +1260,13 @@ outnet_tcptimer(void* arg)

-  	} else {

-  		/* it was in use */

-  		struct pending_tcp* pend=(struct pending_tcp*)w->next_waiting;

- +		if(pend->c->ssl) {

- +#ifdef HAVE_SSL

- +			SSL_shutdown(pend->c->ssl);

- +			SSL_free(pend->c->ssl);

- +			pend->c->ssl = NULL;

- +#endif

- +		}

-  		comm_point_close(pend->c);

-  		pend->query = NULL;

-  		pend->next_free = outnet->tcp_free;

@@ -1,553 +0,0 @@ 

- diff --git a/daemon/worker.c b/daemon/worker.c

- index 44a989a..3acecc1 100644

- --- a/daemon/worker.c

- +++ b/daemon/worker.c

- @@ -1193,7 +1193,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,

-  	if(worker->env.cfg->log_queries) {

-  		char ip[128];

-  		addr_to_str(&repinfo->addr, repinfo->addrlen, ip, sizeof(ip));

- -		log_nametypeclass(0, ip, qinfo.qname, qinfo.qtype, qinfo.qclass);

- +		log_query_in(ip, qinfo.qname, qinfo.qtype, qinfo.qclass);

-  	}

-  	if(qinfo.qtype == LDNS_RR_TYPE_AXFR || 

-  		qinfo.qtype == LDNS_RR_TYPE_IXFR) {

- diff --git a/doc/Changelog b/doc/Changelog

- index 3d05ae5..bb74461 100644

- --- a/doc/Changelog

- +++ b/doc/Changelog

- @@ -1,3 +1,15 @@

- +30 November 2018: Wouter

- +	- log-tag-queryreply: yes in unbound.conf tags the log-queries and

- +	  log-replies in the log file for easier log filter maintenance.

- +

- +21 August 2018: Wouter

- +	- log-local-actions: yes option for unbound.conf that logs all the

- +	  local zone actions, a patch from Saksham Manchanda (Secure64).

- +

- +17 August 2018: Wouter

- +	- log-servfail: yes prints log lines that say why queries are

- +	  returning SERVFAIL to clients.

- +

-  19 June 2018: Wouter

-  	- Fix for unbound-control on Windows and set TCP socket parameters

-  	  more closely.

- diff --git a/doc/example.conf.in b/doc/example.conf.in

- index be83bda..aa06cee 100644

- --- a/doc/example.conf.in

- +++ b/doc/example.conf.in

- @@ -309,6 +309,17 @@ server:

-  	# timetoresolve, fromcache and responsesize.

-  	# log-replies: no

-  

- +	# log with tag 'query' and 'reply' instead of 'info' for

- +	# filtering log-queries and log-replies from the log.

- +	# log-tag-queryreply: no

- +

- +	# log the local-zone actions, like local-zone type inform is enabled

- +	# also for the other local zone types.

- +	# log-local-actions: no

- +

- +	# print log lines that say why queries return SERVFAIL to clients.

- +	# log-servfail: no

- +

-  	# the pid file. Can be an absolute path outside of chroot/work dir.

-  	# pidfile: "@UNBOUND_PIDFILE@"

-  

- diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in

- index 9167a5a..b73bc70 100644

- --- a/doc/unbound.conf.5.in

- +++ b/doc/unbound.conf.5.in

- @@ -618,6 +618,21 @@ Default is no.  Note that it takes time to print these

-  lines which makes the server (significantly) slower.  Odd (nonprintable)

-  characters in names are printed as '?'.

-  .TP

- +.B log\-tag\-queryreply: \fI<yes or no>

- +Prints the word 'query' and 'reply' with log\-queries and log\-replies.

- +This makes filtering logs easier.  The default is off (for backwards

- +compatibility).

- +.TP

- +.B log\-local\-actions: \fI<yes or no>

- +Print log lines to inform about local zone actions.  These lines are like the

- +local\-zone type inform prints out, but they are also printed for the other

- +types of local zones.

- +.TP

- +.B log\-servfail: \fI<yes or no>

- +Print log lines that say why queries return SERVFAIL to clients.

- +This is separate from the verbosity debug logs, much smaller, and printed

- +at the error level, not the info level of debug info from verbosity.

- +.TP

-  .B pidfile: \fI<filename>

-  The process id is written to the file. Default is "@UNBOUND_PIDFILE@".

-  So,

- diff --git a/services/localzone.c b/services/localzone.c

- index 0f60817..a85619b 100644

- --- a/services/localzone.c

- +++ b/services/localzone.c

- @@ -1459,7 +1459,7 @@ lz_inform_print(struct local_zone* z, struct query_info* qinfo,

-  	uint16_t port = ntohs(((struct sockaddr_in*)&repinfo->addr)->sin_port);

-  	dname_str(z->name, zname);

-  	addr_to_str(&repinfo->addr, repinfo->addrlen, ip, sizeof(ip));

- -	snprintf(txt, sizeof(txt), "%s inform %s@%u", zname, ip,

- +	snprintf(txt, sizeof(txt), "%s %s %s@%u", zname, local_zone_type2str(z->type), ip,

-  		(unsigned)port);

-  	log_nametypeclass(0, txt, qinfo->qname, qinfo->qtype, qinfo->qclass);

-  }

- @@ -1576,7 +1576,8 @@ local_zones_answer(struct local_zones* zones, struct module_env* env,

-  			z->override_tree, &tag, tagname, num_tags);

-  		lock_rw_unlock(&zones->lock);

-  	}

- -	if((lzt == local_zone_inform || lzt == local_zone_inform_deny)

- +	if((env->cfg->log_local_actions ||

- +		lzt == local_zone_inform || lzt == local_zone_inform_deny)

-  		&& repinfo)

-  		lz_inform_print(z, qinfo, repinfo);

-  

- diff --git a/services/mesh.c b/services/mesh.c

- index 41aba74..55c1947 100644

- --- a/services/mesh.c

- +++ b/services/mesh.c

- @@ -977,7 +977,7 @@ mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep,

-  		rcode = LDNS_RCODE_SERVFAIL;

-  	if(!rcode && (rep->security == sec_status_bogus ||

-  		rep->security == sec_status_secure_sentinel_fail)) {

- -		if(!(reason = errinf_to_str(&m->s)))

- +		if(!(reason = errinf_to_str_bogus(&m->s)))

-  			rcode = LDNS_RCODE_SERVFAIL;

-  	}

-  	/* send the reply */

- @@ -1148,6 +1148,15 @@ void mesh_query_done(struct mesh_state* mstate)

-  	struct mesh_cb* c;

-  	struct reply_info* rep = (mstate->s.return_msg?

-  		mstate->s.return_msg->rep:NULL);

- +	if((mstate->s.return_rcode == LDNS_RCODE_SERVFAIL ||

- +		(rep && FLAGS_GET_RCODE(rep->flags) == LDNS_RCODE_SERVFAIL))

- +		&& mstate->s.env->cfg->log_servfail

- +		&& !mstate->s.env->cfg->val_log_squelch) {

- +			char* err = errinf_to_str_servfail(&mstate->s);

- +			if(err)

- +				log_err("%s", err);

- +			free(err);

- +	}

-  	for(r = mstate->reply_list; r; r = r->next) {

-  		/* if a response-ip address block has been stored the

-  		 *  information should be logged for each client. */

- diff --git a/util/config_file.c b/util/config_file.c

- index b061760..68a0a15 100644

- --- a/util/config_file.c

- +++ b/util/config_file.c

- @@ -115,6 +115,9 @@ config_create(void)

-  	cfg->log_time_ascii = 0;

-  	cfg->log_queries = 0;

-  	cfg->log_replies = 0;

- +	cfg->log_tag_queryreply = 0;

- +	cfg->log_local_actions = 0;

- +	cfg->log_servfail = 0;

-  #ifndef USE_WINSOCK

-  #  ifdef USE_MINI_EVENT

-  	/* select max 1024 sockets */

- @@ -540,6 +543,9 @@ int config_set_option(struct config_file* cfg, const char* opt,

-  	else S_YNO("val-log-squelch:", val_log_squelch)

-  	else S_YNO("log-queries:", log_queries)

-  	else S_YNO("log-replies:", log_replies)

- +	else S_YNO("log-tag-queryreply:", log_tag_queryreply)

- +	else S_YNO("log-local-actions:", log_local_actions)

- +	else S_YNO("log-servfail:", log_servfail)

-  	else S_YNO("val-permissive-mode:", val_permissive_mode)

-  	else S_YNO("aggressive-nsec:", aggressive_nsec)

-  	else S_YNO("ignore-cd-flag:", ignore_cd)

- @@ -893,6 +899,9 @@ config_get_option(struct config_file* cfg, const char* opt,

-  	else O_STR(opt, "logfile", logfile)

-  	else O_YNO(opt, "log-queries", log_queries)

-  	else O_YNO(opt, "log-replies", log_replies)

- +	else O_YNO(opt, "log-tag-queryreply", log_tag_queryreply)

- +	else O_YNO(opt, "log-local-actions", log_local_actions)

- +	else O_YNO(opt, "log-servfail", log_servfail)

-  	else O_STR(opt, "pidfile", pidfile)

-  	else O_YNO(opt, "hide-identity", hide_identity)

-  	else O_YNO(opt, "hide-version", hide_version)

- @@ -1845,6 +1854,7 @@ config_apply(struct config_file* config)

-  	EDNS_ADVERTISED_SIZE = (uint16_t)config->edns_buffer_size;

-  	MINIMAL_RESPONSES = config->minimal_responses;

-  	RRSET_ROUNDROBIN = config->rrset_roundrobin;

- +	LOG_TAG_QUERYREPLY = config->log_tag_queryreply;

-  	log_set_time_asc(config->log_time_ascii);

-  	autr_permit_small_holddown = config->permit_small_holddown;

-  }

- @@ -2220,7 +2230,7 @@ void errinf_origin(struct module_qstate* qstate, struct sock_list *origin)

-  	}

-  }

-  

- -char* errinf_to_str(struct module_qstate* qstate)

- +char* errinf_to_str_bogus(struct module_qstate* qstate)

-  {

-  	char buf[20480];

-  	char* p = buf;

- @@ -2245,6 +2255,31 @@ char* errinf_to_str(struct module_qstate* qstate)

-  	return p;

-  }

-  

- +char* errinf_to_str_servfail(struct module_qstate* qstate)

- +{

- +    char buf[20480];

- +    char* p = buf;

- +    size_t left = sizeof(buf);

- +    struct config_strlist* s;

- +    char dname[LDNS_MAX_DOMAINLEN+1];

- +    char t[16], c[16];

- +    sldns_wire2str_type_buf(qstate->qinfo.qtype, t, sizeof(t));

- +    sldns_wire2str_class_buf(qstate->qinfo.qclass, c, sizeof(c));

- +    dname_str(qstate->qinfo.qname, dname);

- +    snprintf(p, left, "SERVFAIL <%s %s %s>:", dname, t, c);

- +    left -= strlen(p); p += strlen(p);

- +    if(!qstate->errinf)

- +        snprintf(p, left, " misc failure");

- +    else for(s=qstate->errinf; s; s=s->next) {

- +        snprintf(p, left, " %s", s->str);

- +        left -= strlen(p); p += strlen(p);

- +    }

- +    p = strdup(buf);

- +    if(!p)

- +        log_err("malloc failure in errinf_to_str");

- +    return p;

- +}

- +

-  void errinf_rrset(struct module_qstate* qstate, struct ub_packed_rrset_key *rr)

-  {

-  	char buf[1024];

- diff --git a/util/config_file.h b/util/config_file.h

- index 4206eb9..1e7f402 100644

- --- a/util/config_file.h

- +++ b/util/config_file.h

- @@ -268,6 +268,12 @@ struct config_file {

-  	int log_queries;

-  	/** log replies with one line per reply */

-  	int log_replies;

- +	/** tag log_queries and log_replies for filtering */

- +	int log_tag_queryreply;

- +	/** log every local-zone hit **/

- +	int log_local_actions;

- +	/** log servfails with a reason */

- +	int log_servfail;

-  	/** log identity to report */

-  	char* log_identity;

-  

- @@ -1070,7 +1076,15 @@ void errinf_dname(struct module_qstate* qstate, const char* str,

-   * @return string or NULL on malloc failure (already logged).

-   *    This string is malloced and has to be freed by caller.

-   */

- -char* errinf_to_str(struct module_qstate* qstate);

- +char* errinf_to_str_bogus(struct module_qstate* qstate);

- +

- +/**

- + * Create error info in string.  For other servfails.

- + * @param qstate: query state.

- + * @return string or NULL on malloc failure (already logged).

- + *    This string is malloced and has to be freed by caller.

- + */

- +char* errinf_to_str_servfail(struct module_qstate* qstate);

-  

-  /**

-   * Used during options parsing

- diff --git a/util/configlexer.lex b/util/configlexer.lex

- index 6124e32..9b22db1 100644

- --- a/util/configlexer.lex

- +++ b/util/configlexer.lex

- @@ -366,6 +366,9 @@ log-identity{COLON}		{ YDVAR(1, VAR_LOG_IDENTITY) }

-  log-time-ascii{COLON}		{ YDVAR(1, VAR_LOG_TIME_ASCII) }

-  log-queries{COLON}		{ YDVAR(1, VAR_LOG_QUERIES) }

-  log-replies{COLON}		{ YDVAR(1, VAR_LOG_REPLIES) }

- +log-tag-queryreply{COLON}      { YDVAR(1, VAR_LOG_TAG_QUERYREPLY) }

- +log-local-actions{COLON}       { YDVAR(1, VAR_LOG_LOCAL_ACTIONS) }

- +log-servfail{COLON}            { YDVAR(1, VAR_LOG_SERVFAIL) }

-  local-zone{COLON}		{ YDVAR(2, VAR_LOCAL_ZONE) }

-  local-data{COLON}		{ YDVAR(1, VAR_LOCAL_DATA) }

-  local-data-ptr{COLON}		{ YDVAR(1, VAR_LOCAL_DATA_PTR) }

- diff --git a/util/configparser.y b/util/configparser.y

- index e34665a..4b23a71 100644

- --- a/util/configparser.y

- +++ b/util/configparser.y

- @@ -106,7 +106,7 @@ extern struct config_parser_state* cfg_parser;

-  %token VAR_AUTO_TRUST_ANCHOR_FILE VAR_KEEP_MISSING VAR_ADD_HOLDDOWN 

-  %token VAR_DEL_HOLDDOWN VAR_SO_RCVBUF VAR_EDNS_BUFFER_SIZE VAR_PREFETCH

-  %token VAR_PREFETCH_KEY VAR_SO_SNDBUF VAR_SO_REUSEPORT VAR_HARDEN_BELOW_NXDOMAIN

- -%token VAR_IGNORE_CD_FLAG VAR_LOG_QUERIES VAR_LOG_REPLIES

- +%token VAR_IGNORE_CD_FLAG VAR_LOG_QUERIES VAR_LOG_REPLIES VAR_LOG_LOCAL_ACTIONS

-  %token VAR_TCP_UPSTREAM VAR_SSL_UPSTREAM

-  %token VAR_SSL_SERVICE_KEY VAR_SSL_SERVICE_PEM VAR_SSL_PORT VAR_FORWARD_FIRST

-  %token VAR_STUB_SSL_UPSTREAM VAR_FORWARD_SSL_UPSTREAM VAR_TLS_CERT_BUNDLE

- @@ -158,6 +158,8 @@ extern struct config_parser_state* cfg_parser;

-  %token VAR_AUTH_ZONE VAR_ZONEFILE VAR_MASTER VAR_URL VAR_FOR_DOWNSTREAM

-  %token VAR_FALLBACK_ENABLED VAR_TLS_ADDITIONAL_PORT VAR_LOW_RTT VAR_LOW_RTT_PERMIL

-  %token VAR_ALLOW_NOTIFY VAR_TLS_WIN_CERT

- +%token VAR_FORWARD_NO_CACHE VAR_STUB_NO_CACHE VAR_LOG_SERVFAIL

- +%token VAR_UNKNOWN_SERVER_TIME_LIMIT VAR_LOG_TAG_QUERYREPLY

-  

-  %%

-  toplevelvars: /* empty */ | toplevelvars toplevelvar ;

- @@ -217,6 +219,7 @@ content_server: server_num_threads | server_verbosity | server_port |

-  	server_edns_buffer_size | server_prefetch | server_prefetch_key |

-  	server_so_sndbuf | server_harden_below_nxdomain | server_ignore_cd_flag |

-  	server_log_queries | server_log_replies | server_tcp_upstream | server_ssl_upstream |

- +	server_log_local_actions |

-  	server_ssl_service_key | server_ssl_service_pem | server_ssl_port |

-  	server_minimal_responses | server_rrset_roundrobin | server_max_udp_size |

-  	server_so_reuseport | server_delay_close |

- @@ -249,7 +252,9 @@ content_server: server_num_threads | server_verbosity | server_port |

-  	server_ipsecmod_whitelist | server_ipsecmod_strict |

-  	server_udp_upstream_without_downstream | server_aggressive_nsec |

-  	server_tls_cert_bundle | server_tls_additional_port | server_low_rtt |

- -	server_low_rtt_permil | server_tls_win_cert

- +	server_low_rtt_permil | server_tls_win_cert |

- +	server_tcp_connection_limit | server_log_servfail |

- +	server_unknown_server_time_limit | server_log_tag_queryreply

-  	;

-  stubstart: VAR_STUB_ZONE

-  	{

- @@ -764,6 +769,33 @@ server_log_replies: VAR_LOG_REPLIES STRING_ARG

-    	free($2);

-    }

-    ;

- +server_log_tag_queryreply: VAR_LOG_TAG_QUERYREPLY STRING_ARG

- +  {

- +    OUTYY(("P(server_log_tag_queryreply:%s)\n", $2));

- +    if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)

- +        yyerror("expected yes or no.");

- +    else cfg_parser->cfg->log_tag_queryreply = (strcmp($2, "yes")==0);

- +    free($2);

- +  }

- +  ;

- +server_log_servfail: VAR_LOG_SERVFAIL STRING_ARG

- +  {

- +	OUTYY(("P(server_log_servfail:%s)\n", $2));

- +	if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)

- +		yyerror("expected yes or no.");

- +	else cfg_parser->cfg->log_servfail = (strcmp($2, "yes")==0);

- +	free($2);

- +  }

- +  ;

- +server_log_local_actions: VAR_LOG_LOCAL_ACTIONS STRING_ARG

- +  {

- +	OUTYY(("P(server_log_local_actions:%s)\n", $2));

- +	if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)

- +		yyerror("expected yes or no.");

- +	else cfg_parser->cfg->log_local_actions = (strcmp($2, "yes")==0);

- +	free($2);

- +  }

- +  ;

-  server_chroot: VAR_CHROOT STRING_ARG

-  	{

-  		OUTYY(("P(server_chroot:%s)\n", $2));

- diff --git a/util/data/msgreply.c b/util/data/msgreply.c

- index 772f5d1..df2131c 100644

- --- a/util/data/msgreply.c

- +++ b/util/data/msgreply.c

- @@ -844,7 +844,9 @@ log_reply_info(enum verbosity_value v, struct query_info *qinf,

-  	addr_to_str(addr, addrlen, clientip_buf, sizeof(clientip_buf));

-  	if(rcode == LDNS_RCODE_FORMERR)

-  	{

- -		log_info("%s - - - %s - - - ", clientip_buf, rcode_buf);

- +		if(LOG_TAG_QUERYREPLY)

- +			log_reply("%s - - - %s - - - ", clientip_buf, rcode_buf);

- +		else log_info("%s - - - %s - - - ", clientip_buf, rcode_buf);

-  	} else {

-  		if(qinf->qname)

-  			dname_str(qinf->qname, qname_buf);

- @@ -852,7 +854,11 @@ log_reply_info(enum verbosity_value v, struct query_info *qinf,

-  		pktlen = sldns_buffer_limit(rmsg);

-  		sldns_wire2str_type_buf(qinf->qtype, type_buf, sizeof(type_buf));

-  		sldns_wire2str_class_buf(qinf->qclass, class_buf, sizeof(class_buf));

- -		log_info("%s %s %s %s %s " ARG_LL "d.%6.6d %d %d",

- +		if(LOG_TAG_QUERYREPLY)

- +			log_reply("%s %s %s %s %s " ARG_LL "d.%6.6d %d %d",

- +				clientip_buf, qname_buf, type_buf, class_buf,

- +				rcode_buf, (long long)dur.tv_sec, (int)dur.tv_usec, cached, (int)pktlen);

- +		else log_info("%s %s %s %s %s " ARG_LL "d.%6.6d %d %d",

-  			clientip_buf, qname_buf, type_buf, class_buf,

-  			rcode_buf, (long long)dur.tv_sec, (int)dur.tv_usec, cached, (int)pktlen);

-  	}

- diff --git a/util/log.c b/util/log.c

- index 43dd572..fff4319 100644

- --- a/util/log.c

- +++ b/util/log.c

- @@ -391,6 +391,24 @@ log_hex(const char* msg, void* data, size_t length)

-  	log_hex_f(verbosity, msg, data, length);

-  }

-  

- +void

- +log_query(const char *format, ...)

- +{

- +	va_list args;

- +	va_start(args, format);

- +	log_vmsg(LOG_INFO, "query", format, args);

- +	va_end(args);

- +}

- +

- +void

- +log_reply(const char *format, ...)

- +{

- +	va_list args;

- +	va_start(args, format);

- +	log_vmsg(LOG_INFO, "reply", format, args);

- +	va_end(args);

- +}

- +

-  void log_buf(enum verbosity_value level, const char* msg, sldns_buffer* buf)

-  {

-  	if(verbosity < level)

- diff --git a/util/log.h b/util/log.h

- index 7bc3d9e..172cd01 100644

- --- a/util/log.h

- +++ b/util/log.h

- @@ -160,6 +160,20 @@ void log_warn(const char* format, ...) ATTR_FORMAT(printf, 1, 2);

-   */

-  void log_hex(const char* msg, void* data, size_t length);

-  

- +/**

- + * Log query.

- + * Pass printf formatted arguments. No trailing newline is needed.

- + * @param format: printf-style format string. Arguments follow.

- + */

- +void log_query(const char* format, ...) ATTR_FORMAT(printf, 1, 2);

- +

- +/**

- + * Log reply.

- + * Pass printf formatted arguments. No trailing newline is needed.

- + * @param format: printf-style format string. Arguments follow.

- + */

- +void log_reply(const char* format, ...) ATTR_FORMAT(printf, 1, 2);

- +

-  /**

-   * Easy alternative for log_hex, takes a sldns_buffer.

-   * @param level: verbosity level for this message, compared to global 

- diff --git a/util/net_help.c b/util/net_help.c

- index a193c36..617a896 100644

- --- a/util/net_help.c

- +++ b/util/net_help.c

- @@ -67,6 +67,9 @@ int MINIMAL_RESPONSES = 0;

-  /** rrset order roundrobin: default is no */

-  int RRSET_ROUNDROBIN = 0;

-  

- +/** log tag queries with name instead of 'info' for filtering */

- +int LOG_TAG_QUERYREPLY = 0;

- +

-  /* returns true is string addr is an ip6 specced address */

-  int

-  str_is_ip6(const char* str)

- @@ -335,7 +338,7 @@ log_nametypeclass(enum verbosity_value v, const char* str, uint8_t* name,

-  {

-  	char buf[LDNS_MAX_DOMAINLEN+1];

-  	char t[12], c[12];

- -	const char *ts, *cs; 

- +	const char *ts, *cs;

-  	if(verbosity < v)

-  		return;

-  	dname_str(name, buf);

- @@ -361,6 +364,37 @@ log_nametypeclass(enum verbosity_value v, const char* str, uint8_t* name,

-  	log_info("%s %s %s %s", str, buf, ts, cs);

-  }

-  

- +void

- +log_query_in(const char* str, uint8_t* name, uint16_t type, uint16_t dclass)

- +{

- +    char buf[LDNS_MAX_DOMAINLEN+1];

- +    char t[12], c[12];

- +    const char *ts, *cs;

- +    dname_str(name, buf);

- +    if(type == LDNS_RR_TYPE_TSIG) ts = "TSIG";

- +    else if(type == LDNS_RR_TYPE_IXFR) ts = "IXFR";

- +    else if(type == LDNS_RR_TYPE_AXFR) ts = "AXFR";

- +    else if(type == LDNS_RR_TYPE_MAILB) ts = "MAILB";

- +    else if(type == LDNS_RR_TYPE_MAILA) ts = "MAILA";

- +    else if(type == LDNS_RR_TYPE_ANY) ts = "ANY";

- +    else if(sldns_rr_descript(type) && sldns_rr_descript(type)->_name)

- +        ts = sldns_rr_descript(type)->_name;

- +    else {

- +        snprintf(t, sizeof(t), "TYPE%d", (int)type);

- +        ts = t;

- +    }

- +    if(sldns_lookup_by_id(sldns_rr_classes, (int)dclass) &&

- +        sldns_lookup_by_id(sldns_rr_classes, (int)dclass)->name)

- +        cs = sldns_lookup_by_id(sldns_rr_classes, (int)dclass)->name;

- +    else {

- +        snprintf(c, sizeof(c), "CLASS%d", (int)dclass);

- +        cs = c;

- +    }

- +    if(LOG_TAG_QUERYREPLY)

- +            log_query("%s %s %s %s", str, buf, ts, cs);

- +    else    log_info("%s %s %s %s", str, buf, ts, cs);

- +}

- +

-  void log_name_addr(enum verbosity_value v, const char* str, uint8_t* zone, 

-  	struct sockaddr_storage* addr, socklen_t addrlen)

-  {

- diff --git a/util/net_help.h b/util/net_help.h

- index de2e1ac..f2e0e43 100644

- --- a/util/net_help.h

- +++ b/util/net_help.h

- @@ -99,6 +99,9 @@ extern int MINIMAL_RESPONSES;

-  /** rrset order roundrobin */

-  extern int RRSET_ROUNDROBIN;

-  

- +/** log tag queries with name instead of 'info' for filtering */

- +extern int LOG_TAG_QUERYREPLY;

- +

-  /**

-   * See if string is ip4 or ip6.

-   * @param str: IP specification.

- @@ -235,6 +238,12 @@ void sockaddr_store_port(struct sockaddr_storage* addr, socklen_t addrlen,

-  void log_nametypeclass(enum verbosity_value v, const char* str, 

-  	uint8_t* name, uint16_t type, uint16_t dclass);

-  

- +/**

- + * Like log_nametypeclass, but logs with log_query for query logging

- + */

- +void log_query_in(const char* str, uint8_t* name, uint16_t type,

- +       uint16_t dclass);

- +

-  /**

-   * Compare two sockaddrs. Imposes an ordering on the addresses.

-   * Compares address and port.

- diff --git a/validator/val_kcache.c b/validator/val_kcache.c

- index 22070cc..e0b88b6 100644

- --- a/validator/val_kcache.c

- +++ b/validator/val_kcache.c

- @@ -89,7 +89,7 @@ key_cache_insert(struct key_cache* kcache, struct key_entry_key* kkey,

-  	if(key_entry_isbad(k) && qstate->errinf &&

-  		qstate->env->cfg->val_log_level >= 2) {

-  		/* on malloc failure there is simply no reason string */

- -		key_entry_set_reason(k, errinf_to_str(qstate));

- +		key_entry_set_reason(k, errinf_to_str_bogus(qstate));

-  	}

-  	key_entry_hash(k);

-  	slabhash_insert(kcache->slab, k->entry.hash, &k->entry, 

- diff --git a/validator/validator.c b/validator/validator.c

- index 5777b29..2d9cc17 100644

- --- a/validator/validator.c

- +++ b/validator/validator.c

- @@ -2227,13 +2227,15 @@ processFinished(struct module_qstate* qstate, struct val_qstate* vq,

-  		vq->orig_msg->rep->ttl = ve->bogus_ttl;

-  		vq->orig_msg->rep->prefetch_ttl = 

-  			PREFETCH_TTL_CALC(vq->orig_msg->rep->ttl);

- -		if(qstate->env->cfg->val_log_level >= 1 &&

- +		if((qstate->env->cfg->val_log_level >= 1 ||

- +			qstate->env->cfg->log_servfail) &&

-  			!qstate->env->cfg->val_log_squelch) {

- -			if(qstate->env->cfg->val_log_level < 2)

- +            if(qstate->env->cfg->val_log_level < 2 &&

- +				!qstate->env->cfg->log_servfail)

-  				log_query_info(0, "validation failure",

-  					&qstate->qinfo);

-  			else {

- -				char* err = errinf_to_str(qstate);

- +				char* err = errinf_to_str_bogus(qstate);

-  				if(err) log_info("%s", err);

-  				free(err);

-  			}

- @@ -2332,6 +2334,7 @@ processDLVLookup(struct module_qstate* qstate, struct val_qstate* vq,

-  

-  	if(vq->dlv_status == dlv_error) {

-  		verbose(VERB_QUERY, "failed DLV lookup");

- +		errinf(qstate, "failed DLV lookup");

-  		return val_error(qstate, id);

-  	} else if(vq->dlv_status == dlv_success) {

-  		uint8_t* nm;

@@ -1,944 +0,0 @@ 

- diff --git a/iterator/iter_delegpt.c b/iterator/iter_delegpt.c

- index f88b3e1..522e0e9 100644

- --- a/iterator/iter_delegpt.c

- +++ b/iterator/iter_delegpt.c

- @@ -84,7 +84,7 @@ struct delegpt* delegpt_copy(struct delegpt* dp, struct regional* region)

-  	}

-  	for(a = dp->target_list; a; a = a->next_target) {

-  		if(!delegpt_add_addr(copy, region, &a->addr, a->addrlen, 

- -			a->bogus, a->lame, a->tls_auth_name))

- +           a->bogus, a->lame, a->tls_auth_name, NULL))

-  			return NULL;

-  	}

-  	return copy;

- @@ -161,7 +161,7 @@ delegpt_find_addr(struct delegpt* dp, struct sockaddr_storage* addr,

-  int 

-  delegpt_add_target(struct delegpt* dp, struct regional* region, 

-  	uint8_t* name, size_t namelen, struct sockaddr_storage* addr, 

- -	socklen_t addrlen, uint8_t bogus, uint8_t lame)

- +   socklen_t addrlen, uint8_t bogus, uint8_t lame, int* additions)

-  {

-  	struct delegpt_ns* ns = delegpt_find_ns(dp, name, namelen);

-  	log_assert(!dp->dp_type_mlc);

- @@ -176,13 +176,14 @@ delegpt_add_target(struct delegpt* dp, struct regional* region,

-  		if(ns->got4 && ns->got6)

-  			ns->resolved = 1;

-  	}

- -	return delegpt_add_addr(dp, region, addr, addrlen, bogus, lame, NULL);

- +	return delegpt_add_addr(dp, region, addr, addrlen, bogus, lame, NULL,

- +        additions);

-  }

-  

-  int 

-  delegpt_add_addr(struct delegpt* dp, struct regional* region, 

-  	struct sockaddr_storage* addr, socklen_t addrlen, uint8_t bogus, 

- -	uint8_t lame, char* tls_auth_name)

- +	uint8_t lame, char* tls_auth_name, int* additions)

-  {

-  	struct delegpt_addr* a;

-  	log_assert(!dp->dp_type_mlc);

- @@ -195,6 +196,9 @@ delegpt_add_addr(struct delegpt* dp, struct regional* region,

-  		return 1;

-  	}

-  

- +    if(additions)

- +        *additions = 1;

- +

-  	a = (struct delegpt_addr*)regional_alloc(region,

-  		sizeof(struct delegpt_addr));

-  	if(!a)

- @@ -382,10 +386,10 @@ delegpt_from_message(struct dns_msg* msg, struct regional* region)

-  			continue;

-  

-  		if(ntohs(s->rk.type) == LDNS_RR_TYPE_A) {

- -			if(!delegpt_add_rrset_A(dp, region, s, 0))

- +			if(!delegpt_add_rrset_A(dp, region, s, 0, NULL))

-  				return NULL;

-  		} else if(ntohs(s->rk.type) == LDNS_RR_TYPE_AAAA) {

- -			if(!delegpt_add_rrset_AAAA(dp, region, s, 0))

- +			if(!delegpt_add_rrset_AAAA(dp, region, s, 0, NULL))

-  				return NULL;

-  		}

-  	}

- @@ -416,7 +420,7 @@ delegpt_rrset_add_ns(struct delegpt* dp, struct regional* region,

-  

-  int 

-  delegpt_add_rrset_A(struct delegpt* dp, struct regional* region,

- -	struct ub_packed_rrset_key* ak, uint8_t lame)

- +	struct ub_packed_rrset_key* ak, uint8_t lame, int* additions)

-  {

-          struct packed_rrset_data* d=(struct packed_rrset_data*)ak->entry.data;

-          size_t i;

- @@ -432,7 +436,7 @@ delegpt_add_rrset_A(struct delegpt* dp, struct regional* region,

-                  memmove(&sa.sin_addr, d->rr_data[i]+2, INET_SIZE);

-                  if(!delegpt_add_target(dp, region, ak->rk.dname,

-                          ak->rk.dname_len, (struct sockaddr_storage*)&sa,

- -                        len, (d->security==sec_status_bogus), lame))

- +                        len, (d->security==sec_status_bogus), lame, additions))

-                          return 0;

-          }

-          return 1;

- @@ -440,7 +444,7 @@ delegpt_add_rrset_A(struct delegpt* dp, struct regional* region,

-  

-  int 

-  delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* region,

- -	struct ub_packed_rrset_key* ak, uint8_t lame)

- +	struct ub_packed_rrset_key* ak, uint8_t lame, int* additions)

-  {

-          struct packed_rrset_data* d=(struct packed_rrset_data*)ak->entry.data;

-          size_t i;

- @@ -456,7 +460,7 @@ delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* region,

-                  memmove(&sa.sin6_addr, d->rr_data[i]+2, INET6_SIZE);

-                  if(!delegpt_add_target(dp, region, ak->rk.dname,

-                          ak->rk.dname_len, (struct sockaddr_storage*)&sa,

- -                        len, (d->security==sec_status_bogus), lame))

- +                        len, (d->security==sec_status_bogus), lame, additions))

-                          return 0;

-          }

-          return 1;

- @@ -464,20 +468,32 @@ delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* region,

-  

-  int 

-  delegpt_add_rrset(struct delegpt* dp, struct regional* region,

- -        struct ub_packed_rrset_key* rrset, uint8_t lame)

- +        struct ub_packed_rrset_key* rrset, uint8_t lame, int* additions)

-  {

-  	if(!rrset)

-  		return 1;

-  	if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_NS)

-  		return delegpt_rrset_add_ns(dp, region, rrset, lame);

-  	else if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_A)

- -		return delegpt_add_rrset_A(dp, region, rrset, lame);

- +		return delegpt_add_rrset_A(dp, region, rrset, lame, additions);

-  	else if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_AAAA)

- -		return delegpt_add_rrset_AAAA(dp, region, rrset, lame);

- +		return delegpt_add_rrset_AAAA(dp, region, rrset, lame, additions);

-  	log_warn("Unknown rrset type added to delegpt");

-  	return 1;

-  }

-  

- +void delegpt_mark_neg(struct delegpt_ns* ns, uint16_t qtype)

- +{

- +    if(ns) {

- +        if(qtype == LDNS_RR_TYPE_A)

- +            ns->got4 = 2;

- +        else if(qtype == LDNS_RR_TYPE_AAAA)

- +            ns->got6 = 2;

- +        if(ns->got4 && ns->got6)

- +            ns->resolved = 1;

- +    }

- +}

- +

-  void delegpt_add_neg_msg(struct delegpt* dp, struct msgreply_entry* msg)

-  {

-  	struct reply_info* rep = (struct reply_info*)msg->entry.data;

- @@ -487,14 +503,7 @@ void delegpt_add_neg_msg(struct delegpt* dp, struct msgreply_entry* msg)

-  	if(FLAGS_GET_RCODE(rep->flags) != 0 || rep->an_numrrsets == 0) {

-  		struct delegpt_ns* ns = delegpt_find_ns(dp, msg->key.qname, 

-  			msg->key.qname_len);

- -		if(ns) {

- -			if(msg->key.qtype == LDNS_RR_TYPE_A)

- -				ns->got4 = 1;

- -			else if(msg->key.qtype == LDNS_RR_TYPE_AAAA)

- -				ns->got6 = 1;

- -			if(ns->got4 && ns->got6)

- -				ns->resolved = 1;

- -		}

- +        delegpt_mark_neg(ns, msg->key.qtype);

-  	}

-  }

-  

- diff --git a/iterator/iter_delegpt.h b/iterator/iter_delegpt.h

- index 354bd61..3aded22 100644

- --- a/iterator/iter_delegpt.h

- +++ b/iterator/iter_delegpt.h

- @@ -104,9 +104,10 @@ struct delegpt_ns {

-  	 * and marked true if got4 and got6 are both true.

-  	 */

-  	int resolved;

- -	/** if the ipv4 address is in the delegpt */

- +	/** if the ipv4 address is in the delegpt, 0=not, 1=yes 2=negative,

- +     * negative means it was done, but no content. */

-  	uint8_t got4;

- -	/** if the ipv6 address is in the delegpt */

- +	/** if the ipv6 address is in the delegpt, 0=not, 1=yes 2=negative */

-  	uint8_t got6;

-  	/**

-  	 * If the name is parent-side only and thus dispreferred.

- @@ -213,11 +214,12 @@ int delegpt_rrset_add_ns(struct delegpt* dp, struct regional* regional,

-   * @param addrlen: the length of addr.

-   * @param bogus: security status for the address, pass true if bogus.

-   * @param lame: address is lame.

- + * @param additions: will be set to 1 if a new address is added

-   * @return false on error.

-   */

-  int delegpt_add_target(struct delegpt* dp, struct regional* regional, 

-  	uint8_t* name, size_t namelen, struct sockaddr_storage* addr, 

- -	socklen_t addrlen, uint8_t bogus, uint8_t lame);

- +	socklen_t addrlen, uint8_t bogus, uint8_t lame, int* additions);

-  

-  /**

-   * Add A RRset to delegpt.

- @@ -225,10 +227,11 @@ int delegpt_add_target(struct delegpt* dp, struct regional* regional,

-   * @param regional: where to allocate the info.

-   * @param rrset: RRset A to add.

-   * @param lame: rrset is lame, disprefer it.

- + * @param additions: will be set to 1 if a new address is added

-   * @return 0 on alloc error.

-   */

-  int delegpt_add_rrset_A(struct delegpt* dp, struct regional* regional, 

- -	struct ub_packed_rrset_key* rrset, uint8_t lame);

- +	struct ub_packed_rrset_key* rrset, uint8_t lame, int* additions);

-  

-  /**

-   * Add AAAA RRset to delegpt.

- @@ -236,10 +239,11 @@ int delegpt_add_rrset_A(struct delegpt* dp, struct regional* regional,

-   * @param regional: where to allocate the info.

-   * @param rrset: RRset AAAA to add.

-   * @param lame: rrset is lame, disprefer it.

- + * @param additions: will be set to 1 if a new address is added

-   * @return 0 on alloc error.

-   */

-  int delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* regional, 

- -	struct ub_packed_rrset_key* rrset, uint8_t lame);

- +	struct ub_packed_rrset_key* rrset, uint8_t lame, int* additions);

-  

-  /**

-   * Add any RRset to delegpt.

- @@ -248,10 +252,11 @@ int delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* regional,

-   * @param regional: where to allocate the info.

-   * @param rrset: RRset to add, NS, A, AAAA.

-   * @param lame: rrset is lame, disprefer it.

- + * @param additions: will be set to 1 if a new address is added

-   * @return 0 on alloc error.

-   */

-  int delegpt_add_rrset(struct delegpt* dp, struct regional* regional, 

- -	struct ub_packed_rrset_key* rrset, uint8_t lame);

- +	struct ub_packed_rrset_key* rrset, uint8_t lame, int* additions);

-  

-  /**

-   * Add address to the delegation point. No servername is associated or checked.

- @@ -262,11 +267,13 @@ int delegpt_add_rrset(struct delegpt* dp, struct regional* regional,

-   * @param bogus: if address is bogus.

-   * @param lame: if address is lame.

-   * @param tls_auth_name: TLS authentication name (or NULL).

- + * @param additions: will be set to 1 if a new address is added

- + * @return 0 on alloc error.

-   * @return false on error.

-   */

-  int delegpt_add_addr(struct delegpt* dp, struct regional* regional, 

-  	struct sockaddr_storage* addr, socklen_t addrlen,

- -	uint8_t bogus, uint8_t lame, char* tls_auth_name);

- +	uint8_t bogus, uint8_t lame, char* tls_auth_name, int* additions);

-  

-  /** 

-   * Find NS record in name list of delegation point.

- @@ -339,6 +346,14 @@ size_t delegpt_count_targets(struct delegpt* dp);

-  struct delegpt* delegpt_from_message(struct dns_msg* msg, 

-  	struct regional* regional);

-  

- +/**

- +* Mark negative return in delegation point for specific nameserver.

- +* sets the got4 or got6 to negative, updates the ns->resolved.

- +* @param ns: the nameserver in the delegpt.

- +* @param qtype: A or AAAA (host order).

- +*/

- +void delegpt_mark_neg(struct delegpt_ns* ns, uint16_t qtype);

- +

-  /**

-   * Add negative message to delegation point.

-   * @param dp: delegation point.

- diff --git a/iterator/iter_scrub.c b/iterator/iter_scrub.c

- index 12580dc..8230d17 100644

- --- a/iterator/iter_scrub.c

- +++ b/iterator/iter_scrub.c

- @@ -185,8 +185,9 @@ mark_additional_rrset(sldns_buffer* pkt, struct msg_parse* msg,

-  /** Get target name of a CNAME */

-  static int

-  parse_get_cname_target(struct rrset_parse* rrset, uint8_t** sname, 

- -	size_t* snamelen)

- +	size_t* snamelen, sldns_buffer* pkt)

-  {

- +    size_t oldpos, dlen;

-  	if(rrset->rr_count != 1) {

-  		struct rr_parse* sig;

-  		verbose(VERB_ALGO, "Found CNAME rrset with "

- @@ -204,6 +205,19 @@ parse_get_cname_target(struct rrset_parse* rrset, uint8_t** sname,

-  	*sname = rrset->rr_first->ttl_data + sizeof(uint32_t)

-  		+ sizeof(uint16_t); /* skip ttl, rdatalen */

-  	*snamelen = rrset->rr_first->size - sizeof(uint16_t);

- +

- +    if(rrset->rr_first->outside_packet) {

- +        if(!dname_valid(*sname, *snamelen))

- +            return 0;

- +        return 1;

- +    }

- +    oldpos = sldns_buffer_position(pkt);

- +    sldns_buffer_set_position(pkt, (size_t)(*sname - sldns_buffer_begin(pkt)));

- +    dlen = pkt_dname_len(pkt);

- +    sldns_buffer_set_position(pkt, oldpos);

- +    if(dlen == 0)

- +        return 0; /* parse fail on the rdata name */

- +    *snamelen = dlen;

-  	return 1;

-  }

-  

- @@ -215,7 +229,7 @@ synth_cname(uint8_t* qname, size_t qnamelen, struct rrset_parse* dname_rrset,

-  	/* we already know that sname is a strict subdomain of DNAME owner */

-  	uint8_t* dtarg = NULL;

-  	size_t dtarglen;

- -	if(!parse_get_cname_target(dname_rrset, &dtarg, &dtarglen))

- +	if(!parse_get_cname_target(dname_rrset, &dtarg, &dtarglen, pkt))

-  		return 0; 

-  	log_assert(qnamelen > dname_rrset->dname_len);

-  	/* DNAME from com. to net. with qname example.com. -> example.net. */

- @@ -372,7 +386,7 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,

-  				/* check next cname */

-  				uint8_t* t = NULL;

-  				size_t tlen = 0;

- -				if(!parse_get_cname_target(nx, &t, &tlen))

- +				if(!parse_get_cname_target(nx, &t, &tlen, pkt))

-  					return 0;

-  				if(dname_pkt_compare(pkt, alias, t) == 0) {

-  					/* it's OK and better capitalized */

- @@ -423,7 +437,7 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,

-  				size_t tlen = 0;

-  				if(synth_cname(sname, snamelen, nx, alias,

-  					&aliaslen, pkt) &&

- -					parse_get_cname_target(rrset, &t, &tlen) &&

- +					parse_get_cname_target(rrset, &t, &tlen, pkt) &&

-  			   		dname_pkt_compare(pkt, alias, t) == 0) {

-  					/* the synthesized CNAME equals the

-  					 * current CNAME.  This CNAME is the

- @@ -442,7 +456,7 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,

-  			}

-  

-  			/* move to next name in CNAME chain */

- -			if(!parse_get_cname_target(rrset, &sname, &snamelen))

- +			if(!parse_get_cname_target(rrset, &sname, &snamelen, pkt))

-  				return 0;

-  			prev = rrset;

-  			rrset = rrset->rrset_all_next;

- diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c

- index 0a8f770..a107bee 100644

- --- a/iterator/iter_utils.c

- +++ b/iterator/iter_utils.c

- @@ -1008,7 +1008,7 @@ int iter_lookup_parent_glue_from_cache(struct module_env* env,

-  			log_rrset_key(VERB_ALGO, "found parent-side", akey);

-  			ns->done_pside4 = 1;

-  			/* a negative-cache-element has no addresses it adds */

- -			if(!delegpt_add_rrset_A(dp, region, akey, 1))

- +			if(!delegpt_add_rrset_A(dp, region, akey, 1, NULL))

-  				log_err("malloc failure in lookup_parent_glue");

-  			lock_rw_unlock(&akey->entry.lock);

-  		}

- @@ -1020,7 +1020,7 @@ int iter_lookup_parent_glue_from_cache(struct module_env* env,

-  			log_rrset_key(VERB_ALGO, "found parent-side", akey);

-  			ns->done_pside6 = 1;

-  			/* a negative-cache-element has no addresses it adds */

- -			if(!delegpt_add_rrset_AAAA(dp, region, akey, 1))

- +			if(!delegpt_add_rrset_AAAA(dp, region, akey, 1, NULL))

-  				log_err("malloc failure in lookup_parent_glue");

-  			lock_rw_unlock(&akey->entry.lock);

-  		}

- diff --git a/iterator/iterator.c b/iterator/iterator.c

- index 58a9bff..a4ad319 100644

- --- a/iterator/iterator.c

- +++ b/iterator/iterator.c

- @@ -69,6 +69,8 @@

-  #include "sldns/parseutil.h"

-  #include "sldns/sbuffer.h"

-  

- +static void target_count_increase_nx(struct iter_qstate* iq, int num);

- +

-  int 

-  iter_init(struct module_env* env, int id)

-  {

- @@ -147,6 +149,7 @@ iter_new(struct module_qstate* qstate, int id)

-  	iq->sent_count = 0;

-  	iq->ratelimit_ok = 0;

-  	iq->target_count = NULL;

- +    iq->dp_target_count = 0;

-  	iq->wait_priming_stub = 0;

-  	iq->refetch_glue = 0;

-  	iq->dnssec_expected = 0;

- @@ -218,6 +221,7 @@ final_state(struct iter_qstate* iq)

-  static void

-  error_supers(struct module_qstate* qstate, int id, struct module_qstate* super)

-  {

- +    struct iter_env* ie = (struct iter_env*)qstate->env->modinfo[id];

-  	struct iter_qstate* super_iq = (struct iter_qstate*)super->minfo[id];

-  

-  	if(qstate->qinfo.qtype == LDNS_RR_TYPE_A ||

- @@ -242,7 +246,11 @@ error_supers(struct module_qstate* qstate, int id, struct module_qstate* super)

-  				super->region, super_iq->dp))

-  				log_err("out of memory adding missing");

-  		}

- +        delegpt_mark_neg(dpns, qstate->qinfo.qtype);

-  		dpns->resolved = 1; /* mark as failed */

- +        if((dpns->got4 == 2 || !ie->supports_ipv4) &&

- +            (dpns->got6 == 2 || !ie->supports_ipv6))

- +            target_count_increase_nx(super_iq, 1);

-  	}

-  	if(qstate->qinfo.qtype == LDNS_RR_TYPE_NS) {

-  		/* prime failed to get delegation */

- @@ -577,7 +585,7 @@ static void

-  target_count_create(struct iter_qstate* iq)

-  {

-  	if(!iq->target_count) {

- -		iq->target_count = (int*)calloc(2, sizeof(int));

- +		iq->target_count = (int*)calloc(3, sizeof(int));

-  		/* if calloc fails we simply do not track this number */

-  		if(iq->target_count)

-  			iq->target_count[0] = 1;

- @@ -590,6 +598,15 @@ target_count_increase(struct iter_qstate* iq, int num)

-  	target_count_create(iq);

-  	if(iq->target_count)

-  		iq->target_count[1] += num;

- +    iq->dp_target_count++;

- +}

- +

- +static void

- +target_count_increase_nx(struct iter_qstate* iq, int num)

- +{

- +   target_count_create(iq);

- +   if(iq->target_count)

- +       iq->target_count[2] += num;

-  }

-  

-  /**

- @@ -612,13 +629,15 @@ target_count_increase(struct iter_qstate* iq, int num)

-   * @param subq_ret: if newly allocated, the subquerystate, or NULL if it does

-   * 	not need initialisation.

-   * @param v: if true, validation is done on the subquery.

- + * @param detached: true if this qstate should not attach to the subquery

-   * @return false on error (malloc).

-   */

-  static int

-  generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype, 

-  	uint16_t qclass, struct module_qstate* qstate, int id,

-  	struct iter_qstate* iq, enum iter_state initial_state, 

- -	enum iter_state finalstate, struct module_qstate** subq_ret, int v)

- +	enum iter_state finalstate, struct module_qstate** subq_ret, int v,

- +    int detached)

-  {

-  	struct module_qstate* subq = NULL;

-  	struct iter_qstate* subiq = NULL;

- @@ -645,12 +664,24 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype,

-  		valrec = 1;

-  	}

-  	

- -	/* attach subquery, lookup existing or make a new one */

- -	fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));

- -	if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime, valrec,

- -		&subq)) {

- -		return 0;

- -	}

- +    if(detached) {

- +        struct mesh_state* sub = NULL;

- +        fptr_ok(fptr_whitelist_modenv_add_sub(

- +            qstate->env->add_sub));

- +        if(!(*qstate->env->add_sub)(qstate, &qinf,

- +            qflags, prime, valrec, &subq, &sub)){

- +            return 0;

- +        }

- +    }

- +    else {

- +        /* attach subquery, lookup existing or make a new one */

- +        fptr_ok(fptr_whitelist_modenv_attach_sub(

- +            qstate->env->attach_sub));

- +        if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime,

- +            valrec, &subq)) {

- +            return 0;

- +        }

- +    }

-  	*subq_ret = subq;

-  	if(subq) {

-  		/* initialise the new subquery */

- @@ -672,6 +703,7 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype,

-  		subiq->target_count = iq->target_count;

-  		if(iq->target_count)

-  			iq->target_count[0] ++; /* extra reference */

- +        subiq->dp_target_count = 0;

-  		subiq->num_current_queries = 0;

-  		subiq->depth = iq->depth+1;

-  		outbound_list_init(&subiq->outlist);

- @@ -715,7 +747,7 @@ prime_root(struct module_qstate* qstate, struct iter_qstate* iq, int id,

-  	 * the normal INIT state logic (which would cause an infloop). */

-  	if(!generate_sub_request((uint8_t*)"\000", 1, LDNS_RR_TYPE_NS, 

-  		qclass, qstate, id, iq, QUERYTARGETS_STATE, PRIME_RESP_STATE,

- -		&subq, 0)) {

- +		&subq, 0, 0)) {

-  		verbose(VERB_ALGO, "could not prime root");

-  		return 0;

-  	}

- @@ -805,7 +837,7 @@ prime_stub(struct module_qstate* qstate, struct iter_qstate* iq, int id,

-  	 * redundant INIT state processing. */

-  	if(!generate_sub_request(stub_dp->name, stub_dp->namelen, 

-  		LDNS_RR_TYPE_NS, qclass, qstate, id, iq,

- -		QUERYTARGETS_STATE, PRIME_RESP_STATE, &subq, 0)) {

- +		QUERYTARGETS_STATE, PRIME_RESP_STATE, &subq, 0, 0)) {

-  		verbose(VERB_ALGO, "could not prime stub");

-  		(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);

-  		return 1; /* return 1 to make module stop, with error */

- @@ -976,7 +1008,7 @@ generate_a_aaaa_check(struct module_qstate* qstate, struct iter_qstate* iq,

-  		if(!generate_sub_request(s->rk.dname, s->rk.dname_len, 

-  			ntohs(s->rk.type), ntohs(s->rk.rrset_class),

-  			qstate, id, iq,

- -			INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1)) {

- +			INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1, 0)) {

-  			verbose(VERB_ALGO, "could not generate addr check");

-  			return;

-  		}

- @@ -1020,7 +1052,7 @@ generate_ns_check(struct module_qstate* qstate, struct iter_qstate* iq, int id)

-  		iq->dp->name, LDNS_RR_TYPE_NS, iq->qchase.qclass);

-  	if(!generate_sub_request(iq->dp->name, iq->dp->namelen, 

-  		LDNS_RR_TYPE_NS, iq->qchase.qclass, qstate, id, iq,

- -		INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1)) {

- +		INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1, 0)) {

-  		verbose(VERB_ALGO, "could not generate ns check");

-  		return;

-  	}

- @@ -1077,7 +1109,7 @@ generate_dnskey_prefetch(struct module_qstate* qstate,

-  		iq->dp->name, LDNS_RR_TYPE_DNSKEY, iq->qchase.qclass);

-  	if(!generate_sub_request(iq->dp->name, iq->dp->namelen, 

-  		LDNS_RR_TYPE_DNSKEY, iq->qchase.qclass, qstate, id, iq,

- -		INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0)) {

- +		INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0, 0)) {

-  		/* we'll be slower, but it'll work */

-  		verbose(VERB_ALGO, "could not generate dnskey prefetch");

-  		return;

- @@ -1251,6 +1283,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,

-  			iq->refetch_glue = 0;

-  			iq->query_restart_count++;

-  			iq->sent_count = 0;

- +            iq->dp_target_count = 0;

-  			sock_list_insert(&qstate->reply_origin, NULL, 0, qstate->region);

-  			if(qstate->env->cfg->qname_minimisation)

-  				iq->minimisation_state = INIT_MINIMISE_STATE;

- @@ -1613,7 +1646,7 @@ generate_parentside_target_query(struct module_qstate* qstate,

-  {

-  	struct module_qstate* subq;

-  	if(!generate_sub_request(name, namelen, qtype, qclass, qstate, 

- -		id, iq, INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0))

- +		id, iq, INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0, 0))

-  		return 0;

-  	if(subq) {

-  		struct iter_qstate* subiq = 

- @@ -1664,7 +1697,7 @@ generate_target_query(struct module_qstate* qstate, struct iter_qstate* iq,

-  {

-  	struct module_qstate* subq;

-  	if(!generate_sub_request(name, namelen, qtype, qclass, qstate, 

- -		id, iq, INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0))

- +		id, iq, INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0, 0))

-  		return 0;

-  	log_nametypeclass(VERB_QUERY, "new target", name, qtype, qclass);

-  	return 1;

- @@ -1703,6 +1736,14 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,

-  			"number of glue fetches %d", s, iq->target_count[1]);

-  		return 0;

-  	}

- +    if(iq->dp_target_count > MAX_DP_TARGET_COUNT) {

- +        char s[LDNS_MAX_DOMAINLEN+1];

- +        dname_str(qstate->qinfo.qname, s);

- +        verbose(VERB_QUERY, "request %s has exceeded the maximum "