source:
npl/internetserver/djbdns/CVE2008-4392_0001-dnscache-merge-similar-outgoing-queries.patch
Last change on this file was c5c522c, checked in by , 8 years ago | |
---|---|
|
|
File size: 9.7 KB |
-
Makefile
diff --git a/Makefile b/Makefile index 1429643..bc047c0 100644
a b stralloc.h iopause.h taia.h tai.h uint64.h taia.h 318 318 ./compile dns_txt.c 319 319 320 320 dnscache: \ 321 load dnscache.o droproot.o okclient.o log.o cache.o query.o \321 load dnscache.o droproot.o okclient.o log.o cache.o query.o qmerge.o \ 322 322 response.o dd.o roots.o iopause.o prot.o dns.a env.a alloc.a buffer.a \ 323 323 libtai.a unix.a byte.a socket.lib 324 324 ./load dnscache droproot.o okclient.o log.o cache.o \ 325 query.o response.o dd.o roots.o iopause.o prot.o dns.a \325 query.o qmerge.o response.o dd.o roots.o iopause.o prot.o dns.a \ 326 326 env.a alloc.a buffer.a libtai.a unix.a byte.a `cat \ 327 327 socket.lib` 328 328 … … compile dnscache.c env.h exit.h scan.h strerr.h error.h ip4.h \ 343 343 uint16.h uint64.h socket.h uint16.h dns.h stralloc.h gen_alloc.h \ 344 344 iopause.h taia.h tai.h uint64.h taia.h taia.h byte.h roots.h fmt.h \ 345 345 iopause.h query.h dns.h uint32.h alloc.h response.h uint32.h cache.h \ 346 uint32.h uint64.h ndelay.h log.h uint64.h okclient.h droproot.h 346 uint32.h uint64.h ndelay.h log.h uint64.h okclient.h droproot.h maxclient.h 347 347 ./compile dnscache.c 348 348 349 349 dnsfilter: \ … … qlog.o: \ 687 687 compile qlog.c buffer.h qlog.h uint16.h 688 688 ./compile qlog.c 689 689 690 qmerge.o: \ 691 compile qmerge.c qmerge.h dns.h stralloc.h gen_alloc.h iopause.h \ 692 taia.h tai.h uint64.h log.h maxclient.h 693 ./compile qmerge.c 694 690 695 query.o: \ 691 696 compile query.c error.h roots.h log.h uint64.h case.h cache.h \ 692 697 uint32.h uint64.h byte.h dns.h stralloc.h gen_alloc.h iopause.h \ 693 698 taia.h tai.h uint64.h taia.h uint64.h uint32.h uint16.h dd.h alloc.h \ 694 response.h uint32.h query.h dns.h uint32.h 699 response.h uint32.h query.h dns.h uint32.h qmerge.h 695 700 ./compile query.c 696 701 697 702 random-ip: \ -
dnscache.c
diff --git a/dnscache.c b/dnscache.c index 8c899a3..5ccb16a 100644
a b 22 22 #include "log.h" 23 23 #include "okclient.h" 24 24 #include "droproot.h" 25 #include "maxclient.h" 25 26 26 27 static int packetquery(char *buf,unsigned int len,char **q,char qtype[2],char qclass[2],char id[2]) 27 28 { … … uint64 numqueries = 0; 54 55 55 56 static int udp53; 56 57 57 #define MAXUDP 20058 58 static struct udpclient { 59 59 struct query q; 60 60 struct taia start; … … void u_new(void) 131 131 132 132 static int tcp53; 133 133 134 #define MAXTCP 20135 134 struct tcpclient { 136 135 struct query q; 137 136 struct taia start; -
log.c
diff --git a/log.c b/log.c index c43e8b0..b8cd7ce 100644
a b void log_tx(const char *q,const char qtype[2],const char *control,const char ser 150 150 line(); 151 151 } 152 152 153 void log_tx_piggyback(const char *q, const char qtype[2], const char *control) 154 { 155 string("txpb "); 156 logtype(qtype); space(); name(q); space(); name(control); 157 line(); 158 } 159 153 160 void log_cachedanswer(const char *q,const char type[2]) 154 161 { 155 162 string("cached "); logtype(type); space(); -
log.h
diff --git a/log.h b/log.h index fe62fa3..d9a829b 100644
a b extern void log_cachednxdomain(const char *); 18 18 extern void log_cachedns(const char *,const char *); 19 19 20 20 extern void log_tx(const char *,const char *,const char *,const char *,unsigned int); 21 extern void log_tx_piggyback(const char *,const char *,const char *); 21 22 22 23 extern void log_nxdomain(const char *,const char *,unsigned int); 23 24 extern void log_nodata(const char *,const char *,const char *,unsigned int); -
new file maxclient.h
diff --git a/maxclient.h b/maxclient.h new file mode 100644 index 0000000..e52fcd1
- + 1 #ifndef MAXCLIENT_H 2 #define MAXCLIENT_H 3 4 #define MAXUDP 200 5 #define MAXTCP 20 6 7 #endif /* MAXCLIENT_H */ -
new file qmerge.c
diff --git a/qmerge.c b/qmerge.c new file mode 100644 index 0000000..7c92299
- + 1 #include "qmerge.h" 2 #include "byte.h" 3 #include "log.h" 4 #include "maxclient.h" 5 6 #define QMERGE_MAX (MAXUDP+MAXTCP) 7 struct qmerge inprogress[QMERGE_MAX]; 8 9 static 10 int qmerge_key_init(struct qmerge_key *qmk, const char *q, const char qtype[2], 11 const char *control) 12 { 13 if (!dns_domain_copy(&qmk->q, q)) return 0; 14 byte_copy(qmk->qtype, 2, qtype); 15 if (!dns_domain_copy(&qmk->control, control)) return 0; 16 return 1; 17 } 18 19 static 20 int qmerge_key_equal(struct qmerge_key *a, struct qmerge_key *b) 21 { 22 return 23 byte_equal(a->qtype, 2, b->qtype) && 24 dns_domain_equal(a->q, b->q) && 25 dns_domain_equal(a->control, b->control); 26 } 27 28 static 29 void qmerge_key_free(struct qmerge_key *qmk) 30 { 31 dns_domain_free(&qmk->q); 32 dns_domain_free(&qmk->control); 33 } 34 35 void qmerge_free(struct qmerge **x) 36 { 37 struct qmerge *qm; 38 39 qm = *x; 40 *x = 0; 41 if (!qm || !qm->active) return; 42 43 qm->active--; 44 if (!qm->active) { 45 qmerge_key_free(&qm->key); 46 dns_transmit_free(&qm->dt); 47 } 48 } 49 50 int qmerge_start(struct qmerge **qm, const char servers[64], int flagrecursive, 51 const char *q, const char qtype[2], const char localip[4], 52 const char *control) 53 { 54 struct qmerge_key k; 55 int i; 56 int r; 57 58 qmerge_free(qm); 59 60 byte_zero(&k, sizeof k); 61 if (!qmerge_key_init(&k, q, qtype, control)) return -1; 62 for (i = 0; i < QMERGE_MAX; i++) { 63 if (!inprogress[i].active) continue; 64 if (!qmerge_key_equal(&k, &inprogress[i].key)) continue; 65 log_tx_piggyback(q, qtype, control); 66 inprogress[i].active++; 67 *qm = &inprogress[i]; 68 qmerge_key_free(&k); 69 return 0; 70 } 71 72 for (i = 0; i < QMERGE_MAX; i++) 73 if (!inprogress[i].active) 74 break; 75 if (i == QMERGE_MAX) return -1; 76 77 log_tx(q, qtype, control, servers, 0); 78 r = dns_transmit_start(&inprogress[i].dt, servers, flagrecursive, q, qtype, localip); 79 if (r == -1) { qmerge_key_free(&k); return -1; } 80 inprogress[i].active++; 81 inprogress[i].state = 0; 82 qmerge_key_free(&inprogress[i].key); 83 byte_copy(&inprogress[i].key, sizeof k, &k); 84 *qm = &inprogress[i]; 85 return 0; 86 } 87 88 void qmerge_io(struct qmerge *qm, iopause_fd *io, struct taia *deadline) 89 { 90 if (qm->state == 0) { 91 dns_transmit_io(&qm->dt, io, deadline); 92 qm->state = 1; 93 } 94 else { 95 io->fd = -1; 96 io->events = 0; 97 } 98 } 99 100 int qmerge_get(struct qmerge **x, const iopause_fd *io, const struct taia *when) 101 { 102 int r; 103 struct qmerge *qm; 104 105 qm = *x; 106 if (qm->state == -1) return -1; /* previous error */ 107 if (qm->state == 0) return 0; /* no packet */ 108 if (qm->state == 2) return 1; /* already got packet */ 109 110 r = dns_transmit_get(&qm->dt, io, when); 111 if (r == -1) { qm->state = -1; return -1; } /* error */ 112 if (r == 0) { qm->state = 0; return 0; } /* must wait for i/o */ 113 if (r == 1) { qm->state = 2; return 1; } /* got packet */ 114 return -1; /* bug */ 115 } -
new file qmerge.h
diff --git a/qmerge.h b/qmerge.h new file mode 100644 index 0000000..9a58157
- + 1 #ifndef QMERGE_H 2 #define QMERGE_H 3 4 #include "dns.h" 5 6 struct qmerge_key { 7 char *q; 8 char qtype[2]; 9 char *control; 10 }; 11 12 struct qmerge { 13 int active; 14 struct qmerge_key key; 15 struct dns_transmit dt; 16 int state; /* -1 = error, 0 = need io, 1 = need get, 2 = got packet */ 17 }; 18 19 extern int qmerge_start(struct qmerge **,const char *,int,const char *,const char *,const char *,const char *); 20 extern void qmerge_io(struct qmerge *,iopause_fd *,struct taia *); 21 extern int qmerge_get(struct qmerge **,const iopause_fd *,const struct taia *); 22 extern void qmerge_free(struct qmerge **); 23 24 #endif /* QMERGE_H */ -
query.c
diff --git a/query.c b/query.c index 46cdc00..f091fdd 100644
a b static void cleanup(struct query *z) 81 81 int j; 82 82 int k; 83 83 84 dns_transmit_free(&z->dt);84 qmerge_free(&z->qm); 85 85 for (j = 0;j < QUERY_MAXALIAS;++j) 86 86 dns_domain_free(&z->alias[j]); 87 87 for (j = 0;j < QUERY_MAXLEVEL;++j) { … … static int doit(struct query *z,int state) 429 429 if (j == 64) goto SERVFAIL; 430 430 431 431 dns_sortip(z->servers[z->level],64); 432 if (z->level) { 433 log_tx(z->name[z->level],DNS_T_A,z->control[z->level],z->servers[z->level],z->level); 434 if (dns_transmit_start(&z->dt,z->servers[z->level],flagforwardonly,z->name[z->level],DNS_T_A,z->localip) == -1) goto DIE; 435 } 436 else { 437 log_tx(z->name[0],z->type,z->control[0],z->servers[0],0); 438 if (dns_transmit_start(&z->dt,z->servers[0],flagforwardonly,z->name[0],z->type,z->localip) == -1) goto DIE; 439 } 432 dtype = z->level ? DNS_T_A : z->type; 433 if (qmerge_start(&z->qm,z->servers[z->level],flagforwardonly,z->name[z->level],dtype,z->localip,z->control[z->level]) == -1) goto DIE; 440 434 return 0; 441 435 442 436 … … static int doit(struct query *z,int state) 450 444 451 445 HAVEPACKET: 452 446 if (++z->loop == 100) goto DIE; 453 buf = z-> dt.packet;454 len = z-> dt.packetlen;447 buf = z->qm->dt.packet; 448 len = z->qm->dt.packetlen; 455 449 456 whichserver = z-> dt.servers + 4 * z->dt.curserver;450 whichserver = z->qm->dt.servers + 4 * z->qm->dt.curserver; 457 451 control = z->control[z->level]; 458 452 d = z->name[z->level]; 459 453 dtype = z->level ? DNS_T_A : z->type; … … int query_start(struct query *z,char *dn,char type[2],char class[2],char localip 836 830 837 831 int query_get(struct query *z,iopause_fd *x,struct taia *stamp) 838 832 { 839 switch( dns_transmit_get(&z->dt,x,stamp)) {833 switch(qmerge_get(&z->qm,x,stamp)) { 840 834 case 1: 841 835 return doit(z,1); 842 836 case -1: … … int query_get(struct query *z,iopause_fd *x,struct taia *stamp) 847 841 848 842 void query_io(struct query *z,iopause_fd *x,struct taia *deadline) 849 843 { 850 dns_transmit_io(&z->dt,x,deadline);844 qmerge_io(z->qm,x,deadline); 851 845 } -
query.h
diff --git a/query.h b/query.h index eff68b2..06feab4 100644
a b 1 1 #ifndef QUERY_H 2 2 #define QUERY_H 3 3 4 #include " dns.h"4 #include "qmerge.h" 5 5 #include "uint32.h" 6 6 7 7 #define QUERY_MAXLEVEL 5 … … struct query { 20 20 char localip[4]; 21 21 char type[2]; 22 22 char class[2]; 23 struct dns_transmit dt;23 struct qmerge *qm; 24 24 } ; 25 25 26 26 extern int query_start(struct query *,char *,char *,char *,char *);
Note: See TracBrowser
for help on using the repository browser.