source: npl/internetserver/djbdns/CVE2008-4392_0001-dnscache-merge-similar-outgoing-queries.patch @ 36e2ca3

Last change on this file since 36e2ca3 was c5c522c, checked in by Edwin Eefting <edwin@datux.nl>, 8 years ago

initial commit, transferred from cleaned syn3 svn tree

  • Property mode set to 100644
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 
    318318        ./compile dns_txt.c
    319319
    320320dnscache: \
    321 load dnscache.o droproot.o okclient.o log.o cache.o query.o \
     321load dnscache.o droproot.o okclient.o log.o cache.o query.o qmerge.o \
    322322response.o dd.o roots.o iopause.o prot.o dns.a env.a alloc.a buffer.a \
    323323libtai.a unix.a byte.a socket.lib
    324324        ./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 \
    326326        env.a alloc.a buffer.a libtai.a unix.a byte.a  `cat \
    327327        socket.lib`
    328328
    compile dnscache.c env.h exit.h scan.h strerr.h error.h ip4.h \ 
    343343uint16.h uint64.h socket.h uint16.h dns.h stralloc.h gen_alloc.h \
    344344iopause.h taia.h tai.h uint64.h taia.h taia.h byte.h roots.h fmt.h \
    345345iopause.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
     346uint32.h uint64.h ndelay.h log.h uint64.h okclient.h droproot.h maxclient.h
    347347        ./compile dnscache.c
    348348
    349349dnsfilter: \
    qlog.o: \ 
    687687compile qlog.c buffer.h qlog.h uint16.h
    688688        ./compile qlog.c
    689689
     690qmerge.o: \
     691compile qmerge.c qmerge.h dns.h stralloc.h gen_alloc.h iopause.h \
     692taia.h tai.h uint64.h log.h maxclient.h
     693        ./compile qmerge.c
     694
    690695query.o: \
    691696compile query.c error.h roots.h log.h uint64.h case.h cache.h \
    692697uint32.h uint64.h byte.h dns.h stralloc.h gen_alloc.h iopause.h \
    693698taia.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
     699response.h uint32.h query.h dns.h uint32.h qmerge.h
    695700        ./compile query.c
    696701
    697702random-ip: \
  • dnscache.c

    diff --git a/dnscache.c b/dnscache.c
    index 8c899a3..5ccb16a 100644
    a b  
    2222#include "log.h"
    2323#include "okclient.h"
    2424#include "droproot.h"
     25#include "maxclient.h"
    2526
    2627static int packetquery(char *buf,unsigned int len,char **q,char qtype[2],char qclass[2],char id[2])
    2728{
    uint64 numqueries = 0; 
    5455
    5556static int udp53;
    5657
    57 #define MAXUDP 200
    5858static struct udpclient {
    5959  struct query q;
    6060  struct taia start;
    void u_new(void) 
    131131
    132132static int tcp53;
    133133
    134 #define MAXTCP 20
    135134struct tcpclient {
    136135  struct query q;
    137136  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 
    150150  line();
    151151}
    152152
     153void 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
    153160void log_cachedanswer(const char *q,const char type[2])
    154161{
    155162  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 *); 
    1818extern void log_cachedns(const char *,const char *);
    1919
    2020extern void log_tx(const char *,const char *,const char *,const char *,unsigned int);
     21extern void log_tx_piggyback(const char *,const char *,const char *);
    2122
    2223extern void log_nxdomain(const char *,const char *,unsigned int);
    2324extern 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)
     7struct qmerge inprogress[QMERGE_MAX];
     8
     9static
     10int 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
     19static
     20int 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
     28static
     29void qmerge_key_free(struct qmerge_key *qmk)
     30{
     31  dns_domain_free(&qmk->q);
     32  dns_domain_free(&qmk->control);
     33}
     34
     35void 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
     50int 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
     88void 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
     100int 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
     6struct qmerge_key {
     7  char *q;
     8  char qtype[2];
     9  char *control;
     10};
     11
     12struct 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
     19extern int qmerge_start(struct qmerge **,const char *,int,const char *,const char *,const char *,const char *);
     20extern void qmerge_io(struct qmerge *,iopause_fd *,struct taia *);
     21extern int qmerge_get(struct qmerge **,const iopause_fd *,const struct taia *);
     22extern 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) 
    8181  int j;
    8282  int k;
    8383
    84   dns_transmit_free(&z->dt);
     84  qmerge_free(&z->qm);
    8585  for (j = 0;j < QUERY_MAXALIAS;++j)
    8686    dns_domain_free(&z->alias[j]);
    8787  for (j = 0;j < QUERY_MAXLEVEL;++j) {
    static int doit(struct query *z,int state) 
    429429  if (j == 64) goto SERVFAIL;
    430430
    431431  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;
    440434  return 0;
    441435
    442436
    static int doit(struct query *z,int state) 
    450444
    451445  HAVEPACKET:
    452446  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;
    455449
    456   whichserver = z->dt.servers + 4 * z->dt.curserver;
     450  whichserver = z->qm->dt.servers + 4 * z->qm->dt.curserver;
    457451  control = z->control[z->level];
    458452  d = z->name[z->level];
    459453  dtype = z->level ? DNS_T_A : z->type;
    int query_start(struct query *z,char *dn,char type[2],char class[2],char localip 
    836830
    837831int query_get(struct query *z,iopause_fd *x,struct taia *stamp)
    838832{
    839   switch(dns_transmit_get(&z->dt,x,stamp)) {
     833  switch(qmerge_get(&z->qm,x,stamp)) {
    840834    case 1:
    841835      return doit(z,1);
    842836    case -1:
    int query_get(struct query *z,iopause_fd *x,struct taia *stamp) 
    847841
    848842void query_io(struct query *z,iopause_fd *x,struct taia *deadline)
    849843{
    850   dns_transmit_io(&z->dt,x,deadline);
     844  qmerge_io(z->qm,x,deadline);
    851845}
  • query.h

    diff --git a/query.h b/query.h
    index eff68b2..06feab4 100644
    a b  
    11#ifndef QUERY_H
    22#define QUERY_H
    33
    4 #include "dns.h"
     4#include "qmerge.h"
    55#include "uint32.h"
    66
    77#define QUERY_MAXLEVEL 5
    struct query { 
    2020  char localip[4];
    2121  char type[2];
    2222  char class[2];
    23   struct dns_transmit dt;
     23  struct qmerge *qm;
    2424} ;
    2525
    2626extern int query_start(struct query *,char *,char *,char *,char *);
Note: See TracBrowser for help on using the repository browser.