From 7fc43e3fbd536f391438fc248d523e4bdae2d31d Mon Sep 17 00:00:00 2001 From: z3APA3A <3APA3A@3proxy.ru> Date: Sun, 14 Dec 2014 00:46:03 +0300 Subject: [PATCH] add some entropy to DNS hashtable --- src/3proxy.c | 16 +++++++++++++++- src/auth.c | 42 +++++++++++++++++++++++++++++++++--------- src/proxy.h | 3 +-- src/structures.h | 4 +++- src/version.h | 2 +- 5 files changed, 53 insertions(+), 14 deletions(-) diff --git a/src/3proxy.c b/src/3proxy.c index 9497779..f07b8db 100644 --- a/src/3proxy.c +++ b/src/3proxy.c @@ -1047,7 +1047,21 @@ static int h_nscache(int argc, unsigned char **argv){ fprintf(stderr, "Invalid NS cache size: %d\n", res); return 1; } - if(initdnshashtable((unsigned)res)){ + if(inithashtable(&dns_table, (unsigned)res)){ + fprintf(stderr, "Failed to initialize NS cache\n"); + return 2; + } + return 0; +} +static int h_nscache6(int argc, unsigned char **argv){ + int res; + + res = atoi((char *)argv[1]); + if(res < 256) { + fprintf(stderr, "Invalid NS cache size: %d\n", res); + return 1; + } + if(inithashtable(&dns6_table, (unsigned)res)){ fprintf(stderr, "Failed to initialize NS cache\n"); return 2; } diff --git a/src/auth.c b/src/auth.c index 3608ef4..34596ef 100644 --- a/src/auth.c +++ b/src/auth.c @@ -459,6 +459,7 @@ unsigned bandlimitfunc(struct clientparam *param, unsigned nbytesin, unsigned nb sec = tv.tv_sec; msec = tv.tv_usec; #endif + if(!nbytesin && !nbytesout) return 0; pthread_mutex_lock(&bandlim_mutex); if(param->srv->version != conf.paused){ @@ -829,15 +830,19 @@ struct auth authfuncs[] = { -struct hashtable dns_table = {0, NULL, NULL, NULL}; +struct hashtable dns_table = {0, {0}, NULL, NULL, NULL}; +struct hashtable dns6_table = {0, {0}, NULL, NULL, NULL}; -void nametohash(const unsigned char * name, unsigned char *hash){ - unsigned i, j; - memset(hash, 0, sizeof(unsigned)*4); - for(i=0, j=0; name[j]; j++){ - hash[i] += toupper(name[j]) - 32; - if(++i == sizeof(unsigned)*4) i = 0; +void nametohash(const unsigned char * name, unsigned char *hash, unsigned char *rnd){ + unsigned i, j, k; + memcpy(hash, 0, sizeof(unsigned)*4); + for(i=0, j=0, k=0; name[j]; j++){ + hash[i] += (toupper(name[j]) - 32)+rnd[((toupper(name[j]))*29277+rnd[(k+j+i)%16]+k+j+i)%16]; + if(++i == sizeof(unsigned)*4) { + i = 0; + k++; + } } } @@ -867,6 +872,20 @@ void destroyhashtable(struct hashtable *ht){ int inithashtable(struct hashtable *ht, unsigned nhashsize){ unsigned i; + clock_t c; + + +#ifdef _WIN32 + struct timeb tb; + + ftime(&tb); + +#else + struct timeval tb; + struct timezone tz; + gettimeofday(&tb, &tz); +#endif + c = clock(); if(nhashsize<4) return 1; if(ht->hashtable){ @@ -887,8 +906,13 @@ int inithashtable(struct hashtable *ht, unsigned nhashsize){ return 3; } ht->hashsize = nhashsize; + ht->rnd[0] = myrand(&tb, sizeof(tb)); + ht->rnd[1] = myrand(ht->hashtable, sizeof(ht->hashtable)); + ht->rnd[2] = myrand(&c, sizeof(c)); + ht->rnd[3] = myrand(ht->hashvalues,sizeof(ht->hashvalues)); memset(ht->hashtable, 0, (ht->hashsize>>2) * sizeof(struct hashentry *)); memset(ht->hashvalues, 0, ht->hashsize * sizeof(struct hashentry)); + for(i = 0; i< (ht->hashsize - 1); i++) { (ht->hashvalues + i)->next = ht->hashvalues + i + 1; } @@ -908,7 +932,7 @@ void hashadd(struct hashtable *ht, const unsigned char* name, unsigned long valu pthread_mutex_lock(&hash_mutex); he = ht->hashempty; ht->hashempty = ht->hashempty->next; - nametohash(name, he->hash); + nametohash(name, he->hash, (unsigned char *)ht->rnd); he->value = value; he->expires = expires; he->next = NULL; @@ -934,7 +958,7 @@ unsigned long hashresolv(struct hashtable *ht, const unsigned char* name, unsign if(!ht->hashtable || !name) return 0; time(&t); - nametohash(name, hash); + nametohash(name, hash, (unsigned char *)ht->rnd); index = hashindex(ht, hash); pthread_mutex_lock(&hash_mutex); for(hep = ht->hashtable + index; (he = *hep)!=NULL; ){ diff --git a/src/proxy.h b/src/proxy.h index 0341bdc..4558546 100644 --- a/src/proxy.h +++ b/src/proxy.h @@ -189,7 +189,7 @@ unsigned long getip(unsigned char *name); unsigned long getip46(int family, unsigned char *name, struct sockaddr *sa); unsigned long myresolver(unsigned char *); unsigned long fakeresolver (unsigned char *name); -int initdnshashtable(unsigned nhashsize); +int inithashtable(struct hashtable *hashtable, unsigned nhashsize); void freeparam(struct clientparam * param); void clearstat(struct clientparam * param); void dumpcounters(struct trafcount *tl, int counterd); @@ -308,7 +308,6 @@ extern pthread_mutex_t pwl_mutex; extern pthread_mutex_t odbc_mutex; #endif -extern struct hashtable dns_table; extern struct datatype datatypes[64]; extern struct commands commandhandlers[]; diff --git a/src/structures.h b/src/structures.h index 2d8f046..aaf4322 100644 --- a/src/structures.h +++ b/src/structures.h @@ -583,19 +583,21 @@ struct child { struct hashentry { unsigned char hash[sizeof(unsigned)*4]; - unsigned long value; + unsigned value; time_t expires; struct hashentry *next; }; struct hashtable { unsigned hashsize; + unsigned rnd[4]; struct hashentry ** hashtable; struct hashentry * hashvalues; struct hashentry * hashempty; }; extern struct hashtable dns_table; +extern struct hashtable dns6_table; struct sockfuncs { #ifdef _WIN32 diff --git a/src/version.h b/src/version.h index 1362b4e..d0ce229 100644 --- a/src/version.h +++ b/src/version.h @@ -1,2 +1,2 @@ #define VERSION "3proxy-0.8b-devel" -#define BUILDDATE "141213231838" +#define BUILDDATE "141214004331"