--- pdns-recursor-3.1.7.orig/debian/pdns-recursor.dirs
+++ pdns-recursor-3.1.7/debian/pdns-recursor.dirs
@@ -0,0 +1,6 @@
+etc/powerdns
+etc/init.d
+etc/default
+usr/bin
+usr/sbin
+usr/share/doc/pdns-recursor
--- pdns-recursor-3.1.7.orig/debian/rules
+++ pdns-recursor-3.1.7/debian/rules
@@ -0,0 +1,89 @@
+#!/usr/bin/make -f
+# 
+# debian/rules file
+
+# These are used for cross-compiling and for saving the configure script
+# from having to guess our platform (since we know it already)
+DEB_HOST_GNU_TYPE   ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
+DEB_BUILD_GNU_TYPE  ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
+
+CXXFLAGS = -Wall -g
+CFLAGS = -Wall -g
+
+ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
+	OPTFLAGS += -O0
+else
+	OPTFLAGS += -O3
+endif
+
+export CXXFLAGS CFLAGS OPTFLAGS
+
+# Targets
+configure: configure-stamp
+configure-stamp:
+	dh_testdir
+	
+	# Add here commands to configure the package.
+	./configure
+	
+	touch configure-stamp
+
+build: patch build-stamp
+build-stamp: configure
+	
+	# Add here commands to compile the arch part of the package.
+	$(MAKE) 
+	
+	touch build-stamp
+
+clean: clean1 unpatch
+clean1:
+	dh_testdir
+	dh_testroot
+	rm -f build-stamp configure-stamp
+	
+	# Add here commands to clean up after the build process.
+	rm -rf dep *.o *~ pdns_recursor pdns_hw rec_control optional/*.o optional
+	dh_clean
+
+install: build
+	dh_testdir
+	dh_testroot
+	dh_clean -k
+	dh_installdirs
+	
+	# Install the stuff
+	$(MAKE) install DESTDIR=$(CURDIR)/debian/tmp
+	
+	dh_install
+
+# Build architecture (in)dependant packages.
+binary-indep:
+binary-arch: build install
+	dh_testdir -a
+	dh_testroot -a
+	dh_installchangelogs -a
+	dh_installdocs -a
+	dh_installman -a
+	dh_installlogcheck -a
+	dh_link -a
+	dh_strip -a
+	dh_compress -a
+	dh_fixperms -a
+	dh_installdeb -a
+	dh_shlibdeps -a
+	dh_gencontrol -a
+	dh_md5sums -a
+	dh_builddeb -a
+
+patch: patch-stamp
+patch-stamp:
+	dpatch apply-all
+	touch patch-stamp
+
+unpatch:
+	dpatch deapply-all
+	rm -rf patch-stamp debian/patched
+
+binary: binary-arch binary-indep
+.PHONY: build clean binary-indep binary-arch binary install configure clean1 unpatch
--- pdns-recursor-3.1.7.orig/debian/changelog
+++ pdns-recursor-3.1.7/debian/changelog
@@ -0,0 +1,130 @@
+pdns-recursor (3.1.7-1+lenny1~bpo40+1) etch-backports; urgency=high
+
+  * Security related rebuild for etch-backports which fixes CVE-2009-4009
+    (buffer overflow) and CVE-2009-4010 (cache poisoning).
+
+ -- Gerfried Fuchs <rhonda@debian.at>  Sat, 09 Jan 2010 12:32:40 +0100
+
+pdns-recursor (3.1.7-1+lenny1) stable-security; urgency=high
+
+  * Apply patches by Bert Hubert to fix buffer overflow (CVE-2009-4009)
+    and cache poisoning (CVE-2009-4010).
+
+ -- Florian Weimer <fw@deneb.enyo.de>  Wed, 06 Jan 2010 22:28:23 +0100
+
+pdns-recursor (3.1.7-1) unstable; urgency=low
+
+  * New upstream version (Closes: #490069) (Closes: #477130)
+  * init.d scripts gets socket-dir information from recursor.conf
+    (Closes: #471568)
+  * Added config file directives
+  * Set dont-query to nothing so it won't break pre-3.1.7 configs.
+    (Closes: #476841)
+
+ -- Christoph Haas <haas@debian.org>  Mon, 31 Mar 2008 21:51:59 +0200
+
+pdns-recursor (3.1.4-6) unstable; urgency=low
+
+  * Standards-Version 3.7.3.0
+  * Remove pdns_hw too on cleanup.
+  * Fix for truncating long TXT queries (Closes: #462114)
+  * Don't ignore build errors (Closes: #462128)
+  * Build option noopt was inoperative (Closes: #462126)
+  * Added gcc 4.3 fixes from upstream (Closes: #455631)
+
+ -- Matthijs Mohlmann <matthijs@cacholong.nl>  Wed, 13 Feb 2008 22:49:08 +0100
+
+pdns-recursor (3.1.4-5) unstable; urgency=low
+
+  * daemon=no is now working if used in /etc/powerdns/recursor.conf
+    (Closes: #440020)
+  * patch added to reflect change of L root server (Closes: #449483)
+  * Makefile patched to prevent stripping of binaries (Closes: #437765)
+
+ -- Christoph Haas <haas@debian.org>  Fri, 09 Nov 2007 21:57:58 +0100
+
+pdns-recursor (3.1.4-4) unstable; urgency=low
+
+  * Update to debhelper 5.
+  * Fix lintian warning: debian-rules-sets-DH_COMPAT.
+  * Restore the changelog, it was partly removed by accident. (Closes: #421393)
+  * Fix FTBFS with gcc-4.2 (Closes: #387113)
+
+ -- Matthijs Mohlmann <matthijs@cacholong.nl>  Sun, 03 Jun 2007 15:11:22 +0200
+
+pdns-recursor (3.1.4-3) unstable; urgency=low
+
+  * Stop/stop script does not return an error code when being called as
+    'stop' when the service is actually not running. (Closes: #406428)
+
+ -- Debian PowerDNS Maintainers <powerdns-debian@workaround.org>  Wed, 21 Feb 2007 23:10:00 +0200
+
+pdns-recursor (3.1.4-2) unstable; urgency=medium
+
+  * Run pdns-recursor by default as non-privileged user. (Closes: #399669)
+  * swapcontext is supported by kfreebsd (Fixes a FTBFS) (Closes: #403746)
+  * Added lsb-base to the dependencies. (Closes: #402732)
+
+ -- Matthijs Mohlmann <matthijs@cacholong.nl>  Mon, 25 Dec 2006 14:00:10 +0100
+
+pdns-recursor (3.1.4-1) unstable; urgency=medium
+
+  * New upstream release.
+
+ -- Matthijs Mohlmann <matthijs@cacholong.nl>  Sun, 12 Nov 2006 23:52:20 +0100
+
+pdns-recursor (3.1.3-3) unstable; urgency=low
+
+  [ Matthijs Mohlmann ]
+  * Don't build pdns-recursor for the following architectures: arm, mips,
+    mipsel, hppa and sparc. No support for swapcontext system call.
+    (Closes: #395801)
+  * Fix a big endian problem with TCP processing large answers.
+  * Fix a crash on any record we couldn't properly print for whatever reason.
+
+ -- Matthijs Mohlmann <matthijs@cacholong.nl>  Sun, 29 Oct 2006 17:50:34 +0100
+
+pdns-recursor (3.1.3-2) unstable; urgency=low
+
+  * Added patch to close a connectionless socket on an error.
+  * Added patch to fix a FD leak.
+  * Added missing lsb keyword Short-Description.
+
+ -- Debian PowerDNS Maintainers <powerdns-debian@workaround.org>  Sun,  1 Oct 2006 14:52:46 +0200
+
+pdns-recursor (3.1.3-1) unstable; urgency=low
+
+  * New upstream release.
+  * Make a lsb compliant init script, fixes a lintian warning.
+
+ -- Debian PowerDNS Maintainers <powerdns-debian@workaround.org>  Thu, 14 Sep 2006 21:20:56 +0200
+
+pdns-recursor (3.1.2-2) unstable; urgency=low
+
+  * Added patch to fix crashes on 64bit platforms (Closes: #380403)
+  * Added patch to prevent overwriting of auth data by unauth data.
+  * Fix a small memleak.
+
+ -- Debian PowerDNS Maintainers <powerdns-debian@workaround.org>  Sun,  6 Aug 2006 13:20:45 +0200
+
+pdns-recursor (3.1.2-1) unstable; urgency=low
+
+  * New upstream release.
+  * Drop build-with-g++-4.1 patch. g++ 4.1 is default now. (Closes: #376696)
+  * Fixed minor typo in recursor.conf (Closes: #369957)
+  * Add logcheck rule for pdns-recursor to suppress logcheck warnings.
+    (Closes: #367702)
+
+ -- Debian PowerDNS Maintainers <powerdns-debian@workaround.org>  Tue,  4 Jul 2006 19:16:19 +0200
+
+pdns-recursor (3.1.1-1) unstable; urgency=low
+
+  * New upstream version.
+
+ -- Debian PowerDNS Maintainers <powerdns-debian@workaround.org>  Wed, 24 May 2006 19:41:09 +0200
+
+pdns-recursor (3.0.1-1) unstable; urgency=low
+
+  * New upstream release (Closes: #366681)
+
+ -- Debian PowerDNS Maintainers <powerdns-debian@workaround.org>  Tue, 25 Apr 2006 21:27:26 +0200
--- pdns-recursor-3.1.7.orig/debian/pdns-recursor.postrm
+++ pdns-recursor-3.1.7/debian/pdns-recursor.postrm
@@ -0,0 +1,39 @@
+#! /bin/sh
+# postrm script for pdns-recursor
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+#        * <postrm> `remove'
+#        * <postrm> `purge'
+#        * <old-postrm> `upgrade' <new-version>
+#        * <new-postrm> `failed-upgrade' <old-version>
+#        * <new-postrm> `abort-install'
+#        * <new-postrm> `abort-install' <old-version>
+#        * <new-postrm> `abort-upgrade' <old-version>
+#        * <disappearer's-postrm> `disappear' <r>overwrit>r> <new-version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+  remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
+  ;;
+
+  purge)
+    update-rc.d pdns-recursor remove >/dev/null || exit 0
+  ;;
+
+  *)
+    echo "postrm called with unknown argument \`$1'" >&2
+    exit 1
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
--- pdns-recursor-3.1.7.orig/debian/control
+++ pdns-recursor-3.1.7/debian/control
@@ -0,0 +1,23 @@
+Source: pdns-recursor
+Section: net
+Priority: extra
+Standards-Version: 3.7.3.0
+Maintainer: Debian PowerDNS Maintainers <powerdns-debian@workaround.org>
+Uploaders: Christoph Haas <haas@debian.org>, Matthijs Mohlmann <matthijs@cacholong.nl>, Gerfried Fuchs <rhonda@debian.at>
+Build-Depends: debhelper (>= 5.0.0), dpatch (>= 2.0.0), dpkg-dev (> 1.10.17), libboost-dev, libboost-serialization-dev
+XS-Vcs-Svn: http://svn.cacholong.nl/cgi-bin/viewcvs.cgi/?root=pdns-recursor
+
+Package: pdns-recursor
+Architecture: alpha amd64 i386 ia64 m68k powerpc s390 kfreebsd-i386 kfreebsd-amd64
+Depends: ${shlibs:Depends}, lsb-base (>= 3.0-6), adduser
+Replaces: pdns
+Recommends: pdns-doc
+Description: PowerDNS recursor
+ PowerDNS is a versatile nameserver which supports a large number
+ of different backends ranging from simple zonefiles to relational
+ databases and load balancing/failover algorithms.
+ PowerDNS tries to emphasize speed and security.
+ .
+ This is the recursive nameserver that goes out to the internet and
+ resolve queries about other domains.
+
--- pdns-recursor-3.1.7.orig/debian/watch
+++ pdns-recursor-3.1.7/debian/watch
@@ -0,0 +1,5 @@
+# See uscan(1) for format
+
+version=3
+http://downloads.powerdns.com/releases/pdns-recursor-([\d\.]+)\.tar\.bz2
+
--- pdns-recursor-3.1.7.orig/debian/compat
+++ pdns-recursor-3.1.7/debian/compat
@@ -0,0 +1 @@
+5
--- pdns-recursor-3.1.7.orig/debian/pdns-recursor.postinst
+++ pdns-recursor-3.1.7/debian/pdns-recursor.postinst
@@ -0,0 +1,49 @@
+#!/bin/sh
+#
+#
+
+set -e
+
+case "$1" in
+  configure)
+    if [ -z "`getent group pdns`" ]; then
+      addgroup --quiet --system pdns
+    fi
+    if [ -z "`getent passwd pdns`" ]; then
+      echo -n "Creating user and group pdns..."
+      adduser --quiet --system --home /var/spool/powerdns --shell /bin/false --ingroup pdns --disabled-password --disabled-login --gecos "PowerDNS" pdns
+      echo "done"
+    fi
+  ;;
+
+  *)
+    echo "postinst called with unknown argument \`$1'" >&2
+    exit 1
+  ;;
+esac
+
+# Remove old stuff (Coming from before 2.9.17) if Sarge is not supported anymore
+# this can be replaced by dh_installinit in debian/rules.
+if [ -f /etc/init.d/pdns_recursor ]; then
+  if [ -x /usr/sbin/invoke-rc.d ]; then
+    invoke-rc.d pdns_recursor stop || exit $?
+  else
+    /etc/init.d/pdns_recursor stop || exit $?
+  fi
+  update-rc.d -f pdns_recursor remove >/dev/null 2>&1
+  rm -f /etc/init.d/pdns_recursor
+fi
+
+if [ -x "/etc/init.d/pdns-recursor" ]; then
+  update-rc.d pdns-recursor defaults 19 85 >/dev/null
+  if [ -x /usr/sbin/invoke-rc.d ]; then
+    invoke-rc.d pdns-recursor start || exit $?
+  else
+    /etc/init.d/pdns-recursor start || exit $?
+  fi
+fi
+
+#DEBHELPER#
+
+exit 0
+
--- pdns-recursor-3.1.7.orig/debian/pdns-recursor.logcheck.ignore.server
+++ pdns-recursor-3.1.7/debian/pdns-recursor.logcheck.ignore.server
@@ -0,0 +1,4 @@
+^\w{3} [ :0-9]{11} [._[:alnum:]-]+ pdns_recursor\[[0-9]+\]: stats: [0-9]+ questions, [0-9]+ cache entries, [0-9]+ negative entries, [0-9]+% cache hits
+^\w{3} [ :0-9]{11} [._[:alnum:]-]+ pdns_recursor\[[0-9]+\]: stats: throttle map: [0-9]+, ns speeds: [0-9]+
+^\w{3} [ :0-9]{11} [._[:alnum:]-]+ pdns_recursor\[[0-9]+\]: stats: outpacket\/query ratio [0-9]+%, [0-9]+% throttled, [0-9]+ no-delegation drops
+^\w{3} [ :0-9]{11} [._[:alnum:]-]+ pdns_recursor\[[0-9]+\]: stats: [0-9]+ outgoing tcp connections, [0-9]+ queries running, [0-9]+ outgoing timeouts
--- pdns-recursor-3.1.7.orig/debian/pdns-recursor.prerm
+++ pdns-recursor-3.1.7/debian/pdns-recursor.prerm
@@ -0,0 +1,45 @@
+#! /bin/sh
+# prerm script for pdns-recursor
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+#        * <prerm> `remove'
+#        * <old-prerm> `upgrade' <new-version>
+#        * <new-prerm> `failed-upgrade' <old-version>
+#        * <conflictor's-prerm> `remove' `in-favour' <package> <new-version>
+#        * <deconfigured's-prerm> `deconfigure' `in-favour'
+#          <package-being-installed> <version> `removing'
+#          <conflicting-package> <version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+    remove|upgrade|deconfigure)
+        ;;
+    failed-upgrade)
+        ;;
+    *)
+        echo "prerm called with unknown argument \`$1'" >&2
+        exit 1
+    ;;
+esac
+
+if [ -x "/etc/init.d/pdns-recursor" ]; then
+  if [ -x /usr/sbin/invoke-rc.d ] ; then
+    invoke-rc.d pdns-recursor stop || exit $?
+  else
+    /etc/init.d/pdns-recursor stop || exit $?
+  fi
+fi
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
+
--- pdns-recursor-3.1.7.orig/debian/pdns-recursor.manpages
+++ pdns-recursor-3.1.7/debian/pdns-recursor.manpages
@@ -0,0 +1,2 @@
+pdns_recursor.1
+rec_control.1
--- pdns-recursor-3.1.7.orig/debian/pdns-recursor.install
+++ pdns-recursor-3.1.7/debian/pdns-recursor.install
@@ -0,0 +1,5 @@
+debian/tmp/usr/sbin/pdns_recursor usr/sbin/
+debian/tmp/usr/bin/rec_control usr/bin/
+debian/config/recursor.conf etc/powerdns/
+debian/init.d/pdns-recursor etc/init.d/
+debian/default/pdns-recursor etc/default/
--- pdns-recursor-3.1.7.orig/debian/copyright
+++ pdns-recursor-3.1.7/debian/copyright
@@ -0,0 +1,25 @@
+This is the Debian prepackaged version of pDNS, the PowerDNS
+nameserver.
+
+pDNS can be downloaded from http://www.powerdns.com/
+
+Copyright and license:
+
+    Copyright 2002 PowerDNS.COM BV
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of version 2 of the GNU General Public License as
+    published by the Free Software Foundation.
+
+    Additionally, the license of this program contains a special
+    exception which allows to distribute the program in binary form when
+    it is linked against OpenSSL.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+On Debian systems, the complete text of the GNU General Public License 
+can be found in /usr/share/common-licenses/GPL-2
+
--- pdns-recursor-3.1.7.orig/debian/patches/00list
+++ pdns-recursor-3.1.7/debian/patches/00list
@@ -0,0 +1,5 @@
+# Apply following patches
+gcc-4.2-ftbfs-fix
+do-not-strip-binaries
+CVE-2009-4009
+CVE-2009-4010
--- pdns-recursor-3.1.7.orig/debian/patches/do-not-strip-binaries.dpatch
+++ pdns-recursor-3.1.7/debian/patches/do-not-strip-binaries.dpatch
@@ -0,0 +1,23 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## do-not-strip-binaries.dpatch by Christoph Haas <haas@debian.org>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Prevent stripping binaries upstream. Should be done by dh_strip.
+
+@DPATCH@
+diff -urNad trunk~/Makefile trunk/Makefile
+--- trunk~/Makefile	2007-11-09 22:41:01.000000000 +0100
++++ trunk/Makefile	2007-11-09 22:45:18.000000000 +0100
+@@ -54,10 +54,10 @@
+ install: all
+ 	-mkdir -p $(DESTDIR)/$(SBINDIR)
+ 	mv pdns_recursor $(DESTDIR)/$(SBINDIR)
+-	strip $(DESTDIR)/$(SBINDIR)/pdns_recursor
++	#strip $(DESTDIR)/$(SBINDIR)/pdns_recursor
+ 	mkdir -p $(DESTDIR)/$(BINDIR)
+ 	mv rec_control $(DESTDIR)/$(BINDIR)
+-	strip $(DESTDIR)/$(BINDIR)/rec_control
++	#strip $(DESTDIR)/$(BINDIR)/rec_control
+ 	-mkdir -p $(DESTDIR)/$(CONFIGDIR)
+ 	$(DESTDIR)/$(SBINDIR)/pdns_recursor --config > $(DESTDIR)/$(CONFIGDIR)/recursor.conf-dist
+ 	-mkdir -p $(DESTDIR)/usr/share/man/man1
--- pdns-recursor-3.1.7.orig/debian/patches/CVE-2009-4009.dpatch
+++ pdns-recursor-3.1.7/debian/patches/CVE-2009-4009.dpatch
@@ -0,0 +1,23 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## CVE-2009-4009.dpatch, based on a patch by Bert Hubert
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: CVE-2009-4009
+
+diff -uBbr pdns-recursor-3.1.7.1/pdns_recursor.cc pdns-recursor-3.1.7.2/pdns_recursor.cc
+--- pdns-recursor-3.1.7.1/pdns_recursor.cc	2009-08-02 22:22:51.000000000 +0200
++++ pdns-recursor-3.1.7.2/pdns_recursor.cc	2009-12-26 13:22:42.000000000 +0100
+@@ -823,8 +823,11 @@
+     *dst++='.';
+ 
+   while((labellen=*pos++) && pos < end) { // "scan and copy"
+-    if(dst >= lend)
+-      throw runtime_error("Label length exceeded destination length");
++    if(dst + labellen >= lend) {
++      *qname = 0;
++      return; 
++      // throw runtime_error("Label length exceeded destination length");
++    }
+     for(;labellen;--labellen)
+       *dst++ = *pos++;
+     *dst++='.';
--- pdns-recursor-3.1.7.orig/debian/patches/gcc-4.2-ftbfs-fix.dpatch
+++ pdns-recursor-3.1.7/debian/patches/gcc-4.2-ftbfs-fix.dpatch
@@ -0,0 +1,28 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## gcc-4.2-ftbfs-fix.dpatch by Matthijs Mohlmann <matthijs@cacholong.nl>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: No description.
+
+@DPATCH@
+diff -urNad trunk~/recursor_cache.cc trunk/recursor_cache.cc
+--- trunk~/recursor_cache.cc	2007-07-15 17:07:30.000000000 +0200
++++ trunk/recursor_cache.cc	2007-07-15 17:08:17.688738676 +0200
+@@ -10,7 +10,7 @@
+ 
+ #include "config.h"
+ 
+-#ifdef GCC_SKIP_LOCKING
++/*#ifdef GCC_SKIP_LOCKING
+ #include <bits/atomicity.h>
+ // This code is ugly but does speedup the recursor tremendously on multi-processor systems, and even has a large effect (20, 30%) on uniprocessor 
+ namespace __gnu_cxx
+@@ -31,7 +31,7 @@
+     *__mem+=__val;
+   }
+ }
+-#endif
++#endif*/
+ 
+ string simpleCompress(const string& label)
+ {
--- pdns-recursor-3.1.7.orig/debian/patches/CVE-2009-4010.dpatch
+++ pdns-recursor-3.1.7/debian/patches/CVE-2009-4010.dpatch
@@ -0,0 +1,645 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## CVE-2009-4010.dpatch, based on patches by Bert Hubert
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: CVE-2009-4010
+
+@DPATCH@
+diff -urNad pdns-recursor-3.1.7~/dnsparser.cc pdns-recursor-3.1.7/dnsparser.cc
+--- pdns-recursor-3.1.7~/dnsparser.cc	2008-07-09 21:42:48.000000000 +0200
++++ pdns-recursor-3.1.7/dnsparser.cc	2010-01-06 22:55:59.760178145 +0100
+@@ -74,20 +74,38 @@
+   vector<uint8_t> d_record;
+ };
+ 
+-static const string EncodeDNSLabel(const string& input)  
++static const string EncodeDNSLabel(const string& input) 
+ {  
+-  typedef vector<string> parts_t;  
+-  parts_t parts;  
+-  stringtok(parts,input,".");   	  	 
+-  string ret;  
+-  for(parts_t::const_iterator i=parts.begin(); i!=parts.end(); ++i) {  
+-    ret.append(1,(char)i->length());  
+-    ret.append(*i);  
+-  }  
+-  ret.append(1,(char)0);  
+-  return ret;  
++  if(input.length() == 1 && input[0]=='.') // otherwise we encode .. (long story)
++    return string (1, 0); 
++    
++  labelparts_t parts;
++  bool unescapedSomething = labeltokUnescape(parts, input);
++  string ret;
++  
++  if(!unescapedSomething) {
++    for(labelparts_t::const_iterator i=parts.begin(); i!=parts.end(); ++i) {
++      ret.append(1, i->second - i->first);
++      ret.append(input.c_str() + i->first, i->second - i->first);
++    }
++
++  } else {
++    for(labelparts_t::const_iterator i=parts.begin(); i!=parts.end(); ++i) {
++      string part(input.c_str() + i->first, i->second - i->first);
++      boost::replace_all(part, "\\\\", "\\"); 
++      boost::replace_all(part, "\\.", ".");   
++    
++      ret.append(1, part.length());
++      ret.append(part);
++    }  
++  }    
++  ret.append(1, 0);
++  // cerr<<"Asked to encode '"<<input<<"', returning: '"<<makeHexDump(ret)<<endl;
++  // cerr<<"parts length: "<<parts.size()<<endl;
++  return ret;
+ }  
+ 
++
+ shared_ptr<DNSRecordContent> DNSRecordContent::unserialize(const string& qname, uint16_t qtype, const string& serialized)
+ {
+   dnsheader dnsheader;
+@@ -436,7 +454,7 @@
+       // XXX FIXME THIS MIGHT BE VERY SLOW!
+       ret.reserve(ret.size() + labellen + 2);
+       for(string::size_type n = 0 ; n < labellen; ++n, frompos++) {
+-	if(content.at(frompos)=='.')
++	if(content.at(frompos)=='.' || content.at(frompos)=='\\')
+ 	  ret.append(1, '\\');
+ 	ret.append(1, content[frompos]);
+       }
+diff -urNad pdns-recursor-3.1.7~/dnsparser.hh pdns-recursor-3.1.7/dnsparser.hh
+--- pdns-recursor-3.1.7~/dnsparser.hh	2008-07-09 21:42:48.000000000 +0200
++++ pdns-recursor-3.1.7/dnsparser.hh	2010-01-06 22:55:46.694588616 +0100
+@@ -194,7 +194,7 @@
+   static uint16_t TypeToNumber(const string& name)
+   {
+     for(namemap_t::const_iterator i=getNamemap().begin(); i!=getNamemap().end();++i)
+-      if(!Utility::strcasecmp(i->second.c_str(), name.c_str()))
++      if(pdns_iequals(i->second,name))
+ 	return i->first.second;
+ 
+     throw runtime_error("Unknown DNS type '"+name+"'");
+diff -urNad pdns-recursor-3.1.7~/dnswriter.cc pdns-recursor-3.1.7/dnswriter.cc
+--- pdns-recursor-3.1.7~/dnswriter.cc	2008-07-09 21:42:48.000000000 +0200
++++ pdns-recursor-3.1.7/dnswriter.cc	2010-01-06 22:55:46.694588616 +0100
+@@ -67,7 +67,7 @@
+   d_stuff = 0; 
+   d_rollbackmarker=d_content.size();
+ 
+-  if(iequals(d_qname,d_recordqname)) {  // don't do the whole label compression thing if we *know* we can get away with "see question"
++  if(pdns_iequals(d_qname,d_recordqname)) {  // don't do the whole label compression thing if we *know* we can get away with "see question"
+     static char marker[2]={0xc0, 0x0c};
+     d_content.insert(d_content.end(), &marker[0], &marker[2]);
+   }
+@@ -153,14 +153,12 @@
+ {
+   DNSPacketWriter::lmap_t::iterator ret;
+   for(ret=lmap.begin(); ret != lmap.end(); ++ret)
+-    if(iequals(ret->first,label))
++    if(pdns_iequals(ret->first,label))
+       break;
+   return ret;
+ }
+ 
+-typedef vector<pair<string::size_type, string::size_type> > parts_t;
+-
+-bool labeltokUnescape(parts_t& parts, const string& label)
++bool labeltokUnescape(labelparts_t& parts, const string& label)
+ {
+   string::size_type epos = label.size(), lpos(0), pos;
+   bool unescapedSomething = false;
+@@ -188,7 +186,7 @@
+ // this is the absolute hottest function in the pdns recursor 
+ void DNSPacketWriter::xfrLabel(const string& label, bool compress)
+ {
+-  parts_t parts;
++  labelparts_t parts;
+ 
+   if(label.size()==1 && label[0]=='.') { // otherwise we encode '..'
+     d_record.push_back(0);
+@@ -200,7 +198,7 @@
+   // d_stuff is amount of stuff that is yet to be written out - the dnsrecordheader for example
+   unsigned int pos=d_content.size() + d_record.size() + d_stuff; 
+   string chopped;
+-  for(parts_t::const_iterator i=parts.begin(); i!=parts.end(); ++i) {
++  for(labelparts_t::const_iterator i=parts.begin(); i!=parts.end(); ++i) {
+     chopped.assign(label.c_str() + i->first);
+     lmap_t::iterator li=d_labelmap.end();
+     // see if we've written out this domain before
+@@ -218,6 +216,10 @@
+     if(unescaped) {
+       string part(label.c_str() + i -> first, i->second - i->first);
+       replace_all(part, "\\.", ".");
++      replace_all(part, "\\\\", "\\");      
++      if(part.size() > 255)
++        throw MOADNSException("Attempting to express a label of invalid size in xfrLabel");
++        
+       d_record.push_back(part.size());
+       unsigned int len=d_record.size();
+       d_record.resize(len + part.size());
+diff -urNad pdns-recursor-3.1.7~/dnswriter.hh pdns-recursor-3.1.7/dnswriter.hh
+--- pdns-recursor-3.1.7~/dnswriter.hh	2008-07-09 21:42:48.000000000 +0200
++++ pdns-recursor-3.1.7/dnswriter.hh	2010-01-06 22:55:46.694588616 +0100
+@@ -107,4 +107,8 @@
+   uint16_t d_rollbackmarker; // start of last complete packet, for rollback
+   Place d_recordplace;
+ };
++
++typedef vector<pair<std::string::size_type, std::string::size_type> > labelparts_t;
++
++bool labeltokUnescape(labelparts_t& parts, const std::string& label);
+ #endif
+diff -urNad pdns-recursor-3.1.7~/lwres.cc pdns-recursor-3.1.7/lwres.cc
+--- pdns-recursor-3.1.7~/lwres.cc	2008-07-09 21:42:48.000000000 +0200
++++ pdns-recursor-3.1.7/lwres.cc	2010-01-06 22:55:46.694588616 +0100
+@@ -155,7 +155,7 @@
+     lwr->d_tcbit=mdp.d_header.tc;
+     lwr->d_rcode=mdp.d_header.rcode;
+     
+-    if(Utility::strcasecmp(domain.c_str(), mdp.d_qname.c_str())) { 
++    if(!pdns_iequals(domain,mdp.d_qname)) { 
+       if(domain.find((char)0)==string::npos) {// embedded nulls are too noisy
+ 	L<<Logger::Notice<<"Packet purporting to come from remote server "<<ip.toString()<<" contained wrong answer: '" << domain << "' != '" << mdp.d_qname << "'" << endl;
+ 	g_stats.unexpectedCount++;
+diff -urNad pdns-recursor-3.1.7~/misc.hh pdns-recursor-3.1.7/misc.hh
+--- pdns-recursor-3.1.7~/misc.hh	2008-07-09 21:42:48.000000000 +0200
++++ pdns-recursor-3.1.7/misc.hh	2010-01-06 22:55:46.694588616 +0100
+@@ -318,54 +318,45 @@
+ {
+   return tv.tv_sec + tv.tv_usec/1000000.0f;
+ }
+-struct CIStringCompare: public binary_function<string, string, bool>  
++
++inline bool pdns_ilexicographical_compare(const std::string& a, const std::string& b)  __attribute__((pure));
++inline bool pdns_ilexicographical_compare(const std::string& a, const std::string& b) 
+ {
+-  bool operator()(const string& a, const string& b) const
+-  {
+-    const unsigned char *p1 = (const unsigned char *) a.c_str();
+-    const unsigned char *p2 = (const unsigned char *) b.c_str();
+-    int result;
+-    
+-    if (p1 == p2)
+-      return 0;
+-    
+-    while ((result = dns_tolower (*p1) - dns_tolower (*p2++)) == 0)
+-      if (*p1++ == '\0')
+-	break;
+-    
+-    return result < 0;
++  string::size_type aLen = a.length(), bLen = b.length(), n;
++  const char *aPtr = a.c_str(), *bPtr = b.c_str();
++  int result;
++  
++  for(n = 0 ; n < aLen && n < bLen ; ++n) {
++      if((result = dns_tolower(*aPtr++) - dns_tolower(*bPtr++))) {
++        return result < 0;
++      }
+   }
++  if(n == aLen && n == bLen) // strings are equal (in length)
++    return 0; 
++  if(n == aLen) // first string was shorter
++    return true; 
++  return false;
++}
+ 
+-  bool operator()(const string& a, const char* b) const
+-  {
+-    const unsigned char *p1 = (const unsigned char *) a.c_str();
+-    const unsigned char *p2 = (const unsigned char *) b;
+-    int result;
+-    
+-    if (p1 == p2)
+-      return 0;
+-    
+-    while ((result = dns_tolower (*p1) - dns_tolower (*p2++)) == 0)
+-      if (*p1++ == '\0')
+-	break;
+-    
+-    return result < 0;
++inline bool pdns_iequals(const std::string& a, const std::string& b) __attribute__((pure));
++
++inline bool pdns_iequals(const std::string& a, const std::string& b) 
++{
++  string::size_type aLen = a.length(), bLen = b.length(), n;
++  const char *aPtr = a.c_str(), *bPtr = b.c_str();
++  
++  for(n = 0 ; n < aLen && n < bLen ; ++n) {
++      if(dns_tolower(*aPtr++) != dns_tolower(*bPtr++))
++        return false;
+   }
++  return aLen == bLen; // strings are equal (in length)
++}
+ 
+-  bool operator()(const char* a, const string& b) const
++struct CIStringCompare: public binary_function<string, string, bool>  
++{
++  bool operator()(const string& a, const string& b) const
+   {
+-    const unsigned char *p1 = (const unsigned char *) a;
+-    const unsigned char *p2 = (const unsigned char *) b.c_str();
+-    int result;
+-    
+-    if (p1 == p2)
+-      return 0;
+-    
+-    while ((result = dns_tolower (*p1) - dns_tolower (*p2++)) == 0)
+-      if (*p1++ == '\0')
+-	break;
+-    
+-    return result < 0;
++    return pdns_ilexicographical_compare(a, b);
+   }
+ };
+ 
+diff -urNad pdns-recursor-3.1.7~/pdns_recursor.cc pdns-recursor-3.1.7/pdns_recursor.cc
+--- pdns-recursor-3.1.7~/pdns_recursor.cc	2010-01-06 22:55:46.626587606 +0100
++++ pdns-recursor-3.1.7/pdns_recursor.cc	2010-01-06 22:55:46.694588616 +0100
+@@ -806,45 +806,51 @@
+   }
+ }
+  
+-void questionExpand(const char* packet, uint16_t len, char* qname, int maxlen, uint16_t& type)
++static void appendEscapedLabel(string& ret, const char* begin, unsigned char labellen)
++{
++  unsigned char n = 0;
++  for(n = 0 ; n < labellen; ++n)
++    if(begin[n] == '.' || begin[n] == '\\')
++      break;
++  
++  if( n == labellen) {
++    ret.append(begin, labellen);
++    return;
++  }
++  string label(begin, labellen);
++  boost::replace_all(label, "\\",  "\\\\");
++  boost::replace_all(label, ".",  "\\.");
++  ret.append(label);
++}
++
++string questionExpand(const char* packet, uint16_t len, uint16_t& type)
+ {
+   type=0;
+-  const unsigned char* end=(const unsigned char*)packet+len;
+-  unsigned char* lbegin=(unsigned char*)packet+12;
+-  unsigned char* pos=lbegin;
++  string ret;
++  if(len < 12) 
++    throw runtime_error("Error parsing question in incoming packet: packet too short");
++    
++  const unsigned char* end = (const unsigned char*)packet+len;
++  const unsigned char* pos = (const unsigned char*)packet+12;
+   unsigned char labellen;
+-
+-  // 3www4ds9a2nl0
+-  char *dst=qname;
+-  char* lend=dst + maxlen;
+   
+   if(!*pos)
+-    *dst++='.';
+-
++    ret.assign(1, '.');
++  
+   while((labellen=*pos++) && pos < end) { // "scan and copy"
+-    if(dst + labellen >= lend) {
+-      *qname = 0;
+-      return; 
+-      // throw runtime_error("Label length exceeded destination length");
+-    }
+-    for(;labellen;--labellen)
+-      *dst++ = *pos++;
+-    *dst++='.';
++    if(pos + labellen > end)
++      throw runtime_error("Error parsing question in incoming packet: label extends beyond packet");
++    
++    appendEscapedLabel(ret, (const char*) pos, labellen);
++    
++    ret.append(1, '.');
++    pos += labellen;
+   }
+-  *dst=0;
+ 
+-  if(pos + labellen + 2 <= end)  // is this correct XXX FIXME?
++  if(pos + labellen + 2 <= end)  
+     type=(*pos)*256 + *(pos+1);
+-
+-
+-  //  cerr<<"Returning: '"<< string(tmp+1, pos) <<"'\n";
+-}
+-
+-string questionExpand(const char* packet, uint16_t len, uint16_t& type)
+-{
+-  char tmp[512];
+-  questionExpand(packet, len, tmp, sizeof(tmp), type);
+-  return tmp;
++  // cerr << "returning: '"<<ret<<"'"<<endl;
++  return ret;
+ }
+ 
+ void handleNewUDPQuestion(int fd, FDMultiplexer::funcparam_t& var)
+@@ -877,59 +883,6 @@
+       }
+       else {
+ 	++g_stats.qcounter;
+-#if 0
+-	uint16_t type;
+-	char qname[256];
+-        try {
+-	   questionExpand(data, len, qname, sizeof(qname), type);  
+-        }
+-        catch(exception &e)
+-        {
+-           throw MOADNSException(e.what());
+-        }
+-	
+-	// must all be same length answers right now!
+-	if((type==QType::A || type==QType::AAAA) && dh->arcount==0 && dh->ancount==0 && dh->nscount ==0 && ntohs(dh->qdcount)==1 ) {
+-	  char *record[10];
+-	  uint16_t rlen[10];
+-	  uint32_t ttd[10];
+-	  int count;
+-	  if((count=RC.getDirect(g_now.tv_sec, qname, QType(type), ttd, record, rlen))) { 
+-	    if(len + count*(sizeof(dnsrecordheader) + 2 + rlen[0]) > 512)
+-	      goto slow;
+-
+-	    random_shuffle(record, &record[count]);
+-	    dh->qr=1;
+-	    dh->ra=1;
+-	    dh->ancount=ntohs(count);
+-	    for(int n=0; n < count ; ++n) {
+-	      memcpy(data+len, "\xc0\x0c", 2); // answer label pointer
+-	      len+=2;
+-	      struct dnsrecordheader drh;
+-	      drh.d_type=htons(type);
+-	      drh.d_class=htons(1);
+-	      drh.d_ttl=htonl(ttd[n] - g_now.tv_sec);
+-	      drh.d_clen=htons(rlen[n]);
+-	      memcpy(data+len, &drh, sizeof(drh));
+-	      len+=sizeof(drh);
+-	      memcpy(data+len, record[n], rlen[n]);
+-	      len+=rlen[n];
+-	    }
+-	    RDTSC(tsc2);      	    
+-	    g_stats.shunted++;
+-	    sendto(fd, data, len, 0, (struct sockaddr *)(&fromaddr), fromaddr.getSocklen());
+-//	    cerr<<"shunted: " << (tsc2-tsc1) / 3000.0 << endl;
+-	    return;
+-	  }
+-	}
+-	else {
+-	  if(type!=QType::A && type!=QType::AAAA)
+-    	    g_stats.noShuntWrongType++;
+-          else
+-            g_stats.noShuntWrongQuestion++;
+-        }
+-      slow:
+-#endif
+ 	DNSComboWriter* dc = new DNSComboWriter(data, len, g_now);
+ 	dc->setSocket(fd);
+ 	dc->setRemote(&fromaddr);
+@@ -1307,7 +1260,13 @@
+     pident.remote=fromaddr;
+     pident.id=dh.id;
+     pident.fd=fd;
+-    pident.domain=questionExpand(data, len, pident.type); // don't copy this from above - we need to do the actual read
++    try {
++      pident.domain=questionExpand(data, len, pident.type); // don't copy this from above - we need to do the actual read
++    }
++    catch(...) {
++      return;
++    }
++    
+     string packet;
+     packet.assign(data, len);
+ 
+@@ -1325,7 +1284,7 @@
+       
+       for(MT_t::waiters_t::iterator mthread=MT->d_waiters.begin(); mthread!=MT->d_waiters.end(); ++mthread) {
+ 	if(pident.fd==mthread->key.fd && mthread->key.remote==pident.remote &&  mthread->key.type == pident.type &&
+-	   !Utility::strcasecmp(pident.domain.c_str(), mthread->key.domain.c_str())) {
++	   pdns_iequals(pident.domain,mthread->key.domain)) {
+ 	  mthread->key.nearMisses++;
+ 	}
+       }
+diff -urNad pdns-recursor-3.1.7~/recursor_cache.cc pdns-recursor-3.1.7/recursor_cache.cc
+--- pdns-recursor-3.1.7~/recursor_cache.cc	2010-01-06 22:55:46.618588257 +0100
++++ pdns-recursor-3.1.7/recursor_cache.cc	2010-01-06 22:55:46.694588616 +0100
+@@ -113,74 +113,13 @@
+   return ret;
+ }
+ 
+-int MemRecursorCache::getDirect(time_t now, const char* qname, const QType& qt, uint32_t ttd[10], char* data[10], uint16_t len[10])
+-{
+-  if(!d_cachecachevalid || Utility::strcasecmp(d_cachedqname.c_str(), qname)) {
+-//    cerr<<"had cache cache miss for '"<<qname<<"'"<<endl;
+-    d_cachedqname=qname;
+-    d_cachecache=d_cache.equal_range(tie(qname));
+-    d_cachecachevalid=true;
+-  }
+-  else
+-    ;
+-  //    cerr<<"had cache cache hit!"<<endl;
+-
+-  if(d_cachecache.first == d_cachecache.second) {
+-    g_stats.noShuntNoMatch++;
+-    return false;
+-  }
+-
+-  pair<cache_t::iterator, cache_t::iterator> range = d_cachecache;
+-  
+-  unsigned int n=0;
+-  for(;range.first != range.second; ++range.first) {
+-    if(range.first->d_qtype == QType::CNAME) { // if we see a cname, we need the whole shebang (for now)
+-      g_stats.noShuntCNAME++;
+-      return false;
+-    }
+-    if(range.first->d_qtype != qt.getCode())
+-      continue;
+-    if(range.first->getTTD() < (unsigned int) now) {
+-      g_stats.noShuntExpired++;
+-      return false;
+-    }
+-    
+-    if(range.first->d_records.empty() || range.first->d_records.size() > 9 ) {
+-      g_stats.noShuntSize++;
+-      return false;
+-    }
+-    
+-    size_t limit=range.first->d_records.size();
+-    n=0;
+-    for(; n < limit; ++n) {
+-      data[n]=(char*)range.first->d_records[n].d_string.c_str();
+-      len[n]=range.first->d_records[n].d_string.length();
+-      ttd[n]=range.first->d_records[n].d_ttd;
+-    }
+-    if(n<10) {
+-      data[n]=0;
+-      typedef cache_t::nth_index<1>::type sequence_t;
+-      sequence_t& sidx=d_cache.get<1>();
+-      sequence_t::iterator si=d_cache.project<1>(range.first);
+-      sidx.relocate(sidx.end(), si); // move it in the LRU list 
+-      // can't yet return, need to figure out if there isn't a CNAME that messes things up
+-    }
+-    else
+-      return false;
+-  }
+-  if(!n)
+-    g_stats.noShuntNoMatch++;
+-  return n;
+-
+-}
+-
+ int MemRecursorCache::get(time_t now, const string &qname, const QType& qt, set<DNSResourceRecord>* res)
+ {
+   unsigned int ttd=0;
+ 
+   //  cerr<<"looking up "<< qname+"|"+qt.getName()<<"\n";
+ 
+-  if(!d_cachecachevalid || Utility::strcasecmp(d_cachedqname.c_str(), qname.c_str())) {
++  if(!d_cachecachevalid || !pdns_iequals(d_cachedqname,qname)) {
+     //    cerr<<"had cache cache miss"<<endl;
+     d_cachedqname=qname;
+     d_cachecache=d_cache.equal_range(tie(qname));
+diff -urNad pdns-recursor-3.1.7~/syncres.cc pdns-recursor-3.1.7/syncres.cc
+--- pdns-recursor-3.1.7~/syncres.cc	2008-07-09 21:42:48.000000000 +0200
++++ pdns-recursor-3.1.7/syncres.cc	2010-01-06 22:55:46.698588523 +0100
+@@ -62,8 +62,8 @@
+ int SyncRes::beginResolve(const string &qname, const QType &qtype, uint16_t qclass, vector<DNSResourceRecord>&ret)
+ {
+   s_queries++;
+-  if( (qtype.getCode()==QType::PTR && !Utility::strcasecmp(qname.c_str(), "1.0.0.127.in-addr.arpa.")) ||
+-      (qtype.getCode()==QType::A && qname.length()==10 && !Utility::strcasecmp(qname.c_str(), "localhost."))) {
++  if( (qtype.getCode()==QType::PTR && pdns_iequals(qname, "1.0.0.127.in-addr.arpa.")) ||
++      (qtype.getCode()==QType::A && qname.length()==10 && pdns_iequals(qname, "localhost."))) {
+     ret.clear();
+     DNSResourceRecord rr;
+     rr.qname=qname;
+@@ -79,7 +79,7 @@
+   }
+ 
+   if(qclass==3 && qtype.getCode()==QType::TXT && 
+-        (!Utility::strcasecmp(qname.c_str(), "version.bind.") || !Utility::strcasecmp(qname.c_str(), "id.server.") || !Utility::strcasecmp(qname.c_str(), "version.pdns.") ) 
++        (pdns_iequals(qname, "version.bind.") || pdns_iequals(qname, "id.server.") || pdns_iequals(qname, "version.pdns.") ) 
+      ) {
+     ret.clear();
+     DNSResourceRecord rr;
+@@ -87,7 +87,7 @@
+     rr.qtype=qtype;
+     rr.qclass=qclass;
+     rr.ttl=86400;
+-    if(!Utility::strcasecmp(qname.c_str(),"version.bind.")  || !Utility::strcasecmp(qname.c_str(),"version.pdns."))
++    if(pdns_iequals(qname, "version.bind.")  || pdns_iequals(qname, "version.pdns."))
+       rr.content="\""+::arg()["version-string"]+"\"";
+     else
+       rr.content="\""+s_serverID+"\"";
+@@ -571,10 +571,9 @@
+ {
+   bool operator()(const pair<string, QType>& a, const pair<string, QType>& b) const
+   {
+-    int cmp=Utility::strcasecmp(a.first.c_str(), b.first.c_str());
+-    if(cmp < 0)
++    if(pdns_ilexicographical_compare(a.first, b.first))
+       return true;
+-    if(cmp > 0)
++    if(pdns_ilexicographical_compare(b.first, a.first))
+       return false;
+ 
+     return a.second < b.second;
+@@ -829,7 +828,7 @@
+ 	  newtarget=i->content;
+ 	}
+ 	// for ANY answers we *must* have an authoritive answer
+-	else if(i->d_place==DNSResourceRecord::ANSWER && !Utility::strcasecmp(i->qname.c_str(),qname.c_str()) && 
++	else if(i->d_place==DNSResourceRecord::ANSWER && pdns_iequals(i->qname,qname) && 
+ 		(
+ 		 i->qtype==qtype || (lwr.d_aabit && (qtype==QType(QType::ANY) || magicAddrMatch(qtype, i->qtype) ) )
+ 		) 
+diff -urNad pdns-recursor-3.1.7~/syncres.hh pdns-recursor-3.1.7/syncres.hh
+--- pdns-recursor-3.1.7~/syncres.hh	2008-07-09 21:42:48.000000000 +0200
++++ pdns-recursor-3.1.7/syncres.hh	2010-01-06 22:55:46.698588523 +0100
+@@ -434,12 +434,11 @@
+     if( tie(remote, ourSock, type) > tie(b.remote, bSock, b.type))
+       return false;
+ 
+-    int cmp=Utility::strcasecmp(domain.c_str(), b.domain.c_str());
+-    if(cmp < 0)
++    if(pdns_ilexicographical_compare(domain,b.domain))
+       return true;
+-    if(cmp > 0)
+-      return false;
+ 
++    if(pdns_ilexicographical_compare(b.domain,domain))
++      return false;
+     return tie(fd, id) < tie(b.fd, b.id);
+   }
+ };
+@@ -455,8 +454,7 @@
+     if( tie(a.remote, ourSock, a.type) > tie(b.remote, bSock, b.type))
+       return false;
+ 
+-    int cmp=Utility::strcasecmp(a.domain.c_str(), b.domain.c_str());
+-    return cmp < 0;
++    return pdns_ilexicographical_compare(a.domain,b.domain);
+   }
+ };
+ extern MemRecursorCache RC;
+diff -urNad pdns-recursor-3.1.7~/unix_utility.cc pdns-recursor-3.1.7/unix_utility.cc
+--- pdns-recursor-3.1.7~/unix_utility.cc	2008-07-09 21:42:48.000000000 +0200
++++ pdns-recursor-3.1.7/unix_utility.cc	2010-01-06 22:55:46.698588523 +0100
+@@ -174,13 +174,6 @@
+   ::srandom(seed);
+ }
+ 
+-// Compares two string, ignoring the case.
+-int Utility::strcasecmp( const char *s1, const char *s2 )
+-{
+-  return ::strcasecmp( s1, s2 );
+-}
+-
+-
+ // Writes a vector.
+ int Utility::writev(int socket, const iovec *vector, size_t count )
+ {
+diff -urNad pdns-recursor-3.1.7~/utility.hh pdns-recursor-3.1.7/utility.hh
+--- pdns-recursor-3.1.7~/utility.hh	2008-07-09 21:42:48.000000000 +0200
++++ pdns-recursor-3.1.7/utility.hh	2010-01-06 22:55:46.698588523 +0100
+@@ -187,9 +187,6 @@
+   //! Sets the random seed.
+   static void srandom( unsigned int seed );
+ 
+-  //! Compares two strings and ignores case.
+-  static int strcasecmp( const char *s1, const char *s2 );
+-
+   //! Drops the program's privileges.
+   static void dropPrivs( int uid, int gid );
+   
+diff -urNad pdns-recursor-3.1.7~/win32_utility.cc pdns-recursor-3.1.7/win32_utility.cc
+--- pdns-recursor-3.1.7~/win32_utility.cc	2008-07-09 21:42:48.000000000 +0200
++++ pdns-recursor-3.1.7/win32_utility.cc	2010-01-06 22:55:46.698588523 +0100
+@@ -379,14 +379,6 @@
+   srand( seed );
+ }
+ 
+-
+-// Compares two string, ignoring the case.
+-int Utility::strcasecmp( const char *s1, const char *s2 )
+-{
+-  return strcmp( s1, s2 );
+-}
+-
+-
+ // Sleeps for a number of microseconds.
+ void Utility::usleep( unsigned long usec )
+ {
+diff -urNad pdns-recursor-3.1.7~/zoneparser-tng.cc pdns-recursor-3.1.7/zoneparser-tng.cc
+--- pdns-recursor-3.1.7~/zoneparser-tng.cc	2008-07-09 21:42:48.000000000 +0200
++++ pdns-recursor-3.1.7/zoneparser-tng.cc	2010-01-06 22:55:46.698588523 +0100
+@@ -303,7 +303,7 @@
+ 
+     // cout<<"Next part: '"<<nextpart<<"'"<<endl;
+     
+-    if(!Utility::strcasecmp(nextpart.c_str(), "IN")) {
++    if(pdns_iequals(nextpart, "IN")) {
+       // cout<<"Ignoring 'IN'\n";
+       continue;
+     }
--- pdns-recursor-3.1.7.orig/debian/default/pdns-recursor
+++ pdns-recursor-3.1.7/debian/default/pdns-recursor
@@ -0,0 +1,5 @@
+# Variables for PowerDNS recursor
+#
+# Set START to yes to start the pdns-recursor
+START=yes
+
--- pdns-recursor-3.1.7.orig/debian/config/recursor.conf
+++ pdns-recursor-3.1.7/debian/config/recursor.conf
@@ -0,0 +1,221 @@
+# Autogenerated configuration file template
+#################################
+# aaaa-additional-processing	turn on to do AAAA additional processing (slow)
+#
+# aaaa-additional-processing=off
+
+#################################
+# allow-from	If set, only allow these comma separated netmasks to recurse
+#
+# allow-from=127.0.0.0/8, 10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, ::1/128, fe80::/10
+
+#################################
+# allow-from-file	If set, load allowed netmasks from this file
+#
+# allow-from-file=
+
+#################################
+# auth-can-lower-ttl	If we follow RFC 2181 to the letter, an authoritative server can lower the TTL of NS records
+#
+# auth-can-lower-ttl=off
+
+#################################
+# auth-zones	Zones for which we have authoritative data, comma separated domain=file pairs 
+#
+# auth-zones=
+
+#################################
+# chroot	switch to chroot jail
+#
+# chroot=
+
+#################################
+# client-tcp-timeout	Timeout in seconds when talking to TCP clients
+#
+# client-tcp-timeout=2
+
+#################################
+# config-dir	Location of configuration directory (recursor.conf)
+#
+# config-dir=/etc/powerdns/
+
+#################################
+# daemon	Operate as a daemon
+#
+# daemon=yes
+
+#################################
+# delegation-only	Which domains we only accept delegations from
+#
+# delegation-only=com,net
+
+#################################
+# dont-query	If set, do not query these netmasks for DNS data
+#
+# dont-query=127.0.0.0/8, 10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, ::1/128, fe80::/10
+dont-query=
+
+#################################
+# entropy-source	If set, read entropy from this file
+#
+# entropy-source=/dev/urandom
+
+#################################
+# export-etc-hosts	If we should serve up contents from /etc/hosts
+#
+# export-etc-hosts=off
+
+#################################
+# fork	If set, fork the daemon for possible double performance
+#
+# fork=no
+
+#################################
+# forward-zones	Zones for which we forward queries, comma separated domain=ip pairs
+#
+# forward-zones=
+
+#################################
+# forward-zones-file	File with domain=ip pairs for forwarding
+#
+# forward-zones-file=
+
+#################################
+# hint-file	If set, load root hints from this file
+#
+# hint-file=
+
+#################################
+# ignore-rd-bit	Assume each packet requires recursion, for compatability
+#
+# ignore-rd-bit=off
+
+#################################
+# local-address	IP addresses to listen on, separated by spaces or commas. Also accepts ports.
+#
+local-address=127.0.0.1
+
+#################################
+# local-port	port to listen on
+#
+local-port=53
+
+#################################
+# log-common-errors	If we should log rather common errors
+#
+# log-common-errors=yes
+
+#################################
+# logging-facility	Facility to log messages as. 0 corresponds to local0
+#
+# logging-facility=
+
+#################################
+# max-cache-entries	If set, maximum number of entries in the main cache
+#
+# max-cache-entries=0
+
+#################################
+# max-negative-ttl	maximum number of seconds to keep a negative cached entry in memory
+#
+# max-negative-ttl=3600
+
+#################################
+# max-tcp-clients	Maximum number of simultaneous TCP clients
+#
+# max-tcp-clients=128
+
+#################################
+# max-tcp-per-client	If set, maximum number of TCP sessions per client (IP address)
+#
+# max-tcp-per-client=0
+
+#################################
+# no-shuffle	Don't change
+#
+# no-shuffle=off
+
+#################################
+# query-local-address	Source IP address for sending queries
+#
+# query-local-address=0.0.0.0
+
+#################################
+# query-local-address6	Source IPv6 address for sending queries
+#
+# query-local-address6=
+
+#################################
+# quiet	Suppress logging of questions and answers
+#
+quiet=yes
+
+#################################
+# remotes-ringbuffer-entries	maximum number of packets to store statistics for
+#
+# remotes-ringbuffer-entries=0
+
+#################################
+# serve-rfc1918	If we should be authoritative for RFC 1918 private IP space
+#
+# serve-rfc1918=
+
+#################################
+# server-id	Returned when queried for 'id.server' TXT, defaults to hostname
+#
+# server-id=
+
+#################################
+# setgid	If set, change group id to this gid for more security
+#
+setgid=pdns
+
+#################################
+# setuid	If set, change user id to this uid for more security
+#
+setuid=pdns
+
+#################################
+# single-socket	If set, only use a single socket for outgoing queries
+#
+# single-socket=off
+
+#################################
+# soa-minimum-ttl	Don't change
+#
+# soa-minimum-ttl=0
+
+#################################
+# soa-serial-offset	Don't change
+#
+# soa-serial-offset=0
+
+#################################
+# socket-dir	Where the controlsocket will live
+# HINT: If you change this from the default /var/run then rec_control
+#       will still search in /var/run for the socket file. Keep in mind
+#       to run it as 'rec_control --socket-dir=/your/socket/directory' then.
+#
+# socket-dir=/var/run/
+
+#################################
+# spoof-nearmiss-max	If non-zero, assume spoofing after this many near misses
+#
+# spoof-nearmiss-max=20
+
+#################################
+# stack-size	stack size per mthread
+#
+# stack-size=200000
+
+#################################
+# trace	if we should output heaps of logging
+#
+# trace=off
+
+#################################
+# version-string	string reported on version.pdns or version.bind
+#
+# version-string=PowerDNS Recursor 3.1.5 $Id: pdns_recursor.cc 1170 2008-03-22 20:43:44Z ahu $
+
+
--- pdns-recursor-3.1.7.orig/debian/init.d/pdns-recursor
+++ pdns-recursor-3.1.7/debian/init.d/pdns-recursor
@@ -0,0 +1,165 @@
+#!/bin/sh
+### BEGIN INIT INFO
+# Provides:          pdns-recursor
+# Required-Start:    networking
+# Required-Stop:     networking
+# Default-Start:     2 3 4 5
+# Default-Stop:      0 6
+# Short-Description: Start the recursor at boot time.
+### END INIT INFO
+
+#
+# Authors:	Matthijs Mohlmann <matthijs@cacholong.nl>
+#           Christoph Haas <haas@debian.org>
+# 
+# Thanks to:
+# Thomas Hood <jdthood@aglu.demon.nl>
+#
+# initscript for PowerDNS recursor
+
+set -e
+
+. /lib/lsb/init-functions
+
+PATH=/sbin:/bin:/usr/sbin:/usr/bin
+DESC="PowerDNS recursor"
+NAME=pdns_recursor
+DAEMON=/usr/sbin/$NAME
+# Derive the socket-dir setting from /etc/powerdns/recursor.conf
+# or fall back to the default /var/run if not specified there.
+PIDDIR=$(awk -F= '/^socket-dir=/ {print $2}' /etc/powerdns/recursor.conf)
+if [ -z "$PIDDIR" ]; then PIDDIR=/var/run; fi
+PIDFILE=$PIDDIR/$NAME.pid
+
+# Gracefully exit if the package has been removed.
+test -x $DAEMON || exit 0
+
+# Read config file if it is present.
+if [ -r /etc/default/pdns-recursor ]; then
+  . /etc/default/pdns-recursor
+fi
+
+start() {
+# Return
+#  0 if daemon has been started / was already running
+#  >0 if daemon could not be started
+  start-stop-daemon --start --oknodo --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null || return 0
+  start-stop-daemon --start --oknodo --quiet --pidfile $PIDFILE --exec $DAEMON || return 2
+}
+
+start_resolvconf() {
+  if [ -x /sbin/resolvconf ]; then
+    echo "nameserver 127.0.0.1" | /sbin/resolvconf -a lo.pdns-recursor
+  fi
+  return 0
+}
+
+stop() {
+  start-stop-daemon --stop --oknodo --quiet --retry=TERM/5/KILL/5 --pidfile $PIDFILE --name $NAME
+  rm -f $PIDFILE	# just in case
+}
+
+force_stop() {
+    killall -v -9 pdns_recursor
+    echo "killed"
+}
+
+stop_resolvconf() {
+  if [ -x /sbin/resolvconf ]; then
+    /sbin/resolvconf -d lo.pdns-recursor
+  fi
+  return 0
+}
+
+case "$1" in
+  start)
+    if [ "$START" != "yes" ]; then
+      log_begin_msg "Not starting $DESC -- disabled."
+      log_end_msg 0
+      exit 0
+    fi
+    log_daemon_msg "Starting $DESC" "pdns-recursor"
+    start
+    case "$?" in
+      0)
+        start_resolvconf
+        break
+        ;;
+      1)
+        log_progress_msg "(already running)"
+        break
+        ;;
+      *)
+        log_progress_msg " (failed)."
+        log_end_msg 1
+        exit 1
+        ;;
+    esac
+    log_end_msg 0
+  ;;
+  stop)
+    stop_resolvconf
+    log_daemon_msg "Stopping $DESC" "pdns-recursor"
+    stop
+    case "$?" in
+      0)
+        break
+        ;;
+      1)
+        log_progress_msg "(not running)"
+        break
+        ;;
+      *)
+        log_progress_msg "(failed)"
+        log_end_msg 1
+        exit 1
+        ;;
+    esac
+    log_end_msg 0
+  ;;
+  restart|force-reload)
+    if [ "$START" != "yes" ]; then
+      $0 stop
+      exit 0
+    fi
+    log_daemon_msg "Restarting $DESC" "pdns-recursor"
+    stop
+    case "$?" in
+      0|1)
+        start
+        case "$?" in
+          0)
+            log_end_msg 0
+            exit 0
+            ;;
+          1)
+            log_progress_msg "(failed -- old process still running)"
+            log_end_msg 1
+            exit 1
+            ;;
+          *)
+            log_progress_msg "(failed to start)"
+            log_end_msg 1
+            exit 1
+            ;;
+        esac
+      ;;
+      *)
+        log_progress_msg "(failed to stop)"
+        log_end_msg 1
+        exit 1
+      ;;
+    esac
+  ;;
+  force-stop)
+    force_stop
+    exit 0
+  ;;
+  *)
+    echo "Usage: $0 {start|stop|restart|force-reload|force-stop}" >&2
+    exit 3
+  ;;
+esac
+
+exit 0
+
