From d3491d5a32e5f7818b3ef51fd3aeb57396076b9f Mon Sep 17 00:00:00 2001 From: Bert Hubert Date: Tue, 21 Jan 2003 15:04:02 +0000 Subject: [PATCH] lots git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@139 d19b8d6e-7fed-0310-83ef-9ca221ded41b --- ChangeLog | 2 + pdns/dnspacket.cc | 114 +++++++++++++++++++++++++++++++++++++++---- pdns/dnspacket.hh | 5 +- pdns/docs/pdns.sgml | 26 +++++++++- pdns/mtasker.cc | 4 ++ pdns/qtype.hh | 4 +- pdns/resolver.cc | 1 + pdns/sillyrecords.cc | 1 - 8 files changed, 142 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index fa7a76807..e5c2537f0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,8 @@ Changes since 2.9.4: - added names for SIG and KEY records - HINFO incoming - UltraSparc alignment issues Chris Andrews + - compression (Mark Bergsma) + - SRV records (Ueli Heuer) Changes since 2.9.3a: feat - make *all* sql in gsqlbackends available for configuration (Martin Klebermass/bert hubert) diff --git a/pdns/dnspacket.cc b/pdns/dnspacket.cc index b9b7d4a4a..9394d4f2b 100644 --- a/pdns/dnspacket.cc +++ b/pdns/dnspacket.cc @@ -16,7 +16,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -// $Id: dnspacket.cc,v 1.14 2003/01/21 10:42:34 ahu Exp $ +// $Id: dnspacket.cc,v 1.15 2003/01/21 15:04:02 ahu Exp $ #include "utility.hh" #include @@ -333,6 +333,73 @@ void DNSPacket::addMXRecord(const string &domain, const string &mx, int priority d.ancount++; } + +void DNSPacket::addSRVRecord(const DNSResourceRecord &rr) +{ + addSRVRecord(rr.qname, rr.content, rr.priority, rr.ttl); +} + +void DNSPacket::addSRVRecord(const string &domain, const string &srv, int priority, u_int32_t ttl) +{ + string piece1; + toqname(domain,&piece1); + + string target; + int weight=0; + int port=0; + + vectorparts; + stringtok(parts,srv); + int pleft=parts.size(); + + // We need to have exactly 3 parts, so we have to check it! + if (pleft<2) { + throw AhuException("Missing data for type SRV "+domain); + } + + if(pleft) + weight = atoi(parts[0].c_str()); + + if(pleft>1) + port = atoi(parts[1].c_str()); + + if(pleft>2) + toqname(parts[2],&target); + + + + char p[16]; + makeHeader(p,QType::SRV,ttl); + + p[8]=0; + p[9]=0; // need to fill this in + + // start of payload for which we need to specify the length in 8 & 9 + + // priority aka preference + p[10]=(priority>>8)&0xff; + p[11]=priority&0xff; + + // weight + p[12]=(weight>>8)&0xff; + p[13]=weight&0xff; + + // port + p[14]=(port>>8)&0xff; + p[15]=port&0xff; + + // target + // end of payload + + p[9]=target.length()+6; // fill in length + + stringbuffer+=piece1; + stringbuffer.append(p,16); + stringbuffer+=target; + + d.ancount++; +} + string &DNSPacket::attodot(string &str) { if(str.find_first_of("@")==string::npos) @@ -986,6 +1053,10 @@ void DNSPacket::wrapup(void) addAAAARecord(rr); break; + case QType::SRV: + addSRVRecord(rr); + break; + case QType::LOC: addLOCRecord(rr); break; @@ -1167,6 +1238,8 @@ vector DNSPacket::getAnswers() ostringstream o; int ip; + int weight; + int port; switch(rr.qtype.getCode()) { @@ -1220,6 +1293,18 @@ vector DNSPacket::getAnswers() break; + case QType::SRV: // rfc 2025 + // priority goes into mx-priority + rr.priority=(datapos[0] << 8) + datapos[1]; + // rest glue together + weight = (datapos[2] << 8) + datapos[3]; + port = (datapos[4] << 8) + datapos[5]; + expand(datapos+offset+6,end,part); + rr.content.assign(itoa(weight)); + rr.content+=" "+itoa(port)+" "+part; + break; + + case QType::RP: offset+=expand(datapos+offset,end,rr.content); expand(datapos+offset,end,part); @@ -1307,7 +1392,7 @@ int DNSPacket::findlabel(string &label) break; } else { - if (strcmp(p, label.data()) == 0) + if (strncmp(p, label.data(), label.size()) == 0) return (p - data); p += (*p + 1); } @@ -1332,7 +1417,7 @@ int DNSPacket::findlabel(string &label) } else { - if (strcmp(p, label.data()) == 0) + if (strncmp(p, label.data(), label.size()) == 0) { return (p - data); } @@ -1371,7 +1456,7 @@ int DNSPacket::findlabel(string &label) } else { - if (strcmp(p, label.data()) == 0) { + if (strncmp(p, label.data(), label.size()) == 0) { return (p - data); } @@ -1402,11 +1487,17 @@ int DNSPacket::toqname(const char *name, string &qname, bool comp) // org int i = 0; + bool containsptr=false; - while (qname[i] != 0x00) { + while (qname[i] != 0x00 && /* qname[i] == 0x00 => i == qname.length */ + (qname[i] & 0xC0) != 0xC0) { // no use to try to compress offsets // Get a portion of the name - string s = qname.substr(i); + // qname must include an extra trailing '\0' if it's prefix + // is not an offset ptr + string s = qname.substr(i); /* s == qname[i..N) */ + if (!containsptr) s = s + '\0'; + // Did we see this before? int offset = findlabel(s); @@ -1415,11 +1506,16 @@ int DNSPacket::toqname(const char *name, string &qname, bool comp) qname[i + 0] = (char) (((offset | 0xC000) & 0x0000FF00) >> 8); qname[i + 1] = (char) ((offset | 0xC000) & 0x000000FF); qname = qname.substr(0, i + 2); // XX setlength() ? + containsptr=true; // qname now consists of unique prefix+known suffix (on location 'offset') - break; + // we managed to make qname shorter, maybe we can do that again + i = 0; + + } + else { /* offset == -1 */ + // Move to the next label + i += (qname[i] + 1); // doesn't quite handle very long labels } - // Move to the next label - i += (qname[i] + 1); } } diff --git a/pdns/dnspacket.hh b/pdns/dnspacket.hh index 7f608766e..9b75c258f 100644 --- a/pdns/dnspacket.hh +++ b/pdns/dnspacket.hh @@ -16,7 +16,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -// $Id: dnspacket.hh,v 1.13 2003/01/13 23:05:15 ahu Exp $ +// $Id: dnspacket.hh,v 1.14 2003/01/21 15:04:02 ahu Exp $ #ifndef DNSPACKET_HH #define DNSPACKET_HH @@ -145,6 +145,9 @@ private: void addMXRecord(const string &domain, const string &mx, int priority, u_int32_t ttl); //!< add an MX record to the packet void addMXRecord(const DNSResourceRecord &); //!< add an MX record to the packet + void addSRVRecord(const string &domain, const string &srv, int priority, u_int32_t ttl); //!< add an SRVMX record to the packet + void addSRVRecord(const DNSResourceRecord &); //!< add an SRV record to the packet + void addCNAMERecord(const string &domain, const string &alias, u_int32_t ttl); //!< add a CNAME record to the packet void addCNAMERecord(const DNSResourceRecord &); //!< add a CNAME record to the packet diff --git a/pdns/docs/pdns.sgml b/pdns/docs/pdns.sgml index 4c22615e4..41ceab548 100644 --- a/pdns/docs/pdns.sgml +++ b/pdns/docs/pdns.sgml @@ -11,7 +11,7 @@ - v2.1 $Date: 2003/01/21 10:42:34 $ + v2.1 $Date: 2003/01/21 15:04:02 $ @@ -98,7 +98,8 @@ The 'Contributor of the Month' award goes to Mark Bergsma who has responded to our plea for help with the label compressor and contributed - a wonderfully simple and right fix that allows PDNS to compress just as well as Other namerervers out there. + a wonderfully simple and right fix that allows PDNS to compress just as well as Other namerervers out there. An honorary mention goes to + Ueli Heuer who, despite having no C++ experience, submitted an excellent SRV record implementation. Other changes: @@ -140,6 +141,17 @@ Yet more UltraSPARC alignment issues fixed (Chris Andrews). + + + Label compression was improved so we can now fit all . records in 436 bytes, this used to be 460! (Code & formal + proof of correctness by Mark Bergsma). + + + + + SRV support (incoming and outgoing), submitted by Ueli Heuer. + + @@ -4762,6 +4774,16 @@ local0.err /var/log/pdns.err + + SRV + + + SRV records can be used to encode the location and port of services on a domain name. When encoding, the priority field + is used to encode the priority. For example, '_ldap._tcp.dc._msdcs.conaxis.ch SRV 0 100 389 mars.conaxis.ch' would be + encoded with 0 in the priorit field and '100 389 mars.conaxis.ch' in the tontent field. + + + TXT diff --git a/pdns/mtasker.cc b/pdns/mtasker.cc index 6b9d6aecd..0782526e5 100644 --- a/pdns/mtasker.cc +++ b/pdns/mtasker.cc @@ -41,6 +41,10 @@ MTasker is designed to offer the performance of statemachines while maintaining simple thread semantics. It is not a replacement for a full threading system. + \section compatability Compatability + MTasker is only guaranteed to work on Linux with glibc 2.2.5 and higher. It does not work on FreeBSD and notably, + not on Red Hat 6.0. It may work on Solaris, please test. + \section concepts Concepts There are two important concepts, the 'kernel' and the 'thread'. Each thread starts out as a function, diff --git a/pdns/qtype.hh b/pdns/qtype.hh index 3de281236..c46184faa 100644 --- a/pdns/qtype.hh +++ b/pdns/qtype.hh @@ -19,7 +19,7 @@ #ifndef QTYPE_HH #define QTYPE_HH /* (C) 2002 POWERDNS.COM BV */ -// $Id: qtype.hh,v 1.3 2003/01/21 10:42:34 ahu Exp $ +// $Id: qtype.hh,v 1.4 2003/01/21 15:04:02 ahu Exp $ #include #include #include @@ -59,7 +59,7 @@ public: static int chartocode(const char *p); //!< convert a character string to a code - enum {A=1,NS=2,CNAME=5,SOA=6,PTR=12,HINFO=13,MX=15,TXT=16,RP=17,AAAA=28,LOC=29,NAPTR=35,AXFR=252, ANY=255} types; + enum {A=1,NS=2,CNAME=5,SOA=6,PTR=12,HINFO=13,MX=15,TXT=16,RP=17,AAAA=28,LOC=29,SRV=33,NAPTR=35,AXFR=252, ANY=255} types; private: short int code; typedef pair namenum; diff --git a/pdns/resolver.cc b/pdns/resolver.cc index b3e5ea7a1..f513a9241 100644 --- a/pdns/resolver.cc +++ b/pdns/resolver.cc @@ -187,6 +187,7 @@ int Resolver::resolve(const string &ip, const char *domain, int type) timeout.tv_usec=500000; int res=select(d_sock+1,&rd,0,0,&timeout); + if(!res) throw ResolverException("Timeout waiting for answer from "+ip); if(res<0) diff --git a/pdns/sillyrecords.cc b/pdns/sillyrecords.cc index 3bba10f46..cdd3da7f6 100644 --- a/pdns/sillyrecords.cc +++ b/pdns/sillyrecords.cc @@ -239,7 +239,6 @@ latlon2ul(const char **latlonstrptr, int *which) void DNSPacket::addLOCRecord(const string &domain, const string & content, u_int32_t ttl) { const char *cp, *maxcp; - unsigned char *bcp; u_int32_t latit = 0, longit = 0, alt = 0; u_int32_t lltemp1 = 0, lltemp2 = 0; -- 2.50.0