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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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