Hello community,

here is the log from the commit of package pdns for openSUSE:Factory checked in 
at 2016-01-01 19:48:56
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/pdns (Old)
 and      /work/SRC/openSUSE:Factory/.pdns.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "pdns"

Changes:
--------
--- /work/SRC/openSUSE:Factory/pdns/pdns.changes        2015-09-03 
18:12:20.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.pdns.new/pdns.changes   2016-01-01 
19:51:21.000000000 +0100
@@ -1,0 +2,28 @@
+Tue Nov  3 16:02:55 UTC 2015 - mich...@stroeder.com
+
+- update to 3.4.7
+
+Bug fixes:
+* Ignore invalid/empty TKEY and TSIG records (Christian Hofstaedtler)
+* Don't reply to truncated queries (Christian Hofstaedtler)
+* don't log out-of-zone ents during AXFR in (Kees Monshouwer)
+* Prevent XSS by escaping user input. Thanks to Pierre Jaury and Damien
+  Cauquil at Sysdream for pointing this out.
+* Handle NULL and boolean properly in gPGSql (Aki Tuomi)
+* Improve negative caching (Kees Monshouwer)
+* Do not divide timeout twice (Aki Tuomi)
+* Correctly sort records with a priority.
+
+Improvements:
+* Direct query answers and correct zone-rectification in the GeoIP
+backend (Aki Tuomi)
+* Use token names to identify PKCS#11 keys (Aki Tuomi)
+* Fix typo in an error message (Arjen Zonneveld)
+* limit NSEC3 iterations in bindbackend (Kees Monshouwer)
+* Initialize minbody (Aki Tuomi)
+
+New features:
+* OPENPGPKEY record-type (James Cloos and Kees Monshouwer)
+* add global soa-edit settings (Kees Monshouwer)
+
+-------------------------------------------------------------------

Old:
----
  pdns-3.4.6.tar.bz2

New:
----
  pdns-3.4.7.tar.bz2

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ pdns.spec ++++++
--- /var/tmp/diff_new_pack.zOYUmW/_old  2016-01-01 19:51:23.000000000 +0100
+++ /var/tmp/diff_new_pack.zOYUmW/_new  2016-01-01 19:51:23.000000000 +0100
@@ -17,11 +17,11 @@
 
 
 Name:           pdns
-Version:        3.4.6
+Version:        3.4.7
 Release:        0
 #
 %define pkg_name       pdns
-%define pkg_version 3.4.6
+%define pkg_version 3.4.7
 %define polarssl_version 1.3.2
 #
 %define home           %{_var}/lib/pdns

++++++ pdns-3.4.6.tar.bz2 -> pdns-3.4.7.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pdns-3.4.6/build-scripts/redhat/pdns-server-test.spec 
new/pdns-3.4.7/build-scripts/redhat/pdns-server-test.spec
--- old/pdns-3.4.6/build-scripts/redhat/pdns-server-test.spec   2015-08-27 
15:17:34.000000000 +0200
+++ new/pdns-3.4.7/build-scripts/redhat/pdns-server-test.spec   2015-11-03 
15:36:48.000000000 +0100
@@ -9,7 +9,7 @@
 Epoch:          0
 License:        GPL
 Group:          System/Servers
-Source:         http://downloads.powerdns.com/releases/pdns-3.4.6.tar.bz2
+Source:         http://downloads.powerdns.com/releases/pdns-3.4.7.tar.bz2
 
 BuildRequires:  autoconf automake
 BuildRequires:  gcc gcc-c++
@@ -30,7 +30,7 @@
 PowerDNS testbuild
 
 %prep
-%setup -q -n pdns-3.4.6
+%setup -q -n pdns-3.4.7
 
 %build
 %configure \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-3.4.6/configure new/pdns-3.4.7/configure
--- old/pdns-3.4.6/configure    2015-08-27 15:17:47.000000000 +0200
+++ new/pdns-3.4.7/configure    2015-11-03 15:37:00.000000000 +0100
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for pdns 3.4.6.
+# Generated by GNU Autoconf 2.69 for pdns 3.4.7.
 #
 #
 # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -587,8 +587,8 @@
 # Identity of this package.
 PACKAGE_NAME='pdns'
 PACKAGE_TARNAME='pdns'
-PACKAGE_VERSION='3.4.6'
-PACKAGE_STRING='pdns 3.4.6'
+PACKAGE_VERSION='3.4.7'
+PACKAGE_STRING='pdns 3.4.7'
 PACKAGE_BUGREPORT=''
 PACKAGE_URL=''
 
@@ -1470,7 +1470,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures pdns 3.4.6 to adapt to many kinds of systems.
+\`configure' configures pdns 3.4.7 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1540,7 +1540,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of pdns 3.4.6:";;
+     short | recursive ) echo "Configuration of pdns 3.4.7:";;
    esac
   cat <<\_ACEOF
 
@@ -1740,7 +1740,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-pdns configure 3.4.6
+pdns configure 3.4.7
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2347,7 +2347,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by pdns $as_me 3.4.6, which was
+It was created by pdns $as_me 3.4.7, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -3170,7 +3170,7 @@
 
 # Define the identity of the package.
  PACKAGE='pdns'
- VERSION='3.4.6'
+ VERSION='3.4.7'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -21192,7 +21192,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by pdns $as_me 3.4.6, which was
+This file was extended by pdns $as_me 3.4.7, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -21258,7 +21258,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; 
s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-pdns config.status 3.4.6
+pdns config.status 3.4.7
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-3.4.6/configure.ac new/pdns-3.4.7/configure.ac
--- old/pdns-3.4.6/configure.ac 2015-08-27 15:17:34.000000000 +0200
+++ new/pdns-3.4.7/configure.ac 2015-11-03 15:36:48.000000000 +0100
@@ -1,7 +1,7 @@
 AC_PREREQ([2.61])
 
 dnl The following lines may be patched by set-version-auth.
-AC_INIT([pdns], [3.4.6])
+AC_INIT([pdns], [3.4.7])
 AC_SUBST([DIST_HOST], [jenk...@autotest.powerdns.com])
 dnl End patch area.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-3.4.6/debian-pdns/changelog 
new/pdns-3.4.7/debian-pdns/changelog
--- old/pdns-3.4.6/debian-pdns/changelog        2015-08-27 15:17:34.000000000 
+0200
+++ new/pdns-3.4.7/debian-pdns/changelog        2015-11-03 15:36:48.000000000 
+0100
@@ -1,4 +1,4 @@
-pdns (3.4.6-1) unstable; urgency=medium
+pdns (3.4.7-1) unstable; urgency=medium
 
   * fill in the blanks
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-3.4.6/modules/bindbackend/bindbackend2.hh 
new/pdns-3.4.7/modules/bindbackend/bindbackend2.hh
--- old/pdns-3.4.6/modules/bindbackend/bindbackend2.hh  2015-08-24 
11:11:59.000000000 +0200
+++ new/pdns-3.4.7/modules/bindbackend/bindbackend2.hh  2015-11-02 
13:32:28.000000000 +0100
@@ -39,6 +39,7 @@
 #include "pdns/lock.hh"
 #include "pdns/misc.hh"
 #include "pdns/dnsbackend.hh"
+#include "pdns/logger.hh"
 
 #include "pdns/namespaces.hh"
 using namespace ::boost::multi_index;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-3.4.6/modules/bindbackend/binddnssec.cc 
new/pdns-3.4.7/modules/bindbackend/binddnssec.cc
--- old/pdns-3.4.6/modules/bindbackend/binddnssec.cc    2015-06-09 
14:28:57.000000000 +0200
+++ new/pdns-3.4.7/modules/bindbackend/binddnssec.cc    2015-11-02 
13:32:28.000000000 +0100
@@ -108,16 +108,19 @@
   getDomainMetadata(zname, "NSEC3PARAM", meta);
   if(!meta.empty())
     value=*meta.begin();
-  
-  if(value.empty()) { // "no NSEC3"
-    return false;
-  }
-     
+  else
+    return false; // "no NSEC3"
+
+  static int maxNSEC3Iterations=::arg().asNum("max-nsec3-iterations");
   if(ns3p) {
     NSEC3PARAMRecordContent* 
tmp=dynamic_cast<NSEC3PARAMRecordContent*>(DNSRecordContent::mastermake(QType::NSEC3PARAM,
 1, value));
     *ns3p = *tmp;
     delete tmp;
   }
+  if (ns3p->d_iterations > maxNSEC3Iterations) {
+    ns3p->d_iterations = maxNSEC3Iterations;
+    L<<Logger::Error<<"Number of NSEC3 iterations for zone '"<<zname<<"' is 
above 'max-nsec3-iterations'. Value adjusted to: "<<maxNSEC3Iterations<<endl;
+  }
   return true;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-3.4.6/modules/geoipbackend/geoipbackend.cc 
new/pdns-3.4.7/modules/geoipbackend/geoipbackend.cc
--- old/pdns-3.4.6/modules/geoipbackend/geoipbackend.cc 2015-06-09 
14:28:57.000000000 +0200
+++ new/pdns-3.4.7/modules/geoipbackend/geoipbackend.cc 2015-09-29 
16:50:32.000000000 +0200
@@ -4,14 +4,16 @@
 #include <glob.h>
 
 pthread_rwlock_t GeoIPBackend::s_state_lock=PTHREAD_RWLOCK_INITIALIZER;
+typedef map<string, string> service_map_t;
+typedef map<string, vector<DNSResourceRecord> > record_map_t;
 
 class GeoIPDomain {
 public:
   int id;
   string domain;
   int ttl;
-  map<string, string> services;
-  map<string, vector<DNSResourceRecord> > records;
+  service_map_t services;
+  record_map_t records;
 };
 
 static vector<GeoIPDomain> s_domains;
@@ -128,6 +130,48 @@
       dom.services[service->first.as<string>()] = service->second.as<string>();
     }
 
+    // rectify the zone, first static records
+    BOOST_FOREACH(record_map_t::value_type& item, dom.records) {
+      // ensure we have parent in records
+      string name = item.first;
+      while(chopOff(name) && endsOn(name, dom.domain)) {
+        if (dom.records.find(name) == dom.records.end()) {
+          DNSResourceRecord rr;
+          vector<DNSResourceRecord> rrs;
+          rr.domain_id = dom.id;
+          rr.ttl = dom.ttl;
+          rr.qname = name;
+          rr.qtype = "NULL";
+          rr.content = "";
+          rr.auth = 1;
+          rr.d_place = DNSResourceRecord::ANSWER;
+          rrs.push_back(rr);
+          std::swap(dom.records[name], rrs);
+        }
+      }
+    }
+
+    // then services
+    BOOST_FOREACH(service_map_t::value_type& item, dom.services) {
+      // ensure we have parent in records
+      string name = item.first;
+      while(chopOff(name) && endsOn(name, dom.domain)) {
+        if (dom.records.find(name) == dom.records.end()) {
+          DNSResourceRecord rr;
+          vector<DNSResourceRecord> rrs;
+          rr.domain_id = dom.id;
+          rr.ttl = dom.ttl;
+          rr.qname = name;
+          rr.qtype = "NULL";
+          rr.content = "";
+          rr.auth = 1;
+          rr.d_place = DNSResourceRecord::ANSWER;
+          rrs.push_back(rr);
+          std::swap(dom.records[name], rrs);
+        }
+      }
+    }
+
     tmp_domains.push_back(dom);
   }
 
@@ -188,8 +232,6 @@
     return;
   }
 
-  if (!(qtype == QType::ANY || qtype == QType::CNAME)) return;
-
   string ip = "0.0.0.0";
   bool v6 = false;
   if (pkt_p != NULL) {
@@ -203,6 +245,21 @@
   
   format = format2str(format, ip, v6);
 
+  // see if the record can be found
+  if (dom.records.count(format)) { // return static value
+    record_map_t::iterator i = dom.records.find(format);
+    BOOST_FOREACH(DNSResourceRecord rr, i->second) {
+      if (qtype == QType::ANY || rr.qtype == qtype) {
+        rr.scopeMask = (v6 ? 128 : 32);
+        d_result.push_back(rr);
+        d_result.back().qname = qdomain;
+      }
+    }
+    return;
+  }
+
+  if (!(qtype == QType::ANY || qtype == QType::CNAME)) return;
+
   DNSResourceRecord rr;
   rr.domain_id = dom.id;
   rr.qtype = QType::CNAME;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-3.4.6/modules/gpgsqlbackend/spgsql.cc 
new/pdns-3.4.7/modules/gpgsqlbackend/spgsql.cc
--- old/pdns-3.4.6/modules/gpgsqlbackend/spgsql.cc      2015-06-09 
14:28:57.000000000 +0200
+++ new/pdns-3.4.7/modules/gpgsqlbackend/spgsql.cc      2015-09-15 
12:04:49.000000000 +0200
@@ -166,8 +166,16 @@
     return false;
   }
   
-  for(int i=0;i<PQnfields(d_result);i++)
-    row.push_back(PQgetvalue(d_result,d_count,i) ?: "");
+  for(int i=0;i<PQnfields(d_result);i++) {
+    if (PQgetisnull(d_result, d_count, i)) {
+      row.push_back("");
+    } else if (PQftype(d_result, i) == 16) { // BOOLEAN
+      char *val = PQgetvalue(d_result, d_count, i);
+      row.push_back(val[0] == 't' ? "1" : "0");
+    } else {
+      row.push_back(string(PQgetvalue(d_result, d_count, i)));
+    }
+  }
   d_count++;
   return true;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-3.4.6/modules/remotebackend/httpconnector.cc 
new/pdns-3.4.7/modules/remotebackend/httpconnector.cc
--- old/pdns-3.4.6/modules/remotebackend/httpconnector.cc       2015-08-24 
11:11:59.000000000 +0200
+++ new/pdns-3.4.7/modules/remotebackend/httpconnector.cc       2015-11-03 
13:58:26.000000000 +0100
@@ -388,7 +388,7 @@
 
     try {
       t0 = time((time_t*)NULL);
-      while(arl.ready() == false && (labs(time((time_t*)NULL) - t0) <= 
timeout/1000)) {
+      while(arl.ready() == false && (labs(time((time_t*)NULL) - t0) <= 
timeout)) {
         rd = d_socket->readWithTimeout(buffer, sizeof(buffer), timeout);
         if (rd==0) 
           throw NetworkError("EOF while reading");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-3.4.6/pdns/common_startup.cc 
new/pdns-3.4.7/pdns/common_startup.cc
--- old/pdns-3.4.6/pdns/common_startup.cc       2015-06-09 14:29:04.000000000 
+0200
+++ new/pdns-3.4.7/pdns/common_startup.cc       2015-11-02 14:05:07.000000000 
+0100
@@ -138,6 +138,8 @@
   ::arg().set("soa-refresh-default","Default SOA refresh")="10800";
   ::arg().set("soa-retry-default","Default SOA retry")="3600";
   ::arg().set("soa-expire-default","Default SOA expire")="604800";
+  ::arg().set("default-soa-edit","Default SOA-EDIT value")="";
+  ::arg().set("default-soa-edit-signed","Default SOA-EDIT value for signed 
zones")="";
 
   ::arg().set("trusted-notification-proxy", "IP address of incoming 
notification proxy")="";
   ::arg().set("slave-renotify", "If we should send out notifications for 
slaved updates")="no";
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-3.4.6/pdns/dbdnsseckeeper.cc 
new/pdns-3.4.7/pdns/dbdnsseckeeper.cc
--- old/pdns-3.4.6/pdns/dbdnsseckeeper.cc       2015-06-09 14:29:04.000000000 
+0200
+++ new/pdns-3.4.7/pdns/dbdnsseckeeper.cc       2015-11-02 14:05:07.000000000 
+0100
@@ -212,6 +212,23 @@
   }
 }
 
+void DNSSECKeeper::getSoaEdit(const std::string& zname, std::string& value)
+{
+  static const string soaEdit(::arg()["default-soa-edit"]);
+  static const string soaEditSigned(::arg()["default-soa-edit-signed"]);
+
+  getFromMeta(zname, "SOA-EDIT", value);
+
+  if ((!soaEdit.empty() || !soaEditSigned.empty()) && value.empty() && 
!isPresigned(zname)) {
+    if (!soaEditSigned.empty() && isSecuredZone(zname))
+      value=soaEditSigned;
+    if (value.empty())
+      value=soaEdit;
+  }
+
+  return;
+}
+
 uint64_t DNSSECKeeper::dbdnssecCacheSizes(const std::string& str)
 {
   if(str=="meta-cache-size") {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-3.4.6/pdns/dnsbackend.cc 
new/pdns-3.4.7/pdns/dnsbackend.cc
--- old/pdns-3.4.6/pdns/dnsbackend.cc   2015-06-09 14:29:04.000000000 +0200
+++ new/pdns-3.4.7/pdns/dnsbackend.cc   2015-10-13 10:37:24.000000000 +0200
@@ -44,18 +44,23 @@
   return true;
 }
 
-bool DNSBackend::getAuth(DNSPacket *p, SOAData *sd, const string &target, int 
*zoneId, const int best_match_len)
+bool DNSBackend::getAuth(DNSPacket *p, SOAData *sd, const string &target, int 
*zoneId, const int best_match_len, map<string,int>& negCacheMap)
 {
   bool found=false;
   string subdomain(target);
   do {
-    if( best_match_len >= (int)subdomain.length() )
+    if( best_match_len >= (int)subdomain.length() && p->qtype != QType::DS )
       break;
 
-    if( this->getSOA( subdomain, *sd, p ) ) {
+    map<string,int>::iterator it = negCacheMap.find(subdomain);
+    bool negCached = ( it != negCacheMap.end() && it->second == 1 );
+
+    if(! negCached && this->getSOA( subdomain, *sd, p ) ) {
       sd->qname = subdomain;
       if(zoneId)
         *zoneId = sd->domain_id;
+      if(found) // Second SOA found, we are done
+        return true;
 
       if(p->qtype.getCode() == QType::DS && pdns_iequals(subdomain, target)) {
         // Found authoritative zone but look for parent zone with 'DS' record.
@@ -63,6 +68,8 @@
       } else
         return true;
     }
+    if (found)
+      negCacheMap[subdomain]=2; // don't cache SOA's during our quest for a 
parent zone
   }
   while( chopOff( subdomain ) );   // 'www.powerdns.org' -> 'powerdns.org' -> 
'org' -> ''
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-3.4.6/pdns/dnsbackend.hh 
new/pdns-3.4.7/pdns/dnsbackend.hh
--- old/pdns-3.4.6/pdns/dnsbackend.hh   2015-08-24 11:11:59.000000000 +0200
+++ new/pdns-3.4.7/pdns/dnsbackend.hh   2015-10-13 10:37:24.000000000 +0200
@@ -163,7 +163,7 @@
   virtual void getAllDomains(vector<DomainInfo> *domains, bool 
include_disabled=false) { }
 
   /** Determines if we are authoritative for a zone, and at what level */
-  virtual bool getAuth(DNSPacket *p, SOAData *sd, const string &target, int 
*zoneId, const int best_match_len);
+  virtual bool getAuth(DNSPacket *p, SOAData *sd, const string &target, int 
*zoneId, const int best_match_len, map<string,int>& negCacheMap);
 
   struct KeyData {
     unsigned int id;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-3.4.6/pdns/dnspacket.cc 
new/pdns-3.4.7/pdns/dnspacket.cc
--- old/pdns-3.4.6/pdns/dnspacket.cc    2015-08-25 19:58:41.000000000 +0200
+++ new/pdns-3.4.7/pdns/dnspacket.cc    2015-11-02 11:33:21.000000000 +0100
@@ -464,10 +464,15 @@
   bool gotit=false;
   for(MOADNSParser::answers_t::const_iterator i=mdp.d_answers.begin(); 
i!=mdp.d_answers.end(); ++i) {          
     if(i->first.d_type == QType::TSIG) {
-      *trc = 
*boost::dynamic_pointer_cast<TSIGRecordContent>(i->first.d_content);
-      
-      gotit=true;
+      // cast can fail, f.e. if d_content is an UnknownRecordContent.
+      shared_ptr<TSIGRecordContent> content = 
boost::dynamic_pointer_cast<TSIGRecordContent>(i->first.d_content);
+      if (!content) {
+        L<<Logger::Error<<"TSIG record has no or invalid content (invalid 
packet)"<<endl;
+        return false;
+      }
+      *trc = *content;
       *keyname = i->first.d_label;
+      gotit=true;
       if(!keyname->empty())
         keyname->resize(keyname->size()-1); // drop the trailing dot
     }
@@ -492,7 +497,13 @@
     }
 
     if(i->first.d_type == QType::TKEY) {
-      *tr = 
*boost::dynamic_pointer_cast<TKEYRecordContent>(i->first.d_content);
+      // cast can fail, f.e. if d_content is an UnknownRecordContent.
+      shared_ptr<TKEYRecordContent> content = 
boost::dynamic_pointer_cast<TKEYRecordContent>(i->first.d_content);
+      if (!content) {
+        L<<Logger::Error<<"TKEY record has no or invalid content (invalid 
packet)"<<endl;
+        return false;
+      }
+      *tr = *content;
       *keyname = i->first.d_label;
       gotit=true;
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-3.4.6/pdns/dnsrecords.cc 
new/pdns-3.4.7/pdns/dnsrecords.cc
--- old/pdns-3.4.6/pdns/dnsrecords.cc   2015-06-09 14:29:04.000000000 +0200
+++ new/pdns-3.4.7/pdns/dnsrecords.cc   2015-11-02 13:32:28.000000000 +0100
@@ -284,6 +284,10 @@
                  conv.xfrHexBlob(d_cert, true);
                  )                 
                  
+boilerplate_conv(OPENPGPKEY, 61,
+                 conv.xfrBlob(d_keyring);
+                 )
+
 #undef DS
 DSRecordContent::DSRecordContent() : DNSRecordContent(43) {}
 boilerplate_conv(DS, 43, 
@@ -525,6 +529,7 @@
    NSEC3RecordContent::report();
    NSEC3PARAMRecordContent::report();
    TLSARecordContent::report();
+   OPENPGPKEYRecordContent::report();
    DLVRecordContent::report();
    DNSRecordContent::regist(QClass::ANY, QType::TSIG, 
&TSIGRecordContent::make, &TSIGRecordContent::make, "TSIG");
    DNSRecordContent::regist(QClass::ANY, QType::TKEY, 
&TKEYRecordContent::make, &TKEYRecordContent::make, "TKEY");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-3.4.6/pdns/dnsrecords.hh 
new/pdns-3.4.7/pdns/dnsrecords.hh
--- old/pdns-3.4.6/pdns/dnsrecords.hh   2015-06-09 14:29:05.000000000 +0200
+++ new/pdns-3.4.7/pdns/dnsrecords.hh   2015-11-02 13:32:28.000000000 +0100
@@ -348,6 +348,15 @@
   string d_cert;
 };
 
+class OPENPGPKEYRecordContent : public DNSRecordContent
+{
+public:
+  includeboilerplate(OPENPGPKEY)
+
+private:
+  string d_keyring;
+};
+
 
 class RRSIGRecordContent : public DNSRecordContent
 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-3.4.6/pdns/dnssecinfra.cc 
new/pdns-3.4.7/pdns/dnssecinfra.cc
--- old/pdns-3.4.6/pdns/dnssecinfra.cc  2015-06-09 14:29:05.000000000 +0200
+++ new/pdns-3.4.7/pdns/dnssecinfra.cc  2015-11-02 13:32:28.000000000 +0100
@@ -60,8 +60,7 @@
       pkcs11=true;
       continue;
     } else if (pdns_iequals(key,"slot")) {
-      int slot = atoi(value.c_str());
-      stormap["slot"]=lexical_cast<string>(slot);
+      stormap["slot"]=value;
       continue;
     }  else if (pdns_iequals(key,"label")) {
       stormap["label"]=value;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-3.4.6/pdns/dnsseckeeper.hh 
new/pdns-3.4.7/pdns/dnsseckeeper.hh
--- old/pdns-3.4.6/pdns/dnsseckeeper.hh 2015-06-09 14:29:05.000000000 +0200
+++ new/pdns-3.4.7/pdns/dnsseckeeper.hh 2015-11-02 14:05:07.000000000 +0100
@@ -106,6 +106,7 @@
   }
   
   void getFromMeta(const std::string& zname, const std::string& key, 
std::string& value);
+  void getSoaEdit(const std::string& zname, std::string& value);
 private:
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-3.4.6/pdns/docs/dnstcpbench.1 
new/pdns-3.4.7/pdns/docs/dnstcpbench.1
--- old/pdns-3.4.6/pdns/docs/dnstcpbench.1      2015-08-27 15:18:35.000000000 
+0200
+++ new/pdns-3.4.7/pdns/docs/dnstcpbench.1      2015-11-03 15:37:39.000000000 
+0100
@@ -2,12 +2,12 @@
 .\"     Title: dnstcpbench
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 08/27/2015
+.\"      Date: 11/03/2015
 .\"    Manual: \ \&
 .\"    Source: \ \&
 .\"  Language: English
 .\"
-.TH "DNSTCPBENCH" "1" "08/27/2015" "\ \&" "\ \&"
+.TH "DNSTCPBENCH" "1" "11/03/2015" "\ \&" "\ \&"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-3.4.6/pdns/ext/yahttp/yahttp/reqresp.hpp 
new/pdns-3.4.7/pdns/ext/yahttp/yahttp/reqresp.hpp
--- old/pdns-3.4.6/pdns/ext/yahttp/yahttp/reqresp.hpp   2015-06-19 
11:40:21.000000000 +0200
+++ new/pdns-3.4.7/pdns/ext/yahttp/yahttp/reqresp.hpp   2015-11-03 
14:32:09.000000000 +0100
@@ -303,7 +303,7 @@
 
     void initialize(T* target) {
       chunked = false; chunk_size = 0;
-      bodybuf.str(""); maxbody = 0;
+      bodybuf.str(""); minbody = 0; maxbody = 0;
       pos = 0; state = 0; this->target = target; 
       hasBody = false;
       buffer = "";
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-3.4.6/pdns/packethandler.cc 
new/pdns-3.4.7/pdns/packethandler.cc
--- old/pdns-3.4.6/pdns/packethandler.cc        2015-08-26 11:29:42.000000000 
+0200
+++ new/pdns-3.4.7/pdns/packethandler.cc        2015-11-02 11:33:21.000000000 
+0100
@@ -996,6 +996,14 @@
     return 0;
   }
 
+  if(p->d.tc) { // truncated query. MOADNSParser would silently parse this 
packet in an incomplete way.
+    if(d_logDNSDetails)
+      L<<Logger::Error<<"Received truncated query packet from 
"<<p->getRemote()<<", dropping"<<endl;
+    S.inc("corrupt-packets");
+    S.ringAccount("remotes-corrupt", p->getRemote());
+    return 0;
+  }
+
   if (p->hasEDNS() && p->getEDNSVersion() > 0) {
     r = p->replyPacket();
     r->setRcode(16 & 0xF);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-3.4.6/pdns/pdns.conf-dist 
new/pdns-3.4.7/pdns/pdns.conf-dist
--- old/pdns-3.4.6/pdns/pdns.conf-dist  2015-06-09 14:29:11.000000000 +0200
+++ new/pdns-3.4.7/pdns/pdns.conf-dist  2015-11-02 14:05:07.000000000 +0100
@@ -85,6 +85,16 @@
 # default-ksk-size=0
 
 #################################
+# default-soa-edit     Default SOA-EDIT value
+#
+# default-soa-edit=
+
+#################################
+# default-soa-edit-signed      Default SOA-EDIT value for signed zones
+#
+# default-soa-edit-signed=
+
+#################################
 # default-soa-mail     mail address to insert in the SOA record if none set in 
the backend
 #
 # default-soa-mail=
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-3.4.6/pdns/pdnssec.cc 
new/pdns-3.4.7/pdns/pdnssec.cc
--- old/pdns-3.4.6/pdns/pdnssec.cc      2015-08-24 14:32:10.000000000 +0200
+++ new/pdns-3.4.7/pdns/pdnssec.cc      2015-11-02 14:05:07.000000000 +0100
@@ -133,6 +133,8 @@
   ::arg().set("default-ksk-size","Default KSK size (0 means default)")="0";
   ::arg().set("default-zsk-algorithms","Default ZSK algorithms")="rsasha256";
   ::arg().set("default-zsk-size","Default KSK size (0 means default)")="0";
+  ::arg().set("default-soa-edit","Default SOA-EDIT value")="";
+  ::arg().set("default-soa-edit-signed","Default SOA-EDIT value for signed 
zones")="";
   ::arg().set("max-ent-entries", "Maximum number of empty non-terminals in a 
zone")="100000";
   ::arg().set("module-dir","Default directory for modules")=PKGLIBDIR;
   ::arg().set("entropy-source", "If set, read entropy from this 
file")="/dev/urandom";
@@ -665,9 +667,14 @@
     cout<<"No SOA for zone '"<<zone<<"'"<<endl;
     return -1;
   }
+
+  if (dk.isPresigned(zone)) {
+    cerr<<"Serial increase of presigned zone '"<<zone<<"' is not 
allowed."<<endl;
+    return -1;
+  }
   
   string soaEditKind;
-  dk.getFromMeta(zone, "SOA-EDIT", soaEditKind);
+  dk.getSoaEdit(zone, soaEditKind);
 
   sd.db->lookup(QType(QType::SOA), zone);
   vector<DNSResourceRecord> rrs;
@@ -2034,7 +2041,7 @@
       std::vector<DNSBackend::KeyData> keys;
 
       if (cmds.size() < 9) {
-        std::cout << "Usage: pdnssec hsm assign zone algorithm ksk|zsk module 
slot pin label" << std::endl;
+        std::cout << "Usage: pdnssec hsm assign zone algorithm ksk|zsk module 
token pin label" << std::endl;
         return 1;
       }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-3.4.6/pdns/pkcs11signers.cc 
new/pdns-3.4.7/pdns/pkcs11signers.cc
--- old/pdns-3.4.6/pdns/pkcs11signers.cc        2015-06-09 14:29:11.000000000 
+0200
+++ new/pdns-3.4.7/pdns/pkcs11signers.cc        2015-11-02 13:32:28.000000000 
+0100
@@ -213,6 +213,7 @@
         L<<Logger::Error<< msg << endl;
       }
     }
+
   public:
     Pkcs11Slot(CK_FUNCTION_LIST* functions, const CK_SLOT_ID& slot) {
       CK_TOKEN_INFO tokenInfo;
@@ -260,6 +261,9 @@
     CK_FUNCTION_LIST* f() { return d_functions; }
 
     pthread_mutex_t *m() { return &d_m; }
+
+    static boost::shared_ptr<Pkcs11Slot> GetSlot(const std::string& module, 
const string& tokenId);
+    static CK_RV HuntSlot(const string& tokenId, CK_SLOT_ID &slotId, 
_CK_SLOT_INFO* info, CK_FUNCTION_LIST* functions);
 };
 
 class Pkcs11Token {
@@ -607,31 +611,72 @@
       return d_bits;
     }
 
-    static boost::shared_ptr<Pkcs11Token> GetToken(const std::string& module, 
const CK_SLOT_ID& slotId, const std::string& label);
+    static boost::shared_ptr<Pkcs11Token> GetToken(const std::string& module, 
const string& tokenId, const std::string& label);
 };
 
 static std::map<std::string, boost::shared_ptr<Pkcs11Slot> > pkcs11_slots;
 static std::map<std::string, boost::shared_ptr<Pkcs11Token> > pkcs11_tokens;
 
-boost::shared_ptr<Pkcs11Token> Pkcs11Token::GetToken(const std::string& 
module, const CK_SLOT_ID& slotId, const std::string& label) {
+CK_RV Pkcs11Slot::HuntSlot(const string& tokenId, CK_SLOT_ID &slotId, 
_CK_SLOT_INFO* info, CK_FUNCTION_LIST* functions)
+{
+  CK_RV err;
+  unsigned long slots;
+  _CK_TOKEN_INFO tinfo;
+
+  // go thru all slots
+  // this is required by certain tokens, otherwise C_GetSlotInfo will not 
return a token
+  err = functions->C_GetSlotList(CK_FALSE, NULL_PTR, &slots);
+  if (err) {
+    L<<Logger::Warning<<"C_GetSlotList(CK_FALSE, NULL_PTR, &slots) = " << err 
<< std::endl;
+    return err;
+  }
+
+  // iterate all slots
+  for(slotId=0;slotId<slots;slotId++) {
+    if ((err = functions->C_GetSlotInfo(slotId, info))) {
+      L<<Logger::Warning<<"C_GetSlotList("<<slotId<<", info) = " << err << 
std::endl;
+      return err;
+    }
+    if ((err = functions->C_GetTokenInfo(slotId, &tinfo))) {
+      L<<Logger::Warning<<"C_GetSlotList("<<slotId<<", &tinfo) = " << err << 
std::endl;
+      return err;
+    }
+    std::string slotName;
+    slotName.assign(reinterpret_cast<char*>(tinfo.label), 32);
+    // trim it
+    boost::trim(slotName);
+    if (boost::iequals(slotName, tokenId)) {
+      return 0;
+    }
+  }
+
+  // see if we can find it with slotId
+  try {
+    slotId = boost::lexical_cast<int>(tokenId);
+    if ((err = functions->C_GetSlotInfo(slotId, info))) {
+      L<<Logger::Warning<<"C_GetSlotList("<<slotId<<", info) = " << err << 
std::endl;
+      return err;
+    }
+    L<<Logger::Warning<<"Specifying PKCS#11 token by SLOT ID is deprecated and 
should not be used"<<std::endl;
+    return 0;
+  } catch (...) {
+    return CK_UNAVAILABLE_INFORMATION;
+  }
+  return CK_UNAVAILABLE_INFORMATION;
+}
+
+boost::shared_ptr<Pkcs11Slot> Pkcs11Slot::GetSlot(const std::string& module, 
const string& tokenId) {
   // see if we can find module
-  std::string tidx = module;
-  tidx.append("|");
-  tidx.append(boost::lexical_cast<std::string>(slotId));
-  std::string sidx = tidx;
-  tidx.append("|");
-  tidx.append(label);
-  std::map<std::string, boost::shared_ptr<Pkcs11Token> >::iterator tokenIter;
+  std::string sidx = module;
+  sidx.append("|");
+  sidx.append(tokenId);
   std::map<std::string, boost::shared_ptr<Pkcs11Slot> >::iterator slotIter;
   CK_RV err;
   CK_FUNCTION_LIST* functions;
 
-  if ((tokenIter = pkcs11_tokens.find(tidx)) != pkcs11_tokens.end()) return 
tokenIter->second;
-
   // see if we have slot
   if ((slotIter = pkcs11_slots.find(sidx)) != pkcs11_slots.end()) {
-    pkcs11_tokens[tidx] = boost::make_shared<Pkcs11Token>(slotIter->second, 
label);
-    return pkcs11_tokens[tidx];
+    return slotIter->second;
   }
 
 #ifdef HAVE_P11KIT1_V2
@@ -644,23 +689,30 @@
 
   // try to locate a slot
    _CK_SLOT_INFO info;
-  unsigned long slots;
-
-  // this is required by certain tokens, otherwise C_GetSlotInfo will not 
return a token
-  err = functions->C_GetSlotList(CK_FALSE, NULL_PTR, &slots);
-  if (err)
-    L<<Logger::Warning<<"C_GetSlotList(CK_FALSE, NULL_PTR, &slots) = " << err 
<< std::endl;
+  CK_SLOT_ID slotId;
 
-  if ((err = functions->C_GetSlotInfo(slotId, &info))) {
-    throw PDNSException(std::string("Cannot find PKCS#11 slot ") + 
boost::lexical_cast<std::string>(slotId) + std::string(" on module ") + module 
+ std::string(": error code ") + boost::lexical_cast<std::string>(err));
+  if ((err = Pkcs11Slot::HuntSlot(tokenId, slotId, &info, functions))) {
+    throw PDNSException(std::string("Cannot find PKCS#11 token ") + tokenId + 
std::string(" on module ") + module + std::string(": error code ") + 
boost::lexical_cast<std::string>(err));
   }
 
   // store slot
   pkcs11_slots[sidx] = boost::make_shared<Pkcs11Slot>(functions, slotId);
 
-  // looks ok to me.
-  pkcs11_tokens[tidx] = boost::make_shared<Pkcs11Token>(pkcs11_slots[sidx], 
label);
+  return pkcs11_slots[sidx];
+}
 
+boost::shared_ptr<Pkcs11Token> Pkcs11Token::GetToken(const std::string& 
module, const string& tokenId, const std::string& label) {
+  // see if we can find module
+  std::string tidx = module;
+  tidx.append("|");
+  tidx.append(boost::lexical_cast<std::string>(tokenId));
+  tidx.append("|");
+  tidx.append(label);
+  std::map<std::string, boost::shared_ptr<Pkcs11Token> >::iterator tokenIter;
+  if ((tokenIter = pkcs11_tokens.find(tidx)) != pkcs11_tokens.end()) return 
tokenIter->second;
+
+  boost::shared_ptr<Pkcs11Slot> slot = Pkcs11Slot::GetSlot(module, tokenId);
+  pkcs11_tokens[tidx] = boost::make_shared<Pkcs11Token>(slot, label);
   return pkcs11_tokens[tidx];
 }
 
@@ -677,6 +729,14 @@
 Pkcs11Token::~Pkcs11Token() {
 }
 
+bool PKCS11ModuleSlotLogin(const std::string& module, const string& tokenId, 
const std::string& pin)
+{
+  boost::shared_ptr<Pkcs11Slot> slot;
+  slot = Pkcs11Slot::GetSlot(module, tokenId);
+  if (slot->LoggedIn()) return true; // no point failing
+  return slot->Login(pin);
+}
+
 PKCS11DNSCryptoKeyEngine::PKCS11DNSCryptoKeyEngine(unsigned int algorithm): 
DNSCryptoKeyEngine(algorithm) {}
 PKCS11DNSCryptoKeyEngine::~PKCS11DNSCryptoKeyEngine() {}
 PKCS11DNSCryptoKeyEngine::PKCS11DNSCryptoKeyEngine(const 
PKCS11DNSCryptoKeyEngine& orig) : DNSCryptoKeyEngine(orig.d_algorithm) {}
@@ -866,7 +926,7 @@
   boost::assign::push_back(storvect)
    (make_pair("Algorithm", boost::lexical_cast<std::string>(d_algorithm)))
    (make_pair("Engine", d_module))
-   (make_pair("Slot", boost::lexical_cast<std::string>(d_slot_id)))
+   (make_pair("Slot", d_slot_id))
    (make_pair("PIN", d_pin))
    (make_pair("Label", d_label));
   return storvect;
@@ -875,7 +935,8 @@
 void PKCS11DNSCryptoKeyEngine::fromISCMap(DNSKEYRecordContent& drc, stormap_t& 
stormap) {
   drc.d_algorithm = atoi(stormap["algorithm"].c_str());
   d_module = stormap["engine"];
-  d_slot_id = atoi(stormap["slot"].c_str());
+  d_slot_id = stormap["slot"];
+  boost::trim(d_slot_id);
   d_pin = stormap["pin"];
   d_label = stormap["label"];
   // validate parameters
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-3.4.6/pdns/pkcs11signers.hh 
new/pdns-3.4.7/pdns/pkcs11signers.hh
--- old/pdns-3.4.6/pdns/pkcs11signers.hh        2015-06-09 14:29:11.000000000 
+0200
+++ new/pdns-3.4.7/pdns/pkcs11signers.hh        2015-11-02 13:32:28.000000000 
+0100
@@ -2,7 +2,7 @@
 {
   protected:
     std::string d_module;
-    unsigned long d_slot_id;
+    std::string d_slot_id;
     std::string d_pin;
     std::string d_label;
 
@@ -41,3 +41,4 @@
     static DNSCryptoKeyEngine* maker(unsigned int algorithm);
 };
 
+bool PKCS11ModuleSlotLogin(const std::string& module, const string& tokenId, 
const std::string& pin);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-3.4.6/pdns/qtype.hh new/pdns-3.4.7/pdns/qtype.hh
--- old/pdns-3.4.6/pdns/qtype.hh        2015-06-09 14:29:12.000000000 +0200
+++ new/pdns-3.4.7/pdns/qtype.hh        2015-11-02 13:32:28.000000000 +0100
@@ -82,7 +82,7 @@
 #undef DS
   enum typeenum {A=1, NS=2, CNAME=5, SOA=6, MR=9, PTR=12, HINFO=13, MX=15, 
TXT=16, RP=17, AFSDB=18, SIG=24, KEY=25, AAAA=28, LOC=29, SRV=33, NAPTR=35, 
KX=36,
                 CERT=37, A6=38, DNAME=39, OPT=41, DS=43, SSHFP=44, 
IPSECKEY=45, RRSIG=46, NSEC=47, DNSKEY=48, DHCID=49, NSEC3=50, NSEC3PARAM=51,
-     TLSA=52, SPF=99, EUI48=108, EUI64=109, TKEY=249, TSIG=250, IXFR=251, 
AXFR=252, MAILB=253, MAILA=254, ANY=255, URL=256, MBOXFW=257, CURL=258, 
ADDR=259, DLV=32769} types;
+     TLSA=52, OPENPGPKEY=61, SPF=99, EUI48=108, EUI64=109, TKEY=249, TSIG=250, 
IXFR=251, AXFR=252, MAILB=253, MAILA=254, ANY=255, URL=256, MBOXFW=257, 
CURL=258, ADDR=259, DLV=32769} types;
   typedef pair<string,uint16_t> namenum;
   static vector<namenum> names;
 
@@ -153,6 +153,7 @@
       qtype_insert("NSEC3", 50);
       qtype_insert("NSEC3PARAM", 51);
       qtype_insert("TLSA", 52);
+      qtype_insert("OPENPGPKEY", 61);
       qtype_insert("SPF", 99);
       qtype_insert("EUI48", 108);
       qtype_insert("EUI64", 109);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-3.4.6/pdns/rfc2136handler.cc 
new/pdns-3.4.7/pdns/rfc2136handler.cc
--- old/pdns-3.4.6/pdns/rfc2136handler.cc       2015-06-09 14:29:12.000000000 
+0200
+++ new/pdns-3.4.7/pdns/rfc2136handler.cc       2015-11-02 14:05:07.000000000 
+0100
@@ -955,13 +955,13 @@
   if (!soaEdit2136Setting.empty()) {
     soaEdit2136 = soaEdit2136Setting[0];
     if (pdns_iequals(soaEdit2136, "SOA-EDIT") || 
pdns_iequals(soaEdit2136,"SOA-EDIT-INCREASE") ){
-      vector<string> soaEditSetting;
-      B.getDomainMetadata(di->zone, "SOA-EDIT", soaEditSetting);
+      string soaEditSetting;
+      d_dk.getSoaEdit(di->zone, soaEditSetting);
       if (soaEditSetting.empty()) {
         L<<Logger::Error<<msgPrefix<<"Using "<<soaEdit2136<<" for 
SOA-EDIT-DNSUPDATE increase on DNS update, but SOA-EDIT is not set for domain 
\""<< di->zone <<"\". Using DEFAULT for SOA-EDIT-DNSUPDATE"<<endl;
         soaEdit2136 = "DEFAULT";
       } else
-        soaEdit = soaEditSetting[0];
+        soaEdit = soaEditSetting;
     }
   }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-3.4.6/pdns/serialtweaker.cc 
new/pdns-3.4.7/pdns/serialtweaker.cc
--- old/pdns-3.4.6/pdns/serialtweaker.cc        2015-06-09 14:29:12.000000000 
+0200
+++ new/pdns-3.4.7/pdns/serialtweaker.cc        2015-11-02 14:05:07.000000000 
+0100
@@ -42,7 +42,7 @@
   BOOST_FOREACH(DNSResourceRecord& rr, rrs) {
     if(rr.qtype.getCode() == QType::SOA && pdns_iequals(rr.qname,qname)) {
       string kind;
-      dk.getFromMeta(qname, "SOA-EDIT", kind);
+      dk.getSoaEdit(qname, kind);
       return editSOARecord(rr, kind);
     }
   }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-3.4.6/pdns/signingpipe.cc 
new/pdns-3.4.7/pdns/signingpipe.cc
--- old/pdns-3.4.6/pdns/signingpipe.cc  2015-06-09 14:29:13.000000000 +0200
+++ new/pdns-3.4.7/pdns/signingpipe.cc  2015-11-03 13:26:30.000000000 +0100
@@ -109,16 +109,17 @@
 namespace {
 bool dedupLessThan(const DNSResourceRecord& a, const DNSResourceRecord &b)
 {
-  if(tie(a.content, a.ttl) < tie(b.content, b.ttl))
-    return true;
-  if(a.qtype.getCode() == QType::MX || a.qtype.getCode() == QType::SRV)
-    return a.priority < b.priority;
-  return false;
+  uint16_t aprio = 0, bprio = 0;
+  if (a.qtype.getCode() == QType::MX || a.qtype.getCode() == QType::SRV)
+    aprio = a.priority;
+  if (b.qtype.getCode() == QType::MX || b.qtype.getCode() == QType::SRV)
+    bprio = b.priority;
+  return tie(a.content, aprio) < tie(b.content, bprio);
 }
 
 bool dedupEqual(const DNSResourceRecord& a, const DNSResourceRecord &b)
 {
-  if(tie(a.content, a.ttl) != tie(b.content, b.ttl))
+  if(a.content != b.content)
     return false;
   if(a.qtype.getCode() == QType::MX || a.qtype.getCode() == QType::SRV)
     return a.priority == b.priority;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-3.4.6/pdns/tcpreceiver.cc 
new/pdns-3.4.7/pdns/tcpreceiver.cc
--- old/pdns-3.4.6/pdns/tcpreceiver.cc  2015-06-09 14:29:13.000000000 +0200
+++ new/pdns-3.4.7/pdns/tcpreceiver.cc  2015-11-02 14:05:07.000000000 +0100
@@ -700,7 +700,8 @@
       }
       rrs.push_back(rr);
     } else {
-      L<<Logger::Warning<<"Zone '"<<target<<"' contains out-of-zone data 
'"<<rr.qname<<"'|"<<rr.qtype.getName()<<"', ignoring"<<endl;
+      if (rr.qtype.getCode())
+        L<<Logger::Warning<<"Zone '"<<target<<"' contains out-of-zone data 
'"<<rr.qname<<"|"<<rr.qtype.getName()<<"', ignoring"<<endl;
       continue;
     }
   }
@@ -1021,7 +1022,7 @@
   }
 
   string soaedit;
-  dk.getFromMeta(target, "SOA-EDIT", soaedit);
+  dk.getSoaEdit(target, soaedit);
   if (!rfc1982LessThan(serial, calculateEditSOA(sd, soaedit))) {
     TSIGRecordContent trc;
     string tsigkeyname, tsigsecret;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-3.4.6/pdns/test-dnsrecords_cc.cc 
new/pdns-3.4.7/pdns/test-dnsrecords_cc.cc
--- old/pdns-3.4.6/pdns/test-dnsrecords_cc.cc   2015-06-09 14:29:13.000000000 
+0200
+++ new/pdns-3.4.7/pdns/test-dnsrecords_cc.cc   2015-11-02 13:32:28.000000000 
+0100
@@ -160,6 +160,8 @@
      (CASE_S(QType::TLSA, "3 0 0 
308201f43082015da003020102020900ac547c5557870ec7300d06092a864886f70d010105050030133111300f06035504030c087265632e74657374301e170d3133303531323139343830395a170d3133303631313139343830395a30133111300f06035504030c087265632e7465737430819f300d06092a864886f70d010101050003818d0030818902818100d282bb968dfdec0e5d13dfcc0a36ed73178581424e10a37c89d3014204933b3a8c1159fdecb221afe4168883d2d00ac1f15fca4614fbd5e05de2e37ad0fbad8b7748dddbcf30b39e80466c61c733415e72b9f42d5fad0bf35f041eb5631eded00314c66c4878b351416e5c6b9096f2a7088a24387e5d0149c523739f84f502c70203010001a350304e301d0603551d0e0416041473715bbfd9bc2b824112f858586f166aafb99482301f0603551d2304183016801473715bbfd9bc2b824112f858586f166aafb99482300c0603551d13040530030101ff300d06092a864886f70d0101050500038181005550f1d64139ab0e86c5b303fc69015d1676ca95931071ae41884656c71c116a38138ecf63054b350dc78983cb4a83288dbc81c5a659a56cc6843d5452c3e98449b94a0cf0c0cd7190c96caa5f0ee9a3bef7e75002be4a233673852bdf1a5fd306a7080eb4fead9b3ad162074b5f007e9156e220302dea8c700868a12577e7c4",
 
"\x03\x00\x00\x30\x82\x01\xf4\x30\x82\x01\x5d\xa0\x03\x02\x01\x02\x02\x09\x00\xac\x54\x7c\x55\x57\x87\x0e\xc7\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x05\x05\x00\x30\x13\x31\x11\x30\x0f\x06\x03\x55\x04\x03\x0c\x08\x72\x65\x63\x2e\x74\x65\x73\x74\x30\x1e\x17\x0d\x31\x33\x30\x35\x31\x32\x31\x39\x34\x38\x30\x39\x5a\x17\x0d\x31\x33\x30\x36\x31\x31\x31\x39\x34\x38\x30\x39\x5a\x30\x13\x31\x11\x30\x0f\x06\x03\x55\x04\x03\x0c\x08\x72\x65\x63\x2e\x74\x65\x73\x74\x30\x81\x9f\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x81\x8d\x00\x30\x81\x89\x02\x81\x81\x00\xd2\x82\xbb\x96\x8d\xfd\xec\x0e\x5d\x13\xdf\xcc\x0a\x36\xed\x73\x17\x85\x81\x42\x4e\x10\xa3\x7c\x89\xd3\x01\x42\x04\x93\x3b\x3a\x8c\x11\x59\xfd\xec\xb2\x21\xaf\xe4\x16\x88\x83\xd2\xd0\x0a\xc1\xf1\x5f\xca\x46\x14\xfb\xd5\xe0\x5d\xe2\xe3\x7a\xd0\xfb\xad\x8b\x77\x48\xdd\xdb\xcf\x30\xb3\x9e\x80\x46\x6c\x61\xc7\x33\x41\x5e\x72\xb9\xf4\x2d\x5f\xad\x0b\xf3\x5f\x04\x1e\xb5\x63\x1e\xde\xd0\x03\x14\xc6\x6c\x48\x78\xb3\x51\x41\x6e\x5c\x6b\x90\x96\xf2\xa7\x08\x8a\x24\x38\x7e\x5d\x01\x49\xc5\x23\x73\x9f\x84\xf5\x02\xc7\x02\x03\x01\x00\x01\xa3\x50\x30\x4e\x30\x1d\x06\x03\x55\x1d\x0e\x04\x16\x04\x14\x73\x71\x5b\xbf\xd9\xbc\x2b\x82\x41\x12\xf8\x58\x58\x6f\x16\x6a\xaf\xb9\x94\x82\x30\x1f\x06\x03\x55\x1d\x23\x04\x18\x30\x16\x80\x14\x73\x71\x5b\xbf\xd9\xbc\x2b\x82\x41\x12\xf8\x58\x58\x6f\x16\x6a\xaf\xb9\x94\x82\x30\x0c\x06\x03\x55\x1d\x13\x04\x05\x30\x03\x01\x01\xff\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x05\x05\x00\x03\x81\x81\x00\x55\x50\xf1\xd6\x41\x39\xab\x0e\x86\xc5\xb3\x03\xfc\x69\x01\x5d\x16\x76\xca\x95\x93\x10\x71\xae\x41\x88\x46\x56\xc7\x1c\x11\x6a\x38\x13\x8e\xcf\x63\x05\x4b\x35\x0d\xc7\x89\x83\xcb\x4a\x83\x28\x8d\xbc\x81\xc5\xa6\x59\xa5\x6c\xc6\x84\x3d\x54\x52\xc3\xe9\x84\x49\xb9\x4a\x0c\xf0\xc0\xcd\x71\x90\xc9\x6c\xaa\x5f\x0e\xe9\xa3\xbe\xf7\xe7\x50\x02\xbe\x4a\x23\x36\x73\x85\x2b\xdf\x1a\x5f\xd3\x06\xa7\x08\x0e\xb4\xfe\xad\x9b\x3a\xd1\x62\x07\x4b\x5f\x00\x7e\x91\x56\xe2\x20\x30\x2d\xea\x8c\x70\x08\x68\xa1\x25\x77\xe7\xc4",false))
      (CASE_S(QType::TLSA, "3 1 0 
30819f300d06092a864886f70d010101050003818d0030818902818100d282bb968dfdec0e5d13dfcc0a36ed73178581424e10a37c89d3014204933b3a8c1159fdecb221afe4168883d2d00ac1f15fca4614fbd5e05de2e37ad0fbad8b7748dddbcf30b39e80466c61c733415e72b9f42d5fad0bf35f041eb5631eded00314c66c4878b351416e5c6b9096f2a7088a24387e5d0149c523739f84f502c70203010001",
 
"\x03\x01\x00\x30\x81\x9f\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x81\x8d\x00\x30\x81\x89\x02\x81\x81\x00\xd2\x82\xbb\x96\x8d\xfd\xec\x0e\x5d\x13\xdf\xcc\x0a\x36\xed\x73\x17\x85\x81\x42\x4e\x10\xa3\x7c\x89\xd3\x01\x42\x04\x93\x3b\x3a\x8c\x11\x59\xfd\xec\xb2\x21\xaf\xe4\x16\x88\x83\xd2\xd0\x0a\xc1\xf1\x5f\xca\x46\x14\xfb\xd5\xe0\x5d\xe2\xe3\x7a\xd0\xfb\xad\x8b\x77\x48\xdd\xdb\xcf\x30\xb3\x9e\x80\x46\x6c\x61\xc7\x33\x41\x5e\x72\xb9\xf4\x2d\x5f\xad\x0b\xf3\x5f\x04\x1e\xb5\x63\x1e\xde\xd0\x03\x14\xc6\x6c\x48\x78\xb3\x51\x41\x6e\x5c\x6b\x90\x96\xf2\xa7\x08\x8a\x24\x38\x7e\x5d\x01\x49\xc5\x23\x73\x9f\x84\xf5\x02\xc7\x02\x03\x01\x00\x01",false))
 
+     (CASE_S(QType::OPENPGPKEY, 
"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",
 
"\x99\x02\x0d\x04\x55\x08\x5e\x1d\x01\x10\x00\xcd\x3e\x52\xfa\x36\x95\x84\x69\x1d\x8a\x27\x1e\xa9\xd7\xdb\x1c\x21\x5a\x6c\x04\x8a\x3b\x52\xac\xc2\x23\x37\x85\x6d\x12\x5a\x18\x38\x67\xfc\x79\x50\x81\xcc\x00\x6a\x57\x15\x36\x65\x94\x5f\x46\x50\xb2\xb7\x67\xf4\x21\x1f\x2d\x6b\x85\xbb\xd3\x8d\xda\x8d\x53\xb2\x56\x22\xc2\x7f\xa8\x48\x09\x47\xda\xb6\x85\x9b\x67\xb2\x25\x3a\x7f\x88\xce\xc8\x51\x40\xad\x7b\x98\xe6\x7f\x77\x7e\x2f\xda\xe3\x54\x8e\xc9\x8e\x63\x27\x6d\x5a\x3a\x49\x56\x36\x28\x30\xc3\xef\x67\x54\x2d\xc8\x3b\x22\xa6\x1c\x08\x03\x78\x09\x3f\xad\x3d\x93\xf9\xcb\x87\x18\x7f\xe0\xf1\x46\x5a\x71\x87\x1b\xea\xaa\x21\xb2\x02\x2e\xa5\x01\xc2\x76\xe3\xff\x1f\x27\x88\x6c\x1b\x49\x52\xd6\xf5\x35\xd8\xb5\x9e\x59\x31\xda\xe5\xa4\x4c\x33\xec\x7d\x92\x6b\xf7\x19\x87\x57\x1b\xe1\x71\x16\xa6\x70\xe7\x69\x19\x12\x70\x2c\x72\x90\xb6\xca\x66\xd7\xfb\x56\x05\x0a\xbf\x2c\x8c\x66\x06\x75\xef\xc3\xfb\x97\x0b\xbe\xeb\xb8\x3c\x63\x59\xe1\xf9\x12\x79\x2f\xb4\xc9\x7b\xde\xfe\xce\xae\xd6\x65\xfa\x46\x49\x05\xe9\x23\x86\x5a\xe2\x5f\x04\x93\x86\x75\x6c\xd8\xc1\xb7\xab\xf6\x4a\xa0\xaa\x91\xd3\x8e\x9a\xfc\x1c\xec\x9b\xcd\x5a\xe8\x06\x28\xed\x4e\x50\x7f\xb6\x89\xa6\x21\x47\x78\x05\x39\x3d\x26\xfe\x1f\xbf\x68\x00\xe1\x49\x02\xd7\x75\x0c\xf4\xa0\x45\xd4\xd9\xf3\x52\x72\x82\xf8\x9b\x38\xf4\xed\xe6\x8f\x41\xd9\x0e\x80\xab\x91\x63\x27\x67\x20\xec\x12\x68\x4c\xc9\x03\xd4\xe9\x84\x45\x1d\x69\x81\xe8\xe4\xca\x78\x3f\xd9\x9e\x4f\x9b\xd6\xec\xfe\x1c\x80\x60\xad\xb3\x6e\x88\x6f\xc0\xd1\xcd\x34\x56\x78\xfb\x95\x1e\x29\xf7\x8a\x0e\xbb\x2a\x48\xd3\x45\xee\xb0\xbb\x09\xc0\xfb\x23\x23\x81\x20\x14\x62\x9d\xa1\x1b\x4c\xd2\xca\x49\x86\x2f\xb7\x81\xff\x3c\x56\xad\x0d\x10\xd0\x5a\x15\x51\xcb\x04\x65\x95\x15\xa5\x6b\x7d\xfb\xab\x19\xc0\xd9\x61\x40\x1d\x9e\xf9\xbc\x8d\x23\xc2\x80\x13\xdf\x17\x1a\x59\xba\xd7\xb1\x36\x42\xe3\xc9\xa6\x97\x8c\x3b\x60\x6b\x9f\xe7\xe6\x04\x9d\xff\x74\x69\x58\x2b\xe9\xf6\xed\xd6\xe6\x37\x13\x34\x36\x45\xe1\x33\x91\x9c\xe5\xd4\x58\x77\x28\xb7\xff\x97\x9b\x21\xfc\xff\xe7\x27\xf3\x27\x6d\xd2\x9a\xce\x2c\x64\x3e\x16\xd7\x48\xf8\x05\xb2\x30\x25\xc7\x7a\x7e\x9a\x69\x9d\x63\x79\x22\xd9\xab\x00\x11\x01\x00\x01\xb4\x5a\x70\x64\x6e\x73\x20\x72\x65\x67\x72\x65\x73\x73\x69\x6f\x6e\x20\x74\x65\x73\x74\x69\x6e\x67\x20\x6b\x65\x79\x20\x28\x6f\x6e\x6c\x79\x20\x66\x6f\x72\x20\x74\x65\x73\x74\x69\x6e\x67\x20\x74\x68\x65\x20\x6f\x70\x65\x6e\x70\x67\x70\x6b\x65\x79\x20\x72\x72\x29\x20\x3c\x72\x65\x67\x72\x65\x73\x73\x69\x6f\x6e\x40\x70\x6f\x77\x65\x72\x64\x6e\x73\x2e\x6f\x72\x67\x3e\x89\x02\x37\x04\x13\x01\x08\x00\x21\x05\x02\x55\x08\x5e\x1d\x02\x1b\x03\x05\x0b\x09\x08\x07\x02\x06\x15\x08\x09\x0a\x0b\x02\x04\x16\x02\x03\x01\x02\x1e\x01\x02\x17\x80\x00\x0a\x09\x10\x3e\xbf\xca\xaa\x8c\x8a\xd9\x9e\xc0\xe9\x0f\xff\x60\xe0\x6e\xf2\x7c\x2d\xf9\xf8\x2e\x4a\x8f\xef\xc8\x29\x67\xd0\xfa\xa7\x4e\x20\x66\xe1\x1b\xc4\xda\x03\xc3\x52\x7b\x0a\xba\x85\xe8\x3f\x91\x79\xe9\x71\xc1\x5c\xa9\x7d\x90\x48\x26\xc9\xc8\x6d\xfe\x77\x3b\x73\xb3\x51\x1f\x35\x21\x69\xc3\x36\x45\x06\xae\xe8\x28\x0d\x64\x4f\x0a\x2d\xaa\x83\x4c\xa9\x44\xb9\xcf\xc0\x36\xda\xe7\x18\x66\x06\xf2\x03\x08\x77\x84\xe5\xcd\x4e\x6d\x68\xb1\x00\xf3\x2a\xc7\x20\x79\xf0\x9c\xcb\x83\x0e\x9c\x75\x6b\x41\x13\x91\xb6\x02\xae\x3e\xc2\xca\x7a\x9d\x85\x70\x80\x06\xa1\x63\x81\x12\xfb\x41\xbd\xfb\x52\x72\xcf\x13\xb6\x1d\x16\xde\xdf\x44\x6c\x19\x54\xb9\xdb\xdc\x65\x59\x2c\xa1\xee\xad\x9d\x13\x00\xdb\xcb\x75\x15\x43\x49\x3d\xdf\xd2\x50\x9c\x60\xca\x69\x3d\xb1\xc0\xbe\x2d\x8c\x21\x4e\xf5\x14\xf1\xa4\x9a\xcf\xbe\xb6\x3e\x20\x4e\x5b\x6a\xd1\x54\x6f\xac\xc3\x66\xd5\xee\x6f\xe3\xe8\x47\x67\xef\x90\x37\x8b\x26\xe3\xe0\xc9\x1a\x5a\x3b\x97\xce\x74\x82\x73\x17\x73\xb7\x3b\x1a\x44\x46\xb6\x0f\x20\x57\x48\x79\x93\x98\xd7\xe6\x27\x1d\x83\x1c\xaf\x10\xd4\xee\x05\x0f\x90\xa6\xb9\x18\x4d\x18\x7d\xb9\x8c\xe9\xa1\x34\x3e\x35\x84\x59\x96\x06\x89\xc7\x16\x83\x22\xfd\x4a\xfe\x46\xf7\xa0\xfb\x67\x00\x42\x89\x04\x2d\x36\x21\x96\xc1\xd0\x48\x92\xdd\x1e\x69\xc5\x85\xe1\x50\xda\x16\x57\xb7\xb3\xd8\x0e\x21\x5f\x52\xfe\xb5\xfb\xe5\x80\x20\x1b\x6d\x0f\xdc\x04\xbb\xea\x5e\x0a\x60\xb1\xff\x71\xe3\x28\x12\x8b\x9d\xaf\x40\x1c\xb7\xb7\x06\x72\xae\xd2\xec\xa2\x0c\x5a\x73\x10\x03\x7c\xf7\x32\x95\xe1\xed\x8e\xef\xfe\x95\x29\x2e\xf9\x9e\xbe\x5b\xa3\xa8\x8c\x0d\x24\x63\x61\xe5\x68\xcc\x90\x01\x32\x4b\x21\x77\x7e\xe8\xd1\x3f\xb5\x8c\xbb\xd1\x1b\x14\xf4\xea\xb4\x3b\x25\x53\x8f\x18\x76\xd5\x23\xcb\xb0\x4c\x5e\x4b\x04\x9f\x72\x25\x52\x2e\x7e\xc8\xb8\xa1\x88\x39\x5f\x36\x30\x41\xc5\x86\x9a\x35\x52\x1b\xfe\x1b\x9d\x89\xf1\x3d\x5f\x23\xbd\xf4\xb1\x2e\x13\x97\x90\xde\x90\xb6\x82\xcf\x5a\x60\xfc\x59\x88\xfc\x44\x1e\x02\xc6\x2a\x9b\xdf\x2e\x0c\x06\x85\x41\xcb\x3a\x80\x3b\x1e\xf1\x56\x06\x9a\x9d\x97\x62\xca\x02\x5b\xbd\x9a\xb3\xc1\x25\x2a\x63\x08\x6d\x0f\xf1\x0f\xba\xb1\x0c\xe4\x4b\x9a\x30\xad\x56\x8c\x8a\x1f\x5f\x7e\xb3\xa3\xe9\xeb\x56\xb9\x02\x0d\x04\x55\x08\x5e\x1d\x01\x10\x00\xc3\x7a\xa5\xc2\xc9\x52\x1c\x3d\x6d\xf3\xb9\x92\xa8\x4b\xbf\x8a\x6b\xb7\x40\x2a\x54\x15\x28\x93\xa5\x3c\xb4\x86\x84\x73\xdb\xc3\x69\xab\x01\x70\x51\xd7\x80\xfb\x28\x38\x6f\x7b\x0d\x70\x7a\x05\xdb\xec\x1e\xe2\xbf\xe6\xe3\x15\x1f\x93\xcd\x7b\x9f\x0c\x2e\x9d\x3c\x88\x2a\x08\xb7\x40\xb4\x09\xb3\x77\xf8\x3f\x50\x6d\xe8\x37\xec\x0c\x8a\xc8\x56\xa7\x07\xf0\x97\xab\x5b\x4f\x29\x50\x89\x73\xa0\x4c\x36\x43\xbf\x06\xcc\x27\x52\xc4\xd3\x9a\x57\x1d\xe0\x6a\x2f\xa5\xa2\x54\x38\xe6\x73\x6e\x51\x94\x40\x16\xe1\xcd\x1a\x21\x86\x63\x86\x7d\xdb\x12\x70\x67\x9e\x60\xc1\x3f\xc8\xd1\x6a\xce\xdd\x59\x02\xb5\x78\xbd\xad\x61\x38\xb3\x94\xa4\xd1\x6f\xf5\x33\xb2\xd1\x95\x62\xff\x20\xe2\xfa\xc6\x00\xf5\xf0\x92\x65\x4f\x5a\x95\x62\x3f\x71\xb0\x5c\xb7\x92\x3e\xdd\xb8\x75\x97\x6e\xae\x9a\x56\x6c\x61\x09\xbc\xba\xa9\xd2\x82\x24\x16\xa5\x19\xba\x50\x93\xba\xc5\x06\xe6\x50\xdf\x46\xcc\x26\x32\x28\x29\xa9\xcd\x94\x5d\xba\xaa\xa3\x8e\xd8\x85\xd7\x45\xb5\xcb\x38\xa8\x4d\xf4\xed\xab\x67\x2f\x53\xa3\xdd\x20\xd6\x18\xf3\x0d\x94\xb8\xe8\xd1\x77\xd8\x02\x86\xdb\xc6\xb9\xdb\x8e\x23\x0a\xa5\x45\x36\x12\x69\x75\xf5\x74\x3a\x05\x7b\x5b\xd6\xa9\x9c\xd1\x9b\xea\x48\x0e\xe9\x8e\xf5\xe5\xf9\x8c\xc9\xb3\x15\x72\xc3\x1b\x6a\x43\xda\x5f\x7b\xce\x84\xa3\x54\x57\xff\xa5\x8a\x01\x6a\xc8\x17\xe3\x77\xb7\x57\xf6\x84\x93\xd3\xd4\x81\x76\xd8\x16\x6d\x90\xc4\x53\x1c\x21\x84\x8e\xf4\x61\x03\x32\x81\x3e\x43\x1a\x0c\x5d\xfd\x54\x8c\xbc\x4c\x08\xae\x60\x0f\x98\x87\x2f\x71\x5f\xdb\x3c\x97\x2f\x39\x53\x64\x4f\x9f\x1c\xf3\x0b\x70\x09\x33\x72\x9d\xae\xea\x92\x7d\xc6\x90\x06\x7a\x4a\xaa\x7a\xa9\xc8\x49\x76\x76\xa3\xcc\x97\xb2\xab\xfc\x35\x5b\xe5\xd7\x36\x92\x89\x2a\x94\xfa\x46\xa4\xf6\x62\x20\xff\x6f\x96\x0b\xd5\xb5\xa8\xed\x8f\x79\x22\xd6\xda\xd8\xa2\xb3\xdf\x34\x42\x79\xb2\x0c\xe0\x60\xda\x82\xf4\xd4\x84\xe1\xfe\xef\x86\x4e\x87\x44\x1b\x07\xd1\x60\x9a\x0d\x00\x98\x14\x8d\xc5\x0c\xa5\x69\x74\x2e\xea\x06\xf2\x51\xba\xc2\xe9\x21\x03\x84\x18\x15\x6a\x5f\xd9\x03\xd5\x81\x34\x7a\xdd\x56\xe9\x16\x0c\x02\x9d\x47\x12\x10\xfa\x87\x07\x40\x51\x0a\xc0\xc7\xb1\xdd\x24\xfb\xf6\x12\xb8\xfa\x25\x00\x11\x01\x00\x01\x89\x02\x1f\x04\x18\x01\x08\x00\x09\x05\x02\x55\x08\x5e\x1d\x02\x1b\x0c\x00\x0a\x09\x10\x3e\xbf\xca\xaa\x8c\x8a\xd9\x9e\xb3\x3c\x0f\xfe\x3e\x42\x53\xcc\xff\x24\x43\x0e\x06\x5b\x4c\x76\x67\x15\xdf\x3a\x69\x11\x55\x8a\x52\x12\x81\xde\x85\xfe\xb2\xf5\x81\x4d\xd3\x4f\x93\xf2\x96\xfb\xd5\x11\x88\xb6\xfb\x97\xe6\xfe\xa8\x3c\xa3\xc2\x94\xe9\xc8\x56\x0d\x96\x54\x73\xaa\xe9\x0d\xc7\xb1\x71\x33\x97\xba\x08\x6c\xeb\x4f\x13\xdf\x16\x5c\x78\x95\x5e\xe7\x7f\x76\x37\x39\xe2\xe1\xf3\xf5\x68\xd2\x3d\xfc\xbf\x89\xd3\xfb\x48\xcb\x25\xa3\x6f\x41\x1d\x1f\xca\xf6\x74\x24\x88\x6b\x5a\xc8\x3e\x7b\xc1\xdc\x60\x6c\xb5\xce\x6c\x4d\xdf\x03\x48\x25\xe0\x0b\x16\x97\x51\x19\xcc\xd7\x16\x54\xbe\x12\x22\xbb\xe7\x04\x6a\x58\x21\x41\x81\x72\xc4\xc8\x88\xfd\xe9\xd3\xd6\xee\xe1\x07\xfa\x1e\x32\x51\x5d\x99\x41\xba\x2c\xe2\x80\x88\x1e\x3b\x7f\x65\xfc\x6e\xad\x6f\xa1\x80\xd5\xc9\xdb\xab\x8c\xba\x68\x2b\x50\x79\x71\xcb\xae\x7b\xda\x93\x58\xd1\xab\x39\xe5\x25\x65\x2a\x4b\x59\x90\x80\xe3\xc5\xd4\xcb\x8e\x76\xe1\xc0\xbd\x06\xdf\x30\x14\x17\x00\x47\xe0\x39\x3c\xee\x1f\xd3\xee\x2a\x81\xa6\xec\xc7\x8f\xc1\x3a\xd4\xe4\x6b\x0e\xa4\xd8\x12\xe0\xb6\xef\x21\x13\x83\x27\x16\x03\xfa\xf2\x30\x03\x90\x67\x8a\x28\xe0\x7c\xdf\x5a\x8f\xd2\x90\x54\xc5\x11\xad\xde\x0d\xa7\xb8\xb4\x11\x59\xa3\xf0\xff\x45\xb4\xd8\x18\xb0\x46\x83\xb7\xb9\x5a\x1a\x93\x41\xf7\xef\x58\xf6\x17\x9b\xea\x43\x44\xba\x51\x7b\x28\x8e\xf2\xf0\x22\xa2\x92\x0b\xc5\x18\x71\xc2\xc9\x7d\x81\x08\x26\xd0\x06\xa8\xba\xc1\xb1\x06\xab\x5e\xaa\x91\x32\x66\x7a\xc6\x2e\xf6\x28\x38\xbf\x8c\x43\xfd\x0f\xdc\x2c\x91\x73\x88\x92\xe3\x11\xc5\xac\x2f\xb8\x6a\xee\xad\xa8\xe9\xee\xcd\x2f\xa8\x5f\xe5\xa4\xc7\xd3\xf6\xdd\x78\xc5\xcc\xa9\x1c\xc3\x08\x01\x50\xe5\x9f\xb1\xd1\x05\x02\x81\x5a\x27\xc7\x38\xfe\x0a\xe4\xc3\xfc\xb7\x8e\xb3\xf4\x07\xbb\xff\x5e\x9a\xf9\xbd\x10\xe3\x18\x63\xf5\xfd\xbe\x27\x4b\x7f\x9f\x0f\x4f\xf0\x0c\xa8\xc8\x98\x6c\xd5\xad\xcb\xaa\x98\xea\x4d\x8b\x33\x0e\xf8\x61\xde\x3e\x84\xef\x93\x8e\xb9\x3c\x32\xba\x9b\x09\x4b\x3d\x87\xa8\xa1\xf4\x83\x82\xa3\xaf\x09\x4d\x64\x10\x6e\x05\x92\x93\x64\xc0\xc9\xdd\xd4\xe0\xea\x93\xc8\x19\xc7\x5a\xbd\x07\x84\x70\xd1\x4c\xec\x72\x0d\xb6\x54\xb5\x76\xe4\xfe\xbe\x10\xe2\x04\xdc\x02\xdf\xaa\x8e\x9b\x30\x3f\x29",false))
+
      (CASE_S(QType::SPF, "\"v=spf1 a:mail.rec.test ~all\"", "\x1bv=spf1 
a:mail.rec.test ~all",false))
      (CASE_S(QType::EUI48, "00-11-22-33-44-55", 
"\x00\x11\x22\x33\x44\x55",false))
      (CASE_S(QType::EUI64, "00-11-22-33-44-55-66-77", 
"\x00\x11\x22\x33\x44\x55\x66\x77",false))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-3.4.6/pdns/ueberbackend.cc 
new/pdns-3.4.7/pdns/ueberbackend.cc
--- old/pdns-3.4.6/pdns/ueberbackend.cc 2015-08-24 11:12:00.000000000 +0200
+++ new/pdns-3.4.7/pdns/ueberbackend.cc 2015-10-13 10:37:24.000000000 +0200
@@ -278,11 +278,12 @@
 {
   int best_match_len = -1;
   bool from_cache = false;  // Was this result fetched from the cache?
+  map<string,int> negCacheMap;
 
   // If not special case of caching explicitly disabled (sd->db = -1), first
   // find the best match from the cache. If DS then we need to find parent so
   // dont bother with caching as it confuses matters.
-  if( sd->db != (DNSBackend *)-1 && d_cache_ttl && p->qtype != QType::DS ) {
+  if( sd->db != (DNSBackend *)-1 && (d_cache_ttl || d_negcache_ttl)) {
       string subdomain(target);
       int cstat, loops = 0;
       do {
@@ -292,7 +293,7 @@
 
         cstat = cacheHas(d_question,d_answers);
 
-        if(cstat==1 && !d_answers.empty()) {
+        if(cstat==1 && !d_answers.empty() && d_cache_ttl) {
           fillSOAData(d_answers[0].content,*sd);
           sd->domain_id = d_answers[0].domain_id;
           sd->ttl = d_answers[0].ttl;
@@ -301,29 +302,51 @@
           //L<<Logger::Error<<"Best cache match: " << sd->qname << " 
itteration " << loops <<endl;
 
           // Found first time round this must be the best match
-          if( loops == 0 )
+          if( loops == 0  && p->qtype != QType::DS)
             return true;
 
           from_cache = true;
           best_match_len = sd->qname.length();
 
-          break;
-        }
+          if ( p->qtype != QType::DS || best_match_len < (int)target.length())
+            break;
+        } else if (cstat==0 && d_negcache_ttl) {
+          negCacheMap[subdomain]=1;
+        } else
+          negCacheMap[subdomain]=0;
         loops++;
       }
       while( chopOff( subdomain ) );   // 'www.powerdns.org' -> 'powerdns.org' 
-> 'org' -> ''
   }
 
-  for(vector<DNSBackend *>::const_iterator i=backends.begin(); 
i!=backends.end();++i)
-    if((*i)->getAuth(p, sd, target, zoneId, best_match_len)) {
+  for(vector<DNSBackend *>::const_iterator i=backends.begin(); 
i!=backends.end();++i) {
+
+    // Shortcut for the case that we got a direct hit - no need to go
+    // through the other backends then.
+    if( best_match_len == (int)target.length() && p->qtype != QType::DS )
+      goto auth_found;
+
+    if((*i)->getAuth(p, sd, target, zoneId, best_match_len, negCacheMap)) {
         best_match_len = sd->qname.length();
         from_cache = false;
+    }
+  }
 
-        // Shortcut for the case that we got a direct hit - no need to go
-        // through the other backends then.
-        if( best_match_len == (int)target.length() )
-            goto auth_found;
+  if( sd->db != (DNSBackend *)-1 && d_negcache_ttl) {
+    string shorter(target);
+
+    d_question.qtype=QType::SOA;
+    d_question.zoneId=-1;
+    while((int)shorter.length() > best_match_len ) {
+      map<string,int>::iterator it = negCacheMap.find(shorter);
+      if (it == negCacheMap.end() || it->second == 0) {
+        d_question.qname=shorter;
+        addNegCache(d_question);
+      }
+      if (!chopOff(shorter))
+        break;
     }
+  }
 
   if( best_match_len == -1 )
       return false;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-3.4.6/pdns/ueberbackend.hh 
new/pdns-3.4.7/pdns/ueberbackend.hh
--- old/pdns-3.4.6/pdns/ueberbackend.hh 2015-08-24 11:12:00.000000000 +0200
+++ new/pdns-3.4.7/pdns/ueberbackend.hh 2015-10-13 10:37:24.000000000 +0200
@@ -114,8 +114,8 @@
   void lookup(const QType &, const string &qdomain, DNSPacket *pkt_p=0,  int 
zoneId=-1);
 
   /* 5-arg version is only valid for backends and should never be called 
directly */
-  virtual bool getAuth(DNSPacket *p, SOAData *sd, const string &target, int 
*zoneId, const int best_match_len) {
-    throw PDNSException("5-arg version of getAuth should not be called in 
UeberBackend");
+  virtual bool getAuth(DNSPacket *p, SOAData *sd, const string &target, int 
*zoneId, const int best_match_len, map<string,int>& negCacheMap) {
+    throw PDNSException("6-arg version of getAuth should not be called in 
UeberBackend");
   }
 
   bool getAuth(DNSPacket *p, SOAData *sd, const string &target, int *zoneId);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-3.4.6/pdns/ws-auth.cc 
new/pdns-3.4.7/pdns/ws-auth.cc
--- old/pdns-3.4.6/pdns/ws-auth.cc      2015-08-24 11:12:00.000000000 +0200
+++ new/pdns-3.4.7/pdns/ws-auth.cc      2015-09-30 13:07:31.000000000 +0200
@@ -122,6 +122,9 @@
     case '>':
       result += "&gt;";
       break;
+    case '"':
+      result += "&quot;";
+      break;
     default:
       result += *it;
     }
@@ -141,15 +144,15 @@
   }
 
   ret<<"<div class=\"panel\">";
-  ret<<"<span class=resetring><i></i><a 
href=\"?resetring="<<ringname<<"\">Reset</a></span>"<<endl;
+  ret<<"<span class=resetring><i></i><a 
href=\"?resetring="<<htmlescape(ringname)<<"\">Reset</a></span>"<<endl;
   ret<<"<h2>"<<title<<"</h2>"<<endl;
   ret<<"<div class=ringmeta>";
-  ret<<"<a class=topXofY href=\"?ring="<<ringname<<"\">Showing: Top 
"<<limit<<" of "<<entries<<"</a>"<<endl;
+  ret<<"<a class=topXofY href=\"?ring="<<htmlescape(ringname)<<"\">Showing: 
Top "<<limit<<" of "<<entries<<"</a>"<<endl;
   ret<<"<span class=resizering>Resize: ";
   unsigned int sizes[]={10,100,500,1000,10000,500000,0};
   for(int i=0;sizes[i];++i) {
     if(S.getRingSize(ringname)!=sizes[i])
-      ret<<"<a 
href=\"?resizering="<<ringname<<"&amp;size="<<sizes[i]<<"\">"<<sizes[i]<<"</a> 
";
+      ret<<"<a 
href=\"?resizering="<<htmlescape(ringname)<<"&amp;size="<<sizes[i]<<"\">"<<sizes[i]<<"</a>
 ";
     else
       ret<<"("<<sizes[i]<<") ";
   }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-3.4.6/pdns.spec new/pdns-3.4.7/pdns.spec
--- old/pdns-3.4.6/pdns.spec    2015-08-27 15:17:34.000000000 +0200
+++ new/pdns-3.4.7/pdns.spec    2015-11-03 15:36:48.000000000 +0100
@@ -1,6 +1,6 @@
 BuildRoot: /tmp/pdns
 Name: pdns-static
-Version: 3.4.6
+Version: 3.4.7
 Release: 1
 Summary: extremely powerful and versatile nameserver
 License: GPL


Reply via email to