From d6f29ac6df93fe3ca942f558f2b3c4def468b87c Mon Sep 17 00:00:00 2001 From: z3APA3A <3APA3A@3proxy.ru> Date: Sat, 23 Jan 2016 17:16:49 +0300 Subject: [PATCH 1/3] reset transparent flag on keep-alive connection --- src/proxy.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/proxy.c b/src/proxy.c index d55bc0d..09ee60f 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -293,6 +293,7 @@ for(;;){ RETURN(511); } if(buf[i-3] == '1') keepalive = 2; + param->transparent = 0; if((isconnect = !strncasecmp((char *)buf, "CONNECT", 7))) keepalive = 2; if ((sb=(unsigned char *)(unsigned char *)strchr((char *)buf, ' ')) == NULL) {RETURN(512);} From 1ed5229a54fd5dc9d180276aed0873883bd7139e Mon Sep 17 00:00:00 2001 From: z3APA3A <3APA3A@3proxy.ru> Date: Sat, 23 Jan 2016 15:34:24 +0300 Subject: [PATCH 2/3] Do not use SO_REUSEADDR by default to avoid misbehavior in some glibc versions --- src/socks.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/socks.c b/src/socks.c index 3a26138..6e2b7d8 100644 --- a/src/socks.c +++ b/src/socks.c @@ -179,6 +179,20 @@ void * sockschild(struct clientparam* param) { #endif if ((param->remsock=so._socket(SASOCK(¶m->req), command == 2? SOCK_STREAM:SOCK_DGRAM, command == 2?IPPROTO_TCP:IPPROTO_UDP)) == INVALID_SOCKET) {RETURN (11);} param->operation = command == 2?BIND:UDPASSOC; +#ifdef REUSE + if (command == 2){ + int opt; + +#ifdef SO_REUSEADDR + opt = 1; + so._setsockopt(param->remsock, SOL_SOCKET, SO_REUSEADDR, (unsigned char *)&opt, sizeof(int)); +#endif +#ifdef SO_REUSEPORT + opt = 1; + so._setsockopt(param->remsock, SOL_SOCKET, SO_REUSEPORT, (unsigned char *)&opt, sizeof(int)); +#endif + } +#endif break; default: From 375a2c9f6e694f528757614fff0455a4e9425076 Mon Sep 17 00:00:00 2001 From: z3APA3A <3APA3A@3proxy.ru> Date: Sat, 23 Jan 2016 18:43:30 +0300 Subject: [PATCH 3/3] Do not use SO_REUSEADDR by default to avoid misbehavior in some glibc versions --- src/common.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/common.c b/src/common.c index 266563e..f4a68fb 100644 --- a/src/common.c +++ b/src/common.c @@ -648,7 +648,6 @@ int doconnect(struct clientparam * param){ } else { struct linger lg = {1,conf.timeouts[SINGLEBYTE_S]}; - int opt = 1; if(SAISNULL(¶m->sinsr)){ if(SAISNULL(¶m->req)) { @@ -660,26 +659,38 @@ int doconnect(struct clientparam * param){ if(!*SAPORT(¶m->sinsr))*SAPORT(¶m->sinsr) = *SAPORT(¶m->req); if ((param->remsock=so._socket(SASOCK(¶m->sinsr), SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {return (11);} so._setsockopt(param->remsock, SOL_SOCKET, SO_LINGER, (unsigned char *)&lg, sizeof(lg)); - so._setsockopt(param->remsock, SOL_SOCKET, SO_REUSEADDR, (unsigned char *)&opt, sizeof(int)); +#ifdef REUSE + { + int opt; + +#ifdef SO_REUSEADDR + opt = 1; + so._setsockopt(param->remsock, SOL_SOCKET, SO_REUSEADDR, (unsigned char *)&opt, sizeof(int)); +#endif +#ifdef SO_REUSEPORT + opt = 1; + so._setsockopt(param->remsock, SOL_SOCKET, SO_REUSEPORT, (unsigned char *)&opt, sizeof(int)); +#endif + } +#endif #ifndef NOIPV6 if(*SAFAMILY(¶m->sinsr) == AF_INET6) memcpy(¶m->sinsl, ¶m->srv->extsa6, sizeof(param->srv->extsa6)); else #endif memcpy(¶m->sinsl, ¶m->srv->extsa, sizeof(param->srv->extsa)); - if (param->srv->targetport && !*SAPORT(¶m->sinsl) && ntohs(*SAPORT(¶m->sincr)) > 1023) *SAPORT(¶m->sinsl) = *SAPORT(¶m->sincr); + *SAPORT(¶m->sinsl) = 0; if(so._bind(param->remsock, (struct sockaddr*)¶m->sinsl, SASIZE(¶m->sinsl))==-1) { - *SAPORT(¶m->sinsl) = 0; - if(so._bind(param->remsock, (struct sockaddr*)¶m->sinsl, SASIZE(¶m->sinsl))==-1) { - return 12; - } + return 12; } if(param->operation >= 256 || (param->operation & CONNECT)){ #ifdef _WIN32 unsigned long ul = 1; #endif - if(so._connect(param->remsock,(struct sockaddr *)¶m->sinsr,sizeof(param->sinsr))) {return (13);} + if(so._connect(param->remsock,(struct sockaddr *)¶m->sinsr,sizeof(param->sinsr))) { + return (13); + } param->nconnects++; #ifdef _WIN32 ioctlsocket(param->remsock, FIONBIO, &ul);