From 55d1bbe155fdaf05d7413b129bf63d74b5c81e82 Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Thu, 19 May 2022 18:51:02 +0300 Subject: [PATCH] Grace delay feature added `proxy -g8000,3,10` First parameter is average read size we want to keep, second parameter is minimal number of packets in the same direction to apply algorythm, last value is delay added after polling and prior to reading data. An example above adds 10 millisecond delay before reading data if average polling size is below 8000 bytes and 3 read operations are made in the same direction. It's specially usefule with splice. `logdump 1 1` is useful to see how grace delays work, choose delay value to avoid filling the read pipe/buffer (typically 64K) but keep the request sizes close to chosen average on large file upload/download. --- doc/html/highload.html | 13 +++++++++++++ man/3proxy.cfg.3 | 2 ++ src/common.c | 1 + src/proxy.c | 2 +- src/proxy.h | 2 +- src/proxymain.c | 4 ++++ src/sockmap.c | 25 +++++++++++++++++++++++++ src/structures.h | 2 ++ 8 files changed, 49 insertions(+), 2 deletions(-) diff --git a/doc/html/highload.html b/doc/html/highload.html index a3693cf..b57a687 100644 --- a/doc/html/highload.html +++ b/doc/html/highload.html @@ -285,3 +285,16 @@ requirements. system bus are bottlenecks.
TCP_NODELAY and splice are not contrary to each over and should be combined on high-speed connections. + +
proxy -g8000,3,10+First parameter is average read size we want to keep, second parameter is +minimal number of packets in the same direction to apply algorythm, +last value is delay added after polling and prior to reading data. +An example above adds 10 millisecond delay before reading data if average +polling size is below 8000 bytes and 3 read operations are made in the same +direction. It's specially usefule with splice.
logdump 1 1is useful +to see how grace delays work, choose delay value to avoid filling the read +pipe/buffer (typically 64K) but keep the request sizes close to chosen average +on large file upload/download. diff --git a/man/3proxy.cfg.3 b/man/3proxy.cfg.3 index c29d5c3..82ba02a 100644 --- a/man/3proxy.cfg.3 +++ b/man/3proxy.cfg.3 @@ -110,6 +110,8 @@ disable NTLM authentication (required if passwords are stored in Unix crypt form .B -n1 enable NTLMv1 authentication. .br +.B -g(GRACE_TRAFF,GRACE_NUM,GRACE_DELAY) +delay GRACE_DELAY milliseconds before polling if average polling size below GRACE_TRAFF bytes and GRACE_NUM read operations in single directions are detected within 1 second. Useful to minimize polling .B -s (for admin) secure, allow only secure operations, currently only traffic counters view without ability to reset. diff --git a/src/common.c b/src/common.c index 871f7bc..b4e85d5 100644 --- a/src/common.c +++ b/src/common.c @@ -103,6 +103,7 @@ struct extparam conf = { 0, 0, -1, 0, 0, 0, 0, 0, 500, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 6, 600, 1048576, NULL, NULL, diff --git a/src/proxy.c b/src/proxy.c index 8bc7a38..881ef1e 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -131,7 +131,7 @@ char * proxy_stringtable[] = { NULL }; -#define LINESIZE 4096 +#define LINESIZE 32768 #define BUFSIZE (LINESIZE*2) #define FTPBUFSIZE 1536 diff --git a/src/proxy.h b/src/proxy.h index b30ebe8..1756648 100644 --- a/src/proxy.h +++ b/src/proxy.h @@ -30,7 +30,7 @@ #define MAXNSERVERS 5 #define UDPBUFSIZE 16384 -#define TCPBUFSIZE 8192 +#define TCPBUFSIZE 65536 #define SRVBUFSIZE (param->srv->bufsize?param->srv->bufsize:((param->service == S_UDPPM)?UDPBUFSIZE:TCPBUFSIZE)) diff --git a/src/proxymain.c b/src/proxymain.c index 8d5e1d7..e5cdda1 100644 --- a/src/proxymain.c +++ b/src/proxymain.c @@ -223,6 +223,7 @@ int MODULEMAINFUNC (int argc, char** argv){ #ifdef WITHSLICE " -s Use slice() - faster proxing, but no filtering for data\n" #endif + "-g(GRACE_TRAFF,GRACE_NUM,GRACE_DELAY) - delay GRACE_DELAY milliseconds before polling if average polling size below GRACE_TRAFF bytes and GRACE_NUM read operations in single directions are detected within 1 second to minimize polling\n" " -fFORMAT logging format (see documentation)\n" " -l log to stderr\n" " -lFILENAME log to FILENAME\n" @@ -428,6 +429,9 @@ int MODULEMAINFUNC (int argc, char** argv){ case 'a': srv.anonymous = 1 + atoi(argv[i]+2); break; + case 'g': + sscanf(argv[i]+2, "%d,%d,%d", &srv.gracetraf, &srv.gracenum, &srv.gracedelay); + break; case 's': #ifdef WITHSPLICE if(isudp || srv.service == S_ADMIN) diff --git a/src/sockmap.c b/src/sockmap.c index 19b603f..2f34a63 100644 --- a/src/sockmap.c +++ b/src/sockmap.c @@ -60,6 +60,7 @@ int sockmap(struct clientparam * param, int timeo, int usesplice){ int res; SASIZETYPE sasize; int needaction = 0; + int graceclinum=0, gracesrvnum=0, graceclitraf=0, gracesrvtraf=0, gracetime=0; #ifdef WITHSPLICE uint64_t inclientpipe = 0, inserverpipe = 0; @@ -158,6 +159,18 @@ sprintf(logbuf, "int FROMCLIENT = %d, TOCLIENTBUF = %d, FROMCLIENTBUF = %d, TOSE log(logbuf); #endif + if(needaction && param->srv->gracedelay && !sleeptime){ + if(gracetime != conf.time){ + gracetime = conf.time; + graceclinum=gracesrvnum=graceclitraf=gracesrvtraf=0; + } + else { + if( (graceclinum && graceclitraf && graceclinum>=param->srv->gracenum && (!param->srv->gracetraf || graceclitraf/graceclinum <= param->srv->gracetraf)) || + (gracesrvnum && gracesrvtraf && gracesrvnum>=param->srv->gracenum && (!param->srv->gracetraf || gracesrvtraf/gracesrvnum <= param->srv->gracetraf))) { + sleeptime = param->srv->gracedelay; + } + } + } if(needaction > 2 && !sleeptime){ if(needaction > (MAXFAILATTEMPT+1)){RETURN (93);} sleeptime = (1<<(needaction-2)); @@ -354,6 +367,9 @@ log(logbuf); #ifdef WITHLOG log("done read from client to pipe"); #endif + graceclinum++; + graceclitraf += res; + gracesrvnum = gracesrvtraf = 0; inclientpipe += res; if(inclientpipe >= MAXSPLICE) TOCLIENTPIPE = 0; needaction = 0; @@ -388,6 +404,9 @@ log(logbuf); #ifdef WITHLOG log("done read from server to pipe\n"); #endif + gracesrvnum++; + gracesrvtraf += res; + graceclinum = graceclitraf = 0; param->nreads++; param->statssrv64 += res; inserverpipe += res; @@ -426,6 +445,9 @@ log("read from client to buf"); #ifdef WITHLOG log("done read from client to buf"); #endif + graceclinum++; + graceclitraf += res; + gracesrvnum = gracesrvtraf = 0; inclientbuf += res; param->cliinbuf += res; if(param->clibufsize == param->cliinbuf) TOCLIENTBUF = 0; @@ -451,6 +473,9 @@ log("read from server to buf"); #ifdef WITHLOG log("done read from server to buf"); #endif + gracesrvnum++; + gracesrvtraf += res; + graceclinum = graceclitraf = 0; param->nreads++; param->statssrv64 += res; inserverbuf += res; diff --git a/src/structures.h b/src/structures.h index 6d929ca..3de7795 100644 --- a/src/structures.h +++ b/src/structures.h @@ -437,6 +437,7 @@ struct srvparam { int noforce; int anonymous; int clisockopts, srvsockopts, lissockopts, cbcsockopts, cbssockopts; + int gracetraf, gracenum, gracedelay; #ifdef WITHSPLICE int usesplice; #endif @@ -576,6 +577,7 @@ struct extparam { demon, maxchild, needreload, timetoexit, version, noforce, bandlimver, parentretries; int authcachetype, authcachetime; int filtermaxsize; + int gracetraf, gracenum, gracedelay; unsigned char *logname, **archiver; ROTATION logtype, countertype; char * counterfile;