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

Add support for -os, -oc, -ol

-ocOPTIONS, -osOPTIONS, -olOPTIONS - options for client (oc), server
(os) or listening (ol) socket
e.g.
proxy -ocTCP_NODELAY,SO_KEEPALIVE,SO_DONTROUTE
z3APA3A 9 лет назад
Родитель
Сommit
c1beee44ef
7 измененных файлов с 106 добавлено и 150 удалено
  1. 1 7
      src/Makefile.inc
  2. 1 1
      src/auth.c
  3. 2 0
      src/common.c
  4. 0 141
      src/dighosts.c
  5. 5 1
      src/proxy.h
  6. 96 0
      src/proxymain.c
  7. 1 0
      src/structures.h

+ 1 - 7
src/Makefile.inc

@@ -2,7 +2,7 @@
 # 3 proxy common Makefile
 #
 
-all:	$(BUILDDIR)3proxy$(EXESUFFICS) $(BUILDDIR)mycrypt$(EXESUFFICS) $(BUILDDIR)dighosts$(EXESUFFICS) $(BUILDDIR)pop3p$(EXESUFFICS) $(BUILDDIR)smtpp$(EXESUFFICS) $(BUILDDIR)ftppr$(EXESUFFICS) $(BUILDDIR)tcppm$(EXESUFFICS) $(BUILDDIR)icqpr$(EXESUFFICS) $(BUILDDIR)udppm$(EXESUFFICS) $(BUILDDIR)socks$(EXESUFFICS) $(BUILDDIR)proxy$(EXESUFFICS) allplugins
+all:	$(BUILDDIR)3proxy$(EXESUFFICS) $(BUILDDIR)mycrypt$(EXESUFFICS) $(BUILDDIR)pop3p$(EXESUFFICS) $(BUILDDIR)smtpp$(EXESUFFICS) $(BUILDDIR)ftppr$(EXESUFFICS) $(BUILDDIR)tcppm$(EXESUFFICS) $(BUILDDIR)icqpr$(EXESUFFICS) $(BUILDDIR)udppm$(EXESUFFICS) $(BUILDDIR)socks$(EXESUFFICS) $(BUILDDIR)proxy$(EXESUFFICS) allplugins
 
 
 sockmap$(OBJSUFFICS): sockmap.c proxy.h structures.h
@@ -130,12 +130,6 @@ datatypes$(OBJSUFFICS): datatypes.c proxy.h structures.h
 mycrypt$(OBJSUFFICS): mycrypt.c
 	$(CC) $(COUT)mycrypt$(OBJSUFFICS) $(CFLAGS) mycrypt.c
 
-dighosts$(OBJSUFFICS): dighosts.c
-	$(CC) $(COUT)dighosts$(OBJSUFFICS) $(CFLAGS) dighosts.c
-
-$(BUILDDIR)dighosts$(EXESUFFICS): dighosts$(OBJSUFFICS) myalloc$(OBJSUFFICS) common$(OBJSUFFICS)  $(COMPATLIBS)
-	$(LN) $(LNOUT)$(BUILDDIR)dighosts$(EXESUFFICS) $(LDFLAGS) dighosts$(OBJSUFFICS) myalloc$(OBJSUFFICS) common$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
-
 mycryptmain$(OBJSUFFICS): mycrypt.c
 	$(CC) $(COUT)mycryptmain$(OBJSUFFICS) $(CFLAGS) $(DEFINEOPTION)WITHMAIN mycrypt.c
 

+ 1 - 1
src/auth.c

@@ -1098,7 +1098,7 @@ unsigned long udpresolve(int af, unsigned char * name, unsigned char * value, un
 #ifdef TCP_NODELAY
 			{
 				int opt = 1;
-				setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt));
+				setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&opt, sizeof(opt));
 			}
 #endif
 		}

+ 2 - 0
src/common.c

@@ -694,6 +694,8 @@ int doconnect(struct clientparam * param){
 	}
 	if(!*SAPORT(&param->sinsr))*SAPORT(&param->sinsr) = *SAPORT(&param->req);
 	if ((param->remsock=so._socket(SASOCK(&param->sinsr), SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {return (11);}
+	setopts(param->remsock, param->srv->srvsockopts);
+
 	so._setsockopt(param->remsock, SOL_SOCKET, SO_LINGER, (char *)&lg, sizeof(lg));
 #ifdef REUSE
 	{

+ 0 - 141
src/dighosts.c

@@ -1,141 +0,0 @@
-/*
-   (c) 2002-2016 by Vladimir Dubrovin <3proxy@3proxy.ru>
-
-   please read License Agreement
-
-*/
-
-#include "proxy.h"
-pthread_mutex_t log_mutex;
-
-
-int sockgetchar(SOCKET sock, int timeosec, int timeousec){
- unsigned char buf;
- fd_set fds;
- struct timeval tv;
-
- tv.tv_sec = timeosec;
- tv.tv_usec = timeousec;
- FD_ZERO(&fds);
- FD_SET(sock, &fds);
- if (select (((int)sock)+1, &fds, NULL, NULL, &tv)!=1) return EOF;
- if (recv(sock, (char *)&buf, 1, 0)!=1) return EOF;
- return((int)buf);
-}
-
-
-int sockgetline(SOCKET sock, unsigned char * buf, int bufsize, int delim, int to){
- int c;
- int i=0, tos, tou;
- if(bufsize<2) return 0;
- c = sockgetchar(sock, to, 0);
- if (c == EOF) {
-	return 0;
- }
- tos = to/16;
- tou = ((to * 1000) / bufsize)%1000;
- do {
-	buf[i++] = c;
-	if(delim != EOF && c == delim) break;
- }while(i < bufsize && (c = sockgetchar(sock, tos, tou)) != EOF);
- return i;
-}
-
-
-unsigned char request[] = "GET %.1024s HTTP/1.0\r\nHost: %.256s\r\n\r\n";
-
-int main(int argc, char *argv[]){
-	unsigned char *host, *hostend;
-	SOCKET sock;
-	struct sockaddr_in sa;
-	FILE *fp;
-	unsigned char buf[16000];
-	int i;
-	unsigned x,y,z,w,cidr, x1,y1,z1,w1, mask;
-	int first = 1;
-
-#ifdef _WIN32
- WSADATA wd;
- WSAStartup(MAKEWORD( 1, 1 ), &wd);
-#endif
-
-	if(argc < 3 || argc > 4 || (argc == 4 && (argv[1][0] != '-' || argv[1][1] != 'm'))) {
-		fprintf(stderr, "Usage: %s [-m] <URL> <FILE>\n"
-				" program retrieves requested <URL> and builds comma delimited list of networks\n"
-				" list than stored in <FILE>\n"
-				" networks are searched in xxx.yyy.zzz.www/cidr format\n"
-				" switches:\n"
-				"  -m networks are searched in xxx.yyy.zzz.www mmm.mmm.mmm.mmm format\n"
-				"\n(c)2002 by 3APA3A\n",
-				argv[0]);
-		return 1;
-	}
-	if(strncasecmp(argv[argc-2], "http://", 7)) {
-		fprintf(stderr, "URL must be HTTP://\n");
-		return 2;
-	}
-	hostend = (unsigned char *)strchr((char *)argv[argc-2] + 7, '/');
-	if(!hostend) {
-		fprintf(stderr, "Wrong URL syntaxis\n");
-		return 3;
-	}
-	*hostend = 0;
-	if(!(host = (unsigned char *)strdup((char *)argv[argc-2] + 7))) {
-		return 4;
-	}
-	*hostend = '/';
-	if(!getip46(4, host, (struct sockaddr *)&sa)) {
-		fprintf(stderr, "Unable to resolve %s\n", host);
-		return 5;
-	}
-	sa.sin_port = htons(80);
-	if((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) return 6;
-	sprintf((char *)buf, (char *)request, hostend, host);
-	if(connect(sock,(struct sockaddr *)&sa,sizeof(sa))) {
-		fprintf(stderr, "Unable to connect: %s\n", host);
-		return 8;
-	}
-	if(send(sock, (char *)buf, (int)strlen((char *)buf), 0) != (int)strlen((char *)buf)) return 9;
-	while( (i = sockgetline(sock, buf, sizeof(buf) - 1, '\n', 30)) > 2);
-	if(i<1) return 9;
-	if(!(fp = fopen(argv[argc-1], "w"))) {
-		fprintf(stderr, "Unable to open: %s\n", argv[2]);
-		return 7;
-	}
-	while( (i = sockgetline(sock, buf, sizeof(buf) - 1, '\n', 30)) > 0){
-		buf[i] = 0;
-		for(i = 0; buf[i]; i++){
-			if((buf[i]<'0' || buf[i] > '9') && buf[i] != '.' && buf[i] != '/')buf[i] = ' ';
-		}
-		if(argc == 3){
-			if((i=sscanf((char *)buf, "%u.%u.%u.%u/%u", &x, &y, &z, &w, &cidr)) == 5 &&
-					x<256 && y<256 && z<256 && w<256 &&
-					cidr <= 32){
-				if(!first)fprintf(fp, ",");
-				fprintf(fp, "%u.%u.%u.%u/%u", x, y, z, w, cidr);
-				first = 0;
-			}
-		}
-		else{
-			if((i = sscanf((char *)buf, "%u.%u.%u.%u %u.%u.%u.%u", &x, &y, &z, &w, &x1, &y1, &z1, &w1)) == 8 &&
-					x<256 && y<256 && z<256 && w<256 &&
-					x1<256 && y1<256 && z1<256 && w1<256
-					){
-				mask = (x1<<24)|(y1<<16)|(z1<<8)|w1;
-				for(cidr = 0; cidr <= 32; cidr++)if((((unsigned long)(0xFFFFFFFF))<<(32-cidr)) == mask) break;
-				if(cidr > 32) continue;
-				if(!first)fprintf(fp, ",");
-				fprintf(fp, "%u.%u.%u.%u/%u", x, y, z, w, cidr);
-				first = 0;
-			}
-		}
-	}
-	shutdown(sock, SHUT_RDWR);
-#ifdef _WIN32
-	closesocket(sock);
-#else
-	close(sock);
-#endif
-	fclose(fp);
-	return 0;
-}

+ 5 - 1
src/proxy.h

@@ -339,6 +339,11 @@ extern struct  sockaddr_in6 radiuslist[MAXRADIUS];
 
 extern int nradservers;
 extern char * radiussecret;
+extern struct socketoptions {
+	int opt;
+	char * optname;
+} sockopts[];
+void setopts(SOCKET s, int opts);
 
 #ifdef _WINCE
 char * CEToUnicode (const char *str);
@@ -346,7 +351,6 @@ int cesystem(const char *str);
 int ceparseargs(const char *str);
 extern char * ceargv[32];
 
-
 #define system(S) cesystem(S)
 #endif
 

+ 96 - 0
src/proxymain.c

@@ -61,6 +61,54 @@ void * threadfunc (void *p) {
 #undef param
 
 
+struct socketoptions sockopts[] = {
+#ifdef TCP_NODELAY
+	{TCP_NODELAY, "TCP_NODELAY"},
+#endif
+#ifdef TCP_CORK
+	{TCP_CORK, "TCP_CORK"},
+#endif
+#ifdef TCP_DEFER_ACCEPT
+	{TCP_DEFER_ACCEPT, "TCP_DEFER_ACCEPT"},
+#endif
+#ifdef TCP_QUICKACK
+	{TCP_QUICKACK, "TCP_QUICKACK"},
+#endif
+#ifdef TCP_TIMESTAMPS
+	{TCP_TIMESTAMPS, "TCP_TIMESTAMPS"},
+#endif
+#ifdef USE_TCP_FASTOPEN
+	{USE_TCP_FASTOPEN, "USE_TCP_FASTOPEN"},
+#endif
+#ifdef SO_REUSEADDR
+	{SO_REUSEADDR, "SO_REUSEADDR"},
+#endif
+#ifdef SO_REUSEPORT
+	{SO_REUSEPORT, "SO_REUSEPORT"},
+#endif
+#ifdef SO_KEEPALIVE
+	{SO_KEEPALIVE, "SO_KEEPALIVE"},
+#endif
+#ifdef SO_DONTROUTE
+	{SO_DONTROUTE, "SO_DONTROUTE"},
+#endif
+	{0, NULL}
+};
+
+int getopts(const char *s){
+	int i=0, ret=0;
+	for(; sockopts[i].optname; i++)if(strstr(s,sockopts[i].optname)) ret |= (1<<i);
+	return ret;
+}
+
+void setopts(SOCKET s, int opts){
+	int i, opt, set;
+	for(i = 0; opts >= (opt = (1<<i)); i++){
+		set = 1;
+		if(opts & opt) setsockopt(s, *sockopts[i].optname == 'T'? IPPROTO_TCP:SOL_SOCKET, sockopts[i].opt, (char *)&set, sizeof(set));
+	}
+}
+
 
 #ifndef MODULEMAINFUNC
 #define MODULEMAINFUNC main
@@ -131,6 +179,39 @@ int MODULEMAINFUNC (int argc, char** argv){
 	" -b(BUFSIZE) size of network buffer (default 4096 for TCP, 16384 for UDP)\n"
 	" -S(STACKSIZE) value to add to default client thread stack size\n"
 	" -t be silent (do not log service start/stop)\n"
+	" -ocOPTIONS, -osOPTIONS, -olOPTIONS - options for client (oc), server (os) or listening (ol) socket,"
+	" where possible options are: "
+#ifdef TCP_NODELAY
+	"TCP_NODELAY "
+#endif
+#ifdef TCP_CORK
+	"TCP_CORK "
+#endif
+#ifdef TCP_DEFER_ACCEPT
+	"TCP_DEFER_ACCEPT "
+#endif
+#ifdef TCP_QUICKACK
+	"TCP_QUICKACK "
+#endif
+#ifdef TCP_TIMESTAMPS
+	"TCP_TIMESTAMPS "
+#endif
+#ifdef USE_TCP_FASTOPEN
+	"USE_TCP_FASTOPEN "
+#endif
+#ifdef SO_REUSEADDR
+	"SO_REUSEADDR "
+#endif
+#ifdef SO_REUSEPORT
+	"SO_REUSEPORT "
+#endif
+#ifdef SO_KEEPALIVE
+	"SO_KEEPALIVE "
+#endif
+#ifdef SO_DONTROUTE
+	"SO_DONTROUTE "
+#endif
+	"\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"
 	" -rHOST:PORT Use IP:port for connect back proxy instead of listen port\n"
@@ -315,6 +396,19 @@ int MODULEMAINFUNC (int argc, char** argv){
 				srv.usesplice = 1 + atoi(argv[i]+2);
 #endif
 			break;
+		 case 'o':
+			 if(argv[i][2] == 's'){
+				srv.srvsockopts = getopts(argv[i]+3);
+				break;
+			 }
+			 else if(argv[i][2] == 'c'){
+				srv.clisockopts = getopts(argv[i]+3);
+				break;
+			 }
+			 else if(argv[i][2] == 'l'){
+				srv.lissockopts = getopts(argv[i]+3);
+				break;
+			 }
 		 default:
 			error = 1;
 			break;
@@ -447,6 +541,7 @@ int MODULEMAINFUNC (int argc, char** argv){
 			perror("socket()");
 			return -2;
 		}
+		setopts(sock, srv.lissockopts);
 #ifdef _WIN32
 		ioctlsocket(sock, FIONBIO, &ul);
 #else
@@ -618,6 +713,7 @@ int MODULEMAINFUNC (int argc, char** argv){
 				continue;
 			}
 		}
+		setopts(new_sock, srv.clisockopts);
 		size = sizeof(defparam.sincl);
 		if(so._getsockname(new_sock, (struct sockaddr *)&defparam.sincl, &size)){
 			sprintf((char *)buf, "getsockname(): %s", strerror(errno));

+ 1 - 0
src/structures.h

@@ -397,6 +397,7 @@ struct srvparam {
 	int stacksize;
 	int noforce;
 	int anonymous;
+	int clisockopts, srvsockopts, lissockopts;
 #ifdef WITHSPLICE
 	int usesplice;
 #endif