257 lines
6.7 KiB
Plaintext
257 lines
6.7 KiB
Plaintext
$NetBSD: patch-qmerge2,v 1.2 2015/12/29 04:04:29 dholland Exp $
|
|
|
|
--- clients.h.orig 2009-04-21 23:43:02.000000000 -0400
|
|
+++ clients.h
|
|
@@ -0,0 +1,7 @@
|
|
+#ifndef CLIENTS_H
|
|
+#define CLIENTS_H
|
|
+
|
|
+#define MAXUDP 200
|
|
+#define MAXTCP 20
|
|
+
|
|
+#endif /* CLIENTS_H */
|
|
--- dns.h.orig 2001-02-11 16:11:45.000000000 -0500
|
|
+++ 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"
|
|
@@ -37,8 +38,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);
|
|
|
|
--- dns_transmit.c.orig 2001-02-11 16:11:45.000000000 -0500
|
|
+++ 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_transm
|
|
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 *
|
|
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 *
|
|
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
|
|
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
|
|
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 sock
|
|
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;
|
|
}
|
|
--- dnscache.c.orig 2001-02-11 16:11:45.000000000 -0500
|
|
+++ 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: ");
|
|
--- log.c.orig 2001-02-11 16:11:45.000000000 -0500
|
|
+++ log.c
|
|
@@ -150,6 +150,12 @@ void log_tx(const char *q,const char qty
|
|
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();
|
|
--- log.h.orig 2001-02-11 16:11:45.000000000 -0500
|
|
+++ log.h
|
|
@@ -18,6 +18,7 @@ extern void log_cachednxdomain(const cha
|
|
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);
|