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:
parent
de6ccea84d
commit
05290f7589
Notes:
svn2git
2021-03-31 03:12:20 +00:00
svn path=/head/; revision=198957
@ -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/
|
||||
|
398
dns/powerdns-recursor/files/patch-multiline_txt_records
Normal file
398
dns/powerdns-recursor/files/patch-multiline_txt_records
Normal 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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user