mirror of
				https://github.com/3proxy/3proxy.git
				synced 2025-11-04 07:42:39 +08:00 
			
		
		
		
	Support socket options for connback sockets and connection timeouts
This commit is contained in:
		
							parent
							
								
									b8127257f9
								
							
						
					
					
						commit
						eb09ae7c58
					
				@ -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
 | 
					.B -ocOPTIONS, -osOPTIONS, -olOPTIONS, -orOPTIONS, -oROPTIONS
 | 
				
			||||||
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.
 | 
					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
 | 
				
			||||||
 | 
				
			|||||||
@ -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;
 | 
				
			||||||
 | 
				
			|||||||
@ -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 *)¶m->sinsr,SASIZE(¶m->sinsr))) {
 | 
							if(connectwithpoll(param->remsock,(struct sockaddr *)¶m->sinsr,SASIZE(¶m->sinsr),CONNECT_TO)) {
 | 
				
			||||||
			return 13;
 | 
								return 13;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
				
			|||||||
@ -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 *)¶m->sinsr,SASIZE(¶m->sinsr))) RETURN(830);
 | 
							if(connectwithpoll(param->remsock,(struct sockaddr *)¶m->sinsr,SASIZE(¶m->sinsr),CONNECT_TO)) RETURN(830);
 | 
				
			||||||
		buf-=2;
 | 
							buf-=2;
 | 
				
			||||||
		*(unsigned short*)buf = htons(i);
 | 
							*(unsigned short*)buf = htons(i);
 | 
				
			||||||
		i+=2;
 | 
							i+=2;
 | 
				
			||||||
 | 
				
			|||||||
@ -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(¶m->sincr) = htons((unsigned short)((b5<<8)^b6));
 | 
								*SAPORT(¶m->sincr) = htons((unsigned short)((b5<<8)^b6));
 | 
				
			||||||
			if(connectwithpoll(clidatasock, (struct sockaddr *)¶m->sincr, SASIZE(¶m->sincr))) {
 | 
								if(connectwithpoll(clidatasock, (struct sockaddr *)¶m->sincr, SASIZE(¶m->sincr),CONNECT_TO)) {
 | 
				
			||||||
				so._closesocket(clidatasock);
 | 
									so._closesocket(clidatasock);
 | 
				
			||||||
				clidatasock = INVALID_SOCKET;
 | 
									clidatasock = INVALID_SOCKET;
 | 
				
			||||||
				RETURN(826);
 | 
									RETURN(826);
 | 
				
			||||||
 | 
				
			|||||||
@ -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);
 | 
				
			||||||
 | 
				
			|||||||
@ -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*)¶m->sinsr, &size);
 | 
							param->remsock = so._accept(param->srv->cbsock, (struct sockaddr*)¶m->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;
 | 
				
			||||||
			 }
 | 
								 case 'c':
 | 
				
			||||||
			 else if(argv[i][2] == 'c'){
 | 
					 | 
				
			||||||
				srv.clisockopts = getopts(argv[i]+3);
 | 
									srv.clisockopts = getopts(argv[i]+3);
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
			 }
 | 
								 case 'l':
 | 
				
			||||||
			 else if(argv[i][2] == '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);
 | 
				
			||||||
 | 
				
			|||||||
@ -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 {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user