--- /dev/null
+#!/usr/bin/env bash
+set -e
+set -x
+
+port=5501
+rm -f pdns*.pid
+
+$PDNS --daemon=no --local-port=$port --socket-dir=./ \
+ --no-shuffle --launch=bind,pipe --bind-config=negcache-tests-dotted-cname/named.conf \
+ --pipe-command=negcache-tests-dotted-cname/pipe.py \
+ --send-root-referral --cache-ttl=60 --no-config --module-dir=../regression-tests/modules &
+
+sleep 3
+
+$SDIG 127.0.0.1 5501 cname.example2.com A | LC_ALL=C sort
+
+# check if we didn't neg-cache .com
+$SDIG 127.0.0.1 5501 www.example.com A | LC_ALL=C sort
+
+kill $(cat pdns*.pid)
+rm pdns*.pid
--- /dev/null
+This test the correct workings of DNSName in combination with negative caching.
+In the pre-DNSName era, it was possible for a pipe-backend to return a CNAME
+with a dot on the end. When trying to look up the target of the CNAME, PowerDNS
+would negatively cache _all_ names down to that name (i.e. ., com., powerdns.
+for www.powerdns.com) and send out wrong answers for all domains after that.
--- /dev/null
+$TTL 120
+$ORIGIN example.com.
+@ 100000 IN SOA ns1.example.com. ahu.example.com. (
+ 2000081501
+ 8H ; refresh
+ 2H ; retry
+ 1W ; expire
+ 1D ; default_ttl
+ )
+
+@ IN NS ns1.example.com.
+@ IN NS ns2.example.com.
+
+www IN A 127.0.0.1
--- /dev/null
+0 cname.example2.com. IN CNAME 3600 www.example.com.
+0 www.example.com. IN A 120 127.0.0.1
+Rcode: 0 (No Error), RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0
+Reply to question for qname='cname.example2.com.', qtype=A
+0 www.example.com. IN A 120 127.0.0.1
+Rcode: 0 (No Error), RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0
+Reply to question for qname='www.example.com.', qtype=A
--- /dev/null
+options {
+ directory "negcache-tests-dotted-cname";
+ version "Meow!Meow!";
+};
+
+zone "example.com" {
+ type master;
+ file "example.com.zone";
+};
--- /dev/null
+#!/usr/bin/python2 -u
+
+import sys
+
+line = sys.stdin.readline()
+# TOLO
+print 'OK\tTest backend firing up'
+
+while True:
+ line = sys.stdin.readline()
+ items = line.split('\t')
+ sys.stderr.write(line)
+ if len(items) < 6:
+ print 'LOG\tGot an unparsable line'
+ print 'LOG\t%s' % line
+ print 'END'
+ continue
+
+ what, qname, qclass, qtype, id, ip = items
+
+ if qtype in ['SOA', 'ANY'] and qname == 'example2.com':
+ print 'DATA\t%s\t%s\tSOA\t300\t-1\tns1.example.com ahu.example.com 2008080300 1800 3600 604800 3600' % (qname, qclass)
+
+ if qtype in ['NS', 'ANY'] and qname == 'example2.com':
+ print 'DATA\t%s\t%s\tNS\t3600\t-1\tns1.example.com' % (qname, qclass)
+ print 'DATA\t%s\t%s\tNS\t3600\t-1\tns2.example.com' % (qname, qclass)
+
+ if qtype in ['A', 'ANY'] and qname.endswith('example2.com'):
+ # We were asked a specific record
+ print 'DATA\t%s\t%s\tCNAME\t3600\t-1\twww.example.com.' % (qname, qclass)
+
+ print 'END'