Download | Plain Text | Line Numbers
diff -urN djbdns-1.05/Makefile djbdns-1.05_new/Makefile
--- djbdns-1.05/Makefile Sun Feb 11 23:11:45 2001
+++ djbdns-1.05_new/Makefile Sun Sep 14 18:07:13 2008
@@ -152,9 +152,14 @@
uint32.h uint64.h
./compile cache.c
+cache_djb.o: \
+compile cache_djb.c alloc.h byte.h uint32.h exit.h tai.h uint64.h cache.h \
+uint32.h uint64.h
+ ./compile cache_djb.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 \
+load cachetest.o cache_djb.o libtai.a buffer.a alloc.a unix.a byte.a
+ ./load cachetest cache_djb.o libtai.a buffer.a alloc.a unix.a \
byte.a
cachetest.o: \
diff -urN djbdns-1.05/README.dumpcache djbdns-1.05_new/README.dumpcache
--- djbdns-1.05/README.dumpcache Thu Jan 1 02:00:00 1970
+++ djbdns-1.05_new/README.dumpcache Tue Sep 9 14:57:40 2008
@@ -0,0 +1,23 @@
+dnscache-conf sets variables:
+ DUMPCACHE=14400:dump/data
+ SLURPCACHE=dump/data
+The number 14400 is the dump interval. Set it between 3600 and 43200.
+
+Understands signals:
+ SIGTERM dump cache and exit
+ SIGALARM dump cache
+ SIGHUP reload cache
+
+Filtering like multilog. To use filtering edit run file. Example:
+...
+exec envdir ./env envuidgid dnscache softlimit -o250 -d 3000000 \
+ /usr/local/bin/dnscache '-*' '+stats *' '+slurp *' '+dump *' '+tcp *'
+
+You can comment line 32 of log.c to remove prefix "dns: ".
+
+dnscache ignores SIGPIPE.
+
+I will put documention on:
+http://riemann.fmi.uni-sofia.bg/docs/djbdns-dumpcache.html
+
+Enjoy, Nikola
diff -urN djbdns-1.05/TARGETS djbdns-1.05_new/TARGETS
--- djbdns-1.05/TARGETS Sun Feb 11 23:11:45 2001
+++ djbdns-1.05_new/TARGETS Sun Sep 14 18:12:47 2008
@@ -86,6 +86,7 @@
okclient.o
log.o
cache.o
+cache_djb.o
query.o
response.o
dd.o
diff -urN djbdns-1.05/cache.c djbdns-1.05_new/cache.c
--- djbdns-1.05/cache.c Sun Feb 11 23:11:45 2001
+++ djbdns-1.05_new/cache.c Tue Sep 9 14:57:40 2008
@@ -1,3 +1,16 @@
+#ifdef DUMPCACHE
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include "str.h"
+#include "open.h"
+#include "buffer.h"
+#include "scan.h"
+#include "log.h"
+#endif
#include "alloc.h"
#include "byte.h"
#include "uint32.h"
@@ -137,6 +150,7 @@
if (datalen > MAXDATALEN) return;
if (!ttl) return;
+ if (cache_get(key, keylen, &entrylen, &pos)) return;
if (ttl > 604800) ttl = 604800;
entrylen = keylen + datalen + 20;
@@ -183,25 +197,137 @@
int cache_init(unsigned int cachesize)
{
+#ifdef DUMPCACHE
+ char *y=x;
+ uint32 old_size=size;
+#else
if (x) {
alloc_free(x);
x = 0;
}
+#endif
if (cachesize > 1000000000) cachesize = 1000000000;
if (cachesize < 100) cachesize = 100;
size = cachesize;
- hsize = 4;
- while (hsize <= (size >> 5)) hsize <<= 1;
-
+#ifdef DUMPCACHE
+ x = realloc(x,size);
+ if (!x) { x = y; size = old_size; }
+ log_cachesize(size);
+#else
x = alloc(size);
+#endif
if (!x) return 0;
byte_zero(x,size);
+ hsize = 4;
+ while (hsize <= (size >> 5)) hsize <<= 1;
+
writer = hsize;
oldest = size;
unused = size;
return 1;
}
+
+#ifdef DUMPCACHE
+int cache_dump(char *fn)
+{
+ uint32 pos;
+ uint32 len, last;
+ int r=-1;
+ char *tmp;
+ buffer b = BUFFER_INIT((int (*)(int, char*, unsigned int))write,
+ -1, 0, 8000);
+ len=str_len(fn);
+ tmp = alloc(8032+len);
+ if (tmp == 0) return -1;
+ byte_copy(tmp,len,fn);
+ byte_copy(tmp+len,5,".tmp");
+ if ((b.fd = open_trunc(tmp)) == -1) goto ready;
+ b.x = tmp + len + 16;
+
+ for (r=0, pos=oldest, last=unused; r<2; pos=hsize, last=writer, r++)
+ while (pos < last) {
+ len = get4(pos + 4) + get4(pos + 8) + 16;
+ if (buffer_put(&b, x + pos + 4, len)) goto close_fd;
+ pos += 4 + len;
+ }
+
+ r = 0;
+ if (buffer_flush(&b) || fsync(b.fd) || close(b.fd) || rename(tmp,fn)) {
+ close_fd:
+ r = errno;
+ close(b.fd);
+ unlink(tmp);
+ errno = r;
+ r = -1;
+ }
+ ready:
+ alloc_free(tmp);
+ return r;
+}
+
+int cache_slurp(char *fn, int reinit)
+{
+ char *map, *data;
+ uint32 pos;
+ uint32 keylen;
+ uint32 datalen;
+ uint32 len;
+ struct tai now, expire;
+ int fd;
+ unsigned long a=200, b=32768;
+
+ if ((fd = open_read(fn)) == -1) return -1;
+ len = lseek(fd,0,SEEK_END);
+
+ if (reinit) {
+ static unsigned int cachesize;
+ if (!cachesize) cachesize = size;
+ if ((pos=str_len(fn)) + 48 < size) {
+ int r;
+ data = x + 32;
+ byte_copy(data,pos,fn);
+ byte_copy(data+pos,8,".blowup");
+ r=readlink(data,x,24);
+ if (r > 0) {
+ x[r] = 0;
+ if ((r = scan_ulong(x,&a)) && x[r] == ':')
+ scan_ulong(x+r+1,&b);
+ }
+ }
+
+ pos = ((a*(len/100) + b) & ~4095) - 40;
+ if (pos > cachesize) pos = cachesize;
+ /* next is impossible, since cache is already init */
+ if (!cache_init(pos)) cache_impossible();
+ cache_motion = 0;
+ }
+
+ map=mmap(0,len,PROT_READ,MAP_SHARED,fd,0);
+ close(fd);
+ if (map==MAP_FAILED) return -1;
+
+ tai_now(&now);
+ pos = 0;
+ a = 0;
+ while (pos + 16 <= len) {
+ data = map + pos;
+ uint32_unpack(data, &keylen);
+ uint32_unpack(data + 4, &datalen);
+ tai_unpack(data + 8, &expire);
+ pos += 16 + keylen + datalen;
+ data += 16;
+ if (pos > len) break; /* missing data */
+ if (expire.x > now.x) {
+ cache_set(data, keylen, data + keylen, datalen,
+ (uint32)(expire.x - now.x));
+ a++;
+ }
+ }
+ munmap(map,len);
+ return a;
+}
+#endif
diff -urN djbdns-1.05/cache.h djbdns-1.05_new/cache.h
--- djbdns-1.05/cache.h Sun Feb 11 23:11:45 2001
+++ djbdns-1.05_new/cache.h Tue Sep 9 14:57:40 2008
@@ -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(char *);
+extern int cache_slurp(char *, int);
+#endif
#endif
diff -urN djbdns-1.05/cache_djb.c djbdns-1.05_new/cache_djb.c
--- djbdns-1.05/cache_djb.c Thu Jan 1 02:00:00 1970
+++ djbdns-1.05_new/cache_djb.c Sun Sep 14 18:02:31 2008
@@ -0,0 +1,4 @@
+#ifdef DUMPCACHE
+#undef DUMPCACHE
+#endif
+#include "cache.c"
diff -urN djbdns-1.05/conf-cc djbdns-1.05_new/conf-cc
--- djbdns-1.05/conf-cc Sun Feb 11 23:11:45 2001
+++ djbdns-1.05_new/conf-cc Sun Sep 14 18:14:05 2008
@@ -1,3 +1,3 @@
-gcc -O2 -Wimplicit -Wunused -Wcomment -Wchar-subscripts -Wuninitialized -Wshadow -Wcast-qual -Wcast-align -Wwrite-strings
+gcc -O2 -Wimplicit -Wunused -Wcomment -Wchar-subscripts -Wuninitialized -Wshadow -Wcast-qual -Wcast-align -Wwrite-strings -DDUMPCACHE
This will be used to compile .c files.
diff -urN djbdns-1.05/dnscache-conf.c djbdns-1.05_new/dnscache-conf.c
--- djbdns-1.05/dnscache-conf.c Sun Feb 11 23:11:45 2001
+++ djbdns-1.05_new/dnscache-conf.c Tue Sep 9 14:57:40 2008
@@ -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,12 @@
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/data\n"); finish();
+ seed_addtime(); perm(0644);
+ seed_addtime(); start("env/DUMPCACHE"); outs("14400:dump/data\n"); finish();
+ seed_addtime(); perm(0644);
+#endif
seed_addtime(); start("run");
outs("#!/bin/sh\nexec 2>&1\nexec <seed\nexec envdir ./env sh -c '\n exec envuidgid "); outs(user);
outs(" softlimit -o250 -d \"$DATALIMIT\" ");
@@ -131,6 +149,11 @@
seed_addtime(); perm(0755);
seed_addtime(); makedir("root");
seed_addtime(); perm(02755);
+#ifdef DUMPCACHE
+ seed_addtime(); makedir("root/dump");
+ seed_addtime(); owner(useruid,usergid);
+ seed_addtime(); perm(02755);
+#endif
seed_addtime(); makedir("root/ip");
seed_addtime(); perm(02755);
seed_addtime(); start("root/ip/127.0.0.1"); finish();
diff -urN djbdns-1.05/dnscache.c djbdns-1.05_new/dnscache.c
--- djbdns-1.05/dnscache.c Sun Feb 11 23:11:45 2001
+++ djbdns-1.05_new/dnscache.c Tue Sep 9 14:57:40 2008
@@ -22,6 +22,21 @@
#include "log.h"
#include "okclient.h"
#include "droproot.h"
+#include <signal.h>
+char **ARGV;
+void sig_catch(int sig, void (*f)()) {
+ struct sigaction sa;
+ sa.sa_handler = f;
+ sa.sa_flags = 0;
+ sigemptyset(&sa.sa_mask);
+ sigaction(sig,&sa,(struct sigaction *) 0);
+}
+#ifdef DUMPCACHE
+static unsigned long dumptime, flagsignal;
+static char *slurpcache, *dumpcache;
+static struct tai nextdump;
+void got_signal(int sig) { flagsignal=sig; }
+#endif
static int packetquery(char *buf,unsigned int len,char **q,char qtype[2],char qclass[2],char id[2])
{
@@ -115,6 +130,12 @@
if (x->port < 1024) if (x->port != 53) return;
if (!okclient(x->ip)) return;
+#ifdef DUMPCACHE
+ if (dumptime && nextdump.x < x->start.sec.x) {
+ flagsignal=9999;
+ nextdump.x = x->start.sec.x + (uint64)dumptime;
+ }
+#endif
if (!packetquery(buf,len,&q,qtype,qclass,x->id)) return;
x->active = ++numqueries; ++uactive;
@@ -379,6 +400,18 @@
if (tcp53io)
if (tcp53io->revents)
t_new();
+#ifdef DUMPCACHE
+ if (flagsignal && flagsignal != SIGHUP) { /* SIGTERM SIGALRM 9999 */
+ r=cache_dump(dumpcache);
+ log_dump(r);
+ if (flagsignal == SIGTERM) _exit(0);
+ if (flagsignal == SIGALRM) flagsignal = 0;
+ else if (!r && slurpcache) flagsignal = SIGHUP; /* 9999 */
+ }
+ if (flagsignal == SIGHUP)
+ log_slurp(cache_slurp(slurpcache, 1));
+ flagsignal=0;
+#endif
}
}
@@ -386,11 +419,13 @@
char seed[128];
-int main()
+int main(int argc, char **argv)
{
char *x;
unsigned long cachesize;
+ sig_catch(SIGPIPE, SIG_IGN);
+ ARGV = argv+1; (void)argc;
x = env_get("IP");
if (!x)
strerr_die2x(111,FATAL,"$IP not set");
@@ -443,5 +478,22 @@
strerr_die2sys(111,FATAL,"unable to listen on TCP socket: ");
log_startup();
+#ifdef DUMPCACHE
+ if ((slurpcache=env_get("SLURPCACHE"))) {
+ log_slurp(cache_slurp(slurpcache, 0));
+ sig_catch(SIGHUP, got_signal);
+ }
+ if ((x=env_get("DUMPCACHE"))) {
+ int k=scan_ulong(x, &dumptime);
+ if (dumptime)
+ if (x[k]=':' && x[k+1]) {
+ dumpcache = x+k+1;
+ tai_now(&nextdump);
+ nextdump.x += (uint64)dumptime;
+ sig_catch(SIGTERM, got_signal);
+ sig_catch(SIGALRM, got_signal);
+ } else dumptime = 0;
+ }
+#endif
doit();
}
diff -urN djbdns-1.05/log.c djbdns-1.05_new/log.c
--- djbdns-1.05/log.c Sun Feb 11 23:11:45 2001
+++ djbdns-1.05_new/log.c Tue Sep 9 14:57:40 2008
@@ -4,6 +4,67 @@
#include "error.h"
#include "byte.h"
#include "log.h"
+#include "str.h"
+
+int match(const char *pattern,const char *buf,unsigned int len) {
+ char ch;
+ for (;;) {
+ ch = *pattern++;
+ if (!ch) return !len;
+ if (ch == '*') {
+ ch = *pattern;
+ if (!ch) return 1;
+ for (;;) {
+ if (!len) return 0;
+ if (*buf == ch) break;
+ ++buf; --len;
+ }
+ continue;
+ }
+ if (!len) return 0;
+ if (*buf != ch) return 0;
+ ++buf; --len;
+ }
+}
+
+extern char **ARGV;
+static int ok;
+#define LOG_PREFIX "dns: "
+
+static void buffer_check() {
+ unsigned int len= buffer_2->p;
+ char **p=ARGV, *x= buffer_2->x;
+
+#ifdef LOG_PREFIX
+ if (len>=5) {len -= 5; x += 5;}
+#endif
+ ok = 1;
+ for (; *p; p++) {
+ if (**p=='+' && ok!= 1 && match(*p+1,x,len)) ok= 1;
+ if (**p=='-' && ok!=-1 && match(*p+1,x,len)) ok=-1;
+ }
+ if (ok==-1) buffer_2->p=0;
+}
+
+/* ok==0 no prefix; ok==-2 has prefix; ok==-1 no print; ok==1 print */
+static void out_put(const char *s, unsigned long n) {
+ switch (ok) {
+ case 0: ok=-2;
+#ifdef LOG_PREFIX
+ buffer_puts(buffer_2, LOG_PREFIX);
+#endif
+ case -2:
+ if (n > buffer_2->n - buffer_2->p) { /* no free space */
+ buffer_check();
+ if (ok==-1) break;
+ }
+ case 1: buffer_put(buffer_2,s,n);
+ }
+}
+
+static void out_puts(const char *s) {out_put(s,str_len(s));}
+#define buffer_put(a,b,c) out_put(b,c)
+#define buffer_puts(a,b) out_puts(b)
/* work around gcc 2.95.2 bug */
#define number(x) ( (u64 = (x)), u64_print() )
@@ -37,7 +98,9 @@
static void line(void)
{
string("\n");
+ if (ok!=1 && ok!=-1) buffer_check();
buffer_flush(buffer_2);
+ ok = 0;
}
static void space(void)
@@ -93,6 +156,32 @@
string("starting");
line();
}
+
+
+#ifdef DUMPCACHE
+void log_slurp(int nb)
+{
+ string("slurp ");
+ if (nb<0) { string("err "); string(error_str(errno)); }
+ else number(nb);
+ line();
+}
+
+void log_dump(int e)
+{
+ string("dump ");
+ if (e) { string("err "); string(error_str(errno)); }
+ else string("ok");
+ line();
+}
+
+void log_cachesize(unsigned int e)
+{
+ string("cachesize ");
+ number(e);
+ 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])
{
diff -urN djbdns-1.05/log.h djbdns-1.05_new/log.h
--- djbdns-1.05/log.h Sun Feb 11 23:11:45 2001
+++ djbdns-1.05_new/log.h Tue Sep 9 14:57:40 2008
@@ -33,4 +33,9 @@
extern void log_stats(void);
+#ifdef DUMPCACHE
+extern void log_slurp(int);
+extern void log_dump(int);
+extern void log_cachesize(unsigned int);
+#endif
#endif