Compare commits

...

4 Commits

Author SHA1 Message Date
Vladimir Dubrovin
8bf0d3f4ae Fix authcachesize
Some checks are pending
C/C++ CI Linux / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Waiting to run
C/C++ CI Linux / ${{ matrix.target }} (ubuntu-latest) (push) Waiting to run
C/C++ CI MacOS / ${{ matrix.target }} (macos-15) (push) Waiting to run
C/C++ CI Windows / ${{ matrix.target }} (windows-2022) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (macos-15) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (ubuntu-latest) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (windows-2022) (push) Waiting to run
2026-04-20 20:13:21 +03:00
Vladimir Dubrovin
3957210609 Allow different hash lengths; fix bug on hashtable grow 2026-04-20 18:49:53 +03:00
Vladimir Dubrovin
ee00956b74 hash username/password with terminators 2026-04-20 11:59:58 +03:00
Vladimir Dubrovin
083a70393f Minor hashtable refactor 2026-04-20 10:40:38 +03:00
6 changed files with 110 additions and 106 deletions

View File

@ -7,7 +7,6 @@
*/ */
#include "proxy.h" #include "proxy.h"
#include "libs/blake2.h"
static FILTER_ACTION (*ext_ssl_parent)(struct clientparam * param) = NULL; static FILTER_ACTION (*ext_ssl_parent)(struct clientparam * param) = NULL;
@ -776,34 +775,6 @@ int checkACL(struct clientparam * param){
return 3; return 3;
} }
struct authcache {
unsigned char username[64];
#ifndef NOIPv6
uint8_t sincr_addr[16];
uint8_t sinsl_addr[16];
#else
uint8_t sincr_addr[4];
uint8_t sinsl_addr[4];
#endif
uint16_t sincr_family;
uint16_t sinsl_family;
};
void param2hash(const void *index, uint8_t *hash, const unsigned char *rnd){
blake2b_state S;
const struct clientparam *param = (struct clientparam *)index;
blake2b_init_key(&S, HASH_SIZE, rnd, sizeof(unsigned)*4);
if((conf.authcachetype & 1) && !(conf.authcachetype & 8))blake2b_update(&S, SAADDR(&param->sincr), SAADDRLEN(&param->sincr));
if((conf.authcachetype & 2) && param->username)blake2b_update(&S, param->username, strlen((const char *)param->username));
if((conf.authcachetype & 4) && param->password)blake2b_update(&S, param->password, strlen((const char *)param->password));
if((conf.authcachetype & 16))blake2b_update(&S, &param->srv->acl, sizeof(param->srv->acl));
blake2b_final(&S, hash, HASH_SIZE);
}
struct hashtable auth_table = {0, sizeof(struct authcache), {0,0,0,0}, NULL, NULL, 0, param2hash};
int cacheauth(struct clientparam * param){ int cacheauth(struct clientparam * param){
struct authcache ac; struct authcache ac;
uint32_t ttl; uint32_t ttl;

View File

@ -197,7 +197,7 @@ static int h_proxy(int argc, unsigned char ** argv){
childdef.service = S_PROXY; childdef.service = S_PROXY;
childdef.helpmessage = " -n - no NTLM support\n"; childdef.helpmessage = " -n - no NTLM support\n";
#ifdef NOIPV6 #ifdef NOIPV6
if(!resolvfunc || (resolvfunc == myresolver && !dns_table.hashsize)){ if(!resolvfunc || (resolvfunc == myresolver && !dns_table.poolsize)){
fprintf(stderr, "[line %d] Warning: no nserver/nscache configured, proxy may run very slow\n", linenum); fprintf(stderr, "[line %d] Warning: no nserver/nscache configured, proxy may run very slow\n", linenum);
} }
#endif #endif
@ -230,7 +230,7 @@ static int h_proxy(int argc, unsigned char ** argv){
childdef.service = S_SOCKS; childdef.service = S_SOCKS;
childdef.helpmessage = " -n - no NTLM support\n"; childdef.helpmessage = " -n - no NTLM support\n";
#ifdef NOIPV6 #ifdef NOIPV6
if(!resolvfunc || (resolvfunc == myresolver && !dns_table.hashsize)){ if(!resolvfunc || (resolvfunc == myresolver && !dns_table.poolsize)){
fprintf(stderr, "[line %d] Warning: no nserver/nscache configured, socks may run very slow\n", linenum); fprintf(stderr, "[line %d] Warning: no nserver/nscache configured, socks may run very slow\n", linenum);
} }
#endif #endif
@ -276,7 +276,7 @@ static int h_proxy(int argc, unsigned char ** argv){
childdef.service = S_DNSPR; childdef.service = S_DNSPR;
childdef.helpmessage = " -s - simple DNS forwarding - do not use 3proxy resolver / name cache\n"; childdef.helpmessage = " -s - simple DNS forwarding - do not use 3proxy resolver / name cache\n";
#ifndef NOIPV6 #ifndef NOIPV6
if(!resolvfunc || (resolvfunc == myresolver && !dns_table.hashsize) || resolvfunc == fakeresolver){ if(!resolvfunc || (resolvfunc == myresolver && !dns_table.poolsize) || resolvfunc == fakeresolver){
fprintf(stderr, "[line %d] Warning: no nserver/nscache configured, dnspr will not work as expected\n", linenum); fprintf(stderr, "[line %d] Warning: no nserver/nscache configured, dnspr will not work as expected\n", linenum);
} }
#endif #endif
@ -655,14 +655,14 @@ static int h_fakeresolve(int argc, unsigned char **argv){
} }
static int h_nscache(int argc, unsigned char **argv){ static int h_nscache(int argc, unsigned char **argv){
int res; unsigned res;
res = atoi((char *)argv[1]); res = (unsigned)atoi((char *)argv[1]);
if(res < 256) { if(res < 256) {
fprintf(stderr, "Invalid NS cache size: %d\n", res); fprintf(stderr, "Invalid NS cache size: %d\n", res);
return 1; return 1;
} }
if(inithashtable(&dns_table, (unsigned)res)){ if(inithashtable(&dns_table, (res << 2), (res << 2), res)){
fprintf(stderr, "Failed to initialize NS cache\n"); fprintf(stderr, "Failed to initialize NS cache\n");
return 2; return 2;
} }
@ -678,14 +678,14 @@ static int h_parentretries(int argc, unsigned char **argv){
} }
static int h_nscache6(int argc, unsigned char **argv){ static int h_nscache6(int argc, unsigned char **argv){
int res; unsigned res;
res = atoi((char *)argv[1]); res = (unsigned)atoi((char *)argv[1]);
if(res < 256) { if(res < 256) {
fprintf(stderr, "Invalid NS cache size: %d\n", res); fprintf(stderr, "Invalid NS cache size: %d\n", res);
return 1; return 1;
} }
if(inithashtable(&dns6_table, (unsigned)res)){ if(inithashtable(&dns6_table, (res<<2), (res<<2), res)){
fprintf(stderr, "Failed to initialize NS cache\n"); fprintf(stderr, "Failed to initialize NS cache\n");
return 2; return 2;
} }
@ -1429,8 +1429,9 @@ static int h_radius(int argc, unsigned char **argv){
} }
#endif #endif
static int h_authcache(int argc, unsigned char **argv){ static int h_authcache(int argc, unsigned char **argv){
int authcachesize = 0;
conf.authcachetype = 0; conf.authcachetype = 0;
int authcachesize;
if(strstr((char *) *(argv + 1), "ip")) conf.authcachetype |= 1; if(strstr((char *) *(argv + 1), "ip")) conf.authcachetype |= 1;
if(strstr((char *) *(argv + 1), "user")) conf.authcachetype |= 2; if(strstr((char *) *(argv + 1), "user")) conf.authcachetype |= 2;
if(strstr((char *) *(argv + 1), "pass")) conf.authcachetype |= 4; if(strstr((char *) *(argv + 1), "pass")) conf.authcachetype |= 4;
@ -1438,14 +1439,14 @@ static int h_authcache(int argc, unsigned char **argv){
if(strstr((char *) *(argv + 1), "acl")) conf.authcachetype |= 16; if(strstr((char *) *(argv + 1), "acl")) conf.authcachetype |= 16;
if(strstr((char *) *(argv + 1), "ext")) conf.authcachetype |= 32; if(strstr((char *) *(argv + 1), "ext")) conf.authcachetype |= 32;
if(argc > 2) conf.authcachetime = (unsigned) atoi((char *) *(argv + 2)); if(argc > 2) conf.authcachetime = (unsigned) atoi((char *) *(argv + 2));
if(argc > 3) authcachesize = (unsigned) atoi((char *) *(argv + 2)); if(argc > 3) authcachesize = (unsigned) atoi((char *) *(argv + 3));
if(!conf.authcachetype) conf.authcachetype = 6; if(!conf.authcachetype) conf.authcachetype = 6;
if(!conf.authcachetime) conf.authcachetime = 600; if(!conf.authcachetime) conf.authcachetime = 600;
if(inithashtable(&auth_table, authcachesize? authcachesize : 4096)){ if(!authcachesize) authcachesize = 65536*4;
if(inithashtable(&auth_table, 1024, 1024, authcachesize)){
fprintf(stderr, "Failed to initialize auth cache\n"); fprintf(stderr, "Failed to initialize auth cache\n");
return 2; return 2;
} }
if(!authcachesize)auth_table.growlimit = 65536*4;
return 0; return 0;
} }

View File

@ -1,6 +1,13 @@
#include "proxy.h" #include "proxy.h"
#include "libs/blake2.h" #include "libs/blake2.h"
struct hashentry {
time_t expires;
uint32_t inext;
char value[4];
};
static uint32_t hashindex(struct hashtable *ht, const uint8_t* hash){ static uint32_t hashindex(struct hashtable *ht, const uint8_t* hash){
return (*(unsigned *)hash ) % (ht->tablesize); return (*(unsigned *)hash ) % (ht->tablesize);
} }
@ -16,16 +23,20 @@ void destroyhashtable(struct hashtable *ht){
myfree(ht->hashvalues); myfree(ht->hashvalues);
ht->hashvalues = NULL; ht->hashvalues = NULL;
} }
ht->hashsize = 0; if(ht->hashhashvalues){
myfree(ht->hashvalues);
ht->hashvalues = NULL;
}
ht->poolsize = 0;
ht->tablesize = 0; ht->tablesize = 0;
pthread_mutex_unlock(&hash_mutex); pthread_mutex_unlock(&hash_mutex);
} }
#define hvalue(ht,I) ((struct hashentry *)(ht->hashvalues + (I-1)*(sizeof(struct hashentry) + ht->recsize - 4))) #define hvalue(ht,I) ((struct hashentry *)(ht->hashvalues + (I-1)*(sizeof(struct hashentry) + ht->recsize - 4)))
#define hhash(ht,I) ((ht->hashhashvalues + (I-1)*(ht->hash_size)))
int inithashtable(struct hashtable *ht, unsigned nhashsize){ int inithashtable(struct hashtable *ht, unsigned tablesize, unsigned poolsize, unsigned growlimit){
unsigned i; unsigned i;
unsigned tablesize, hashsize;
clock_t c; clock_t c;
#ifdef _WIN32 #ifdef _WIN32
@ -40,8 +51,7 @@ int inithashtable(struct hashtable *ht, unsigned nhashsize){
#endif #endif
c = clock(); c = clock();
hashsize = tablesize = (nhashsize >> 2); if(tablesize < 2 || poolsize < tablesize || growlimit < poolsize) return 1;
if(tablesize < 2) return 1;
pthread_mutex_lock(&hash_mutex); pthread_mutex_lock(&hash_mutex);
if(ht->ihashtable){ if(ht->ihashtable){
myfree(ht->ihashtable); myfree(ht->ihashtable);
@ -51,29 +61,30 @@ int inithashtable(struct hashtable *ht, unsigned nhashsize){
myfree(ht->hashvalues); myfree(ht->hashvalues);
ht->hashvalues = NULL; ht->hashvalues = NULL;
} }
ht->hashsize = 0; if(ht->hashhashvalues){
ht->tablesize = 0; myfree(ht->hashvalues);
if(!(ht->ihashtable = myalloc(tablesize * sizeof(uint32_t)))){ ht->hashvalues = NULL;
pthread_mutex_unlock(&hash_mutex);
return 2;
} }
if(!(ht->hashvalues = myalloc(hashsize * (sizeof(struct hashentry) + (ht->recsize-4))))){ ht->poolsize = 0;
ht->tablesize = 0;
if(!(ht->ihashtable = myalloc(tablesize * sizeof(uint32_t)))
|| !(ht->hashvalues = myalloc(poolsize * (sizeof(struct hashentry) + (ht->recsize-4))))
|| !(ht->hashhashvalues = myalloc(poolsize * ht->hash_size))
){
myfree(ht->ihashtable); myfree(ht->ihashtable);
ht->ihashtable = NULL; ht->ihashtable = NULL;
myfree(ht->hashvalues);
ht->hashvalues = NULL;
pthread_mutex_unlock(&hash_mutex); pthread_mutex_unlock(&hash_mutex);
return 3; return 3;
} }
ht->hashsize = hashsize; ht->poolsize = poolsize;
ht->tablesize = tablesize; ht->tablesize = tablesize;
ht->growlimit = nhashsize; ht->growlimit = growlimit;
ht->rnd[0] = myrand(&tb, sizeof(tb));
ht->rnd[1] = myrand(ht->ihashtable, sizeof(ht->ihashtable));
ht->rnd[2] = myrand(&c, sizeof(c));
ht->rnd[3] = myrand(ht->hashvalues,sizeof(ht->hashvalues));
memset(ht->ihashtable, 0, ht->tablesize * sizeof(uint32_t)); memset(ht->ihashtable, 0, ht->tablesize * sizeof(uint32_t));
memset(ht->hashvalues, 0, ht->hashsize * (sizeof(struct hashentry) + ht->recsize - 4)); memset(ht->hashvalues, 0, ht->poolsize * (sizeof(struct hashentry) + ht->recsize - 4));
for(i = 1; i < ht->hashsize; i++) { for(i = 1; i < ht->poolsize; i++) {
hvalue(ht,i)->inext = i+1; hvalue(ht,i)->inext = i+1;
} }
ht->ihashempty = 1; ht->ihashempty = 1;
@ -85,7 +96,7 @@ static void hashcompact(struct hashtable *ht){
int i; int i;
uint32_t he, *hep; uint32_t he, *hep;
if((conf.time - ht->compacted) < 300 || !ht->tablesize || !ht->hashsize || ht->ihashempty) return; if((conf.time - ht->compacted) < 300 || !ht->tablesize || !ht->poolsize || ht->ihashempty) return;
for(i = 0; i < ht->tablesize; i++){ for(i = 0; i < ht->tablesize; i++){
for(hep = ht->ihashtable + i; (he = *hep) != 0; ){ for(hep = ht->ihashtable + i; (he = *hep) != 0; ){
if(hvalue(ht,he)->expires < conf.time ) { if(hvalue(ht,he)->expires < conf.time ) {
@ -102,24 +113,28 @@ static void hashcompact(struct hashtable *ht){
} }
static void hashgrow(struct hashtable *ht){ static void hashgrow(struct hashtable *ht){
unsigned newsize = (ht->hashsize + (ht->hashsize >> 1)); unsigned newsize = (ht->poolsize + (ht->poolsize >> 1));
unsigned i; unsigned i;
void * newvalues; void * newvalues;
if(!ht->tablesize || !ht->hashsize) return; if(!ht->tablesize || !ht->poolsize) return;
if(ht->hashsize / ht->tablesize < 4) hashcompact(ht); if(ht->poolsize / ht->tablesize < 4) hashcompact(ht);
if(ht->ihashempty) return; if(ht->ihashempty) return;
if(ht->hashsize >= ht->growlimit) return; if(ht->poolsize >= ht->growlimit) return;
if(newsize > ht->growlimit) newsize = ht->growlimit; if(newsize > ht->growlimit) newsize = ht->growlimit;
newvalues = myrealloc(ht->hashvalues, newsize * (sizeof(struct hashentry) + ht->recsize - 4)); newvalues = myrealloc(ht->hashvalues, newsize * (sizeof(struct hashentry) + ht->recsize - 4));
if(!newvalues) return; if(!newvalues) return;
memset(ht->hashvalues + (ht->hashsize * (sizeof(struct hashentry) + ht->recsize - 4)), 0, (newsize - ht->hashsize) * (sizeof(struct hashentry) + ht->recsize - 4)); ht->hashvalues = newvalues;
for(i = ht->hashsize + 1; i < newsize; i++) { newvalues = myrealloc(ht->hashhashvalues, newsize * ht->hash_size);
if(!newvalues) return;
ht->hashhashvalues = newvalues;
memset(ht->hashvalues + (ht->poolsize * (sizeof(struct hashentry) + ht->recsize - 4)), 0, (newsize - ht->poolsize) * (sizeof(struct hashentry) + ht->recsize - 4));
for(i = ht->poolsize + 1; i < newsize; i++) {
hvalue(ht,i)->inext = i+1; hvalue(ht,i)->inext = i+1;
} }
hvalue(ht,newsize)->inext = ht->ihashempty; hvalue(ht,newsize)->inext = ht->ihashempty;
ht->ihashempty = ht->hashsize + 1; ht->ihashempty = ht->poolsize + 1;
ht->hashsize = newsize; ht->poolsize = newsize;
} }
@ -128,21 +143,20 @@ void hashadd(struct hashtable *ht, const void* name, const void* value, time_t e
uint32_t hen, he; uint32_t hen, he;
uint32_t *hep; uint32_t *hep;
int overwrite = 0; int overwrite = 0;
uint8_t hash[HASH_SIZE]; uint8_t hash[ht->hash_size];
uint32_t index; uint32_t index;
uint32_t last = 0; uint32_t last = 0;
pthread_mutex_lock(&hash_mutex);
if(!ht||!value||!name||!ht->ihashtable) { if(!ht||!value||!name||!ht->ihashtable) {
pthread_mutex_unlock(&hash_mutex);
return; return;
} }
ht->index2hash(name, hash, (unsigned char *)ht->rnd); ht->index2hash(ht, name, hash);
pthread_mutex_lock(&hash_mutex);
index = hashindex(ht, hash); index = hashindex(ht, hash);
for(hep = ht->ihashtable + index; (he = *hep)!=0; ){ for(hep = ht->ihashtable + index; (he = *hep)!=0; ){
if(hvalue(ht,he)->expires < conf.time || !memcmp(hash, hvalue(ht,he)->hash, HASH_SIZE)) { if(hvalue(ht,he)->expires < conf.time || !memcmp(hash, hhash(ht,he), ht->hash_size)) {
(*hep) = hvalue(ht,he)->inext; (*hep) = hvalue(ht,he)->inext;
hvalue(ht,he)->expires = 0; hvalue(ht,he)->expires = 0;
hvalue(ht,he)->inext = ht->ihashempty; hvalue(ht,he)->inext = ht->ihashempty;
@ -168,7 +182,7 @@ void hashadd(struct hashtable *ht, const void* name, const void* value, time_t e
hen = last; hen = last;
} }
if(hen){ if(hen){
memcpy(hvalue(ht,hen)->hash, hash, HASH_SIZE); memcpy(hhash(ht,hen), hash, ht->hash_size);
memcpy(hvalue(ht,hen)->value, value, ht->recsize); memcpy(hvalue(ht,hen)->value, value, ht->recsize);
hvalue(ht,hen)->expires = expires; hvalue(ht,hen)->expires = expires;
} }
@ -177,17 +191,16 @@ void hashadd(struct hashtable *ht, const void* name, const void* value, time_t e
} }
int hashresolv(struct hashtable *ht, const void* name, void* value, uint32_t *ttl){ int hashresolv(struct hashtable *ht, const void* name, void* value, uint32_t *ttl){
uint8_t hash[HASH_SIZE]; uint8_t hash[ht->hash_size];
uint32_t *hep; uint32_t *hep;
uint32_t he; uint32_t he;
uint32_t index; uint32_t index;
pthread_mutex_lock(&hash_mutex);
if(!ht || !ht->ihashtable || !name) { if(!ht || !ht->ihashtable || !name) {
pthread_mutex_unlock(&hash_mutex);
return 0; return 0;
} }
ht->index2hash(name, hash, (unsigned char *)ht->rnd); ht->index2hash(ht,name, hash);
pthread_mutex_lock(&hash_mutex);
index = hashindex(ht, hash); index = hashindex(ht, hash);
for(hep = ht->ihashtable + index; (he = *hep)!=0; ){ for(hep = ht->ihashtable + index; (he = *hep)!=0; ){
if(hvalue(ht, he)->expires < conf.time) { if(hvalue(ht, he)->expires < conf.time) {
@ -196,7 +209,7 @@ int hashresolv(struct hashtable *ht, const void* name, void* value, uint32_t *tt
hvalue(ht,he)->inext = ht->ihashempty; hvalue(ht,he)->inext = ht->ihashempty;
ht->ihashempty = he; ht->ihashempty = he;
} }
else if(!memcmp(hash, hvalue(ht,he)->hash, HASH_SIZE)){ else if(!memcmp(hash, hhash(ht,he), ht->hash_size)){
if(ttl) *ttl = (uint32_t)(hvalue(ht,he)->expires - conf.time); if(ttl) *ttl = (uint32_t)(hvalue(ht,he)->expires - conf.time);
memcpy(value, hvalue(ht,he)->value, ht->recsize); memcpy(value, hvalue(ht,he)->value, ht->recsize);
pthread_mutex_unlock(&hash_mutex); pthread_mutex_unlock(&hash_mutex);
@ -207,3 +220,25 @@ int hashresolv(struct hashtable *ht, const void* name, void* value, uint32_t *tt
pthread_mutex_unlock(&hash_mutex); pthread_mutex_unlock(&hash_mutex);
return 0; return 0;
} }
void char_index2hash(const struct hashtable *ht, const void *index, uint8_t *hash){
const char* name = index;
blake2b(hash, ht->hash_size, index, strlen((const char*)index), NULL, 0);
}
void param2hash(const struct hashtable *ht, const void *index, uint8_t *hash){
blake2b_state S;
const struct clientparam *param = (struct clientparam *)index;
blake2b_init(&S, HASH_SIZE);
if((conf.authcachetype & 2) && param->username)blake2b_update(&S, param->username, strlen((const char *)param->username) + 1);
if((conf.authcachetype & 4) && param->password)blake2b_update(&S, param->password, strlen((const char *)param->password) + 1);
if((conf.authcachetype & 1) && !(conf.authcachetype & 8))blake2b_update(&S, SAADDR(&param->sincr), SAADDRLEN(&param->sincr));
if((conf.authcachetype & 16))blake2b_update(&S, &param->srv->acl, sizeof(param->srv->acl));
blake2b_final(&S, hash, ht->hash_size);
}
struct hashtable dns_table = {char_index2hash, 4, HASH_SIZE};
struct hashtable dns6_table = {char_index2hash, 16, HASH_SIZE};
struct hashtable auth_table = {param2hash, sizeof(struct authcache), HASH_SIZE};

View File

@ -244,7 +244,7 @@ void mschap(const unsigned char *win_password,
const unsigned char *challenge, unsigned char *response); const unsigned char *challenge, unsigned char *response);
void destroyhashtable(struct hashtable *ht); void destroyhashtable(struct hashtable *ht);
int inithashtable(struct hashtable *ht, unsigned nhashsize); int inithashtable(struct hashtable *ht, unsigned tablesize, unsigned poolsize, unsigned growlimit);
void hashadd(struct hashtable *ht, const void* name, const void* value, time_t expires); void hashadd(struct hashtable *ht, const void* name, const void* value, time_t expires);
int hashresolv(struct hashtable *ht, const void* name, void* value, uint32_t *ttl); int hashresolv(struct hashtable *ht, const void* name, void* value, uint32_t *ttl);

View File

@ -1,15 +1,4 @@
#include "proxy.h" #include "proxy.h"
#include "libs/blake2.h"
void char_index2hash(const void *index, uint8_t *hash, const unsigned char *rnd){
const char* name = index;
blake2b(hash, HASH_SIZE, index, strlen((const char*)index), rnd, 4*sizeof(unsigned) );
}
struct hashtable dns_table = {0, 4, {0,0,0,0}, NULL, NULL, 0, char_index2hash};
struct hashtable dns6_table = {0, 16, {0,0,0,0}, NULL, NULL, 0, char_index2hash};
struct nserver nservers[MAXNSERVERS] = {{{0},0}, {{0},0}, {{0},0}, {{0},0}, {{0},0}}; struct nserver nservers[MAXNSERVERS] = {{{0},0}, {{0},0}, {{0},0}, {{0},0}, {{0},0}};
struct nserver authnserver; struct nserver authnserver;

View File

@ -756,30 +756,38 @@ struct child {
#define HASH_SIZE (16) #define HASH_SIZE (16)
struct hashentry {
uint8_t hash[HASH_SIZE];
time_t expires;
uint32_t inext;
char value[4];
};
struct hashtable { struct hashtable {
unsigned hashsize; void (*index2hash)(const struct hashtable *ht, const void *index, uint8_t *hash);
unsigned recsize; unsigned recsize;
unsigned rnd[4]; unsigned hash_size;
unsigned poolsize;
unsigned tablesize;
unsigned growlimit;
uint32_t * ihashtable; uint32_t * ihashtable;
uint8_t * hashvalues; uint8_t * hashvalues;
uint32_t ihashempty; uint8_t * hashhashvalues;
void (*index2hash)(const void *index, unsigned char *hash, const unsigned char *rnd);
unsigned growlimit;
int tablesize;
time_t compacted; time_t compacted;
uint32_t ihashhashempty;
uint32_t ihashempty;
}; };
extern struct hashtable dns_table; extern struct hashtable dns_table;
extern struct hashtable dns6_table; extern struct hashtable dns6_table;
extern struct hashtable auth_table; extern struct hashtable auth_table;
struct authcache {
unsigned char username[64];
#ifndef NOIPv6
uint8_t sincr_addr[16];
uint8_t sinsl_addr[16];
#else
uint8_t sincr_addr[4];
uint8_t sinsl_addr[4];
#endif
uint16_t sincr_family;
uint16_t sinsl_family;
};
struct pluginlink { struct pluginlink {
struct symbol symbols; struct symbol symbols;
struct extparam *conf; struct extparam *conf;