diff --git a/CMakeLists.txt b/CMakeLists.txt index cc6e9f6..1b324a1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,7 +51,7 @@ option(3PROXY_USE_OPENSSL "Enable TLS/SSL support via OpenSSL (fallback when wol option(3PROXY_USE_PCRE2 "Enable PCRE2 regex filtering" ON) option(3PROXY_USE_PAM "Enable PAM/PamAuth" ON) option(3PROXY_USE_ODBC "Enable ODBC support (Unix only, always ON on Windows)" OFF) -option(3PROXY_USE_SPLICE "Use Linux splice() for zero-copy (Linux only)" ON) +option(3PROXY_USE_SPLICE "Build Linux splice() support, slower than read/write for most traffic (Linux only)" OFF) option(3PROXY_USE_POLL "Use poll() instead of select() (Unix only)" ON) option(3PROXY_USE_WSAPOLL "Use WSAPoll instead of select() (Windows only)" ON) option(3PROXY_USE_NETFILTER "Enable Linux netfilter support (Linux only)" ON) diff --git a/Makefile.Linux b/Makefile.Linux index 6bbaa2e..bd8982a 100644 --- a/Makefile.Linux +++ b/Makefile.Linux @@ -3,6 +3,10 @@ # # add -DWITH_ODBC to CFLAGS and -lodbc to LIBS to compile with ODBC # library support. Add -DSAFESQL for poorely written ODBC library / drivers. +# +# Linux splice() support is not built by default, it is slower than the +# read/write path for most traffic. Add -DWITHSPLICE to CFLAGS to build it, +# it must additionally be enabled per service with the -s option. BUILDDIR = ../bin/ PREFIX ?= 3proxy_ @@ -10,7 +14,7 @@ CRYPT_PREFIX ?= $(PREFIX) CC ?= gcc CFLAGS ?= -O3 -flto -CFLAGS += -fno-strict-aliasing -c -pthread -DWITHSPLICE -D_GNU_SOURCE -DGETHOSTBYNAME_R -D_THREAD_SAFE -D_REENTRANT -DFD_SETSIZE=4096 -DWITH_POLL -DWITH_NETFILTER -D WITH_UN +CFLAGS += -fno-strict-aliasing -c -pthread -D_GNU_SOURCE -DGETHOSTBYNAME_R -D_THREAD_SAFE -D_REENTRANT -DFD_SETSIZE=4096 -DWITH_POLL -DWITH_NETFILTER -D WITH_UN COUT = -o LN ?= ${CC} DCFLAGS ?= -fPIC diff --git a/doc/html/highload.html b/doc/html/highload.html index a91f829..dea64a5 100644 --- a/doc/html/highload.html +++ b/doc/html/highload.html @@ -30,10 +30,7 @@ Each connected client requires:
-socks -s0 -
Do not use TCP_NODELAY on slow connections with high delays when connection bandwidth is a bottleneck. -
-proxy -s0 --Splice is only available on Linux. Splice requires more system buffers and file descriptors -and produces more IOCTLs but reduces process memory and overall CPU usage. -Disable splice if there are a lot of short-lived connections with no bandwidth -requirements. -
Use splice only on high-speed connections (e.g., 10GbE) when the processor, memory speed, or -system bus are bottlenecks. -
TCP_NODELAY and splice are not contrary to each other and should be combined on -high-speed connections. -
proxy -g8000,3,10@@ -294,7 +264,7 @@ the minimal number of packets in the same direction to apply the algorithm, and the last value is the delay added after polling and prior to reading data. The example above adds a 10-millisecond delay before reading data if the average polling size is below 8000 bytes and 3 read operations have been made in the same -direction. It's especially useful with splice.
logdump 1 1is useful +direction.
logdump 1 1is useful to see how grace delays work; choose a delay value to avoid filling the read pipe/buffer (typically 64K) but keep the request sizes close to the chosen average on large file uploads/downloads. diff --git a/man/3proxy.cfg.5 b/man/3proxy.cfg.5 index 59675bc..e21d31a 100644 --- a/man/3proxy.cfg.5 +++ b/man/3proxy.cfg.5 @@ -188,9 +188,16 @@ any protocol-specific data. .br .B -g(\fIGRACE_TRAFF\fB,\fIGRACE_NUM\fB,\fIGRACE_DELAY\fR) delay GRACE_DELAY milliseconds before polling if average polling size is below GRACE_TRAFF bytes and GRACE_NUM read operations in a single direction are detected within 1 second. Useful to minimize polling +.br .B -s (for admin) secure, allow only secure operations, currently only traffic counters view without ability to reset. +.br + (for TCP services, Linux) enable splice(). splice() is not built by default and +is disabled even when built, because current Linux does not implement +SPLICE_F_MOVE, so no real zero-copy takes place and the read/write path is faster +for most traffic. Rebuild with -DWITHSPLICE to make -s available, -s0 disables it +explicitly. .br (for dnspr) simple, do not use resolver and 3proxy cache, always use external DNS server. .br diff --git a/src/dnspr.c b/src/dnspr.c index 0eddd72..d6372e7 100644 --- a/src/dnspr.c +++ b/src/dnspr.c @@ -35,7 +35,6 @@ void * dnsprchild(struct clientparam* param) { if(!(bbuf = malloc(BUFSIZE+2))){ - param->srv->fds.events = POLLIN; RETURN (21); } buf = bbuf+2; @@ -59,7 +58,6 @@ void * dnsprchild(struct clientparam* param) { #else param->clisock = param->srv->srvsock; #endif - param->srv->fds.events = POLLIN; if(i < 0) { RETURN(813); diff --git a/src/proxymain.c b/src/proxymain.c index 4e3ba86..0cbda7f 100644 --- a/src/proxymain.c +++ b/src/proxymain.c @@ -311,7 +311,7 @@ int MODULEMAINFUNC (int argc, char** argv){ " -De(DEVICENAME) bind external interface to device, e.g. eth1\n" #endif #ifdef WITHSPLICE - " -s Use splice() - faster proxing, but no filtering for data\n" + " -s Use splice() - no filtering for data, off by default\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" @@ -586,7 +586,7 @@ int MODULEMAINFUNC (int argc, char** argv){ srv.s_option = 1 + atoi(argv[i]+2); #ifdef WITHSPLICE else - if(*(argv[i]+2)) srv.usesplice = atoi(argv[i]+2); + srv.usesplice = *(argv[i]+2)? atoi(argv[i]+2) : 1; #endif break; case 'o': @@ -956,13 +956,7 @@ int MODULEMAINFUNC (int argc, char** argv){ } if (iscbc) break; if (conf.paused != srv.paused) break; - if (srv.fds.events & POLLIN) { - error = srv.so._poll(srv.so.state, &srv.fds, 1, 1000); - } - else { - usleep(SLEEPTIME); - continue; - } + error = srv.so._poll(srv.so.state, &srv.fds, 1, 1000); if (error >= 1) break; if (error == 0) continue; if (errno != EAGAIN && errno != EINTR) { @@ -1225,7 +1219,7 @@ void srvinit(struct srvparam * srv, struct clientparam *param){ srv->saved_nsfd = srv->i_nsfd = srv->o_nsfd = -1; #endif #ifdef WITHSPLICE - srv->usesplice = 1; + srv->usesplice = 0; #endif memset(param, 0, sizeof(struct clientparam)); param->srv = srv;