Преглед изворни кода

Connect back proxy functionality added

-r and -R options added to support connect back functionality between
two instances of proxy
z3APA3A пре 10 година
родитељ
комит
a2b5af6dab
5 измењених фајлова са 182 додато и 67 уклоњено
  1. 18 0
      src/common.c
  2. 2 0
      src/proxy.h
  3. 158 63
      src/proxymain.c
  4. 3 3
      src/structures.h
  5. 1 1
      src/version.h

+ 18 - 0
src/common.c

@@ -216,6 +216,24 @@ int ceparseargs(const char *str){
 
 
 #endif
 #endif
 
 
+void parsehost(int family, char *host, struct sockaddr *sa){
+	char *sp=NULL,*se=NULL;
+	unsigned short port;
+
+	if(*host == '[') se=strchr(host, ']');
+	if ( (sp = strchr(se?se:host, ':')) ) *sp = 0;
+	if(se){
+		*se = 0;
+	}
+	if(sp){
+		port = atoi(sp+1);
+	}
+	getip46(family, host + (se!=0), (struct sockaddr *)sa);
+	if(se) *se = ']';
+	if(sp) *sp = ':';
+	*SAPORT(sa) = htons(port);
+}
+
 int parsehostname(char *hostname, struct clientparam *param, unsigned short port){
 int parsehostname(char *hostname, struct clientparam *param, unsigned short port){
 	char *sp=NULL,*se=NULL;
 	char *sp=NULL,*se=NULL;
 
 

+ 2 - 0
src/proxy.h

@@ -235,10 +235,12 @@ void mschap(const unsigned char *win_password,
 struct hashtable;
 struct hashtable;
 void hashadd(struct hashtable *ht, const unsigned char* name, unsigned char* value, time_t expires);
 void hashadd(struct hashtable *ht, const unsigned char* name, unsigned char* value, time_t expires);
 
 
+void parsehost(int family, char *host, struct sockaddr *sa);
 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);
+int checkACL(struct clientparam * param);
 
 
 unsigned long udpresolve(int af, unsigned char * name, unsigned char * value, 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);
 
 

+ 158 - 63
src/proxymain.c

@@ -9,8 +9,46 @@
 #include "proxy.h"
 #include "proxy.h"
 
 
 
 
-
-
+#define param ((struct clientparam *) p)
+#ifdef _WIN32
+DWORD WINAPI threadfunc(LPVOID p) {
+#else
+void * threadfunc (void *p) {
+#endif
+ if(param->srv->cbsock != INVALID_SOCKET){
+	SASIZETYPE size = sizeof(param->sinsr);
+	param->remsock = so._accept(param->srv->cbsock, (struct sockaddr*)&param->sinsr, &size);
+	if(param->remsock == INVALID_SOCKET) {
+		param->res = 13;
+		param->srv->logfunc(param, "Connect back accept() failed");
+#ifdef _WIN32
+ return 0;
+#else
+ return NULL;
+#endif
+	}
+#ifndef WITHMAIN
+	memcpy(&param->req, &param->sinsr, size);
+	if(param->srv->acl) param->res = checkACL(param);
+	if(param->res){
+		param->srv->logfunc(param, "Connect back ACL failed");
+	}
+#ifdef _WIN32
+ return 0;
+#else
+ return NULL;
+#endif
+#endif
+	
+ }
+ ((struct clientparam *) p)->srv->pf((struct clientparam *)p);
+#ifdef _WIN32
+ return 0;
+#else
+ return NULL;
+#endif
+}
+#undef param
 
 
 
 
 
 
@@ -42,7 +80,7 @@ int MODULEMAINFUNC (int argc, char** argv){
 
 
 
 
 
 
- SOCKET sock = INVALID_SOCKET;
+ SOCKET sock = INVALID_SOCKET, new_sock = INVALID_SOCKET;
  int i=0;
  int i=0;
  SASIZETYPE size;
  SASIZETYPE size;
  pthread_t thread;
  pthread_t thread;
@@ -53,8 +91,15 @@ int MODULEMAINFUNC (int argc, char** argv){
  unsigned sleeptime;
  unsigned sleeptime;
  unsigned char buf[256];
  unsigned char buf[256];
  char *hostname=NULL;
  char *hostname=NULL;
- int opt = 1, isudp;
+ int opt = 1, isudp = 0, iscbl = 0, iscbc = 0;
+ unsigned char *cbc_string = NULL, *cbl_string = NULL;
+#ifndef NOIPV6
+ struct sockaddr_in6 cbsa;
+#else
+ struct sockaddr_in cbsa;
+#endif
  FILE *fp = NULL;
  FILE *fp = NULL;
+ struct linger lg;
  int nlog = 5000;
  int nlog = 5000;
  char loghelp[] =
  char loghelp[] =
 #ifdef STDMAIN
 #ifdef STDMAIN
@@ -73,6 +118,8 @@ int MODULEMAINFUNC (int argc, char** argv){
 	" -t be silent (do not log service start/stop)\n"
 	" -t be silent (do not log service start/stop)\n"
 	" -iIP ip address or internal interface (clients are expected to connect)\n"
 	" -iIP ip address or internal interface (clients are expected to connect)\n"
 	" -eIP ip address or external interface (outgoing connection will have this)\n"
 	" -eIP ip address or external interface (outgoing connection will have this)\n"
+	" -rIP:PORT Use IP:port for connect back proxy instead of listen port\n"
+	" -RPORT Use PORT to listen connect back proxy connection to pass data to\n"
 	" -4 Use IPv4 for outgoing connections\n"
 	" -4 Use IPv4 for outgoing connections\n"
 	" -6 Use IPv6 for outgoing connections\n"
 	" -6 Use IPv6 for outgoing connections\n"
 	" -46 Prefer IPv4 for outgoing connections, use both IPv4 and IPv6\n"
 	" -46 Prefer IPv4 for outgoing connections, use both IPv4 and IPv6\n"
@@ -85,8 +132,6 @@ int MODULEMAINFUNC (int argc, char** argv){
  int inetd = 0;
  int inetd = 0;
 #endif
 #endif
 #endif
 #endif
- SOCKET new_sock = INVALID_SOCKET;
- struct linger lg;
 #ifdef _WIN32
 #ifdef _WIN32
  HANDLE h;
  HANDLE h;
 #endif
 #endif
@@ -222,6 +267,14 @@ int MODULEMAINFUNC (int argc, char** argv){
 		 case 'h':
 		 case 'h':
 			hostname = argv[i] + 2;
 			hostname = argv[i] + 2;
 			break;
 			break;
+		 case 'r':
+			cbc_string = mystrdup(argv[i] + 2);
+			iscbc = 1;
+			break;
+		 case 'R':
+			cbl_string = mystrdup(argv[i] + 2);
+			iscbl = 1;
+			break;
 		 case 'u':
 		 case 'u':
 			srv.nouser = 1;
 			srv.nouser = 1;
 			break;
 			break;
@@ -255,6 +308,8 @@ int MODULEMAINFUNC (int argc, char** argv){
 			"Available options are:\n"
 			"Available options are:\n"
 			"%s"
 			"%s"
 			" -pPORT - service port to accept connections\n"
 			" -pPORT - service port to accept connections\n"
+			" -RIP:PORT - connect back IP:PORT to listen and accept connections\n"
+			" -rIP:PORT - connect back IP:PORT to establish connect back connection\n"
 			"%s"
 			"%s"
 			"\tExample: %s -i127.0.0.1\n\n"
 			"\tExample: %s -i127.0.0.1\n\n"
 			"%s", 
 			"%s", 
@@ -284,6 +339,8 @@ int MODULEMAINFUNC (int argc, char** argv){
 			" [-e<external_ip>] <port_to_bind>"
 			" [-e<external_ip>] <port_to_bind>"
 			" <target_hostname> <target_port>\n"
 			" <target_hostname> <target_port>\n"
 			"Available options are:\n"
 			"Available options are:\n"
+			" -RIP:PORT - connect back IP:PORT to listen and accept connections\n"
+			" -rIP:PORT - connect back IP:PORT to establish connect back connection\n"
 			"%s"
 			"%s"
 			"%s"
 			"%s"
 			"\tExample: %s -d -i127.0.0.1 6666 serv.somehost.ru 6666\n\n"
 			"\tExample: %s -d -i127.0.0.1 6666 serv.somehost.ru 6666\n\n"
@@ -343,56 +400,7 @@ int MODULEMAINFUNC (int argc, char** argv){
 
 
 #endif
 #endif
 
 
- if(srv.srvsock == INVALID_SOCKET){
-
-	if(!isudp){
-		lg.l_onoff = 1;
-		lg.l_linger = conf.timeouts[STRING_L];
-		sock=so._socket(SASOCK(&srv.intsa), SOCK_STREAM, IPPROTO_TCP);
-	}
-	else {
-		sock=so._socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
-	}
-	if( sock == INVALID_SOCKET) {
-		perror("socket()");
-		return -2;
-	}
-#ifdef _WIN32
-	ioctlsocket(sock, FIONBIO, &ul);
-#else
-	fcntl(sock,F_SETFL,O_NONBLOCK);
-#endif
-	srv.srvsock = sock;
-	if(so._setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (unsigned char *)&opt, sizeof(int)))perror("setsockopt()");
-#ifdef SO_REUSEPORT
-	so._setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (unsigned char *)&opt, sizeof(int));
-#endif
- }
 
 
- size = sizeof(srv.intsa);
- for(sleeptime = SLEEPTIME * 100; so._bind(sock, (struct sockaddr*)&srv.intsa, size)==-1; usleep(sleeptime)) {
-	sprintf((char *)buf, "bind(): %s", strerror(errno));
-	if(!srv.silent)(*srv.logfunc)(&defparam, buf);	
-	sleeptime = (sleeptime<<1);	
-	if(!sleeptime) {
-		so._closesocket(sock);
-		return -3;
-	}
- }
- if(!isudp){
- 	if(so._listen (sock, 1 + (srv.maxchild>>4))==-1) {
-		sprintf((char *)buf, "listen(): %s", strerror(errno));
-		if(!srv.silent)(*srv.logfunc)(&defparam, buf);
-		return -4;
-	}
- }
- else 
-	 defparam.clisock = sock;
-
- if(!srv.silent){
-	sprintf((char *)buf, "Accepting connections [%u/%u]", (unsigned)getpid(), (unsigned)pthread_self());
-	(*srv.logfunc)(&defparam, buf);
- }
  memset(&defparam.sincr, 0, sizeof(defparam.sincr));
  memset(&defparam.sincr, 0, sizeof(defparam.sincr));
  memset(&defparam.sincl, 0, sizeof(defparam.sincl));
  memset(&defparam.sincl, 0, sizeof(defparam.sincl));
  memset(&defparam.sinsl, 0, sizeof(defparam.sinsl));
  memset(&defparam.sinsl, 0, sizeof(defparam.sinsl));
@@ -404,6 +412,76 @@ int MODULEMAINFUNC (int argc, char** argv){
  *SAFAMILY(&defparam.sinsr) = AF_INET;
  *SAFAMILY(&defparam.sinsr) = AF_INET;
  *SAFAMILY(&defparam.req) = AF_INET;
  *SAFAMILY(&defparam.req) = AF_INET;
 
 
+ if (!iscbc) {
+	if(srv.srvsock == INVALID_SOCKET){
+
+		if(!isudp){
+			lg.l_onoff = 1;
+			lg.l_linger = conf.timeouts[STRING_L];
+			sock=so._socket(SASOCK(&srv.intsa), SOCK_STREAM, IPPROTO_TCP);
+		}
+		else {
+			sock=so._socket(SASOCK(&srv.intsa), SOCK_DGRAM, IPPROTO_UDP);
+		}
+		if( sock == INVALID_SOCKET) {
+			perror("socket()");
+			return -2;
+		}
+#ifdef _WIN32
+		ioctlsocket(sock, FIONBIO, &ul);
+#else
+		fcntl(sock,F_SETFL,O_NONBLOCK);
+#endif
+		srv.srvsock = sock;
+		if(so._setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (unsigned char *)&opt, sizeof(int)))perror("setsockopt()");
+#ifdef SO_REUSEPORT
+		so._setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (unsigned char *)&opt, sizeof(int));
+#endif
+	}
+	size = sizeof(srv.intsa);
+	for(sleeptime = SLEEPTIME * 100; so._bind(sock, (struct sockaddr*)&srv.intsa, size)==-1; usleep(sleeptime)) {
+		sprintf((char *)buf, "bind(): %s", strerror(errno));
+		if(!srv.silent)(*srv.logfunc)(&defparam, buf);	
+		sleeptime = (sleeptime<<1);	
+		if(!sleeptime) {
+			so._closesocket(sock);
+			return -3;
+		}
+	}
+ 	if(!isudp){
+ 		if(so._listen (sock, 1 + (srv.maxchild>>4))==-1) {
+			sprintf((char *)buf, "listen(): %s", strerror(errno));
+			if(!srv.silent)(*srv.logfunc)(&defparam, buf);
+			return -4;
+		}
+	}
+	else 
+		defparam.clisock = sock;
+
+	if(!srv.silent && !iscbc){
+		sprintf((char *)buf, "Accepting connections [%u/%u]", (unsigned)getpid(), (unsigned)pthread_self());
+		(*srv.logfunc)(&defparam, buf);
+	}
+ }
+ else {
+	parsehost(srv.family, cbc_string, (struct sockaddr *)&defparam.sincr);
+ }
+ if(iscbl){
+	parsehost(srv.family, cbl_string, (struct sockaddr *)&cbsa);
+	if((srv.cbsock=so._socket(SASOCK(&cbsa), SOCK_STREAM, IPPROTO_TCP))==INVALID_SOCKET) {
+		(*srv.logfunc)(&defparam, "Failed to allocate connect back socket");
+		return -6;
+	}
+	if(so._bind(srv.cbsock, (struct sockaddr*)&cbsa, sizeof(cbsa))==-1) {
+		(*srv.logfunc)(&defparam, "Failed to bind connect back socket");
+		return -7;
+	}
+	if(so._listen(srv.cbsock, 1 + (srv.maxchild>>4))==-1) {
+		(*srv.logfunc)(&defparam, "Failed to listen connect back socket");
+		return -8;
+	}
+ }
+
  srv.fds.fd = sock;
  srv.fds.fd = sock;
  srv.fds.events = POLLIN;
  srv.fds.events = POLLIN;
  
  
@@ -419,6 +497,7 @@ int MODULEMAINFUNC (int argc, char** argv){
 			}
 			}
 			usleep(SLEEPTIME);
 			usleep(SLEEPTIME);
 		}
 		}
+		if (iscbc) break;
 		if (conf.paused != srv.version) break;
 		if (conf.paused != srv.version) break;
 		if (srv.fds.events & POLLIN) {
 		if (srv.fds.events & POLLIN) {
 			error = so._poll(&srv.fds, 1, 1000);
 			error = so._poll(&srv.fds, 1, 1000);
@@ -439,11 +518,23 @@ int MODULEMAINFUNC (int argc, char** argv){
 	if((conf.paused != srv.version) || (error < 0)) break;
 	if((conf.paused != srv.version) || (error < 0)) break;
 	if(!isudp){
 	if(!isudp){
 		size = sizeof(defparam.sincr);
 		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;
+		if(iscbc){
+			new_sock=so._socket(SASOCK(&defparam.sincr), SOCK_STREAM, IPPROTO_TCP);
+			if(new_sock != INVALID_SOCKET){
+				if(so._connect(new_sock,(struct sockaddr *)&defparam.sincr,sizeof(defparam.sincr))) {
+					so._closesocket(new_sock);
+					new_sock = INVALID_SOCKET;
+					continue;
+				}
+			}
+		}
+		else {
+			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);
 		size = sizeof(defparam.sincl);
 		if(so._getsockname(new_sock, (struct sockaddr *)&defparam.sincl, &size)){
 		if(so._getsockname(new_sock, (struct sockaddr *)&defparam.sincl, &size)){
@@ -490,9 +581,9 @@ int MODULEMAINFUNC (int argc, char** argv){
 	}
 	}
 #ifdef _WIN32
 #ifdef _WIN32
 #ifndef _WINCE
 #ifndef _WINCE
-	h = (HANDLE)_beginthreadex((LPSECURITY_ATTRIBUTES )NULL, (unsigned)16384, (BEGINTHREADFUNC)srv.pf, (void *) newparam, 0, &thread);
+	h = (HANDLE)_beginthreadex((LPSECURITY_ATTRIBUTES )NULL, (unsigned)16384, threadfunc, (void *) newparam, 0, &thread);
 #else
 #else
-	h = (HANDLE)CreateThread((LPSECURITY_ATTRIBUTES )NULL, (unsigned)32768, (BEGINTHREADFUNC)srv.pf, (void *) newparam, 0, &thread);
+	h = (HANDLE)CreateThread((LPSECURITY_ATTRIBUTES )NULL, (unsigned)32768, threadfunc, (void *) newparam, 0, &thread);
 #endif
 #endif
 	srv.childcount++;
 	srv.childcount++;
 	if (h) {
 	if (h) {
@@ -506,7 +597,7 @@ int MODULEMAINFUNC (int argc, char** argv){
 	}
 	}
 #else
 #else
 
 
-	error = pthread_create(&thread, &pa, (PTHREADFUNC)srv.pf, (void *)newparam);
+	error = pthread_create(&thread, &pa, threadfunc, (void *)newparam);
 	srv.childcount++;
 	srv.childcount++;
 	if(error){
 	if(error){
 		sprintf((char *)buf, "pthread_create(): %s", strerror(error));
 		sprintf((char *)buf, "pthread_create(): %s", strerror(error));
@@ -527,6 +618,8 @@ int MODULEMAINFUNC (int argc, char** argv){
  if(fp) fclose(fp);
  if(fp) fclose(fp);
  srvfree(&srv);
  srvfree(&srv);
  if(defparam.hostname)myfree(defparam.hostname);
  if(defparam.hostname)myfree(defparam.hostname);
+ if(cbc_string)myfree(cbc_string);
+ if(cbl_string)myfree(cbc_string);
 
 
 #ifndef STDMAIN
 #ifndef STDMAIN
  if(srv.next)srv.next->prev = srv.prev;
  if(srv.next)srv.next->prev = srv.prev;
@@ -553,6 +646,7 @@ void srvinit(struct srvparam * srv, struct clientparam *param){
  srv->srvsock = INVALID_SOCKET;
  srv->srvsock = INVALID_SOCKET;
  srv->logdumpsrv = conf.logdumpsrv;
  srv->logdumpsrv = conf.logdumpsrv;
  srv->logdumpcli = conf.logdumpcli;
  srv->logdumpcli = conf.logdumpcli;
+ srv->cbsock = INVALID_SOCKET; 
  memset(param, 0, sizeof(struct clientparam));
  memset(param, 0, sizeof(struct clientparam));
  param->srv = srv;
  param->srv = srv;
  param->remsock = param->clisock = param->ctrlsock = param->ctrlsocksrv = INVALID_SOCKET;
  param->remsock = param->clisock = param->ctrlsock = param->ctrlsocksrv = INVALID_SOCKET;
@@ -588,6 +682,7 @@ void srvinit2(struct srvparam * srv, struct clientparam *param){
 
 
 void srvfree(struct srvparam * srv){
 void srvfree(struct srvparam * srv){
  if(srv->srvsock != INVALID_SOCKET) so._closesocket(srv->srvsock);
  if(srv->srvsock != INVALID_SOCKET) so._closesocket(srv->srvsock);
+ if(srv->cbsock != INVALID_SOCKET) so._closesocket(srv->cbsock);
  srv->srvsock = INVALID_SOCKET;
  srv->srvsock = INVALID_SOCKET;
  srv->service = S_ZOMBIE;
  srv->service = S_ZOMBIE;
  while(srv->child) usleep(SLEEPTIME * 100);
  while(srv->child) usleep(SLEEPTIME * 100);

+ 3 - 3
src/structures.h

@@ -34,7 +34,6 @@ extern "C" {
 #define pthread_mutex_lock(x) EnterCriticalSection(x)
 #define pthread_mutex_lock(x) EnterCriticalSection(x)
 #define pthread_mutex_unlock(x) LeaveCriticalSection(x)
 #define pthread_mutex_unlock(x) LeaveCriticalSection(x)
 #define pthread_mutex_destroy(x) DeleteCriticalSection(x)
 #define pthread_mutex_destroy(x) DeleteCriticalSection(x)
-typedef unsigned (__stdcall *BEGINTHREADFUNC)(void *);
 #ifdef MSVC
 #ifdef MSVC
 #pragma warning (disable : 4996)
 #pragma warning (disable : 4996)
 #endif
 #endif
@@ -140,6 +139,8 @@ typedef enum {
 	S_FTPPR,
 	S_FTPPR,
 	S_SMTPP,
 	S_SMTPP,
 	S_ICQPR,
 	S_ICQPR,
+	S_REVLI,
+	S_REVCO,
 /*
 /*
 	S_MSNPR,
 	S_MSNPR,
 */
 */
@@ -162,7 +163,6 @@ typedef void * (*EXTENDFUNC) (struct node *node);
 typedef void (*CBFUNC)(void *cb, char * buf, int inbuf);
 typedef void (*CBFUNC)(void *cb, char * buf, int inbuf);
 typedef void (*PRINTFUNC) (struct node *node, CBFUNC cbf, void*cb);
 typedef void (*PRINTFUNC) (struct node *node, CBFUNC cbf, void*cb);
 typedef int (*PLUGINFUNC) (struct pluginlink *pluginlink, int argc, char** argv);
 typedef int (*PLUGINFUNC) (struct pluginlink *pluginlink, int argc, char** argv);
-typedef void * (*PTHREADFUNC)(void *);
 
 
 struct auth {
 struct auth {
 	struct auth *next;
 	struct auth *next;
@@ -360,7 +360,7 @@ struct srvparam {
 	LOGFUNC logfunc;
 	LOGFUNC logfunc;
 	AUTHFUNC authfunc;
 	AUTHFUNC authfunc;
 	PROXYFUNC pf;
 	PROXYFUNC pf;
-	SOCKET srvsock;
+	SOCKET srvsock, cbsock;
 	int childcount;
 	int childcount;
 	int maxchild;
 	int maxchild;
 	int version;
 	int version;

+ 1 - 1
src/version.h

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