Index: npl/internetserver/djbdns/djbdns.SlackBuild
===================================================================
--- npl/internetserver/djbdns/djbdns.SlackBuild	(revision 892871dd93b543e93ef2b47887b901a98993e33c)
+++ npl/internetserver/djbdns/djbdns.SlackBuild	(revision 37aaf89e77b20f6e39546bacbb26f2c12ed8f8cb)
@@ -1,4 +1,4 @@
 #!/bin/bash
-#NEED:bind_tools
+##NEED:bind_tools
 #NEED:patch
 ##NEED:mpc
@@ -46,13 +46,17 @@
 
 #patches must be applied in some order.
+for P in ../patches/*; do
+	echo "Patching $P"
+	patch -p1 < $P || exit 1
+done
+
 cat ../ignoreip-1.05.patch  | patch -p1 || exit 1
 cat ../headtail.patch  | patch -p2 || exit 1
-cat ../dnsroots.patch  | patch -p1  || exit 1
-cat ../dnstracesort.patch | patch -p1 dnstracesort.sh || exit 1
-cat ../CVE2009-0858_0001-check-response-domain-name-length.patch | patch -p1 || exit 1
-cat ../CVE2008-4392_0001-dnscache-merge-similar-outgoing-queries.patch  | patch -p1 || exit 1
-cat ../CVE2008-4392_0002-dnscache-cache-soa-records.patch  | patch -p1 || exit 1
+#cat ../dnstracesort.patch | patch -p1 dnstracesort.sh || exit 1
+#c#at ../CVE2009-0858_0001-check-response-domain-name-length.patch | patch -p1 || exit 1
+#c#at ../CVE2008-4392_0001-dnscache-merge-similar-outgoing-queries.patch  | patch -p1 || exit 1
+#cat ../CVE2008-4392_0002-dnscache-cache-soa-records.patch  | patch -p1 || exit 1
 cat ../err.patch | patch -p1 || exit 1
-cat ../tinydns-conf.patch | patch -p1 || exit 1
+#cat ../tinydns-conf.patch | patch -p1 || exit 1
 
 cat conf-home |sed s/"\/local"// >conf-home.new
Index: npl/internetserver/djbdns/djbdns.build
===================================================================
--- npl/internetserver/djbdns/djbdns.build	(revision 892871dd93b543e93ef2b47887b901a98993e33c)
+++ npl/internetserver/djbdns/djbdns.build	(revision 37aaf89e77b20f6e39546bacbb26f2c12ed8f8cb)
@@ -1,1 +1,1 @@
-6367
+6368
Index: npl/internetserver/djbdns/djbdns.md5
===================================================================
--- npl/internetserver/djbdns/djbdns.md5	(revision 892871dd93b543e93ef2b47887b901a98993e33c)
+++ npl/internetserver/djbdns/djbdns.md5	(revision 37aaf89e77b20f6e39546bacbb26f2c12ed8f8cb)
@@ -3,7 +3,7 @@
 25fc1ac8ca418261ac7a852d4f7aa8a3  ./CVE2009-0858_0001-check-response-domain-name-length.patch
 3147c5cd56832aa3b41955c7a51cbeb2  ./djbdns-1.05.tar.gz
-664b036f04c31a543789ac53ab3e13d6  ./djbdns.pkg
-30926aa948b4b704e66944338475f504  ./djbdns.SlackBuild
-67ed285af6f2a490bf68e51ea7d995fd  ./djbdns.SlackBuild.log.gz
+87af38bbf8cbdcecaee4db5f0c93712e  ./djbdns.pkg
+7b7770d9f68a1ae23a06479ca8be3e8b  ./djbdns.SlackBuild
+d4906da872d98dc2e3baea7120d66802  ./djbdns.SlackBuild.log.gz
 7a18b6f7b9552c745ff9acaf528eff4c  ./djb_update.pl
 dfd675b2775efcbb604413a84db8bf1a  ./dnsroots.patch
@@ -12,4 +12,15 @@
 94dab17c699b2e05f64ba9b79fddca65  ./headtail.patch
 d34dbdc27785b08571865d12c218c7eb  ./ignoreip-1.05.patch
+d8bc0952f4d0d99907a9017ec94465a5  ./patches/0001-hier.c-don-t-install-etc-dnsroots.global.diff
+23b9413699429e6b187ee940f5dabd77  ./patches/0002-djbdns-misformats-some-long-response-packets-patch-a.diff
+08c487a3c14e7ef82bbac4e36b724413  ./patches/0003-dnstracesort.sh-don-t-use-deprecated-number-sort.diff
+c9ac91e78f23e2e6212fea676a073574  ./patches/0004-tinydns-data-SRV-axfr-get-SRV-PTR-patches.patch
+e4fa605fee8cd28b2e092e1f018ad05f  ./patches/0005-query.c-increase-recursion-depth-to-200.patch
+f1eff75ec50ac5254b541fbd75e12dfc  ./patches/0006-Fix-ghost-domain-attack-vulnerability-CVE-2012-1191.patch
+e733f62658666c026b6041d112cf4143  ./patches/0007-dnscache-merge-similar-outgoing-udp-packets.patch
+d6b9afed37e9f00be87d4d84bcaacf38  ./patches/0008-Cache-SOA-records.patch
+cc48336bee300028db27df82d63006df  ./patches/0009-usr-sbin.patch
+d3921db2b92f24bbf2aacf099fc20052  ./patches/0010-dnsroots.global.patch
+6026c0d3f563ad2e9bfd2e6d30a797e5  ./patches/0011-datalimit.patch
 3e94e7b18733ccf8069258f86f79f0cb  ./post.djbdns
 17ba8a1f69b9bb0561c82a8be4f290d7  ./start.djbdns
Index: npl/internetserver/djbdns/patches/0001-hier.c-don-t-install-etc-dnsroots.global.diff
===================================================================
--- npl/internetserver/djbdns/patches/0001-hier.c-don-t-install-etc-dnsroots.global.diff	(revision 37aaf89e77b20f6e39546bacbb26f2c12ed8f8cb)
+++ npl/internetserver/djbdns/patches/0001-hier.c-don-t-install-etc-dnsroots.global.diff	(revision 37aaf89e77b20f6e39546bacbb26f2c12ed8f8cb)
@@ -0,0 +1,22 @@
+Description: hier.c: don't install /etc/dnsroots.global
+ dnsroots.global is installed by debian/rules into debian/djbdns/etc/
+ instead while building the Debian package.
+Author: Gerrit Pape <pape@smarden.org>
+Date: Mon, 12 Feb 2001 14:02:49 +0000
+Last-Update: 2020-07-26
+
+diff --git a/hier.c b/hier.c
+index 4aef75b..b57dba0 100644
+--- a/hier.c
++++ b/hier.c
+@@ -2,7 +2,10 @@
+ 
+ void hier()
+ {
++/*
++  This file is installed by debian/rules in debian/tmp/etc
+   c("/","etc","dnsroots.global",-1,-1,0644);
++*/
+ 
+   h(auto_home,-1,-1,02755);
+   d(auto_home,"bin",-1,-1,02755);
Index: npl/internetserver/djbdns/patches/0002-djbdns-misformats-some-long-response-packets-patch-a.diff
===================================================================
--- npl/internetserver/djbdns/patches/0002-djbdns-misformats-some-long-response-packets-patch-a.diff	(revision 37aaf89e77b20f6e39546bacbb26f2c12ed8f8cb)
+++ npl/internetserver/djbdns/patches/0002-djbdns-misformats-some-long-response-packets-patch-a.diff	(revision 37aaf89e77b20f6e39546bacbb26f2c12ed8f8cb)
@@ -0,0 +1,106 @@
+Description: djbdns misformats some long response packets
+ The DNS protocol restricts name compression to point into the first
+ 16384 bytes of a packet.  Line 18 of response.c from djbdns 1.05
+ directly references this, but response_addname() in the same file does
+ not enforce this at all.  The consequence of this is that names in
+ very large DNS packets may be mangled, and clients may misparse the
+ packet.
+ .
+ Because this email is somewhat long, I'll state up front you can find
+ a patch for this issue at the bottom of this email or at:
+     http://shinobi.dempsky.org/~matthew/djbdns-bug/patch
+ .
+ To help demonstrate this bug, I've constructed an example attack.  In
+ this scenario, there's a .foo TLD operated using tinydns and axfrdns
+ (to support DNS queries over TCP; AXFR support is not required).  The
+ attacker has registered x.foo and is allowed to upload NS records for
+ x.foo and A records for names within the x.foo domain.  However,
+ because of the aforementioned bug, this attacker can construct a
+ record set that causes the .foo servers to respond to queries asking
+ about names within the x.foo domain with poisonous records for names
+ outside of x.foo.
+ .
+ Using tinydns-data and tinydns-get from stock djbdns 1.05, you can
+ reproduce this as follows:
+ .
+     $ curl -O http://shinobi.dempsky.org/~matthew/djbdns-bug/data
+     $ grep -c -v -e '&x\.foo::' -e '^+[^:]*\.x\.foo:' data
+     0
+     $ tinydns-data
+     $ tinydns-get a www.x.foo | grep ': foo '
+     additional: foo 8388608 NS a.ns.bar
+     additional: foo 8388608 NS b.ns.bar
+ .
+ (With the patch I linked above, no records outside of x.foo will be
+ served.  It's also worth noting the printpacket_cat() routine
+ tinydns-get uses for pretty printing the response packet is much
+ stricter about parsing than dnscache's parser is; e.g., it rejects
+ packets with extra trailing bytes and records with bad rdlength fields
+ on known record types.)
+ .
+ If a victim using dnscache now makes an A query for www.x.foo,
+ dnscache will save the poisoned records, and begin contacting the
+ attacker's nameservers for all .foo requests.  (The response will be
+ over 512 bytes long, so dnscache will have to retry the query over
+ TCP, which is why axfrdns is necessary too.)
+ .
+ Now, admittedly if you peek at data, you'll see the supplied records
+ exceed what most TLDs probably allow: there are redundant NS records,
+ there are very long names (but still within the allowed limits of the
+ DNS protocol), names use non-printable characters, there are over 100
+ records totalling about 24K of storage.  However, neither the djbdns
+ documentation nor standard practice warn potential .foo administrators
+ that their domain will be at risk for poisoning if they were to add
+ support for glue record sets.  (Standard practice only warns that such
+ absurd records can negatively impact x.foo, not .foo as well.)
+ .
+ A perhaps more reasonable scenario is that the .foo servers fetch the
+ contents of the x.foo domain over AXFR (removing any records from
+ outside of x.foo) and then serve the records themselves.  axfr-get,
+ the AXFR client from djbdns, would handle the above data set fine.
+ .
+ In looking for a real life example of this latter scenario, I found
+ freedns.afraid.org.  They allowed me to register burlap.afraid.org and
+ set it up as an AXFR slave to my personal server.  I have not explored
+ what limits they place on imported records, and their website states
+ they're using BIND, but assuming they're not too limiting and were to
+ instead use tinydns/axfrdns/axfr-get, it would be possible for me to
+ trick any dnscache that queries for www.burlap.afraid.org into
+ contacting another set of nameservers for all of afraid.org's DNS
+ traffic.
+ .
+ There's a similar service everydns.net.  They do claim to use tinydns
+ (and so I assume axfrdns and axfr-get) and also provide AXFR slave
+ support, but they did not allow me to register burlap.everydns.net.
+ If they did, it would probably be possible to similarly poison
+ everydns.net.
+ .
+ I've tried to search for previous reports of this issue more
+ thoroughly than the last bug I mentioned to the list, and I haven't
+ found any mention of it yet.  I emailed Dan earlier today when I first
+ began to suspect this bug was 'exploitable' to clarify his definition
+ of a 'security hole' in djbdns.  I think the afraid.org example is a
+ reasonable use case where this bug would violate afraid.org's security
+ constraints if they were to instead use djbdns.
+ .
+ Any thoughts from the list on this bug?  (Except from Dean Anderson;
+ I'm sure he'll spend the next 3 weeks now arguing I'm a blackhat
+ hacker while refusing to look at the patch or sample data file because
+ my web server might hack his computer.)
+Author: Matthew Dempsky <matthew@dempsky.org>
+Date: Mon, 2 Mar 2009 04:46:05 +0000
+Last-Update: 2020-07-26
+
+diff --git a/response.c b/response.c
+index ba90c89..33b2fb1 100644
+--- a/response.c
++++ b/response.c
+@@ -34,7 +34,7 @@ int response_addname(const char *d)
+         uint16_pack_big(buf,49152 + name_ptr[i]);
+         return response_addbytes(buf,2);
+       }
+-    if (dlen <= 128)
++    if ((dlen <= 128) && (response_len < 16384))
+       if (name_num < NAMES) {
+ 	byte_copy(name[name_num],dlen,d);
+ 	name_ptr[name_num] = response_len;
Index: npl/internetserver/djbdns/patches/0003-dnstracesort.sh-don-t-use-deprecated-number-sort.diff
===================================================================
--- npl/internetserver/djbdns/patches/0003-dnstracesort.sh-don-t-use-deprecated-number-sort.diff	(revision 37aaf89e77b20f6e39546bacbb26f2c12ed8f8cb)
+++ npl/internetserver/djbdns/patches/0003-dnstracesort.sh-don-t-use-deprecated-number-sort.diff	(revision 37aaf89e77b20f6e39546bacbb26f2c12ed8f8cb)
@@ -0,0 +1,21 @@
+Description: dnstracesort.sh: don't use deprecated "+number" sort(1) option
+ dnstracesort contained the line "sort -t: +0 -2 +4 +3 -4 +2 -3" which
+ uses the deprecated sort field selection.  This commit changes the
+ options to "-k": "sort -t: -k 1,3 -k 5 -k 4,5 -k 3,4".
+Author: Shai Rosenfeld <shaiguitar@gmail.com>
+Date: Wed, 30 Sep 2009 18:50:32 +0000
+Last-Update: 2020-07-26
+
+diff --git a/dnstracesort.sh b/dnstracesort.sh
+index e57359c..108ef2f 100644
+--- a/dnstracesort.sh
++++ b/dnstracesort.sh
+@@ -12,7 +12,7 @@ awk -F: '
+     }
+     print
+   }
+-' | sort -t: +0 -2 +4 +3 -4 +2 -3 | uniq | awk -F: '
++' | sort -t: -k 1,3 -k 5 -k 4,5 -k 3,4 | uniq | awk -F: '
+   {
+     type = $1
+     q = $2
Index: npl/internetserver/djbdns/patches/0004-tinydns-data-SRV-axfr-get-SRV-PTR-patches.patch
===================================================================
--- npl/internetserver/djbdns/patches/0004-tinydns-data-SRV-axfr-get-SRV-PTR-patches.patch	(revision 37aaf89e77b20f6e39546bacbb26f2c12ed8f8cb)
+++ npl/internetserver/djbdns/patches/0004-tinydns-data-SRV-axfr-get-SRV-PTR-patches.patch	(revision 37aaf89e77b20f6e39546bacbb26f2c12ed8f8cb)
@@ -0,0 +1,141 @@
+Description: tinydns-data SRV & axfr-get SRV/PTR patches
+ Here's a combined patch that:
+ .
+ a) adds a native SRV type to tinydns-data
+ .
+ Sfqdn:ip:x:port:weight:priority:ttl:timestamp
+ .
+ Standard rules for ip, x, ttl, and timestamp apply. Port, weight, and
+ priority all range from 0-65535. Weight and priority are optional; they
+ default to zero if not provided.
+ .
+ Sconsole.zoinks.example.com:1.2.3.4:rack102-con1:2001:69:7:300:
+ .
+ b) makes axfr-get decompose SRV and PTR records and write them out in
+ native format, rather than opaque. Again, this is necessary because if the
+ DNAME fields in the records reference the same zone as fqdn, they can have
+ compression pointers that are bogus outside the context of that specific
+ packet, and which can't be correctly loaded into data.cdb by tinydns-data.
+ .
+ --michael
+ .
+ Laurent G. Bercot <ska-djbdns@skarnet.org> updated it for
+ djbdns-1.05. Documentation patch by Alex Efros.
+Author: Michael Handler <handler@sub-rosa.com>
+Date: Thu, 14 Sep 2000 20:37:50 -0400
+Last-Update: 2020-07-26
+
+diff --git a/axfr-get.c b/axfr-get.c
+index 75db627..a5d5c0c 100644
+--- a/axfr-get.c
++++ b/axfr-get.c
+@@ -209,6 +209,26 @@ unsigned int doit(char *buf,unsigned int len,unsigned int pos)
+     if (!stralloc_cats(&line,".:")) return 0;
+     if (!stralloc_catulong0(&line,dist,0)) return 0;
+   }
++  else if (byte_equal(data,2,DNS_T_SRV)) {
++    uint16 dist, weight, port;
++    if (!stralloc_copys(&line,"S")) return 0;
++    if (!dns_domain_todot_cat(&line,d1)) return 0;
++    if (!stralloc_cats(&line,"::")) return 0;
++    pos = x_copy(buf,len,pos,data,2);
++    uint16_unpack_big(data,&dist);
++    pos = x_copy(buf,len,pos,data,2);
++    uint16_unpack_big(data,&weight);
++    pos = x_copy(buf,len,pos,data,2);
++    uint16_unpack_big(data,&port);
++    x_getname(buf,len,pos,&d1);
++    if (!dns_domain_todot_cat(&line,d1)) return 0;
++    if (!stralloc_cats(&line,".:")) return 0;
++    if (!stralloc_catulong0(&line,dist,0)) return 0;
++    if (!stralloc_cats(&line,":")) return 0;
++    if (!stralloc_catulong0(&line,weight,0)) return 0;
++    if (!stralloc_cats(&line,":")) return 0;
++    if (!stralloc_catulong0(&line,port,0)) return 0;
++  }
+   else if (byte_equal(data,2,DNS_T_A) && (dlen == 4)) {
+     char ipstr[IP4_FMT];
+     if (!stralloc_copys(&line,"+")) return 0;
+@@ -217,6 +237,14 @@ unsigned int doit(char *buf,unsigned int len,unsigned int pos)
+     x_copy(buf,len,pos,data,4);
+     if (!stralloc_catb(&line,ipstr,ip4_fmt(ipstr,data))) return 0;
+   }
++  else if (byte_equal(data,2,DNS_T_PTR)) {
++    if (!stralloc_copys(&line,"^")) return 0;
++    if (!dns_domain_todot_cat(&line,d1)) return 0;
++    if (!stralloc_cats(&line,":")) return 0;
++    x_getname(buf,len,pos,&d1);
++    if (!dns_domain_todot_cat(&line,d1)) return 0;
++    if (!stralloc_cats(&line,".")) return 0;
++  }
+   else {
+     unsigned char ch;
+     unsigned char ch2;
+diff --git a/dns.h b/dns.h
+index 2f899ef..3849f4c 100644
+--- a/dns.h
++++ b/dns.h
+@@ -20,6 +20,7 @@
+ #define DNS_T_SIG "\0\30"
+ #define DNS_T_KEY "\0\31"
+ #define DNS_T_AAAA "\0\34"
++#define DNS_T_SRV "\0\41"
+ #define DNS_T_AXFR "\0\374"
+ #define DNS_T_ANY "\0\377"
+ 
+diff --git a/tinydns-data.c b/tinydns-data.c
+index ba82f84..0137f09 100644
+--- a/tinydns-data.c
++++ b/tinydns-data.c
+@@ -196,6 +196,7 @@ int main()
+   char type[2];
+   char soa[20];
+   char buf[4];
++  char srv[6];
+ 
+   umask(022);
+ 
+@@ -369,6 +370,43 @@ int main()
+ 	  rr_finish(d2);
+ 	}
+ 	break;
++	
++      case 'S':
++	if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
++	if (!stralloc_0(&f[6])) nomem();
++	if (!scan_ulong(f[6].s,&ttl)) ttl = TTL_POSITIVE;
++	ttdparse(&f[7],ttd);
++	locparse(&f[8],loc);
++
++	if (!stralloc_0(&f[1])) nomem();
++
++	if (byte_chr(f[2].s,f[2].len,'.') >= f[2].len) {
++	  if (!stralloc_cats(&f[2],".srv.")) nomem();
++	  if (!stralloc_catb(&f[2],f[0].s,f[0].len)) nomem();
++	}
++	if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem();
++
++	if (!stralloc_0(&f[4])) nomem();
++	if (!scan_ulong(f[4].s,&u)) u = 0;
++	uint16_pack_big(srv,u);
++	if (!stralloc_0(&f[5])) nomem();
++	if (!scan_ulong(f[5].s,&u)) u = 0;
++	uint16_pack_big(srv + 2,u);
++	if (!stralloc_0(&f[3])) nomem();
++	if (!scan_ulong(f[3].s,&u)) nomem();
++	uint16_pack_big(srv + 4,u);
++
++	rr_start(DNS_T_SRV,ttl,ttd,loc);
++	rr_add(srv,6);
++	rr_addname(d2);
++	rr_finish(d1);
++
++	if (ip4_scan(f[1].s,ip)) {
++	  rr_start(DNS_T_A,ttl,ttd,loc);
++	  rr_add(ip,4);
++	  rr_finish(d2);
++	}
++	break;
+ 
+       case '^': case 'C':
+ 	if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
Index: npl/internetserver/djbdns/patches/0005-query.c-increase-recursion-depth-to-200.patch
===================================================================
--- npl/internetserver/djbdns/patches/0005-query.c-increase-recursion-depth-to-200.patch	(revision 37aaf89e77b20f6e39546bacbb26f2c12ed8f8cb)
+++ npl/internetserver/djbdns/patches/0005-query.c-increase-recursion-depth-to-200.patch	(revision 37aaf89e77b20f6e39546bacbb26f2c12ed8f8cb)
@@ -0,0 +1,35 @@
+Description: query.c: increase recursion depth to 200.
+ The recursion loop for CNAME resolution has an upper limit of 100
+ iterations by default. This has proven too small in some cases where
+ large CDNs are concerned. This commit increases the limit to 200.
+ .
+ The patch was based on the OpenWrt fix, supplied by user ylxu.
+Author: Michael Orlitzky <michael@orlitzky.com>
+Date: Fri, 5 Aug 2016 09:13:11 -0400
+Gentoo-Bug: 590548
+OpenWrt-Bug: 5881
+SMEServer-Bug: 8362
+Last-Update: 2020-07-26
+
+diff --git a/query.c b/query.c
+index 46cdc00..61fe708 100644
+--- a/query.c
++++ b/query.c
+@@ -203,7 +203,7 @@ static int doit(struct query *z,int state)
+ 
+ 
+   NEWNAME:
+-  if (++z->loop == 100) goto DIE;
++  if (++z->loop == 200) goto DIE;
+   d = z->name[z->level];
+   dtype = z->level ? DNS_T_A : z->type;
+   dlen = dns_domain_length(d);
+@@ -449,7 +449,7 @@ static int doit(struct query *z,int state)
+ 
+ 
+   HAVEPACKET:
+-  if (++z->loop == 100) goto DIE;
++  if (++z->loop == 200) goto DIE;
+   buf = z->dt.packet;
+   len = z->dt.packetlen;
+ 
Index: npl/internetserver/djbdns/patches/0006-Fix-ghost-domain-attack-vulnerability-CVE-2012-1191.patch
===================================================================
--- npl/internetserver/djbdns/patches/0006-Fix-ghost-domain-attack-vulnerability-CVE-2012-1191.patch	(revision 37aaf89e77b20f6e39546bacbb26f2c12ed8f8cb)
+++ npl/internetserver/djbdns/patches/0006-Fix-ghost-domain-attack-vulnerability-CVE-2012-1191.patch	(revision 37aaf89e77b20f6e39546bacbb26f2c12ed8f8cb)
@@ -0,0 +1,24 @@
+Description: Fix ghost domain attack vulnerability (CVE-2012-1191)
+Origin: http://marc.info/?l=djbdns&m=134269902121506&w=2
+Author: Peter Conrad <conrad@tivano.de>
+Date: Tue, 18 Jun 2019 00:51:18 +0000
+Gentoo-Bug: https://bugs.gentoo.org/404959
+Last-Update: 2020-07-26
+
+diff --git a/query.c b/query.c
+index 61fe708..085cf44 100644
+--- a/query.c
++++ b/query.c
+@@ -578,6 +578,12 @@ static int doit(struct query *z,int state)
+     }
+ 
+     if (!dns_domain_suffix(t1,control)) { i = j; continue; }
++
++    if (!flagforwardonly && byte_equal(type,2,DNS_T_NS) && dns_domain_equal(t1,control)) {
++        char dummy[256];
++        if (!roots(dummy,control)) { i = j; continue; }
++    }
++
+     if (!roots_same(t1,control)) { i = j; continue; }
+ 
+     if (byte_equal(type,2,DNS_T_ANY))
Index: npl/internetserver/djbdns/patches/0007-dnscache-merge-similar-outgoing-udp-packets.patch
===================================================================
--- npl/internetserver/djbdns/patches/0007-dnscache-merge-similar-outgoing-udp-packets.patch	(revision 37aaf89e77b20f6e39546bacbb26f2c12ed8f8cb)
+++ npl/internetserver/djbdns/patches/0007-dnscache-merge-similar-outgoing-udp-packets.patch	(revision 37aaf89e77b20f6e39546bacbb26f2c12ed8f8cb)
@@ -0,0 +1,339 @@
+Description: dnscache: merge similar outgoing udp packets
+ This patch takes a slightly different approach to merging
+ than the previous qmerge patch: rather than merging between
+ the "query" and "dns_transmit" layers, it actually
+ incorporates the merging into the dns_transmit layer.
+ .
+ This makes it a much more invasive and messy patch, but
+ means that it should correctly handle all situations
+ (in particular, ones where sending to two different IPs will
+ gives different results, generally because one server is
+ down or lame).
+ .
+ The general strategy is this:
+ .
+   - when a dns_transmit is about to send() a UDP query, it
+     checks for an equivalent inprogress query.
+ .
+     If it finds one, it marks the inprogress dns_transmit as
+     its "master", and itself as a "slave" of the master.
+ .
+     If it doesn't, it sends the packet and registers itself
+     as inprogress.
+ .
+   - when a dns_transmit recv()s a UDP packet, it creates a
+     copy of the packet for each of its slaves
+ .
+ Two outgoing packets are considered equivalent if:
+ .
+   1. they are going to the same IP
+   2. they have the same qtype
+   3. they have the same qname
+ .
+ Because this change affects the dns library itself, this
+ change can potentially affect not just dnscache, but all of
+ the diagnostic tools. To address this, merging must be
+ enabled explicitly by the caller; dnscache will enable
+ merging if the MERGEQUERIES environment variable is set.
+ .
+ I tried to keep the patch as small and simple as possible so
+ that its correctness could be verified by readers.  There
+ are a few places where performance might benefit from making
+ it more complex:
+ .
+   - dns_transmit now knows the value of MAXUDP, since it is
+     an upper bound on the number of slaves and inprogress
+     queries. As a result:
+ .
+       - each non-merging program which uses the dns library
+         wastes MAXUDP*sizeof(pointer) bytes of static memory
+         for the inprogress list
+ .
+       - each dns_transmit uses an extra MAXUDP*sizeof(pointer)
+         bytes for its slaves list. For dnscache, this
+         translates to 160K total on a 32-bit platform with
+         default MAXUDP.
+ .
+     Both could be avoided by using dynamic allocation.
+ .
+   - We have to do an O(MAXUDP) linear search to find similar
+     inprogress queries (non-merge-enabled users of the
+     library avoid paying this price, though).
+ .
+     This could be avoided by using a data structure with a
+     fast key lookup for inprogress.
+ .
+ This patch is only lightly tested. Use on production servers at your own
+ risk (and please report to the list if you have success using it).
+Author: Jeff King <peff () peff ! net>
+Date: Wed, 1 Apr 2009 14:10:54 +0000
+Debian-Bug: https://bugs.debian.org/516394
+Last-Update: 2020-07-26
+
+diff --git a/clients.h b/clients.h
+new file mode 100644
+index 0000000..983a4ad
+--- /dev/null
++++ b/clients.h
+@@ -0,0 +1,7 @@
++#ifndef CLIENTS_H
++#define CLIENTS_H
++
++#define MAXUDP 200
++#define MAXTCP 20
++
++#endif /* CLIENTS_H */
+diff --git a/dns.h b/dns.h
+index 3849f4c..d1e2ffc 100644
+--- a/dns.h
++++ b/dns.h
+@@ -4,6 +4,7 @@
+ #include "stralloc.h"
+ #include "iopause.h"
+ #include "taia.h"
++#include "clients.h"
+ 
+ #define DNS_C_IN "\0\1"
+ #define DNS_C_ANY "\0\377"
+@@ -38,8 +39,14 @@ struct dns_transmit {
+   const char *servers;
+   char localip[4];
+   char qtype[2];
++  struct dns_transmit *master;
++  struct dns_transmit *slaves[MAXUDP];
++  int nslaves;
+ } ;
+ 
++extern void dns_enable_merge(void (*logger)(const char *, const char *,
++      const char *));
++
+ extern void dns_random_init(const char *);
+ extern unsigned int dns_random(unsigned int);
+ 
+diff --git a/dns_transmit.c b/dns_transmit.c
+index 4d6e39f..3984776 100644
+--- a/dns_transmit.c
++++ b/dns_transmit.c
+@@ -7,6 +7,61 @@
+ #include "byte.h"
+ #include "uint16.h"
+ #include "dns.h"
++#include "strerr.h"
++
++static int merge_enable;
++static void (*merge_logger)(const char *, const char *, const char *);
++void dns_enable_merge(void (*f)(const char *, const char *, const char *))
++{
++  merge_enable = 1;
++  merge_logger = f;
++}
++
++static int merge_equal(struct dns_transmit *a, struct dns_transmit *b)
++{
++  const char *ip1 = a->servers + 4 * a->curserver;
++  const char *ip2 = b->servers + 4 * b->curserver;
++  return
++    byte_equal(ip1, 4, ip2) &&
++    byte_equal(a->qtype, 2, b->qtype) &&
++    dns_domain_equal(a->query + 14, b->query + 14);
++}
++
++struct dns_transmit *inprogress[MAXUDP];
++
++static int try_merge(struct dns_transmit *d)
++{
++  int i;
++  for (i = 0; i < MAXUDP; i++) {
++    if (!inprogress[i]) continue;
++    if (!merge_equal(d, inprogress[i])) continue;
++    d->master = inprogress[i];
++    inprogress[i]->slaves[inprogress[i]->nslaves++] = d;
++    return 1;
++  }
++  return 0;
++}
++
++static void register_inprogress(struct dns_transmit *d)
++{
++  int i;
++  for (i = 0; i < MAXUDP; i++) {
++    if (!inprogress[i]) {
++      inprogress[i] = d;
++      return;
++    }
++  }
++  strerr_die1x(100, "BUG: out of inprogress slots");
++}
++
++static void unregister_inprogress(struct dns_transmit *d)
++{
++  int i;
++  for (i = 0; i < MAXUDP; i++) {
++    if (inprogress[i] == d)
++      inprogress[i] = 0;
++  }
++}
+ 
+ static int serverwantstcp(const char *buf,unsigned int len)
+ {
+@@ -59,8 +114,28 @@ static void packetfree(struct dns_transmit *d)
+   d->packet = 0;
+ }
+ 
++static void mergefree(struct dns_transmit *d)
++{
++  int i;
++  if (merge_enable)
++    unregister_inprogress(d);
++  /* unregister us from our master */
++  if (d->master) {
++    for (i = 0; i < d->master->nslaves; i++)
++      if (d->master->slaves[i] == d)
++        d->master->slaves[i] = 0;
++  }
++  /* and unregister all of our slaves from us */
++  for (i = 0; i < d->nslaves; i++) {
++    if (d->slaves[i])
++      d->slaves[i]->master = NULL;
++  }
++  d->nslaves = 0;
++}
++
+ static void queryfree(struct dns_transmit *d)
+ {
++  mergefree(d);
+   if (!d->query) return;
+   alloc_free(d->query);
+   d->query = 0;
+@@ -99,11 +174,18 @@ static int thisudp(struct dns_transmit *d)
+   const char *ip;
+ 
+   socketfree(d);
++  mergefree(d);
+ 
+   while (d->udploop < 4) {
+     for (;d->curserver < 16;++d->curserver) {
+       ip = d->servers + 4 * d->curserver;
+       if (byte_diff(ip,4,"\0\0\0\0")) {
++        if (merge_enable && try_merge(d)) {
++          if (merge_logger)
++            merge_logger(ip, d->qtype, d->query + 14);
++          return 0;
++        }
++
+ 	d->query[2] = dns_random(256);
+ 	d->query[3] = dns_random(256);
+   
+@@ -118,6 +200,8 @@ static int thisudp(struct dns_transmit *d)
+             taia_uint(&d->deadline,timeouts[d->udploop]);
+             taia_add(&d->deadline,&d->deadline,&now);
+             d->tcpstate = 0;
++            if (merge_enable)
++              register_inprogress(d);
+             return 0;
+           }
+   
+@@ -226,8 +310,12 @@ void dns_transmit_io(struct dns_transmit *d,iopause_fd *x,struct taia *deadline)
+   x->fd = d->s1 - 1;
+ 
+   switch(d->tcpstate) {
+-    case 0: case 3: case 4: case 5:
+-      x->events = IOPAUSE_READ;
++    case 0:
++      if (d->master) return;
++      if (d->packet) { taia_now(deadline); return; }
++      /* otherwise, fall through */
++    case 3: case 4: case 5:
++        x->events = IOPAUSE_READ;
+       break;
+     case 1: case 2:
+       x->events = IOPAUSE_WRITE;
+@@ -244,10 +332,14 @@ int dns_transmit_get(struct dns_transmit *d,const iopause_fd *x,const struct tai
+   unsigned char ch;
+   int r;
+   int fd;
++  int i;
+ 
+   errno = error_io;
+   fd = d->s1 - 1;
+ 
++  if (d->tcpstate == 0 && d->master) return 0;
++  if (d->tcpstate == 0 && d->packet) return 1;
++
+   if (!x->revents) {
+     if (taia_less(when,&d->deadline)) return 0;
+     errno = error_timeout;
+@@ -279,6 +371,15 @@ have sent query to curserver on UDP socket s
+     d->packet = alloc(d->packetlen);
+     if (!d->packet) { dns_transmit_free(d); return -1; }
+     byte_copy(d->packet,d->packetlen,udpbuf);
++
++    for (i = 0; i < d->nslaves; i++) {
++      if (!d->slaves[i]) continue;
++      d->slaves[i]->packetlen = d->packetlen;
++      d->slaves[i]->packet = alloc(d->packetlen);
++      if (!d->slaves[i]->packet) { dns_transmit_free(d->slaves[i]); continue; }
++      byte_copy(d->slaves[i]->packet,d->packetlen,udpbuf);
++    }
++
+     queryfree(d);
+     return 1;
+   }
+diff --git a/dnscache.c b/dnscache.c
+index 8c899a3..c8db179 100644
+--- a/dnscache.c
++++ b/dnscache.c
+@@ -54,7 +54,6 @@ uint64 numqueries = 0;
+ 
+ static int udp53;
+ 
+-#define MAXUDP 200
+ static struct udpclient {
+   struct query q;
+   struct taia start;
+@@ -131,7 +130,6 @@ void u_new(void)
+ 
+ static int tcp53;
+ 
+-#define MAXTCP 20
+ struct tcpclient {
+   struct query q;
+   struct taia start;
+@@ -435,6 +433,8 @@ int main()
+     response_hidettl();
+   if (env_get("FORWARDONLY"))
+     query_forwardonly();
++  if (env_get("MERGEQUERIES"))
++    dns_enable_merge(log_merge);
+ 
+   if (!roots_init())
+     strerr_die2sys(111,FATAL,"unable to read servers: ");
+diff --git a/log.c b/log.c
+index c43e8b0..3e1c674 100644
+--- a/log.c
++++ b/log.c
+@@ -150,6 +150,12 @@ void log_tx(const char *q,const char qtype[2],const char *control,const char ser
+   line();
+ }
+ 
++void log_merge(const char *addr, const char qtype[2], const char *q)
++{
++  string("merge "); ip(addr); space(); logtype(qtype); space(); name(q);
++  line();
++}
++
+ void log_cachedanswer(const char *q,const char type[2])
+ {
+   string("cached "); logtype(type); space();
+diff --git a/log.h b/log.h
+index fe62fa3..dd6408a 100644
+--- a/log.h
++++ b/log.h
+@@ -18,6 +18,7 @@ extern void log_cachednxdomain(const char *);
+ extern void log_cachedns(const char *,const char *);
+ 
+ extern void log_tx(const char *,const char *,const char *,const char *,unsigned int);
++extern void log_merge(const char *, const char *, const char *);
+ 
+ extern void log_nxdomain(const char *,const char *,unsigned int);
+ extern void log_nodata(const char *,const char *,const char *,unsigned int);
Index: npl/internetserver/djbdns/patches/0008-Cache-SOA-records.patch
===================================================================
--- npl/internetserver/djbdns/patches/0008-Cache-SOA-records.patch	(revision 37aaf89e77b20f6e39546bacbb26f2c12ed8f8cb)
+++ npl/internetserver/djbdns/patches/0008-Cache-SOA-records.patch	(revision 37aaf89e77b20f6e39546bacbb26f2c12ed8f8cb)
@@ -0,0 +1,77 @@
+Description: Cache SOA records
+ For more information, how this patch helps to mitigate poisoning attack,
+ see http://www.your.org/dnscache.
+Author: Jeff King <peff@peff.net>
+Date: Tue, 18 Jun 2019 01:11:07 +0000
+Debian-Bug: https://bugs.debian.org/516394
+Last-Update: 2020-07-26
+
+diff --git a/query.c b/query.c
+index 085cf44..372d0a6 100644
+--- a/query.c
++++ b/query.c
+@@ -319,6 +319,29 @@ static int doit(struct query *z,int state)
+       }
+     }
+ 
++    if (typematch(DNS_T_SOA,dtype)) {
++      byte_copy(key,2,DNS_T_SOA);
++      cached = cache_get(key,dlen + 2,&cachedlen,&ttl);
++      if (cached && (cachedlen || byte_diff(dtype,2,DNS_T_ANY))) {
++        log_cachedanswer(d,DNS_T_SOA);
++        if (!rqa(z)) goto DIE;
++        pos = 0;
++        while (pos = dns_packet_copy(cached,cachedlen,pos,misc,20)) {
++          pos = dns_packet_getname(cached,cachedlen,pos,&t2);
++          if (!pos) break;
++          pos = dns_packet_getname(cached,cachedlen,pos,&t3);
++          if (!pos) break;
++          if (!response_rstart(d,DNS_T_SOA,ttl)) goto DIE;
++          if (!response_addname(t2)) goto DIE;
++          if (!response_addname(t3)) goto DIE;
++          if (!response_addbytes(misc,20)) goto DIE;
++          response_rfinish(RESPONSE_ANSWER);
++        }
++        cleanup(z);
++        return 1;
++      }
++    }
++
+     if (typematch(DNS_T_A,dtype)) {
+       byte_copy(key,2,DNS_T_A);
+       cached = cache_get(key,dlen + 2,&cachedlen,&ttl);
+@@ -351,7 +374,7 @@ static int doit(struct query *z,int state)
+       }
+     }
+ 
+-    if (!typematch(DNS_T_ANY,dtype) && !typematch(DNS_T_AXFR,dtype) && !typematch(DNS_T_CNAME,dtype) && !typematch(DNS_T_NS,dtype) && !typematch(DNS_T_PTR,dtype) && !typematch(DNS_T_A,dtype) && !typematch(DNS_T_MX,dtype)) {
++    if (!typematch(DNS_T_ANY,dtype) && !typematch(DNS_T_AXFR,dtype) && !typematch(DNS_T_CNAME,dtype) && !typematch(DNS_T_NS,dtype) && !typematch(DNS_T_PTR,dtype) && !typematch(DNS_T_A,dtype) && !typematch(DNS_T_MX,dtype) && !typematch(DNS_T_SOA,dtype)) {
+       byte_copy(key,2,dtype);
+       cached = cache_get(key,dlen + 2,&cachedlen,&ttl);
+       if (cached && (cachedlen || byte_diff(dtype,2,DNS_T_ANY))) {
+@@ -591,15 +614,24 @@ static int doit(struct query *z,int state)
+     else if (byte_equal(type,2,DNS_T_AXFR))
+       ;
+     else if (byte_equal(type,2,DNS_T_SOA)) {
++      int non_authority = 0;
++      save_start();
+       while (i < j) {
+         pos = dns_packet_skipname(buf,len,records[i]); if (!pos) goto DIE;
+         pos = dns_packet_getname(buf,len,pos + 10,&t2); if (!pos) goto DIE;
+         pos = dns_packet_getname(buf,len,pos,&t3); if (!pos) goto DIE;
+         pos = dns_packet_copy(buf,len,pos,misc,20); if (!pos) goto DIE;
+-        if (records[i] < posauthority)
++        if (records[i] < posauthority) {
+           log_rrsoa(whichserver,t1,t2,t3,misc,ttl);
++          save_data(misc,20);
++          save_data(t2,dns_domain_length(t2));
++          save_data(t3,dns_domain_length(t3));
++          non_authority++;
++        }
+         ++i;
+       }
++      if (non_authority)
++        save_finish(DNS_T_SOA,t1,ttl);
+     }
+     else if (byte_equal(type,2,DNS_T_CNAME)) {
+       pos = dns_packet_skipname(buf,len,records[j - 1]); if (!pos) goto DIE;
Index: npl/internetserver/djbdns/patches/0009-usr-sbin.patch
===================================================================
--- npl/internetserver/djbdns/patches/0009-usr-sbin.patch	(revision 37aaf89e77b20f6e39546bacbb26f2c12ed8f8cb)
+++ npl/internetserver/djbdns/patches/0009-usr-sbin.patch	(revision 37aaf89e77b20f6e39546bacbb26f2c12ed8f8cb)
@@ -0,0 +1,115 @@
+Description: Teach the *-conf tools about /usr/sbin.
+ In the Debian djbdns binary packages, some programs and tools are
+ located in the /usr/sbin directory, not in /usr/bin.
+Forwarded: not-needed
+Author: Peter Pentchev <roam@ringlet.net>
+Last-Update: 2020-07-26
+
+--- a/axfrdns-conf.c
++++ b/axfrdns-conf.c
+@@ -51,7 +51,7 @@
+   start("run");
+   outs("#!/bin/sh\nexec 2>&1\nexec envdir ./env sh -c '\n  exec envuidgid "); outs(user);
+   outs(" softlimit -d300000 tcpserver -vDRHl0 -x tcp.cdb -- \"$IP\" 53 ");
+-  outs(auto_home); outs("/bin/axfrdns\n'\n");
++  outs(auto_home); outs("/sbin/axfrdns\n'\n");
+   finish();
+   perm(0755);
+ 
+--- a/dnscache-conf.c
++++ b/dnscache-conf.c
+@@ -123,7 +123,7 @@
+   seed_addtime(); start("run");
+   outs("#!/bin/sh\nexec 2>&1\nexec <seed\nexec envdir ./env sh -c '\n  exec envuidgid "); outs(user);
+   outs(" softlimit -o250 -d \"$DATALIMIT\" ");
+-  outs(auto_home); outs("/bin/dnscache\n'\n"); finish();
++  outs(auto_home); outs("/sbin/dnscache\n'\n"); finish();
+   seed_addtime(); perm(0755);
+   seed_addtime(); start("log/run");
+   outs("#!/bin/sh\nexec setuidgid "); outs(loguser);
+--- a/rbldns-conf.c
++++ b/rbldns-conf.c
+@@ -52,7 +52,7 @@
+   start("run");
+   outs("#!/bin/sh\nexec 2>&1\nexec envuidgid "); outs(user);
+   outs(" envdir ./env softlimit -d250000 ");
+-  outs(auto_home); outs("/bin/rbldns\n");
++  outs(auto_home); outs("/sbin/rbldns\n");
+   finish();
+   perm(0755);
+ 
+@@ -63,7 +63,7 @@
+   perm(0644);
+   start("root/Makefile");
+   outs("data.cdb: data\n");
+-  outs("\t"); outs(auto_home); outs("/bin/rbldns-data\n");
++  outs("\t"); outs(auto_home); outs("/sbin/rbldns-data\n");
+   finish();
+   perm(0644);
+ 
+--- a/tinydns-conf.c
++++ b/tinydns-conf.c
+@@ -47,7 +47,7 @@
+   start("run");
+   outs("#!/bin/sh\nexec 2>&1\nexec envuidgid "); outs(user);
+   outs(" envdir ./env softlimit -d300000 ");
+-  outs(auto_home); outs("/bin/tinydns\n");
++  outs(auto_home); outs("/sbin/tinydns\n");
+   finish();
+   perm(0755);
+ 
+@@ -60,37 +60,37 @@
+ 
+   start("root/add-ns");
+   outs("#!/bin/sh\nexec ");
+-  outs(auto_home); outs("/bin/tinydns-edit data data.new add ns ${1+\"$@\"}\n");
++  outs(auto_home); outs("/sbin/tinydns-edit data data.new add ns ${1+\"$@\"}\n");
+   finish();
+   perm(0755);
+ 
+   start("root/add-childns");
+   outs("#!/bin/sh\nexec ");
+-  outs(auto_home); outs("/bin/tinydns-edit data data.new add childns ${1+\"$@\"}\n");
++  outs(auto_home); outs("/sbin/tinydns-edit data data.new add childns ${1+\"$@\"}\n");
+   finish();
+   perm(0755);
+ 
+   start("root/add-host");
+   outs("#!/bin/sh\nexec ");
+-  outs(auto_home); outs("/bin/tinydns-edit data data.new add host ${1+\"$@\"}\n");
++  outs(auto_home); outs("/sbin/tinydns-edit data data.new add host ${1+\"$@\"}\n");
+   finish();
+   perm(0755);
+ 
+   start("root/add-alias");
+   outs("#!/bin/sh\nexec ");
+-  outs(auto_home); outs("/bin/tinydns-edit data data.new add alias ${1+\"$@\"}\n");
++  outs(auto_home); outs("/sbin/tinydns-edit data data.new add alias ${1+\"$@\"}\n");
+   finish();
+   perm(0755);
+ 
+   start("root/add-mx");
+   outs("#!/bin/sh\nexec ");
+-  outs(auto_home); outs("/bin/tinydns-edit data data.new add mx ${1+\"$@\"}\n");
++  outs(auto_home); outs("/sbin/tinydns-edit data data.new add mx ${1+\"$@\"}\n");
+   finish();
+   perm(0755);
+ 
+   start("root/Makefile");
+   outs("data.cdb: data\n");
+-  outs("\t"); outs(auto_home); outs("/bin/tinydns-data\n");
++  outs("\t"); outs(auto_home); outs("/sbin/tinydns-data\n");
+   finish();
+   perm(0644);
+ 
+--- a/walldns-conf.c
++++ b/walldns-conf.c
+@@ -47,7 +47,7 @@
+   start("run");
+   outs("#!/bin/sh\nexec 2>&1\nexec envuidgid "); outs(user);
+   outs(" envdir ./env softlimit -d250000 ");
+-  outs(auto_home); outs("/bin/walldns\n");
++  outs(auto_home); outs("/sbin/walldns\n");
+   finish();
+   perm(0755);
+ 
Index: npl/internetserver/djbdns/patches/0010-dnsroots.global.patch
===================================================================
--- npl/internetserver/djbdns/patches/0010-dnsroots.global.patch	(revision 37aaf89e77b20f6e39546bacbb26f2c12ed8f8cb)
+++ npl/internetserver/djbdns/patches/0010-dnsroots.global.patch	(revision 37aaf89e77b20f6e39546bacbb26f2c12ed8f8cb)
@@ -0,0 +1,27 @@
+Description: Update the list of root nameservers.
+Bug-Debian: https://bugs.debian.org/996373
+Author: Andrew Richards <ar-debianbugs@nwdb.co.uk>
+Forwarded: no
+Last-Update: 2021-11-13
+
+--- a/dnsroots.global
++++ b/dnsroots.global
+@@ -1,13 +1,13 @@
+ 198.41.0.4
+-128.9.0.107
++199.9.14.201
+ 192.33.4.12
+-128.8.10.90
++199.7.91.13
+ 192.203.230.10
+ 192.5.5.241
+ 192.112.36.4
+-128.63.2.53
++198.97.190.53
+ 192.36.148.17
+-198.41.0.10
++192.58.128.30
+ 193.0.14.129
+-198.32.64.12
++199.7.83.42
+ 202.12.27.33
Index: npl/internetserver/djbdns/patches/0011-datalimit.patch
===================================================================
--- npl/internetserver/djbdns/patches/0011-datalimit.patch	(revision 37aaf89e77b20f6e39546bacbb26f2c12ed8f8cb)
+++ npl/internetserver/djbdns/patches/0011-datalimit.patch	(revision 37aaf89e77b20f6e39546bacbb26f2c12ed8f8cb)
@@ -0,0 +1,38 @@
+Description: Raise the axfrdns, dnscache, and tinydns data limit.
+Bug-Debian: https://bugs.debian.org/996807
+Author: Peter Pentchev <roam@ringlet.net>
+Last-Update: 2021-11-13
+
+--- a/axfrdns-conf.c
++++ b/axfrdns-conf.c
+@@ -50,7 +50,7 @@
+ 
+   start("run");
+   outs("#!/bin/sh\nexec 2>&1\nexec envdir ./env sh -c '\n  exec envuidgid "); outs(user);
+-  outs(" softlimit -d300000 tcpserver -vDRHl0 -x tcp.cdb -- \"$IP\" 53 ");
++  outs(" softlimit -d400000 tcpserver -vDRHl0 -x tcp.cdb -- \"$IP\" 53 ");
+   outs(auto_home); outs("/sbin/axfrdns\n'\n");
+   finish();
+   perm(0755);
+--- a/dnscache-conf.c
++++ b/dnscache-conf.c
+@@ -118,7 +118,7 @@
+   seed_addtime(); perm(0644);
+   seed_addtime(); start("env/CACHESIZE"); outs("1000000\n"); finish();
+   seed_addtime(); perm(0644);
+-  seed_addtime(); start("env/DATALIMIT"); outs("3000000\n"); finish();
++  seed_addtime(); start("env/DATALIMIT"); outs("4000000\n"); finish();
+   seed_addtime(); perm(0644);
+   seed_addtime(); start("run");
+   outs("#!/bin/sh\nexec 2>&1\nexec <seed\nexec envdir ./env sh -c '\n  exec envuidgid "); outs(user);
+--- a/tinydns-conf.c
++++ b/tinydns-conf.c
+@@ -46,7 +46,7 @@
+ 
+   start("run");
+   outs("#!/bin/sh\nexec 2>&1\nexec envuidgid "); outs(user);
+-  outs(" envdir ./env softlimit -d300000 ");
++  outs(" envdir ./env softlimit -d400000 ");
+   outs(auto_home); outs("/sbin/tinydns\n");
+   finish();
+   perm(0755);
