while((labellen=*pos++) && pos < end) {
if(pos + labellen + 1 > end) // include length field in hash
return 0;
- ret=burtle(pos, labellen+1, ret);
+ ret=burtleCI(pos, labellen+1, ret);
pos += labellen;
}
return ret;
return c;
}
+uint32_t burtleCI(const unsigned char* k, uint32_t length, uint32_t initval)
+{
+ uint32_t a,b,c,len;
+
+ /* Set up the internal state */
+ len = length;
+ a = b = 0x9e3779b9; /* the golden ratio; an arbitrary value */
+ c = initval; /* the previous hash value */
+
+ /*---------------------------------------- handle most of the key */
+ while (len >= 12) {
+ a += (dns_tolower(k[0]) +((uint32_t)dns_tolower(k[1])<<8) +((uint32_t)dns_tolower(k[2])<<16) +((uint32_t)dns_tolower(k[3])<<24));
+ b += (dns_tolower(k[4]) +((uint32_t)dns_tolower(k[5])<<8) +((uint32_t)dns_tolower(k[6])<<16) +((uint32_t)dns_tolower(k[7])<<24));
+ c += (dns_tolower(k[8]) +((uint32_t)dns_tolower(k[9])<<8) +((uint32_t)dns_tolower(k[10])<<16)+((uint32_t)dns_tolower(k[11])<<24));
+ burtlemix(a,b,c);
+ k += 12; len -= 12;
+ }
+
+ /*------------------------------------- handle the last 11 bytes */
+ c += length;
+ switch(len) { /* all the case statements fall through */
+ case 11: c+=((uint32_t)dns_tolower(k[10])<<24);
+ case 10: c+=((uint32_t)dns_tolower(k[9])<<16);
+ case 9 : c+=((uint32_t)dns_tolower(k[8])<<8);
+ /* the first byte of c is reserved for the length */
+ case 8 : b+=((uint32_t)dns_tolower(k[7])<<24);
+ case 7 : b+=((uint32_t)dns_tolower(k[6])<<16);
+ case 6 : b+=((uint32_t)dns_tolower(k[5])<<8);
+ case 5 : b+=dns_tolower(k[4]);
+ case 4 : a+=((uint32_t)dns_tolower(k[3])<<24);
+ case 3 : a+=((uint32_t)dns_tolower(k[2])<<16);
+ case 2 : a+=((uint32_t)dns_tolower(k[1])<<8);
+ case 1 : a+=dns_tolower(k[0]);
+ /* case 0: nothing left to add */
+ }
+ burtlemix(a,b,c);
+ /*-------------------------------------------- report the result */
+ return c;
+}
+
+
void setSocketTimestamps(int fd)
{
#ifdef SO_TIMESTAMP
void setFilenumLimit(unsigned int lim);
bool readFileIfThere(const char* fname, std::string* line);
uint32_t burtle(const unsigned char* k, uint32_t lengh, uint32_t init);
+uint32_t burtleCI(const unsigned char* k, uint32_t lengh, uint32_t init);
void setSocketTimestamps(int fd);
#endif
#include <boost/assign/list_of.hpp>
#include <boost/foreach.hpp>
#include <boost/tuple/tuple.hpp>
+#include <math.h>
#include "misc.hh"
#include "dns.hh"
+#include "dnswriter.hh"
+#include "dnsrecords.hh"
#include <utility>
using std::string;
BOOST_CHECK_EQUAL(ac, 2);
}
+BOOST_AUTO_TEST_CASE(test_QuestionHash) {
+ vector<unsigned char> packet;
+ reportBasicTypes();
+ DNSPacketWriter dpw1(packet, "www.ds9a.nl.", QType::AAAA);
+
+ uint32_t hash1=hashQuestion((char*)&packet[0], packet.size(), 0);
+ DNSPacketWriter dpw2(packet, "wWw.Ds9A.nL.", QType::AAAA);
+ uint32_t hash2=hashQuestion((char*)&packet[0], packet.size(), 0);
+ BOOST_CHECK_EQUAL(hash1, hash2);
+
+ vector<uint32_t> counts(1500);
+
+ for(unsigned int n=0; n < 100000; ++n) {
+ packet.clear();
+ DNSPacketWriter dpw1(packet, lexical_cast<string>(n)+"."+lexical_cast<string>(n*2)+".", QType::AAAA);
+ counts[hashQuestion((char*)&packet[0], packet.size(), 0) % counts.size()]++;
+ }
+
+ double sum = 0.0;
+ BOOST_FOREACH(double d, counts){
+ sum += d;
+ }
+
+ double m = sum / counts.size();
+
+ double accum = 0.0;
+ BOOST_FOREACH(double d, counts) {
+ accum += (d - m) * (d - m);
+ };
+
+ double stdev = sqrt(accum / (counts.size()-1));
+ BOOST_CHECK(stdev < 10);
+}
+
BOOST_AUTO_TEST_CASE(test_endianness) {
uint32_t i = 1;
#if BYTE_ORDER == BIG_ENDIAN