[Pdns-dev] dnsparser.cc:simpleCompress()

Johan Ekenberg johan at ekenberg.se
Tue Jun 12 22:51:36 CEST 2012


Hello

I'm looking at pdns 3.1 and dnsparser.cc:simpleCompress().

If I'm not mistaken, the basic usage case of simpleCompress() should just 
return a record with dots removed, so that "foo.bar.com" becomes "foobarcom". 
(?)

However, depending on the length of the string, this doesn't always happen.

I made a basic test program which just calls simpleCompress() on its arguments 
and prints to stdout (see below for src).

Please look at these examples, is this the intended behaviour?
============================================
$ ./test_simple_compress foo.1234567.com
foo1234567com
# OK

$ ./test_simple_compress foo.12345678.com
fo12345678com
# ERROR: foo became fo

$ ./test_simple_compress foo.123456789.com
foo     123456789com
# ERROR: whitespace

$ ./test_simple_compress foo.1234567890.com
foo
1234567890com
# ERROR: newline

$ ./test_simple_compress foo.12345678901.com
foo
   12345678901com
# ERROR: newline + whitespace

$ ./test_simple_compress foo.123456789012.com
foo
   123456789012com
# ERROR: newline + whitespace

$ ./test_simple_compress foo.1234567890123.com
1234567890123com
# ERROR: foo is gone

$ ./test_simple_compress foo.12345678901234.com
foo12345678901234com
# OK
===============================================

Here's the source for test_simple_compress:
===============================================
#include "string"
#include <string.h>
#include "vector"
#include "iostream"
using namespace std;

// vstringtok from misc.hh                                                                                                                                                                                                                                     
template <typename Container>
void
vstringtok (Container &container, string const &in,
           const char * const delimiters = " \t\n")
{
  const string::size_type len = in.length();
  string::size_type i = 0;

  while (i<len) {
    // eat leading whitespace                                                                                                                                                                                                                                  
    i = in.find_first_not_of (delimiters, i);
    if (i == string::npos)
      return;   // nothing left but white space                                                                                                                                                                                                                

    // find the end of the token                                                                                                                                                                                                                               
    string::size_type j = in.find_first_of (delimiters, i);

    // push token                                                                                                                                                                                                                                              
    if (j == string::npos) {
      container.push_back (make_pair(i, len));
      return;
    } else
      container.push_back (make_pair(i, j));

    // set up for next loop                                                                                                                                                                                                                                    
    i = j + 1;
  }
}

string simpleCompress(const string& label, const string& root = ""){
  typedef vector<pair<unsigned int, unsigned int> > parts_t;
  parts_t parts;
  vstringtok(parts, label, ".");
  string ret;
  ret.reserve(label.size()+4);
  for(parts_t::const_iterator i=parts.begin(); i!=parts.end(); ++i) {
    if(!root.empty() && !strncasecmp(root.c_str(), label.c_str() + i->first, 1 
+ label.length() - i->first)) { // also match trailing 0, hence '1 +'                                                                                                           
      const char rootptr[2]={0xc0,0x11};
      ret.append(rootptr, 2);
      return ret;
    }
    ret.append(1, (char)(i->second - i->first));
    ret.append(label.c_str() + i->first, i->second - i->first);
  }
  ret.append(1, (char)0);
  return ret;
}

int main(int argc, char **argv) {
   if (argc > 1) {
      for (int i = 1; i < argc; i++) {
         std::cout << simpleCompress(argv[i]) << std::endl;
      }
   }
   return 0;
}

==================================================

Best regards,
/Johan Ekenberg


More information about the Pdns-dev mailing list