Browse Source

IPv6 server side code

+ IPv6 server side support
!!! Auth need to be fixed
Vladimir Dubrovin 11 years ago
parent
commit
a30d5d51a5
15 changed files with 141 additions and 122 deletions
  1. 20 13
      src/auth.c
  2. 4 4
      src/common.c
  3. 12 17
      src/datatypes.c
  4. 6 6
      src/dnspr.c
  5. 27 24
      src/ftppr.c
  6. 1 1
      src/icqpr.c
  7. 3 5
      src/proxy.c
  8. 2 2
      src/proxy.h
  9. 20 12
      src/proxymain.c
  10. 1 1
      src/smtpp.c
  11. 8 8
      src/sockgetchar.c
  12. 4 4
      src/sockmap.c
  13. 20 18
      src/socks.c
  14. 10 4
      src/structures.h
  15. 3 3
      src/udppm.c

+ 20 - 13
src/auth.c

@@ -44,12 +44,12 @@ unsigned char * getNetBIOSnamebyip(unsigned long ip){
  sins.sin_family = AF_INET;
  sins.sin_addr.s_addr = ip;
  sins.sin_port = htons(137);
- res=socksendto(sock, &sins, request, sizeof(request), conf.timeouts[SINGLEBYTE_L]*1000);
+ res=socksendto(sock, (struct sockaddr*)&sins, request, sizeof(request), conf.timeouts[SINGLEBYTE_L]*1000);
  if(res <= 0) {
 	so._closesocket(sock);
 	return NULL;
  }
- res = sockrecvfrom(sock, &sins, buf, sizeof(buf), conf.timeouts[SINGLEBYTE_L]*1000);
+ res = sockrecvfrom(sock, (struct sockaddr*)&sins, buf, sizeof(buf), conf.timeouts[SINGLEBYTE_L]*1000);
  so._closesocket(sock);
  if(res < (HEADERSIZE + RECORDSIZE)) {
 	return NULL;
@@ -376,7 +376,8 @@ int ACLmatches(struct ace* acentry, struct clientparam * param){
 	username = param->username?param->username:(unsigned char *)"-";
 	if(acentry->src) {
 	 for(ipentry = acentry->src; ipentry; ipentry = ipentry->next)
-		if(ipentry->ip == (param->sinc.sin_addr.s_addr & ipentry->mask)) {
+/* FIX IT !*/
+		if(ipentry->ip == (*(unsigned long *)SAADDR(&param->sincr) & ipentry->mask)) {
 			break;
 		}
 		if(!ipentry) return 0;
@@ -673,7 +674,8 @@ int cacheauth(struct clientparam * param){
 			
 		}
 		if(((!(conf.authcachetype&2)) || (param->username && ac->username && !strcmp(ac->username, param->username))) &&
-		   ((!(conf.authcachetype&1)) || ac->ip == param->sinc.sin_addr.s_addr) && 
+/* FIX IT */
+		   ((!(conf.authcachetype&1)) || ac->ip == *(unsigned long *)SAADDR(&param->sincr)) && 
 		   (!(conf.authcachetype&4) || (ac->password && param->password && !strcmp(ac->password, param->password)))) {
 			if(param->username){
 				myfree(param->username);
@@ -707,7 +709,8 @@ int doauth(struct clientparam * param){
 				pthread_mutex_lock(&hash_mutex);
 				for(ac = authc; ac; ac = ac->next){
 					if((!(conf.authcachetype&2) || !strcmp(ac->username, param->username)) &&
-					   (!(conf.authcachetype&1) || ac->ip == param->sinc.sin_addr.s_addr)  &&
+/* FIX IT */
+					   (!(conf.authcachetype&1) || ac->ip == *(unsigned long *)SAADDR(&param->sincr))  &&
 					   (!(conf.authcachetype&4) || (ac->password && !strcmp(ac->password, param->password)))) {
 						ac->expires = conf.time + conf.authcachetime;
 						if(strcmp(ac->username, param->username)){
@@ -720,7 +723,8 @@ int doauth(struct clientparam * param){
 							ac->password = mystrdup(param->password);
 							myfree(tmp);
 						}
-						ac->ip = param->sinc.sin_addr.s_addr;
+/* FIX IT */
+						ac->ip = *(unsigned long *)SAADDR(&param->sincr);
 						break;
 					}
 				}
@@ -729,7 +733,8 @@ int doauth(struct clientparam * param){
 					if(ac){
 						ac->expires = conf.time + conf.authcachetime;
 						ac->username = mystrdup(param->username);
-						ac->ip = param->sinc.sin_addr.s_addr;
+/* FIX IT */
+						ac->ip = *(unsigned long *)SAADDR(&param->sincr);
 						ac->password = NULL;
 						if((conf.authcachetype&4) && param->password) ac->password = mystrdup(param->password);
 					}
@@ -765,7 +770,8 @@ int userauth(struct clientparam * param){
 }
 
 int nbnameauth(struct clientparam * param){
-	unsigned char * name = getNetBIOSnamebyip(param->sinc.sin_addr.s_addr);
+/* FIX IT */
+	unsigned char * name = getNetBIOSnamebyip(*(unsigned long *)SAADDR(&param->sincr));
 
 	if (param->username) myfree (param->username);
 	param->username = name;
@@ -774,7 +780,8 @@ int nbnameauth(struct clientparam * param){
 
 int dnsauth(struct clientparam * param){
         char buf[32];
-	unsigned u = ntohl(param->sinc.sin_addr.s_addr);
+/* FIX IT */
+	unsigned u = ntohl(*(unsigned long *)SAADDR(&param->sincr));
 
 	sprintf(buf, "%u.%u.%u.%u.in-addr.arpa", 
 
@@ -784,8 +791,8 @@ int dnsauth(struct clientparam * param){
 	((u&0x00FF0000)>>16),
 	((u&0xFF000000)>>24));
 	
-
-	if(param->sinc.sin_addr.s_addr != udpresolve(buf, NULL, param, 1)) return 6;
+/* FIX IT */
+	if(*(unsigned long *)SAADDR(&param->sincr) != udpresolve(buf, NULL, param, 1)) return 6;
 
 	return param->username? 0:4;
 }
@@ -1054,13 +1061,13 @@ unsigned long udpresolve(unsigned char * name, unsigned *retttl, struct clientpa
 		buf[len++] = (makeauth == 1)? 0x0c : 0x01;	/* PTR:host address */
 		buf[len++] = 0;
 		buf[len++] = 1;			/* INET */
-		if(socksendto(sock, sinsp, buf, len, conf.timeouts[SINGLEBYTE_L]*1000) != len){
+		if(socksendto(sock, (struct sockaddr *)sinsp, buf, len, conf.timeouts[SINGLEBYTE_L]*1000) != len){
 			so._shutdown(sock, SHUT_RDWR);
 			so._closesocket(sock);
 			continue;
 		}
 		if(param) param->statscli64 += len;
-		len = sockrecvfrom(sock, sinsp, buf, 4096, 15000);
+		len = sockrecvfrom(sock, (struct sockaddr *) sinsp, buf, 4096, 15000);
 		so._shutdown(sock, SHUT_RDWR);
 		so._closesocket(sock);
 		if(len <= 13) continue;

+ 4 - 4
src/common.c

@@ -22,7 +22,7 @@ int randomizer = 1;
 
 unsigned char **stringtable = NULL;
 
-int myinet_ntop(int af, const void *src, char *dst, socklen_t size){
+int myinet_ntop(int af, void *src, char *dst, socklen_t size){
 #ifndef NOIPV6
  if(af != AF_INET6){
 #endif 
@@ -463,7 +463,7 @@ int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char
 				 i += myinet_ntop(AF_INET, &tmpia, (char *)buf + i, 64);
 				 break;
 				case 'C':
-				 i += myinet_ntop(*SAFAMILY(&param->sinc), SAADDR(&param->sinc), (char *)buf + i, 64);
+				 i += myinet_ntop(*SAFAMILY(&param->sincr), SAADDR(&param->sincr), (char *)buf + i, 64);
 				 break;
 				case 'R':
 				 i += myinet_ntop(*SAFAMILY(&param->sins), SAADDR(&param->sins), (char *)buf + i, 64);
@@ -476,7 +476,7 @@ int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char
 				 i += (int)strlen((char *)buf+i);
 				 break;
 				case 'c':
-				 sprintf((char *)buf+i, "%hu", ntohs(param->sinc.sin_port));
+				 sprintf((char *)buf+i, "%hu", ntohs(*SAPORT(&param->sincr)));
 				 i += (int)strlen((char *)buf+i);
 				 break;
 				case 'r':
@@ -612,7 +612,7 @@ int doconnect(struct clientparam * param){
 	bindsa.sin_family = AF_INET;
 	bindsa.sin_port = param->extport;
 	bindsa.sin_addr.s_addr = param->extip;
-	if (param->srv->targetport && !bindsa.sin_port && ntohs(param->sinc.sin_port) > 1023) bindsa.sin_port = param->sinc.sin_port;
+	if (param->srv->targetport && !bindsa.sin_port && ntohs(*SAPORT(&param->sincr)) > 1023) bindsa.sin_port = *SAPORT(&param->sincr);
 	if(so._bind(param->remsock, (struct sockaddr*)&bindsa, sizeof(bindsa))==-1) {
 		memset(&bindsa, 0, sizeof(bindsa));
 		bindsa.sin_family = AF_INET;

+ 12 - 17
src/datatypes.c

@@ -637,8 +637,8 @@ static void * ef_client_extpassword(struct node * node){
 	return ((struct clientparam *)node->value) -> extpassword;
 }
 
-static void * ef_client_cliip(struct node * node){
-	return &((struct clientparam *)node->value) -> sinc.sin_addr.s_addr;
+static void * ef_client_clisa(struct node * node){
+	return &((struct clientparam *)node->value) -> sincr;
 }
 
 static void * ef_client_srvip(struct node * node){
@@ -657,10 +657,6 @@ static void * ef_client_srvport(struct node * node){
 	return &((struct clientparam *)node->value) -> sins.sin_port;
 }
 
-static void * ef_client_cliport(struct node * node){
-	return &((struct clientparam *)node->value) -> sinc.sin_port;
-}
-
 static void * ef_client_pwtype(struct node * node){
 	return &((struct clientparam *)node->value) -> pwtype;
 }
@@ -802,17 +798,16 @@ static struct property prop_client[] = {
 	{prop_client + 9, "extpassword", ef_client_extpassword, TYPE_STRING, "password for requested host"},
 	{prop_client + 10, "username", ef_client_username, TYPE_STRING, "client username"},
 	{prop_client + 11, "password", ef_client_password, TYPE_STRING, "client password"},
-	{prop_client + 12, "cliip", ef_client_cliip, TYPE_IP, "client ip"},
-	{prop_client + 13, "cliport", ef_client_cliport, TYPE_PORT, "client port"},
-	{prop_client + 14, "srvip", ef_client_srvip, TYPE_IP, "target server ip"},
-	{prop_client + 15, "srvport", ef_client_srvport, TYPE_PORT, "target server port"},
-	{prop_client + 16, "reqip", ef_client_reqip, TYPE_IP, "requested server ip"},
-	{prop_client + 17, "reqport", ef_client_reqport, TYPE_PORT, "requested server port"},
-	{prop_client + 18, "bytesin", ef_client_bytesin64, TYPE_UNSIGNED64, "bytes from server to client"},
-	{prop_client + 19, "bytesout", ef_client_bytesout64, TYPE_UNSIGNED64, "bytes from client to server"},
-	{prop_client + 20, "maxtrafin", ef_client_maxtrafin64, TYPE_UNSIGNED64, "maximum traffic allowed for download"},
-	{prop_client + 21, "maxtrafout", ef_client_maxtrafout64, TYPE_UNSIGNED64, "maximum traffic allowed for upload"},
-	{prop_client + 22, "pwtype", ef_client_pwtype, TYPE_INTEGER, "type of client password"},
+	{prop_client + 12, "clisa", ef_client_clisa, TYPE_SA, "client sa"},
+	{prop_client + 13, "srvip", ef_client_srvip, TYPE_IP, "target server ip"},
+	{prop_client + 14, "srvport", ef_client_srvport, TYPE_PORT, "target server port"},
+	{prop_client + 15, "reqip", ef_client_reqip, TYPE_IP, "requested server ip"},
+	{prop_client + 16, "reqport", ef_client_reqport, TYPE_PORT, "requested server port"},
+	{prop_client + 17, "bytesin", ef_client_bytesin64, TYPE_UNSIGNED64, "bytes from server to client"},
+	{prop_client + 18, "bytesout", ef_client_bytesout64, TYPE_UNSIGNED64, "bytes from client to server"},
+	{prop_client + 19, "maxtrafin", ef_client_maxtrafin64, TYPE_UNSIGNED64, "maximum traffic allowed for download"},
+	{prop_client + 20, "maxtrafout", ef_client_maxtrafout64, TYPE_UNSIGNED64, "maximum traffic allowed for upload"},
+	{prop_client + 21, "pwtype", ef_client_pwtype, TYPE_INTEGER, "type of client password"},
 	{NULL, "next", ef_client_next, TYPE_CLIENT, "next"}
 
 	

+ 6 - 6
src/dnspr.c

@@ -36,8 +36,8 @@ void * dnsprchild(struct clientparam* param) {
 	param->srv->fds.events = POLLIN;
 	RETURN (21);
  }
- size = sizeof(struct sockaddr_in);
- i = so._recvfrom(param->srv->srvsock, buf, BUFSIZE, 0, (struct sockaddr *)&param->sinc, &size); 
+ size = sizeof(param->sincr);
+ i = so._recvfrom(param->srv->srvsock, buf, BUFSIZE, 0, (struct sockaddr *)&param->sincr, &size); 
 #ifdef _WIN32
 	if((param->clisock=so._socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {
 		RETURN(818);
@@ -144,19 +144,19 @@ void * dnsprchild(struct clientparam* param) {
 	}
 	param->sins.sin_addr.s_addr = nservers[0];
 	param->sins.sin_port = htons(53);
-	if(socksendto(param->remsock, &param->sins, buf, i, conf.timeouts[SINGLEBYTE_L]*1000) != i){
+	if(socksendto(param->remsock, (struct sockaddr *)&param->sins, buf, i, conf.timeouts[SINGLEBYTE_L]*1000) != i){
 		RETURN(820);
 	}
 	param->statscli64 += i;
 	param->nwrites++;
-	len = sockrecvfrom(param->remsock, &param->sins, buf, BUFSIZE, 15000);
+	len = sockrecvfrom(param->remsock, (struct sockaddr *)&param->sins, buf, BUFSIZE, 15000);
 	if(len <= 13) {
 		RETURN(821);
 	}
 	param->statssrv64 += len;
 	param->nreads++;
 	if(buf[6] || buf[7]){
-		if(socksendto(param->clisock, &param->sinc, buf, len, conf.timeouts[SINGLEBYTE_L]*1000) != len){
+		if(socksendto(param->clisock, (struct sockaddr *)&param->sincr, buf, len, conf.timeouts[SINGLEBYTE_L]*1000) != len){
 			RETURN(822);
 		}
 		RETURN(0);
@@ -168,7 +168,7 @@ void * dnsprchild(struct clientparam* param) {
 	buf[3] = 0x83;
  }
  usleep(SLEEPTIME);
- res = socksendto(param->clisock, &param->sinc, buf, len, conf.timeouts[SINGLEBYTE_L]*1000); 
+ res = socksendto(param->clisock, (struct sockaddr *)&param->sincr, buf, len, conf.timeouts[SINGLEBYTE_L]*1000); 
  if(res != len){RETURN(819);}
  if(!ip) {RETURN(888);}
 

+ 27 - 24
src/ftppr.c

@@ -119,32 +119,35 @@ void * ftpprchild(struct clientparam* param) {
 			so._closesocket(clidatasock);
 			clidatasock = INVALID_SOCKET;
 		}
-		if ((clidatasock=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {RETURN(821);}
-		sasize = sizeof(struct sockaddr_in);
-		if(so._getsockname(param->ctrlsock, (struct sockaddr *)&param->sinc, &sasize)){RETURN(824);}
-		param->sinc.sin_port = 0;
-		if(so._bind(clidatasock, (struct sockaddr *)&param->sinc, sasize)){RETURN(822);}
+		if ((clidatasock=socket(SASOCK(&param->sincl), SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {RETURN(821);}
+		sasize = sizeof(param->sincl);
+		*SAPORT(&param->sincl) = 0;
+		if(so._bind(clidatasock, (struct sockaddr *)&param->sincl, sasize)){RETURN(822);}
 		if (pasv) {
 			if(so._listen(clidatasock, 1)) {RETURN(823);}
-			if(so._getsockname(clidatasock, (struct sockaddr *)&param->sinc, &sasize)){RETURN(824);}
-			sprintf((char *)buf, "227 OK (%u,%u,%u,%u,%u,%u)\r\n",
-				 (unsigned)(((unsigned char *)(&param->sinc.sin_addr.s_addr))[0]),
-				 (unsigned)(((unsigned char *)(&param->sinc.sin_addr.s_addr))[1]),
-				 (unsigned)(((unsigned char *)(&param->sinc.sin_addr.s_addr))[2]),
-				 (unsigned)(((unsigned char *)(&param->sinc.sin_addr.s_addr))[3]),
-				 (unsigned)(((unsigned char *)(&param->sinc.sin_port))[0]),
-				 (unsigned)(((unsigned char *)(&param->sinc.sin_port))[1])
-				);
+			if(so._getsockname(clidatasock, (struct sockaddr *)&param->sincl, &sasize)){RETURN(824);}
+			if(*SAFAMILY(&param->sincl) == AF_INET)
+				sprintf((char *)buf, "227 OK (%u,%u,%u,%u,%u,%u)\r\n",
+					 (unsigned)(((unsigned char *)(SAADDR(&param->sincl)))[0]),
+					 (unsigned)(((unsigned char *)(SAADDR(&param->sincl)))[1]),
+					 (unsigned)(((unsigned char *)(SAADDR(&param->sincl)))[2]),
+					 (unsigned)(((unsigned char *)(SAADDR(&param->sincl)))[3]),
+					 (unsigned)(((unsigned char *)(SAPORT(&param->sincl)))[3]),
+					 (unsigned)(((unsigned char *)(SAPORT(&param->sincl)))[3])
+					);
+			else sprintf((char *)buf, "227 OK (127,0,0,1,%u,%u)\r\n", 
+					 (unsigned)(((unsigned char *)(SAPORT(&param->sincl)))[3]),
+					 (unsigned)(((unsigned char *)(SAPORT(&param->sincl)))[3])
+					);			
 		}
 		else {
 			unsigned long b1, b2, b3, b4;
 			unsigned short b5, b6;
 
 			if(sscanf((char *)buf+5, "%lu,%lu,%lu,%lu,%hu,%hu", &b1, &b2, &b3, &b4, &b5, &b6)!=6) {RETURN(828);}
-			param->sinc.sin_family = AF_INET;
-			param->sinc.sin_port = htons((unsigned short)((b5<<8)^b6));
-			param->sinc.sin_addr.s_addr = htonl((b1<<24)^(b2<<16)^(b3<<8)^b4);
-			if(so._connect(clidatasock, (struct sockaddr *)&param->sinc, sasize)) {
+			*SAPORT(&param->sincr) = htons((unsigned short)((b5<<8)^b6));
+			sasize = sizeof(param->sincr);
+			if(so._connect(clidatasock, (struct sockaddr *)&param->sincr, sasize)) {
 				so._closesocket(clidatasock);
 				clidatasock = INVALID_SOCKET;
 				RETURN(826);
@@ -203,8 +206,8 @@ void * ftpprchild(struct clientparam* param) {
 			if(res != 1) {
 				RETURN(857);
 			}
-			sasize = sizeof(struct sockaddr_in);
-			ss = so._accept(clidatasock, (struct sockaddr *)&param->sinc, &sasize);
+			sasize = sizeof(param->sincr);
+			ss = so._accept(clidatasock, (struct sockaddr *)&param->sincr, &sasize);
 			if (ss == INVALID_SOCKET) { RETURN (858);}
 			so._shutdown(clidatasock, SHUT_RDWR);
 			so._closesocket(clidatasock);
@@ -283,8 +286,8 @@ void * ftpprchild(struct clientparam* param) {
 		if(status == 5) {RETURN (0);}
 		if(i < 3) {RETURN (813);}
 	}
-	sasize = sizeof(struct sockaddr_in);
-	if(so._getpeername(param->ctrlsock, (struct sockaddr *)&param->sinc, &sasize)){RETURN(819);}
+	sasize = sizeof(param->sincr);
+	if(so._getpeername(param->ctrlsock, (struct sockaddr *)&param->sincr, &sasize)){RETURN(819);}
 	if(req && (param->statscli64 || param->statssrv64)){
 		(*param->srv->logfunc)(param, (unsigned char *)req);
 	}
@@ -304,8 +307,8 @@ CLEANRET:
 	so._shutdown(clidatasock, SHUT_RDWR);
 	so._closesocket(clidatasock);
  }
- sasize = sizeof(struct sockaddr_in);
- so._getpeername(param->ctrlsock, (struct sockaddr *)&param->sinc, &sasize);
+ sasize = sizeof(param->sincr);
+ so._getpeername(param->ctrlsock, (struct sockaddr *)&param->sincr, &sasize);
  if(param->res != 0 || param->statscli64 || param->statssrv64 ){
 	(*param->srv->logfunc)(param, (unsigned char *)((req && (param->res > 802))? req:NULL));
  }

+ 1 - 1
src/icqpr.c

@@ -105,7 +105,7 @@ static void addbuffer(int increment, struct clientparam * param, unsigned char *
 		*buf_p = newbuf;
 		*bufsize_p = bufsize;
 	}
-	if(increment) len = sockrecvfrom(param->remsock, &param->sins, *buf_p + *length_p, increment, conf.timeouts[STRING_S]*1000);
+	if(increment) len = sockrecvfrom(param->remsock, (struct sockaddr *)&param->sins, *buf_p + *length_p, increment, conf.timeouts[STRING_S]*1000);
 	if(len > 0) {
 		*length_p += len;
 		param->nreads++;

+ 3 - 5
src/proxy.c

@@ -831,14 +831,12 @@ for(;;){
 		sprintf((char*)buf+strlen((char *)buf), "Via: 1.1 ");
 		gethostname((char *)(buf+strlen((char *)buf)), 256);
 		sprintf((char*)buf+strlen((char *)buf), ":%d (%s %s)\r\nX-Forwarded-For: ", (int)ntohs(*SAPORT(&param->srv->intsa)), conf.stringtable?conf.stringtable[2]:(unsigned char *)"", conf.stringtable?conf.stringtable[3]:(unsigned char *)"");
-		if(!anonymous)myinet_ntop(*SAFAMILY(&param->sinc), SAADDR(&param->sinc), (char *)buf + strlen((char *)buf), 64);
+		if(!anonymous)myinet_ntop(*SAFAMILY(&param->sincr), SAADDR(&param->sincr), (char *)buf + strlen((char *)buf), 64);
 		else {
 			unsigned long tmp;
 
-			tmp = param->sinc.sin_addr.s_addr;
-			param->sinc.sin_addr.s_addr = ((unsigned long)myrand(param, sizeof(struct clientparam))<<16)^(unsigned long)rand();
-			myinet_ntop(*SAFAMILY(&param->sinc), SAADDR(&param->sinc), (char *)buf + strlen((char *)buf), 64);
-			param->sinc.sin_addr.s_addr = tmp;
+			tmp = ((unsigned long)myrand(param, sizeof(struct clientparam))<<16)^(unsigned long)rand();
+			myinet_ntop(AF_INET, &tmp, (char *)buf + strlen((char *)buf), 64);
 		}
 		sprintf((char*)buf+strlen((char *)buf), "\r\n");
  }

+ 2 - 2
src/proxy.h

@@ -148,8 +148,8 @@ extern struct extparam conf;
 
 int sockmap(struct clientparam * param, int timeo);
 int socksend(SOCKET sock, unsigned char * buf, int bufsize, int to);
-int socksendto(SOCKET sock, struct sockaddr_in * sin, unsigned char * buf, int bufsize, int to);
-int sockrecvfrom(SOCKET sock, struct sockaddr_in * sin, unsigned char * buf, int bufsize, int to);
+int socksendto(SOCKET sock, struct sockaddr * sin, unsigned char * buf, int bufsize, int to);
+int sockrecvfrom(SOCKET sock, struct sockaddr * sin, unsigned char * buf, int bufsize, int to);
 
 
 int sockgetcharcli(struct clientparam * param, int timeosec, int timeousec);

+ 20 - 12
src/proxymain.c

@@ -190,9 +190,9 @@ int MODULEMAINFUNC (int argc, char** argv){
 #ifdef STDMAIN
 #ifndef _WIN32
 		 case 'I':
-			size = sizeof(defparam.sinc);
-			if(so._getsockname(0, (struct sockaddr*)&defparam.sinc, &size) ||
-				defparam.sinc.sin_family != AF_INET) error = 1;
+			size = sizeof(defparam.sincl);
+			if(so._getsockname(0, (struct sockaddr*)&defparam.sincl, &size) ||
+				defparam.sincl.sin_family != AF_INET) error = 1;
 
 			else inetd = 1;
 			break;
@@ -311,8 +311,8 @@ int MODULEMAINFUNC (int argc, char** argv){
 
  
  srvinit2(&srv, &defparam);
+ if(!*SAFAMILY(&srv.intsa)) *SAFAMILY(&srv.intsa) = AF_INET;
  if(!*SAPORT(&srv.intsa)) *SAPORT(&srv.intsa) = htons(childdef.port);
- if(!defparam.sinc.sin_port) defparam.sinc.sin_port = htons(childdef.port);
  if(hostname)parsehostname(hostname, &defparam, childdef.port);
 
 
@@ -374,9 +374,11 @@ int MODULEMAINFUNC (int argc, char** argv){
 	sprintf((char *)buf, "Accepting connections [%u/%u]", (unsigned)getpid(), (unsigned)pthread_self());
 	(*srv.logfunc)(&defparam, buf);
  }
- memset(&defparam.sinc, 0, sizeof(defparam.sinc));
+ memset(&defparam.sincr, 0, sizeof(defparam.sincr));
+ memset(&defparam.sincl, 0, sizeof(defparam.sincl));
  memset(&defparam.sins, 0, sizeof(defparam.sins));
- *SAFAMILY(&defparam.sinc) = AF_INET;
+ *SAFAMILY(&defparam.sincr) = AF_INET;
+ *SAFAMILY(&defparam.sincl) = AF_INET;
  *SAFAMILY(&defparam.sins) = AF_INET;
 
  srv.fds.fd = sock;
@@ -413,13 +415,19 @@ int MODULEMAINFUNC (int argc, char** argv){
 	}
 	if((conf.paused != srv.version) || (error < 0)) break;
 	if(!isudp){
-		size = sizeof(defparam.sinc);
-		new_sock = so._accept(sock, (struct sockaddr*)&defparam.sinc, &size);
+		size = sizeof(defparam.sincr);
+		new_sock = so._accept(sock, (struct sockaddr*)&defparam.sincr, &size);
 		if(new_sock == INVALID_SOCKET){
 			sprintf((char *)buf, "accept(): %s", strerror(errno));
 			if(!srv.silent)(*srv.logfunc)(&defparam, buf);
 			continue;
 		}
+		size = sizeof(defparam.sincl);
+		if(so._getsockname(new_sock, (struct sockaddr *)&defparam.sincl, &size)){
+			sprintf((char *)buf, "getsockname(): %s", strerror(errno));
+			if(!srv.silent)(*srv.logfunc)(&defparam, buf);
+			continue;
+		}
 #ifdef _WIN32
 		ioctlsocket(new_sock, FIONBIO, &ul);
 #else
@@ -482,7 +490,8 @@ int MODULEMAINFUNC (int argc, char** argv){
 	}
 #endif
 	pthread_mutex_unlock(&srv.counter_mutex);
-	memset(&defparam.sinc, 0, sizeof(defparam.sinc));
+	memset(&defparam.sincl, 0, sizeof(defparam.sincl));
+	memset(&defparam.sincr, 0, sizeof(defparam.sincr));
 	if(isudp) while(!srv.fds.events)usleep(SLEEPTIME);
  }
 
@@ -519,7 +528,7 @@ void srvinit(struct srvparam * srv, struct clientparam *param){
  memset(param, 0, sizeof(struct clientparam));
  param->srv = srv;
  param->remsock = param->clisock = param->ctrlsock = param->ctrlsocksrv = INVALID_SOCKET;
- param->req.sin_family = param->sins.sin_family = param->sinc.sin_family = AF_INET;
+ *SAFAMILY(&param->req) = *SAFAMILY(&param->sins) = *SAFAMILY(&param->sincr) = *SAFAMILY(&param->sincl) = AF_INET;
  pthread_mutex_init(&srv->counter_mutex, NULL);
  memcpy(&srv->intsa, &conf.intsa, sizeof(srv->intsa));
 }
@@ -538,8 +547,7 @@ void srvinit2(struct srvparam * srv, struct clientparam *param){
  }
  if(srv->logtarget) srv->logtarget = (unsigned char *)mystrdup((char *)srv->logtarget);
  if(!*SAFAMILY(&srv->intsa)) *SAFAMILY(&srv->intsa) = AF_INET;
- param->sinc.sin_addr.s_addr = ((struct sockaddr_in *)&srv->intsa)->sin_addr.s_addr;
- param->sinc.sin_port = *SAPORT(&srv->intsa);
+ memcpy(&param->sincr, &srv->intsa, sizeof(param->sincr));
  if(!srv->extip) srv->extip = conf.extip;
  param->sins.sin_addr.s_addr = param->extip = srv->extip;
  if(!srv->extport) srv->extport = htons(conf.extport);

+ 1 - 1
src/smtpp.c

@@ -83,7 +83,7 @@ int readdata (struct clientparam* param) {
 		return -1;
 	}
 #endif
-	socksendto(param->remsock, &param->sins, buf, i, conf.timeouts[STRING_S]);	
+	socksendto(param->remsock, (struct sockaddr *)&param->sins, buf, i, conf.timeouts[STRING_S]);	
  } 
  if(i < 1) {
 	myfree(buf);

+ 8 - 8
src/sockgetchar.c

@@ -33,7 +33,7 @@ int socksend(SOCKET sock, unsigned char * buf, int bufsize, int to){
 }
 
 
-int socksendto(SOCKET sock, struct sockaddr_in * sin, unsigned char * buf, int bufsize, int to){
+int socksendto(SOCKET sock, struct sockaddr * sin, unsigned char * buf, int bufsize, int to){
  int sent = 0;
  int res;
  struct pollfd fds;
@@ -45,7 +45,7 @@ int socksendto(SOCKET sock, struct sockaddr_in * sin, unsigned char * buf, int b
  	res = so._poll(&fds, 1, to);
 	if(res < 0 && (errno == EAGAIN || errno == EINTR)) continue;
 	if(res < 1) break;
-	res = so._sendto(sock, buf + sent, bufsize - sent, 0,  (struct sockaddr *)sin, sizeof(struct sockaddr_in));
+	res = so._sendto(sock, buf + sent, bufsize - sent, 0, sin, SASIZE(sin));
 	if(res < 0) {
 		if(errno !=  EAGAIN) break;
 		continue;
@@ -55,7 +55,7 @@ int socksendto(SOCKET sock, struct sockaddr_in * sin, unsigned char * buf, int b
  return sent;
 }
 
-int sockrecvfrom(SOCKET sock, struct sockaddr_in * sin, unsigned char * buf, int bufsize, int to){
+int sockrecvfrom(SOCKET sock, struct sockaddr * sin, unsigned char * buf, int bufsize, int to){
 	struct pollfd fds;
 	SASIZETYPE sasize;
 	int res;
@@ -64,7 +64,7 @@ int sockrecvfrom(SOCKET sock, struct sockaddr_in * sin, unsigned char * buf, int
 	fds.events = POLLIN;
 	if(conf.timetoexit) return EOF;
 	if (so._poll(&fds, 1, to)<1) return 0;
-	sasize = sizeof(struct sockaddr_in);
+	sasize = SASIZE(sin);
 	do {
 		res = so._recvfrom(sock, buf, bufsize, 0, (struct sockaddr *)sin, &sasize);
 	} while (res < 0 && (errno == EAGAIN || errno == EINTR));
@@ -83,7 +83,7 @@ int sockgetcharcli(struct clientparam * param, int timeosec, int timeousec){
 		return (int)param->clibuf[param->clioffset++];
 	}
 	param->clioffset = param->cliinbuf = 0;
-	if ((len = sockrecvfrom(param->clisock, &param->sinc, param->clibuf, param->clibufsize, timeosec*1000 + timeousec))<=0) return EOF;
+	if ((len = sockrecvfrom(param->clisock, (struct sockaddr *)&param->sincr, param->clibuf, param->clibufsize, timeosec*1000 + timeousec))<=0) return EOF;
 	param->cliinbuf = len;
 	param->clioffset = 1;
 	return (int)*param->clibuf;
@@ -103,7 +103,7 @@ int sockfillbuffcli(struct clientparam * param, unsigned long size, int timeosec
 	}
 	if(size <= param->cliinbuf) return size;
 	size -= param->cliinbuf;
-	if((len = sockrecvfrom(param->clisock, &param->sinc, param->clibuf + param->cliinbuf, (param->clibufsize - param->cliinbuf) < size? param->clibufsize - param->cliinbuf:size, timeosec*1000)) > 0){
+	if((len = sockrecvfrom(param->clisock, (struct sockaddr *)&param->sincr, param->clibuf + param->cliinbuf, (param->clibufsize - param->cliinbuf) < size? param->clibufsize - param->cliinbuf:size, timeosec*1000)) > 0){
 		param->cliinbuf += len;
 	}
 	return param->cliinbuf;
@@ -123,7 +123,7 @@ int sockfillbuffsrv(struct clientparam * param, unsigned long size, int timeosec
 	}
 	if(size <= param->srvinbuf) return size;
 	size -= param->srvinbuf;
-	if((len = sockrecvfrom(param->remsock, &param->sinc, param->srvbuf + param->srvinbuf, (param->srvbufsize - param->srvinbuf) < size? param->srvbufsize - param->srvinbuf:size, timeosec*1000)) > 0){
+	if((len = sockrecvfrom(param->remsock, (struct sockaddr *)&param->sins, param->srvbuf + param->srvinbuf, (param->srvbufsize - param->srvinbuf) < size? param->srvbufsize - param->srvinbuf:size, timeosec*1000)) > 0){
 		param->srvinbuf += len;
 		param->nreads++;
 		param->statssrv64 += len;
@@ -148,7 +148,7 @@ int sockgetcharsrv(struct clientparam * param, int timeosec, int timeousec){
 		return (int)param->srvbuf[param->srvoffset++];
 	}
 	param->srvoffset = param->srvinbuf = 0;
-	if ((len = sockrecvfrom(param->remsock, &param->sins, param->srvbuf, param->srvbufsize, timeosec*1000 + timeousec))<=0) return EOF;
+	if ((len = sockrecvfrom(param->remsock, (struct sockaddr *)&param->sins, param->srvbuf, param->srvbufsize, timeosec*1000 + timeousec))<=0) return EOF;
 	param->srvinbuf = len;
 	param->srvoffset = 1;
 	param->nreads++;

+ 4 - 4
src/sockmap.c

@@ -128,7 +128,7 @@ int sockmap(struct clientparam * param, int timeo){
 		if(param->bandlimfunc) {
 			sleeptime = (*param->bandlimfunc)(param, param->srvinbuf - param->srvoffset, 0);
 		}
-		res = so._sendto(param->clisock, param->srvbuf + param->srvoffset,(!param->waitserver64 || (param->waitserver64 - received) > (param->srvinbuf - param->srvoffset))? param->srvinbuf - param->srvoffset : (int)(param->waitserver64 - received), 0, (struct sockaddr*)&param->sinc, sasize);
+		res = so._sendto(param->clisock, param->srvbuf + param->srvoffset,(!param->waitserver64 || (param->waitserver64 - received) > (param->srvinbuf - param->srvoffset))? param->srvinbuf - param->srvoffset : (int)(param->waitserver64 - received), 0, (struct sockaddr*)&param->sincr, sasize);
 		if(res < 0) {
 			if(errno != EAGAIN) return 96;
 			continue;
@@ -171,7 +171,7 @@ int sockmap(struct clientparam * param, int timeo){
 #if DEBUGLEVEL > 2
 (*param->srv->logfunc)(param, "recv from client");
 #endif
-		res = so._recvfrom(param->clisock, param->clibuf + param->cliinbuf, param->clibufsize - param->cliinbuf, 0, (struct sockaddr *)&param->sinc, &sasize);
+		res = so._recvfrom(param->clisock, param->clibuf + param->cliinbuf, param->clibufsize - param->cliinbuf, 0, (struct sockaddr *)&param->sincr, &sasize);
 		if (res==0) {
 			so._shutdown(param->clisock, SHUT_RDWR);
 			so._closesocket(param->clisock);
@@ -241,7 +241,7 @@ int sockmap(struct clientparam * param, int timeo){
 #if DEBUGLEVEL > 2
 (*param->srv->logfunc)(param, "flushing buffer to client");
 #endif
-	res = socksendto(param->clisock, &param->sinc, param->srvbuf + param->srvoffset, param->srvinbuf - param->srvoffset, conf.timeouts[STRING_S] * 1000);
+	res = socksendto(param->clisock, (struct sockaddr *)&param->sincr, param->srvbuf + param->srvoffset, param->srvinbuf - param->srvoffset, conf.timeouts[STRING_S] * 1000);
 	if(res > 0){
 		param->srvoffset += res;
 		param->statssrv64 += res;
@@ -253,7 +253,7 @@ int sockmap(struct clientparam * param, int timeo){
 #if DEBUGLEVEL > 2
 (*param->srv->logfunc)(param, "flushing buffer to server");
 #endif
-	res = socksendto(param->remsock, &param->sins, param->clibuf + param->clioffset, param->cliinbuf - param->clioffset, conf.timeouts[STRING_S] * 1000);
+	res = socksendto(param->remsock, (struct sockaddr *)&param->sins, param->clibuf + param->clioffset, param->cliinbuf - param->clioffset, conf.timeouts[STRING_S] * 1000);
 	if(res > 0){
 		param->clioffset += res;
 		param->statscli64 += res;

+ 20 - 18
src/socks.c

@@ -28,7 +28,11 @@ void * sockschild(struct clientparam* param) {
  struct pollfd fds[3];
  int ver=0;
  int havepass = 0;
+#ifndef NOIPV6
+ struct sockaddr_in6 sin;
+#else
  struct sockaddr_in sin;
+#endif
  int len;
 
 
@@ -171,20 +175,18 @@ fprintf(stderr, "%s:%hu binded to communicate with server\n",
 fflush(stderr);
 #endif
 	}
-	sasize = sizeof(struct sockaddr_in);
+	sasize = sizeof(param->sins);
 	so._getsockname(param->remsock, (struct sockaddr *)&param->sins,  &sasize);
 	if(command == 3) {
 		param->ctrlsock = param->clisock;
-		param->clisock = so._socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+		param->clisock = so._socket(SASOCK(&param->sincr), SOCK_DGRAM, IPPROTO_UDP);
 		if(param->clisock == INVALID_SOCKET) {RETURN(11);}
-		sin.sin_family = AF_INET;
-		sin.sin_addr.s_addr = ((struct sockaddr_in *)&param->srv->intsa)->sin_addr.s_addr;
-		sin.sin_port = htons(0);
-		if(so._bind(param->clisock,(struct sockaddr *)&sin,sizeof(struct sockaddr_in))) {RETURN (12);}
+		memcpy(&sin, &param->sincl, sizeof(&sin));
+		*SAPORT(&sin) = htons(0);
+		if(so._bind(param->clisock,(struct sockaddr *)&sin,sizeof(sin))) {RETURN (12);}
 #if SOCKSTRACE > 0
-fprintf(stderr, "%s:%hu binded to communicate with client\n",
-			inet_ntoa(sin.sin_addr),
-			ntohs(sin.sin_port)
+fprintf(stderr, "%hu binded to communicate with client\n",
+			ntohs(*SAPORT(&sin))
 	);
 fflush(stderr);
 #endif
@@ -195,7 +197,7 @@ fflush(stderr);
 CLEANRET:
 
  if(param->clisock != INVALID_SOCKET){
-	sasize = sizeof(struct sockaddr_in);
+	sasize = sizeof(sin);
 	if(command != 3) so._getsockname(param->remsock, (struct sockaddr *)&sin,  &sasize);
 	else so._getsockname(param->clisock, (struct sockaddr *)&sin,  &sasize);
 #if SOCKSTRACE > 0
@@ -212,15 +214,15 @@ fflush(stderr);
 		buf[1] = param->res%10;
 		buf[2] = 0;
 		buf[3] = 1;
-		memcpy(buf+4, &sin.sin_addr.s_addr, 4);
-		memcpy(buf+8, &sin.sin_port, 2);
+		memcpy(buf+4, SAADDR(&sin), 4);
+		memcpy(buf+8, SAPORT(&sin), 2);
 		socksend((command == 3)?param->ctrlsock:param->clisock, buf, 10, conf.timeouts[STRING_S]);
 	}
 	else{
 		buf[0] = 0;
 		buf[1] = 90 + (param->res%10);
-		memcpy(buf+2, &sin.sin_port, 2);
-		memcpy(buf+4, &sin.sin_addr.s_addr, 4);
+		memcpy(buf+2, SAPORT(&sin), 2);
+		memcpy(buf+4, SAADDR(&sin), 4);
 		socksend(param->clisock, buf, 8, conf.timeouts[STRING_S]);
 	}
 
@@ -300,12 +302,12 @@ fflush(stderr);
 						break;
 					}
 					if (fds[1].revents) {
-						sasize = sizeof(struct sockaddr_in);
+						sasize = sizeof(sin);
 						if((len = so._recvfrom(param->clisock, buf, 65535, 0, (struct sockaddr *)&sin, &sasize)) <= 10) {
 							param->res = 464;
 							break;
 						}
-						if(sin.sin_addr.s_addr != param->sinc.sin_addr.s_addr){
+						if(SAADDRLEN(&sin) != SAADDRLEN(&param->sincr) || memcmp(SAADDR(&sin), SAADDR(&param->sincr), SAADDRLEN(&sin))){
 							param->res = 465;
 							break;
 						}
@@ -335,7 +337,7 @@ fflush(stderr);
 
 						sasize = sizeof(param->sins);
 						if(len > (int)i){
-							if(socksendto(param->remsock, &param->sins, buf+i, len - i, conf.timeouts[SINGLEBYTE_L]*1000) <= 0){
+							if(socksendto(param->remsock, (struct sockaddr *)&param->sins, buf+i, len - i, conf.timeouts[SINGLEBYTE_L]*1000) <= 0){
 								param->res = 467;
 								break;
 							}
@@ -371,7 +373,7 @@ fflush(stderr);
 						memcpy(buf+4, &tsin.sin_addr.s_addr, 4);
 						memcpy(buf+8, &tsin.sin_port, 2);
 						sasize = sizeof(param->sins);
-						if(socksendto(param->clisock, &sin, buf, len + 10, conf.timeouts[SINGLEBYTE_L]*1000) <=0){
+						if(socksendto(param->clisock, (struct sockaddr *)&sin, buf, len + 10, conf.timeouts[SINGLEBYTE_L]*1000) <=0){
 							param->res = 469;
 							break;
 						}

+ 10 - 4
src/structures.h

@@ -109,11 +109,13 @@ int
 #define SAADDR(sa)  (((struct sockaddr_in *)sa)->sin_family == AF_INET6? (unsigned char *)((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr : (unsigned char *)&((struct sockaddr_in *)sa)->sin_addr.s_addr)
 #define SAADDRLEN(sa) (((struct sockaddr_in *)sa)->sin_family == AF_INET6? 16:4)
 #define SASOCK(sa) (((struct sockaddr_in *)sa)->sin_family == AF_INET6? PF_INET6:PF_INET)
+#define SASIZE(sa) (((struct sockaddr_in *)sa)->sin_family == AF_INET6? sizeof(struct sockaddr_in6):sizeof(struct sockaddr_in))
 #else
 #define SAPORT(sa)  (&((struct sockaddr_in *)sa)->sin_port)
 #define SAADDR(sa)  ((unsigned char *)&((struct sockaddr_in *)sa)->sin_addr.a_addr)
 #define SAADDRLEN(sa) (4)
 #define SASOCK(sa) (PF_INET)
+#define SASIZE(sa) (sizeof(struct sockaddr_in))
 #endif
 
 typedef enum {
@@ -431,8 +433,12 @@ struct clientparam {
 	uint64_t
 			maxtrafin64,
 			maxtrafout64;
-	struct sockaddr_in	sinc,
-				sins,
+#ifndef NOIPV6
+	struct sockaddr_in6	sincl, sincr;
+#else
+	struct sockaddr_in	sincl, sincr;
+#endif
+	struct sockaddr_in	sins,
 				req;
 
 	uint64_t	statscli64,
@@ -620,8 +626,8 @@ struct pluginlink {
 	struct commands * commandhandlers;
 	void * (*findbyname)(const char *name);
 	int (*socksend)(SOCKET sock, unsigned char * buf, int bufsize, int to);
-	int (*socksendto)(SOCKET sock, struct sockaddr_in * sin, unsigned char * buf, int bufsize, int to);
-	int (*sockrecvfrom)(SOCKET sock, struct sockaddr_in * sin, unsigned char * buf, int bufsize, int to);
+	int (*socksendto)(SOCKET sock, struct sockaddr * sin, unsigned char * buf, int bufsize, int to);
+	int (*sockrecvfrom)(SOCKET sock, struct sockaddr * sin, unsigned char * buf, int bufsize, int to);
 	int (*sockgetcharcli)(struct clientparam * param, int timeosec, int timeousec);
 	int (*sockgetcharsrv)(struct clientparam * param, int timeosec, int timeousec);
 	int (*sockgetlinebuf)(struct clientparam * param, DIRECTION which, unsigned char * buf, int bufsize, int delim, int to);

+ 3 - 3
src/udppm.c

@@ -49,7 +49,7 @@ void * udppmchild(struct clientparam* param) {
 	RETURN (21);
  }
  param->cliinbuf = param->clioffset = 0;
- i = sockrecvfrom(param->srv->srvsock, &param->sinc, param->clibuf, param->clibufsize, 0);
+ i = sockrecvfrom(param->srv->srvsock, (struct sockaddr *)&param->sincr, param->clibuf, param->clibufsize, 0);
  if(i<=0){
 	param->srv->fds.events = POLLIN;
 	RETURN (214);
@@ -57,12 +57,12 @@ void * udppmchild(struct clientparam* param) {
  param->cliinbuf = i;
 
 #ifdef _WIN32
-	if((param->clisock=so._socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {
+	if((param->clisock=so._socket(*SAFAMILY(&param->sincr), SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {
 		RETURN(818);
 	}
 	if(so._setsockopt(param->clisock, SOL_SOCKET, SO_REUSEADDR, (unsigned char *)&ul, sizeof(int))) {RETURN(820);};
 	ioctlsocket(param->clisock, FIONBIO, &ul);
-	size = sizeof(struct sockaddr_in);
+	size = sizeof(param->sins);
 	if(so._getsockname(param->srv->srvsock, (struct sockaddr *)&param->sins, &size)) {RETURN(21);};
 	if(so._bind(param->clisock,(struct sockaddr *)&param->sins,sizeof(struct sockaddr_in))) {
 		RETURN(822);