summaryrefslogtreecommitdiff
path: root/net-dns/djbdns
diff options
context:
space:
mode:
authorV3n3RiX <venerix@redcorelinux.org>2018-04-14 01:05:40 +0100
committerV3n3RiX <venerix@redcorelinux.org>2018-04-14 01:05:40 +0100
commit76cba73c47c8694e74377004634daca18f2d9c08 (patch)
tree468603ebdc189bcfae77696162761b3be936baea /net-dns/djbdns
parent6957f5c65b02bba533954eabc0b62f5de36be206 (diff)
gentoo resync : 14.04.2018
Diffstat (limited to 'net-dns/djbdns')
-rw-r--r--net-dns/djbdns/Manifest3
-rw-r--r--net-dns/djbdns/djbdns-1.05-r33.ebuild132
-rw-r--r--net-dns/djbdns/files/CVE2008-4392_0001-dnscache-merge-similar-outgoing-queries-ipv6-test28.patch351
3 files changed, 486 insertions, 0 deletions
diff --git a/net-dns/djbdns/Manifest b/net-dns/djbdns/Manifest
index 6e6c04b9e179..0abb2d0e335f 100644
--- a/net-dns/djbdns/Manifest
+++ b/net-dns/djbdns/Manifest
@@ -1,5 +1,6 @@
AUX 1.05-errno-r1.patch 242 BLAKE2B b02d686bbdad4178de2e8ba822feeeec5a3aa4549119c86ec806bfc34d0bebdcef7ee6bb2f57ffe73dc42e9d96b2bf08a28be7502aa8974f8f96cd32dcece178 SHA512 086d02600034d486f084fd2500aba9041dfa02110781594cdc3781a3ad7823f61f11c54c053c8c1241f58660527abe536906aba0e7f6c49ed3b8dbd74ba8f2b7
AUX CVE2008-4392_0001-dnscache-merge-similar-outgoing-queries-ipv6-test25-r1.patch 9944 BLAKE2B 05be2d88ff5e8c212370cea199d7e817d07fa9ecb807c567d48b34c963e101c18bd1d785be9d46ee6cbf6f8a84ca53e4dd1432c868d9acecabbb3ffcc326f878 SHA512 6c40018bfe97f9ed2ab1bb4034ceb20089edc93514a4c9931a5e1f09cb6d9a8f221eb9652b3b1485f80df643a1fb1d2c88ff148421e86af7cf7b1485b9c61c30
+AUX CVE2008-4392_0001-dnscache-merge-similar-outgoing-queries-ipv6-test28.patch 9954 BLAKE2B ab189b25421c016bd24ecc34d9eae3552eeeb1303d158a2adeeb9c27b48a8935425d76f803104ba0be4bcc1bacd6cac48fb9b800c7401ea306d017525404b0cb SHA512 3ff6e971739bfe7f0fd7defd6520f4a03f88dd907668018c10efd91d03e4dbc2068773953d6feed22308d82fb2d38066b2102c6f6fd738c15c4bee6835a52dce
AUX CVE2008-4392_0001-dnscache-merge-similar-outgoing-queries-r1.patch 9914 BLAKE2B 3224e58eac5ac254359158a193b8a4c7618ff12826cce0f71b7c45e9c886ff54d1fb883d02a6b2d80801f395b721dee46390b6b5191e22cc5f2d75da06f2b08c SHA512 59e9aae2fd8e7c1e4d275066afceaade3b1276c6cda78cd58fef1dfbe9749c9e1bb415a80643b3c50a33372166aec055a9b3a6bcb3ed4cfd77e6e6038e069cff
AUX CVE2008-4392_0002-dnscache-cache-soa-records-ipv6.patch 3043 BLAKE2B 224cf29a7db357c3c421212cc240c16801ea544e1cbad65605e0ba8413139c09d37144f2f784a751015abbb99c2f36e3716c28a821b8f66edf02310c72d28417 SHA512 f830bfd2fabd4d9b4e2649bcc4061d656d4645b93829415d070b26c6a22e8e17d941666b8e776947bf9a8ef93007f77d8be57fc9911dcc6dc2b7ac607d556ba0
AUX CVE2008-4392_0002-dnscache-cache-soa-records.patch 2944 BLAKE2B 22d0fa17c99e3b979faa3a1f1d7dae72834d47f8362efbe917f321847847147f3e7992599b27489a6ea898e1bcc0df5193f64202dc594e2840df6932dcc428d4 SHA512 f65ca7dfc8e85f469f22d72a1c79126c35243dc077abf4b688eb7d057f19456dc8a3665f558a8a3c1908f96fa1838792aa1bc317d2e89f4953020828c05926e6
@@ -14,6 +15,8 @@ AUX srv_record_support.patch 5423 BLAKE2B 28167fbf8b404b926e484a4cf93ddf4b1ff450
AUX string_length_255.patch 299 BLAKE2B 083d963d8d67baec402321c7fb8be2e485985ce03daea1d198912204dda6a90b794d5df3519b4177de8720122b46600cc9fe669f265cf9b81c75e4335ae081d6 SHA512 b451d23e1a45636dfae7cf69c64e3edde6b655bc0c7407586429e0d8282f17ef6215c6c33a6d238115c39d34fa57fa7699a7a10f146344c677fde10c0e207ac3
DIST djbdns-1.05-man.tar.gz 17170 BLAKE2B 2fef7e1be8a427b2c426c2af58bf4c22795e64d03e0f605ca333e38f187ff65b333e88a7cea0e8a9ec867b446b5ca34a5c97dd24ae18b28ee4c747f2fd1f1608 SHA512 98af7bd9033a2205fbbc0f23b7eab45b9756f6ceff5199a62952e19c89c9fe3c03495cb6f8621d388f883c40650309a1509095417df3f54af21a71350c4aa183
DIST djbdns-1.05-test27.diff.bz2 20695 BLAKE2B 5eb2b5deeb81ec802bec4787b844f8b072e46a06ea28cf28a2702f8d545c3248256357669471f78b61f30c656b6f325bb8c0710dbdfa3ad2c2b00d5fb02bfc66 SHA512 e5acf26ff353ae20b6c2186140255bf0ae478a75a9946163d4474a003afbf8c2f47e61a12fc3ed4b9eff17ec8732e9d91bfbb10fb2762310b067180b6d471ba0
+DIST djbdns-1.05-test28.diff.xz 22072 BLAKE2B fff6c13220adfa056a0ac5942ff9385d83b75f8622adaebab65f557a2ca8d014fe3c255fe55ba9afca56b24880b7cd28597b26b5bcc3bbbd3ef9f581b67004fd SHA512 7fbfeda10221a0a09897c2e744df5606c83113c394ce055d822b0d8733873d72567a88c37905d21c7d2395170fc12b9e9eb133a941aa809f1b9856872ab48230
DIST djbdns-1.05.tar.gz 85648 BLAKE2B 51918fcc8944e64e72709636ee7d56975a138a2806e22c019fa836770de3a338bb8f682216b89c09d6b2861c2423e60e28dc60639f5a86aca2040e1788e4cf5c SHA512 20f066402801d7bec183cb710a5bc51e41f1410024741e5803e26f68f2c13567e48eba793f233dfab903459c3335bc169e24b99d66a4c64e617e1f0779732fa9
EBUILD djbdns-1.05-r32.ebuild 4351 BLAKE2B ef4774774e33fc267e4a4f9f94c82c5d0e909cf32a8edbcec301991325e83c9d48a5ddc96f01a0f7fb5fc8e0f775133410fc97f61da861753f83bc774d8d6ea4 SHA512 03311e521344f266b46fa0e72e319363c22f344d330422343f6f4fb7474017ca97b6361decb7956a5e396b067a00aa11c82769945bec34ae285302a99804fd95
+EBUILD djbdns-1.05-r33.ebuild 3678 BLAKE2B b64b85007e2e0aa3620af5898b2abc737d5efbb6989ff3e7d8e45a90b1660c481a01d0441c83fadf690ef4945cfd202a0dbaed599bcf0c0cddb43686f428f693 SHA512 fa5078523925f715933dea95fd1b8cb6c50ea46e73841d0ca05e477ea95e362c05750bf5a7dbb8174a13cf617d113c02ab7a5ee627b7f8e87b03a33d6987fed6
MISC metadata.xml 244 BLAKE2B c21c7a6cd7f859220baee98b22912e06955a7d63b4fc954a40507126ef6cb30659a3b7e89e798bb7d074814810f9625d3979ed2ac8877e213dc378da841bc786 SHA512 125b00b9e85650a6dcc365871f9f8be44d85cde4b938a66f7d96b6dc0237a1cae68b30be1ee16d7850998fc31be35eaf459df1bb7d9ea169904854b532f37bab
diff --git a/net-dns/djbdns/djbdns-1.05-r33.ebuild b/net-dns/djbdns/djbdns-1.05-r33.ebuild
new file mode 100644
index 000000000000..ad80420e697d
--- /dev/null
+++ b/net-dns/djbdns/djbdns-1.05-r33.ebuild
@@ -0,0 +1,132 @@
+# Copyright 1999-2018 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=6
+inherit flag-o-matic readme.gentoo-r1 toolchain-funcs user
+
+DESCRIPTION="Collection of DNS client/server software"
+HOMEPAGE="http://cr.yp.to/djbdns.html"
+IPV6_PATCH="test28"
+
+SRC_URI="http://cr.yp.to/djbdns/${P}.tar.gz
+ http://smarden.org/pape/djb/manpages/${P}-man.tar.gz
+ ipv6? ( http://www.fefe.de/dns/${P}-${IPV6_PATCH}.diff.xz )"
+
+SLOT="0"
+LICENSE="public-domain"
+KEYWORDS="~alpha ~amd64 ~hppa ~mips ~ppc ~ppc64 ~sparc ~x86"
+IUSE="ipv6 selinux"
+
+DEPEND=""
+RDEPEND="sys-apps/ucspi-tcp
+ virtual/daemontools
+ selinux? ( sec-policy/selinux-djbdns )"
+
+src_unpack(){
+ # Unpack both djbdns and its man pages to separate directories.
+ default
+
+ # Now move the man pages under ${S} so that user patches can be
+ # applied to them as well in src_prepare().
+ mv "${PN}-man" "${P}/man" || die "failed to transplant man pages"
+}
+
+PATCHES=(
+ "${FILESDIR}/headtail-r1.patch"
+ "${FILESDIR}/dnsroots.patch"
+ "${FILESDIR}/dnstracesort.patch"
+ "${FILESDIR}/string_length_255.patch"
+ "${FILESDIR}/srv_record_support.patch"
+ "${FILESDIR}/increase-cname-recustion-depth.patch"
+ "${FILESDIR}/CVE2009-0858_0001-check-response-domain-name-length.patch"
+ "${FILESDIR}/CVE2012-1191_0001-ghost-domain-attack.patch"
+)
+
+src_prepare() {
+ if use ipv6; then
+ PATCHES=(${PATCHES[@]}
+ # The big ipv6 patch.
+ "${WORKDIR}/${P}-${IPV6_PATCH}.diff"
+ # Fix CVE2008-4392 (ipv6)
+ "${FILESDIR}/CVE2008-4392_0001-dnscache-merge-similar-outgoing-queries-ipv6-test28.patch"
+ "${FILESDIR}/CVE2008-4392_0002-dnscache-cache-soa-records-ipv6.patch"
+ "${FILESDIR}/makefile-parallel-test25.patch"
+ )
+ else
+ PATCHES=(${PATCHES[@]}
+ # Fix CVE2008-4392 (no ipv6)
+ "${FILESDIR}/CVE2008-4392_0001-dnscache-merge-similar-outgoing-queries-r1.patch"
+ "${FILESDIR}/CVE2008-4392_0002-dnscache-cache-soa-records.patch"
+ # Later versions of the ipv6 patch include this
+ "${FILESDIR}/${PV}-errno-r1.patch"
+ )
+ fi
+
+ default
+}
+
+src_compile() {
+ echo "$(tc-getCC) ${CFLAGS}" > conf-cc || die
+ echo "$(tc-getCC) ${LDFLAGS}" > conf-ld || die
+ echo "/usr" > conf-home || die
+ emake
+}
+
+src_install() {
+ insinto /etc
+ doins dnsroots.global
+
+ into /usr
+ dobin *-conf dnscache tinydns walldns rbldns pickdns axfrdns \
+ *-get *-data *-edit dnsip dnsipq dnsname dnstxt dnsmx \
+ dnsfilter random-ip dnsqr dnsq dnstrace dnstracesort
+
+ if use ipv6; then
+ dobin dnsip6 dnsip6q
+ fi
+
+ dodoc CHANGES README
+
+ doman man/*.[158]
+
+ readme.gentoo_create_doc
+}
+
+pkg_preinst() {
+ # The nofiles group is no longer provided by baselayout.
+ # Share it with qmail if possible.
+ enewgroup nofiles 200
+
+ enewuser dnscache -1 -1 -1 nofiles
+ enewuser dnslog -1 -1 -1 nofiles
+ enewuser tinydns -1 -1 -1 nofiles
+}
+
+DISABLE_AUTOFORMATTING=1
+DOC_CONTENTS='
+To configure djbdns, please follow the instructions at,
+
+ http://cr.yp.to/djbdns.html
+
+Of particular interest are,
+
+ axfrdns : http://cr.yp.to/djbdns/axfrdns-conf.html
+ dnscache: http://cr.yp.to/djbdns/run-cache-x-home.html
+ tinydns : http://cr.yp.to/djbdns/run-server.html
+
+Portage has created users for axfrdns, dnscache, and tinydns; the
+commands to configure these programs are,
+
+ 1. axfrdns-conf tinydns dnslog /var/axfrdns /var/tinydns $ip
+ 2. dnscache-conf dnscache dnslog /var/dnscache $ip
+ 3. tinydns-conf tinydns dnslog /var/tinydns $ip
+
+(replace $ip with the ip address on which the server will run).
+
+If you wish to configure rbldns or walldns, you will need to create
+those users yourself (although you should still use the "dnslog"
+user for the logs):
+
+ 4. rbldns-conf $username dnslog /var/rbldns $ip $base
+ 5. walldns-conf $username dnslog /var/walldns $ip
+'
diff --git a/net-dns/djbdns/files/CVE2008-4392_0001-dnscache-merge-similar-outgoing-queries-ipv6-test28.patch b/net-dns/djbdns/files/CVE2008-4392_0001-dnscache-merge-similar-outgoing-queries-ipv6-test28.patch
new file mode 100644
index 000000000000..d493b8985e05
--- /dev/null
+++ b/net-dns/djbdns/files/CVE2008-4392_0001-dnscache-merge-similar-outgoing-queries-ipv6-test28.patch
@@ -0,0 +1,351 @@
+diff --git a/Makefile b/Makefile
+index 5ccd647..eee09dd 100644
+--- a/Makefile
++++ b/Makefile
+@@ -346,11 +346,11 @@ stralloc.h iopause.h taia.h tai.h uint64.h taia.h
+ ./compile dns_txt.c
+
+ dnscache: \
+-load dnscache.o droproot.o okclient.o log.o cache.o query.o \
++load dnscache.o droproot.o okclient.o log.o cache.o query.o qmerge.o \
+ response.o dd.o roots.o iopause.o prot.o dns.a env.a alloc.a buffer.a \
+ libtai.a unix.a byte.a socket.lib
+ ./load dnscache droproot.o okclient.o log.o cache.o \
+- query.o response.o dd.o roots.o iopause.o prot.o dns.a \
++ query.o qmerge.o response.o dd.o roots.o iopause.o prot.o dns.a \
+ env.a alloc.a buffer.a libtai.a unix.a byte.a `cat \
+ socket.lib`
+
+@@ -371,7 +371,7 @@ compile dnscache.c env.h exit.h scan.h strerr.h error.h ip4.h \
+ uint16.h uint64.h socket.h uint16.h dns.h stralloc.h gen_alloc.h \
+ iopause.h taia.h tai.h uint64.h taia.h taia.h byte.h roots.h fmt.h \
+ iopause.h query.h dns.h uint32.h alloc.h response.h uint32.h cache.h \
+-uint32.h uint64.h ndelay.h log.h uint64.h okclient.h droproot.h
++uint32.h uint64.h ndelay.h log.h uint64.h okclient.h droproot.h maxclient.h
+ ./compile dnscache.c
+
+ dnsfilter: \
+@@ -749,11 +749,16 @@ qlog.o: \
+ compile qlog.c buffer.h qlog.h uint16.h
+ ./compile qlog.c
+
++qmerge.o: \
++compile qmerge.c qmerge.h dns.h stralloc.h gen_alloc.h iopause.h \
++taia.h tai.h uint64.h log.h maxclient.h
++ ./compile qmerge.c
++
+ query.o: \
+ compile query.c error.h roots.h log.h uint64.h case.h cache.h \
+ uint32.h uint64.h byte.h dns.h stralloc.h gen_alloc.h iopause.h \
+ taia.h tai.h uint64.h taia.h uint64.h uint32.h uint16.h dd.h alloc.h \
+-response.h uint32.h query.h dns.h uint32.h
++response.h uint32.h query.h dns.h uint32.h qmerge.h
+ ./compile query.c
+
+ random-ip: \
+diff --git a/dnscache.c b/dnscache.c
+index abcba69..c84e4b8 100644
+--- a/dnscache.c
++++ b/dnscache.c
+@@ -23,6 +23,7 @@
+ #include "okclient.h"
+ #include "droproot.h"
+ #include "openreadclose.h"
++#include "maxclient.h"
+
+ long interface;
+
+@@ -59,7 +60,6 @@ uint64 numqueries = 0;
+
+ static int udp53;
+
+-#define MAXUDP 200
+ static struct udpclient {
+ struct query q;
+ struct taia start;
+@@ -136,7 +136,6 @@ void u_new(void)
+
+ static int tcp53;
+
+-#define MAXTCP 20
+ struct tcpclient {
+ struct query q;
+ struct taia start;
+diff --git a/log.c b/log.c
+index df465e2..1b0d98c 100644
+--- a/log.c
++++ b/log.c
+@@ -149,6 +149,13 @@ void log_tx(const char *q,const char qtype[2],const char *control,const char ser
+ line();
+ }
+
++void log_tx_piggyback(const char *q, const char qtype[2], const char *control)
++{
++ string("txpb ");
++ logtype(qtype); space(); name(q); space(); name(control);
++ 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..d9a829b 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_tx_piggyback(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);
+diff --git a/maxclient.h b/maxclient.h
+new file mode 100644
+index 0000000..e52fcd1
+--- /dev/null
++++ b/maxclient.h
+@@ -0,0 +1,7 @@
++#ifndef MAXCLIENT_H
++#define MAXCLIENT_H
++
++#define MAXUDP 200
++#define MAXTCP 20
++
++#endif /* MAXCLIENT_H */
+diff --git a/qmerge.c b/qmerge.c
+new file mode 100644
+index 0000000..7c92299
+--- /dev/null
++++ b/qmerge.c
+@@ -0,0 +1,115 @@
++#include "qmerge.h"
++#include "byte.h"
++#include "log.h"
++#include "maxclient.h"
++
++#define QMERGE_MAX (MAXUDP+MAXTCP)
++struct qmerge inprogress[QMERGE_MAX];
++
++static
++int qmerge_key_init(struct qmerge_key *qmk, const char *q, const char qtype[2],
++ const char *control)
++{
++ if (!dns_domain_copy(&qmk->q, q)) return 0;
++ byte_copy(qmk->qtype, 2, qtype);
++ if (!dns_domain_copy(&qmk->control, control)) return 0;
++ return 1;
++}
++
++static
++int qmerge_key_equal(struct qmerge_key *a, struct qmerge_key *b)
++{
++ return
++ byte_equal(a->qtype, 2, b->qtype) &&
++ dns_domain_equal(a->q, b->q) &&
++ dns_domain_equal(a->control, b->control);
++}
++
++static
++void qmerge_key_free(struct qmerge_key *qmk)
++{
++ dns_domain_free(&qmk->q);
++ dns_domain_free(&qmk->control);
++}
++
++void qmerge_free(struct qmerge **x)
++{
++ struct qmerge *qm;
++
++ qm = *x;
++ *x = 0;
++ if (!qm || !qm->active) return;
++
++ qm->active--;
++ if (!qm->active) {
++ qmerge_key_free(&qm->key);
++ dns_transmit_free(&qm->dt);
++ }
++}
++
++int qmerge_start(struct qmerge **qm, const char servers[64], int flagrecursive,
++ const char *q, const char qtype[2], const char localip[4],
++ const char *control)
++{
++ struct qmerge_key k;
++ int i;
++ int r;
++
++ qmerge_free(qm);
++
++ byte_zero(&k, sizeof k);
++ if (!qmerge_key_init(&k, q, qtype, control)) return -1;
++ for (i = 0; i < QMERGE_MAX; i++) {
++ if (!inprogress[i].active) continue;
++ if (!qmerge_key_equal(&k, &inprogress[i].key)) continue;
++ log_tx_piggyback(q, qtype, control);
++ inprogress[i].active++;
++ *qm = &inprogress[i];
++ qmerge_key_free(&k);
++ return 0;
++ }
++
++ for (i = 0; i < QMERGE_MAX; i++)
++ if (!inprogress[i].active)
++ break;
++ if (i == QMERGE_MAX) return -1;
++
++ log_tx(q, qtype, control, servers, 0);
++ r = dns_transmit_start(&inprogress[i].dt, servers, flagrecursive, q, qtype, localip);
++ if (r == -1) { qmerge_key_free(&k); return -1; }
++ inprogress[i].active++;
++ inprogress[i].state = 0;
++ qmerge_key_free(&inprogress[i].key);
++ byte_copy(&inprogress[i].key, sizeof k, &k);
++ *qm = &inprogress[i];
++ return 0;
++}
++
++void qmerge_io(struct qmerge *qm, iopause_fd *io, struct taia *deadline)
++{
++ if (qm->state == 0) {
++ dns_transmit_io(&qm->dt, io, deadline);
++ qm->state = 1;
++ }
++ else {
++ io->fd = -1;
++ io->events = 0;
++ }
++}
++
++int qmerge_get(struct qmerge **x, const iopause_fd *io, const struct taia *when)
++{
++ int r;
++ struct qmerge *qm;
++
++ qm = *x;
++ if (qm->state == -1) return -1; /* previous error */
++ if (qm->state == 0) return 0; /* no packet */
++ if (qm->state == 2) return 1; /* already got packet */
++
++ r = dns_transmit_get(&qm->dt, io, when);
++ if (r == -1) { qm->state = -1; return -1; } /* error */
++ if (r == 0) { qm->state = 0; return 0; } /* must wait for i/o */
++ if (r == 1) { qm->state = 2; return 1; } /* got packet */
++ return -1; /* bug */
++}
+diff --git a/qmerge.h b/qmerge.h
+new file mode 100644
+index 0000000..9a58157
+--- /dev/null
++++ b/qmerge.h
+@@ -0,0 +1,24 @@
++#ifndef QMERGE_H
++#define QMERGE_H
++
++#include "dns.h"
++
++struct qmerge_key {
++ char *q;
++ char qtype[2];
++ char *control;
++};
++
++struct qmerge {
++ int active;
++ struct qmerge_key key;
++ struct dns_transmit dt;
++ int state; /* -1 = error, 0 = need io, 1 = need get, 2 = got packet */
++};
++
++extern int qmerge_start(struct qmerge **,const char *,int,const char *,const char *,const char *,const char *);
++extern void qmerge_io(struct qmerge *,iopause_fd *,struct taia *);
++extern int qmerge_get(struct qmerge **,const iopause_fd *,const struct taia *);
++extern void qmerge_free(struct qmerge **);
++
++#endif /* QMERGE_H */
+diff --git a/query.c b/query.c
+index d61b20c..d9be8b8 100644
+--- a/query.c
++++ b/query.c
+@@ -84,7 +84,7 @@ static void cleanup(struct query *z)
+ int j;
+ int k;
+
+- dns_transmit_free(&z->dt);
++ qmerge_free(&z->qm);
+ for (j = 0;j < QUERY_MAXALIAS;++j)
+ dns_domain_free(&z->alias[j]);
+ for (j = 0;j < QUERY_MAXLEVEL;++j) {
+@@ -624,15 +624,9 @@ static int doit(struct query *z,int state)
+ if (j == 256) goto SERVFAIL;
+
+ dns_sortip6(z->servers[z->level],256);
+- if (z->level) {
+- dtype = z->ipv6[z->level] ? DNS_T_AAAA : DNS_T_A;
+- log_tx(z->name[z->level],dtype,z->control[z->level],z->servers[z->level],z->level);
+- if (dns_transmit_start(&z->dt,z->servers[z->level],flagforwardonly,z->name[z->level],dtype,z->localip) == -1) goto DIE;
+- }
+- else {
+- log_tx(z->name[0],z->type,z->control[0],z->servers[0],0);
+- if (dns_transmit_start(&z->dt,z->servers[0],flagforwardonly,z->name[0],z->type,z->localip) == -1) goto DIE;
+- }
++ dtype = z->level ? (z->ipv6[z->level] ? DNS_T_AAAA : DNS_T_A) : z->type;
++ if (qmerge_start(&z->qm,z->servers[z->level],flagforwardonly,z->name[z->level],dtype,z->localip,z->control[z->level]) == -1) goto DIE;
++
+ return 0;
+
+
+@@ -646,10 +640,10 @@ static int doit(struct query *z,int state)
+
+ HAVEPACKET:
+ if (++z->loop == 200) goto DIE;
+- buf = z->dt.packet;
+- len = z->dt.packetlen;
++ buf = z->qm->dt.packet;
++ len = z->qm->dt.packetlen;
+
+- whichserver = z->dt.servers + 16 * z->dt.curserver;
++ whichserver = z->qm->dt.servers + 16 * z->qm->dt.curserver;
+ control = z->control[z->level];
+ d = z->name[z->level];
+ /* dtype = z->level ? DNS_T_A : z->type; */
+@@ -1071,7 +1065,7 @@ int query_start(struct query *z,char *dn,char type[2],char class[2],char localip
+
+ int query_get(struct query *z,iopause_fd *x,struct taia *stamp)
+ {
+- switch(dns_transmit_get(&z->dt,x,stamp)) {
++ switch(qmerge_get(&z->qm,x,stamp)) {
+ case 1:
+ return doit(z,1);
+ case -1:
+@@ -1082,5 +1076,5 @@ int query_get(struct query *z,iopause_fd *x,struct taia *stamp)
+
+ void query_io(struct query *z,iopause_fd *x,struct taia *deadline)
+ {
+- dns_transmit_io(&z->dt,x,deadline);
++ qmerge_io(z->qm,x,deadline);
+ }
+diff --git a/query.h b/query.h
+index 61812aa..93a322e 100644
+--- a/query.h
++++ b/query.h
+@@ -1,7 +1,7 @@
+ #ifndef QUERY_H
+ #define QUERY_H
+
+-#include "dns.h"
++#include "qmerge.h"
+ #include "uint32.h"
+
+ #define QUERY_MAXLEVEL 5
+@@ -22,7 +22,7 @@ struct query {
+ uint32 scope_id;
+ char type[2];
+ char class[2];
+- struct dns_transmit dt;
++ struct qmerge *qm;
+ } ;
+
+ extern int query_start(struct query *,char *,char *,char *,char *,unsigned int);