From ea65f3834bf62839c1a86bc905b51c59dc362267 Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Tue, 13 Oct 2026 15:12:05 +0300 Subject: [PATCH] per-service timeouts --- man/3proxy.cfg.5 | 14 +++++ src/common.c | 6 +-- src/dnspr.c | 12 ++--- src/ftp.c | 22 ++++---- src/ftppr.c | 40 +++++++------- src/httpsrv.c | 18 +++---- src/imapp.c | 72 ++++++++++++------------- src/plugins/FilePlugin/FilePlugin.c | 12 ++--- src/pop3p.c | 26 ++++----- src/proxy.c | 72 ++++++++++++------------- src/proxymain.c | 7 +-- src/redirect.c | 30 +++++------ src/smtpp.c | 78 +++++++++++++-------------- src/sockmap.c | 2 +- src/socks.c | 62 ++++++++++----------- src/structures.h | 1 + src/tcppm.c | 2 +- src/tlspr.c | 84 ++++++++++++++--------------- src/udppm.c | 2 +- src/webadmin.c | 4 +- tests/cases/timeouts.py | 40 ++++++++++++++ 21 files changed, 331 insertions(+), 275 deletions(-) create mode 100644 tests/cases/timeouts.py diff --git a/man/3proxy.cfg.5 b/man/3proxy.cfg.5 index 66b4971..ffcca9a 100644 --- a/man/3proxy.cfg.5 +++ b/man/3proxy.cfg.5 @@ -485,6 +485,20 @@ value may cause the tail of the data to be lost on slow connections, too large o delays release of the sockets. .br default timeouts 1 5 30 60 180 1800 15 60 15 5 5 +.br + Like other service settings, timeouts apply to the services started after +the command, so services can have timeouts of their own: +.br + timeouts 1 5 30 60 180 1800 15 60 +.br + proxy -p3128 +.br + timeouts 1 5 30 60 180 7200 15 60 +.br + socks +.br +gives SOCKS a longer inactivity timeout than the HTTP proxy. The resolver and +RADIUS authentication, which serve all the services, use the values given last. .br .BR maxseg diff --git a/src/common.c b/src/common.c index b29bece..2c8ce21 100644 --- a/src/common.c +++ b/src/common.c @@ -772,7 +772,7 @@ int doconnect(struct clientparam * param){ } else { #ifndef _WIN32 - struct linger lg = {1,conf.timeouts[LINGER_TO]}; + struct linger lg = {1,param->srv->timeouts[LINGER_TO]}; #endif int tries = RANGETRIES; @@ -818,7 +818,7 @@ int doconnect(struct clientparam * param){ } if(!(param->operation >= 256 || (param->operation & CONNECT) || param->redirected)) break; - if(!connectwithpoll(param, param->remsock,(struct sockaddr *)¶m->sinsr,SASIZE(¶m->sinsr),conf.timeouts[CONNECT_TO])) break; + if(!connectwithpoll(param, param->remsock,(struct sockaddr *)¶m->sinsr,SASIZE(¶m->sinsr),param->srv->timeouts[CONNECT_TO])) break; /* The port was free to bind, but the pair it makes with the destination is still closing from an earlier connection through the same range, which Windows refuses. Another port out of the range may do. Anything @@ -1087,7 +1087,7 @@ int hascap(const unsigned char *line, const char *cap){ int getmultiline(struct clientparam *param, DIRECTION which, unsigned char *buf, int bufsize, const char *cap, int *found){ int i; do { - i = sockgetlinebuf(param, which, buf, bufsize, '\n', conf.timeouts[STRING_L]); + i = sockgetlinebuf(param, which, buf, bufsize, '\n', param->srv->timeouts[STRING_L]); if(i > 0 && cap && found && !*found){ buf[i] = 0; if(hascap(buf, cap)) *found = 1; diff --git a/src/dnspr.c b/src/dnspr.c index 29e51f5..551a2a6 100644 --- a/src/dnspr.c +++ b/src/dnspr.c @@ -156,7 +156,7 @@ void * dnsprchild(struct clientparam* param) { } param->sinsr = nservers[0].addr; if(nservers[0].usetcp) { - if(connectwithpoll(param, param->remsock,(struct sockaddr *)¶m->sinsr,SASIZE(¶m->sinsr),conf.timeouts[CONNECT_TO])) RETURN(830); + if(connectwithpoll(param, param->remsock,(struct sockaddr *)¶m->sinsr,SASIZE(¶m->sinsr),param->srv->timeouts[CONNECT_TO])) RETURN(830); buf-=2; *(unsigned short*)buf = htons(i); i+=2; @@ -169,12 +169,12 @@ void * dnsprchild(struct clientparam* param) { #endif } - if(socksendto(param, param->remsock, (struct sockaddr *)¶m->sinsr, buf, i, conf.timeouts[SINGLEBYTE_L]*1000) != i){ + if(socksendto(param, param->remsock, (struct sockaddr *)¶m->sinsr, buf, i, param->srv->timeouts[SINGLEBYTE_L]*1000) != i){ RETURN(820); } param->statscli64 += i; param->nwrites++; - len = sockrecvfrom(param, param->remsock, (struct sockaddr *)¶m->sinsr, buf, BUFSIZE, conf.timeouts[DNS_TO]*1000); + len = sockrecvfrom(param, param->remsock, (struct sockaddr *)¶m->sinsr, buf, BUFSIZE, param->srv->timeouts[DNS_TO]*1000); if(len <= 13) { RETURN(821); } @@ -186,11 +186,11 @@ void * dnsprchild(struct clientparam* param) { if(us > 4096) RETURN(833); buf += 2; len -= 2; - if(len < us) len += sockgetlinebuf(param, SERVER, buf+len, us - len, 0, conf.timeouts[SINGLEBYTE_L]); + if(len < us) len += sockgetlinebuf(param, SERVER, buf+len, us - len, 0, param->srv->timeouts[SINGLEBYTE_L]); if(len != us) RETURN(832); } if(buf[6] || buf[7]){ - if(socksendto(param, param->clisock, (struct sockaddr *)¶m->sincr, buf, len, conf.timeouts[SINGLEBYTE_L]*1000) != len){ + if(socksendto(param, param->clisock, (struct sockaddr *)¶m->sincr, buf, len, param->srv->timeouts[SINGLEBYTE_L]*1000) != len){ RETURN(822); } RETURN(0); @@ -201,7 +201,7 @@ void * dnsprchild(struct clientparam* param) { buf[2] = 0x85; buf[3] = 0x83; } - res = socksendto(param, param->clisock, (struct sockaddr *)¶m->sincr, buf, len, conf.timeouts[SINGLEBYTE_L]*1000); + res = socksendto(param, param->clisock, (struct sockaddr *)¶m->sincr, buf, len, param->srv->timeouts[SINGLEBYTE_L]*1000); if(res != len){RETURN(819);} if(!ip) {RETURN(888);} diff --git a/src/ftp.c b/src/ftp.c index 997286a..d3b3d5c 100644 --- a/src/ftp.c +++ b/src/ftp.c @@ -17,7 +17,7 @@ static int ftpreadresponse(struct clientparam *param, char *buf, int buflen) { int i; while((i = sockgetlinebuf(param, SERVER, (unsigned char *)buf, buflen - 1, '\n', - conf.timeouts[STRING_L])) > 0 + param->srv->timeouts[STRING_L])) > 0 && (i < 3 || !isnumber(*buf) || buf[3] == '-')) {} return i; } @@ -42,7 +42,7 @@ int ftplogin(struct clientparam *param, char *nbuf, int *innbuf) { return 702; } sprintf(buf, "USER %.128s\r\n", *param->extusername?param->extusername:(unsigned char *)"anonymous"); - if((int)socksend(param, param->remsock, (unsigned char *)buf, (int)strlen(buf), conf.timeouts[STRING_S]) != (int)strlen(buf)){ + if((int)socksend(param, param->remsock, (unsigned char *)buf, (int)strlen(buf), param->srv->timeouts[STRING_S]) != (int)strlen(buf)){ return 703; } param->statscli64 += (int)strlen(buf); @@ -55,12 +55,12 @@ int ftplogin(struct clientparam *param, char *nbuf, int *innbuf) { sprintf(buf, "PASS %.128s\r\n", *param->extusername? param->extpassword : (unsigned char *)"3proxy@"); res = (int)strlen(buf); - if((int)socksend(param, param->remsock, (unsigned char *)buf, res, conf.timeouts[STRING_S]) != (int)strlen(buf)){ + if((int)socksend(param, param->remsock, (unsigned char *)buf, res, param->srv->timeouts[STRING_S]) != (int)strlen(buf)){ return 705; } param->statscli64 += res; param->nwrites++; - while((i = sockgetlinebuf(param, SERVER, (unsigned char *)buf, len - 1, '\n', conf.timeouts[STRING_L])) > 0){ + while((i = sockgetlinebuf(param, SERVER, (unsigned char *)buf, len - 1, '\n', param->srv->timeouts[STRING_L])) > 0){ buf[i] = 0; res = (i>3 && buf[3] != '-')? atoi(buf)/100 : 0; if(res || (nbuf && (len-i) > 256 && i > 3)) { @@ -86,12 +86,12 @@ int ftpcd(struct clientparam *param, unsigned char* path, char *nbuf, int *innbu int inbuf = 0; sprintf(buf, "CWD %.512s\r\n", path); - if((int)socksend(param, param->remsock, (unsigned char *)buf, (int)strlen(buf), conf.timeouts[STRING_S]) != (int)strlen(buf)){ + if((int)socksend(param, param->remsock, (unsigned char *)buf, (int)strlen(buf), param->srv->timeouts[STRING_S]) != (int)strlen(buf)){ return 711; } param->statscli64 += (int)strlen(buf); param->nwrites++; - while((i = sockgetlinebuf(param, SERVER, (unsigned char *)buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L])) > 0 && (i < 3 || !isnumber(*buf) || buf[3] == '-')){ + while((i = sockgetlinebuf(param, SERVER, (unsigned char *)buf, sizeof(buf) - 1, '\n', param->srv->timeouts[STRING_L])) > 0 && (i < 3 || !isnumber(*buf) || buf[3] == '-')){ if(nbuf && innbuf && inbuf + i < *innbuf && i > 6) { memcpy(nbuf + inbuf, buf, i); inbuf += i; @@ -118,7 +118,7 @@ int ftpres(struct clientparam *param, unsigned char * buf, int l){ int ftpsyst(struct clientparam *param, unsigned char *buf, unsigned len){ int i; - if(socksend(param, param->remsock, (unsigned char *)"SYST\r\n", 6, conf.timeouts[STRING_S]) != 6){ + if(socksend(param, param->remsock, (unsigned char *)"SYST\r\n", 6, param->srv->timeouts[STRING_S]) != 6){ return 721; } param->statscli64 += 6; @@ -136,7 +136,7 @@ int ftppwd(struct clientparam *param, unsigned char *buf, unsigned len){ int i; char *b, *e; - if(socksend(param, param->remsock, (unsigned char *)"PWD\r\n", 5, conf.timeouts[STRING_S]) != 5){ + if(socksend(param, param->remsock, (unsigned char *)"PWD\r\n", 5, param->srv->timeouts[STRING_S]) != 5){ return 731; } param->statscli64 += 5; @@ -160,7 +160,7 @@ int ftptype(struct clientparam *param, unsigned char* f_type){ int i; sprintf(buf, "TYPE %.512s\r\n", f_type); - if((int)socksend(param, param->remsock, (unsigned char *)buf, (int)strlen(buf), conf.timeouts[STRING_S]) != (int)strlen(buf)){ + if((int)socksend(param, param->remsock, (unsigned char *)buf, (int)strlen(buf), param->srv->timeouts[STRING_S]) != (int)strlen(buf)){ return 741; } param->statscli64 += (int)strlen(buf); @@ -181,7 +181,7 @@ SOCKET ftpdata(struct clientparam *param){ unsigned short b5, b6; SASIZETYPE sasize; - if(socksend(param, param->remsock, (unsigned char *)"PASV\r\n", 6, conf.timeouts[STRING_S]) != 6){ + if(socksend(param, param->remsock, (unsigned char *)"PASV\r\n", 6, param->srv->timeouts[STRING_S]) != 6){ return INVALID_SOCKET; } param->statscli64 += 6; @@ -231,7 +231,7 @@ SOCKET ftpcommand(struct clientparam *param, unsigned char * command, unsigned c sprintf(buf, "%.15s%s%.512s\r\n", command, arg? (unsigned char *)" ":(unsigned char *)"", arg?arg:(unsigned char *)""); - if((int)socksend(param, param->remsock, (unsigned char *)buf, (int)strlen(buf), conf.timeouts[STRING_S]) != (int)strlen(buf)){ + if((int)socksend(param, param->remsock, (unsigned char *)buf, (int)strlen(buf), param->srv->timeouts[STRING_S]) != (int)strlen(buf)){ param->srv->so._closesocket(param->sostate, s); return INVALID_SOCKET; } diff --git a/src/ftppr.c b/src/ftppr.c index ff64d9b..52ae032 100644 --- a/src/ftppr.c +++ b/src/ftppr.c @@ -33,11 +33,11 @@ void * ftpprchild(struct clientparam* param) { param->operation = CONNECT; #ifndef _WIN32 lg.l_onoff = 1; - lg.l_linger = conf.timeouts[STRING_L]; + lg.l_linger = param->srv->timeouts[STRING_L]; #endif - if(socksend(param, param->ctrlsock, (unsigned char *)"220 Ready\r\n", 11, conf.timeouts[STRING_S])!=11) {RETURN (801);} + if(socksend(param, param->ctrlsock, (unsigned char *)"220 Ready\r\n", 11, param->srv->timeouts[STRING_S])!=11) {RETURN (801);} for(;;){ - i = sockgetlinebuf(param, CLIENT, buf, BUFSIZE - 10, '\n', conf.timeouts[CONNECTION_S]); + i = sockgetlinebuf(param, CLIENT, buf, BUFSIZE - 10, '\n', param->srv->timeouts[CONNECTION_S]); if(!i) { RETURN(0); } @@ -56,7 +56,7 @@ void * ftpprchild(struct clientparam* param) { } if((res = (*param->srv->authfunc)(param))) {RETURN(res);} param->ctrlsocksrv = param->remsock; - if(socksend(param, param->ctrlsock, (unsigned char *)"220 Ready\r\n", 11, conf.timeouts[STRING_S])!=11) {RETURN (801);} + if(socksend(param, param->ctrlsock, (unsigned char *)"220 Ready\r\n", 11, param->srv->timeouts[STRING_S])!=11) {RETURN (801);} status = 1; } else if (!strncasecmp((char *)buf, "USER ", 5)){ @@ -65,7 +65,7 @@ void * ftpprchild(struct clientparam* param) { if((res = (*param->srv->authfunc)(param))) {RETURN(res);} param->ctrlsocksrv = param->remsock; } - if(socksend(param, param->ctrlsock, (unsigned char *)"331 ok\r\n", 8, conf.timeouts[STRING_S])!=8) {RETURN (807);} + if(socksend(param, param->ctrlsock, (unsigned char *)"331 ok\r\n", 8, param->srv->timeouts[STRING_S])!=8) {RETURN (807);} status = 2; } @@ -74,14 +74,14 @@ void * ftpprchild(struct clientparam* param) { with USER. Without it there is nothing to log in to, and what follows would read the name and the host as if there were. */ if(!*param->hostname || !*param->extusername){ - socksend(param, param->ctrlsock, (unsigned char *)"503 Login with USER first\r\n", 27, conf.timeouts[STRING_S]); + socksend(param, param->ctrlsock, (unsigned char *)"503 Login with USER first\r\n", 27, param->srv->timeouts[STRING_S]); RETURN(805); } if(PARAMSTR(param, extpassword, buf+5)){RETURN(806);} inbuf = BUFSIZE; res = ftplogin(param, (char *)buf, &inbuf); param->res = res; - if(inbuf && inbuf != BUFSIZE && socksend(param, param->ctrlsock, buf, inbuf, conf.timeouts[STRING_S])!=inbuf) {RETURN (807);} + if(inbuf && inbuf != BUFSIZE && socksend(param, param->ctrlsock, buf, inbuf, param->srv->timeouts[STRING_S])!=inbuf) {RETURN (807);} if(!res) status = 3; sprintf((char *)buf, "%.128s@%.128s%c%hu", param->extusername, param->hostname, (ntohs(*SAPORT(¶m->sinsr))==21)?0:':', ntohs(*SAPORT(¶m->sinsr))); req = strdup((char *)buf); @@ -167,7 +167,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(¶m->sincr) = htons((uint16_t)((b5<<8)^b6)); - if(connectwithpoll(param, clidatasock, (struct sockaddr *)¶m->sincr, SASIZE(¶m->sincr),conf.timeouts[CONNECT_TO])) { + if(connectwithpoll(param, clidatasock, (struct sockaddr *)¶m->sincr, SASIZE(¶m->sincr),param->srv->timeouts[CONNECT_TO])) { param->srv->so._closesocket(param->sostate, clidatasock); clidatasock = INVALID_SOCKET; RETURN(826); @@ -187,7 +187,7 @@ void * ftpprchild(struct clientparam* param) { if(action != PASS) RETURN(879); } #endif - if(socksend(param, param->ctrlsock, buf, (int)strlen((char *)buf), conf.timeouts[STRING_S])!=(int)strlen((char *)buf)) {RETURN (825);} + if(socksend(param, param->ctrlsock, buf, (int)strlen((char *)buf), param->srv->timeouts[STRING_S])!=(int)strlen((char *)buf)) {RETURN (825);} status = 4; } else if (status == 4 && ( @@ -222,7 +222,7 @@ void * ftpprchild(struct clientparam* param) { fds.fd = clidatasock; fds.events = POLLIN; - res = param->srv->so._poll (param->sostate, &fds, 1, conf.timeouts[STRING_L]*1000); + res = param->srv->so._poll (param->sostate, &fds, 1, param->srv->timeouts[STRING_L]*1000); if(res != 1) { RETURN(857); } @@ -249,16 +249,16 @@ void * ftpprchild(struct clientparam* param) { param->srv->so._closesocket(param->sostate, clidatasock); clidatasock = INVALID_SOCKET; - if(socksend(param, param->ctrlsock, (unsigned char *)"550 err\r\n", 9, conf.timeouts[STRING_S])!=9) {RETURN (831);} + if(socksend(param, param->ctrlsock, (unsigned char *)"550 err\r\n", 9, param->srv->timeouts[STRING_S])!=9) {RETURN (831);} continue; } - if(socksend(param, param->ctrlsock, (unsigned char *)"125 data\r\n", 10, conf.timeouts[STRING_S]) != 10) { + if(socksend(param, param->ctrlsock, (unsigned char *)"125 data\r\n", 10, param->srv->timeouts[STRING_S]) != 10) { param->remsock = INVALID_SOCKET; RETURN (832); } if(param->srvoffset < param->srvinbuf)while((i = sockgetlinebuf(param, SERVER, buf, BUFSIZE, '\n', 0)) > 3){ - if(socksend(param, param->ctrlsock, buf, i, conf.timeouts[STRING_S])!=i) {RETURN(833);} + if(socksend(param, param->ctrlsock, buf, i, param->srv->timeouts[STRING_S])!=i) {RETURN(833);} if(isnumber(*buf) && buf[3] != '-') { ressent = 1; break; @@ -272,7 +272,7 @@ void * ftpprchild(struct clientparam* param) { param->srv->so._setsockopt(param->sostate, clidatasock, SOL_SOCKET, SO_LINGER, (char *)&lg, sizeof(lg)); #endif param->clisock = clidatasock; - res = mapsocket(param, conf.timeouts[CONNECTION_S]); + res = mapsocket(param, param->srv->timeouts[CONNECTION_S]); if(param->remsock != INVALID_SOCKET) { param->srv->so._shutdown (param->sostate, param->remsock, SHUT_RDWR); param->srv->so._closesocket(param->sostate, param->remsock); @@ -287,8 +287,8 @@ void * ftpprchild(struct clientparam* param) { ss = INVALID_SOCKET; clidatasock = INVALID_SOCKET; if(!ressent){ - while((i = sockgetlinebuf(param, SERVER, buf, BUFSIZE, '\n', conf.timeouts[STRING_L])) > 3){ - if(socksend(param, param->ctrlsock, buf, i, conf.timeouts[STRING_S])!=i) {RETURN(833);} + while((i = sockgetlinebuf(param, SERVER, buf, BUFSIZE, '\n', param->srv->timeouts[STRING_L])) > 3){ + if(socksend(param, param->ctrlsock, buf, i, param->srv->timeouts[STRING_S])!=i) {RETURN(833);} if(isnumber(*buf) && buf[3] != '-') break; } if(i < 3) {RETURN(834);} @@ -296,7 +296,7 @@ void * ftpprchild(struct clientparam* param) { } else { if(status < 3) { - if(socksend(param, param->remsock, (unsigned char *)"530 login\r\n", 11, conf.timeouts[STRING_S])!=1) {RETURN (810);} + if(socksend(param, param->remsock, (unsigned char *)"530 login\r\n", 11, param->srv->timeouts[STRING_S])!=1) {RETURN (810);} continue; } if(!strncasecmp((char *)buf, "QUIT", 4)) status = 5; @@ -304,11 +304,11 @@ void * ftpprchild(struct clientparam* param) { i = (int)strlen((char *)buf); buf[i++] = '\r'; buf[i++] = '\n'; - if(socksend(param, param->remsock, buf, i, conf.timeouts[STRING_S])!=i) {RETURN (811);} + if(socksend(param, param->remsock, buf, i, param->srv->timeouts[STRING_S])!=i) {RETURN (811);} param->statscli64+=(i); param->nwrites++; - while((i = sockgetlinebuf(param, SERVER, buf, BUFSIZE, '\n', conf.timeouts[STRING_L])) > 0){ - if(socksend(param, param->ctrlsock, buf, i, conf.timeouts[STRING_S])!=i) {RETURN (812);} + while((i = sockgetlinebuf(param, SERVER, buf, BUFSIZE, '\n', param->srv->timeouts[STRING_L])) > 0){ + if(socksend(param, param->ctrlsock, buf, i, param->srv->timeouts[STRING_S])!=i) {RETURN (812);} if(i > 4 && isnumber(*buf) && buf[3] != '-') break; } if(status == 5) {RETURN (0);} diff --git a/src/httpsrv.c b/src/httpsrv.c index 9e1065d..a754dfe 100644 --- a/src/httpsrv.c +++ b/src/httpsrv.c @@ -150,7 +150,7 @@ static int64_t qparam(const char *query, const char *name, int64_t def) static int httpsrv_send(struct httpreq *r, const char *buf, int len) { return socksend(r->param, r->param->clisock, (unsigned char *)buf, len, - conf.timeouts[STRING_S]) != len; + r->param->srv->timeouts[STRING_S]) != len; } static int httpsrv_printf(struct httpreq *r, const char *fmt, ...) @@ -339,17 +339,17 @@ int httpchunk(struct clientparam *param, const char *buf, int len) if(len <= 0){ return socksend(param, param->clisock, (unsigned char *)"0\r\n\r\n", 5, - conf.timeouts[STRING_S]) != 5; + param->srv->timeouts[STRING_S]) != 5; } hlen = sprintf(hdr, "%x\r\n", len); if(socksend(param, param->clisock, (unsigned char *)hdr, hlen, - conf.timeouts[STRING_S]) != hlen) return 1; + param->srv->timeouts[STRING_S]) != hlen) return 1; if(socksend(param, param->clisock, (unsigned char *)buf, len, - conf.timeouts[STRING_S]) != len) return 1; + param->srv->timeouts[STRING_S]) != len) return 1; return socksend(param, param->clisock, (unsigned char *)"\r\n", 2, - conf.timeouts[STRING_S]) != 2; + param->srv->timeouts[STRING_S]) != 2; } /* Fills buf with a repeating pattern carrying its own offset, so a truncated or @@ -1146,7 +1146,7 @@ static void httpsrv_drain(struct clientparam *param, uint64_t len) while(len){ int want = (len > (uint64_t)HTTPSRV_BLOCK)? (int)HTTPSRV_BLOCK : (int)len; int got = sockgetlinebuf(param, CLIENT, (unsigned char *)buf, want, EOF, - conf.timeouts[STRING_S]); + param->srv->timeouts[STRING_S]); if(got <= 0) break; len -= (uint64_t)got; @@ -1164,7 +1164,7 @@ static void httpsrv_linger(struct clientparam *param) char *buf = (char *)param->tmpbuf; struct pollfd fd; uint64_t left = HTTPSRV_MAXBODY; - time_t deadline = time(NULL) + conf.timeouts[LINGER_TO]; + time_t deadline = time(NULL) + param->srv->timeouts[LINGER_TO]; if(param->clisock == INVALID_SOCKET) return; if(param->srv->so._shutdown(param->sostate, param->clisock, SHUT_WR)) return; @@ -1268,7 +1268,7 @@ static int httpsrv_request(struct clientparam *param, struct httpreq *r) does not fit in the buffer is not answered. */ param->climark = (int)param->clioffset; i = sockgetlinebuf(param, CLIENT, (unsigned char *)buf, sizeof(buf) - 1, '\n', - conf.timeouts[STRING_S]); + param->srv->timeouts[STRING_S]); if(i <= 0 && !r->first) return 0; /* the client is done with us */ if(param->climark == -2) RETURN(710); if(i < 5) RETURN(701); @@ -1350,7 +1350,7 @@ static int httpsrv_request(struct clientparam *param, struct httpreq *r) bounds what is read and not what a client may send in one header. */ while(hdrs < HTTPSRV_MAXHDR && (i = sockgetlinebuf(param, CLIENT, (unsigned char *)buf, sizeof(buf) - 1, - '\n', conf.timeouts[STRING_S])) > 2){ + '\n', param->srv->timeouts[STRING_S])) > 2){ hdrs++; buf[i] = 0; if(!strncasecmp(buf, "host:", 5) && !r->proxy){ diff --git a/src/imapp.c b/src/imapp.c index 2d3d1d8..42368f1 100644 --- a/src/imapp.c +++ b/src/imapp.c @@ -37,9 +37,9 @@ void * imappchild(struct clientparam* param) { *tag = 0; i = sprintf((char *)buf, "* OK [CAPABILITY IMAP4rev1%s AUTH=PLAIN AUTH=LOGIN] IMAP4rev1 Proxy Ready\r\n", NOSTARTTLS?"":" STARTTLS"); - if(socksend(param, param->clisock, buf, i, conf.timeouts[STRING_S])!=i) {RETURN (691);} + if(socksend(param, param->clisock, buf, i, param->srv->timeouts[STRING_S])!=i) {RETURN (691);} for(;;){ - i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', conf.timeouts[STRING_S]); + i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', param->srv->timeouts[STRING_S]); if(i < 4) {RETURN(692);} buf[i] = 0; if ((se=(unsigned char *)strchr((char *)buf, '\r'))) *se = 0; @@ -48,22 +48,22 @@ void * imappchild(struct clientparam* param) { tag[se - buf] = 0; cmd = se + 1; if(!strncasecmp((char *)cmd, "LOGOUT", 6)){ - socksend(param, param->clisock, (unsigned char *)"* BYE\r\n", 7, conf.timeouts[STRING_S]); + socksend(param, param->clisock, (unsigned char *)"* BYE\r\n", 7, param->srv->timeouts[STRING_S]); sprintf((char *)buf, "%.60s OK LOGOUT completed\r\n", (char *)tag); - socksend(param, param->clisock, buf, (int)strlen((char *)buf), conf.timeouts[STRING_S]); + socksend(param, param->clisock, buf, (int)strlen((char *)buf), param->srv->timeouts[STRING_S]); RETURN(0); } if(!strncasecmp((char *)cmd, "CAPABILITY", 10)){ i = sprintf((char *)buf, "* CAPABILITY IMAP4rev1%s AUTH=PLAIN AUTH=LOGIN\r\n", NOSTARTTLS?"":" STARTTLS"); - socksend(param, param->clisock, buf, i, conf.timeouts[STRING_S]); + socksend(param, param->clisock, buf, i, param->srv->timeouts[STRING_S]); sprintf((char *)buf, "%.60s OK CAPABILITY completed\r\n", (char *)tag); - socksend(param, param->clisock, buf, (int)strlen((char *)buf), conf.timeouts[STRING_S]); + socksend(param, param->clisock, buf, (int)strlen((char *)buf), param->srv->timeouts[STRING_S]); continue; } #ifndef WITHMAIN if(!strncasecmp((char *)cmd, "STARTTLS", 8) && !param->srv->nostarttls){ sprintf((char *)buf, "%.60s OK Begin TLS negotiation\r\n", (char *)tag); - if(socksend(param, param->clisock, buf, (int)strlen((char *)buf), conf.timeouts[STRING_S]) <= 0) {RETURN(698);} + if(socksend(param, param->clisock, buf, (int)strlen((char *)buf), param->srv->timeouts[STRING_S]) <= 0) {RETURN(698);} param->clientstarttls = S_IMAPP; if(!param->srv->targetport) param->srv->targetport = htons(143); return (void *)tlsprchild; @@ -93,8 +93,8 @@ void * imappchild(struct clientparam* param) { se = cmd + 18; if(*se == ' ') se++; else se = NULL; if(!se || !*se){ - if(socksend(param, param->clisock, (unsigned char *)"+ \r\n", 4, conf.timeouts[STRING_S])!=4) {RETURN(698);} - i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', conf.timeouts[STRING_S]); + if(socksend(param, param->clisock, (unsigned char *)"+ \r\n", 4, param->srv->timeouts[STRING_S])!=4) {RETURN(698);} + i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', param->srv->timeouts[STRING_S]); if(i < 1) {RETURN(698);} buf[i] = 0; if ((se=(unsigned char *)strchr((char *)buf, '\r'))) *se = 0; @@ -129,8 +129,8 @@ void * imappchild(struct clientparam* param) { ub[i] = 0; } else { - if(socksend(param, param->clisock, (unsigned char *)"+ VXNlcm5hbWU6\r\n", 16, conf.timeouts[STRING_S])!=16) {RETURN(698);} - i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', conf.timeouts[STRING_S]); + if(socksend(param, param->clisock, (unsigned char *)"+ VXNlcm5hbWU6\r\n", 16, param->srv->timeouts[STRING_S])!=16) {RETURN(698);} + i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', param->srv->timeouts[STRING_S]); if(i < 1) {RETURN(698);} buf[i] = 0; if ((se=(unsigned char *)strchr((char *)buf, '\r'))) *se = 0; @@ -138,8 +138,8 @@ void * imappchild(struct clientparam* param) { if(i < 0) {RETURN(693);} ub[i] = 0; } - if(socksend(param, param->clisock, (unsigned char *)"+ UGFzc3dvcmQ6\r\n", 16, conf.timeouts[STRING_S])!=16) {RETURN(698);} - i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', conf.timeouts[STRING_S]); + if(socksend(param, param->clisock, (unsigned char *)"+ UGFzc3dvcmQ6\r\n", 16, param->srv->timeouts[STRING_S])!=16) {RETURN(698);} + i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', param->srv->timeouts[STRING_S]); if(i < 1) {RETURN(698);} buf[i] = 0; if ((se=(unsigned char *)strchr((char *)buf, '\r'))) *se = 0; @@ -149,14 +149,14 @@ void * imappchild(struct clientparam* param) { break; } sprintf((char *)buf, "%.60s BAD need LOGIN first\r\n", (char *)tag); - socksend(param, param->clisock, buf, (int)strlen((char *)buf), conf.timeouts[STRING_S]); + socksend(param, param->clisock, buf, (int)strlen((char *)buf), param->srv->timeouts[STRING_S]); } if(parseconnusername((char *)ub, param, 0, 143)){RETURN(694);} if(*pb && !*param->password && PARAMSTR(param, password, pb)){RETURN(694);} param->operation = CONNECT; res = (*param->srv->authfunc)(param); if(res) {RETURN(res);} - i = sockgetlinebuf(param, SERVER, srvbuf, sizeof(srvbuf) - 1, '\n', conf.timeouts[STRING_L]); + i = sockgetlinebuf(param, SERVER, srvbuf, sizeof(srvbuf) - 1, '\n', param->srv->timeouts[STRING_L]); if( i < 4 ) {RETURN(695);} srvbuf[i] = 0; if(strncasecmp((char *)srvbuf, "* OK", 4)){RETURN(696);} @@ -165,9 +165,9 @@ void * imappchild(struct clientparam* param) { if(hascap(se, "AUTH=LOGIN")) caps |= CAP_LOGIN; } else { - if(socksend(param, param->remsock, (unsigned char *)"zz CAPABILITY\r\n", 15, conf.timeouts[STRING_S])!=15) {RETURN(697);} + if(socksend(param, param->remsock, (unsigned char *)"zz CAPABILITY\r\n", 15, param->srv->timeouts[STRING_S])!=15) {RETURN(697);} for(;;){ - i = sockgetlinebuf(param, SERVER, srvbuf, sizeof(srvbuf) - 1, '\n', conf.timeouts[STRING_L]); + i = sockgetlinebuf(param, SERVER, srvbuf, sizeof(srvbuf) - 1, '\n', param->srv->timeouts[STRING_L]); if(i < 3) {RETURN(697);} srvbuf[i] = 0; if(!strncasecmp((char *)srvbuf, "* CAPABILITY", 12)){ @@ -190,36 +190,36 @@ void * imappchild(struct clientparam* param) { ibuf[i + 1] = 0; memcpy(ibuf + i + 2, pb, res); if(!en64(ibuf, srvbuf, i + res + 2, (int)sizeof(srvbuf))) {RETURN(693);} - if( socksend(param, param->remsock, tag, (int)strlen((char *)tag), conf.timeouts[STRING_S]) <= 0 || - socksend(param, param->remsock, (unsigned char *)" AUTHENTICATE PLAIN ", 20, conf.timeouts[STRING_S])!= 20 || - socksend(param, param->remsock, srvbuf, (int)strlen((char *)srvbuf), conf.timeouts[STRING_S]) <= 0 || - socksend(param, param->remsock, (unsigned char *)"\r\n", 2, conf.timeouts[STRING_S])!=2) + if( socksend(param, param->remsock, tag, (int)strlen((char *)tag), param->srv->timeouts[STRING_S]) <= 0 || + socksend(param, param->remsock, (unsigned char *)" AUTHENTICATE PLAIN ", 20, param->srv->timeouts[STRING_S])!= 20 || + socksend(param, param->remsock, srvbuf, (int)strlen((char *)srvbuf), param->srv->timeouts[STRING_S]) <= 0 || + socksend(param, param->remsock, (unsigned char *)"\r\n", 2, param->srv->timeouts[STRING_S])!=2) {RETURN(699);} } else if(method == CL_LOGIN){ - if( socksend(param, param->remsock, tag, (int)strlen((char *)tag), conf.timeouts[STRING_S]) <= 0 || - socksend(param, param->remsock, (unsigned char *)" AUTHENTICATE LOGIN\r\n", 21, conf.timeouts[STRING_S])!= 21) + if( socksend(param, param->remsock, tag, (int)strlen((char *)tag), param->srv->timeouts[STRING_S]) <= 0 || + socksend(param, param->remsock, (unsigned char *)" AUTHENTICATE LOGIN\r\n", 21, param->srv->timeouts[STRING_S])!= 21) {RETURN(699);} - i = sockgetlinebuf(param, SERVER, srvbuf, sizeof(srvbuf) - 1, '\n', conf.timeouts[STRING_L]); + i = sockgetlinebuf(param, SERVER, srvbuf, sizeof(srvbuf) - 1, '\n', param->srv->timeouts[STRING_L]); if(i < 1 || *srvbuf != '+') {RETURN(699);} if(!en64(param->extusername, ibuf, (int)strlen((char *)param->extusername), (int)sizeof(ibuf))) {RETURN(693);} - if( socksend(param, param->remsock, ibuf, (int)strlen((char *)ibuf), conf.timeouts[STRING_S]) <= 0 || - socksend(param, param->remsock, (unsigned char *)"\r\n", 2, conf.timeouts[STRING_S])!=2) + if( socksend(param, param->remsock, ibuf, (int)strlen((char *)ibuf), param->srv->timeouts[STRING_S]) <= 0 || + socksend(param, param->remsock, (unsigned char *)"\r\n", 2, param->srv->timeouts[STRING_S])!=2) {RETURN(699);} - i = sockgetlinebuf(param, SERVER, srvbuf, sizeof(srvbuf) - 1, '\n', conf.timeouts[STRING_L]); + i = sockgetlinebuf(param, SERVER, srvbuf, sizeof(srvbuf) - 1, '\n', param->srv->timeouts[STRING_L]); if(i < 1 || *srvbuf != '+') {RETURN(699);} if(!en64(pb, ibuf, (int)strlen((char *)pb), (int)sizeof(ibuf))) {RETURN(693);} - if( socksend(param, param->remsock, ibuf, (int)strlen((char *)ibuf), conf.timeouts[STRING_S]) <= 0 || - socksend(param, param->remsock, (unsigned char *)"\r\n", 2, conf.timeouts[STRING_S])!=2) + if( socksend(param, param->remsock, ibuf, (int)strlen((char *)ibuf), param->srv->timeouts[STRING_S]) <= 0 || + socksend(param, param->remsock, (unsigned char *)"\r\n", 2, param->srv->timeouts[STRING_S])!=2) {RETURN(699);} } else { - if( socksend(param, param->remsock, tag, (int)strlen((char *)tag), conf.timeouts[STRING_S]) <= 0 || - socksend(param, param->remsock, (unsigned char *)" LOGIN ", 7, conf.timeouts[STRING_S])!= 7 || - socksend(param, param->remsock, param->extusername, (int)strlen((char *)param->extusername), conf.timeouts[STRING_S]) <= 0 || - socksend(param, param->remsock, (unsigned char *)" ", 1, conf.timeouts[STRING_S])!= 1 || - socksend(param, param->remsock, pb, (int)strlen((char *)pb), conf.timeouts[STRING_S]) <= 0 || - socksend(param, param->remsock, (unsigned char *)"\r\n", 2, conf.timeouts[STRING_S])!=2) + if( socksend(param, param->remsock, tag, (int)strlen((char *)tag), param->srv->timeouts[STRING_S]) <= 0 || + socksend(param, param->remsock, (unsigned char *)" LOGIN ", 7, param->srv->timeouts[STRING_S])!= 7 || + socksend(param, param->remsock, param->extusername, (int)strlen((char *)param->extusername), param->srv->timeouts[STRING_S]) <= 0 || + socksend(param, param->remsock, (unsigned char *)" ", 1, param->srv->timeouts[STRING_S])!= 1 || + socksend(param, param->remsock, pb, (int)strlen((char *)pb), param->srv->timeouts[STRING_S]) <= 0 || + socksend(param, param->remsock, (unsigned char *)"\r\n", 2, param->srv->timeouts[STRING_S])!=2) {RETURN(699);} } param->statscli64 += (uint64_t)(strlen((char *)tag) + strlen((char *)param->extusername) + strlen((char *)pb) + 11); @@ -235,7 +235,7 @@ CLEANRET: if(param->clisock != INVALID_SOCKET) { if ((param->res > 0 && param->res < 100) || (param->res > 691 && param->res <700)) { sprintf((char *)buf, "%.60s NO proxy error\r\n", *tag? (char *)tag : "*"); - socksend(param, param->clisock, buf, (int)strlen((char *)buf),conf.timeouts[STRING_S]); + socksend(param, param->clisock, buf, (int)strlen((char *)buf),param->srv->timeouts[STRING_S]); } } return (NULL); diff --git a/src/plugins/FilePlugin/FilePlugin.c b/src/plugins/FilePlugin/FilePlugin.c index ba9fc18..94ca52f 100644 --- a/src/plugins/FilePlugin/FilePlugin.c +++ b/src/plugins/FilePlugin/FilePlugin.c @@ -286,7 +286,7 @@ void processcallbacks(struct fp_stream *fps, int what, char *msg, int size){ case GOT_SMTP_REQ: case GOT_SMTP_DATA: fps->state = FLUSH_DATA; - pl->socksend(fps->fpd.cp->sostate,fps->fpd.cp->clisock, (unsigned char *)fp_stringtable[1], (int)strlen((char *)fp_stringtable[1]), pl->conf->timeouts[STRING_S]); + pl->socksend(fps->fpd.cp->sostate,fps->fpd.cp->clisock, (unsigned char *)fp_stringtable[1], (int)strlen((char *)fp_stringtable[1]), fps->fpd.cp->srv->timeouts[STRING_S]); fps->state = state; break; case GOT_HTTP_REQUEST: @@ -298,7 +298,7 @@ void processcallbacks(struct fp_stream *fps, int what, char *msg, int size){ case GOT_HTTP_SRVDATA: if(!fps->serversent){ fps->state = FLUSH_DATA; - pl->socksend(fps->fpd.cp->sostate, fps->fpd.cp->clisock, (unsigned char *)fp_stringtable[0], (int)strlen((char *)fp_stringtable[0]), pl->conf->timeouts[STRING_S]); + pl->socksend(fps->fpd.cp->sostate, fps->fpd.cp->clisock, (unsigned char *)fp_stringtable[0], (int)strlen((char *)fp_stringtable[0]), fps->fpd.cp->srv->timeouts[STRING_S]); fps->state = state; } break; @@ -306,7 +306,7 @@ void processcallbacks(struct fp_stream *fps, int what, char *msg, int size){ case GOT_FTP_REQ: case GOT_FTP_SRVDATA: fps->state = FLUSH_DATA; - pl->socksend(fps->fpd.cp->sostate, fps->fpd.cp->ctrlsock, (unsigned char *)fp_stringtable[1], (int)strlen((char *)fp_stringtable[1]), pl->conf->timeouts[STRING_S]); + pl->socksend(fps->fpd.cp->sostate, fps->fpd.cp->ctrlsock, (unsigned char *)fp_stringtable[1], (int)strlen((char *)fp_stringtable[1]), fps->fpd.cp->srv->timeouts[STRING_S]); fps->state = state; break; default: @@ -358,7 +358,7 @@ static int copyfdtosock(struct fp_stream * fps, DIRECTION which, long len){ if(fps->serversent >= fps->srvhdrwritten){ sprintf(fps->buf, "%lx\r\n", len); sendchunk = (int)strlen(fps->buf); - if(pl->socksend(fps->fpd.cp->sostate, fps->fpd.cp->clisock, (unsigned char *)fps->buf, sendchunk, pl->conf->timeouts[STRING_S]) != sendchunk){ + if(pl->socksend(fps->fpd.cp->sostate, fps->fpd.cp->clisock, (unsigned char *)fps->buf, sendchunk, fps->fpd.cp->srv->timeouts[STRING_S]) != sendchunk){ return -4; } } @@ -397,13 +397,13 @@ static int copyfdtosock(struct fp_stream * fps, DIRECTION which, long len){ #endif return -3; } - if(pl->socksend(fps->fpd.cp->sostate, sock, (unsigned char *)fps->buf, res, pl->conf->timeouts[STRING_S]) != res) { + if(pl->socksend(fps->fpd.cp->sostate, sock, (unsigned char *)fps->buf, res, fps->fpd.cp->srv->timeouts[STRING_S]) != res) { return -4; } len -= res; } if(sendchunk){ - if(pl->socksend(fps->fpd.cp->sostate, sock, (unsigned char *)"\r\n", 2, pl->conf->timeouts[STRING_S]) != 2) + if(pl->socksend(fps->fpd.cp->sostate, sock, (unsigned char *)"\r\n", 2, fps->fpd.cp->srv->timeouts[STRING_S]) != 2) return -4; } fps->state = state; diff --git a/src/pop3p.c b/src/pop3p.c index c915601..8eea358 100644 --- a/src/pop3p.c +++ b/src/pop3p.c @@ -23,28 +23,28 @@ void * pop3pchild(struct clientparam* param) { unsigned char buf[320]; unsigned char *se; - if(socksend(param, param->clisock, (unsigned char *)"+OK Proxy\r\n", 11, conf.timeouts[STRING_S])!=11) {RETURN (611);} - i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', conf.timeouts[STRING_S]); + if(socksend(param, param->clisock, (unsigned char *)"+OK Proxy\r\n", 11, param->srv->timeouts[STRING_S])!=11) {RETURN (611);} + i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', param->srv->timeouts[STRING_S]); while(i > 4 && strncasecmp((char *)buf, "USER", 4)){ if(!strncasecmp((char *)buf, "QUIT", 4)){ - socksend(param, param->clisock, (unsigned char *)"+OK\r\n", 5,conf.timeouts[STRING_S]); + socksend(param, param->clisock, (unsigned char *)"+OK\r\n", 5,param->srv->timeouts[STRING_S]); RETURN(0); } if(!strncasecmp((char *)buf, "CAPA", 4) && !NOSTARTTLS){ - socksend(param, param->clisock, (unsigned char *)"+OK Capability list follows\r\nSTLS\r\n.\r\n", 38, conf.timeouts[STRING_S]); - i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', conf.timeouts[STRING_S]); + socksend(param, param->clisock, (unsigned char *)"+OK Capability list follows\r\nSTLS\r\n.\r\n", 38, param->srv->timeouts[STRING_S]); + i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', param->srv->timeouts[STRING_S]); continue; } #ifndef WITHMAIN if(!strncasecmp((char *)buf, "STLS", 4) && !param->srv->nostarttls){ - if(socksend(param, param->clisock, (unsigned char *)"+OK Begin TLS negotiation\r\n", 27, conf.timeouts[STRING_S])!=27) {RETURN(623);} + if(socksend(param, param->clisock, (unsigned char *)"+OK Begin TLS negotiation\r\n", 27, param->srv->timeouts[STRING_S])!=27) {RETURN(623);} param->clientstarttls = S_POP3P; if(!param->srv->targetport) param->srv->targetport = htons(110); return (void *)tlsprchild; } #endif - socksend(param, param->clisock, (unsigned char *)"-ERR need USER first\r\n", 22, conf.timeouts[STRING_S]); - i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', conf.timeouts[STRING_S]); + socksend(param, param->clisock, (unsigned char *)"-ERR need USER first\r\n", 22, param->srv->timeouts[STRING_S]); + i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', param->srv->timeouts[STRING_S]); } if(i<6) {RETURN(612);} @@ -55,13 +55,13 @@ void * pop3pchild(struct clientparam* param) { param->operation = CONNECT; res = (*param->srv->authfunc)(param); if(res) {RETURN(res);} - i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L]); + i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', param->srv->timeouts[STRING_L]); if( i < 3 ) {RETURN(621);} buf[i] = 0; if(strncasecmp((char *)buf, "+OK", 3)||!strncasecmp((char *)buf+4, "PROXY", 5)){RETURN(622);} - if( socksend(param, param->remsock, (unsigned char *)"USER ", 5, conf.timeouts[STRING_S])!= 5 || - socksend(param, param->remsock, param->extusername, (int)strlen((char *)param->extusername), conf.timeouts[STRING_S]) <= 0 || - socksend(param, param->remsock, (unsigned char *)"\r\n", 2, conf.timeouts[STRING_S])!=2) + if( socksend(param, param->remsock, (unsigned char *)"USER ", 5, param->srv->timeouts[STRING_S])!= 5 || + socksend(param, param->remsock, param->extusername, (int)strlen((char *)param->extusername), param->srv->timeouts[STRING_S]) <= 0 || + socksend(param, param->remsock, (unsigned char *)"\r\n", 2, param->srv->timeouts[STRING_S])!=2) {RETURN(623);} param->statscli64 += (uint64_t)(strlen((char *)param->extusername) + 7); param->nwrites++; @@ -74,7 +74,7 @@ CLEANRET: } else dolog(param, NULL); if(param->clisock != INVALID_SOCKET) { - if ((param->res > 0 && param->res < 100) || (param->res > 611 && param->res <700)) socksend(param, param->clisock, (unsigned char *)"-ERR\r\n", 6,conf.timeouts[STRING_S]); + if ((param->res > 0 && param->res < 100) || (param->res > 611 && param->res <700)) socksend(param, param->clisock, (unsigned char *)"-ERR\r\n", 6,param->srv->timeouts[STRING_S]); } return (NULL); } diff --git a/src/proxy.c b/src/proxy.c index d17296b..d243e4c 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -156,7 +156,7 @@ static int pst_len(int idx){ } static int send_st(struct clientparam *param, int idx){ - return socksend(param, param->clisock, (unsigned char *)proxy_stringtable[idx], pst_len(idx), conf.timeouts[STRING_S]); + return socksend(param, param->clisock, (unsigned char *)proxy_stringtable[idx], pst_len(idx), param->srv->timeouts[STRING_S]); } #ifndef WITHMAIN @@ -368,7 +368,7 @@ for(;;){ fds[0].events = POLLIN; fds[1].fd = param->remsock; fds[1].events = POLLIN; - res = param->srv->so._poll(param->sostate, fds, 2, conf.timeouts[STRING_S]*1000); + res = param->srv->so._poll(param->sostate, fds, 2, param->srv->timeouts[STRING_S]*1000); if(res<=0) { RETURN(555); } @@ -387,13 +387,13 @@ for(;;){ } if(!buf){ - if(sockgetcharcli(param, conf.timeouts[STRING_L], 0) == EOF) RETURN((keepalive)?555:508); + if(sockgetcharcli(param, param->srv->timeouts[STRING_L], 0) == EOF) RETURN((keepalive)?555:508); param->clioffset--; if(!(buf = malloc(BUFSIZE))) {RETURN(21);} bufsize = BUFSIZE; memset(buf, 0, bufsize); } - i = sockgetlinebuf(param, CLIENT, buf, LINESIZE - 1, '\n', conf.timeouts[STRING_L]); + i = sockgetlinebuf(param, CLIENT, buf, LINESIZE - 1, '\n', param->srv->timeouts[STRING_L]); if(i<=0) { RETURN((keepalive)?555:(i)?507:508); } @@ -629,7 +629,7 @@ for(;;){ buf = newbuf; bufsize += BUFSIZE; } - } while( (i = sockgetlinebuf(param, CLIENT, buf + inbuf, LINESIZE - 2, '\n', conf.timeouts[STRING_S])) > 2); + } while( (i = sockgetlinebuf(param, CLIENT, buf + inbuf, LINESIZE - 2, '\n', param->srv->timeouts[STRING_S])) > 2); buf[inbuf] = 0; @@ -812,7 +812,7 @@ for(;;){ s = param->remsock; param->remsock = ftps; if((param->operation == FTP_PUT) && (contentlength64 > 0)) param->waitclient64 = contentlength64; - res = mapsocket(param, conf.timeouts[CONNECTION_L]); + res = mapsocket(param, param->srv->timeouts[CONNECTION_L]); if (res == 99) res = 0; param->srv->so._closesocket(param->sostate, ftps); ftps = INVALID_SOCKET; @@ -829,7 +829,7 @@ for(;;){ } param->remsock = ftps; - if(gotres <= 0) for(; (res = sockgetlinebuf(param, SERVER, (unsigned char *)ftpbuf, FTPBUFSIZE - 20, '\n', conf.timeouts[STRING_S])) > 0; i++){ + if(gotres <= 0) for(; (res = sockgetlinebuf(param, SERVER, (unsigned char *)ftpbuf, FTPBUFSIZE - 20, '\n', param->srv->timeouts[STRING_S])) > 0; i++){ int isdir = 0; int islink = 0; int filetoken =-1; @@ -954,7 +954,7 @@ for(;;){ if(!headsent++){ send_st(param, 9); } - if((unsigned)socksend(param, param->clisock, buf, inbuf, conf.timeouts[STRING_S]) != inbuf){ + if((unsigned)socksend(param, param->clisock, buf, inbuf, param->srv->timeouts[STRING_S]) != inbuf){ param->srv->so._closesocket(param->sostate, ftps); ftps = INVALID_SOCKET; param->remsock = s; @@ -991,9 +991,9 @@ for(;;){ "Connection: keep-alive\r\n" "Content-Length: %d\r\n\r\n", inbuf); - socksend(param, param->clisock, (unsigned char *)ftpbuf, (int)strlen(ftpbuf), conf.timeouts[STRING_S]); + socksend(param, param->clisock, (unsigned char *)ftpbuf, (int)strlen(ftpbuf), param->srv->timeouts[STRING_S]); } - socksend(param, param->clisock, buf, inbuf, conf.timeouts[STRING_S]); + socksend(param, param->clisock, buf, inbuf, param->srv->timeouts[STRING_S]); if(res){RETURN(res);} if(!headsent)goto REQUESTEND; } @@ -1009,7 +1009,7 @@ for(;;){ return (void *)param->redirectfunc; } freeptr(&buf); - param->res = mapsocket(param, conf.timeouts[CONNECTION_L]); + param->res = mapsocket(param, param->srv->timeouts[CONNECTION_L]); RETURN(param->res); } @@ -1024,7 +1024,7 @@ for(;;){ #endif redirect = 1; res = (int)strlen((char *)req); - if(socksend(param, param->remsock, req , res, conf.timeouts[STRING_L]) != res) { + if(socksend(param, param->remsock, req , res, param->srv->timeouts[STRING_L]) != res) { RETURN(518); } param->statscli64 += res; @@ -1068,7 +1068,7 @@ for(;;){ hlen += sprintf((char*)buf + hlen, "\r\n"); } hlen += sprintf((char*)buf + hlen, "\r\n"); - if ((res = socksend(param, param->remsock, buf+reqlen, hlen - reqlen, conf.timeouts[STRING_S])) != hlen - reqlen) { + if ((res = socksend(param, param->remsock, buf+reqlen, hlen - reqlen, param->srv->timeouts[STRING_S])) != hlen - reqlen) { RETURN(518); } } @@ -1087,15 +1087,15 @@ for(;;){ if(chunkedcli){ do { unsigned char smallbuf[32]; - while ((i = sockgetlinebuf(param, CLIENT, smallbuf, 30, '\n', conf.timeouts[STRING_S])) == 2) { - if (socksend(param, param->remsock, smallbuf, i, conf.timeouts[STRING_S]) != i) RETURN(536); + while ((i = sockgetlinebuf(param, CLIENT, smallbuf, 30, '\n', param->srv->timeouts[STRING_S])) == 2) { + if (socksend(param, param->remsock, smallbuf, i, param->srv->timeouts[STRING_S]) != i) RETURN(536); if(chunkedcli == 2) break; } if(i<3) break; - if (socksend(param, param->remsock, smallbuf, i, conf.timeouts[STRING_S]) != i) RETURN(536); + if (socksend(param, param->remsock, smallbuf, i, param->srv->timeouts[STRING_S]) != i) RETURN(536); if(chunkedcli == 2) { - if((i = sockgetlinebuf(param, CLIENT, smallbuf, 30, '\n', conf.timeouts[STRING_S])) != 2) RETURN(537); - if (socksend(param, param->remsock, smallbuf, i, conf.timeouts[STRING_S]) != i) RETURN(536); + if((i = sockgetlinebuf(param, CLIENT, smallbuf, 30, '\n', param->srv->timeouts[STRING_S])) != 2) RETURN(537); + if (socksend(param, param->remsock, smallbuf, i, param->srv->timeouts[STRING_S]) != i) RETURN(536); break; } smallbuf[i] = 0; @@ -1104,13 +1104,13 @@ for(;;){ /* chunk-size line may be longer than smallbuf: drain and relay the remainder up to LF so client/backend framing stays in sync */ while(i > 0 && smallbuf[i-1] != '\n'){ - if((i = sockgetlinebuf(param, CLIENT, smallbuf, 30, '\n', conf.timeouts[STRING_S])) <= 0) RETURN(537); - if (socksend(param, param->remsock, smallbuf, i, conf.timeouts[STRING_S]) != i) RETURN(536); + if((i = sockgetlinebuf(param, CLIENT, smallbuf, 30, '\n', param->srv->timeouts[STRING_S])) <= 0) RETURN(537); + if (socksend(param, param->remsock, smallbuf, i, param->srv->timeouts[STRING_S]) != i) RETURN(536); } if(contentlength64 == 0) chunkedcli = 2; else { param->waitclient64 = contentlength64; - res = mapsocket(param, conf.timeouts[CONNECTION_S]); + res = mapsocket(param, param->srv->timeouts[CONNECTION_S]); param->waitclient64 = 0; if(res != 99) RETURN(res); } @@ -1119,7 +1119,7 @@ for(;;){ } else { param->waitclient64 = contentlength64; - res = mapsocket(param, conf.timeouts[CONNECTION_S]); + res = mapsocket(param, param->srv->timeouts[CONNECTION_S]); param->waitclient64 = 0; if(res != 99) { RETURN(res); @@ -1135,7 +1135,7 @@ for(;;){ hascontent = 0; clhdrofs = -1; - while( (i = sockgetlinebuf(param, SERVER, buf + inbuf, LINESIZE - 1, '\n', conf.timeouts[(res)?STRING_S:STRING_L])) > 2) { + while( (i = sockgetlinebuf(param, SERVER, buf + inbuf, LINESIZE - 1, '\n', param->srv->timeouts[(res)?STRING_S:STRING_L])) > 2) { if(!res && i>9)param->status = res = atoi((char *)buf + inbuf + 9); if(((i >= 25 && !strncasecmp((char *)(buf+inbuf), "proxy-connection:", 17)) || @@ -1266,7 +1266,7 @@ for(;;){ (hascontent && ckeepalive)?"keep-alive":"close"); } hlen += sprintf((char*)buf + hlen, "\r\n"); - if(socksend(param, param->clisock, buf, hlen, conf.timeouts[STRING_S]) != hlen) { + if(socksend(param, param->clisock, buf, hlen, param->srv->timeouts[STRING_S]) != hlen) { RETURN(521); } } @@ -1274,8 +1274,8 @@ for(;;){ do { if(param->chunked){ unsigned char smallbuf[32]; - while ((i = sockgetlinebuf(param, SERVER, smallbuf, 30, '\n', conf.timeouts[STRING_S])) == 2) { - if (socksend(param, param->clisock, smallbuf, i, conf.timeouts[STRING_S]) != i){ + while ((i = sockgetlinebuf(param, SERVER, smallbuf, 30, '\n', param->srv->timeouts[STRING_S])) == 2) { + if (socksend(param, param->clisock, smallbuf, i, param->srv->timeouts[STRING_S]) != i){ RETURN(533); } if(param->chunked == 2) break; @@ -1284,12 +1284,12 @@ for(;;){ keepalive = 0; break; } - if (socksend(param, param->clisock, smallbuf, i, conf.timeouts[STRING_S]) != i){ + if (socksend(param, param->clisock, smallbuf, i, param->srv->timeouts[STRING_S]) != i){ RETURN(535); } if(param->chunked == 2) { - if((i = sockgetlinebuf(param, SERVER, smallbuf, 30, '\n', conf.timeouts[STRING_S])) != 2) RETURN(534); - if (socksend(param, param->clisock, smallbuf, i, conf.timeouts[STRING_S]) != i){ + if((i = sockgetlinebuf(param, SERVER, smallbuf, 30, '\n', param->srv->timeouts[STRING_S])) != 2) RETURN(534); + if (socksend(param, param->clisock, smallbuf, i, param->srv->timeouts[STRING_S]) != i){ RETURN(533); } break; @@ -1303,8 +1303,8 @@ for(;;){ /* chunk-size line may be longer than smallbuf: drain and relay the remainder up to LF so client/backend framing stays in sync */ while(i > 0 && smallbuf[i-1] != '\n'){ - if((i = sockgetlinebuf(param, SERVER, smallbuf, 30, '\n', conf.timeouts[STRING_S])) <= 0) RETURN(534); - if (socksend(param, param->clisock, smallbuf, i, conf.timeouts[STRING_S]) != i) RETURN(535); + if((i = sockgetlinebuf(param, SERVER, smallbuf, 30, '\n', param->srv->timeouts[STRING_S])) <= 0) RETURN(534); + if (socksend(param, param->clisock, smallbuf, i, param->srv->timeouts[STRING_S]) != i) RETURN(535); } if(contentlength64 == 0) { param->chunked = 2; @@ -1312,7 +1312,7 @@ for(;;){ } if(param->chunked != 2){ param->waitserver64 = contentlength64; - if((res = mapsocket(param, conf.timeouts[CONNECTION_S])) != 98){ + if((res = mapsocket(param, param->srv->timeouts[CONNECTION_S])) != 98){ RETURN(res); } param->waitserver64 = 0; @@ -1321,13 +1321,13 @@ for(;;){ } if(isconnect && res == 200 && param->operation){ freeptr(&buf); - RETURN (mapsocket(param, conf.timeouts[CONNECTION_S])); + RETURN (mapsocket(param, param->srv->timeouts[CONNECTION_S])); } else if(isconnect){ ckeepalive = keepalive = 1; } else if(!hascontent && !param->chunked) { - RETURN(mapsocket(param, conf.timeouts[CONNECTION_S])); + RETURN(mapsocket(param, param->srv->timeouts[CONNECTION_S])); } contentlength64 = 0; REQUESTEND: @@ -1361,7 +1361,7 @@ CLEANRET: int r = param->res; if((r >= 509 && r < 517) || r > 900) { - if(buf) while( (i = sockgetlinebuf(param, CLIENT, buf, BUFSIZE - 1, '\n', conf.timeouts[STRING_S])) > 2); + if(buf) while( (i = sockgetlinebuf(param, CLIENT, buf, BUFSIZE - 1, '\n', param->srv->timeouts[STRING_S])) > 2); } if(r == 10) stidx = 2; else if(r == 700 || r == 701) stidx = 16; @@ -1378,7 +1378,7 @@ CLEANRET: if(stidx >= 0) { send_st(param, stidx); - if(r == 700 || r == 701) socksend(param, param->clisock, (unsigned char *)ftpbuf, inftpbuf, conf.timeouts[STRING_S]); + if(r == 700 || r == 701) socksend(param, param->clisock, (unsigned char *)ftpbuf, inftpbuf, param->srv->timeouts[STRING_S]); } } logurl(param, (char *)buf, (char *)req, ftp); diff --git a/src/proxymain.c b/src/proxymain.c index f33eed9..203ebff 100644 --- a/src/proxymain.c +++ b/src/proxymain.c @@ -104,7 +104,7 @@ static void serveparam(struct clientparam *param){ if(param->srv->haproxy){ char buf[128]; int i; - i = sockgetlinebuf(param, CLIENT, (unsigned char *)buf, sizeof(buf)-1, '\n', conf.timeouts[STRING_S]); + i = sockgetlinebuf(param, CLIENT, (unsigned char *)buf, sizeof(buf)-1, '\n', param->srv->timeouts[STRING_S]); if(i > 12 && !strncasecmp(buf, "PROXY TCP", 9)){ char *token, *token2=NULL; unsigned short u1=0, u2=0; @@ -1073,7 +1073,7 @@ static int tcpnext(struct srvstart *s, SOCKET *client, int *nlog){ timeout fails with WSAEWOULDBLOCK while data is queued, leaving the socket open. Without it the close completes in the background, data first. */ lg.l_onoff = 1; - lg.l_linger = conf.timeouts[STRING_L]; + lg.l_linger = srv->timeouts[STRING_L]; srv->so._setsockopt(srv->so.state, new_sock, SOL_SOCKET, SO_LINGER, (char *)&lg, sizeof(lg)); #endif srv->so._setsockopt(srv->so.state, new_sock, SOL_SOCKET, SO_OOBINLINE, (char *)&opt, sizeof(int)); @@ -1393,7 +1393,7 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int fcntl(0,F_SETFL,O_NONBLOCK | fcntl(0,F_GETFL)); if(!s.isudp){ lg.l_onoff = 1; - lg.l_linger = conf.timeouts[STRING_L]; + lg.l_linger = s.srv.timeouts[STRING_L]; s.srv.so._setsockopt(s.srv.so.state, 0, SOL_SOCKET, SO_LINGER, (unsigned char *)&lg, sizeof(lg)); s.srv.so._setsockopt(s.srv.so.state, 0, SOL_SOCKET, SO_OOBINLINE, (unsigned char *)&opt, sizeof(int)); } @@ -1477,6 +1477,7 @@ void srvinit(struct srvparam * srv, struct clientparam *param){ srv->maxchild = conf.maxchild; srv->backlog = conf.backlog; srv->stacksize = conf.stacksize; + memcpy(srv->timeouts, conf.timeouts, sizeof(srv->timeouts)); srv->time_start = time(NULL); if(havelog && conf.logtarget){ srv->logtarget = (unsigned char *)strdup((char *)conf.logtarget); diff --git a/src/redirect.c b/src/redirect.c index 955a8f6..700baad 100644 --- a/src/redirect.c +++ b/src/redirect.c @@ -70,14 +70,14 @@ int clientnegotiate(struct chain * redir, struct clientparam * param, struct soc len += sprintf((char *)buf + len, "\r\n"); } len += sprintf((char *)buf + len, "\r\n"); - if(socksend(param, param->remsock, buf, len, conf.timeouts[CHAIN_TO]) != (int)strlen((char *)buf)) + if(socksend(param, param->remsock, buf, len, param->srv->timeouts[CHAIN_TO]) != (int)strlen((char *)buf)) return 31; param->statssrv64+=len; param->nwrites++; - if((res = sockgetlinebuf(param, SERVER,buf,13,'\n',conf.timeouts[CHAIN_TO])) < 13) + if((res = sockgetlinebuf(param, SERVER,buf,13,'\n',param->srv->timeouts[CHAIN_TO])) < 13) return 32; if(buf[9] != '2') return 33; - while((res = sockgetlinebuf(param, SERVER,buf,1023,'\n', conf.timeouts[CHAIN_TO])) > 2); + while((res = sockgetlinebuf(param, SERVER,buf,1023,'\n', param->srv->timeouts[CHAIN_TO])) > 2); if(res <= 0) return 34; return 0; } @@ -107,12 +107,12 @@ int clientnegotiate(struct chain * redir, struct clientparam * param, struct soc memcpy(buf+len, hostname, hostnamelen); len += hostnamelen; } - if(socksend(param, param->remsock, buf, len, conf.timeouts[CHAIN_TO]) < len){ + if(socksend(param, param->remsock, buf, len, param->srv->timeouts[CHAIN_TO]) < len){ return 41; } param->statssrv64+=len; param->nwrites++; - if((len = sockgetlinebuf(param, SERVER, buf, (redir->type == R_SOCKS4B)? 3:8, EOF, conf.timeouts[CHAIN_TO])) != ((redir->type == R_SOCKS4B)? 3:8)){ + if((len = sockgetlinebuf(param, SERVER, buf, (redir->type == R_SOCKS4B)? 3:8, EOF, param->srv->timeouts[CHAIN_TO])) != ((redir->type == R_SOCKS4B)? 3:8)){ return 42; } if(buf[1] != 90) { @@ -133,12 +133,12 @@ int clientnegotiate(struct chain * redir, struct clientparam * param, struct soc buf[1] = user? 2 : 1; buf[2] = 0; buf[3] = 2; - if(socksend(param, param->remsock, buf, user?4:3, conf.timeouts[CHAIN_TO]) < 2){ + if(socksend(param, param->remsock, buf, user?4:3, param->srv->timeouts[CHAIN_TO]) < 2){ return 51; } param->statssrv64+=user?4:3; param->nwrites++; - if(sockgetlinebuf(param, SERVER, buf, 2, EOF, conf.timeouts[CHAIN_TO]) != 2){ + if(sockgetlinebuf(param, SERVER, buf, 2, EOF, param->srv->timeouts[CHAIN_TO]) != 2){ return 52; } if(buf[0] != 5) { @@ -155,7 +155,7 @@ int clientnegotiate(struct chain * redir, struct clientparam * param, struct soc buf[inbuf] = pass?(unsigned char)strlen((char *)pass):0; if(pass)memcpy(buf+inbuf+1, pass, buf[inbuf]); inbuf += buf[inbuf] + 1; - if(socksend(param, param->remsock, buf, inbuf, conf.timeouts[CHAIN_TO]) != inbuf){ + if(socksend(param, param->remsock, buf, inbuf, param->srv->timeouts[CHAIN_TO]) != inbuf){ return 51; } param->statssrv64+=inbuf; @@ -193,12 +193,12 @@ int clientnegotiate(struct chain * redir, struct clientparam * param, struct soc memcpy(buf+len, SAPORT(addr), 2); len += 2; } - if(socksend(param, param->remsock, buf, len, conf.timeouts[CHAIN_TO]) != len){ + if(socksend(param, param->remsock, buf, len, param->srv->timeouts[CHAIN_TO]) != len){ return 51; } param->statssrv64+=len; param->nwrites++; - if(sockgetlinebuf(param, SERVER, buf, 4, EOF, conf.timeouts[CHAIN_TO]) != 4){ + if(sockgetlinebuf(param, SERVER, buf, 4, EOF, param->srv->timeouts[CHAIN_TO]) != 4){ return 57; } if(buf[0] != 5) { @@ -210,16 +210,16 @@ int clientnegotiate(struct chain * redir, struct clientparam * param, struct soc atyp = buf[3]; switch (buf[3]) { case 1: - if (redir->type == R_SOCKS5B || sockgetlinebuf(param, SERVER, buf, 6, EOF, conf.timeouts[CHAIN_TO]) == 6) + if (redir->type == R_SOCKS5B || sockgetlinebuf(param, SERVER, buf, 6, EOF, param->srv->timeouts[CHAIN_TO]) == 6) break; return 59; case 3: - if (sockgetlinebuf(param, SERVER, buf, 1, EOF, conf.timeouts[CHAIN_TO]) != 1) return 59; + if (sockgetlinebuf(param, SERVER, buf, 1, EOF, param->srv->timeouts[CHAIN_TO]) != 1) return 59; len = (unsigned char)buf[4]; - if (sockgetlinebuf(param, SERVER, buf, len + 2, EOF, conf.timeouts[CHAIN_TO]) != len + 2) return 59; + if (sockgetlinebuf(param, SERVER, buf, len + 2, EOF, param->srv->timeouts[CHAIN_TO]) != len + 2) return 59; break; case 4: - if (sockgetlinebuf(param, SERVER, buf, 18, EOF, conf.timeouts[CHAIN_TO]) == 18) + if (sockgetlinebuf(param, SERVER, buf, 18, EOF, param->srv->timeouts[CHAIN_TO]) == 18) break; return 59; default: @@ -461,7 +461,7 @@ int handleredirect(struct clientparam * param, struct ace * acentry){ ntohs(*SAPORT(¶m->sincr)), ntohs(*SAPORT(¶m->sincl)) ); - if(socksend(param, param->remsock, (unsigned char *)buf, len, conf.timeouts[CHAIN_TO])!=len) return 39; + if(socksend(param, param->remsock, (unsigned char *)buf, len, param->srv->timeouts[CHAIN_TO])!=len) return 39; if(cur->type == R_HA) return 0; } } diff --git a/src/smtpp.c b/src/smtpp.c index dfb3d26..7381ce5 100644 --- a/src/smtpp.c +++ b/src/smtpp.c @@ -35,7 +35,7 @@ int readreply (struct clientparam* param) { buf = param->tmpbuf; /* a filter may replace it with one of its own */ do { - i = sockgetlinebuf(param, SERVER, buf, bufsize-1, '\n', conf.timeouts[STRING_L]); + i = sockgetlinebuf(param, SERVER, buf, bufsize-1, '\n', param->srv->timeouts[STRING_L]); if(i < 1) break; #ifndef WITHMAIN res = handlehdrfilterssrv(param, &buf, &bufsize, 0, &i); @@ -44,7 +44,7 @@ int readreply (struct clientparam* param) { return -1; } #endif - socksend(param, param->clisock, buf, i, conf.timeouts[STRING_S]); + socksend(param, param->clisock, buf, i, param->srv->timeouts[STRING_S]); } while (i > 3 && buf[3] == '-'); if(i < 3) { if(buf != param->tmpbuf) free(buf); @@ -65,7 +65,7 @@ int readcommand (struct clientparam* param) { int ret = 1; buf = param->tmpbuf; /* a filter may replace it with one of its own */ - i = sockgetlinebuf(param, CLIENT, buf, bufsize-1, '\n', conf.timeouts[STRING_L]); + i = sockgetlinebuf(param, CLIENT, buf, bufsize-1, '\n', param->srv->timeouts[STRING_L]); if(i < 4) return 0; #ifndef WITHMAIN if(!strncasecmp((char *)buf, "MAIL", 4) || !strncasecmp((char *)buf, "RCPT", 4) || !strncasecmp((char *)buf, "STARTTLS", 8) || !strncasecmp((char *)buf, "TURN", 4)){ @@ -77,7 +77,7 @@ int readcommand (struct clientparam* param) { } } #endif - socksend(param, param->remsock, buf, i, conf.timeouts[STRING_S]); + socksend(param, param->remsock, buf, i, param->srv->timeouts[STRING_S]); if(!strncasecmp((char *)buf, "STARTTLS", 8) || !strncasecmp((char *)buf, "TURN", 4)){ ret = 22; } @@ -93,7 +93,7 @@ int readdata (struct clientparam* param) { #endif buf = param->tmpbuf; /* a filter may replace it with one of its own */ - while ((i = sockgetlinebuf(param, CLIENT, buf, bufsize-1, '\n', conf.timeouts[STRING_L])) > 0 && !(i==3 && buf[0] == '.')){ + while ((i = sockgetlinebuf(param, CLIENT, buf, bufsize-1, '\n', param->srv->timeouts[STRING_L])) > 0 && !(i==3 && buf[0] == '.')){ #ifndef WITHMAIN res = handledatfltcli(param, &buf, &bufsize, 0, &i); if(res != PASS) { @@ -102,13 +102,13 @@ int readdata (struct clientparam* param) { return -1; } #endif - socksend(param, param->remsock, buf, i, conf.timeouts[STRING_S]); + socksend(param, param->remsock, buf, i, param->srv->timeouts[STRING_S]); } if(i < 1) { if(buf != param->tmpbuf) free(buf); return 0; } - socksend(param, param->remsock, buf, i, conf.timeouts[STRING_S]); + socksend(param, param->remsock, buf, i, param->srv->timeouts[STRING_S]); if(buf != param->tmpbuf) free(buf); return 1; } @@ -121,41 +121,41 @@ void * smtppchild(struct clientparam* param) { char * command = NULL; int login = 0; - if(socksend(param, param->clisock, (unsigned char *)"220 Proxy\r\n", 11, conf.timeouts[STRING_S])!=11) {RETURN (611);} - i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', conf.timeouts[STRING_S]); + if(socksend(param, param->clisock, (unsigned char *)"220 Proxy\r\n", 11, param->srv->timeouts[STRING_S])!=11) {RETURN (611);} + i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', param->srv->timeouts[STRING_S]); while(i > 4 && (strncasecmp((char *)buf, "AUTH PLAIN", 10) || !(login = 2)) && (strncasecmp((char *)buf, "AUTH LOGIN", 10) || !(login = 1))){ if(!strncasecmp((char *)buf, "QUIT", 4)){ - socksend(param, param->clisock, (unsigned char *)"221 Proxy\r\n", 11,conf.timeouts[STRING_S]); + socksend(param, param->clisock, (unsigned char *)"221 Proxy\r\n", 11,param->srv->timeouts[STRING_S]); RETURN(0); } else if(!strncasecmp((char *)buf, "HELO ", 5)){ - socksend(param, param->clisock, (unsigned char *)"250 Proxy\r\n", 11,conf.timeouts[STRING_S]); + socksend(param, param->clisock, (unsigned char *)"250 Proxy\r\n", 11,param->srv->timeouts[STRING_S]); } else if(!strncasecmp((char *)buf, "EHLO ", 5)){ - if(!NOSTARTTLS) socksend(param, param->clisock, (unsigned char *)ehlotls, sizeof(ehlotls) - 1,conf.timeouts[STRING_S]); - else socksend(param, param->clisock, (unsigned char *)ehlo, sizeof(ehlo) - 1,conf.timeouts[STRING_S]); + if(!NOSTARTTLS) socksend(param, param->clisock, (unsigned char *)ehlotls, sizeof(ehlotls) - 1,param->srv->timeouts[STRING_S]); + else socksend(param, param->clisock, (unsigned char *)ehlo, sizeof(ehlo) - 1,param->srv->timeouts[STRING_S]); } #ifndef WITHMAIN else if(!strncasecmp((char *)buf, "STARTTLS", 8) && !param->srv->nostarttls){ - if(socksend(param, param->clisock, (unsigned char *)"220 2.0.0 Ready to start TLS\r\n", 30, conf.timeouts[STRING_S])!=30) {RETURN(673);} + if(socksend(param, param->clisock, (unsigned char *)"220 2.0.0 Ready to start TLS\r\n", 30, param->srv->timeouts[STRING_S])!=30) {RETURN(673);} param->clientstarttls = S_SMTPP; if(!param->srv->targetport) param->srv->targetport = htons(587); return (void *)tlsprchild; } #endif - else if(!*param->hostname) socksend(param, param->clisock, (unsigned char *)"571 need AUTH first\r\n", 22, conf.timeouts[STRING_S]); + else if(!*param->hostname) socksend(param, param->clisock, (unsigned char *)"571 need AUTH first\r\n", 22, param->srv->timeouts[STRING_S]); else { login = -1; buf[i] = 0; command = strdup((char *)buf); break; } - i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', conf.timeouts[STRING_S]); + i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', param->srv->timeouts[STRING_S]); } if(!login) {RETURN(662);} if(login == 1){ - socksend(param, param->clisock, (unsigned char *)"334 VXNlcm5hbWU6\r\n", 18,conf.timeouts[STRING_S]); - i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', conf.timeouts[STRING_S]); + socksend(param, param->clisock, (unsigned char *)"334 VXNlcm5hbWU6\r\n", 18,param->srv->timeouts[STRING_S]); + i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', param->srv->timeouts[STRING_S]); if(i < 3) {RETURN(663);} buf[i-2] = 0; i = de64(buf,username,255); @@ -165,8 +165,8 @@ void * smtppchild(struct clientparam* param) { whether it did: without one there is nowhere to go, and what follows reads the name as if there were. */ if(parseconnusername((char *)username, param, 0, 587)) {RETURN(669);} - socksend(param, param->clisock, (unsigned char *)"334 UGFzc3dvcmQ6\r\n", 18,conf.timeouts[STRING_S]); - i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', conf.timeouts[STRING_S]); + socksend(param, param->clisock, (unsigned char *)"334 UGFzc3dvcmQ6\r\n", 18,param->srv->timeouts[STRING_S]); + i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', param->srv->timeouts[STRING_S]); if(i < 2) {RETURN(665);} buf[i-2] = 0; i = de64(buf,username,255); @@ -180,8 +180,8 @@ void * smtppchild(struct clientparam* param) { i = de64(buf+11,username,255); } else { - socksend(param, param->clisock, (unsigned char *)"334\r\n", 5,conf.timeouts[STRING_S]); - i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', conf.timeouts[STRING_S]); + socksend(param, param->clisock, (unsigned char *)"334\r\n", 5,param->srv->timeouts[STRING_S]); + i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', param->srv->timeouts[STRING_S]); if(i < 3) {RETURN(667);} buf[i-2] = 0; i = de64(buf,username,255); @@ -225,12 +225,12 @@ void * smtppchild(struct clientparam* param) { i = sprintf((char *)buf, "EHLO ["); i += myinet_ntop(*SAFAMILY(¶m->sinsl), SAADDR(¶m->sinsl), (char *)buf+strlen((char *)buf), 64); i += sprintf((char *)buf+strlen((char *)buf), "]\r\n"); - if(socksend(param, param->remsock, buf, i, conf.timeouts[STRING_S])!= i) {RETURN(673);} + if(socksend(param, param->remsock, buf, i, param->srv->timeouts[STRING_S])!= i) {RETURN(673);} param->statscli64+=i; param->nwrites++; login = 0; do { - i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L]); + i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', param->srv->timeouts[STRING_L]); if(i < 1) break; buf[i] = 0; if(strstr((char *)buf, "LOGIN")) login |= 1; @@ -240,32 +240,32 @@ void * smtppchild(struct clientparam* param) { if(i<3) {RETURN(672);} if(!command || (*param->extusername && *param->extpassword)){ if(!*param->extusername || !*param->extpassword || !login){ - socksend(param, param->clisock, (unsigned char *)"235 auth required\r\n", 19,conf.timeouts[STRING_S]); + socksend(param, param->clisock, (unsigned char *)"235 auth required\r\n", 19,param->srv->timeouts[STRING_S]); } if ((login & 1)) { - socksend(param, param->remsock, (unsigned char *)"AUTH LOGIN\r\n", 12, conf.timeouts[STRING_S]); + socksend(param, param->remsock, (unsigned char *)"AUTH LOGIN\r\n", 12, param->srv->timeouts[STRING_S]); param->statscli64+=12; param->nwrites++; - i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L]); + i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', param->srv->timeouts[STRING_L]); if(i<4 || strncasecmp((char *)buf, "334", 3)) {RETURN(680);} if(!en64(param->extusername, buf, (int)strlen((char *)param->extusername), (int)sizeof(buf))) {RETURN(683);} - socksend(param, param->remsock, buf, (int)strlen((char *)buf), conf.timeouts[STRING_S]); - socksend(param, param->remsock, (unsigned char *)"\r\n", 2, conf.timeouts[STRING_S]); + socksend(param, param->remsock, buf, (int)strlen((char *)buf), param->srv->timeouts[STRING_S]); + socksend(param, param->remsock, (unsigned char *)"\r\n", 2, param->srv->timeouts[STRING_S]); param->statscli64+=(i+2); param->nwrites+=2; - i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L]); + i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', param->srv->timeouts[STRING_L]); if(i<4 || strncasecmp((char *)buf, "334", 3)) {RETURN(681);} if(!en64(param->extpassword, buf, (int)strlen((char *)param->extpassword), (int)sizeof(buf))) {RETURN(683);} - socksend(param, param->remsock, buf, (int)strlen((char *)buf), conf.timeouts[STRING_S]); - socksend(param, param->remsock, (unsigned char *)"\r\n", 2, conf.timeouts[STRING_S]); + socksend(param, param->remsock, buf, (int)strlen((char *)buf), param->srv->timeouts[STRING_S]); + socksend(param, param->remsock, (unsigned char *)"\r\n", 2, param->srv->timeouts[STRING_S]); param->statscli64+=(i+2); param->nwrites+=2; } else if((login & 2)){ - socksend(param, param->remsock, (unsigned char *)"AUTH PLAIN\r\n", 12, conf.timeouts[STRING_S]); + socksend(param, param->remsock, (unsigned char *)"AUTH PLAIN\r\n", 12, param->srv->timeouts[STRING_S]); param->statscli64+=(12); param->nwrites++; - i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L]); + i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', param->srv->timeouts[STRING_L]); if(i<4 || strncasecmp((char *)buf, "334", 3)) {RETURN(682);} *username = 0; i = (int)strlen((char *)param->extusername) + 1; @@ -277,13 +277,13 @@ void * smtppchild(struct clientparam* param) { i+=res; if(!en64(username, buf, i, (int)sizeof(buf))) {RETURN(683);} i = (int)strlen((char *)buf); - socksend(param, param->remsock, buf, i, conf.timeouts[STRING_S]); - socksend(param, param->remsock, (unsigned char *)"\r\n", 2, conf.timeouts[STRING_S]); + socksend(param, param->remsock, buf, i, param->srv->timeouts[STRING_S]); + socksend(param, param->remsock, (unsigned char *)"\r\n", 2, param->srv->timeouts[STRING_S]); param->statscli64+=(i+2); param->nwrites+=2; } if(command) { - i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L]); + i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', param->srv->timeouts[STRING_L]); } res = 1; } @@ -303,7 +303,7 @@ void * smtppchild(struct clientparam* param) { } #endif i = (int)strlen(command); - if(res != 2) socksend(param, param->remsock, (unsigned char *)command, i, conf.timeouts[STRING_S]); + if(res != 2) socksend(param, param->remsock, (unsigned char *)command, i, param->srv->timeouts[STRING_S]); } #ifndef WITHMAIN @@ -333,7 +333,7 @@ CLEANRET: } else dolog(param, NULL); if(param->clisock != INVALID_SOCKET) { - if ((param->res > 0 && param->res < 100) || (param->res > 661 && param->res <700)) socksend(param, param->clisock, (unsigned char *)"571 \r\n", 6,conf.timeouts[STRING_S]); + if ((param->res > 0 && param->res < 100) || (param->res > 661 && param->res <700)) socksend(param, param->clisock, (unsigned char *)"571 \r\n", 6,param->srv->timeouts[STRING_S]); } if(command) free(command); return (NULL); diff --git a/src/sockmap.c b/src/sockmap.c index 5dd913f..ed15289 100644 --- a/src/sockmap.c +++ b/src/sockmap.c @@ -900,7 +900,7 @@ log("entering poll"); #endif res = param->srv->so._poll(param->sostate, fds, fdsc, ((CLIENTTERMREAD || SERVERTERMREAD)? - MIN(timeo, conf.timeouts[LINGER_TO]) : timeo) * 1000); + MIN(timeo, param->srv->timeouts[LINGER_TO]) : timeo) * 1000); #ifdef WITHLOG log("leaving poll"); #endif diff --git a/src/socks.c b/src/socks.c index 4f9a453..2b4f607 100644 --- a/src/socks.c +++ b/src/socks.c @@ -53,55 +53,55 @@ void * sockschild(struct clientparam* param) { param->service = S_SOCKS; memset(buf, 0, BUFSIZE); - if ((ver = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_L], 0)) != 5 && ver != 4) { + if ((ver = sockgetcharcli(param, param->srv->timeouts[SINGLEBYTE_L], 0)) != 5 && ver != 4) { RETURN(401); } /* version */ param->service = ver; if(ver == 5){ - if ((i = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(441);} /* nmethods */ + if ((i = sockgetcharcli(param, param->srv->timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(441);} /* nmethods */ for (; i; i--) { - if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(441);} + if ((res = sockgetcharcli(param, param->srv->timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(441);} if (res == 2 && param->srv->needuser) { havepass = res; } } buf[0] = 5; buf[1] = (param->srv->needuser > 1 && !havepass)? 255 : havepass; - if(socksend(param, param->clisock, buf, 2, conf.timeouts[STRING_S])!=2){RETURN(401);} + if(socksend(param, param->clisock, buf, 2, param->srv->timeouts[STRING_S])!=2){RETURN(401);} if (param->srv->needuser > 1 && !havepass) RETURN(4); if (havepass) { - if (((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_L], 0))) != 1) { + if (((res = sockgetcharcli(param, param->srv->timeouts[SINGLEBYTE_L], 0))) != 1) { RETURN(412); } - if ((i = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(451);} - if (i && (res = sockgetlinebuf(param, CLIENT, buf, i, 0, conf.timeouts[STRING_S])) != (int)i) {RETURN(441);} + if ((i = sockgetcharcli(param, param->srv->timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(451);} + if (i && (res = sockgetlinebuf(param, CLIENT, buf, i, 0, param->srv->timeouts[STRING_S])) != (int)i) {RETURN(441);} buf[i] = 0; if(!*param->username) { if(PARAMSTR(param, username, buf)){RETURN(21);} } - if ((i = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(445);} - if (i && (res = sockgetlinebuf(param, CLIENT, buf, i, 0, conf.timeouts[STRING_S])) != (int)i) {RETURN(441);} + if ((i = sockgetcharcli(param, param->srv->timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(445);} + if (i && (res = sockgetlinebuf(param, CLIENT, buf, i, 0, param->srv->timeouts[STRING_S])) != (int)i) {RETURN(441);} buf[i] = 0; if(!*param->password) { if(PARAMSTR(param, password, buf)){RETURN(21);} } buf[0] = 1; buf[1] = 0; - if(socksend(param, param->clisock, buf, 2, conf.timeouts[STRING_S])!=2){RETURN(481);} + if(socksend(param, param->clisock, buf, 2, param->srv->timeouts[STRING_S])!=2){RETURN(481);} } - if ((c = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_L], 0)) != 5) { + if ((c = sockgetcharcli(param, param->srv->timeouts[SINGLEBYTE_L], 0)) != 5) { RETURN(421); } } - if( (command = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) < 1 || command > 3){command = 0; RETURN(407);} /* command */ + if( (command = sockgetcharcli(param, param->srv->timeouts[SINGLEBYTE_S], 0)) < 1 || command > 3){command = 0; RETURN(407);} /* command */ if(ver == 5){ - if (sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0) == EOF) {RETURN(447);} /* reserved */ - c = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0); /* atype */ + if (sockgetcharcli(param, param->srv->timeouts[SINGLEBYTE_S], 0) == EOF) {RETURN(447);} /* reserved */ + c = sockgetcharcli(param, param->srv->timeouts[SINGLEBYTE_S], 0); /* atype */ } else { - if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(441);} + if ((res = sockgetcharcli(param, param->srv->timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(441);} buf[0] = (unsigned char) res; - if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(441);} + if ((res = sockgetcharcli(param, param->srv->timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(441);} buf[1] = (unsigned char) res; memcpy(&port, buf, 2); c = 1; @@ -115,7 +115,7 @@ void * sockschild(struct clientparam* param) { #endif case 1: for (i = 0; isrv->timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(441);} buf[i] = (unsigned char)res; } res = socks5_setaddr(param->srv->family, c, buf, ¶m->req); @@ -125,9 +125,9 @@ void * sockschild(struct clientparam* param) { myinet_ntop(*SAFAMILY(¶m->sinsr), SAADDR(¶m->sinsr), (char *)buf, 64); break; case 3: - if ((size = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(451);} /* nmethods */ + if ((size = sockgetcharcli(param, param->srv->timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(451);} /* nmethods */ for (i=0; isrv->timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(451);} buf[i] = (unsigned char)res; } buf[i] = 0; @@ -140,22 +140,22 @@ void * sockschild(struct clientparam* param) { } if(PARAMSTR(param, hostname, buf)){RETURN(21);} if (ver == 5) { - if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(441);} + if ((res = sockgetcharcli(param, param->srv->timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(441);} buf[0] = (unsigned char) res; - if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(441);} + if ((res = sockgetcharcli(param, param->srv->timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(441);} buf[1] = (unsigned char) res; memcpy(&port, buf, 2); } else { - if(sockgetlinebuf(param, CLIENT, buf, BUFSIZE - 1, 0, conf.timeouts[STRING_S]) < 0) {RETURN(441);} + if(sockgetlinebuf(param, CLIENT, buf, BUFSIZE - 1, 0, param->srv->timeouts[STRING_S]) < 0) {RETURN(441);} buf[127] = 0; if(param->srv->needuser && *buf && !*param->username) { if(PARAMSTR(param, username, buf)){RETURN(21);} } if(!memcmp(SAADDR(¶m->req), "\0\0\0", 3)){ param->service = S_SOCKS45; - if(sockgetlinebuf(param, CLIENT, buf, BUFSIZE - 1, 0, conf.timeouts[STRING_S]) < 0) {RETURN(441);} + if(sockgetlinebuf(param, CLIENT, buf, BUFSIZE - 1, 0, param->srv->timeouts[STRING_S]) < 0) {RETURN(441);} buf[127] = 0; if(PARAMSTR(param, hostname, buf)){RETURN(21);} if(!getip46(param->srv->family, buf, (struct sockaddr *) ¶m->req)) RETURN(100); @@ -312,7 +312,7 @@ fflush(stderr); buf[3] = (*SAFAMILY(&sin) == AF_INET)?1:4; memcpy(buf+4, SAADDR(&sin), SAADDRLEN(&sin)); memcpy(buf+4+SAADDRLEN(&sin), SAPORT(&sin), 2); - socksend(param, (command == 3)?param->ctrlsock:param->clisock, buf, 6+SAADDRLEN(&sin), conf.timeouts[STRING_S]); + socksend(param, (command == 3)?param->ctrlsock:param->clisock, buf, 6+SAADDRLEN(&sin), param->srv->timeouts[STRING_S]); } else{ buf[0] = 0; @@ -324,7 +324,7 @@ fflush(stderr); memset(buf+2, 0, 6); param->res = 997; } - socksend(param, param->clisock, buf, 8, conf.timeouts[STRING_S]); + socksend(param, param->clisock, buf, 8, param->srv->timeouts[STRING_S]); } @@ -347,7 +347,7 @@ fflush(stderr); if(buf != param->tmpbuf) free(buf); return (void *)param->redirectfunc; } - param->res = mapsocket(param, conf.timeouts[CONNECTION_L]); + param->res = mapsocket(param, param->srv->timeouts[CONNECTION_L]); break; case 2: param->srv->so._listen (param->sostate, param->remsock, 1); @@ -355,7 +355,7 @@ fflush(stderr); fds[0].fd = param->remsock; fds[1].fd = param->clisock; fds[0].events = fds[1].events = POLLIN; - res = param->srv->so._poll(param->sostate, fds, 2, conf.timeouts[CONNECTION_L] * 1000); + res = param->srv->so._poll(param->sostate, fds, 2, param->srv->timeouts[CONNECTION_L] * 1000); if (res < 1 || fds[1].revents) { res = 460; break; @@ -397,19 +397,19 @@ fflush(stderr); buf[3] = (*SAFAMILY(¶m->sinsr) == AF_INET)?1:4; memcpy(buf+4, SAADDR(¶m->sinsr), SAADDRLEN(¶m->sinsr)); memcpy(buf+4+SAADDRLEN(¶m->sinsr), SAPORT(¶m->sinsr), 2); - socksend(param, param->clisock, buf, 6+SAADDRLEN(¶m->sinsr), conf.timeouts[STRING_S]); + socksend(param, param->clisock, buf, 6+SAADDRLEN(¶m->sinsr), param->srv->timeouts[STRING_S]); } else { memcpy (buf+2, SAPORT(¶m->sinsr), 2); memcpy (buf+4, SAADDR(¶m->sinsr), 4); - socksend(param, param->clisock, buf, 8, conf.timeouts[STRING_S]); + socksend(param, param->clisock, buf, 8, param->srv->timeouts[STRING_S]); } - param->res = mapsocket(param, conf.timeouts[CONNECTION_S]); + param->res = mapsocket(param, param->srv->timeouts[CONNECTION_S]); break; case 3: param->sinsr = param->req; - param->res = udpsockmap(param, conf.timeouts[CONNECTION_L]); + param->res = udpsockmap(param, param->srv->timeouts[CONNECTION_L]); break; default: param->res = 417; diff --git a/src/structures.h b/src/structures.h index 56b913f..9140b05 100644 --- a/src/structures.h +++ b/src/structures.h @@ -621,6 +621,7 @@ struct srvparam { int nfilters, nreqfilters, nconnectfilters, nafterauthfilters, nhdrfilterscli, nhdrfilterssrv, npredatfilters, ndatfilterscli, ndatfilterssrv; int family; int stacksize; + int timeouts[12]; /* conf.timeouts as they were when the service started */ int noforce; int anonymous; struct sockoptset clisockopts, srvsockopts, lissockopts, cbcsockopts, cbssockopts; diff --git a/src/tcppm.c b/src/tcppm.c index 98a5fd7..3bed52d 100644 --- a/src/tcppm.c +++ b/src/tcppm.c @@ -43,7 +43,7 @@ void * tcppmchild(struct clientparam* param) { return (void *)param->redirectfunc; } - RETURN (mapsocket(param, conf.timeouts[CONNECTION_L])); + RETURN (mapsocket(param, param->srv->timeouts[CONNECTION_L])); CLEANRET: dolog(param, *param->hostname? param->hostname : NULL); diff --git a/src/tlspr.c b/src/tlspr.c index c0d35c6..3571b4f 100644 --- a/src/tlspr.c +++ b/src/tlspr.c @@ -29,15 +29,15 @@ int srvstarttls(struct clientparam *param, PROXYSERVICE proto){ switch(proto){ case S_IMAPP: - i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L]); + i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', param->srv->timeouts[STRING_L]); if(i < 4) return 1; buf[i] = 0; if(strncasecmp((char *)buf, "* OK", 4)) return 1; found = hascap(buf, "STARTTLS"); if(!found){ - if(socksend(param, param->remsock, (unsigned char *)"zz CAPABILITY\r\n", 15, conf.timeouts[STRING_S])!=15) return 2; + if(socksend(param, param->remsock, (unsigned char *)"zz CAPABILITY\r\n", 15, param->srv->timeouts[STRING_S])!=15) return 2; for(;;){ - i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L]); + i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', param->srv->timeouts[STRING_L]); if(i < 3) return 2; buf[i] = 0; if(!strncasecmp((char *)buf, "* CAPABILITY", 12) && hascap(buf, "STARTTLS")) found = 1; @@ -45,20 +45,20 @@ int srvstarttls(struct clientparam *param, PROXYSERVICE proto){ } if(!found) return 3; } - if(socksend(param, param->remsock, (unsigned char *)"zz STARTTLS\r\n", 13, conf.timeouts[STRING_S])!=13) return 2; - i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L]); + if(socksend(param, param->remsock, (unsigned char *)"zz STARTTLS\r\n", 13, param->srv->timeouts[STRING_S])!=13) return 2; + i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', param->srv->timeouts[STRING_L]); if(i < 5) return 2; buf[i] = 0; if(strncasecmp((char *)buf, "zz OK", 5)) return 3; break; case S_POP3P: - i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L]); + i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', param->srv->timeouts[STRING_L]); if(i < 3) return 1; buf[i] = 0; if(strncasecmp((char *)buf, "+OK", 3)) return 1; - if(socksend(param, param->remsock, (unsigned char *)"CAPA\r\n", 6, conf.timeouts[STRING_S])!=6) return 2; + if(socksend(param, param->remsock, (unsigned char *)"CAPA\r\n", 6, param->srv->timeouts[STRING_S])!=6) return 2; for(;;){ - i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L]); + i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', param->srv->timeouts[STRING_L]); if(i < 1) return 2; buf[i] = 0; if(buf[0] == '.') break; @@ -66,8 +66,8 @@ int srvstarttls(struct clientparam *param, PROXYSERVICE proto){ if(hascap(buf, "STLS")) found = 1; } if(!found) return 3; - if(socksend(param, param->remsock, (unsigned char *)"STLS\r\n", 6, conf.timeouts[STRING_S])!=6) return 2; - i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L]); + if(socksend(param, param->remsock, (unsigned char *)"STLS\r\n", 6, param->srv->timeouts[STRING_S])!=6) return 2; + i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', param->srv->timeouts[STRING_L]); if(i < 3) return 2; buf[i] = 0; if(strncasecmp((char *)buf, "+OK", 3)) return 3; @@ -80,14 +80,14 @@ int srvstarttls(struct clientparam *param, PROXYSERVICE proto){ i = sprintf((char *)buf, "EHLO ["); i += myinet_ntop(*SAFAMILY(¶m->sinsl), SAADDR(¶m->sinsl), (char *)buf+strlen((char *)buf), 64); i += sprintf((char *)buf+strlen((char *)buf), "]\r\n"); - if(socksend(param, param->remsock, buf, i, conf.timeouts[STRING_S])!= i) return 2; + if(socksend(param, param->remsock, buf, i, param->srv->timeouts[STRING_S])!= i) return 2; i = getmultiline(param, SERVER, buf, sizeof(buf) - 1, "STARTTLS", &found); if(i < 3) return 2; buf[i] = 0; if(strncasecmp((char *)buf, "250", 3)) return 2; if(!found) return 3; - if(socksend(param, param->remsock, (unsigned char *)"STARTTLS\r\n", 10, conf.timeouts[STRING_S])!= 10) return 2; - i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L]); + if(socksend(param, param->remsock, (unsigned char *)"STARTTLS\r\n", 10, param->srv->timeouts[STRING_S])!= 10) return 2; + i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', param->srv->timeouts[STRING_L]); if(i < 3) return 2; buf[i] = 0; if(strncasecmp((char *)buf, "220", 3)) return 3; @@ -116,9 +116,9 @@ int clistarttls(struct clientparam *param, PROXYSERVICE proto){ switch(proto){ case S_IMAPP: i = sprintf((char *)buf, "* OK [CAPABILITY IMAP4rev1 STARTTLS LOGINDISABLED] IMAP4rev1 Proxy Ready\r\n"); - if(socksend(param, param->clisock, buf, i, conf.timeouts[STRING_S])!=i) return 1; + if(socksend(param, param->clisock, buf, i, param->srv->timeouts[STRING_S])!=i) return 1; for(;;){ - i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', conf.timeouts[STRING_S]); + i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', param->srv->timeouts[STRING_S]); if(i < 4) return 1; buf[i] = 0; if ((se=(unsigned char *)strchr((char *)buf, '\r'))) *se = 0; @@ -127,67 +127,67 @@ int clistarttls(struct clientparam *param, PROXYSERVICE proto){ tag[se - buf] = 0; cmd = se + 1; if(!strncasecmp((char *)cmd, "LOGOUT", 6)){ - socksend(param, param->clisock, (unsigned char *)"* BYE\r\n", 7, conf.timeouts[STRING_S]); + socksend(param, param->clisock, (unsigned char *)"* BYE\r\n", 7, param->srv->timeouts[STRING_S]); sprintf((char *)buf, "%.60s OK LOGOUT completed\r\n", (char *)tag); - socksend(param, param->clisock, buf, (int)strlen((char *)buf), conf.timeouts[STRING_S]); + socksend(param, param->clisock, buf, (int)strlen((char *)buf), param->srv->timeouts[STRING_S]); return -1; } if(!strncasecmp((char *)cmd, "CAPABILITY", 10)){ i = sprintf((char *)buf, "* CAPABILITY IMAP4rev1 STARTTLS LOGINDISABLED\r\n"); - socksend(param, param->clisock, buf, i, conf.timeouts[STRING_S]); + socksend(param, param->clisock, buf, i, param->srv->timeouts[STRING_S]); sprintf((char *)buf, "%.60s OK CAPABILITY completed\r\n", (char *)tag); - socksend(param, param->clisock, buf, (int)strlen((char *)buf), conf.timeouts[STRING_S]); + socksend(param, param->clisock, buf, (int)strlen((char *)buf), param->srv->timeouts[STRING_S]); continue; } if(!strncasecmp((char *)cmd, "STARTTLS", 8)){ sprintf((char *)buf, "%.60s OK Begin TLS negotiation\r\n", (char *)tag); - if(socksend(param, param->clisock, buf, (int)strlen((char *)buf), conf.timeouts[STRING_S]) <= 0) return 1; + if(socksend(param, param->clisock, buf, (int)strlen((char *)buf), param->srv->timeouts[STRING_S]) <= 0) return 1; return 0; } sprintf((char *)buf, "%.60s BAD need STARTTLS first\r\n", (char *)tag); - socksend(param, param->clisock, buf, (int)strlen((char *)buf), conf.timeouts[STRING_S]); + socksend(param, param->clisock, buf, (int)strlen((char *)buf), param->srv->timeouts[STRING_S]); } case S_POP3P: - if(socksend(param, param->clisock, (unsigned char *)"+OK Proxy\r\n", 11, conf.timeouts[STRING_S])!=11) return 1; + if(socksend(param, param->clisock, (unsigned char *)"+OK Proxy\r\n", 11, param->srv->timeouts[STRING_S])!=11) return 1; for(;;){ - i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', conf.timeouts[STRING_S]); + i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', param->srv->timeouts[STRING_S]); if(i < 4) return 1; if(!strncasecmp((char *)buf, "STLS", 4)){ - if(socksend(param, param->clisock, (unsigned char *)"+OK Begin TLS negotiation\r\n", 27, conf.timeouts[STRING_S])!=27) return 1; + if(socksend(param, param->clisock, (unsigned char *)"+OK Begin TLS negotiation\r\n", 27, param->srv->timeouts[STRING_S])!=27) return 1; return 0; } if(!strncasecmp((char *)buf, "CAPA", 4)){ - socksend(param, param->clisock, (unsigned char *)"+OK Capability list follows\r\nSTLS\r\n.\r\n", 38, conf.timeouts[STRING_S]); + socksend(param, param->clisock, (unsigned char *)"+OK Capability list follows\r\nSTLS\r\n.\r\n", 38, param->srv->timeouts[STRING_S]); continue; } if(!strncasecmp((char *)buf, "QUIT", 4)){ - socksend(param, param->clisock, (unsigned char *)"+OK\r\n", 5, conf.timeouts[STRING_S]); + socksend(param, param->clisock, (unsigned char *)"+OK\r\n", 5, param->srv->timeouts[STRING_S]); return -1; } - socksend(param, param->clisock, (unsigned char *)"-ERR need STLS first\r\n", 22, conf.timeouts[STRING_S]); + socksend(param, param->clisock, (unsigned char *)"-ERR need STLS first\r\n", 22, param->srv->timeouts[STRING_S]); } case S_SMTPP: - if(socksend(param, param->clisock, (unsigned char *)"220 Proxy\r\n", 11, conf.timeouts[STRING_S])!=11) return 1; + if(socksend(param, param->clisock, (unsigned char *)"220 Proxy\r\n", 11, param->srv->timeouts[STRING_S])!=11) return 1; for(;;){ - i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', conf.timeouts[STRING_S]); + i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', param->srv->timeouts[STRING_S]); if(i < 4) return 1; if(!strncasecmp((char *)buf, "STARTTLS", 8)){ - if(socksend(param, param->clisock, (unsigned char *)"220 2.0.0 Ready to start TLS\r\n", 30, conf.timeouts[STRING_S])!=30) return 1; + if(socksend(param, param->clisock, (unsigned char *)"220 2.0.0 Ready to start TLS\r\n", 30, param->srv->timeouts[STRING_S])!=30) return 1; return 0; } if(!strncasecmp((char *)buf, "EHLO ", 5)){ - socksend(param, param->clisock, (unsigned char *)"250-Proxy\r\n250 STARTTLS\r\n", 25, conf.timeouts[STRING_S]); + socksend(param, param->clisock, (unsigned char *)"250-Proxy\r\n250 STARTTLS\r\n", 25, param->srv->timeouts[STRING_S]); continue; } if(!strncasecmp((char *)buf, "HELO ", 5)){ - socksend(param, param->clisock, (unsigned char *)"250 Proxy\r\n", 11, conf.timeouts[STRING_S]); + socksend(param, param->clisock, (unsigned char *)"250 Proxy\r\n", 11, param->srv->timeouts[STRING_S]); continue; } if(!strncasecmp((char *)buf, "QUIT", 4)){ - socksend(param, param->clisock, (unsigned char *)"221 Proxy\r\n", 11, conf.timeouts[STRING_S]); + socksend(param, param->clisock, (unsigned char *)"221 Proxy\r\n", 11, param->srv->timeouts[STRING_S]); return -1; } - socksend(param, param->clisock, (unsigned char *)"530 5.7.0 Must issue a STARTTLS command first\r\n", 47, conf.timeouts[STRING_S]); + socksend(param, param->clisock, (unsigned char *)"530 5.7.0 Must issue a STARTTLS command first\r\n", 47, param->srv->timeouts[STRING_S]); } default: break; @@ -280,16 +280,16 @@ static int tlstobuf(struct clientparam *param, DIRECTION which){ if(*oinbuf != *ooffset){ len = *oinbuf - *ooffset; - if((unsigned long)socksend(param, which? param->remsock : param->clisock, obuf + *ooffset, (int)len, conf.timeouts[STRING_S]) != len) + if((unsigned long)socksend(param, which? param->remsock : param->clisock, obuf + *ooffset, (int)len, param->srv->timeouts[STRING_S]) != len) return which? -1 : -2; *oinbuf = *ooffset = 0; } - if(sockfillbuf(param, which, 5, conf.timeouts[STRING_S]) < 5) return -2 - e; + if(sockfillbuf(param, which, 5, param->srv->timeouts[STRING_S]) < 5) return -2 - e; buf = which? param->srvbuf : param->clibuf; if(buf[1] != 3) return -3 - e; len = 5 + size16(buf + 3); if(len > (which? param->srvbufsize : param->clibufsize)) return -4 - e; - if(sockfillbuf(param, which, len, conf.timeouts[STRING_S]) < len) return -5 - e; + if(sockfillbuf(param, which, len, param->srv->timeouts[STRING_S]) < len) return -5 - e; return (int)len; } @@ -324,7 +324,7 @@ void * tlsprchild(struct clientparam* param) { if(param->srv->s_option && snipos && res > 1){ int len; - len = socksend(param, param->remsock, param->clibuf+param->clioffset,snipos + (res/2), conf.timeouts[STRING_S]); + len = socksend(param, param->remsock, param->clibuf+param->clioffset,snipos + (res/2), param->srv->timeouts[STRING_S]); if(len != snipos + (res/2)){ RETURN(310); } @@ -353,7 +353,7 @@ void * tlsprchild(struct clientparam* param) { if(stlsproto){ res = srvstarttls(param, stlsproto); if(res){ - socksend(param, param->clisock, (unsigned char *)"\x15\x03\x01\x00\x02\x02\x28", 7, conf.timeouts[STRING_S]); + socksend(param, param->clisock, (unsigned char *)"\x15\x03\x01\x00\x02\x02\x28", 7, param->srv->timeouts[STRING_S]); RETURN(360+res); } } @@ -370,7 +370,7 @@ void * tlsprchild(struct clientparam* param) { if(lv > 3) RETURN(370); for(done=0;!done;) { len = param->srvinbuf; - if(socksend(param, param->clisock, param->srvbuf,len, conf.timeouts[STRING_S]) != len) RETURN(371); + if(socksend(param, param->clisock, param->srvbuf,len, param->srv->timeouts[STRING_S]) != len) RETURN(371); param->srvinbuf = 0; res = tlstobuf(param, SERVER); if(res <= 0) RETURN(380-res); @@ -410,14 +410,14 @@ void * tlsprchild(struct clientparam* param) { break; } if(done) break; - if(socksend(param, param->remsock, param->clibuf,len, conf.timeouts[STRING_S]) != len) RETURN(375); + if(socksend(param, param->remsock, param->clibuf,len, param->srv->timeouts[STRING_S]) != len) RETURN(375); param->cliinbuf = 0; } if(!clicert) RETURN(375); } } - RETURN (mapsocket(param, conf.timeouts[CONNECTION_L])); + RETURN (mapsocket(param, param->srv->timeouts[CONNECTION_L])); CLEANRET: sprintf(req, "%sv%d.%d %s %s", lv<0?"NONE":lv?"TLS":"SSL", lv<0?0:lv?1:3, lv<0?0:lv?lv-1:0, *param->hostname?(char *)param->hostname:"-", proto); diff --git a/src/udppm.c b/src/udppm.c index 28a3752..cbf7e56 100644 --- a/src/udppm.c +++ b/src/udppm.c @@ -67,7 +67,7 @@ void * udppmchild(struct clientparam* param) { param->srvinbuf = 0; param->clisock = param->srv->srvsock; param->waitserver64 = 0x7fffffffffffffff; - param->res = udpsockmap(param, conf.timeouts[STRING_L]); + param->res = udpsockmap(param, param->srv->timeouts[STRING_L]); _3proxy_sem_lock(udpinit); if(!param->srv->s_option)hashdelete(&udp_table, param); diff --git a/src/webadmin.c b/src/webadmin.c index 44b8f68..54fe975 100644 --- a/src/webadmin.c +++ b/src/webadmin.c @@ -27,12 +27,12 @@ struct printparam { static void stdpr(struct printparam* pp, char *buf, int inbuf){ if((pp->inbuf + inbuf > 1024) || !buf) { - socksend(pp->cp, pp->cp->clisock, (unsigned char *)pp->buf, pp->inbuf, conf.timeouts[STRING_S]); + socksend(pp->cp, pp->cp->clisock, (unsigned char *)pp->buf, pp->inbuf, pp->cp->srv->timeouts[STRING_S]); pp->inbuf = 0; if(!buf) return; } if(inbuf >= 1000){ - socksend(pp->cp, pp->cp->clisock, (unsigned char *)buf, inbuf, conf.timeouts[STRING_S]); + socksend(pp->cp, pp->cp->clisock, (unsigned char *)buf, inbuf, pp->cp->srv->timeouts[STRING_S]); } else { memcpy(pp->buf + pp->inbuf, buf, inbuf); diff --git a/tests/cases/timeouts.py b/tests/cases/timeouts.py new file mode 100644 index 0000000..7375ae2 --- /dev/null +++ b/tests/cases/timeouts.py @@ -0,0 +1,40 @@ +"""timeouts: a service keeps the timeouts given before it, so services can +have timeouts of their own.""" + +import socket +import time + + +def run(t): + short = t.free_port() + long = t.free_port() + t.start("timeouts", f""" + auth none + timeouts 1 5 30 2 + proxy -p{short} + timeouts 1 5 30 60 + proxy -p{long} + """, ports=[short, long]) + + def idle(port, wait): + """Connects and sends nothing: how long until the proxy gives up on + the request (STRING_LONG), or None if it still waits after wait.""" + sock = socket.create_connection(("127.0.0.1", port), 5) + sock.settimeout(wait) + start = time.time() + try: + sock.recv(100) + return time.time() - start + except socket.timeout: + return None + except OSError: + return time.time() - start + finally: + sock.close() + + took = idle(short, 10) + t.in_range(round(took) if took is not None else None, 1, 5, + "a service started after timeouts with STRING_LONG 2 closes an " + "idle connection in about 2 seconds") + t.eq(None, idle(long, 4), + "a service started after timeouts with STRING_LONG 60 still waits")