[Pdns-dev] [PATCH 1/3] Classless in-addr.arpa delegation for autogenerated records

Peter Collingbourne peter at pcc.me.uk
Mon Nov 17 22:42:17 CET 2008


This patch allows the LDAP (and other) backends to support classless
in-addr.arpa delegation for autogenerated PTR records. This is achieved
by modifying the ptr2ip4 function to discard non-numeric domain parts.
The patch also moves the ptr2ip* functions out of the LDAP backend
and into the server proper so they may be reused by other backends.
---
 modules/ldapbackend/ldapbackend.cc |    6 +-
 modules/ldapbackend/utils.hh       |   63 ------------------------------
 pdns/misc.hh                       |   74 ++++++++++++++++++++++++++++++++++++
 3 files changed, 77 insertions(+), 66 deletions(-)

diff --git a/modules/ldapbackend/ldapbackend.cc b/modules/ldapbackend/ldapbackend.cc
index 14e12ad..ef96a80 100644
--- a/modules/ldapbackend/ldapbackend.cc
+++ b/modules/ldapbackend/ldapbackend.cc
@@ -225,7 +225,7 @@ void LdapBackend::lookup_strict( const QType &qtype, const string &qname, DNSPac
 {
 	int len;
 	vector<string> parts;
-	string filter, attr, qesc;
+	string filter, attr, qesc, ip;
 	const char** attributes = ldap_attrany + 1;   // skip associatedDomain
 	const char* attronly[] = { NULL, "dNSTTL", "modifyTimestamp", NULL };
 
@@ -234,9 +234,9 @@ void LdapBackend::lookup_strict( const QType &qtype, const string &qname, DNSPac
 	stringtok( parts, qesc, "." );
 	len = qesc.length();
 
-	 if( parts.size() == 6 && len > 13 && qesc.substr( len - 13, 13 ) == ".in-addr.arpa" )   // IPv4 reverse lookups
+	 if( len > 13 && qesc.substr( len - 13, 13 ) == ".in-addr.arpa" && ptr2ip4( parts, ip ) )   // IPv4 reverse lookups
 	{
-		filter = "aRecord=" + ptr2ip4( parts );
+		filter = "aRecord=" + ip;
 		attronly[0] = "associatedDomain";
 		attributes = attronly;
 	}
diff --git a/modules/ldapbackend/utils.hh b/modules/ldapbackend/utils.hh
index 84b7bf8..600b6d0 100644
--- a/modules/ldapbackend/utils.hh
+++ b/modules/ldapbackend/utils.hh
@@ -12,69 +12,6 @@ using std::string;
 using std::vector;
 
 
-inline string ptr2ip4( vector<string>& parts )
-{
-	string ip;
-	parts.pop_back();
-	parts.pop_back();
-
-
-	ip = parts.back();
-	parts.pop_back();
-
-	while( !parts.empty() )
-	{
-		ip += "." + parts.back();
-		parts.pop_back();
-	}
-
-	return ip;
-}
-
-
-inline string ptr2ip6( vector<string>& parts )
-{
-	int i = 0;
-	string ip;
-
-
-	parts.pop_back();
-	parts.pop_back();
-
-	while( i < 3 && parts.size() > 1 && parts.back() == "0" )
-	{
-		parts.pop_back();
-		i++;
-	}
-
-	while( i++ < 4 && !parts.empty() )
-	{
-		ip += parts.back();
-		parts.pop_back();
-	}
-
-	while( !parts.empty() )
-	{
-		i = 0;
-		ip += ":";
-
-		while( i < 3 && parts.size() > 1 && parts.back() == "0" )
-		{
-			parts.pop_back();
-			i++;
-		}
-
-		while( i++ < 4 && !parts.empty() )
-		{
-			ip += parts.back();
-			parts.pop_back();
-		}
-	}
-
-	return ip;
-}
-
-
 inline string ip2ptr4( const string& ip )
 {
 	string ptr;
diff --git a/pdns/misc.hh b/pdns/misc.hh
index f04787a..4e4bc3a 100644
--- a/pdns/misc.hh
+++ b/pdns/misc.hh
@@ -380,6 +380,80 @@ inline void setSocketReusable(int fd)
   setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&tmp, static_cast<unsigned>(sizeof tmp));
 }
 
+inline bool isdigitstr(const string& str)
+{
+	for (string::const_iterator i = str.begin(); i != str.end(); i++)
+	{
+		if (!isdigit(*i))
+			return false;
+	}
+	return true;
+}
+
+inline bool ptr2ip4( const vector<string>& parts, string& ip )
+{
+	int count = 1;
+
+	vector<string>::const_reverse_iterator i = parts.rbegin();
+	++i; ++i;
+
+	ip = *i;
+
+	while( count <= 4 && ++i != parts.rend() )
+	{
+		if (isdigitstr(*i))
+		{
+			count++;
+			ip += "." + *i;
+		}
+	}
+
+	return ( count == 4 );
+}
+
+
+inline string ptr2ip6( vector<string>& parts )
+{
+	int i = 0;
+	string ip;
+
+
+	parts.pop_back();
+	parts.pop_back();
+
+	while( i < 3 && parts.size() > 1 && parts.back() == "0" )
+	{
+		parts.pop_back();
+		i++;
+	}
+
+	while( i++ < 4 && !parts.empty() )
+	{
+		ip += parts.back();
+		parts.pop_back();
+	}
+
+	while( !parts.empty() )
+	{
+		i = 0;
+		ip += ":";
+
+		while( i < 3 && parts.size() > 1 && parts.back() == "0" )
+		{
+			parts.pop_back();
+			i++;
+		}
+
+		while( i++ < 4 && !parts.empty() )
+		{
+			ip += parts.back();
+			parts.pop_back();
+		}
+	}
+
+	return ip;
+}
+
 string stripDot(const string& dom);
 void seedRandom(const string& source);
 #endif
-- 
1.5.6.5


-- 
Peter
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: Digital signature
Url : http://mailman.powerdns.com/pipermail/pdns-dev/attachments/20081117/f37ffd58/attachment.bin


More information about the Pdns-dev mailing list