]> granicus.if.org Git - pdns/commitdiff
dnsname: isRoot() empty() clear() toStringNoDot() makeRelative() labelReverse()
authorKees Monshouwer <mind04@monshouwer.org>
Wed, 3 Jun 2015 18:32:18 +0000 (20:32 +0200)
committermind04 <mind04@monshouwer.org>
Tue, 30 Jun 2015 06:12:46 +0000 (08:12 +0200)
pdns/dnsname.cc
pdns/dnsname.hh
pdns/misc.cc
pdns/packetcache.hh
pdns/packethandler.cc
pdns/test-dnsname_cc.cc
pdns/test-zoneparser_tng_cc.cc

index a926b7c130baec3ce59a91a29bf08c8478a86fd4..3b4f13038b456cd425fc067970916a4f403339ff 100644 (file)
@@ -18,6 +18,7 @@
 
 DNSName::DNSName(const char* p)
 {
+  d_empty=false;
   auto labels = segmentDNSName(p);
   for(const auto& e : labels)
     appendRawLabel(e);
@@ -25,6 +26,7 @@ DNSName::DNSName(const char* p)
 
 DNSName::DNSName(const char* pos, int len, int offset, bool uncompress, uint16_t* qtype, uint16_t* qclass, unsigned int* consumed)
 {
+  d_empty=false;
   d_recurse = 0;
   packetParser(pos, len, offset, uncompress, qtype, qclass, consumed);
 }
@@ -71,19 +73,23 @@ void DNSName::packetParser(const char* pos, int len, int offset, bool uncompress
 
 }
 
-std::string DNSName::toString() const
+std::string DNSName::toString(const std::string& separator, const bool trailing) const
 {
-  if(d_storage.empty())  // I keep wondering if there is some deeper meaning to the need to do this
-    return ".";
+  if (d_empty)
+    return "";
+  if(d_storage.empty() && trailing)  // I keep wondering if there is some deeper meaning to the need to do this
+    return separator;
   std::string ret;
   for(const auto& s : getRawLabels()) {
-    ret+= escapeLabel(s) + ".";
+    ret+= escapeLabel(s) + separator;
   }
-  return ret;
+  return ret.substr(0, ret.size()-!trailing);
 }
 
 std::string DNSName::toDNSString() const
 {
+  if (d_empty)
+    return "";
   string ret(d_storage.c_str(), d_storage.length());
   ret.append(1,(char)0);
   return ret;
@@ -96,6 +102,8 @@ size_t DNSName::length() const {
 // are WE part of parent
 bool DNSName::isPartOf(const DNSName& parent) const
 {
+  if(parent.d_empty || d_empty)
+    return false;
   if(parent.d_storage.empty())
     return true;
   if(parent.d_storage.size() > d_storage.size())
@@ -115,6 +123,29 @@ bool DNSName::isPartOf(const DNSName& parent) const
   return false;
 }
 
+DNSName DNSName::makeRelative(const DNSName& zone) const
+{
+  DNSName ret(*this);
+  if (ret.isPartOf(zone)) {
+    ret.d_storage.erase(ret.d_storage.size()-zone.d_storage.size());
+  } else
+    ret.clear();
+  return ret;
+}
+
+DNSName DNSName::labelReverse() const
+{
+  DNSName ret;
+  if (!d_empty) {
+    vector<string> l=getRawLabels();
+    while(!l.empty()) {
+      ret.appendRawLabel(l.back());
+      l.pop_back();
+    }
+  }
+  return ret;
+}
+
 void DNSName::appendRawLabel(const std::string& label)
 {
   if(label.empty())
@@ -124,6 +155,7 @@ void DNSName::appendRawLabel(const std::string& label)
   if(d_storage.size() + label.size() > 253) // reserve two bytes, one for length and one for the root label
     throw std::range_error("name too long to append");
 
+  d_empty=false;
   d_storage.append(1, (char)label.size());
   d_storage.append(label.c_str(), label.length());
 }
@@ -137,6 +169,7 @@ void DNSName::prependRawLabel(const std::string& label)
   if(d_storage.size() + label.size() > 253) // reserve two bytes, one for length and one for the root label
     throw std::range_error("name too long to prepend");
 
+  d_empty=false;
   string_t prep(1, (char)label.size());
   prep.append(label.c_str(), label.size());
   d_storage = prep+d_storage;
@@ -191,7 +224,7 @@ void DNSName::trimToLabels(unsigned int to)
 
 bool DNSName::operator==(const DNSName& rhs) const
 {
-  if(rhs.d_storage.size() != d_storage.size())
+  if(rhs.d_empty != d_empty || rhs.d_storage.size() != d_storage.size())
     return false;
 
   auto us = d_storage.crbegin();
index da3effe8cdcffe9ee5a34d4ed554087f2a8423e1..15d830bd3aa6db64a28f1d72f84947fecac4e5bb 100644 (file)
@@ -26,7 +26,7 @@
 class DNSName
 {
 public:
-  DNSName() {}                 //!< Constructs the root name
+  DNSName() : d_empty(true) {}                 //!< Don't constructs the root name
   DNSName(const char* p);      //!< Constructs from a human formatted, escaped presentation
   DNSName(const std::string& str) : DNSName(str.c_str()) {}   //!< Constructs from a human formatted, escaped presentation
   DNSName(const char* p, int len, int offset, bool uncompress, uint16_t* qtype=0, uint16_t* qclass=0, unsigned int* consumed=0); //!< Construct from a DNS Packet, taking the first question
@@ -35,17 +35,21 @@ public:
   bool operator==(const DNSName& rhs) const; //!< DNS-native comparison (case insensitive)
   bool operator!=(const DNSName& other) const { return !(*this == other); }
 
-  std::string toString() const;              //!< Our human-friendly, escaped, representation
+  std::string toString(const std::string& separator=".", const bool trailing=true) const;              //!< Our human-friendly, escaped, representation
+  std::string toStringNoDot() const { return toString(".", false); }
   std::string toDNSString() const;           //!< Our representation in DNS native format
   void appendRawLabel(const std::string& str); //!< Append this unescaped label
   void prependRawLabel(const std::string& str); //!< Prepend this unescaped label
   std::vector<std::string> getRawLabels() const; //!< Individual raw unescaped labels
   bool chopOff();                               //!< Turn www.powerdns.com. into powerdns.com., returns false for .
+  DNSName makeRelative(const DNSName& zone) const;
+  DNSName labelReverse() const;
   bool isWildcard() const;
   unsigned int countLabels() const;
-  bool empty() const { return countLabels()==0; } // FIXME remove me?
   size_t length() const; // FIXME remove me?
-  void clear() { trimToLabels(0); } // FIXME remove me?
+  bool empty() const { return d_empty; }
+  bool isRoot() const { return !d_empty && d_storage.empty(); }
+  void clear() { d_storage.clear(); d_empty=true; }
   void trimToLabels(unsigned int);
   DNSName& operator+=(const DNSName& rhs)
   {
@@ -53,6 +57,7 @@ public:
       throw std::range_error("name too long");
 
     d_storage+=rhs.d_storage;
+    d_empty&=rhs.d_empty;
     return *this;
   }
 
@@ -71,11 +76,13 @@ public:
   void serialize(Archive &ar, const unsigned int version)
   {
     ar & d_storage;
+    ar & d_empty;
   }
 private:
   //  typedef __gnu_cxx::__sso_string string_t;
   typedef std::string string_t;
   string_t d_storage;
+  bool d_empty;
   int d_recurse;
 
   void packetParser(const char* p, int len, int offset, bool uncompress, uint16_t* qtype=0, uint16_t* qclass=0, unsigned int* consumed=0);
index a8f016ccd9420a8351eec3ebf0dc61f171cb38a7..6e673a9ab4ad3d9b3bb5a17bc1a0ade83ee602bc 100644 (file)
@@ -52,6 +52,7 @@
 #include <boost/algorithm/string.hpp>
 #include "iputils.hh"
 
+
 bool g_singleThreaded;
 
 int writen2(int fd, const void *buf, size_t count)
@@ -222,12 +223,6 @@ bool endsOn(const string &domain, const string &suffix)
   return true;
 }
 
-// REMOVE ME
-bool dottedEndsOn(const DNSName &domain, const DNSName &suffix)
-{
-  return domain.isPartOf(suffix);
-}
-
 /** does domain end on suffix? Is smart about "wwwds9a.nl" "ds9a.nl" not matching */
 bool dottedEndsOn(const string &domain, const string &suffix) 
 {
index 6177e8007a7d83ce9e889d76c463c5503ca960f7..556c81c73cbe0ea7a3de7e7e7916899ea5daa233 100644 (file)
@@ -122,7 +122,7 @@ private:
   };
 
   vector<MapCombo> d_maps;
-  MapCombo& getMap(const DNSName& qname) 
+  MapCombo& getMap(const DNSName& qname)
   {
     return d_maps[burtle((const unsigned char*)qname.toString().c_str(), qname.toString().length(), 0) % d_maps.size()];
   }
index 8ca5b5d98decb22d76b003d939387daa90999a82..325cf68bf98c3da249b3a1186620c9a0a6873937 100644 (file)
@@ -263,7 +263,7 @@ vector<DNSResourceRecord> PacketHandler::getBestDNAMESynth(DNSPacket *p, SOAData
       ret.push_back(rr);  // put in the original
       rr.qtype = QType::CNAME;
       rr.qname = prefix + rr.qname;
-      rr.content = (prefix + rr.content).toString();
+      rr.content = (prefix + rr.content).toStringNoDot();
       rr.auth = 0; // don't sign CNAME
       target= rr.content;
       ret.push_back(rr); 
index 1c58066316a3c25961fd433ad767a76c8b05d30d..1607f630897c8268e6c7b33d11fc781d5aa55ddb 100644 (file)
@@ -40,15 +40,21 @@ BOOST_AUTO_TEST_CASE(test_basic) {
   BOOST_CHECK(DNSName("www.ds9a.nl.").toString() == "www.ds9a.nl.");
 
 
+  { // Check root vs empty
+    DNSName name("."); // root
+    DNSName parent; // empty
+    BOOST_CHECK(name != parent);
+  }
+
   { // Check root part of root
     DNSName name;
     DNSName parent;
-    BOOST_CHECK(name.isPartOf(parent));
+    BOOST_CHECK(!name.isPartOf(parent));
   }
 
   { // Check name part of root
     DNSName name("a.");
-    DNSName parent;
+    DNSName parent(".");
     BOOST_CHECK(name.isPartOf(parent));
   }
 
@@ -82,6 +88,26 @@ BOOST_AUTO_TEST_CASE(test_basic) {
     BOOST_CHECK(!name.isPartOf(parent));
   }
 
+  { // Make relative
+    DNSName name("aaaa.bbb.cc.d.");
+    DNSName parent("cc.d.");
+    BOOST_CHECK( name.makeRelative(parent) == DNSName("aaaa.bbb."));
+  }
+
+  { // Labelreverse
+    DNSName name("aaaa.bbb.cc.d.");
+    BOOST_CHECK( name.labelReverse() == DNSName("d.cc.bbb.aaaa."));
+  }
+
+  { // empty() empty
+    DNSName name;
+    BOOST_CHECK(name.empty());
+  }
+  
+  { // empty() root
+    DNSName name(".");
+    BOOST_CHECK(!name.empty());
+  }
 
   DNSName left("ds9a.nl.");
   left.prependRawLabel("www");
@@ -92,7 +118,7 @@ BOOST_AUTO_TEST_CASE(test_basic) {
   BOOST_CHECK( left == DNSName("WwW.Ds9A.Nl.com."));
   
   DNSName root;
-  BOOST_CHECK(root.toString() == ".");
+  BOOST_CHECK(root.toString() != ".");
 
   root.appendRawLabel("www");
   root.appendRawLabel("powerdns.com");
@@ -123,7 +149,7 @@ BOOST_AUTO_TEST_CASE(test_basic) {
 
   BOOST_CHECK_EQUAL(n.toString(), "powerdns\\.dnsmaster.powerdns.com.");
 
-  BOOST_CHECK_EQUAL(DNSName().toString(), ".");
+  BOOST_CHECK(DNSName().toString() != ".");
 
   DNSName p;
   string label("power");
index 34de26b2d8a8c5daddd872e9d36c8b64a548d5d4..cd801c83cd0b0a8c057659992a566d4cb256042b 100644 (file)
@@ -13,6 +13,7 @@
 #include "dns.hh"
 #include "zoneparser-tng.hh"
 #include "dnsrecords.hh"
+#include "dnsname.hh"
 #include <fstream>
 #include <cstdlib>