Downloaded from: http://lizzy.dyndns.org/~jos/djbdns-1.05-jumbo-josb.patch This patch combines the following patches: - Claudiu Costin's jumbo-p13.patch http://www.ro.kde.org/djbdns/mywork/jumbo/jumbo-p13.patch.gz - Guilherme Balena Versiani's djbdns SRV+NAPTR combined patch http://mywebpage.netscape.com/guibv/djbdns-1.05-srvnaptr.diff diff -ruN djbdns-1.05-dist/CHANGES djbdns-1.05/CHANGES --- djbdns-1.05-dist/CHANGES 2008-08-11 19:32:53.000000000 -0700 +++ djbdns-1.05/CHANGES 2008-08-11 19:33:30.000000000 -0700 @@ -374,3 +374,5 @@ ui: servers print starting message. internal: some respond() declarations. version: djbdns 1.05. +20010313 + patch: to dump and reload the cache diff -ruN djbdns-1.05-dist/Makefile djbdns-1.05/Makefile --- djbdns-1.05-dist/Makefile 2008-08-11 19:32:53.000000000 -0700 +++ djbdns-1.05/Makefile 2008-08-11 19:33:30.000000000 -0700 @@ -4,6 +4,8 @@ default: it +include Makefile.sig + alloc.a: \ makelib alloc.o alloc_re.o getln.o getln2.o stralloc_cat.o \ stralloc_catb.o stralloc_cats.o stralloc_copy.o stralloc_eady.o \ @@ -149,13 +151,13 @@ cache.o: \ compile cache.c alloc.h byte.h uint32.h exit.h tai.h uint64.h cache.h \ -uint32.h uint64.h +uint32.h uint64.h env.h error.h open.h openreadclose.h ./compile cache.c cachetest: \ -load cachetest.o cache.o libtai.a buffer.a alloc.a unix.a byte.a - ./load cachetest cache.o libtai.a buffer.a alloc.a unix.a \ - byte.a +load cachetest.o cache.o libtai.a buffer.a alloc.a unix.a byte.a env.a + ./load cachetest cache.o libtai.a buffer.a unix.a env.a \ + alloc.a byte.a dns.a cachetest.o: \ compile cachetest.c buffer.h exit.h cache.h uint32.h uint64.h str.h @@ -228,11 +230,11 @@ dns.a: \ makelib dns_dfd.o dns_domain.o dns_dtda.o dns_ip.o dns_ipq.o dns_mx.o \ dns_name.o dns_nd.o dns_packet.o dns_random.o dns_rcip.o dns_rcrw.o \ -dns_resolve.o dns_sortip.o dns_transmit.o dns_txt.o +dns_resolve.o dns_rotateip.o dns_sortip.o dns_transmit.o dns_txt.o ./makelib dns.a dns_dfd.o dns_domain.o dns_dtda.o dns_ip.o \ dns_ipq.o dns_mx.o dns_name.o dns_nd.o dns_packet.o \ dns_random.o dns_rcip.o dns_rcrw.o dns_resolve.o \ - dns_sortip.o dns_transmit.o dns_txt.o + dns_rotateip.o dns_sortip.o dns_transmit.o dns_txt.o dns_dfd.o: \ compile dns_dfd.c error.h alloc.h byte.h dns.h stralloc.h gen_alloc.h \ @@ -301,6 +303,10 @@ dns.h stralloc.h gen_alloc.h iopause.h taia.h ./compile dns_resolve.c +dns_rotateip.o: \ +compile dns_rotateip.c byte.h dns.h stralloc.h gen_alloc.h + ./compile dns_rotateip.c + dns_sortip.o: \ compile dns_sortip.c byte.h dns.h stralloc.h gen_alloc.h iopause.h \ taia.h tai.h uint64.h taia.h @@ -320,10 +326,10 @@ dnscache: \ load dnscache.o droproot.o okclient.o log.o cache.o query.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 +libtai.a unix.a byte.a sig.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 \ - env.a alloc.a buffer.a libtai.a unix.a byte.a `cat \ + env.a alloc.a buffer.a libtai.a unix.a byte.a sig.a `cat \ socket.lib` dnscache-conf: \ @@ -626,9 +632,9 @@ ./compile parsetype.c pickdns: \ -load pickdns.o server.o response.o droproot.o qlog.o prot.o dns.a \ +load pickdns.o server.o iopause.o response.o droproot.o qlog.o prot.o dns.a \ env.a libtai.a cdb.a alloc.a buffer.a unix.a byte.a socket.lib - ./load pickdns server.o response.o droproot.o qlog.o \ + ./load pickdns server.o iopause.o response.o droproot.o qlog.o \ prot.o dns.a env.a libtai.a cdb.a alloc.a buffer.a unix.a \ byte.a `cat socket.lib` @@ -704,9 +710,9 @@ ./compile random-ip.c rbldns: \ -load rbldns.o server.o response.o dd.o droproot.o qlog.o prot.o dns.a \ +load rbldns.o server.o iopause.o response.o dd.o droproot.o qlog.o prot.o dns.a \ env.a libtai.a cdb.a alloc.a buffer.a unix.a byte.a socket.lib - ./load rbldns server.o response.o dd.o droproot.o qlog.o \ + ./load rbldns server.o iopause.o response.o dd.o droproot.o qlog.o \ prot.o dns.a env.a libtai.a cdb.a alloc.a buffer.a unix.a \ byte.a `cat socket.lib` @@ -774,7 +780,7 @@ 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 +taia.h iopause.h alloc.h ./compile server.c setup: \ @@ -979,10 +985,10 @@ ./compile timeoutwrite.c tinydns: \ -load tinydns.o server.o droproot.o tdlookup.o response.o qlog.o \ +load tinydns.o server.o iopause.o droproot.o tdlookup.o response.o qlog.o \ prot.o dns.a libtai.a env.a cdb.a alloc.a buffer.a unix.a byte.a \ socket.lib - ./load tinydns server.o droproot.o tdlookup.o response.o \ + ./load tinydns server.o iopause.o droproot.o tdlookup.o response.o \ qlog.o prot.o dns.a libtai.a env.a cdb.a alloc.a buffer.a \ unix.a byte.a `cat socket.lib` @@ -1084,10 +1090,10 @@ ./compile utime.c walldns: \ -load walldns.o server.o response.o droproot.o qlog.o prot.o dd.o \ +load walldns.o server.o iopause.o response.o droproot.o qlog.o prot.o dd.o \ dns.a env.a cdb.a alloc.a buffer.a unix.a byte.a socket.lib - ./load walldns server.o response.o droproot.o qlog.o \ - prot.o dd.o dns.a env.a cdb.a alloc.a buffer.a unix.a \ + ./load walldns server.o iopause.o response.o droproot.o qlog.o \ + prot.o dd.o dns.a libtai.a env.a cdb.a alloc.a buffer.a unix.a \ byte.a `cat socket.lib` walldns-conf: \ diff -ruN djbdns-1.05-dist/Makefile.sig djbdns-1.05/Makefile.sig --- djbdns-1.05-dist/Makefile.sig 1969-12-31 16:00:00.000000000 -0800 +++ djbdns-1.05/Makefile.sig 2008-08-11 19:33:30.000000000 -0700 @@ -0,0 +1,27 @@ +sig.o: \ +compile sig.c sig.h + ./compile sig.c + +sig_block.o: \ +compile sig_block.c sig.h hassgprm.h + ./compile sig_block.c + +sig_catch.o: \ +compile sig_catch.c sig.h hassgact.h + ./compile sig_catch.c + +sig_pause.o: \ +compile sig_pause.c sig.h hassgprm.h + ./compile sig_pause.c + +sig.a: \ +makelib sig.o sig_block.o sig_catch.o sig_pause.o + ./makelib sig.a sig.o sig_block.o sig_catch.o sig_pause.o + +hassgact.h: \ +choose compile load trysgact.c hassgact.h1 hassgact.h2 + ./choose cl trysgact hassgact.h1 hassgact.h2 > hassgact.h + +hassgprm.h: \ +choose compile load trysgprm.c hassgprm.h1 hassgprm.h2 + ./choose cl trysgprm hassgprm.h1 hassgprm.h2 > hassgprm.h diff -ruN djbdns-1.05-dist/README djbdns-1.05/README --- djbdns-1.05-dist/README 2008-08-11 19:32:53.000000000 -0700 +++ djbdns-1.05/README 2008-08-11 19:33:30.000000000 -0700 @@ -1,3 +1,9 @@ +patchlevel fg1 +20010313 +by Florent Guillaume +patch home page: http://mapage.noos.fr/efgeor/djbdns/index.html +Uses parts of Felix von Leitner's djb-0.5.2 package: http://www.fefe.de/djb/ + djbdns 1.05 20010211 Copyright 2001 diff -ruN djbdns-1.05-dist/SYSDEPS djbdns-1.05/SYSDEPS --- djbdns-1.05-dist/SYSDEPS 2008-08-11 19:32:53.000000000 -0700 +++ djbdns-1.05/SYSDEPS 2008-08-11 19:33:30.000000000 -0700 @@ -7,4 +7,6 @@ direntry.h hasshsgr.h hasdevtcp.h +hassgact.h +hassgprm.h socket.lib diff -ruN djbdns-1.05-dist/TARGETS djbdns-1.05/TARGETS --- djbdns-1.05-dist/TARGETS 2008-08-11 19:32:53.000000000 -0700 +++ djbdns-1.05/TARGETS 2008-08-11 19:33:30.000000000 -0700 @@ -214,3 +214,10 @@ it setup check +sig.o +sig.a +sig_catch.o +sig_block.o +hassgact.h +hassgprm.h +sig_pause.o diff -ruN djbdns-1.05-dist/VERSION djbdns-1.05/VERSION --- djbdns-1.05-dist/VERSION 2008-08-11 19:32:53.000000000 -0700 +++ djbdns-1.05/VERSION 2008-08-11 19:33:30.000000000 -0700 @@ -1 +1 @@ -djbdns 1.05 +djbdns 1.05-fg1 diff -ruN djbdns-1.05-dist/auto_home.c djbdns-1.05/auto_home.c --- djbdns-1.05-dist/auto_home.c 1969-12-31 16:00:00.000000000 -0800 +++ djbdns-1.05/auto_home.c 2008-08-12 09:17:21.000000000 -0700 @@ -0,0 +1,3 @@ +const char auto_home[] = "\ +\057\165\163\162\057\154\157\143\141\154\ +"; diff -ruN djbdns-1.05-dist/axfr-get.c djbdns-1.05/axfr-get.c --- djbdns-1.05-dist/axfr-get.c 2008-08-11 19:32:53.000000000 -0700 +++ djbdns-1.05/axfr-get.c 2008-08-11 22:49:05.000000000 -0700 @@ -209,6 +209,57 @@ if (!stralloc_cats(&line,".:")) return 0; if (!stralloc_catulong0(&line,dist,0)) return 0; } + else if (byte_equal(data,2,DNS_T_SRV)) { + uint16 priority, weight, port; + if (!stralloc_copys(&line,"S")) return 0; + if (!dns_domain_todot_cat(&line,d1)) return 0; + if (!stralloc_cats(&line,"::")) return 0; + pos = x_copy(buf,len,pos,data,2); + uint16_unpack_big(data,&priority); + pos = x_copy(buf,len,pos,data,2); + uint16_unpack_big(data,&weight); + pos = x_copy(buf,len,pos,data,2); + uint16_unpack_big(data,&port); + x_getname(buf,len,pos,&d1); + if (!dns_domain_todot_cat(&line,d1)) return 0; + if (!stralloc_cats(&line,".:")) return 0; + if (!stralloc_catulong0(&line,port,0)) return 0; + if (!stralloc_cats(&line,":")) return 0; + if (!stralloc_catulong0(&line,priority,0)) return 0; + if (!stralloc_cats(&line,":")) return 0; + if (!stralloc_catulong0(&line,weight,0)) return 0; + } + else if (byte_equal(data,2,DNS_T_NAPTR)) { + uint16 order, preference; + char flags[255], service[255], regexp[255]; + char fs, ss, rs; + if (!stralloc_copys(&line,"N")) return 0; + if (!dns_domain_todot_cat(&line,d1)) return 0; + if (!stralloc_cats(&line,":")) return 0; + pos = x_copy(buf,len,pos,data,2); + uint16_unpack_big(data,&order); + pos = x_copy(buf,len,pos,data,2); + uint16_unpack_big(data,&preference); + pos = x_copy(buf,len,pos,&fs,1); + pos = x_copy(buf,len,pos,flags,fs); + pos = x_copy(buf,len,pos,&ss,1); + pos = x_copy(buf,len,pos,service,ss); + pos = x_copy(buf,len,pos,&rs,1); + pos = x_copy(buf,len,pos,regexp,rs); + x_getname(buf,len,pos,&d1); + if (!stralloc_catulong0(&line,order,0)) return 0; + if (!stralloc_cats(&line,":")) return 0; + if (!stralloc_catulong0(&line,preference,0)) return 0; + if (!stralloc_cats(&line,":")) return 0; + if (!stralloc_catb(&line,flags,fs)) return 0; + if (!stralloc_cats(&line,":")) return 0; + if (!stralloc_catb(&line,service,ss)) return 0; + if (!stralloc_cats(&line,":")) return 0; + if (!stralloc_catb(&line,regexp,rs)) return 0; + if (!stralloc_cats(&line,":")) return 0; + if (!dns_domain_todot_cat(&line,d1)) return 0; + if (!stralloc_cats(&line,".")) return 0; + } else if (byte_equal(data,2,DNS_T_A) && (dlen == 4)) { char ipstr[IP4_FMT]; if (!stralloc_copys(&line,"+")) return 0; @@ -217,6 +268,14 @@ x_copy(buf,len,pos,data,4); if (!stralloc_catb(&line,ipstr,ip4_fmt(ipstr,data))) return 0; } + else if (byte_equal(data,2,DNS_T_PTR)) { + if (!stralloc_copys(&line,"^")) return 0; + if (!dns_domain_todot_cat(&line,d1)) return 0; + if (!stralloc_cats(&line,":")) return 0; + x_getname(buf,len,pos,&d1); + if (!dns_domain_todot_cat(&line,d1)) return 0; + if (!stralloc_cats(&line,".")) return 0; + } else { unsigned char ch; unsigned char ch2; diff -ruN djbdns-1.05-dist/cache.c djbdns-1.05/cache.c --- djbdns-1.05-dist/cache.c 2008-08-11 19:32:53.000000000 -0700 +++ djbdns-1.05/cache.c 2008-08-11 19:33:30.000000000 -0700 @@ -1,12 +1,23 @@ +#ifdef DUMPCACHE +#include +#include +#include "env.h" +#include "error.h" +#include "open.h" +#include "openreadclose.h" +#endif #include "alloc.h" #include "byte.h" #include "uint32.h" #include "exit.h" #include "tai.h" #include "cache.h" +#include "dns.h" +#include "buffer.h" uint64 cache_motion = 0; +static char *rrobin; static char *x = 0; static uint32 size; static uint32 hsize; @@ -87,6 +98,12 @@ uint32 u; unsigned int loop; double d; + static int trigger=0; + + if (!trigger) { + rrobin = env_get("ROUNDROBIN"); + trigger++; + } if (!x) return 0; if (keylen > MAXKEYLEN) return 0; @@ -111,7 +128,11 @@ u = get4(pos + 8); if (u > size - pos - 20 - keylen) cache_impossible(); *datalen = u; - + if (byte_equal(key,2,DNS_T_A)) { + if (rrobin) { + dns_rotateip(x + pos + 20 + keylen,u); + } + } return x + pos + 20 + keylen; } } @@ -205,3 +226,97 @@ return 1; } + +#ifdef DUMPCACHE +static int fd; + +static int cache_writeline(const char *buf, unsigned int len) +{ + int w; + + while (len) { + w = write(fd,buf,len); + if (w == -1) { + if (errno == error_intr) continue; + close(fd); + return -1; + } + buf += w; + len -= w; + } + return 0; +} + +int cache_dump(void) +{ + static char *fn; + static char *fntmp; + uint32 pos; + unsigned int len; + + fn = env_get("DUMPCACHE"); + if (!fn) return 999; + fntmp = env_get("DUMPCACHETMP"); + if (!fntmp) return 999; + fd = open_trunc(fntmp); + if (fd == -1) return -1; + + pos = oldest; + while (pos < unused) { + len = get4(pos + 4) + get4(pos + 8) + 16; + if (cache_writeline(x + pos + 4, len)) return -1; + pos += 4 + len; + } + pos = hsize; + while (pos < writer) { + len = get4(pos + 4) + get4(pos + 8) + 16; + if (cache_writeline(x + pos + 4, len)) return -1; + pos += 4 + len; + } + + if (fsync(fd) == -1) return -1; + if (close(fd) == -1) return -1; + if (rename(fntmp,fn) == -1) return -1; + return 0; +} + +int cache_slurp(const char *fn) +{ + static stralloc buf = {0}; + char *p; + uint32 pos; + unsigned int len; + uint32 keylen; + uint32 datalen; + struct tai now; + struct tai expire; + int nb; + + if (openreadclose(fn,&buf,16384) != 1) goto DIE; + tai_now(&now); + p = buf.s; + pos = 0; + len = buf.len; + nb = 0; + while (pos + 16 <= len) { + uint32_unpack(p + pos, &keylen); + uint32_unpack(p + pos + 4, &datalen); + tai_unpack(p + pos + 8, &expire); + pos += 16; + if (pos + keylen + datalen > len) break; /* missing data */ + if (!tai_less(&expire,&now)) { + tai_sub(&expire,&expire,&now); + cache_set(p + pos, keylen, p + pos + keylen, datalen, (unsigned int)expire.x); + } + pos += keylen + datalen; + nb++; + } + alloc_free(buf.s); buf.s = 0; + return nb; + + DIE: + alloc_free(buf.s); buf.s = 0; + if (errno == error_noent) return 0; + return -1; +} +#endif diff -ruN djbdns-1.05-dist/cache.h djbdns-1.05/cache.h --- djbdns-1.05-dist/cache.h 2008-08-11 19:32:53.000000000 -0700 +++ djbdns-1.05/cache.h 2008-08-11 19:33:30.000000000 -0700 @@ -8,5 +8,9 @@ extern int cache_init(unsigned int); extern void cache_set(const char *,unsigned int,const char *,unsigned int,uint32); extern char *cache_get(const char *,unsigned int,unsigned int *,uint32 *); +#ifdef DUMPCACHE +extern int cache_dump(void); +extern int cache_slurp(const char *); +#endif #endif diff -ruN djbdns-1.05-dist/chkshsgr.c djbdns-1.05/chkshsgr.c --- djbdns-1.05-dist/chkshsgr.c 2008-08-11 19:32:53.000000000 -0700 +++ djbdns-1.05/chkshsgr.c 2008-08-11 19:33:30.000000000 -0700 @@ -1,4 +1,6 @@ #include "exit.h" +#include +#include int main() { diff -ruN djbdns-1.05-dist/direntry.h djbdns-1.05/direntry.h --- djbdns-1.05-dist/direntry.h 1969-12-31 16:00:00.000000000 -0800 +++ djbdns-1.05/direntry.h 2008-08-11 22:55:14.000000000 -0700 @@ -0,0 +1,10 @@ +#ifndef DIRENTRY_H +#define DIRENTRY_H + +/* sysdep: +dirent */ + +#include +#include +#define direntry struct dirent + +#endif diff -ruN djbdns-1.05-dist/dns.h djbdns-1.05/dns.h --- djbdns-1.05-dist/dns.h 2008-08-11 19:32:53.000000000 -0700 +++ djbdns-1.05/dns.h 2008-08-11 22:49:25.000000000 -0700 @@ -20,6 +20,8 @@ #define DNS_T_SIG "\0\30" #define DNS_T_KEY "\0\31" #define DNS_T_AAAA "\0\34" +#define DNS_T_SRV "\0\41" +#define DNS_T_NAPTR "\0\43" #define DNS_T_AXFR "\0\374" #define DNS_T_ANY "\0\377" @@ -43,6 +45,7 @@ extern unsigned int dns_random(unsigned int); extern void dns_sortip(char *,unsigned int); +extern void dns_rotateip(char *,unsigned int); extern void dns_domain_free(char **); extern int dns_domain_copy(char **,const char *); diff -ruN djbdns-1.05-dist/dns_rotateip.c djbdns-1.05/dns_rotateip.c --- djbdns-1.05-dist/dns_rotateip.c 1969-12-31 16:00:00.000000000 -0800 +++ djbdns-1.05/dns_rotateip.c 2008-08-11 19:33:30.000000000 -0700 @@ -0,0 +1,15 @@ +#include "byte.h" + +void dns_rotateip(char *s, unsigned int n) +{ + unsigned int i; + char tmp[4]; + + i = n >> 2; + while (i > 1) { + --i; + byte_copy(tmp,4,s + (i << 2)); + byte_copy(s + (i << 2),4,s); + byte_copy(s,4,tmp); + } +} diff -ruN djbdns-1.05-dist/dnscache-conf.c djbdns-1.05/dnscache-conf.c --- djbdns-1.05-dist/dnscache-conf.c 2008-08-11 19:32:53.000000000 -0700 +++ djbdns-1.05/dnscache-conf.c 2008-08-11 19:33:30.000000000 -0700 @@ -32,6 +32,10 @@ char *user; char *loguser; struct passwd *pw; +#ifdef DUMPCACHE +int useruid; +int usergid; +#endif const char *myip; uint32 seed[32]; @@ -81,6 +85,14 @@ myip = argv[4]; if (!myip) myip = "127.0.0.1"; +#ifdef DUMPCACHE + pw = getpwnam(user); + seed_addtime(); + if (!pw) + strerr_die3x(111,FATAL,"unknown account ",user); + useruid = pw->pw_uid; + usergid = pw->pw_gid; +#endif pw = getpwnam(loguser); seed_addtime(); if (!pw) @@ -120,6 +132,14 @@ seed_addtime(); perm(0644); seed_addtime(); start("env/DATALIMIT"); outs("3000000\n"); finish(); seed_addtime(); perm(0644); +#ifdef DUMPCACHE + seed_addtime(); start("env/SLURPCACHE"); outs("dump/slurpcache\n"); finish(); + seed_addtime(); perm(0644); + seed_addtime(); start("env/DUMPCACHE"); outs("dump/dumpcache\n"); finish(); + seed_addtime(); perm(0644); + seed_addtime(); start("env/DUMPCACHETMP"); outs("dump/dumpcache.tmp\n"); finish(); + seed_addtime(); perm(0644); +#endif seed_addtime(); start("run"); outs("#!/bin/sh\nexec 2>&1\nexec 512) response_tc(); - socket_send4(udp53,response,response_len,u[j].ip,u[j].port); + socket_send4(u[j].fd,response,response_len,u[j].ip,u[j].port); log_querydone(&u[j].active,response_len); u[j].active = 0; --uactive; } -void u_new(void) +void u_new(int fd) { int j; int i; @@ -108,8 +119,9 @@ x = u + j; taia_now(&x->start); + x->fd = fd; - len = socket_recv4(udp53,buf,sizeof buf,x->ip,&x->port); + len = socket_recv4(x->fd,buf,sizeof buf,x->ip,&x->port); if (len == -1) return; if (len >= sizeof buf) return; if (x->port < 1024) if (x->port != 53) return; @@ -129,8 +141,6 @@ } -static int tcp53; - #define MAXTCP 20 struct tcpclient { struct query q; @@ -138,6 +148,7 @@ struct taia timeout; uint64 active; /* query number or 1, if active; otherwise 0 */ iopause_fd *io; + int fd; char ip[4]; /* send response to this address */ uint16 port; /* send response to this port */ char id[2]; @@ -266,7 +277,7 @@ x->state = 0; } -void t_new(void) +void t_new(int fd) { int i; int j; @@ -290,8 +301,9 @@ x = t + j; taia_now(&x->start); + x->fd = fd; - x->tcp = socket_accept4(tcp53,x->ip,&x->port); + x->tcp = socket_accept4(x->fd,x->ip,&x->port); if (x->tcp == -1) return; if (x->port < 1024) if (x->port != 53) { close(x->tcp); return; } if (!okclient(x->ip)) { close(x->tcp); return; } @@ -304,19 +316,44 @@ log_tcpopen(x->ip,x->port); } +#ifdef DUMPCACHE +static void do_dump(void) +{ + int r; + r = cache_dump(); + if (r < 0) + r = errno; + log_dump(r); +} +#endif + +#define FATAL "dnscache: fatal: " + +iopause_fd *io = 0; +int numio; + +void hup_me() +{ + if (!roots_init()) + strerr_die2sys(111,FATAL,"unable to read servers: "); + + log_reread(); +} -iopause_fd io[3 + MAXUDP + MAXTCP]; -iopause_fd *udp53io; -iopause_fd *tcp53io; static void doit(void) { int j; struct taia deadline; struct taia stamp; + struct interf *inter; int iolen; int r; + io = (iopause_fd *) alloc((numio + 1 + MAXUDP + MAXTCP) * sizeof(iopause_fd)); + if (!io) + strerr_die2sys(111,FATAL,"unable to alloc io: "); + for (;;) { taia_now(&stamp); taia_uint(&deadline,120); @@ -324,13 +361,15 @@ iolen = 0; - udp53io = io + iolen++; - udp53io->fd = udp53; - udp53io->events = IOPAUSE_READ; - - tcp53io = io + iolen++; - tcp53io->fd = tcp53; - tcp53io->events = IOPAUSE_READ; + for (inter = interhead; inter != 0; inter = inter->next) { + inter->udp53io = io + iolen++; + inter->udp53io->fd = inter->udp53; + inter->udp53io->events = IOPAUSE_READ; + + inter->tcp53io = io + iolen++; + inter->tcp53io->fd = inter->tcp53; + inter->tcp53io->events = IOPAUSE_READ; + } for (j = 0;j < MAXUDP;++j) if (u[j].active) { @@ -372,46 +411,83 @@ t_rw(j); } - if (udp53io) - if (udp53io->revents) - u_new(); - - if (tcp53io) - if (tcp53io->revents) - t_new(); + for (inter = interhead; inter != 0; inter = inter->next) { + if (inter->udp53io) + if (inter->udp53io->revents) + u_new(inter->udp53); + + if (inter->tcp53io) + if (inter->tcp53io->revents) + t_new(inter->tcp53); + } } } -#define FATAL "dnscache: fatal: " - char seed[128]; int main() { char *x; + char nxdip[4]; + int len; + int pos; + int oldpos; + char iptmp[4]; + char iperr[IP4_FMT]; + struct interf *inter; + struct interf *itmp; unsigned long cachesize; x = env_get("IP"); if (!x) strerr_die2x(111,FATAL,"$IP not set"); - if (!ip4_scan(x,myipincoming)) - strerr_die3x(111,FATAL,"unable to parse IP address ",x); - udp53 = socket_udp(); - if (udp53 == -1) - strerr_die2sys(111,FATAL,"unable to create UDP socket: "); - if (socket_bind4_reuse(udp53,myipincoming,53) == -1) - strerr_die2sys(111,FATAL,"unable to bind UDP socket: "); - - tcp53 = socket_tcp(); - if (tcp53 == -1) - strerr_die2sys(111,FATAL,"unable to create TCP socket: "); - if (socket_bind4_reuse(tcp53,myipincoming,53) == -1) - strerr_die2sys(111,FATAL,"unable to bind TCP socket: "); + len = str_len(x); + numio = pos = oldpos = 0; + + while (pos < len) { + if (pos) oldpos = pos + 1; + pos = oldpos + str_chr(x + oldpos,'/'); + x[pos] = 0; + if (!str_len(x + oldpos)) continue; + + if (!ip4_scan(x + oldpos,iptmp)) + strerr_die3x(111,FATAL,"unable to parse IP address ",x + oldpos); + + inter = (struct interf *) alloc(sizeof(struct interf)); + + if (interhead == 0) interhead = inter; + else if (interhead->next == 0) interhead->next = inter; + else { + for (itmp = interhead; itmp->next != 0; itmp = itmp->next); + itmp->next = inter; + } + + inter->next = 0; + + inter->udp53 = socket_udp(); + if (inter->udp53 == -1) + strerr_die4sys(111,FATAL,"unable to create UDP socket for IP address ",x + oldpos,": "); + if (socket_bind4_reuse(inter->udp53,iptmp,53) == -1) + strerr_die4sys(111,FATAL,"unable to bind UDP socket for IP address ",x + oldpos,": "); + + inter->tcp53 = socket_tcp(); + if (inter->tcp53 == -1) + strerr_die4sys(111,FATAL,"unable to create TCP socket for IP address ",x + oldpos,": "); + if (socket_bind4_reuse(inter->tcp53,iptmp,53) == -1) + strerr_die4sys(111,FATAL,"unable to bind TCP socket for IP address ",x + oldpos,": "); + + numio++; + log_listen(iptmp); + } + + if (interhead == 0) + strerr_die2x(111,FATAL,"no interfaces to listen on"); droproot(FATAL); - socket_tryreservein(udp53,131072); + for (inter = interhead; inter != 0; inter = inter->next) + socket_tryreservein(inter->udp53,131072); byte_zero(seed,sizeof seed); read(0,seed,sizeof seed); @@ -430,17 +506,42 @@ scan_ulong(x,&cachesize); if (!cache_init(cachesize)) strerr_die3x(111,FATAL,"not enough memory for cache of size ",x); +#ifdef DUMPCACHE + x = env_get("SLURPCACHE"); + if (x) { + int nb = cache_slurp(x); + if (nb < 0) + strerr_die4sys(111,FATAL,"unable to slurp cache ",x," : "); + else + log_slurp(nb); + } +#endif if (env_get("HIDETTL")) response_hidettl(); if (env_get("FORWARDONLY")) query_forwardonly(); + x = env_get("NXDSPECIAL"); + if (x) { + if (!ip4_scan(x,nxdip)) + strerr_die3x(111,FATAL,"unable to parse NXDSPECIAL IP address ",x); + query_nxdspecial(nxdip); + } + if (!roots_init()) strerr_die2sys(111,FATAL,"unable to read servers: "); - if (socket_listen(tcp53,20) == -1) - strerr_die2sys(111,FATAL,"unable to listen on TCP socket: "); + for (inter = interhead; inter != 0; inter = inter->next) + if (socket_listen(inter->tcp53,20) == -1) { + iperr[ip4_fmt(iperr,inter->ip)] = 0; + strerr_die4sys(111,FATAL,"unable to listen on TCP socket for IP ",iperr,": "); + } + +#ifdef DUMPCACHE + sig_catch(sig_alarm,do_dump); +#endif + sig_catch(sig_hangup, hup_me); log_startup(); doit(); diff -ruN djbdns-1.05-dist/dnsfilter.c djbdns-1.05/dnsfilter.c --- djbdns-1.05-dist/dnsfilter.c 2008-08-11 19:32:53.000000000 -0700 +++ djbdns-1.05/dnsfilter.c 2008-08-11 19:33:30.000000000 -0700 @@ -41,6 +41,7 @@ iopause_fd *inio; int flag0 = 1; +int opt_replace = 0; iopause_fd *io; int iolen; @@ -51,12 +52,16 @@ void errout(int i) { int j; - - if (!stralloc_copys(&x[i].middle,":")) nomem(); - if (!stralloc_cats(&x[i].middle,error_str(errno))) nomem(); - for (j = 0;j < x[i].middle.len;++j) - if (x[i].middle.s[j] == ' ') - x[i].middle.s[j] = '-'; + + if (opt_replace) + x[i].middle.len=0; + else { + if (!stralloc_copys(&x[i].middle,":")) nomem(); + if (!stralloc_cats(&x[i].middle,error_str(errno))) nomem(); + for (j = 0;j < x[i].middle.len;++j) + if (x[i].middle.s[j] == ' ') + x[i].middle.s[j] = '-'; + } } int main(int argc,char **argv) @@ -69,7 +74,7 @@ int j; int r; - while ((opt = getopt(argc,argv,"c:l:")) != opteof) + while ((opt = getopt(argc,argv,"c:l:r")) != opteof) switch(opt) { case 'c': scan_ulong(optarg,&u); @@ -83,8 +88,11 @@ if (u > 1000000) u = 1000000; xmax = u; break; + case 'r': + opt_replace = 1; + break; default: - strerr_die1x(111,"dnsfilter: usage: dnsfilter [ -c concurrency ] [ -l lines ]"); + strerr_die1x(111,"dnsfilter: usage: dnsfilter [ -c concurrency ] [ -l lines ] [-r]"); } x = (struct line *) alloc(xmax * sizeof(struct line)); @@ -140,8 +148,13 @@ else if (r == 1) { if (dns_name_packet(&x[i].middle,x[i].dt.packet,x[i].dt.packetlen) == -1) errout(i); - if (x[i].middle.len) - if (!stralloc_cats(&x[i].left,"=")) nomem(); + if (x[i].middle.len) { + if (opt_replace) { + if (!stralloc_copys(&x[i].left, "")) nomem(); + } else { + if (!stralloc_cats(&x[i].left, "=")) nomem(); + } + } x[i].flagactive = 0; --numactive; } diff -ruN djbdns-1.05-dist/hasdevtcp.h djbdns-1.05/hasdevtcp.h --- djbdns-1.05-dist/hasdevtcp.h 1969-12-31 16:00:00.000000000 -0800 +++ djbdns-1.05/hasdevtcp.h 2008-08-11 22:55:09.000000000 -0700 @@ -0,0 +1 @@ +/* sysdep: -devtcp */ diff -ruN djbdns-1.05-dist/hassgact.h djbdns-1.05/hassgact.h --- djbdns-1.05-dist/hassgact.h 1969-12-31 16:00:00.000000000 -0800 +++ djbdns-1.05/hassgact.h 2008-08-11 22:55:16.000000000 -0700 @@ -0,0 +1,2 @@ +/* sysdep: +sigaction */ +#define HASSIGACTION 1 diff -ruN djbdns-1.05-dist/hassgact.h1 djbdns-1.05/hassgact.h1 --- djbdns-1.05-dist/hassgact.h1 1969-12-31 16:00:00.000000000 -0800 +++ djbdns-1.05/hassgact.h1 2008-08-11 19:33:30.000000000 -0700 @@ -0,0 +1 @@ +/* sysdep: -sigaction */ diff -ruN djbdns-1.05-dist/hassgact.h2 djbdns-1.05/hassgact.h2 --- djbdns-1.05-dist/hassgact.h2 1969-12-31 16:00:00.000000000 -0800 +++ djbdns-1.05/hassgact.h2 2008-08-11 19:33:30.000000000 -0700 @@ -0,0 +1,2 @@ +/* sysdep: +sigaction */ +#define HASSIGACTION 1 diff -ruN djbdns-1.05-dist/hassgprm.h djbdns-1.05/hassgprm.h --- djbdns-1.05-dist/hassgprm.h 1969-12-31 16:00:00.000000000 -0800 +++ djbdns-1.05/hassgprm.h 2008-08-11 22:55:15.000000000 -0700 @@ -0,0 +1,2 @@ +/* sysdep: +sigprocmask */ +#define HASSIGPROCMASK 1 diff -ruN djbdns-1.05-dist/hassgprm.h1 djbdns-1.05/hassgprm.h1 --- djbdns-1.05-dist/hassgprm.h1 1969-12-31 16:00:00.000000000 -0800 +++ djbdns-1.05/hassgprm.h1 2008-08-11 19:33:30.000000000 -0700 @@ -0,0 +1 @@ +/* sysdep: -sigprocmask */ diff -ruN djbdns-1.05-dist/hassgprm.h2 djbdns-1.05/hassgprm.h2 --- djbdns-1.05-dist/hassgprm.h2 1969-12-31 16:00:00.000000000 -0800 +++ djbdns-1.05/hassgprm.h2 2008-08-11 19:33:30.000000000 -0700 @@ -0,0 +1,2 @@ +/* sysdep: +sigprocmask */ +#define HASSIGPROCMASK 1 diff -ruN djbdns-1.05-dist/hasshsgr.h djbdns-1.05/hasshsgr.h --- djbdns-1.05-dist/hasshsgr.h 1969-12-31 16:00:00.000000000 -0800 +++ djbdns-1.05/hasshsgr.h 2008-08-12 09:17:24.000000000 -0700 @@ -0,0 +1 @@ +/* sysdep: -shortsetgroups */ diff -ruN djbdns-1.05-dist/iopause.h djbdns-1.05/iopause.h --- djbdns-1.05-dist/iopause.h 1969-12-31 16:00:00.000000000 -0800 +++ djbdns-1.05/iopause.h 2008-08-11 22:55:12.000000000 -0700 @@ -0,0 +1,18 @@ +#ifndef IOPAUSE_H +#define IOPAUSE_H + +/* sysdep: +poll */ +#define IOPAUSE_POLL + +#include +#include + +typedef struct pollfd iopause_fd; +#define IOPAUSE_READ POLLIN +#define IOPAUSE_WRITE POLLOUT + +#include "taia.h" + +extern void iopause(iopause_fd *,unsigned int,struct taia *,struct taia *); + +#endif diff -ruN djbdns-1.05-dist/log.c djbdns-1.05/log.c --- djbdns-1.05-dist/log.c 2008-08-11 19:32:53.000000000 -0700 +++ djbdns-1.05/log.c 2008-08-11 19:33:30.000000000 -0700 @@ -88,12 +88,39 @@ } } +void log_reread(void) +{ + string("rereading servers configuration"); + line(); +} + void log_startup(void) { string("starting"); line(); } +void log_listen(const char addr[4]) +{ + string("listening on "); + ip(addr); + line(); +} + +#ifdef DUMPCACHE +void log_slurp(int nb) +{ + string("slurp "); number(nb); + line(); +} + +void log_dump(int err) +{ + string("dump err "); number(err); + line(); +} +#endif + void log_query(uint64 *qnum,const char client[4],unsigned int port,const char id[2],const char *q,const char qtype[2]) { string("query "); number(*qnum); space(); diff -ruN djbdns-1.05-dist/log.h djbdns-1.05/log.h --- djbdns-1.05-dist/log.h 2008-08-11 19:32:53.000000000 -0700 +++ djbdns-1.05/log.h 2008-08-11 19:33:30.000000000 -0700 @@ -4,6 +4,12 @@ #include "uint64.h" extern void log_startup(void); +extern void log_listen(const char *); +#ifdef DUMPCACHE +extern void log_slurp(int); +extern void log_dump(int); +#endif +extern void log_reread(void); extern void log_query(uint64 *,const char *,unsigned int,const char *,const char *,const char *); extern void log_querydrop(uint64 *); diff -ruN djbdns-1.05-dist/okclient.c djbdns-1.05/okclient.c --- djbdns-1.05-dist/okclient.c 2008-08-11 19:32:53.000000000 -0700 +++ djbdns-1.05/okclient.c 2008-08-11 19:33:30.000000000 -0700 @@ -1,5 +1,6 @@ #include #include +#include "env.h" #include "str.h" #include "ip4.h" #include "okclient.h" @@ -10,6 +11,14 @@ { struct stat st; int i; + static int init_done=0; + if (!init_done) { + if (env_get("OKCLIENT")) { + init_done=1; + } else + init_done=2; + } + if (init_done==1) return 1; fn[0] = 'i'; fn[1] = 'p'; diff -ruN djbdns-1.05-dist/parsetype.c djbdns-1.05/parsetype.c --- djbdns-1.05-dist/parsetype.c 2008-08-11 19:32:53.000000000 -0700 +++ djbdns-1.05/parsetype.c 2008-08-11 22:49:52.000000000 -0700 @@ -24,6 +24,8 @@ else if (case_equals(s,"key")) byte_copy(type,2,DNS_T_KEY); else if (case_equals(s,"aaaa")) byte_copy(type,2,DNS_T_AAAA); else if (case_equals(s,"axfr")) byte_copy(type,2,DNS_T_AXFR); + else if (case_equals(s,"srv")) byte_copy(type,2,DNS_T_SRV); + else if (case_equals(s,"naptr")) byte_copy(type,2,DNS_T_NAPTR); else return 0; diff -ruN djbdns-1.05-dist/printrecord.c djbdns-1.05/printrecord.c --- djbdns-1.05-dist/printrecord.c 2008-08-11 19:32:53.000000000 -0700 +++ djbdns-1.05/printrecord.c 2008-08-11 23:10:20.000000000 -0700 @@ -82,6 +82,56 @@ if (!stralloc_catulong0(out,ch,0)) return 0; } } + else if (byte_equal(misc,2,DNS_T_SRV)) { + if (!stralloc_cats(out," SRV ")) return 0; + pos = dns_packet_copy(buf,len,pos,misc,2); if (!pos) return 0; + uint16_unpack_big(misc,&u16); + if (!stralloc_catulong0(out,u16,0)) return 0; + if (!stralloc_cats(out," ")) return 0; + pos = dns_packet_copy(buf,len,pos,misc,2); if (!pos) return 0; + uint16_unpack_big(misc,&u16); + if (!stralloc_catulong0(out,u16,0)) return 0; + if (!stralloc_cats(out," ")) return 0; + pos = dns_packet_copy(buf,len,pos,misc,2); if (!pos) return 0; + uint16_unpack_big(misc,&u16); + if (!stralloc_catulong0(out,u16,0)) return 0; + if (!stralloc_cats(out," ")) return 0; + pos = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0; + if (!dns_domain_todot_cat(out,d)) return 0; + } + else if (byte_equal(misc,2,DNS_T_NAPTR)) { + char str[255]; + unsigned int oldpos; + if (!stralloc_cats(out," NAPTR ")) return 0; + pos = dns_packet_copy(buf,len,pos,misc,2); if (!pos) return 0; + uint16_unpack_big(misc,&u16); + if (!stralloc_catulong0(out,u16,0)) return 0; + if (!stralloc_cats(out," ")) return 0; + pos = dns_packet_copy(buf,len,pos,misc,2); if (!pos) return 0; + uint16_unpack_big(misc,&u16); + if (!stralloc_catulong0(out,u16,0)) return 0; + if (!stralloc_cats(out," ")) return 0; + pos = dns_packet_copy(buf,len,pos,&ch,1); if (!pos) return 0; + pos = dns_packet_copy(buf,len,pos,str,ch); if (!pos) return 0; + if (!stralloc_cats(out,"\"")) return 0; + if (!stralloc_catb(out,str,ch)) return 0; + if (!stralloc_cats(out,"\" ")) return 0; + pos = dns_packet_copy(buf,len,pos,&ch,1); if (!pos) return 0; + pos = dns_packet_copy(buf,len,pos,str,ch); if (!pos) return 0; + if (!stralloc_cats(out,"\"")) return 0; + if (!stralloc_catb(out,str,ch)) return 0; + if (!stralloc_cats(out,"\" ")) return 0; + pos = dns_packet_copy(buf,len,pos,&ch,1); if (!pos) return 0; + pos = dns_packet_copy(buf,len,pos,str,ch); if (!pos) return 0; + if (!stralloc_cats(out,"\"")) return 0; + if (!stralloc_catb(out,str,ch)) return 0; + if (!stralloc_cats(out,"\" ")) return 0; + pos = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0; + oldpos = out->len; + if (!dns_domain_todot_cat(out,d)) return 0; + if (out->len == oldpos) + if (!stralloc_cats(out,".")) return 0; + } else { if (!stralloc_cats(out," ")) return 0; uint16_unpack_big(misc,&u16); diff -ruN djbdns-1.05-dist/prot.c djbdns-1.05/prot.c --- djbdns-1.05-dist/prot.c 2008-08-11 19:32:53.000000000 -0700 +++ djbdns-1.05/prot.c 2008-08-11 19:33:30.000000000 -0700 @@ -1,5 +1,7 @@ #include "hasshsgr.h" #include "prot.h" +#include +#include int prot_gid(int gid) { diff -ruN djbdns-1.05-dist/query.c djbdns-1.05/query.c --- djbdns-1.05-dist/query.c 2008-08-11 19:32:53.000000000 -0700 +++ djbdns-1.05/query.c 2008-08-11 19:33:30.000000000 -0700 @@ -20,6 +20,15 @@ flagforwardonly = 1; } +static int flagnxdspecial = 0; +static char nxdip[4]; + +void query_nxdspecial(const char ip[4]) +{ + byte_copy(nxdip,4,ip); + flagnxdspecial = 1; +} + static void cachegeneric(const char type[2],const char *d,const char *data,unsigned int datalen,uint32 ttl) { unsigned int len; @@ -246,6 +255,7 @@ case_lowerb(key + 2,dlen); cached = cache_get(key,dlen + 2,&cachedlen,&ttl); if (cached) { + soattl = rcode = 0; log_cachednxdomain(d); goto NXDOMAIN; } @@ -695,7 +705,12 @@ NXDOMAIN: if (z->level) goto LOWERLEVEL; if (!rqa(z)) goto DIE; - response_nxdomain(); + if (flagnxdspecial && typematch(DNS_T_A,dtype)) { + if (!response_rstart(d,DNS_T_A,rcode == 3 ? soattl : ttl)) goto DIE; + if (!response_addbytes(nxdip,4)) goto DIE; + response_rfinish(RESPONSE_ANSWER); + } else + response_nxdomain(); cleanup(z); return 1; } diff -ruN djbdns-1.05-dist/query.h djbdns-1.05/query.h --- djbdns-1.05-dist/query.h 2008-08-11 19:32:53.000000000 -0700 +++ djbdns-1.05/query.h 2008-08-11 19:33:30.000000000 -0700 @@ -28,5 +28,6 @@ extern int query_get(struct query *,iopause_fd *,struct taia *); extern void query_forwardonly(void); +extern void query_nxdspecial(const char *); #endif diff -ruN djbdns-1.05-dist/seek_set.c djbdns-1.05/seek_set.c --- djbdns-1.05-dist/seek_set.c 2008-08-11 19:32:53.000000000 -0700 +++ djbdns-1.05/seek_set.c 2008-08-11 19:33:30.000000000 -0700 @@ -1,4 +1,5 @@ #include +#include #include "seek.h" #define SET 0 /* sigh */ diff -ruN djbdns-1.05-dist/select.h djbdns-1.05/select.h --- djbdns-1.05-dist/select.h 1969-12-31 16:00:00.000000000 -0800 +++ djbdns-1.05/select.h 2008-08-11 22:55:14.000000000 -0700 @@ -0,0 +1,11 @@ +#ifndef SELECT_H +#define SELECT_H + +/* sysdep: +sysselect */ + +#include +#include +#include +extern int select(); + +#endif diff -ruN djbdns-1.05-dist/server.c djbdns-1.05/server.c --- djbdns-1.05-dist/server.c 2008-08-11 19:32:53.000000000 -0700 +++ djbdns-1.05/server.c 2008-08-11 19:33:30.000000000 -0700 @@ -11,6 +11,8 @@ #include "qlog.h" #include "response.h" #include "dns.h" +#include "alloc.h" +#include "iopause.h" extern char *fatal; extern char *starting; @@ -25,6 +27,44 @@ static char *q; + +static void hex(unsigned char c) +{ + buffer_put(buffer_2,"0123456789abcdef" + (c >> 4),1); + buffer_put(buffer_2,"0123456789abcdef" + (c & 15),1); +} + +static void put_ip(const char i[4]) +{ + hex(i[0]); + hex(i[1]); + hex(i[2]); + hex(i[3]); +} + +static void string(const char *s) +{ + buffer_puts(buffer_2,s); +} + +static void line(void) +{ + string("\n"); + buffer_flush(buffer_2); +} + +void log_listen(const char addr[4]) +{ + string("listening on "); + put_ip(addr); + line(); +} + +void nomem() +{ + strerr_die2x(111,fatal,"out of memory"); +} + static int doit(void) { unsigned int pos; @@ -51,6 +91,13 @@ response[3] &= ~128; if (!(header[2] & 1)) response[2] &= ~1; + if ((header[2] & 126) == 0x24) /* NOTIFY + AA */ + if (byte_equal(qtype,2,DNS_T_SOA)) { + response[2] |= 0x20; /* NOTIFY */ + qlog(ip,port,header,q,qtype," N "); + return 1; + } + if (header[2] & 126) goto NOTIMP; if (byte_equal(qtype,2,DNS_T_AXFR)) goto NOTIMP; @@ -59,7 +106,12 @@ qlog(ip,port,header,q,qtype," - "); return 0; } - qlog(ip,port,header,q,qtype," + "); + + if ((response[2] & 4) && (response[3] & 3)) + qlog(ip,port,header,q,qtype," X "); + else + qlog(ip,port,header,q,qtype," + "); + return 1; NOTIMP: @@ -82,35 +134,75 @@ int main() { char *x; - int udp53; + int *udp53; + unsigned int off; + unsigned int cnt; + iopause_fd *iop; x = env_get("IP"); if (!x) strerr_die2x(111,fatal,"$IP not set"); - if (!ip4_scan(x,ip)) - strerr_die3x(111,fatal,"unable to parse IP address ",x); - - udp53 = socket_udp(); - if (udp53 == -1) - strerr_die2sys(111,fatal,"unable to create UDP socket: "); - if (socket_bind4_reuse(udp53,ip,53) == -1) - strerr_die2sys(111,fatal,"unable to bind UDP socket: "); + off=0; + cnt=0; + while (x[off]) { + unsigned int l; + char dummy[4]; + l=ip4_scan(x+off,dummy); + if (!l) + strerr_die3x(111,fatal,"unable to parse IP address ",x+off); + cnt++; + if (!x[off+l]) break; + if (x[off+l]!='/') + strerr_die3x(111,fatal,"unable to parse IP address ",x+off); + off+=l+1; + } + udp53=(int *) alloc(sizeof(int) *cnt); + if (!udp53) nomem(); + iop=(iopause_fd *) alloc(sizeof(*iop) * cnt); + if (!iop) nomem(); + + off=0; + cnt=0; + while (x[off]) { + unsigned int l; + l=ip4_scan(x+off,ip); + udp53[cnt] = socket_udp(); + if (udp53[cnt] == -1) + strerr_die2sys(111,fatal,"unable to create UDP socket: "); + if (socket_bind4_reuse(udp53[cnt],ip,53) == -1) + strerr_die2sys(111,fatal,"unable to bind UDP socket: "); + ndelay_off(udp53[cnt]); + socket_tryreservein(udp53[cnt],65536); + iop[cnt].fd=udp53[cnt]; + iop[cnt].events=IOPAUSE_READ; + log_listen(ip); + cnt++; + if (!x[off+l]) break; + off+=l+1; + } droproot(fatal); initialize(); - - 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; - if (!doit()) continue; - if (response_len > 512) response_tc(); - socket_send4(udp53,response,response_len,ip,port); - /* may block for buffer space; if it fails, too bad */ + struct taia stamp; + struct taia deadline; + unsigned int i; + taia_now(&stamp); + taia_uint(&deadline,300); + taia_add(&deadline,&deadline,&stamp); + iopause(iop,cnt,&deadline,&stamp); + for (i=0;i 512) response_tc(); + socket_send4(udp53[i],response,response_len,ip,port); + /* may block for buffer space; if it fails, too bad */ + } } } diff -ruN djbdns-1.05-dist/sig.c djbdns-1.05/sig.c --- djbdns-1.05-dist/sig.c 1969-12-31 16:00:00.000000000 -0800 +++ djbdns-1.05/sig.c 2008-08-11 19:33:30.000000000 -0700 @@ -0,0 +1,12 @@ +#include +#include "sig.h" + +int sig_alarm = SIGALRM; +int sig_child = SIGCHLD; +int sig_cont = SIGCONT; +int sig_hangup = SIGHUP; +int sig_pipe = SIGPIPE; +int sig_term = SIGTERM; + +void (*sig_defaulthandler)() = SIG_DFL; +void (*sig_ignorehandler)() = SIG_IGN; diff -ruN djbdns-1.05-dist/sig.h djbdns-1.05/sig.h --- djbdns-1.05-dist/sig.h 1969-12-31 16:00:00.000000000 -0800 +++ djbdns-1.05/sig.h 2008-08-11 19:33:30.000000000 -0700 @@ -0,0 +1,25 @@ +#ifndef SIG_H +#define SIG_H + +extern int sig_alarm; +extern int sig_child; +extern int sig_cont; +extern int sig_hangup; +extern int sig_pipe; +extern int sig_term; + +extern void (*sig_defaulthandler)(); +extern void (*sig_ignorehandler)(); + +extern void sig_catch(int,void (*)()); +#define sig_ignore(s) (sig_catch((s),sig_ignorehandler)) +#define sig_uncatch(s) (sig_catch((s),sig_defaulthandler)) + +extern void sig_block(int); +extern void sig_unblock(int); +extern void sig_blocknone(void); +extern void sig_pause(void); + +extern void sig_dfl(int); + +#endif diff -ruN djbdns-1.05-dist/sig_block.c djbdns-1.05/sig_block.c --- djbdns-1.05-dist/sig_block.c 1969-12-31 16:00:00.000000000 -0800 +++ djbdns-1.05/sig_block.c 2008-08-11 19:33:30.000000000 -0700 @@ -0,0 +1,38 @@ +#include +#include "sig.h" +#include "hassgprm.h" + +void sig_block(int sig) +{ +#ifdef HASSIGPROCMASK + sigset_t ss; + sigemptyset(&ss); + sigaddset(&ss,sig); + sigprocmask(SIG_BLOCK,&ss,(sigset_t *) 0); +#else + sigblock(1 << (sig - 1)); +#endif +} + +void sig_unblock(int sig) +{ +#ifdef HASSIGPROCMASK + sigset_t ss; + sigemptyset(&ss); + sigaddset(&ss,sig); + sigprocmask(SIG_UNBLOCK,&ss,(sigset_t *) 0); +#else + sigsetmask(sigsetmask(~0) & ~(1 << (sig - 1))); +#endif +} + +void sig_blocknone(void) +{ +#ifdef HASSIGPROCMASK + sigset_t ss; + sigemptyset(&ss); + sigprocmask(SIG_SETMASK,&ss,(sigset_t *) 0); +#else + sigsetmask(0); +#endif +} diff -ruN djbdns-1.05-dist/sig_catch.c djbdns-1.05/sig_catch.c --- djbdns-1.05-dist/sig_catch.c 1969-12-31 16:00:00.000000000 -0800 +++ djbdns-1.05/sig_catch.c 2008-08-11 19:33:30.000000000 -0700 @@ -0,0 +1,16 @@ +#include +#include "sig.h" +#include "hassgact.h" + +void sig_catch(int sig,void (*f)()) +{ +#ifdef HASSIGACTION + struct sigaction sa; + sa.sa_handler = f; + sa.sa_flags = 0; + sigemptyset(&sa.sa_mask); + sigaction(sig,&sa,(struct sigaction *) 0); +#else + signal(sig,f); /* won't work under System V, even nowadays---dorks */ +#endif +} diff -ruN djbdns-1.05-dist/sig_pause.c djbdns-1.05/sig_pause.c --- djbdns-1.05-dist/sig_pause.c 1969-12-31 16:00:00.000000000 -0800 +++ djbdns-1.05/sig_pause.c 2008-08-11 19:33:30.000000000 -0700 @@ -0,0 +1,14 @@ +#include +#include "sig.h" +#include "hassgprm.h" + +void sig_pause(void) +{ +#ifdef HASSIGPROCMASK + sigset_t ss; + sigemptyset(&ss); + sigsuspend(&ss); +#else + sigpause(0); +#endif +} diff -ruN djbdns-1.05-dist/tinydns-data.c djbdns-1.05/tinydns-data.c --- djbdns-1.05-dist/tinydns-data.c 2008-08-11 19:32:53.000000000 -0700 +++ djbdns-1.05/tinydns-data.c 2008-08-11 22:56:09.000000000 -0700 @@ -159,11 +159,7 @@ die_datatmp(); } -buffer b; -char bspace[1024]; - static stralloc line; -int match = 1; unsigned long linenum = 0; #define NUMFIELDS 15 @@ -171,6 +167,8 @@ static char *d1; static char *d2; +static char *contact; + char dptr[DNS_NAME4_DOMAIN]; char strnum[FMT_ULONG]; @@ -181,7 +179,7 @@ strerr_die4x(111,FATAL,"unable to parse data line ",strnum,why); } -int main() +int load(const char *fname) { int fddata; int i; @@ -196,20 +194,20 @@ char type[2]; char soa[20]; char buf[4]; + char naptr[4]; + char srv[6]; + int match; + buffer b; + char bspace[1024]; - umask(022); - - fddata = open_read("data"); + fddata = open_read(fname); if (fddata == -1) - strerr_die2sys(111,FATAL,"unable to open data: "); + strerr_die4sys(111,FATAL,"unable to open ",fname,": "); defaultsoa_init(fddata); buffer_init(&b,buffer_unixread,fddata,bspace,sizeof bspace); - fdcdb = open_trunc("data.tmp"); - if (fdcdb == -1) die_datatmp(); - if (cdb_make_start(&cdb,fdcdb) == -1) die_datatmp(); - + match = 1; while (match) { ++linenum; if (getln(&b,&line,&match,'\n') == -1) @@ -247,6 +245,11 @@ die_datatmp(); break; + case 'D': + if (!dns_domain_fromdot(&contact,f[0].s,f[0].len)) nomem(); + if (f[0].len == 0) contact = NULL; + break; + case 'Z': if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); @@ -298,8 +301,13 @@ if (line.s[0] == '.') { rr_start(DNS_T_SOA,ttl ? TTL_NEGATIVE : 0,ttd,loc); rr_addname(d2); - rr_add("\12hostmaster",11); - rr_addname(d1); + if (!contact) { + rr_add("\12hostmaster",11); + rr_addname(d1); + } else { + rr_addname(contact); + } + rr_add(defaultsoa,20); rr_finish(d1); } @@ -369,6 +377,43 @@ rr_finish(d2); } break; + + case 'S': + if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); + if (!stralloc_0(&f[6])) nomem(); + if (!scan_ulong(f[6].s,&ttl)) ttl = TTL_POSITIVE; + ttdparse(&f[7],ttd); + locparse(&f[8],loc); + + if (!stralloc_0(&f[1])) nomem(); + + if (byte_chr(f[2].s,f[2].len,'.') >= f[2].len) { + if (!stralloc_cats(&f[2],".srv.")) nomem(); + if (!stralloc_catb(&f[2],f[0].s,f[0].len)) nomem(); + } + if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem(); + + if (!stralloc_0(&f[4])) nomem(); + if (!scan_ulong(f[4].s,&u)) u = 0; + uint16_pack_big(srv,u); + if (!stralloc_0(&f[5])) nomem(); + if (!scan_ulong(f[5].s,&u)) u = 0; + uint16_pack_big(srv + 2,u); + if (!stralloc_0(&f[3])) nomem(); + if (!scan_ulong(f[3].s,&u)) nomem(); + uint16_pack_big(srv + 4,u); + + rr_start(DNS_T_SRV,ttl,ttd,loc); + rr_add(srv,6); + rr_addname(d2); + rr_finish(d1); + + if (ip4_scan(f[1].s,ip)) { + rr_start(DNS_T_A,ttl,ttd,loc); + rr_add(ip,4); + rr_finish(d2); + } + break; case '^': case 'C': if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); @@ -441,10 +486,61 @@ rr_finish(d1); break; + case 'N': + if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); + if (!dns_domain_fromdot(&d2,f[6].s,f[6].len)) nomem(); + if (!stralloc_0(&f[7])) nomem(); + if (!scan_ulong(f[7].s,&ttl)) ttl = TTL_POSITIVE; + ttdparse(&f[8],ttd); + locparse(&f[9],loc); + + if (!stralloc_0(&f[1])) nomem(); + if (!scan_ulong(f[1].s,&u)) u = 0; + uint16_pack_big(naptr,u); + if (!stralloc_0(&f[2])) nomem(); + if (!scan_ulong(f[2].s,&u)) u = 0; + uint16_pack_big(naptr + 2,u); + + txtparse(&f[3]); if (f[3].len > 255) + syntaxerror(": it is not allowed more than 255 chars in a label"); + txtparse(&f[4]); if (f[4].len > 255) + syntaxerror(": it is not allowed more than 255 chars in a label"); + txtparse(&f[5]); if (f[5].len > 255) + syntaxerror(": it is not allowed more than 255 chars in a label"); + + rr_start(DNS_T_NAPTR,ttl,ttd,loc); + rr_add(naptr,4); + + ch = f[3].len; rr_add(&ch,1); + rr_add(f[3].s, f[3].len); + ch = f[4].len; rr_add(&ch,1); + rr_add(f[4].s, f[4].len); + ch = f[5].len; rr_add(&ch,1); + rr_add(f[5].s, f[5].len); + + rr_addname(d2); + rr_finish(d1); + break; + default: syntaxerror(": unrecognized leading character"); } } + close(fddata); +} + +int main(int argc, char **argv) +{ + umask(022); + fdcdb = open_trunc("data.tmp"); + if (fdcdb == -1) die_datatmp(); + if (cdb_make_start(&cdb,fdcdb) == -1) die_datatmp(); + + if (argc == 1) + load("data"); + while(--argc) { + load(argv[argc]); + } if (cdb_make_finish(&cdb) == -1) die_datatmp(); if (fsync(fdcdb) == -1) die_datatmp(); diff -ruN djbdns-1.05-dist/trysgact.c djbdns-1.05/trysgact.c --- djbdns-1.05-dist/trysgact.c 1969-12-31 16:00:00.000000000 -0800 +++ djbdns-1.05/trysgact.c 2008-08-11 19:33:30.000000000 -0700 @@ -0,0 +1,10 @@ +#include + +main() +{ + struct sigaction sa; + sa.sa_handler = 0; + sa.sa_flags = 0; + sigemptyset(&sa.sa_mask); + sigaction(0,&sa,(struct sigaction *) 0); +} diff -ruN djbdns-1.05-dist/trysgprm.c djbdns-1.05/trysgprm.c --- djbdns-1.05-dist/trysgprm.c 1969-12-31 16:00:00.000000000 -0800 +++ djbdns-1.05/trysgprm.c 2008-08-11 19:33:30.000000000 -0700 @@ -0,0 +1,10 @@ +#include + +main() +{ + sigset_t ss; + + sigemptyset(&ss); + sigaddset(&ss,SIGCHLD); + sigprocmask(SIG_SETMASK,&ss,(sigset_t *) 0); +} diff -ruN djbdns-1.05-dist/uint32.h djbdns-1.05/uint32.h --- djbdns-1.05-dist/uint32.h 1969-12-31 16:00:00.000000000 -0800 +++ djbdns-1.05/uint32.h 2008-08-11 22:55:10.000000000 -0700 @@ -0,0 +1,11 @@ +#ifndef UINT32_H +#define UINT32_H + +typedef unsigned long uint32; + +extern void uint32_pack(char *,uint32); +extern void uint32_pack_big(char *,uint32); +extern void uint32_unpack(const char *,uint32 *); +extern void uint32_unpack_big(const char *,uint32 *); + +#endif diff -ruN djbdns-1.05-dist/uint64.h djbdns-1.05/uint64.h --- djbdns-1.05-dist/uint64.h 1969-12-31 16:00:00.000000000 -0800 +++ djbdns-1.05/uint64.h 2008-08-11 22:55:10.000000000 -0700 @@ -0,0 +1,8 @@ +#ifndef UINT64_H +#define UINT64_H + +/* sysdep: -ulong64 */ + +typedef unsigned long long uint64; + +#endif