From 6b99de69c408e753e86ae11c03d15d9ff5427533 Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Tue, 6 May 2014 02:56:35 +0400 Subject: [PATCH] getip46() added int getip46(int family, unsigned char *name, struct sockaddr_storage *sa) family: IPv4/IPv6 preference order 4, 6, 46, 64 or 0 for getip() compatibility. name - hostname, sa - destination sockaddr (must be large enougth) returns: 0 fo failed resolution IP address for family = 0 AF_INET/AF_INET6 overwise. --- src/common.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++--- src/proxy.h | 9 ++++++++ 2 files changed, 69 insertions(+), 3 deletions(-) diff --git a/src/common.c b/src/common.c index b2509a3..fe94d3e 100644 --- a/src/common.c +++ b/src/common.c @@ -688,9 +688,8 @@ unsigned long getip(unsigned char *name){ if(name[i] <'0' || name[i] >'9') break; } if(!name[i] && ndots == 3){ - unsigned long ip; - if(scanaddr(name, &ip, NULL) == 4){ - return ip; + if(scanaddr(name, &retval, NULL) == 4){ + return retval; } } if(resolvfunc){ @@ -719,3 +718,61 @@ unsigned long getip(unsigned char *name){ #endif return retval; } + +#ifdef NOIPV6 +unsigned long getip46(int family, unsigned char *name, struct sockaddr_in *sa){ +#else +unsigned long getip46(int family, unsigned char *name, struct sockaddr_storage *sa){ + int ndots=0, ncols=0; + struct addrinfo *ai, *iter; + struct sockaddr *sa4, *sa6; + int i; + + if(!sa) return 0; + if(!family) { +#endif + memset(sa, 0, sizeof(struct sockaddr_in)); + ((struct sockaddr_in *)sa)->sin_family = AF_INET; + return (((struct sockaddr_in *)sa)->sin_addr.s_addr = getip(name))? AF_INET:0; +#ifndef NOIPV6 + } + for(i=0; name[i]; i++){ + if(name[i] == '.'){ + if(++ndots > 3) break; + continue; + } + else if(name[i] == ':'){ + if(++ndots > 7) break; + continue; + } + if(name[i] <'0' || name[i] >'9') break; + } + if(!name[i]){ + if(ndots == 3 && ncols == 0){ + return inet_pton(AF_INET, name, sa)? AF_INET : 0; + } + if(ncols >= 2) { + return inet_pton(AF_INET6, name, sa)? AF_INET6 : 0; + } + } + if (getaddrinfo(name, NULL, NULL, &ai)) return 0; + for(iter = ai; iter; iter = iter->ai_next){ + if(!sa4 && iter->ai_addr->sa_family == AF_INET) sa4 = iter->ai_addr; + if(!sa6 && iter->ai_addr->sa_family == AF_INET) sa6 = iter->ai_addr; + } + if(sa6 && ((family == 6) || (family == 64) || (family == 46 && !sa4))){ + memcpy(sa, sa6, sizeof(struct sockaddr_in6)); + freeaddrinfo(ai); + return AF_INET6; + } + else if(sa4 && family != 6){ + memcpy(sa, sa4, sizeof(struct sockaddr_in)); + freeaddrinfo(ai); + return AF_INET; + } + else { + freeaddrinfo(ai); + return 0; + } +#endif +} diff --git a/src/proxy.h b/src/proxy.h index fbccdde..e195cc1 100644 --- a/src/proxy.h +++ b/src/proxy.h @@ -47,6 +47,10 @@ #ifdef _WIN32 #include +#ifndef NOIPV6 +#include + +#endif #ifndef _WINCE #include #else @@ -188,6 +192,11 @@ int myinet_ntoa(struct in_addr in, char * buf); extern unsigned long nservers[MAXNSERVERS]; extern unsigned long authnserver; unsigned long getip(unsigned char *name); +#ifdef NOIPV6 +unsigned long getip46(int family, unsigned char *name, struct sockaddr_in *sa){ +#else +unsigned long getip46(int family, unsigned char *name, struct sockaddr_storage *sa){ +#endif unsigned long myresolver(unsigned char *); unsigned long fakeresolver (unsigned char *name); int initdnshashtable(unsigned nhashsize);