From: Bert Hubert Date: Sat, 31 Mar 2007 18:37:43 +0000 (+0000) Subject: re-add support for LOC records, plus finally a LOC regression test (which exposed... X-Git-Tag: pdns-2.9.21~34 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c6a60874da55b1a591878d0b1c6a5635fb1ba730;p=pdns re-add support for LOC records, plus finally a LOC regression test (which exposed a heap of errors in the old code!) git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@1011 d19b8d6e-7fed-0310-83ef-9ca221ded41b --- diff --git a/pdns/Makefile.am b/pdns/Makefile.am index 77277d454..ccf1ad408 100644 --- a/pdns/Makefile.am +++ b/pdns/Makefile.am @@ -36,7 +36,7 @@ backends/bind/bindbackend2.cc \ backends/bind/bindparser.cc backends/bind/bindlexer.c \ backends/bind/huffman.cc backends/gsql/gsqlbackend.cc \ backends/gsql/gsqlbackend.hh backends/gsql/ssql.hh \ -base64.cc \ +base64.cc sillyrecords.cc \ base64.hh zoneparser-tng.cc dnsrecords.cc dnswriter.cc \ rcpgenerator.cc dnsparser.cc @@ -46,7 +46,7 @@ pdns_server_INCLUDES= sdig_SOURCES=sdig.cc sstuff.hh dnsparser.cc dnsparser.hh dnsrecords.cc dnswriter.cc dnswriter.hh \ misc.cc misc.hh rcpgenerator.cc rcpgenerator.hh base64.cc base64.hh unix_utility.cc \ - logger.cc statbag.cc qtype.cc + logger.cc statbag.cc qtype.cc sillyrecords.cc dnspbench_SOURCES=dnspbench.cc sstuff.hh dnsparser.cc dnsparser.hh dnsrecords.cc dnswriter.cc dnswriter.hh \ misc.cc misc.hh rcpgenerator.cc rcpgenerator.hh base64.cc base64.hh unix_utility.cc logger.cc \ diff --git a/pdns/backends/bind/Makefile.am b/pdns/backends/bind/Makefile.am index 101b2c755..1dd00986d 100644 --- a/pdns/backends/bind/Makefile.am +++ b/pdns/backends/bind/Makefile.am @@ -14,16 +14,13 @@ bin_PROGRAMS = zone2sql zone2ldap zone2sql_SOURCES=bindparser.yy bindlexer.l \ ../../arguments.cc ../../logger.cc zone2sql.cc ../../statbag.cc ../../misc.cc \ ../../unix_utility.cc ../../qtype.cc ../../dnspacket.cc \ -../../zoneparser-tng.cc ../../dnsrecords.cc \ +../../zoneparser-tng.cc ../../dnsrecords.cc ../../sillyrecords.cc \ ../../dnswriter.cc ../../rcpgenerator.cc ../../dnsparser.cc ../../base64.cc - zone2ldap_SOURCES=bindparser.yy bindlexer.l \ ../../arguments.cc ../../logger.cc zone2ldap.cc ../../statbag.cc ../../misc.cc \ ../../unix_utility.cc ../../qtype.cc ../../zoneparser-tng.cc ../../dnsrecords.cc \ -../../dnswriter.cc ../../rcpgenerator.cc ../../dnsparser.cc ../../base64.cc - - +../../dnswriter.cc ../../rcpgenerator.cc ../../dnsparser.cc ../../base64.cc ../../sillyrecords.cc zone2ldap_LDFLAGS=@THREADFLAGS@ diff --git a/pdns/dnsrecords.cc b/pdns/dnsrecords.cc index 5165fdf4b..b69c65f64 100644 --- a/pdns/dnsrecords.cc +++ b/pdns/dnsrecords.cc @@ -172,8 +172,6 @@ string NSECRecordContent::getZoneRepresentation() const return ret; } - - boilerplate_conv(NS, ns_t_ns, conv.xfrLabel(d_content, true)); boilerplate_conv(PTR, ns_t_ptr, conv.xfrLabel(d_content, true)); boilerplate_conv(CNAME, ns_t_cname, conv.xfrLabel(d_content, true)); @@ -308,6 +306,7 @@ void reportOtherTypes() AFSDBRecordContent::report(); SPFRecordContent::report(); NAPTRRecordContent::report(); + LOCRecordContent::report(); RPRecordContent::report(); KEYRecordContent::report(); DNSKEYRecordContent::report(); diff --git a/pdns/dnsrecords.hh b/pdns/dnsrecords.hh index 303462520..69b1235f1 100644 --- a/pdns/dnsrecords.hh +++ b/pdns/dnsrecords.hh @@ -285,7 +285,24 @@ public: private: }; +class LOCRecordContent : public DNSRecordContent +{ +public: + static void report(void); + LOCRecordContent() : DNSRecordContent(ns_t_loc) + {} + LOCRecordContent(const string& content, const string& zone=""); + static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr); + static DNSRecordContent* make(const string& content); + string getZoneRepresentation() const; + void toPacket(DNSPacketWriter& pw); + + uint8_t d_version, d_size, d_horizpre, d_vertpre; + uint32_t d_latitude, d_longitude, d_altitude; + +private: +}; #define boilerplate(RNAME, RTYPE) \ RNAME##RecordContent::DNSRecordContent* RNAME##RecordContent::make(const DNSRecord& dr, PacketReader& pr) \ diff --git a/pdns/sillyrecords.cc b/pdns/sillyrecords.cc index 7ed67e0ad..0e58a44be 100644 --- a/pdns/sillyrecords.cc +++ b/pdns/sillyrecords.cc @@ -1,103 +1,15 @@ #include "utility.hh" #include - +#include #include #include - -#include - #include #include - -#include - -#include "dns.hh" -#include "dnsbackend.hh" -#include "ahuexception.hh" -#include "dnspacket.hh" -#include "logger.hh" -#include "arguments.hh" - -void DNSPacket::addLOCRecord(const DNSResourceRecord &rr) -{ - addLOCRecord(rr.qname, rr.content, rr.ttl); -} - -string DNSPacket::parseLOC(const unsigned char *p, unsigned int length) -{ - /* - MSB LSB - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - 0| VERSION | SIZE | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - 2| HORIZ PRE | VERT PRE | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - 4| LATITUDE | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - 6| LATITUDE | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - 8| LONGITUDE | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - 10| LONGITUDE | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - 12| ALTITUDE | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - 14| ALTITUDE | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - */ - - struct RP - { - unsigned int version:8; - unsigned int size:8; - unsigned int horizpre:8; - unsigned int vertpre:8; - }rp; - - memcpy(&rp,p,sizeof(rp)); - char ret[256]; - - double latitude= (((p[4]<<24) + (p[5]<<16) + (p[6]<<8) + p[7]) - (1<<31))/3600000.0; - double longitude=(((p[8]<<24) + (p[9]<<16) + (p[10]<<8) + p[11]) - (1<<31))/3600000.0; - double altitude= (((p[12]<<24) + (p[13]<<16) + (p[14]<<8) + p[15]) )/100 - 100000; - - double size=0.01*((rp.size>>4)&0xf); - int count=rp.size&0xf; - while(count--) - size*=10; - - double horizpre=0.01*((rp.horizpre>>4)&0xf); - count=rp.horizpre&0xf; - while(count--) - horizpre*=10; - - double vertpre=0.01*((rp.vertpre>>4)&0xf); - count=rp.vertpre&0xf; - while(count--) - vertpre*=10; - - - double remlat=60.0*(latitude-(int)latitude); - double remlong=60.0*(longitude-(int)longitude); - snprintf(ret,sizeof(ret)-1,"%d %d %2.03f %c %d %d %2.03f %c %.2fm %.2fm %.2fm %.2fm", - abs((int)latitude), (int) ((latitude-(int)latitude)*60), - (double)((remlat-(int)remlat)*60.0), - latitude>0 ? 'N' : 'S', - abs((int)longitude), (int) ((longitude-(int)longitude)*60), - (double)((remlong-(int)remlong)*60.0), - longitude>0 ? 'E' : 'W', - altitude, size, horizpre, vertpre); - - - return ret; -} - +#include "dnsrecords.hh" static unsigned int poweroften[10] = {1, 10, 100, 1000, 10000, 100000, 1000000,10000000,100000000,1000000000}; - - /* converts ascii size/precision X * 10**Y(cm) to 0xXY. moves pointer.*/ static uint8_t precsize_aton(const char **strptr) { @@ -160,8 +72,7 @@ latlon2ul(const char **latlonstrptr, int *which) while (isdigit(*cp)) min = min * 10 + (*cp++ - '0'); - - + while (isspace(*cp)) cp++; @@ -236,34 +147,73 @@ latlon2ul(const char **latlonstrptr, int *which) return (retval); } -void DNSPacket::addLOCRecord(const string &domain, const string & content, uint32_t ttl) +void LOCRecordContent::report(void) +{ + regist(1, ns_t_loc, &make, &make, "LOC"); +} + +DNSRecordContent* LOCRecordContent::make(const string& content) { + return new LOCRecordContent(content); +} + + +void LOCRecordContent::toPacket(DNSPacketWriter& pw) +{ + pw.xfr8BitInt(d_version); + pw.xfr8BitInt(d_size); + pw.xfr8BitInt(d_horizpre); + pw.xfr8BitInt(d_vertpre); + + pw.xfr32BitInt(d_latitude); + pw.xfr32BitInt(d_longitude); + pw.xfr32BitInt(d_altitude); +} + +LOCRecordContent::DNSRecordContent* LOCRecordContent::make(const DNSRecord &dr, PacketReader& pr) +{ + LOCRecordContent* ret=new LOCRecordContent(); + pr.xfr8BitInt(ret->d_version); + pr.xfr8BitInt(ret->d_size); + pr.xfr8BitInt(ret->d_horizpre); + pr.xfr8BitInt(ret->d_vertpre); + + pr.xfr32BitInt(ret->d_latitude); + pr.xfr32BitInt(ret->d_longitude); + pr.xfr32BitInt(ret->d_altitude); + + return ret; +} + +LOCRecordContent::LOCRecordContent(const string& content, const string& zone) : DNSRecordContent(ns_t_loc) +{ + // 51 59 00.000 N 5 55 00.000 E 4.00m 1.00m 10000.00m 10.00m + // convert this to d_version, d_size, d_horiz/vertpre, d_latitude, d_longitude, d_altitude + d_version = 0; + const char *cp, *maxcp; - uint32_t latit = 0, longit = 0, alt = 0; uint32_t lltemp1 = 0, lltemp2 = 0; int altmeters = 0, altfrac = 0, altsign = 1; - uint8_t hp = 0x16; /* default = 1e6 cm = 10000.00m = 10km */ - uint8_t vp = 0x13; /* default = 1e3 cm = 10.00m */ - uint8_t siz = 0x12; /* default = 1e2 cm = 1.00m */ + d_horizpre = 0x16; /* default = 1e6 cm = 10000.00m = 10km */ + d_vertpre = 0x13; /* default = 1e3 cm = 10.00m */ + d_size = 0x12; /* default = 1e2 cm = 1.00m */ int which1 = 0, which2 = 0; cp = content.c_str(); maxcp = cp + strlen(content.c_str()); lltemp1 = latlon2ul(&cp, &which1); - - lltemp2 = latlon2ul(&cp, &which2); switch (which1 + which2) { case 3: /* 1 + 2, the only valid combination */ if ((which1 == 1) && (which2 == 2)) { /* normal case */ - latit = lltemp1; - longit = lltemp2; + d_latitude = lltemp1; + d_longitude = lltemp2; } else if ((which1 == 2) && (which2 == 1)) {/*reversed*/ - longit = lltemp1; - latit = lltemp2; + d_latitude = lltemp1; + d_longitude = lltemp2; } else { /* some kind of brokenness */ return; } @@ -294,7 +244,7 @@ void DNSPacket::addLOCRecord(const string &domain, const string & content, uint3 } } - alt = (10000000 + (altsign * (altmeters * 100 + altfrac))); + d_altitude = (10000000 + (altsign * (altmeters * 100 + altfrac))); while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */ @@ -307,7 +257,7 @@ void DNSPacket::addLOCRecord(const string &domain, const string & content, uint3 if (cp >= maxcp) goto defaults; - siz = precsize_aton(&cp); + d_size = precsize_aton(&cp); while (!isspace(*cp) && (cp < maxcp))/*if trailing garbage or m*/ cp++; @@ -318,7 +268,7 @@ void DNSPacket::addLOCRecord(const string &domain, const string & content, uint3 if (cp >= maxcp) goto defaults; - hp = precsize_aton(&cp); + d_horizpre = precsize_aton(&cp); while (!isspace(*cp) && (cp < maxcp))/*if trailing garbage or m*/ cp++; @@ -329,36 +279,48 @@ void DNSPacket::addLOCRecord(const string &domain, const string & content, uint3 if (cp >= maxcp) goto defaults; - vp = precsize_aton(&cp); + d_vertpre = precsize_aton(&cp); defaults: + ; +} + + +string LOCRecordContent::getZoneRepresentation() const +{ + // convert d_version, d_size, d_horiz/vertpre, d_latitude, d_longitude, d_altitude to: + // 51 59 00.000 N 5 55 00.000 E 4.00m 1.00m 10000.00m 10.00m + + double latitude= ((int32_t)d_latitude - (1<<31))/3600000.0; + double longitude=((int32_t)d_longitude - (1<<31))/3600000.0; + double altitude= ((int32_t)d_altitude )/100 - 100000; + + double size=0.01*((d_size>>4)&0xf); + int count=d_size & 0xf; + while(count--) + size*=10; - string piece1; - toqname(domain, &piece1); - - char p[10]; - p[0]=0;p[1]=QType::LOC; - p[2]=0;p[3]=1; - - uint32_t *ttlp=(uint32_t *)(p+4); - *ttlp=htonl(ttl); // 4, 5, 6, 7 - - p[8]=0; - p[9]=16; - - string piece3; - piece3.resize(4); - piece3[0]=0; - piece3[1]=siz; - piece3[2]=hp; - piece3[3]=vp; - - stringbuffer+=piece1; - stringbuffer.append(p,10); - stringbuffer+=piece3; - latit=htonl(latit); longit=htonl(longit); alt=htonl(alt); - stringbuffer.append((char *)&latit,4); - stringbuffer.append((char *)&longit,4); - stringbuffer.append((char *)&alt,4); - d.ancount++; + double horizpre=0.01*((d_horizpre>>4) & 0xf); + count=d_horizpre&0xf; + while(count--) + horizpre*=10; + + double vertpre=0.01*((d_vertpre>>4)&0xf); + count=d_vertpre&0xf; + while(count--) + vertpre*=10; + + double remlat=60.0*(latitude-(int)latitude); + double remlong=60.0*(longitude-(int)longitude); + char ret[80]; + snprintf(ret,sizeof(ret)-1,"%d %d %2.03f %c %d %d %2.03f %c %.2fm %.2fm %.2fm %.2fm", + abs((int)latitude), abs((int) ((latitude-(int)latitude)*60)), + fabs((double)((remlat-(int)remlat)*60.0)), + latitude>0 ? 'N' : 'S', + abs((int)longitude), abs((int) ((longitude-(int)longitude)*60)), + fabs((double)((remlong-(int)remlong)*60.0)), + longitude>0 ? 'E' : 'W', + altitude, size, horizpre, vertpre); + + return ret; } diff --git a/regression-tests/basic-loc/command b/regression-tests/basic-loc/command new file mode 100755 index 000000000..69a6ab1eb --- /dev/null +++ b/regression-tests/basic-loc/command @@ -0,0 +1,2 @@ +cleandig location.example.com LOC + diff --git a/regression-tests/basic-loc/description b/regression-tests/basic-loc/description new file mode 100644 index 000000000..8fd24a018 --- /dev/null +++ b/regression-tests/basic-loc/description @@ -0,0 +1,2 @@ +This test tries to resolve a straight LOC record that is directly available in +the database. diff --git a/regression-tests/basic-loc/expected_result b/regression-tests/basic-loc/expected_result new file mode 100644 index 000000000..95b62e384 --- /dev/null +++ b/regression-tests/basic-loc/expected_result @@ -0,0 +1,6 @@ +0 location.example.com. IN LOC 120 51 56 0.123 N 5 54 0.000 E 4.00m 1.00m 10000.00m 10.00m +0 location.example.com. IN LOC 120 51 56 1.456 S 5 54 0.000 E 4.00m 2.00m 10000.00m 10.00m +0 location.example.com. IN LOC 120 51 56 2.789 N 5 54 0.000 W 4.00m 3.00m 10000.00m 10.00m +0 location.example.com. IN LOC 120 51 56 3.012 S 5 54 0.000 W 4.00m 4.00m 10000.00m 10.00m +Rcode: 0, RD: 0, TC: 0, AA: 1, opcode: 0 +Reply to question for qname='location.example.com.', qtype=LOC diff --git a/regression-tests/example.com b/regression-tests/example.com index 36d61c106..81157d203 100644 --- a/regression-tests/example.com +++ b/regression-tests/example.com @@ -19,6 +19,11 @@ ns2 IN A 192.168.1.2 localhost IN A 127.0.0.1 www IN CNAME outpost.example.com. ; +location IN LOC 51 56 0.123 N 5 54 0.000 E 4.00m 1.00m 10000.00m 10.00m + IN LOC 51 56 1.456 S 5 54 0.000 E 4.00m 2.00m 10000.00m 10.00m + IN LOC 51 56 2.789 N 5 54 0.000 W 4.00m 3.00m 10000.00m 10.00m + IN LOC 51 56 3.012 S 5 54 0.000 W 4.00m 4.00m 10000.00m 10.00m +; smtp-servers IN A 192.168.0.2 smtp-servers IN A 192.168.0.3 smtp-servers IN A 192.168.0.4