Просмотр исходного кода

Support socket options for connback sockets and connection timeouts

z3APA3A 7 лет назад
Родитель
Сommit
eb09ae7c58
8 измененных файлов с 44 добавлено и 28 удалено
  1. 5 4
      man/3proxy.cfg.3
  2. 1 1
      src/auth.c
  3. 4 4
      src/common.c
  4. 1 1
      src/dnspr.c
  5. 1 1
      src/ftppr.c
  6. 1 1
      src/proxy.h
  7. 26 13
      src/proxymain.c
  8. 5 3
      src/structures.h

+ 5 - 4
man/3proxy.cfg.3

@@ -152,8 +152,9 @@ listen on given local HOST:port for incoming connections instead of making remot
 .B -rHOST:port
 .B -rHOST:port
 connect to given remote HOST:port instead of listening local connection on -p or default port. Can be used with another 3proxy service running -R option for connect back functionality. Most commonly used with proxy or socks. HOST can be given as IP or hostname, useful in case of dynamic DNS.
 connect to given remote HOST:port instead of listening local connection on -p or default port. Can be used with another 3proxy service running -R option for connect back functionality. Most commonly used with proxy or socks. HOST can be given as IP or hostname, useful in case of dynamic DNS.
 .br
 .br
-.B -ocOPTIONS, -osOPTIONS, -olOPTIONS
-options for client (oc), server (os) or listening (ol) socket. Options like TCP_CORK, TCP_NODELAY, TCP_DEFER_ACCEPT, TCP_QUICKACK, TCP_TIMESTAMPS, USE_TCP_FASTOPEN, SO_REUSEADDR, SO_REUSEPORT, SO_PORT_SCALABILITY, SO_REUSE_UNICASTPORT, SO_KEEPALIVE, SO_DONTROUTE may be supported depending on OS.
+.B -ocOPTIONS, -osOPTIONS, -olOPTIONS, -orOPTIONS, -oROPTIONS
+options for proxy-to-client (oc), proxy-to-server (os), proxy listening (ol), connect back client (or), connect back listening (oR) sockets.
+Options like TCP_CORK, TCP_NODELAY, TCP_DEFER_ACCEPT, TCP_QUICKACK, TCP_TIMESTAMPS, USE_TCP_FASTOPEN, SO_REUSEADDR, SO_REUSEPORT, SO_PORT_SCALABILITY, SO_REUSE_UNICASTPORT, SO_KEEPALIVE, SO_DONTROUTE may be supported depending on OS.
 .br
 .br
 .B -DiINTERFACE, -DeINTERFACE
 .B -DiINTERFACE, -DeINTERFACE
 bind internal interface / external inteface to given INTERFACE (e.g. eth0) if SO_BINDTODEVICE supported by system
 bind internal interface / external inteface to given INTERFACE (e.g. eth0) if SO_BINDTODEVICE supported by system
@@ -350,9 +351,9 @@ can use %A as produced archive name and %F as filename.
 
 
 .br
 .br
 .B timeouts
 .B timeouts
-<BYTE_SHORT> <BYTE_LONG> <STRING_SHORT> <STRING_LONG> <CONNECTION_SHORT> <CONNECTION_LONG> <DNS> <CHAIN>
+<BYTE_SHORT> <BYTE_LONG> <STRING_SHORT> <STRING_LONG> <CONNECTION_SHORT> <CONNECTION_LONG> <DNS> <CHAIN> <CONNECT> <CONNECTBACK>
 .br
 .br
- Sets timeout values
+ Sets timeout values, defaults 1, 5, 30, 60, 180, 1800, 15, 60, 15, 5.
 .br
 .br
   BYTE_SHORT - short timeout for single byte, is usually used for receiving single byte from stream.
   BYTE_SHORT - short timeout for single byte, is usually used for receiving single byte from stream.
 .br
 .br

+ 1 - 1
src/auth.c

@@ -1154,7 +1154,7 @@ unsigned long udpresolve(int af, unsigned char * name, unsigned char * value, un
 			*sinsr = nservers[i].addr;
 			*sinsr = nservers[i].addr;
 		}
 		}
 		if(usetcp){
 		if(usetcp){
-			if(connectwithpoll(sock,(struct sockaddr *)sinsr,SASIZE(sinsr))) {
+			if(connectwithpoll(sock,(struct sockaddr *)sinsr,SASIZE(sinsr),CONNECT_TO)) {
 				so._shutdown(sock, SHUT_RDWR);
 				so._shutdown(sock, SHUT_RDWR);
 				so._closesocket(sock);
 				so._closesocket(sock);
 				break;
 				break;

+ 4 - 4
src/common.c

@@ -65,7 +65,7 @@ char *rotations[] = {
 
 
 
 
 struct extparam conf = {
 struct extparam conf = {
-	{1, 5, 30, 60, 180, 1800, 15, 60, 0, 0},
+	{1, 5, 30, 60, 180, 1800, 15, 60, 15, 5, 0, 0},
 	NULL,
 	NULL,
 	NULL,
 	NULL,
 	NULL, NULL,
 	NULL, NULL,
@@ -649,7 +649,7 @@ void logsyslog(struct clientparam * param, const unsigned char *s) {
 }
 }
 #endif
 #endif
 
 
-int connectwithpoll(SOCKET sock, struct sockaddr *sa, SASIZETYPE size){
+int connectwithpoll(SOCKET sock, struct sockaddr *sa, SASIZETYPE size, int to){
 		struct pollfd fds[1];
 		struct pollfd fds[1];
 #ifdef _WIN32
 #ifdef _WIN32
 		unsigned long ul = 1;
 		unsigned long ul = 1;
@@ -663,7 +663,7 @@ int connectwithpoll(SOCKET sock, struct sockaddr *sa, SASIZETYPE size){
 	        memset(fds, 0, sizeof(fds));
 	        memset(fds, 0, sizeof(fds));
 	        fds[0].fd = sock;
 	        fds[0].fd = sock;
 	        fds[0].events = POLLOUT;
 	        fds[0].events = POLLOUT;
-		if(so._poll(fds, 1, conf.timeouts[STRING_S]*1000) <= 0) {
+		if(so._poll(fds, 1, to*1000) <= 0) {
 			return (13);
 			return (13);
 		}
 		}
 		return 0;
 		return 0;
@@ -728,7 +728,7 @@ int doconnect(struct clientparam * param){
 	}
 	}
 	
 	
 	if(param->operation >= 256 || (param->operation & CONNECT)){
 	if(param->operation >= 256 || (param->operation & CONNECT)){
-		if(connectwithpoll(param->remsock,(struct sockaddr *)&param->sinsr,SASIZE(&param->sinsr))) {
+		if(connectwithpoll(param->remsock,(struct sockaddr *)&param->sinsr,SASIZE(&param->sinsr),CONNECT_TO)) {
 			return 13;
 			return 13;
 		}
 		}
 	}
 	}

+ 1 - 1
src/dnspr.c

@@ -140,7 +140,7 @@ void * dnsprchild(struct clientparam* param) {
 	}
 	}
 	param->sinsr = nservers[0].addr;
 	param->sinsr = nservers[0].addr;
 	if(nservers[0].usetcp) {
 	if(nservers[0].usetcp) {
-		if(connectwithpoll(param->remsock,(struct sockaddr *)&param->sinsr,SASIZE(&param->sinsr))) RETURN(830);
+		if(connectwithpoll(param->remsock,(struct sockaddr *)&param->sinsr,SASIZE(&param->sinsr),CONNECT_TO)) RETURN(830);
 		buf-=2;
 		buf-=2;
 		*(unsigned short*)buf = htons(i);
 		*(unsigned short*)buf = htons(i);
 		i+=2;
 		i+=2;

+ 1 - 1
src/ftppr.c

@@ -153,7 +153,7 @@ void * ftpprchild(struct clientparam* param) {
 
 
 			if(sscanf((char *)buf+5, "%lu,%lu,%lu,%lu,%hu,%hu", &b1, &b2, &b3, &b4, &b5, &b6)!=6) {RETURN(828);}
 			if(sscanf((char *)buf+5, "%lu,%lu,%lu,%lu,%hu,%hu", &b1, &b2, &b3, &b4, &b5, &b6)!=6) {RETURN(828);}
 			*SAPORT(&param->sincr) = htons((unsigned short)((b5<<8)^b6));
 			*SAPORT(&param->sincr) = htons((unsigned short)((b5<<8)^b6));
-			if(connectwithpoll(clidatasock, (struct sockaddr *)&param->sincr, SASIZE(&param->sincr))) {
+			if(connectwithpoll(clidatasock, (struct sockaddr *)&param->sincr, SASIZE(&param->sincr),CONNECT_TO)) {
 				so._closesocket(clidatasock);
 				so._closesocket(clidatasock);
 				clidatasock = INVALID_SOCKET;
 				clidatasock = INVALID_SOCKET;
 				RETURN(826);
 				RETURN(826);

+ 1 - 1
src/proxy.h

@@ -268,7 +268,7 @@ void srvinit2(struct srvparam * srv, struct clientparam *param);
 void srvfree(struct srvparam * srv);
 void srvfree(struct srvparam * srv);
 unsigned char * dologname (unsigned char *buf, unsigned char *name, const unsigned char *ext, ROTATION lt, time_t t);
 unsigned char * dologname (unsigned char *buf, unsigned char *name, const unsigned char *ext, ROTATION lt, time_t t);
 int readconfig(FILE * fp);
 int readconfig(FILE * fp);
-int connectwithpoll(SOCKET sock, struct sockaddr *sa, SASIZETYPE size);
+int connectwithpoll(SOCKET sock, struct sockaddr *sa, SASIZETYPE size, int to);
 
 
 
 
 int myrand(void * entropy, int len);
 int myrand(void * entropy, int len);

+ 26 - 13
src/proxymain.c

@@ -16,14 +16,12 @@ DWORD WINAPI threadfunc(LPVOID p) {
 #else
 #else
 void * threadfunc (void *p) {
 void * threadfunc (void *p) {
 #endif
 #endif
- int i = 0;
+ int i = -1;
  if(param->srv->cbsock != INVALID_SOCKET){
  if(param->srv->cbsock != INVALID_SOCKET){
 	SASIZETYPE size = sizeof(param->sinsr);
 	SASIZETYPE size = sizeof(param->sinsr);
-	for(i=0; i<3; i++){
+	for(i=5+(param->srv->maxchild>>10); i; i--){
 		param->remsock = so._accept(param->srv->cbsock, (struct sockaddr*)&param->sinsr, &size);
 		param->remsock = so._accept(param->srv->cbsock, (struct sockaddr*)&param->sinsr, &size);
 		if(param->remsock == INVALID_SOCKET) {
 		if(param->remsock == INVALID_SOCKET) {
-			param->res = 13;
-			param->srv->logfunc(param, (unsigned char *)"Connect back accept() failed");
 			continue;
 			continue;
 		}
 		}
 #ifndef WITHMAIN
 #ifndef WITHMAIN
@@ -46,7 +44,9 @@ void * threadfunc (void *p) {
 		break;
 		break;
 	}
 	}
  }
  }
- if(i == 3){
+ if(!i){
+	param->res = 13;
+	param->srv->logfunc(param, (unsigned char *)"Connect back accept() repeatedly failed");
 	freeparam(param);
 	freeparam(param);
  }
  }
  else {
  else {
@@ -214,7 +214,9 @@ int MODULEMAINFUNC (int argc, char** argv){
 	" -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"
 	" -64 Prefer IPv6 for outgoing connections, use both IPv4 and IPv6\n"
 	" -64 Prefer IPv6 for outgoing connections, use both IPv4 and IPv6\n"
-	" -ocOPTIONS, -osOPTIONS, -olOPTIONS - options for client (oc), server (os) or listening (ol) socket,"
+	" -ocOPTIONS, -osOPTIONS, -olOPTIONS, -orOPTIONS -oROPTIONS - options for\n"
+	" to-client (oc), to-server (os), listening (ol) socket, connect back client\n"
+	" (or) socket, connect back server (oR) listening socket\n"
 	" where possible options are: ";
 	" where possible options are: ";
 
 
 #ifdef _WIN32
 #ifdef _WIN32
@@ -401,18 +403,25 @@ int MODULEMAINFUNC (int argc, char** argv){
 #endif
 #endif
 			break;
 			break;
 		 case 'o':
 		 case 'o':
-			 if(argv[i][2] == 's'){
+			switch(argv[i][2]){
+			 case 's':
 				srv.srvsockopts = getopts(argv[i]+3);
 				srv.srvsockopts = getopts(argv[i]+3);
 				break;
 				break;
-			 }
-			 else if(argv[i][2] == 'c'){
+			 case 'c':
 				srv.clisockopts = getopts(argv[i]+3);
 				srv.clisockopts = getopts(argv[i]+3);
 				break;
 				break;
-			 }
-			 else if(argv[i][2] == 'l'){
+			 case 'l':
 				srv.lissockopts = getopts(argv[i]+3);
 				srv.lissockopts = getopts(argv[i]+3);
 				break;
 				break;
-			 }
+			 case 'r':
+				srv.cbcsockopts = getopts(argv[i]+3);
+				break;
+			 case 'R':
+				srv.cbcsockopts = getopts(argv[i]+3);
+				break;
+			 default:
+				error = 1;
+			}
 		 default:
 		 default:
 			error = 1;
 			error = 1;
 			break;
 			break;
@@ -602,6 +611,8 @@ int MODULEMAINFUNC (int argc, char** argv){
 	so._setsockopt(srv.cbsock, SOL_SOCKET, SO_REUSEPORT, (char *)&opt, sizeof(int));
 	so._setsockopt(srv.cbsock, SOL_SOCKET, SO_REUSEPORT, (char *)&opt, sizeof(int));
 #endif
 #endif
 
 
+	setopts(srv.cbsock, srv.cbssockopts);
+
 	if(so._bind(srv.cbsock, (struct sockaddr*)&cbsa, SASIZE(&cbsa))==-1) {
 	if(so._bind(srv.cbsock, (struct sockaddr*)&cbsa, SASIZE(&cbsa))==-1) {
 		(*srv.logfunc)(&defparam, (unsigned char *)"Failed to bind connect back socket");
 		(*srv.logfunc)(&defparam, (unsigned char *)"Failed to bind connect back socket");
 		return -7;
 		return -7;
@@ -656,8 +667,10 @@ int MODULEMAINFUNC (int argc, char** argv){
 		if(iscbc){
 		if(iscbc){
 			new_sock=so._socket(SASOCK(&defparam.sincr), SOCK_STREAM, IPPROTO_TCP);
 			new_sock=so._socket(SASOCK(&defparam.sincr), SOCK_STREAM, IPPROTO_TCP);
 			if(new_sock != INVALID_SOCKET){
 			if(new_sock != INVALID_SOCKET){
+				setopts(new_sock, srv.cbcsockopts);
+
 				parsehost(srv.family, cbc_string, (struct sockaddr *)&defparam.sincr);
 				parsehost(srv.family, cbc_string, (struct sockaddr *)&defparam.sincr);
-				if(connectwithpoll(new_sock,(struct sockaddr *)&defparam.sincr,SASIZE(&defparam.sincr))) {
+				if(connectwithpoll(new_sock,(struct sockaddr *)&defparam.sincr,SASIZE(&defparam.sincr),CONNBACK_TO)) {
 					so._closesocket(new_sock);
 					so._closesocket(new_sock);
 					new_sock = INVALID_SOCKET;
 					new_sock = INVALID_SOCKET;
 					usleep(SLEEPTIME);
 					usleep(SLEEPTIME);

+ 5 - 3
src/structures.h

@@ -418,7 +418,7 @@ struct srvparam {
 	int stacksize;
 	int stacksize;
 	int noforce;
 	int noforce;
 	int anonymous;
 	int anonymous;
-	int clisockopts, srvsockopts, lissockopts;
+	int clisockopts, srvsockopts, lissockopts, cbcsockopts, cbssockopts;
 #ifdef WITHSPLICE
 #ifdef WITHSPLICE
 	int usesplice;
 	int usesplice;
 #endif
 #endif
@@ -543,7 +543,7 @@ struct filemon {
 
 
 
 
 struct extparam {
 struct extparam {
-	int timeouts[10];
+	int timeouts[12];
 	struct ace * acl;
 	struct ace * acl;
 	char * conffile;
 	char * conffile;
 	struct bandlim * bandlimiter,  *bandlimiterout;
 	struct bandlim * bandlimiter,  *bandlimiterout;
@@ -774,7 +774,9 @@ typedef enum {
 	CONNECTION_S,
 	CONNECTION_S,
 	CONNECTION_L,
 	CONNECTION_L,
 	DNS_TO,
 	DNS_TO,
-	CHAIN_TO
+	CHAIN_TO,
+	CONNECT_TO,
+	CONNBACK_TO
 }TIMEOUT;
 }TIMEOUT;
 
 
 typedef enum {
 typedef enum {