Download | Plain Text | Line Numbers


diff -Naur ./djbdns-1.05.orig/dnscache.c ./djbdns-1.05/dnscache.c
--- ./djbdns-1.05.orig/dnscache.c	2011-07-12 15:32:50.000000000 +0200
+++ ./djbdns-1.05/dnscache.c	2011-07-13 00:23:19.000000000 +0200
@@ -24,6 +24,9 @@
 #include "okclient.h"
 #include "droproot.h"
 #include "maxclient.h"
+#include "openreadclose.h"
+#include "open.h"
+#include "cdb.h"
 
 long interface;
 
@@ -473,6 +476,18 @@
   if (socket_listen(tcp53,20) == -1)
     strerr_die2sys(111,FATAL,"unable to listen on TCP socket: ");
 
+  int fd = open_read("rewrite.cdb");
+  if (fd > -1) {
+    cdb_init(&c, fd);
+    query_rewrite_enabled = 1;
+  }
+  log_rewrite(query_rewrite_enabled);
+
   log_startup();
   doit();
+
+  if (query_rewrite_enabled) {
+    cdb_free(&c);
+    close(fd);
+  }
 }
diff -Naur ./djbdns-1.05.orig/log.c ./djbdns-1.05/log.c
--- ./djbdns-1.05.orig/log.c	2011-07-12 15:32:50.000000000 +0200
+++ ./djbdns-1.05/log.c	2011-07-13 00:17:20.000000000 +0200
@@ -292,3 +292,10 @@
   number(tactive);
   line();
 }
+
+void log_rewrite(unsigned enabled)
+{
+  string("rewrite ");
+  string((enabled) ? "enabled" : "disabled");
+  line();
+}
diff -Naur ./djbdns-1.05.orig/log.h ./djbdns-1.05/log.h
--- ./djbdns-1.05.orig/log.h	2011-07-12 15:32:50.000000000 +0200
+++ ./djbdns-1.05/log.h	2011-07-13 00:22:05.000000000 +0200
@@ -33,5 +33,6 @@
 extern void log_rrsoa(const char *,const char *,const char *,const char *,const char *,unsigned int);
 
 extern void log_stats(void);
+extern void log_rewrite(unsigned enabled);
 
 #endif
diff -Naur ./djbdns-1.05.orig/Makefile ./djbdns-1.05/Makefile
--- ./djbdns-1.05.orig/Makefile	2011-07-12 15:32:50.000000000 +0200
+++ ./djbdns-1.05/Makefile	2011-07-13 00:21:52.000000000 +0200
@@ -344,10 +344,10 @@
 dnscache: \
 load dnscache.o droproot.o okclient.o log.o cache.o query.o qmerge.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 cdb.a unix.a byte.a socket.lib
 	./load dnscache droproot.o okclient.o log.o cache.o \
 	query.o qmerge.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 cdb.a unix.a byte.a  `cat \
 	socket.lib`
 
 dnscache-conf: \
diff -Naur ./djbdns-1.05.orig/query.c ./djbdns-1.05/query.c
--- ./djbdns-1.05.orig/query.c	2011-07-12 15:32:50.000000000 +0200
+++ ./djbdns-1.05/query.c	2011-07-13 00:24:01.000000000 +0200
@@ -13,6 +13,53 @@
 #include "response.h"
 #include "query.h"
 #include "ip6.h"
+#include "cdb.h"
+
+struct cdb c;
+int query_rewrite_enabled = 0;
+static char cdb_data[32767];
+static uint32 cdb_dlen;
+static char cdb_type[2];
+static unsigned int cdb_dpos;
+static char *cdb_domain;
+
+int query_rewrite_name(char **name, unsigned from_client)
+{
+  int r;
+  unsigned int pos, len;
+  char *newname, *tmp;
+  unsigned char x;
+  const char *type = (from_client) ? DNS_T_CNAME : DNS_T_PTR;
+
+  if (!query_rewrite_enabled) return 1;
+
+  tmp = *name;
+  while (x = *tmp++) {
+    tmp += (unsigned int) x;
+    r = cdb_find(&c, tmp, dns_domain_length(tmp));
+    if (r <= 0) continue;
+    cdb_dlen = cdb_datalen(&c);
+    if (cdb_dlen > sizeof cdb_data) continue;
+    if (cdb_read(&c, cdb_data, cdb_dlen, cdb_datapos(&c)) == -1) continue;
+    cdb_dpos = dns_packet_copy(cdb_data, cdb_dlen, 0, cdb_type, 2);
+    if (!byte_equal(cdb_type, 2, type)) continue;
+    cdb_dpos += 1 + 4 + 8;
+    cdb_dpos = dns_packet_getname(cdb_data, cdb_dlen, cdb_dpos, &cdb_domain);
+    if (!cdb_dpos) continue;
+
+    len = dns_domain_length(cdb_domain);
+    pos = tmp - *name;
+    newname = alloc(pos + len);
+    if (!newname) return 0;
+    byte_copy(newname, pos, *name); // copy name prefix
+    byte_copy(newname + pos, len, cdb_domain); // copy new name suffix
+    if (*name) alloc_free(*name);
+    *name = newname;
+    break;
+  }
+
+  return 1;
+}
 
 extern stralloc ignoreip;
 
@@ -97,6 +144,7 @@
 static int rqa(struct query *z)
 {
   int i;
+  char *namecpy = 0;
 
   for (i = QUERY_MAXALIAS - 1;i >= 0;--i)
     if (z->alias[i]) {
@@ -109,7 +157,13 @@
       return 1;
     }
 
-  if (!response_query(z->name[0],z->type,z->class)) return 0;
+  if (query_rewrite_enabled) {
+    if (!dns_domain_copy(&namecpy,z->name[0])) return 0;
+    if (!query_rewrite_name(&namecpy, 0)) return 0;
+    if (!response_query(namecpy,z->type,z->class)) return 0;
+    alloc_free(namecpy);
+  } else
+    if (!response_query(z->name[0],z->type,z->class)) return 0;
   return 1;
 }
 
@@ -643,6 +697,8 @@
 
   dns_sortip6(z->servers[z->level],256);
   dtype = z->level ? DNS_T_A : z->type;
+
+  if (!query_rewrite_name(&z->name[z->level], 1)) goto DIE;
   if (qmerge_start(&z->qm,z->servers[z->level],flagforwardonly,z->name[z->level],dtype,z->localip,z->control[z->level]) == -1) goto DIE;
   return 0;
 
@@ -786,6 +842,7 @@
 
     if (!dns_domain_suffix(t1,control)) { i = j; continue; }
     if (!roots_same(t1,control)) { i = j; continue; }
+    if (!query_rewrite_name(&t1, 0)) goto DIE;
 
     if (byte_equal(type,2,DNS_T_ANY))
       ;
@@ -983,6 +1040,7 @@
       if (dns_domain_equal(t1,d))
         if (byte_equal(header + 2,2,DNS_C_IN)) /* should always be true */
           if (typematch(header,dtype)) {
+            if (!query_rewrite_name(&t1, 0)) goto DIE;
             if (!response_rstart(t1,header,ttl)) goto DIE;
 
             if (typematch(header,DNS_T_NS) || typematch(header,DNS_T_CNAME) || typematch(header,DNS_T_PTR)) {
diff -Naur ./djbdns-1.05.orig/query.h ./djbdns-1.05/query.h
--- ./djbdns-1.05.orig/query.h	2011-07-12 15:32:50.000000000 +0200
+++ ./djbdns-1.05/query.h	2011-07-12 23:57:12.000000000 +0200
@@ -30,4 +30,7 @@
 
 extern void query_forwardonly(void);
 
+extern struct cdb c;
+extern int query_rewrite_enabled;
+
 #endif