File pdns-recursor-3.1.7.2.patch of Package pdns-recursor

--- pdns-recursor-3.1.7/dnsparser.cc
+++ pdns-recursor-3.1.7/dnsparser.cc
@@ -75,20 +75,38 @@
   vector<uint8_t> d_record;
 };
 
-static const string EncodeDNSLabel(const string& input)  
+static const string EncodeDNSLabel(const string& input) 
 {  
-  typedef vector<string> parts_t;  
-  parts_t parts;  
-  stringtok(parts,input,".");   	  	 
-  string ret;  
-  for(parts_t::const_iterator i=parts.begin(); i!=parts.end(); ++i) {  
-    ret.append(1,(char)i->length());  
-    ret.append(*i);  
-  }  
-  ret.append(1,(char)0);  
-  return ret;  
+  if(input.length() == 1 && input[0]=='.') // otherwise we encode .. (long story)
+    return string (1, 0); 
+    
+  labelparts_t parts;
+  bool unescapedSomething = labeltokUnescape(parts, input);
+  string ret;
+  
+  if(!unescapedSomething) {
+    for(labelparts_t::const_iterator i=parts.begin(); i!=parts.end(); ++i) {
+      ret.append(1, i->second - i->first);
+      ret.append(input.c_str() + i->first, i->second - i->first);
+    }
+
+  } else {
+    for(labelparts_t::const_iterator i=parts.begin(); i!=parts.end(); ++i) {
+      string part(input.c_str() + i->first, i->second - i->first);
+      boost::replace_all(part, "\\\\", "\\"); 
+      boost::replace_all(part, "\\.", ".");   
+    
+      ret.append(1, part.length());
+      ret.append(part);
+    }  
+  }    
+  ret.append(1, 0);
+  // cerr<<"Asked to encode '"<<input<<"', returning: '"<<makeHexDump(ret)<<endl;
+  // cerr<<"parts length: "<<parts.size()<<endl;
+  return ret;
 }  
 
+
 shared_ptr<DNSRecordContent> DNSRecordContent::unserialize(const string& qname, uint16_t qtype, const string& serialized)
 {
   dnsheader dnsheader;
@@ -437,7 +455,7 @@
       // XXX FIXME THIS MIGHT BE VERY SLOW!
       ret.reserve(ret.size() + labellen + 2);
       for(string::size_type n = 0 ; n < labellen; ++n, frompos++) {
-	if(content.at(frompos)=='.')
+	if(content.at(frompos)=='.' || content.at(frompos)=='\\')
 	  ret.append(1, '\\');
 	ret.append(1, content[frompos]);
       }
--- pdns-recursor-3.1.7/dnsparser.hh
+++ pdns-recursor-3.1.7/dnsparser.hh
@@ -194,7 +194,7 @@
   static uint16_t TypeToNumber(const string& name)
   {
     for(namemap_t::const_iterator i=getNamemap().begin(); i!=getNamemap().end();++i)
-      if(!Utility::strcasecmp(i->second.c_str(), name.c_str()))
+      if(pdns_iequals(i->second,name))
 	return i->first.second;
 
     throw runtime_error("Unknown DNS type '"+name+"'");
--- pdns-recursor-3.1.7/dnswriter.cc
+++ pdns-recursor-3.1.7/dnswriter.cc
@@ -67,7 +67,7 @@
   d_stuff = 0; 
   d_rollbackmarker=d_content.size();
 
-  if(iequals(d_qname,d_recordqname)) {  // don't do the whole label compression thing if we *know* we can get away with "see question"
+  if(pdns_iequals(d_qname,d_recordqname)) {  // don't do the whole label compression thing if we *know* we can get away with "see question"
     static char marker[2]={0xc0, 0x0c};
     d_content.insert(d_content.end(), &marker[0], &marker[2]);
   }
@@ -153,14 +153,12 @@
 {
   DNSPacketWriter::lmap_t::iterator ret;
   for(ret=lmap.begin(); ret != lmap.end(); ++ret)
-    if(iequals(ret->first,label))
+    if(pdns_iequals(ret->first,label))
       break;
   return ret;
 }
 
-typedef vector<pair<string::size_type, string::size_type> > parts_t;
-
-bool labeltokUnescape(parts_t& parts, const string& label)
+bool labeltokUnescape(labelparts_t& parts, const string& label)
 {
   string::size_type epos = label.size(), lpos(0), pos;
   bool unescapedSomething = false;
@@ -188,7 +186,7 @@
 // this is the absolute hottest function in the pdns recursor 
 void DNSPacketWriter::xfrLabel(const string& label, bool compress)
 {
-  parts_t parts;
+  labelparts_t parts;
 
   if(label.size()==1 && label[0]=='.') { // otherwise we encode '..'
     d_record.push_back(0);
@@ -200,7 +198,7 @@
   // d_stuff is amount of stuff that is yet to be written out - the dnsrecordheader for example
   unsigned int pos=d_content.size() + d_record.size() + d_stuff; 
   string chopped;
-  for(parts_t::const_iterator i=parts.begin(); i!=parts.end(); ++i) {
+  for(labelparts_t::const_iterator i=parts.begin(); i!=parts.end(); ++i) {
     chopped.assign(label.c_str() + i->first);
     lmap_t::iterator li=d_labelmap.end();
     // see if we've written out this domain before
@@ -218,6 +216,10 @@
     if(unescaped) {
       string part(label.c_str() + i -> first, i->second - i->first);
       replace_all(part, "\\.", ".");
+      replace_all(part, "\\\\", "\\");      
+      if(part.size() > 255)
+        throw MOADNSException("Attempting to express a label of invalid size in xfrLabel");
+        
       d_record.push_back(part.size());
       unsigned int len=d_record.size();
       d_record.resize(len + part.size());
--- pdns-recursor-3.1.7/dnswriter.hh
+++ pdns-recursor-3.1.7/dnswriter.hh
@@ -107,4 +107,8 @@
   uint16_t d_rollbackmarker; // start of last complete packet, for rollback
   Place d_recordplace;
 };
+
+typedef vector<pair<std::string::size_type, std::string::size_type> > labelparts_t;
+
+bool labeltokUnescape(labelparts_t& parts, const std::string& label);
 #endif
--- pdns-recursor-3.1.7/lwres.cc
+++ pdns-recursor-3.1.7/lwres.cc
@@ -155,7 +155,7 @@
     lwr->d_tcbit=mdp.d_header.tc;
     lwr->d_rcode=mdp.d_header.rcode;
     
-    if(Utility::strcasecmp(domain.c_str(), mdp.d_qname.c_str())) { 
+    if(!pdns_iequals(domain,mdp.d_qname)) { 
       if(domain.find((char)0)==string::npos) {// embedded nulls are too noisy
 	L<<Logger::Notice<<"Packet purporting to come from remote server "<<ip.toString()<<" contained wrong answer: '" << domain << "' != '" << mdp.d_qname << "'" << endl;
 	g_stats.unexpectedCount++;
--- pdns-recursor-3.1.7/misc.hh
+++ pdns-recursor-3.1.7/misc.hh
@@ -318,54 +318,45 @@
 {
   return tv.tv_sec + tv.tv_usec/1000000.0f;
 }
-struct CIStringCompare: public binary_function<string, string, bool>  
+
+inline bool pdns_ilexicographical_compare(const std::string& a, const std::string& b)  __attribute__((pure));
+inline bool pdns_ilexicographical_compare(const std::string& a, const std::string& b) 
 {
-  bool operator()(const string& a, const string& b) const
-  {
-    const unsigned char *p1 = (const unsigned char *) a.c_str();
-    const unsigned char *p2 = (const unsigned char *) b.c_str();
-    int result;
-    
-    if (p1 == p2)
-      return 0;
-    
-    while ((result = dns_tolower (*p1) - dns_tolower (*p2++)) == 0)
-      if (*p1++ == '\0')
-	break;
-    
-    return result < 0;
+  string::size_type aLen = a.length(), bLen = b.length(), n;
+  const char *aPtr = a.c_str(), *bPtr = b.c_str();
+  int result;
+  
+  for(n = 0 ; n < aLen && n < bLen ; ++n) {
+      if((result = dns_tolower(*aPtr++) - dns_tolower(*bPtr++))) {
+        return result < 0;
+      }
   }
+  if(n == aLen && n == bLen) // strings are equal (in length)
+    return 0; 
+  if(n == aLen) // first string was shorter
+    return true; 
+  return false;
+}
 
-  bool operator()(const string& a, const char* b) const
-  {
-    const unsigned char *p1 = (const unsigned char *) a.c_str();
-    const unsigned char *p2 = (const unsigned char *) b;
-    int result;
-    
-    if (p1 == p2)
-      return 0;
-    
-    while ((result = dns_tolower (*p1) - dns_tolower (*p2++)) == 0)
-      if (*p1++ == '\0')
-	break;
-    
-    return result < 0;
+inline bool pdns_iequals(const std::string& a, const std::string& b) __attribute__((pure));
+
+inline bool pdns_iequals(const std::string& a, const std::string& b) 
+{
+  string::size_type aLen = a.length(), bLen = b.length(), n;
+  const char *aPtr = a.c_str(), *bPtr = b.c_str();
+  
+  for(n = 0 ; n < aLen && n < bLen ; ++n) {
+      if(dns_tolower(*aPtr++) != dns_tolower(*bPtr++))
+        return false;
   }
+  return aLen == bLen; // strings are equal (in length)
+}
 
-  bool operator()(const char* a, const string& b) const
+struct CIStringCompare: public binary_function<string, string, bool>  
+{
+  bool operator()(const string& a, const string& b) const
   {
-    const unsigned char *p1 = (const unsigned char *) a;
-    const unsigned char *p2 = (const unsigned char *) b.c_str();
-    int result;
-    
-    if (p1 == p2)
-      return 0;
-    
-    while ((result = dns_tolower (*p1) - dns_tolower (*p2++)) == 0)
-      if (*p1++ == '\0')
-	break;
-    
-    return result < 0;
+    return pdns_ilexicographical_compare(a, b);
   }
 };
 
--- pdns-recursor-3.1.7/pdns_recursor.cc
+++ pdns-recursor-3.1.7/pdns_recursor.cc
@@ -806,43 +806,54 @@
   }
 }
  
-void questionExpand(const char* packet, uint16_t len, char* qname, int maxlen, uint16_t& type)
+
+static void appendEscapedLabel(string& ret, const char* begin, unsigned char labellen)
+{
+  unsigned char n = 0;
+  for(n = 0 ; n < labellen; ++n)
+    if(begin[n] == '.' || begin[n] == '\\')
+      break;
+  
+  if( n == labellen) {
+    ret.append(begin, labellen);
+    return;
+  }
+  string label(begin, labellen);
+  boost::replace_all(label, "\\",  "\\\\");
+  boost::replace_all(label, ".",  "\\.");
+  ret.append(label);
+}
+
+string questionExpand(const char* packet, uint16_t len, uint16_t& type)
 {
   type=0;
-  const unsigned char* end=(const unsigned char*)packet+len;
-  unsigned char* lbegin=(unsigned char*)packet+12;
-  unsigned char* pos=lbegin;
+  string ret;
+  if(len < 12) 
+    throw runtime_error("Error parsing question in incoming packet: packet too short");
+    
+  const unsigned char* end = (const unsigned char*)packet+len;
+  const unsigned char* pos = (const unsigned char*)packet+12;
   unsigned char labellen;
-
-  // 3www4ds9a2nl0
-  char *dst=qname;
-  char* lend=dst + maxlen;
   
   if(!*pos)
-    *dst++='.';
-
+    ret.assign(1, '.');
+  
   while((labellen=*pos++) && pos < end) { // "scan and copy"
-    if(dst >= lend)
-      throw runtime_error("Label length exceeded destination length");
-    for(;labellen;--labellen)
-      *dst++ = *pos++;
-    *dst++='.';
+    if(pos + labellen > end)
+      throw runtime_error("Error parsing question in incoming packet: label extends beyond packet");
+    
+    appendEscapedLabel(ret, (const char*) pos, labellen);
+    
+    ret.append(1, '.');
+    pos += labellen;
   }
-  *dst=0;
 
-  if(pos + labellen + 2 <= end)  // is this correct XXX FIXME?
+  if(pos + labellen + 2 <= end)  
     type=(*pos)*256 + *(pos+1);
-
-
-  //  cerr<<"Returning: '"<< string(tmp+1, pos) <<"'\n";
+  // cerr << "returning: '"<<ret<<"'"<<endl;
+  return ret;
 }
 
-string questionExpand(const char* packet, uint16_t len, uint16_t& type)
-{
-  char tmp[512];
-  questionExpand(packet, len, tmp, sizeof(tmp), type);
-  return tmp;
-}
 
 void handleNewUDPQuestion(int fd, FDMultiplexer::funcparam_t& var)
 {
@@ -874,59 +885,6 @@
       }
       else {
 	++g_stats.qcounter;
-#if 0
-	uint16_t type;
-	char qname[256];
-        try {
-	   questionExpand(data, len, qname, sizeof(qname), type);  
-        }
-        catch(exception &e)
-        {
-           throw MOADNSException(e.what());
-        }
-	
-	// must all be same length answers right now!
-	if((type==QType::A || type==QType::AAAA) && dh->arcount==0 && dh->ancount==0 && dh->nscount ==0 && ntohs(dh->qdcount)==1 ) {
-	  char *record[10];
-	  uint16_t rlen[10];
-	  uint32_t ttd[10];
-	  int count;
-	  if((count=RC.getDirect(g_now.tv_sec, qname, QType(type), ttd, record, rlen))) { 
-	    if(len + count*(sizeof(dnsrecordheader) + 2 + rlen[0]) > 512)
-	      goto slow;
-
-	    random_shuffle(record, &record[count]);
-	    dh->qr=1;
-	    dh->ra=1;
-	    dh->ancount=ntohs(count);
-	    for(int n=0; n < count ; ++n) {
-	      memcpy(data+len, "\xc0\x0c", 2); // answer label pointer
-	      len+=2;
-	      struct dnsrecordheader drh;
-	      drh.d_type=htons(type);
-	      drh.d_class=htons(1);
-	      drh.d_ttl=htonl(ttd[n] - g_now.tv_sec);
-	      drh.d_clen=htons(rlen[n]);
-	      memcpy(data+len, &drh, sizeof(drh));
-	      len+=sizeof(drh);
-	      memcpy(data+len, record[n], rlen[n]);
-	      len+=rlen[n];
-	    }
-	    RDTSC(tsc2);      	    
-	    g_stats.shunted++;
-	    sendto(fd, data, len, 0, (struct sockaddr *)(&fromaddr), fromaddr.getSocklen());
-//	    cerr<<"shunted: " << (tsc2-tsc1) / 3000.0 << endl;
-	    return;
-	  }
-	}
-	else {
-	  if(type!=QType::A && type!=QType::AAAA)
-    	    g_stats.noShuntWrongType++;
-          else
-            g_stats.noShuntWrongQuestion++;
-        }
-      slow:
-#endif
 	DNSComboWriter* dc = new DNSComboWriter(data, len, g_now);
 	dc->setSocket(fd);
 	dc->setRemote(&fromaddr);
@@ -1304,7 +1262,13 @@
     pident.remote=fromaddr;
     pident.id=dh.id;
     pident.fd=fd;
-    pident.domain=questionExpand(data, len, pident.type); // don't copy this from above - we need to do the actual read
+    try {
+      pident.domain=questionExpand(data, len, pident.type); // don't copy this from above - we need to do the actual read
+    }
+    catch(...) {
+      return;
+    }
+    
     string packet;
     packet.assign(data, len);
 
@@ -1322,7 +1286,7 @@
       
       for(MT_t::waiters_t::iterator mthread=MT->d_waiters.begin(); mthread!=MT->d_waiters.end(); ++mthread) {
 	if(pident.fd==mthread->key.fd && mthread->key.remote==pident.remote &&  mthread->key.type == pident.type &&
-	   !Utility::strcasecmp(pident.domain.c_str(), mthread->key.domain.c_str())) {
+	   pdns_iequals(pident.domain,mthread->key.domain)) {
 	  mthread->key.nearMisses++;
 	}
       }
--- pdns-recursor-3.1.7/rec_channel_rec.cc
+++ pdns-recursor-3.1.7/rec_channel_rec.cc
@@ -294,6 +294,7 @@
     return "bye\n";
   }
 
+
   if(cmd=="dump-cache") 
     return doDumpCache(begin, end);
 
--- pdns-recursor-3.1.7/recursor_cache.cc
+++ pdns-recursor-3.1.7/recursor_cache.cc
@@ -121,74 +121,13 @@
   return ret;
 }
 
-int MemRecursorCache::getDirect(time_t now, const char* qname, const QType& qt, uint32_t ttd[10], char* data[10], uint16_t len[10])
-{
-  if(!d_cachecachevalid || Utility::strcasecmp(d_cachedqname.c_str(), qname)) {
-//    cerr<<"had cache cache miss for '"<<qname<<"'"<<endl;
-    d_cachedqname=qname;
-    d_cachecache=d_cache.equal_range(tie(qname));
-    d_cachecachevalid=true;
-  }
-  else
-    ;
-  //    cerr<<"had cache cache hit!"<<endl;
-
-  if(d_cachecache.first == d_cachecache.second) {
-    g_stats.noShuntNoMatch++;
-    return false;
-  }
-
-  pair<cache_t::iterator, cache_t::iterator> range = d_cachecache;
-  
-  unsigned int n=0;
-  for(;range.first != range.second; ++range.first) {
-    if(range.first->d_qtype == QType::CNAME) { // if we see a cname, we need the whole shebang (for now)
-      g_stats.noShuntCNAME++;
-      return false;
-    }
-    if(range.first->d_qtype != qt.getCode())
-      continue;
-    if(range.first->getTTD() < (unsigned int) now) {
-      g_stats.noShuntExpired++;
-      return false;
-    }
-    
-    if(range.first->d_records.empty() || range.first->d_records.size() > 9 ) {
-      g_stats.noShuntSize++;
-      return false;
-    }
-    
-    size_t limit=range.first->d_records.size();
-    n=0;
-    for(; n < limit; ++n) {
-      data[n]=(char*)range.first->d_records[n].d_string.c_str();
-      len[n]=range.first->d_records[n].d_string.length();
-      ttd[n]=range.first->d_records[n].d_ttd;
-    }
-    if(n<10) {
-      data[n]=0;
-      typedef cache_t::nth_index<1>::type sequence_t;
-      sequence_t& sidx=d_cache.get<1>();
-      sequence_t::iterator si=d_cache.project<1>(range.first);
-      sidx.relocate(sidx.end(), si); // move it in the LRU list 
-      // can't yet return, need to figure out if there isn't a CNAME that messes things up
-    }
-    else
-      return false;
-  }
-  if(!n)
-    g_stats.noShuntNoMatch++;
-  return n;
-
-}
-
 int MemRecursorCache::get(time_t now, const string &qname, const QType& qt, set<DNSResourceRecord>* res)
 {
   unsigned int ttd=0;
 
   //  cerr<<"looking up "<< qname+"|"+qt.getName()<<"\n";
 
-  if(!d_cachecachevalid || Utility::strcasecmp(d_cachedqname.c_str(), qname.c_str())) {
+  if(!d_cachecachevalid || !pdns_iequals(d_cachedqname,qname)) {
     //    cerr<<"had cache cache miss"<<endl;
     d_cachedqname=qname;
     d_cachecache=d_cache.equal_range(tie(qname));
--- pdns-recursor-3.1.7/syncres.cc
+++ pdns-recursor-3.1.7/syncres.cc
@@ -62,8 +62,8 @@
 int SyncRes::beginResolve(const string &qname, const QType &qtype, uint16_t qclass, vector<DNSResourceRecord>&ret)
 {
   s_queries++;
-  if( (qtype.getCode()==QType::PTR && !Utility::strcasecmp(qname.c_str(), "1.0.0.127.in-addr.arpa.")) ||
-      (qtype.getCode()==QType::A && qname.length()==10 && !Utility::strcasecmp(qname.c_str(), "localhost."))) {
+  if( (qtype.getCode()==QType::PTR && pdns_iequals(qname, "1.0.0.127.in-addr.arpa.")) ||
+      (qtype.getCode()==QType::A && qname.length()==10 && pdns_iequals(qname, "localhost."))) {
     ret.clear();
     DNSResourceRecord rr;
     rr.qname=qname;
@@ -79,7 +79,7 @@
   }
 
   if(qclass==3 && qtype.getCode()==QType::TXT && 
-        (!Utility::strcasecmp(qname.c_str(), "version.bind.") || !Utility::strcasecmp(qname.c_str(), "id.server.") || !Utility::strcasecmp(qname.c_str(), "version.pdns.") ) 
+        (pdns_iequals(qname, "version.bind.") || pdns_iequals(qname, "id.server.") || pdns_iequals(qname, "version.pdns.") ) 
      ) {
     ret.clear();
     DNSResourceRecord rr;
@@ -87,7 +87,7 @@
     rr.qtype=qtype;
     rr.qclass=qclass;
     rr.ttl=86400;
-    if(!Utility::strcasecmp(qname.c_str(),"version.bind.")  || !Utility::strcasecmp(qname.c_str(),"version.pdns."))
+    if(pdns_iequals(qname, "version.bind.")  || pdns_iequals(qname, "version.pdns."))
       rr.content="\""+::arg()["version-string"]+"\"";
     else
       rr.content="\""+s_serverID+"\"";
@@ -571,10 +571,9 @@
 {
   bool operator()(const pair<string, QType>& a, const pair<string, QType>& b) const
   {
-    int cmp=Utility::strcasecmp(a.first.c_str(), b.first.c_str());
-    if(cmp < 0)
+    if(pdns_ilexicographical_compare(a.first, b.first))
       return true;
-    if(cmp > 0)
+    if(pdns_ilexicographical_compare(b.first, a.first))
       return false;
 
     return a.second < b.second;
@@ -829,7 +828,7 @@
 	  newtarget=i->content;
 	}
 	// for ANY answers we *must* have an authoritive answer
-	else if(i->d_place==DNSResourceRecord::ANSWER && !Utility::strcasecmp(i->qname.c_str(),qname.c_str()) && 
+	else if(i->d_place==DNSResourceRecord::ANSWER && pdns_iequals(i->qname,qname) && 
 		(
 		 i->qtype==qtype || (lwr.d_aabit && (qtype==QType(QType::ANY) || magicAddrMatch(qtype, i->qtype) ) )
 		) 
--- pdns-recursor-3.1.7/syncres.hh
+++ pdns-recursor-3.1.7/syncres.hh
@@ -434,12 +434,11 @@
     if( tie(remote, ourSock, type) > tie(b.remote, bSock, b.type))
       return false;
 
-    int cmp=Utility::strcasecmp(domain.c_str(), b.domain.c_str());
-    if(cmp < 0)
+    if(pdns_ilexicographical_compare(domain,b.domain))
       return true;
-    if(cmp > 0)
-      return false;
 
+    if(pdns_ilexicographical_compare(b.domain,domain))
+      return false;
     return tie(fd, id) < tie(b.fd, b.id);
   }
 };
@@ -455,8 +454,7 @@
     if( tie(a.remote, ourSock, a.type) > tie(b.remote, bSock, b.type))
       return false;
 
-    int cmp=Utility::strcasecmp(a.domain.c_str(), b.domain.c_str());
-    return cmp < 0;
+    return pdns_ilexicographical_compare(a.domain,b.domain);
   }
 };
 extern MemRecursorCache RC;
--- pdns-recursor-3.1.7/unix_utility.cc
+++ pdns-recursor-3.1.7/unix_utility.cc
@@ -174,13 +174,6 @@
   ::srandom(seed);
 }
 
-// Compares two string, ignoring the case.
-int Utility::strcasecmp( const char *s1, const char *s2 )
-{
-  return ::strcasecmp( s1, s2 );
-}
-
-
 // Writes a vector.
 int Utility::writev(int socket, const iovec *vector, size_t count )
 {
--- pdns-recursor-3.1.7/utility.hh
+++ pdns-recursor-3.1.7/utility.hh
@@ -187,9 +187,6 @@
   //! Sets the random seed.
   static void srandom( unsigned int seed );
 
-  //! Compares two strings and ignores case.
-  static int strcasecmp( const char *s1, const char *s2 );
-
   //! Drops the program's privileges.
   static void dropPrivs( int uid, int gid );
   
--- pdns-recursor-3.1.7/win32_utility.cc
+++ pdns-recursor-3.1.7/win32_utility.cc
@@ -379,14 +379,6 @@
   srand( seed );
 }
 
-
-// Compares two string, ignoring the case.
-int Utility::strcasecmp( const char *s1, const char *s2 )
-{
-  return strcmp( s1, s2 );
-}
-
-
 // Sleeps for a number of microseconds.
 void Utility::usleep( unsigned long usec )
 {
--- pdns-recursor-3.1.7/zoneparser-tng.cc
+++ pdns-recursor-3.1.7/zoneparser-tng.cc
@@ -303,7 +303,7 @@
 
     // cout<<"Next part: '"<<nextpart<<"'"<<endl;
     
-    if(!Utility::strcasecmp(nextpart.c_str(), "IN")) {
+    if(pdns_iequals(nextpart, "IN")) {
       // cout<<"Ignoring 'IN'\n";
       continue;
     }
openSUSE Build Service is sponsored by