From 0715ca5de14ad5eae2c779c536beee2ef56d07a2 Mon Sep 17 00:00:00 2001 From: "D. J. Bernstein" Date: Sun, 11 Feb 2001 13:11:45 -0800 Subject: [PATCH] import djbdns 1.05 --- CHANGES | 15 +++++++++++++++ Makefile | 7 ++++--- README | 4 ++-- VERSION | 2 +- axfrdns.c | 22 +++++++++++++++------- dnscache.c | 13 +++++++------ pickdns.c | 1 + query.c | 7 ++++--- query.h | 3 ++- rbldns.c | 1 + response.c | 4 ++-- response.h | 2 +- server.c | 7 +++++-- tinydns-get.c | 4 +++- tinydns.c | 1 + walldns.c | 1 + 16 files changed, 65 insertions(+), 29 deletions(-) diff --git a/CHANGES b/CHANGES index 738c7c4..2442a0c 100644 --- a/CHANGES +++ b/CHANGES @@ -359,3 +359,18 @@ ui: dnstrace uses a ``start'' IP address for the root glue. 20010121 version: djbdns 1.04. +20010206 + internal: response_query() takes a class argument. + internal: query_start() takes a class argument. + internal: packetquery() takes a class argument. + ui: tinydns et al., axfrdns, and dnscache repeat qclass * in + response to bogus * queries. tnx Mike Batchelor. + ui: axfrdns rejects queries for weird classes. + ui: axfrdns uses query ID instead of ID 0 in the series of AXFR + response messages between the SOAs, to support the AXFR + client in BIND 9. + ui: axfrdns sets AA in the series of AXFR response messages. +20010211 + ui: servers print starting message. + internal: some respond() declarations. + version: djbdns 1.05. diff --git a/Makefile b/Makefile index 6a9f026..1429643 100644 --- a/Makefile +++ b/Makefile @@ -771,9 +771,10 @@ choose compile trysysel.c select.h1 select.h2 ./choose c trysysel select.h1 select.h2 > select.h server.o: \ -compile server.c byte.h case.h env.h strerr.h ip4.h uint16.h ndelay.h \ -socket.h uint16.h droproot.h qlog.h uint16.h response.h uint32.h \ -dns.h stralloc.h gen_alloc.h iopause.h taia.h tai.h uint64.h taia.h +compile server.c byte.h case.h env.h buffer.h strerr.h ip4.h uint16.h \ +ndelay.h socket.h uint16.h droproot.h qlog.h uint16.h response.h \ +uint32.h dns.h stralloc.h gen_alloc.h iopause.h taia.h tai.h uint64.h \ +taia.h ./compile server.c setup: \ diff --git a/README b/README index 7f66f96..a9617eb 100644 --- a/README +++ b/README @@ -1,5 +1,5 @@ -djbdns 1.04 -20010121 +djbdns 1.05 +20010211 Copyright 2001 D. J. Bernstein diff --git a/VERSION b/VERSION index 0da8ebf..835d795 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -djbdns 1.04 +djbdns 1.05 diff --git a/axfrdns.c b/axfrdns.c index 410b534..7079850 100644 --- a/axfrdns.c +++ b/axfrdns.c @@ -22,6 +22,8 @@ #include "qlog.h" #include "response.h" +extern int respond(char *,char *,char *); + #define FATAL "axfrdns: fatal: " void nomem() @@ -144,7 +146,7 @@ void doname(stralloc *sa) if (!stralloc_catb(sa,d,dns_domain_length(d))) nomem(); } -int build(stralloc *sa,char *q,int flagsoa) +int build(stralloc *sa,char *q,int flagsoa,char id[2]) { unsigned int rdatapos; char misc[20]; @@ -159,7 +161,8 @@ int build(stralloc *sa,char *q,int flagsoa) if (flagsoa) if (byte_diff(type,2,DNS_T_SOA)) return 0; if (!flagsoa) if (byte_equal(type,2,DNS_T_SOA)) return 0; - if (!stralloc_copyb(sa,"\0\0\200\200\0\0\0\1\0\0\0\0",12)) nomem(); + if (!stralloc_copyb(sa,id,2)) nomem(); + if (!stralloc_catb(sa,"\204\000\0\0\0\1\0\0\0\0",10)) nomem(); copy(misc,1); if ((misc[0] == '=' + 1) || (misc[0] == '*' + 1)) { --misc[0]; @@ -217,7 +220,7 @@ static char *q; static stralloc soa; static stralloc message; -void doaxfr(void) +void doaxfr(char id[2]) { char key[512]; uint32 klen; @@ -252,7 +255,7 @@ void doaxfr(void) dlen = cdb_datalen(&c); if (dlen > sizeof data) die_cdbformat(); if (cdb_read(&c,data,dlen,cdb_datapos(&c)) == -1) die_cdbformat(); - if (build(&soa,zone,1)) break; + if (build(&soa,zone,1,id)) break; } cdb_free(&c); @@ -286,7 +289,7 @@ void doaxfr(void) if (klen < 1) die_cdbformat(); if (dns_packet_getname(key,klen,0,&q) != klen) die_cdbformat(); if (!dns_domain_suffix(q,zone)) continue; - if (!build(&message,q,0)) continue; + if (!build(&message,q,0,id)) continue; print(message.s,message.len); } @@ -316,6 +319,7 @@ int main() unsigned int pos; char header[12]; char qtype[2]; + char qclass[2]; const char *x; droproot(FATAL); @@ -346,6 +350,10 @@ int main() pos = dns_packet_getname(buf,len,pos,&zone); if (!pos) die_truncated(); zonelen = dns_domain_length(zone); pos = dns_packet_copy(buf,len,pos,qtype,2); if (!pos) die_truncated(); + pos = dns_packet_copy(buf,len,pos,qclass,2); if (!pos) die_truncated(); + + if (byte_diff(qclass,2,DNS_C_IN) && byte_diff(qclass,2,DNS_C_ANY)) + strerr_die2x(111,FATAL,"bogus query: bad class"); qlog(ip,port,header,zone,qtype," "); @@ -353,11 +361,11 @@ int main() case_lowerb(zone,zonelen); fdcdb = open_read("data.cdb"); if (fdcdb == -1) die_cdbread(); - doaxfr(); + doaxfr(header); close(fdcdb); } else { - if (!response_query(zone,qtype)) nomem(); + if (!response_query(zone,qtype,qclass)) nomem(); response[2] |= 4; case_lowerb(zone,zonelen); response_id(header); diff --git a/dnscache.c b/dnscache.c index 3f7c728..8c899a3 100644 --- a/dnscache.c +++ b/dnscache.c @@ -23,10 +23,9 @@ #include "okclient.h" #include "droproot.h" -static int packetquery(char *buf,unsigned int len,char **q,char qtype[2],char id[2]) +static int packetquery(char *buf,unsigned int len,char **q,char qtype[2],char qclass[2],char id[2]) { unsigned int pos; - char qclass[2]; char header[12]; errno = error_proto; @@ -92,6 +91,7 @@ void u_new(void) int len; static char *q = 0; char qtype[2]; + char qclass[2]; for (j = 0;j < MAXUDP;++j) if (!u[j].active) @@ -115,11 +115,11 @@ void u_new(void) if (x->port < 1024) if (x->port != 53) return; if (!okclient(x->ip)) return; - if (!packetquery(buf,len,&q,qtype,x->id)) return; + if (!packetquery(buf,len,&q,qtype,qclass,x->id)) return; x->active = ++numqueries; ++uactive; log_query(&x->active,x->ip,x->port,x->id,q,qtype); - switch(query_start(&x->q,q,qtype,myipoutgoing)) { + switch(query_start(&x->q,q,qtype,qclass,myipoutgoing)) { case -1: u_drop(j); return; @@ -210,6 +210,7 @@ void t_rw(int j) char ch; static char *q = 0; char qtype[2]; + char qclass[2]; int r; x = t + j; @@ -249,11 +250,11 @@ void t_rw(int j) x->buf[x->pos++] = ch; if (x->pos < x->len) return; - if (!packetquery(x->buf,x->len,&q,qtype,x->id)) { t_close(j); return; } + if (!packetquery(x->buf,x->len,&q,qtype,qclass,x->id)) { t_close(j); return; } x->active = ++numqueries; log_query(&x->active,x->ip,x->port,x->id,q,qtype); - switch(query_start(&x->q,q,qtype,myipoutgoing)) { + switch(query_start(&x->q,q,qtype,qclass,myipoutgoing)) { case -1: t_drop(j); return; diff --git a/pickdns.c b/pickdns.c index 86c7122..28c4ba5 100644 --- a/pickdns.c +++ b/pickdns.c @@ -7,6 +7,7 @@ #include "response.h" const char *fatal = "pickdns: fatal: "; +const char *starting = "starting pickdns\n"; static char seed[128]; diff --git a/query.c b/query.c index 4c61c85..46cdc00 100644 --- a/query.c +++ b/query.c @@ -97,7 +97,7 @@ static int rqa(struct query *z) for (i = QUERY_MAXALIAS - 1;i >= 0;--i) if (z->alias[i]) { - if (!response_query(z->alias[i],z->type)) return 0; + if (!response_query(z->alias[i],z->type,z->class)) return 0; while (i > 0) { if (!response_cname(z->alias[i],z->alias[i - 1],z->aliasttl[i])) return 0; --i; @@ -106,7 +106,7 @@ static int rqa(struct query *z) return 1; } - if (!response_query(z->name[0],z->type)) return 0; + if (!response_query(z->name[0],z->type,z->class)) return 0; return 1; } @@ -818,7 +818,7 @@ static int doit(struct query *z,int state) return -1; } -int query_start(struct query *z,char *dn,char type[2],char localip[4]) +int query_start(struct query *z,char *dn,char type[2],char class[2],char localip[4]) { if (byte_equal(type,2,DNS_T_AXFR)) { errno = error_perm; return -1; } @@ -828,6 +828,7 @@ int query_start(struct query *z,char *dn,char type[2],char localip[4]) if (!dns_domain_copy(&z->name[0],dn)) return -1; byte_copy(z->type,2,type); + byte_copy(z->class,2,class); byte_copy(z->localip,4,localip); return doit(z,0); diff --git a/query.h b/query.h index 339fa68..eff68b2 100644 --- a/query.h +++ b/query.h @@ -19,10 +19,11 @@ struct query { uint32 aliasttl[QUERY_MAXALIAS]; char localip[4]; char type[2]; + char class[2]; struct dns_transmit dt; } ; -extern int query_start(struct query *,char *,char *,char *); +extern int query_start(struct query *,char *,char *,char *,char *); extern void query_io(struct query *,iopause_fd *,struct taia *); extern int query_get(struct query *,iopause_fd *,struct taia *); diff --git a/rbldns.c b/rbldns.c index eff7076..2c13c27 100644 --- a/rbldns.c +++ b/rbldns.c @@ -102,6 +102,7 @@ int respond(char *q,char qtype[2],char ip[4]) } const char *fatal = "rbldns: fatal: "; +const char *starting = "starting rbldns\n"; void initialize(void) { diff --git a/response.c b/response.c index b421fdb..ba90c89 100644 --- a/response.c +++ b/response.c @@ -49,14 +49,14 @@ int response_addname(const char *d) return response_addbytes(d,1); } -int response_query(const char *q,const char qtype[2]) +int response_query(const char *q,const char qtype[2],const char qclass[2]) { response_len = 0; name_num = 0; if (!response_addbytes("\0\0\201\200\0\1\0\0\0\0\0\0",12)) return 0; if (!response_addname(q)) return 0; if (!response_addbytes(qtype,2)) return 0; - if (!response_addbytes(DNS_C_IN,2)) return 0; + if (!response_addbytes(qclass,2)) return 0; tctarget = response_len; return 1; } diff --git a/response.h b/response.h index 2557ddf..206b1d4 100644 --- a/response.h +++ b/response.h @@ -6,7 +6,7 @@ extern char response[]; extern unsigned int response_len; -extern int response_query(const char *,const char *); +extern int response_query(const char *,const char *,const char *); extern void response_nxdomain(void); extern void response_servfail(void); extern void response_id(const char *); diff --git a/server.c b/server.c index 677a1f1..e486fe1 100644 --- a/server.c +++ b/server.c @@ -1,6 +1,7 @@ #include "byte.h" #include "case.h" #include "env.h" +#include "buffer.h" #include "strerr.h" #include "ip4.h" #include "uint16.h" @@ -12,6 +13,7 @@ #include "dns.h" extern char *fatal; +extern char *starting; extern int respond(char *,char *,char *); extern void initialize(void); @@ -40,7 +42,7 @@ static int doit(void) pos = dns_packet_copy(buf,len,pos,qtype,2); if (!pos) goto NOQ; pos = dns_packet_copy(buf,len,pos,qclass,2); if (!pos) goto NOQ; - if (!response_query(q,qtype)) goto NOQ; + if (!response_query(q,qtype,qclass)) goto NOQ; response_id(header); if (byte_equal(qclass,2,DNS_C_IN)) response[2] |= 4; @@ -69,7 +71,6 @@ static int doit(void) WEIRDCLASS: response[3] &= ~15; response[3] |= 1; - byte_copy(response + response_len - 2,2,qclass); qlog(ip,port,header,q,qtype," C "); return 1; @@ -102,6 +103,8 @@ int main() ndelay_off(udp53); socket_tryreservein(udp53,65536); + buffer_putsflush(buffer_2,starting); + for (;;) { len = socket_recv4(udp53,buf,sizeof buf,ip,&port); if (len < 0) continue; diff --git a/tinydns-get.c b/tinydns-get.c index 734f42d..f7fd67f 100644 --- a/tinydns-get.c +++ b/tinydns-get.c @@ -13,6 +13,8 @@ #include "ip4.h" #include "dns.h" +extern int respond(char *,char *,char *); + #define FATAL "tinydns-get: fatal: " void usage(void) @@ -53,7 +55,7 @@ int main(int argc,char **argv) if (!dns_domain_todot_cat(&out,q)) oops(); if (!stralloc_cats(&out,":\n")) oops(); - if (!response_query(q,type)) oops(); + if (!response_query(q,type,DNS_C_IN)) oops(); response[3] &= ~128; response[2] &= ~1; response[2] |= 4; diff --git a/tinydns.c b/tinydns.c index c62d325..2a5b560 100644 --- a/tinydns.c +++ b/tinydns.c @@ -1,6 +1,7 @@ #include "dns.h" const char *fatal = "tinydns: fatal: "; +const char *starting = "starting tinydns\n"; static char seed[128]; diff --git a/walldns.c b/walldns.c index 507ea12..3cdaa72 100644 --- a/walldns.c +++ b/walldns.c @@ -4,6 +4,7 @@ #include "response.h" const char *fatal = "walldns: fatal: "; +const char *starting = "starting walldns\n"; void initialize(void) {