Parcourir la source

nscache6 command support + nsrecord with IPv6

nscache6 - new command for IPv6 addresses cache
nsrecord supports IPv6 addresses
dnsauth should work with IPv6 servers and clients
+ caching is now more accurate
z3APA3A il y a 11 ans
Parent
commit
5844e165b5
9 fichiers modifiés avec 168 ajouts et 120 suppressions
  1. 38 29
      src/3proxy.c
  2. 90 61
      src/auth.c
  3. 17 3
      src/common.c
  4. 1 2
      src/dighosts.c
  5. 12 13
      src/dnspr.c
  6. 1 3
      src/plugins.c
  7. 4 4
      src/proxy.h
  8. 4 4
      src/structures.h
  9. 1 1
      src/version.h

+ 38 - 29
src/3proxy.c

@@ -1069,7 +1069,15 @@ static int h_nscache6(int argc, unsigned char **argv){
 }
 }
 
 
 static int h_nsrecord(int argc, unsigned char **argv){
 static int h_nsrecord(int argc, unsigned char **argv){
-	hashadd(&dns_table, argv[1], getip(argv[2]), (time_t)0xffffffff);
+#ifndef NOIPV6
+	struct sockaddr_in6 sa;
+#else
+	struct sockaddr_in sa;
+#endif
+	memset(&sa, 0, sizeof(sa));
+	if(!getip46(46, argv[2], (struct sockaddr *)&sa)) return 1;
+
+	hashadd(*SAFAMILY(&sa)==AF_INET6?&dns6_table:&dns_table, argv[1], SAADDR(&sa), (time_t)0xffffffff);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -1819,34 +1827,35 @@ struct commands commandhandlers[]={
 	{commandhandlers+26, "nserver", h_nserver, 2, 2},
 	{commandhandlers+26, "nserver", h_nserver, 2, 2},
 	{commandhandlers+27, "fakeresolve", h_fakeresolve, 1, 1},
 	{commandhandlers+27, "fakeresolve", h_fakeresolve, 1, 1},
 	{commandhandlers+28, "nscache", h_nscache, 2, 2},
 	{commandhandlers+28, "nscache", h_nscache, 2, 2},
-	{commandhandlers+29, "nsrecord", h_nsrecord, 3, 3},
-	{commandhandlers+30, "dialer", h_dialer, 2, 2},
-	{commandhandlers+31, "system", h_system, 2, 2},
-	{commandhandlers+32, "pidfile", h_pidfile, 2, 2},
-	{commandhandlers+33, "monitor", h_monitor, 2, 2},
-	{commandhandlers+34, "parent", h_parent, 5, 0},
-	{commandhandlers+35, "allow", h_ace, 1, 0},
-	{commandhandlers+36, "deny", h_ace, 1, 0},
-	{commandhandlers+37, "redirect", h_ace, 3, 0},
-	{commandhandlers+38, "bandlimin", h_ace, 2, 0},
-	{commandhandlers+39, "bandlimout", h_ace, 2, 0},
-	{commandhandlers+40, "nobandlimin", h_ace, 1, 0},
-	{commandhandlers+41, "nobandlimout", h_ace, 1, 0},
-	{commandhandlers+42, "countin", h_ace, 4, 0},
-	{commandhandlers+43, "nocountin", h_ace, 1, 0},
-	{commandhandlers+44, "countout", h_ace, 4, 0},
-	{commandhandlers+45, "nocountout", h_ace, 1, 0},
-	{commandhandlers+46, "plugin", h_plugin, 3, 0},
-	{commandhandlers+47, "logdump", h_logdump, 2, 3},
-	{commandhandlers+48, "filtermaxsize", h_filtermaxsize, 2, 2},
-	{commandhandlers+49, "nolog", h_nolog, 1, 1},
-	{commandhandlers+50, "weight", h_nolog, 2, 2},
-	{commandhandlers+51, "authcache", h_authcache, 2, 3},
-	{commandhandlers+52, "smtpp", h_proxy, 1, 0},
-	{commandhandlers+53, "icqpr", h_proxy, 4, 0},
-	{commandhandlers+54, "msnpr", h_proxy, 4, 0},
-	{commandhandlers+55, "delimchar",h_delimchar, 2, 2},
-	{commandhandlers+56, "authnserver", h_authnserver, 2, 2},
+	{commandhandlers+29, "nscache6", h_nscache6, 2, 2},
+	{commandhandlers+30, "nsrecord", h_nsrecord, 3, 3},
+	{commandhandlers+31, "dialer", h_dialer, 2, 2},
+	{commandhandlers+32, "system", h_system, 2, 2},
+	{commandhandlers+33, "pidfile", h_pidfile, 2, 2},
+	{commandhandlers+34, "monitor", h_monitor, 2, 2},
+	{commandhandlers+35, "parent", h_parent, 5, 0},
+	{commandhandlers+36, "allow", h_ace, 1, 0},
+	{commandhandlers+37, "deny", h_ace, 1, 0},
+	{commandhandlers+38, "redirect", h_ace, 3, 0},
+	{commandhandlers+39, "bandlimin", h_ace, 2, 0},
+	{commandhandlers+40, "bandlimout", h_ace, 2, 0},
+	{commandhandlers+41, "nobandlimin", h_ace, 1, 0},
+	{commandhandlers+42, "nobandlimout", h_ace, 1, 0},
+	{commandhandlers+43, "countin", h_ace, 4, 0},
+	{commandhandlers+44, "nocountin", h_ace, 1, 0},
+	{commandhandlers+45, "countout", h_ace, 4, 0},
+	{commandhandlers+46, "nocountout", h_ace, 1, 0},
+	{commandhandlers+47, "plugin", h_plugin, 3, 0},
+	{commandhandlers+48, "logdump", h_logdump, 2, 3},
+	{commandhandlers+49, "filtermaxsize", h_filtermaxsize, 2, 2},
+	{commandhandlers+50, "nolog", h_nolog, 1, 1},
+	{commandhandlers+51, "weight", h_nolog, 2, 2},
+	{commandhandlers+52, "authcache", h_authcache, 2, 3},
+	{commandhandlers+53, "smtpp", h_proxy, 1, 0},
+	{commandhandlers+54, "icqpr", h_proxy, 4, 0},
+	{commandhandlers+55, "msnpr", h_proxy, 4, 0},
+	{commandhandlers+56, "delimchar",h_delimchar, 2, 2},
+	{commandhandlers+57, "authnserver", h_authnserver, 2, 2},
 	{specificcommands, 	 "", h_noop, 1, 0}
 	{specificcommands, 	 "", h_noop, 1, 0}
 };
 };
 
 

+ 90 - 61
src/auth.c

@@ -733,24 +733,36 @@ int userauth(struct clientparam * param){
 }
 }
 
 
 int dnsauth(struct clientparam * param){
 int dnsauth(struct clientparam * param){
-        char buf[32];
+        char buf[128];
+	char addr[16];
+	char dig[]="0123456789abcdef";
 
 
-/* FIX IT */
-	unsigned u ;
-
-	if(*SAFAMILY(&param->sincr)!=AF_INET) return 6;
-	u = ntohl(*(unsigned long *)SAADDR(&param->sincr));
-
-	sprintf(buf, "%u.%u.%u.%u.in-addr.arpa", 
+	unsigned u;
+	int i;
 
 
+	if(*SAFAMILY(&param->sincr)!=AF_INET){
+		char *s = buf;
+		for(i=15; i>=0; i--){
+			unsigned char c=((unsigned char *)SAADDR(&param->sincr))[i];
+			*s++ = dig[(c&0xf)];
+			*s++ = '.';
+			*s++ = dig[(c>>4)];
+			*s++ = '.';
+		}
+		sprintf(s, "ip6.arpa");
+	}
+	else {
+		u = ntohl(*(unsigned long *)SAADDR(&param->sincr));
 
 
-	((u&0x000000FF)),
-	((u&0x0000FF00)>>8),
-	((u&0x00FF0000)>>16),
-	((u&0xFF000000)>>24));
+		sprintf(buf, "%u.%u.%u.%u.in-addr.arpa", 
+			((u&0x000000FF)),
+			((u&0x0000FF00)>>8),
+			((u&0x00FF0000)>>16),
+			((u&0xFF000000)>>24));
 	
 	
-/* FIX IT */
-	if(*(unsigned long *)SAADDR(&param->sincr) != udpresolve(buf, NULL, param, 1)) return 6;
+	}
+	if(!udpresolve(*SAFAMILY(&param->sincr), buf, addr, NULL, param, 1)) return 6;
+	if(!memcmp(SAADDR(&param->sincr), addr, SAADDRLEN(&param->sincr))) return 6;
 
 
 	return param->username? 0:4;
 	return param->username? 0:4;
 }
 }
@@ -830,13 +842,13 @@ struct auth authfuncs[] = {
 
 
 
 
 
 
-struct hashtable dns_table = {0, {0}, NULL, NULL, NULL};
-struct hashtable dns6_table = {0, {0}, NULL, NULL, NULL};
+struct hashtable dns_table = {0, 4, {0}, NULL, NULL, NULL};
+struct hashtable dns6_table = {0, 16, {0}, NULL, NULL, NULL};
 
 
 
 
 void nametohash(const unsigned char * name, unsigned char *hash, unsigned char *rnd){
 void nametohash(const unsigned char * name, unsigned char *hash, unsigned char *rnd){
 	unsigned i, j, k;
 	unsigned i, j, k;
-	memcpy(hash, 0, sizeof(unsigned)*4);
+	memcpy(hash, rnd, sizeof(unsigned)*4);
 	for(i=0, j=0, k=0; name[j]; j++){
 	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];
 		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) {
 		if(++i == sizeof(unsigned)*4) {
@@ -870,6 +882,7 @@ void destroyhashtable(struct hashtable *ht){
 	pthread_mutex_unlock(&hash_mutex);
 	pthread_mutex_unlock(&hash_mutex);
 }
 }
 
 
+#define hvalue(i) ((struct hashentry *)((char *)ht->hashvalues + i*(sizeof(struct hashentry) + ht->recsize - 4)))
 int inithashtable(struct hashtable *ht, unsigned nhashsize){
 int inithashtable(struct hashtable *ht, unsigned nhashsize){
 	unsigned i;
 	unsigned i;
 	clock_t c;
 	clock_t c;
@@ -897,10 +910,10 @@ int inithashtable(struct hashtable *ht, unsigned nhashsize){
 		ht->hashvalues = NULL;
 		ht->hashvalues = NULL;
 	}
 	}
 	ht->hashsize = 0;
 	ht->hashsize = 0;
-	if(!(ht->hashtable = myalloc((nhashsize>>2) * sizeof(struct hashentry *)))){
+	if(!(ht->hashtable = myalloc((nhashsize>>2) *  sizeof(struct hashentry *)))){
 		return 2;
 		return 2;
 	}
 	}
-	if(!(ht->hashvalues = myalloc(nhashsize * sizeof(struct hashentry)))){
+	if(!(ht->hashvalues = myalloc(nhashsize * (sizeof(struct hashentry) + (ht->recsize-4))))){
 		myfree(ht->hashtable);
 		myfree(ht->hashtable);
 		ht->hashtable = NULL;
 		ht->hashtable = NULL;
 		return 3;
 		return 3;
@@ -911,58 +924,57 @@ int inithashtable(struct hashtable *ht, unsigned nhashsize){
 	ht->rnd[2] = myrand(&c, sizeof(c));
 	ht->rnd[2] = myrand(&c, sizeof(c));
 	ht->rnd[3] = myrand(ht->hashvalues,sizeof(ht->hashvalues));
 	ht->rnd[3] = myrand(ht->hashvalues,sizeof(ht->hashvalues));
 	memset(ht->hashtable, 0, (ht->hashsize>>2) * sizeof(struct hashentry *));
 	memset(ht->hashtable, 0, (ht->hashsize>>2) * sizeof(struct hashentry *));
-	memset(ht->hashvalues, 0, ht->hashsize * sizeof(struct hashentry));
+	memset(ht->hashvalues, 0, ht->hashsize * (sizeof(struct hashentry) + ht->recsize -4));
 
 
 	for(i = 0; i< (ht->hashsize - 1); i++) {
 	for(i = 0; i< (ht->hashsize - 1); i++) {
-		(ht->hashvalues + i)->next = ht->hashvalues + i + 1;
+		hvalue(i)->next = hvalue(i+1);
 	}
 	}
 	ht->hashempty = ht->hashvalues;
 	ht->hashempty = ht->hashvalues;
 	return 0;
 	return 0;
 }
 }
 
 
-int initdnshashtable(unsigned nhashsize){
-	return inithashtable(&dns_table, nhashsize);
-}
+void hashadd(struct hashtable *ht, const unsigned char* name, unsigned char* value, time_t expires){
+        struct hashentry * hen, *he;
+        struct hashentry ** hep;
 
 
-void hashadd(struct hashtable *ht, const unsigned char* name, unsigned long value, time_t expires){
-        struct hashentry * he;
 	unsigned index;
 	unsigned index;
 	
 	
 	if(!value||!name||!ht->hashtable||!ht->hashempty) return;
 	if(!value||!name||!ht->hashtable||!ht->hashempty) return;
 	pthread_mutex_lock(&hash_mutex);
 	pthread_mutex_lock(&hash_mutex);
-	he = ht->hashempty;
+	hen = ht->hashempty;
 	ht->hashempty = ht->hashempty->next;
 	ht->hashempty = ht->hashempty->next;
-	nametohash(name, he->hash, (unsigned char *)ht->rnd);
-	he->value = value;
-	he->expires = expires;
-	he->next = NULL;
-	index = hashindex(ht, he->hash);
-	if(!ht->hashtable[index] || !memcmp(he->hash, ht->hashtable[index]->hash, sizeof(he->hash))){
-		he->next = ht->hashtable[index];
-		ht->hashtable[index] = he;
-	}
-	else {
-		memset(he, 0, sizeof(struct hashentry));
-		he->next = ht->hashempty;
-		ht->hashempty = he;
+	nametohash(name, hen->hash, (unsigned char *)ht->rnd);
+	memcpy(hen->value, value, ht->recsize);
+	hen->expires = expires;
+	hen->next = NULL;
+	index = hashindex(ht, hen->hash);
+
+	for(hep = ht->hashtable + index; (he = *hep)!=NULL; ){
+		if(he->expires < conf.time || !memcmp(hen->hash, he->hash, sizeof(he->hash))) {
+			(*hep) = he->next;
+			he->expires = 0;
+			he->next = ht->hashempty;
+			ht->hashempty = he;
+		}
+		else hep=&(he->next);
 	}
 	}
+	hen->next = ht->hashtable[index];
+	ht->hashtable[index] = hen;
 	pthread_mutex_unlock(&hash_mutex);
 	pthread_mutex_unlock(&hash_mutex);
 }
 }
 
 
-unsigned long hashresolv(struct hashtable *ht, const unsigned char* name, unsigned *ttl){
+unsigned long hashresolv(struct hashtable *ht, const unsigned char* name, unsigned char* value, unsigned *ttl){
 	unsigned char hash[sizeof(unsigned)*4];
 	unsigned char hash[sizeof(unsigned)*4];
         struct hashentry ** hep;
         struct hashentry ** hep;
 	struct hashentry *he;
 	struct hashentry *he;
 	unsigned index;
 	unsigned index;
-	time_t t;
 
 
 	if(!ht->hashtable || !name) return 0;
 	if(!ht->hashtable || !name) return 0;
-	time(&t);
 	nametohash(name, hash, (unsigned char *)ht->rnd);
 	nametohash(name, hash, (unsigned char *)ht->rnd);
 	index = hashindex(ht, hash);
 	index = hashindex(ht, hash);
 	pthread_mutex_lock(&hash_mutex);
 	pthread_mutex_lock(&hash_mutex);
 	for(hep = ht->hashtable + index; (he = *hep)!=NULL; ){
 	for(hep = ht->hashtable + index; (he = *hep)!=NULL; ){
-		if((unsigned long)he->expires < (unsigned long)t) {
+		if(he->expires < conf.time) {
 			(*hep) = he->next;
 			(*hep) = he->next;
 			he->expires = 0;
 			he->expires = 0;
 			he->next = ht->hashempty;
 			he->next = ht->hashempty;
@@ -970,8 +982,9 @@ unsigned long hashresolv(struct hashtable *ht, const unsigned char* name, unsign
 		}
 		}
 		else if(!memcmp(hash, he->hash, sizeof(unsigned)*4)){
 		else if(!memcmp(hash, he->hash, sizeof(unsigned)*4)){
 			pthread_mutex_unlock(&hash_mutex);
 			pthread_mutex_unlock(&hash_mutex);
-			if(ttl) *ttl = (unsigned)(he->expires - t);
-			return he->value;
+			if(ttl) *ttl = (unsigned)(he->expires - conf.time);
+			memcpy(value, he->value, ht->recsize);
+			return 1;
 		}
 		}
 		else hep=&(he->next);
 		else hep=&(he->next);
 	}
 	}
@@ -983,12 +996,15 @@ struct nserver nservers[MAXNSERVERS] = {{{0},0}, {{0},0}, {{0},0}, {{0},0}, {{0}
 struct nserver authnserver;
 struct nserver authnserver;
 
 
 
 
-unsigned long udpresolve(unsigned char * name, unsigned *retttl, struct clientparam* param, int makeauth){
+unsigned long udpresolve(int af, unsigned char * name, unsigned char * value, unsigned *retttl, struct clientparam* param, int makeauth){
 
 
 	int i,n;
 	int i,n;
 	unsigned long retval;
 	unsigned long retval;
 
 
-	if((retval = hashresolv(&dns_table, name, retttl))) {
+	if((af == AF_INET) && (retval = hashresolv(&dns_table, name, value, retttl))) {
+		return retval;
+	}
+	if((af == AF_INET6) && (retval = hashresolv(&dns6_table, name, value, retttl))) {
 		return retval;
 		return retval;
 	}
 	}
 	n = (makeauth && !SAISNULL(&authnserver.addr))? 1 : numservers;
 	n = (makeauth && !SAISNULL(&authnserver.addr))? 1 : numservers;
@@ -1064,7 +1080,7 @@ unsigned long udpresolve(unsigned char * name, unsigned *retttl, struct clientpa
 		*s2 = (len - (int)(s2 - buf)) - 1;
 		*s2 = (len - (int)(s2 - buf)) - 1;
 		len++;
 		len++;
 		buf[len++] = 0;
 		buf[len++] = 0;
-		buf[len++] = (makeauth == 1)? 0x0c : 0x01;	/* PTR:host address */
+		buf[len++] = (makeauth == 1)? 0x0c : (af==AF_INET6? 0x1c:0x01);	/* PTR:host address */
 		buf[len++] = 0;
 		buf[len++] = 0;
 		buf[len++] = 1;			/* INET */
 		buf[len++] = 1;			/* INET */
 		if(usetcp){
 		if(usetcp){
@@ -1112,25 +1128,27 @@ unsigned long udpresolve(unsigned char * name, unsigned *retttl, struct clientpa
 		k += 4;
 		k += 4;
 		if(na > 255) na = 255;			/* somebody is very evil */
 		if(na > 255) na = 255;			/* somebody is very evil */
 		for (j = 0; j < na; j++) {		/* now there should be answers */
 		for (j = 0; j < na; j++) {		/* now there should be answers */
-			if((k+16) > len) {
+			if((k+(af == AF_INET6?28:16)) > len) {
 				break;
 				break;
 			}
 			}
 			flen = buf[k+11] + (((unsigned short)buf[k+10])<<8);
 			flen = buf[k+11] + (((unsigned short)buf[k+10])<<8);
-			if((k+12+flen) > len) break;
+			if((k+12+flen) > len) {
+				break;
+			}
 			if(makeauth != 1){
 			if(makeauth != 1){
-				if(buf[k+2] != 0 || buf[k+3] != 0x01 || flen != 4) {
+				if(buf[k+2] != 0 || buf[k+3] != (af == AF_INET6?0x1c:0x1) || flen != (af == AF_INET6?16:4)) {
 					k+= (12 + flen);
 					k+= (12 + flen);
 					continue; 		/* we need A IPv4 */
 					continue; 		/* we need A IPv4 */
 				}
 				}
-				retval = *(unsigned long *)(buf + k + 12);
 				ttl = ntohl(*(unsigned long *)(buf + k + 6));
 				ttl = ntohl(*(unsigned long *)(buf + k + 6));
-				t = time(0);
+				memcpy(value, buf + k + 12, af == AF_INET6? 16:4);
 				if(ttl < 60 || ((unsigned)t)+ttl < ttl) ttl = 300;
 				if(ttl < 60 || ((unsigned)t)+ttl < ttl) ttl = 300;
 				if(ttl){
 				if(ttl){
-					hashadd(&dns_table, name, retval, ((unsigned)t)+ttl);
+					hashadd(af == AF_INET6?&dns6_table:&dns_table, name, value, conf.time+ttl);
+
 				}
 				}
 				if(retttl) *retttl = ttl;
 				if(retttl) *retttl = ttl;
-				return retval;
+				return 1;
 			}
 			}
 			else {
 			else {
 				
 				
@@ -1147,19 +1165,30 @@ unsigned long udpresolve(unsigned char * name, unsigned *retttl, struct clientpa
 				if(param->username)myfree(param->username);
 				if(param->username)myfree(param->username);
 				param->username = mystrdup (buf + k + 13);
 				param->username = mystrdup (buf + k + 13);
 				
 				
-				return udpresolve(param->username, NULL, NULL, 2);
+				return udpresolve(af,param->username, value, NULL, NULL, 2);
 			}
 			}
 		}
 		}
 	}
 	}
 	return 0;
 	return 0;
 }
 }
 
 
-unsigned long myresolver(unsigned char * name){
- return udpresolve(name, NULL, NULL, 0);
+unsigned long myresolver(int af, unsigned char * name, unsigned char * value){
+ return udpresolve(af, name, value, NULL, NULL, 0);
 }
 }
 
 
-unsigned long fakeresolver (unsigned char *name){
- return htonl(0x7F000002);
+unsigned long fakeresolver (int af, unsigned char *name, unsigned char * value){
+ memset(value, 0, af == AF_INET6? 16 : 4);
+ if(af == AF_INET6){
+	memset(value, 0, 16);
+	value[15] = 2;
+ }
+ else {
+	value[0] = 127;
+	value[1] = 0;
+	value[2] = 0;
+	value[3] = 2;
+ }
+ return 1;
 }
 }
 
 
 #ifndef NOODBC
 #ifndef NOODBC

+ 17 - 3
src/common.c

@@ -693,6 +693,7 @@ struct hostent * my_gethostbyname(char *name, char *buf, struct hostent *hp){
 }
 }
 #endif
 #endif
 
 
+#ifdef NOIPV6
 unsigned long getip(unsigned char *name){
 unsigned long getip(unsigned char *name){
 	unsigned long retval;
 	unsigned long retval;
 	int i;
 	int i;
@@ -719,9 +720,9 @@ unsigned long getip(unsigned char *name){
 		}
 		}
 	}
 	}
 	if(resolvfunc){
 	if(resolvfunc){
-		if((retval = (*resolvfunc)(name))) return retval;
+		if((*resolvfunc)(AF_INET, name, &retval)) return retval;
 		if(conf.demanddialprog) system(conf.demanddialprog);
 		if(conf.demanddialprog) system(conf.demanddialprog);
-		return (*resolvfunc)(name);
+		return (*resolvfunc)(AF_INET, name, &retval)?retval:0;
 	}
 	}
 #if !defined(_WIN32) && !defined(GETHOSTBYNAME_R)
 #if !defined(_WIN32) && !defined(GETHOSTBYNAME_R)
 	if(!ghbn_init){
 	if(!ghbn_init){
@@ -744,6 +745,7 @@ unsigned long getip(unsigned char *name){
 #endif
 #endif
 	return retval;
 	return retval;
 }
 }
+#endif
 
 
 unsigned long getip46(int family, unsigned char *name,  struct sockaddr *sa){
 unsigned long getip46(int family, unsigned char *name,  struct sockaddr *sa){
 #ifndef NOIPV6
 #ifndef NOIPV6
@@ -753,9 +755,11 @@ unsigned long getip46(int family, unsigned char *name,  struct sockaddr *sa){
 
 
 	if(!sa) return 0;
 	if(!sa) return 0;
 	if(!family) {
 	if(!family) {
-#endif
+		family = AF_INET;
+#else
 		((struct sockaddr_in *)sa)->sin_family = AF_INET;
 		((struct sockaddr_in *)sa)->sin_family = AF_INET;
 		return (((struct sockaddr_in *)sa)->sin_addr.s_addr = getip(name))? AF_INET:0;
 		return (((struct sockaddr_in *)sa)->sin_addr.s_addr = getip(name))? AF_INET:0;
+#endif
 #ifndef NOIPV6
 #ifndef NOIPV6
 	}
 	}
 	for(i=0; name[i]; i++){
 	for(i=0; name[i]; i++){
@@ -786,6 +790,16 @@ unsigned long getip46(int family, unsigned char *name,  struct sockaddr *sa){
 			return inet_pton(AF_INET6, name, SAADDR(sa))?(family==4? 0:AF_INET6) : 0;
 			return inet_pton(AF_INET6, name, SAADDR(sa))?(family==4? 0:AF_INET6) : 0;
 		}
 		}
 	}
 	}
+	if(resolvfunc){
+		int f = (family == 6 || family == 64)?AF_INET6:AF_INET;
+		*SAFAMILY(sa) = f;
+		if(resolvfunc(f, name, SAADDR(sa))) return f;
+		if(family == 4 || family == 6) return 0;
+		f = (family == 46)? AF_INET6 : AF_INET;
+		*SAFAMILY(sa) = f;
+		if(resolvfunc(f, name, SAADDR(sa))) return f;
+		return 0;
+	}
 	memset(&hint, 0, sizeof(hint));
 	memset(&hint, 0, sizeof(hint));
 	hint.ai_family = (family == 6 || family == 64)?AF_INET6:AF_INET;
 	hint.ai_family = (family == 6 || family == 64)?AF_INET6:AF_INET;
 	if (getaddrinfo(name, NULL, &hint, &ai)) {
 	if (getaddrinfo(name, NULL, &hint, &ai)) {

+ 1 - 2
src/dighosts.c

@@ -83,12 +83,11 @@ int main(int argc, char *argv[]){
 		return 4;
 		return 4;
 	}
 	}
 	*hostend = '/';
 	*hostend = '/';
-	if(!(sa.sin_addr.s_addr = getip(host))) {
+	if(!getip46(4, host, (struct sockaddr *)&sa)) {
 		fprintf(stderr, "Unable to resolve %s\n", host);
 		fprintf(stderr, "Unable to resolve %s\n", host);
 		return 5;
 		return 5;
 	}
 	}
 	sa.sin_port = htons(80);
 	sa.sin_port = htons(80);
-	sa.sin_family = AF_INET;
 	if((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) return 6;
 	if((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) return 6;
 	sprintf((char *)buf, (char *)request, hostend, host);
 	sprintf((char *)buf, (char *)request, hostend, host);
 	if(connect(sock,(struct sockaddr *)&sa,sizeof(sa))) {
 	if(connect(sock,(struct sockaddr *)&sa,sizeof(sa))) {

+ 12 - 13
src/dnspr.c

@@ -27,6 +27,7 @@ void * dnsprchild(struct clientparam* param) {
  int len;
  int len;
  unsigned type=0;
  unsigned type=0;
  unsigned ttl;
  unsigned ttl;
+ unsigned char addr[16];
 #ifdef _WIN32
 #ifdef _WIN32
 	unsigned long ul = 1;
 	unsigned long ul = 1;
 #endif
 #endif
@@ -81,8 +82,8 @@ void * dnsprchild(struct clientparam* param) {
  *s2 = (len - (int)(s2 - buf)) - 1;
  *s2 = (len - (int)(s2 - buf)) - 1;
 
 
  type = ((unsigned)buf[len+1])*256 + (unsigned)buf[len+2];
  type = ((unsigned)buf[len+1])*256 + (unsigned)buf[len+2];
- if(type==1 && !param->srv->singlepacket){
- 	 ip = udpresolve((unsigned char *)host, &ttl, param, 0);
+ if((type==0x01 || type==0x1c) && !param->srv->singlepacket){
+ 	ip = udpresolve((type==0x1c)?AF_INET6:AF_INET, (unsigned char *)host, addr, &ttl, param, 0);
  }
  }
 
 
  len+=5;
  len+=5;
@@ -96,13 +97,13 @@ void * dnsprchild(struct clientparam* param) {
  	memset(buf+len, 0, 16);
  	memset(buf+len, 0, 16);
 	buf[len] = 0xc0;
 	buf[len] = 0xc0;
 	buf[len+1] = 0x0c;
 	buf[len+1] = 0x0c;
-	buf[len+3] = 1;
+	buf[len+3] = type;
 	buf[len+5] = 1;
 	buf[len+5] = 1;
 	ttl = htonl(ttl);
 	ttl = htonl(ttl);
 	memcpy(buf + len + 6, &ttl, 4);
 	memcpy(buf + len + 6, &ttl, 4);
-	buf[len+11] = 4;
-	memcpy(buf+len+12,(void *)&ip,4);
-	len+=16;
+	buf[len+11] = type==1? 4:16;
+	memcpy(buf+len+12,(void *)&addr,type==1? 4:16);
+	len+=(type==1?16:28);
  }
  }
  else if(type == 0x0c) {
  else if(type == 0x0c) {
 	unsigned a, b, c, d;
 	unsigned a, b, c, d;
@@ -191,14 +192,12 @@ void * dnsprchild(struct clientparam* param) {
 CLEANRET:
 CLEANRET:
 
 
  if(param->res!=813){
  if(param->res!=813){
-	sprintf((char *)buf, "%04x/%s(%u.%u.%u.%u)", 
+	sprintf((char *)buf, "%04x/%s/", 
 			(unsigned)type,
 			(unsigned)type,
-			host?host:"",
-			(unsigned)(ntohl(ip)&0xff000000)>>24,
-			(unsigned)(ntohl(ip)&0x00ff0000)>>16,
-			(unsigned)(ntohl(ip)&0x0000ff00)>>8,
-			(unsigned)(ntohl(ip)&0x000000ff)
-	);
+			host?host:"");
+	if(ip && type == 0x01 || type == 0x1c){
+		myinet_ntop(type == 0x01? AF_INET:AF_INET6, addr, buf+strlen(buf), 64);
+	}
 	(*param->srv->logfunc)(param, buf);
 	(*param->srv->logfunc)(param, buf);
  }
  }
  if(bbuf)myfree(bbuf);
  if(bbuf)myfree(bbuf);

+ 1 - 3
src/plugins.c

@@ -35,7 +35,7 @@ struct symbol symbols[] = {
 	{symbols+8, "myinet_ntop", (void *) myinet_ntop},
 	{symbols+8, "myinet_ntop", (void *) myinet_ntop},
 	{symbols+9, "dobuf", (void *) dobuf},
 	{symbols+9, "dobuf", (void *) dobuf},
 	{symbols+10, "scanaddr", (void *) scanaddr},
 	{symbols+10, "scanaddr", (void *) scanaddr},
-	{symbols+11, "getip", (void *) getip},
+	{symbols+11, "getip46", (void *) getip46},
 	{symbols+12, "sockmap", (void *) sockmap},
 	{symbols+12, "sockmap", (void *) sockmap},
 	{symbols+13, "sockfuncs", (void *) &so},
 	{symbols+13, "sockfuncs", (void *) &so},
 	{symbols+14, "ACLmatches", (void *) ACLmatches},
 	{symbols+14, "ACLmatches", (void *) ACLmatches},
@@ -78,7 +78,6 @@ struct symbol symbols[] = {
 	{symbols+48, "parsestr", (void *) parsestr},
 	{symbols+48, "parsestr", (void *) parsestr},
 	{symbols+49, "make_ace", (void *) make_ace},
 	{symbols+49, "make_ace", (void *) make_ace},
 	{symbols+50, "freeacl", (void *) freeacl},
 	{symbols+50, "freeacl", (void *) freeacl},
-	{symbols+51, "getip46", (void *) getip46},
 	{NULL, "", NULL}
 	{NULL, "", NULL}
 };
 };
 
 
@@ -108,7 +107,6 @@ struct pluginlink pluginlink = {
 	dobuf,
 	dobuf,
 	dobuf2,
 	dobuf2,
 	scanaddr,
 	scanaddr,
-	getip,
 	getip46,
 	getip46,
 	sockmap,
 	sockmap,
 	ACLmatches,		
 	ACLmatches,		

+ 4 - 4
src/proxy.h

@@ -187,8 +187,8 @@ extern struct nserver nservers[MAXNSERVERS];
 struct nserver authnserver;
 struct nserver authnserver;
 unsigned long getip(unsigned char *name);
 unsigned long getip(unsigned char *name);
 unsigned long getip46(int family, unsigned char *name,  struct sockaddr *sa);
 unsigned long getip46(int family, unsigned char *name,  struct sockaddr *sa);
-unsigned long myresolver(unsigned char *);
-unsigned long fakeresolver (unsigned char *name);
+unsigned long myresolver(int, unsigned char *, unsigned char *);
+unsigned long fakeresolver (int, unsigned char *, unsigned char*);
 int inithashtable(struct hashtable *hashtable, unsigned nhashsize);
 int inithashtable(struct hashtable *hashtable, unsigned nhashsize);
 void freeparam(struct clientparam * param);
 void freeparam(struct clientparam * param);
 void clearstat(struct clientparam * param);
 void clearstat(struct clientparam * param);
@@ -227,14 +227,14 @@ void mschap(const unsigned char *win_password,
 		 const unsigned char *challenge, unsigned char *response);
 		 const unsigned char *challenge, unsigned char *response);
 
 
 struct hashtable;
 struct hashtable;
-void hashadd(struct hashtable *ht, const unsigned char* name, unsigned long value, time_t expires);
+void hashadd(struct hashtable *ht, const unsigned char* name, unsigned char* value, time_t expires);
 
 
 int parsehostname(char *hostname, struct clientparam *param, unsigned short port);
 int parsehostname(char *hostname, struct clientparam *param, unsigned short port);
 int parseusername(char *username, struct clientparam *param, int extpasswd);
 int parseusername(char *username, struct clientparam *param, int extpasswd);
 int parseconnusername(char *username, struct clientparam *param, int extpasswd, unsigned short port);
 int parseconnusername(char *username, struct clientparam *param, int extpasswd, unsigned short port);
 int ACLmatches(struct ace* acentry, struct clientparam * param);
 int ACLmatches(struct ace* acentry, struct clientparam * param);
 
 
-unsigned long udpresolve(unsigned char * name, unsigned *retttl, struct clientparam* param, int makeauth);
+unsigned long udpresolve(int af, unsigned char * name, unsigned char * value, unsigned *retttl, struct clientparam* param, int makeauth);
 
 
 struct ace * copyacl (struct ace *ac);
 struct ace * copyacl (struct ace *ac);
 struct auth * copyauth (struct auth *);
 struct auth * copyauth (struct auth *);

+ 4 - 4
src/structures.h

@@ -155,7 +155,7 @@ struct srvparam;
 typedef void (*LOGFUNC)(struct clientparam * param, const unsigned char *);
 typedef void (*LOGFUNC)(struct clientparam * param, const unsigned char *);
 typedef int (*AUTHFUNC)(struct clientparam * param);
 typedef int (*AUTHFUNC)(struct clientparam * param);
 typedef void * (*REDIRECTFUNC)(struct clientparam * param);
 typedef void * (*REDIRECTFUNC)(struct clientparam * param);
-typedef unsigned long (*RESOLVFUNC)(unsigned char *);
+typedef unsigned long (*RESOLVFUNC)(int af, unsigned char *name, unsigned char *value);
 typedef unsigned (*BANDLIMFUNC)(struct clientparam * param, unsigned nbytesin, unsigned nbytesout);
 typedef unsigned (*BANDLIMFUNC)(struct clientparam * param, unsigned nbytesin, unsigned nbytesout);
 typedef void (*TRAFCOUNTFUNC)(struct clientparam * param);
 typedef void (*TRAFCOUNTFUNC)(struct clientparam * param);
 typedef void * (*EXTENDFUNC) (struct node *node);
 typedef void * (*EXTENDFUNC) (struct node *node);
@@ -583,16 +583,17 @@ struct child {
 
 
 struct hashentry {
 struct hashentry {
 	unsigned char hash[sizeof(unsigned)*4];
 	unsigned char hash[sizeof(unsigned)*4];
-	unsigned value;
 	time_t expires;
 	time_t expires;
 	struct hashentry *next;
 	struct hashentry *next;
+	char value[4];
 };
 };
 
 
 struct hashtable {
 struct hashtable {
 	unsigned hashsize;
 	unsigned hashsize;
+	unsigned recsize;
 	unsigned rnd[4];
 	unsigned rnd[4];
 	struct hashentry ** hashtable;
 	struct hashentry ** hashtable;
-	struct hashentry * hashvalues;
+	void * hashvalues;
 	struct hashentry * hashempty;
 	struct hashentry * hashempty;
 };
 };
 
 
@@ -656,7 +657,6 @@ struct pluginlink {
 	int (*dobuf)(struct clientparam * param, unsigned char * buf, const unsigned char *s, const unsigned char * doublec);
 	int (*dobuf)(struct clientparam * param, unsigned char * buf, const unsigned char *s, const unsigned char * doublec);
 	int (*dobuf2)(struct clientparam * param, unsigned char * buf, const unsigned char *s, const unsigned char * doublec, struct tm* tm, char * format);
 	int (*dobuf2)(struct clientparam * param, unsigned char * buf, const unsigned char *s, const unsigned char * doublec, struct tm* tm, char * format);
 	int (*scanaddr)(const unsigned char *s, unsigned long * ip, unsigned long * mask);
 	int (*scanaddr)(const unsigned char *s, unsigned long * ip, unsigned long * mask);
-	unsigned long (*getip)(unsigned char *name);
 	unsigned long (*getip46)(int family, unsigned char *name,  struct sockaddr *sa);
 	unsigned long (*getip46)(int family, unsigned char *name,  struct sockaddr *sa);
 	int (*sockmap)(struct clientparam * param, int timeo);
 	int (*sockmap)(struct clientparam * param, int timeo);
 	int (*ACLMatches)(struct ace* acentry, struct clientparam * param);
 	int (*ACLMatches)(struct ace* acentry, struct clientparam * param);

+ 1 - 1
src/version.h

@@ -1,2 +1,2 @@
 #define VERSION "3proxy-0.8b-devel"
 #define VERSION "3proxy-0.8b-devel"
-#define BUILDDATE "141214004331"
+#define BUILDDATE "141214052453"