Przeglądaj źródła

Support socket options for connback sockets and connection timeouts

z3APA3A 7 lat temu
rodzic
commit
eb09ae7c58
8 zmienionych plików z 44 dodań i 28 usunięć
  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
 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
-.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
 .B -DiINTERFACE, -DeINTERFACE
 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
 .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
- Sets timeout values
+ Sets timeout values, defaults 1, 5, 30, 60, 180, 1800, 15, 60, 15, 5.
 .br
   BYTE_SHORT - short timeout for single byte, is usually used for receiving single byte from stream.
 .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;
 		}
 		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._closesocket(sock);
 				break;

+ 4 - 4
src/common.c

@@ -65,7 +65,7 @@ char *rotations[] = {
 
 
 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,
@@ -649,7 +649,7 @@ void logsyslog(struct clientparam * param, const unsigned char *s) {
 }
 #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];
 #ifdef _WIN32
 		unsigned long ul = 1;
@@ -663,7 +663,7 @@ int connectwithpoll(SOCKET sock, struct sockaddr *sa, SASIZETYPE size){
 	        memset(fds, 0, sizeof(fds));
 	        fds[0].fd = sock;
 	        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 0;
@@ -728,7 +728,7 @@ int doconnect(struct clientparam * param){
 	}
 	
 	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;
 		}
 	}

+ 1 - 1
src/dnspr.c

@@ -140,7 +140,7 @@ void * dnsprchild(struct clientparam* param) {
 	}
 	param->sinsr = nservers[0].addr;
 	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;
 		*(unsigned short*)buf = htons(i);
 		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);}
 			*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);
 				clidatasock = INVALID_SOCKET;
 				RETURN(826);

+ 1 - 1
src/proxy.h

@@ -268,7 +268,7 @@ void srvinit2(struct srvparam * srv, struct clientparam *param);
 void srvfree(struct srvparam * srv);
 unsigned char * dologname (unsigned char *buf, unsigned char *name, const unsigned char *ext, ROTATION lt, time_t t);
 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);

+ 26 - 13
src/proxymain.c

@@ -16,14 +16,12 @@ DWORD WINAPI threadfunc(LPVOID p) {
 #else
 void * threadfunc (void *p) {
 #endif
- int i = 0;
+ int i = -1;
  if(param->srv->cbsock != INVALID_SOCKET){
 	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);
 		if(param->remsock == INVALID_SOCKET) {
-			param->res = 13;
-			param->srv->logfunc(param, (unsigned char *)"Connect back accept() failed");
 			continue;
 		}
 #ifndef WITHMAIN
@@ -46,7 +44,9 @@ void * threadfunc (void *p) {
 		break;
 	}
  }
- if(i == 3){
+ if(!i){
+	param->res = 13;
+	param->srv->logfunc(param, (unsigned char *)"Connect back accept() repeatedly failed");
 	freeparam(param);
  }
  else {
@@ -214,7 +214,9 @@ int MODULEMAINFUNC (int argc, char** argv){
 	" -6 Use IPv6 for outgoing connections\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"
-	" -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: ";
 
 #ifdef _WIN32
@@ -401,18 +403,25 @@ int MODULEMAINFUNC (int argc, char** argv){
 #endif
 			break;
 		 case 'o':
-			 if(argv[i][2] == 's'){
+			switch(argv[i][2]){
+			 case 's':
 				srv.srvsockopts = getopts(argv[i]+3);
 				break;
-			 }
-			 else if(argv[i][2] == 'c'){
+			 case 'c':
 				srv.clisockopts = getopts(argv[i]+3);
 				break;
-			 }
-			 else if(argv[i][2] == 'l'){
+			 case 'l':
 				srv.lissockopts = getopts(argv[i]+3);
 				break;
-			 }
+			 case 'r':
+				srv.cbcsockopts = getopts(argv[i]+3);
+				break;
+			 case 'R':
+				srv.cbcsockopts = getopts(argv[i]+3);
+				break;
+			 default:
+				error = 1;
+			}
 		 default:
 			error = 1;
 			break;
@@ -602,6 +611,8 @@ int MODULEMAINFUNC (int argc, char** argv){
 	so._setsockopt(srv.cbsock, SOL_SOCKET, SO_REUSEPORT, (char *)&opt, sizeof(int));
 #endif
 
+	setopts(srv.cbsock, srv.cbssockopts);
+
 	if(so._bind(srv.cbsock, (struct sockaddr*)&cbsa, SASIZE(&cbsa))==-1) {
 		(*srv.logfunc)(&defparam, (unsigned char *)"Failed to bind connect back socket");
 		return -7;
@@ -656,8 +667,10 @@ int MODULEMAINFUNC (int argc, char** argv){
 		if(iscbc){
 			new_sock=so._socket(SASOCK(&defparam.sincr), SOCK_STREAM, IPPROTO_TCP);
 			if(new_sock != INVALID_SOCKET){
+				setopts(new_sock, srv.cbcsockopts);
+
 				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);
 					new_sock = INVALID_SOCKET;
 					usleep(SLEEPTIME);

+ 5 - 3
src/structures.h

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