Support socket options for connback sockets and connection timeouts

This commit is contained in:
z3APA3A 2018-05-05 17:16:51 +03:00
parent b8127257f9
commit eb09ae7c58
8 changed files with 44 additions and 28 deletions

View File

@ -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

View File

@ -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;

View File

@ -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;
} }
} }

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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;
} 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);

View File

@ -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 {