1
0
mirror of https://git.FreeBSD.org/ports.git synced 2024-12-02 01:20:54 +00:00

- 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)
This commit is contained in:
Martin Wilke 2007-09-06 22:37:02 +00:00
parent de6ccea84d
commit 05290f7589
Notes: svn2git 2021-03-31 03:12:20 +00:00
svn path=/head/; revision=198957
2 changed files with 399 additions and 1 deletions

View File

@ -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/

View File

@ -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);
}