summaryrefslogtreecommitdiff
path: root/dns/powerdns-recursor
diff options
context:
space:
mode:
authorMartin Wilke <miwi@FreeBSD.org>2007-09-06 22:37:02 +0000
committerMartin Wilke <miwi@FreeBSD.org>2007-09-06 22:37:02 +0000
commit05290f75897f6fc985520835782119ad8b28d6d8 (patch)
tree5f62d89ed675a9ff4a6da8eb5822da45e905058b /dns/powerdns-recursor
parent[new port] japanese/asterisk-sounds-jp Japanese sound files for Asterisk (diff)
- Backport multiline txt records support [1]
- Bump PORTREVISION [1] Notes: powerdns-recursor 3.1.4 doesn't support multiline txt records, which are used by various dns information systems. 3.1.5 does have support for this. A backport of the code changes is relatively risk-free, and has been requested by users and port maintainers. http://www.nabble.com/recursor-unable-to-resolve-asn.routeviews.org-data-t4252567.html PR: 116029 Submitted by: Sten Spans <sten@blinkenlights.nl> (Maintainer)
Notes
Notes: svn path=/head/; revision=198957
Diffstat (limited to 'dns/powerdns-recursor')
-rw-r--r--dns/powerdns-recursor/Makefile2
-rw-r--r--dns/powerdns-recursor/files/patch-multiline_txt_records398
2 files changed, 399 insertions, 1 deletions
diff --git a/dns/powerdns-recursor/Makefile b/dns/powerdns-recursor/Makefile
index f06e38fad9ec..ced0e2082574 100644
--- a/dns/powerdns-recursor/Makefile
+++ b/dns/powerdns-recursor/Makefile
@@ -7,7 +7,7 @@
PORTNAME= powerdns-recursor
PORTVERSION= 3.1.4
-PORTREVISION= 5
+PORTREVISION= 6
CATEGORIES= dns ipv6
MASTER_SITES= http://downloads.powerdns.com/releases/ \
http://mirrors.evolva.ro/powerdns.com/releases/
diff --git a/dns/powerdns-recursor/files/patch-multiline_txt_records b/dns/powerdns-recursor/files/patch-multiline_txt_records
new file mode 100644
index 000000000000..6e17c396bfe0
--- /dev/null
+++ b/dns/powerdns-recursor/files/patch-multiline_txt_records
@@ -0,0 +1,398 @@
+Index: dnswriter.hh
+===================================================================
+--- dnswriter.hh (revision 962)
++++ dnswriter.hh (revision 996)
+@@ -84,5 +84,5 @@
+
+ void xfrLabel(const string& label, bool compress=false);
+- void xfrText(const string& text);
++ void xfrText(const string& text, bool multi=false);
+ void xfrBlob(const string& blob);
+ void xfrHexBlob(const string& blob);
+Index: dnsparser.hh
+===================================================================
+--- dnsparser.hh (revision 972)
++++ dnsparser.hh (revision 996)
+@@ -110,7 +110,7 @@
+ }
+
+- void xfrText(string &text)
+- {
+- text=getText();
++ void xfrText(string &text, bool multi=false)
++ {
++ text=getText(multi);
+ }
+
+@@ -126,5 +126,5 @@
+
+ string getLabel(unsigned int recurs=0);
+- string getText();
++ string getText(bool multi);
+
+ uint16_t d_pos;
+Index: zoneparser-tng.cc
+===================================================================
+--- zoneparser-tng.cc (revision 989)
++++ zoneparser-tng.cc (revision 996)
+@@ -281,6 +281,5 @@
+ }
+ catch(...) {
+- cerr<<"Oops, this doesn't look like a qtype, stopping loop\n";
+- break;
++ throw runtime_error("Parsing zone content line: '"+nextpart+"' doesn't look like a qtype, stopping loop");
+ }
+ }
+Index: dnswriter.cc
+===================================================================
+--- dnswriter.cc (revision 962)
++++ dnswriter.cc (revision 996)
+@@ -2,4 +2,5 @@
+ #include "misc.hh"
+ #include "dnsparser.hh"
++#include <boost/tokenizer.hpp>
+
+ DNSPacketWriter::DNSPacketWriter(vector<uint8_t>& content, const string& qname, uint16_t qtype, uint16_t qclass, uint8_t opcode)
+@@ -116,9 +117,20 @@
+ }
+
+-void DNSPacketWriter::xfrText(const string& text)
+-{
+- d_record.push_back(text.length());
+- const uint8_t* ptr=(uint8_t*)(text.c_str());
+- d_record.insert(d_record.end(), ptr, ptr+text.size());
++void DNSPacketWriter::xfrText(const string& text, bool)
++{
++ escaped_list_separator<char> sep('\\', ' ' , '"');
++ tokenizer<escaped_list_separator<char> > tok(text, sep);
++
++ tokenizer<escaped_list_separator<char> >::iterator beg=tok.begin();
++
++ if(beg==tok.end()) {
++ d_record.push_back(0);
++ }
++ else
++ for(; beg!=tok.end(); ++beg){
++ d_record.push_back(beg->length());
++ const uint8_t* ptr=(uint8_t*)(beg->c_str());
++ d_record.insert(d_record.end(), ptr, ptr+beg->length());
++ }
+ }
+
+Index: dnsparser.cc
+===================================================================
+--- dnsparser.cc (revision 972)
++++ dnsparser.cc (revision 996)
+@@ -359,14 +359,42 @@
+ }
+
+-string PacketReader::getText()
++static string txtEscape(const string &name)
++{
++ string ret;
++
++ for(string::const_iterator i=name.begin();i!=name.end();++i)
++ if(*i=='"' || *i=='\\'){
++ ret += '\\';
++ ret += *i;
++ }
++ else
++ ret += *i;
++ return ret;
++}
++
++// exceptions thrown here do not result in logging in the main pdns auth server - just so you know!
++string PacketReader::getText(bool multi)
+ {
+ string ret;
+ ret.reserve(40);
+-
+- unsigned char labellen=d_content.at(d_pos++);
+- ret.append(&d_content.at(d_pos), &d_content.at(d_pos+labellen-1)+1); // the end is one beyond the packet
+- d_pos+=labellen;
+- return ret;
+-}
++ while(d_pos < d_startrecordpos + d_recordlen ) {
++ if(!ret.empty()) {
++ ret.append(1,' ');
++ }
++ unsigned char labellen=d_content.at(d_pos++);
++
++ ret.append(1,'"');
++ string val(&d_content.at(d_pos), &d_content.at(d_pos+labellen-1)+1);
++
++ ret.append(txtEscape(val)); // the end is one beyond the packet
++ ret.append(1,'"');
++ d_pos+=labellen;
++ if(!multi)
++ break;
++ }
++
++ return ret;
++}
++
+
+ void PacketReader::getLabelFromContent(const vector<uint8_t>& content, uint16_t& frompos, string& ret, int recurs)
+Index: rcpgenerator.hh
+===================================================================
+--- rcpgenerator.hh (revision 802)
++++ rcpgenerator.hh (revision 996)
+@@ -51,5 +51,5 @@
+
+ void xfrLabel(string& val, bool compress=false);
+- void xfrText(string& val);
++ void xfrText(string& val, bool multi=false);
+ void xfrHexBlob(string& val);
+ void xfrBlob(string& val);
+@@ -76,5 +76,5 @@
+ void xfrType(const uint16_t& val);
+ void xfrLabel(const string& val, bool compress=false);
+- void xfrText(const string& val);
++ void xfrText(const string& val, bool multi=false);
+ void xfrBlob(const string& val);
+ void xfrHexBlob(const string& val);
+Index: dnsrecords.cc
+===================================================================
+--- dnsrecords.cc (revision 823)
++++ dnsrecords.cc (revision 996)
+@@ -1,5 +1,5 @@
+ /*
+ PowerDNS Versatile Database Driven Nameserver
+- Copyright (C) 2005 - 2006 PowerDNS.COM BV
++ Copyright (C) 2005 - 2007 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+@@ -178,6 +178,6 @@
+ boilerplate_conv(PTR, ns_t_ptr, conv.xfrLabel(d_content, true));
+ boilerplate_conv(CNAME, ns_t_cname, conv.xfrLabel(d_content, true));
+-boilerplate_conv(TXT, ns_t_txt, conv.xfrText(d_text));
+-boilerplate_conv(SPF, 99, conv.xfrText(d_text));
++boilerplate_conv(TXT, ns_t_txt, conv.xfrText(d_text, true));
++boilerplate_conv(SPF, 99, conv.xfrText(d_text, true));
+ boilerplate_conv(HINFO, ns_t_hinfo, conv.xfrText(d_cpu); conv.xfrText(d_host));
+
+@@ -199,4 +199,9 @@
+ conv.xfr16BitInt(d_preference);
+ conv.xfrLabel(d_mxname, true);
++ )
++
++boilerplate_conv(AFSDB, ns_t_afsdb,
++ conv.xfr16BitInt(d_subtype);
++ conv.xfrLabel(d_hostname);
+ )
+
+@@ -235,4 +240,11 @@
+ conv.xfr32BitInt(d_st.expire);
+ conv.xfr32BitInt(d_st.minimum);
++ );
++#undef KEY
++boilerplate_conv(KEY, ns_t_key,
++ conv.xfr16BitInt(d_flags);
++ conv.xfr8BitInt(d_protocol);
++ conv.xfr8BitInt(d_algorithm);
++ conv.xfrBlob(d_certificate);
+ );
+
+@@ -294,7 +306,9 @@
+ void reportOtherTypes()
+ {
++ AFSDBRecordContent::report();
+ SPFRecordContent::report();
+ NAPTRRecordContent::report();
+ RPRecordContent::report();
++ KEYRecordContent::report();
+ DNSKEYRecordContent::report();
+ RRSIGRecordContent::report();
+Index: dnsrecords.hh
+===================================================================
+--- dnsrecords.hh (revision 823)
++++ dnsrecords.hh (revision 978)
+@@ -196,4 +196,26 @@
+ string d_fingerprint;
+ };
++
++class KEYRecordContent : public DNSRecordContent
++{
++public:
++ includeboilerplate(KEY)
++
++private:
++ uint16_t d_flags;
++ uint8_t d_protocol, d_algorithm;
++ string d_certificate;
++};
++
++class AFSDBRecordContent : public DNSRecordContent
++{
++public:
++ includeboilerplate(AFSDB)
++
++private:
++ uint16_t d_subtype;
++ string d_hostname;
++};
++
+
+ class CERTRecordContent : public DNSRecordContent
+Index: rcpgenerator.cc
+===================================================================
+--- rcpgenerator.cc (revision 850)
++++ rcpgenerator.cc (revision 996)
+@@ -67,9 +67,38 @@
+ if(!isdigit(d_string.at(d_pos)))
+ throw RecordTextException("while parsing IP address, expected digits at position "+lexical_cast<string>(d_pos)+" in '"+d_string+"'");
+-
+- string ip;
+- xfrLabel(ip);
+- if(!IpToU32(ip, &val))
+- throw RecordTextException("unable to parse IP address '"+ip+"'");
++
++ uint32_t octet=0;
++ val=0;
++ char count=0;
++
++ for(;;) {
++ if(d_string.at(d_pos)=='.') {
++ val<<=8;
++ val+=octet;
++ octet=0;
++ count++;
++ if(count > 3)
++ break;
++ }
++ else if(isdigit(d_string.at(d_pos))) {
++ octet*=10;
++ octet+=d_string.at(d_pos) - '0';
++ if(octet > 255)
++ throw RecordTextException("unable to parse IP address");
++ }
++ else if(dns_isspace(d_string.at(d_pos)))
++ break;
++ else
++ throw RecordTextException("unable to parse IP address, strange character: "+d_string.at(d_pos));
++
++ d_pos++;
++ if(d_pos == d_string.length())
++ break;
++ }
++ if(count<=3) {
++ val<<=8;
++ val+=octet;
++ }
++ val=ntohl(val);
+ }
+
+@@ -178,23 +207,31 @@
+ }
+
+-
+-void RecordTextReader::xfrText(string& val)
+-{
+- skipSpaces();
+- if(d_string[d_pos]!='"')
+- throw RecordTextException("Data field in DNS should start with quote (\") at position "+lexical_cast<string>(d_pos)+" of '"+d_string+"'");
+-
++void RecordTextReader::xfrText(string& val, bool multi)
++{
+ val.clear();
+ val.reserve(d_end - d_pos);
+-
+- while(++d_pos < d_end && d_string[d_pos]!='"') {
+- if(d_string[d_pos]=='\\' && d_pos+1!=d_end) {
+- ++d_pos;
++
++ while(d_pos != d_end) {
++ if(!val.empty())
++ val.append(1, ' ');
++
++ skipSpaces();
++ if(d_string[d_pos]!='"')
++ throw RecordTextException("Data field in DNS should start with quote (\") at position "+lexical_cast<string>(d_pos)+" of '"+d_string+"'");
++
++ val.append(1, '"');
++ while(++d_pos < d_end && d_string[d_pos]!='"') {
++ if(d_string[d_pos]=='\\' && d_pos+1!=d_end) {
++ val.append(1, d_string[d_pos++]);
++ }
++ val.append(1, d_string[d_pos]);
+ }
+- val.append(1, d_string[d_pos]);
+- }
+- if(d_pos == d_end)
+- throw RecordTextException("Data field in DNS should end on a quote (\") in '"+d_string+"'");
+- d_pos++;
++ val.append(1,'"');
++ if(d_pos == d_end)
++ throw RecordTextException("Data field in DNS should end on a quote (\") in '"+d_string+"'");
++ d_pos++;
++ if(!multi)
++ break;
++ }
+ }
+
+@@ -251,11 +288,28 @@
+
+ char tmp[17];
+- snprintf(tmp, sizeof(tmp)-1, "%u.%u.%u.%u",
+- (val >> 24)&0xff,
+- (val >> 16)&0xff,
+- (val >> 8)&0xff,
+- (val )&0xff);
+-
+- d_string+=tmp;
++ uint32_t ip=htonl(val);
++ uint8_t vals[4];
++
++ memcpy(&vals[0], &ip, sizeof(ip));
++
++ char *pos=tmp;
++
++ for(int n=0; n < 4; ++n) {
++ if(vals[n]<10) {
++ *(pos++)=vals[n]+'0';
++ } else if(vals[n] < 100) {
++ *(pos++)=(vals[n]/10) +'0';
++ *(pos++)=(vals[n]%10) +'0';
++ } else {
++ *(pos++)=(vals[n]/100) +'0';
++ vals[n]%=100;
++ *(pos++)=(vals[n]/10) +'0';
++ *(pos++)=(vals[n]%10) +'0';
++ }
++ if(n!=3)
++ *(pos++)='.';
++ }
++ *pos=0;
++ d_string.append(tmp, pos);
+ }
+
+@@ -338,23 +392,10 @@
+ }
+
+-void RecordTextWriter::xfrText(const string& val)
+-{
+- if(!d_string.empty())
+- d_string.append(1,' ');
+- d_string.append(1,'"');
+-
+- if(val.find_first_of("\\\"") == string::npos)
+- d_string+=val;
+- else {
+- string::size_type end=val.size();
+-
+- for(string::size_type pos=0; pos < end; ++pos) {
+- if(val[pos]=='\'' || val[pos]=='"')
+- d_string.append(1,'\\');
+- d_string.append(1, val[pos]);
+- }
+- }
+-
+- d_string.append(1,'"');
++void RecordTextWriter::xfrText(const string& val, bool multi)
++{
++ if(!d_string.empty())
++ d_string.append(1,' ');
++
++ d_string.append(val);
+ }
+