mirror of
https://github.com/3proxy/3proxy.git
synced 2026-08-26 09:55:48 +08:00
Fix: insufficient default stack for wolfSSL with glibc
This commit is contained in:
parent
a0ae86957f
commit
cb9effab9b
5
.github/workflows/c-cpp-Windows.yml
vendored
5
.github/workflows/c-cpp-Windows.yml
vendored
@ -28,7 +28,9 @@ jobs:
|
||||
LDFLAGS: '-L "c:/msys64/mingw64/lib"'
|
||||
CFLAGS: '-I "c:/msys64/mingw64/include"'
|
||||
- name: regression tests (MinGW)
|
||||
run: python tests\run.py --bin bin\3proxy.exe
|
||||
run: |
|
||||
$env:PATH = "c:\msys64\mingw64\bin;$env:PATH"
|
||||
python tests\run.py --bin bin\3proxy.exe
|
||||
- name: make clean Windows
|
||||
run: make -f Makefile.win clean
|
||||
- name: Add msbuild to PATH
|
||||
@ -42,5 +44,6 @@ jobs:
|
||||
set "LIB=%LIB%;c:/vcpkg/installed/x64-windows-static/lib;c:/vcpkg/installed/x64-windows/lib"
|
||||
set "INCLUDE=%INCLUDE%;c:/vcpkg/installed/x64-windows-static/include;c:/vcpkg/installed/x64-windows/include"
|
||||
nmake /F Makefile.msvc WOLFSSL=1 || exit /b 1
|
||||
set "PATH=%PATH%;c:/vcpkg/installed/x64-windows/bin"
|
||||
python tests\run.py --bin bin\3proxy.exe || exit /b 1
|
||||
nmake /F Makefile.msvc clean
|
||||
|
||||
@ -871,7 +871,7 @@ with probability of 0.7) for outgoing web connections. Chains are only applied t
|
||||
.br
|
||||
\fBextip\fR does not actually redirect the request; it sets the external address for this request to \fI<ip>\fR. It can be chained with another parent type. It's useful to set the external IP based on ACL or make it random.
|
||||
.br
|
||||
\fBextport\fR does not redirect the request; it sets the range the local port of outgoing connections is taken from, given as \fIFIRST-LAST\fR inclusive in place of the port argument, with 0.0.0.0 as the address, for example \fBparent 1000 extport 0.0.0.0 40000-40100\fR. Where the system can be asked to pick the port itself (Linux \fBIP_LOCAL_PORT_RANGE\fR) it does, otherwise a port is picked at random from the range and retried if it is already in use, up to ten times. It can be chained with another parent type, and the access rule it belongs to decides which requests it applies to, so \fBallow * * * * UDPASSOC\fR followed by \fBparent 1000 extport 0.0.0.0 40000-40100\fR limits it to UDP associations. The range is applied when the outgoing connection is made, so a kept alive connection carrying several requests uses the rule that matched when it was opened.
|
||||
\fBextport\fR does not redirect the request; it sets the range the local port of outgoing connections is taken from, given as \fIFIRST-LAST\fR inclusive in place of the port argument, with 0.0.0.0 as the address, for example \fBparent 1000 extport 0.0.0.0 40000-40100\fR. Where the system can be asked to pick the port itself (Linux \fBIP_LOCAL_PORT_RANGE\fR) it does, otherwise a port is picked at random from the range and retried if it is already in use, up to ten times. On Linux the range has to lie within \fInet.ipv4.ip_local_port_range\fR, commonly 32768-60999: the kernel ignores a range outside it and picks an ordinary ephemeral port instead. If no port in the range can be bound, an ephemeral port is used rather than failing the connection. It can be chained with another parent type, and the access rule it belongs to decides which requests it applies to, so \fBallow * * * * UDPASSOC\fR followed by \fBparent 1000 extport 0.0.0.0 40000-40100\fR limits it to UDP associations. The range is applied when the outgoing connection is made, so a kept alive connection carrying several requests uses the rule that matched when it was opened.
|
||||
.br
|
||||
\fBintport\fR is the same for sockets bound on the side facing the client: the port a UDP association tells the client to send its datagrams to, and the FTP proxy data connection.
|
||||
.br
|
||||
|
||||
@ -182,7 +182,7 @@ int timeouts[12] = {
|
||||
EINVAL below it and the thread silently gets the 8M system default stack.
|
||||
*/
|
||||
size_t threadstacksize(int extra){
|
||||
long size = BASESTACKSIZE + extra;
|
||||
long size = BASESTACKSIZE + TLSSTACKSIZE + extra;
|
||||
|
||||
if(size < (long)PTHREAD_STACK_MIN) size = (long)PTHREAD_STACK_MIN;
|
||||
return (size_t)size;
|
||||
@ -803,8 +803,11 @@ int bindwithrange(struct clientparam *param, SOCKET sock, PROXYSOCKADDRTYPE *sa,
|
||||
if(!param->srv->so._bind(param->sostate, sock, (struct sockaddr *)sa, SASIZE(sa))) return 0;
|
||||
}
|
||||
|
||||
/* Every port tried was taken. Fall back to an ephemeral one, which is
|
||||
what the kernel option above does when it cannot honour the range, so
|
||||
an exhausted range behaves the same way on every platform. */
|
||||
*SAPORT(sa) = 0;
|
||||
return -1;
|
||||
return param->srv->so._bind(param->sostate, sock, (struct sockaddr *)sa, SASIZE(sa));
|
||||
}
|
||||
|
||||
/* Host lists in access rules have always accepted name, name*, *name and
|
||||
|
||||
@ -157,7 +157,12 @@ int start_proxy_thread(struct child * chp){
|
||||
pthread_attr_init(&pa);
|
||||
pthread_attr_setstacksize(&pa,threadstacksize(conf.stacksize));
|
||||
pthread_attr_setdetachstate(&pa,PTHREAD_CREATE_DETACHED);
|
||||
pthread_create(&thread, &pa, startsrv, (void *)chp);
|
||||
if(pthread_create(&thread, &pa, startsrv, (void *)chp)){
|
||||
pthread_attr_destroy(&pa);
|
||||
fprintf(stderr, "Failed to create service thread on line %d, try to set larger stacksize\n", linenum);
|
||||
_3proxy_sem_unlock(conf.threadinit);
|
||||
return(40);
|
||||
}
|
||||
pthread_attr_destroy(&pa);
|
||||
#endif
|
||||
_3proxy_sem_lock(conf.threadinit);
|
||||
|
||||
17
src/proxy.h
17
src/proxy.h
@ -135,6 +135,23 @@ void daemonize(void);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* wolfSSL reserves around 48K of static thread-local storage. glibc counts
|
||||
that against the thread stack, so pthread_create() fails with EINVAL and
|
||||
no thread starts at all. musl places the block next to the stack instead
|
||||
of inside it and needs nothing extra, and OpenSSL has no static TLS.
|
||||
musl identifies itself by no macro of its own, but it does not define
|
||||
__GLIBC__, which any libc header pulled in above would have set.
|
||||
*/
|
||||
#ifndef TLSSTACKSIZE
|
||||
#if defined(__linux__) && !defined(__GLIBC__)
|
||||
#define TLSSTACKSIZE 0
|
||||
#elif defined(WITH_WOLFSSL)
|
||||
#define TLSSTACKSIZE 49152
|
||||
#else
|
||||
#define TLSSTACKSIZE 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
size_t threadstacksize(int extra);
|
||||
#endif
|
||||
|
||||
@ -134,8 +134,15 @@ class Tester:
|
||||
|
||||
for port in ports:
|
||||
if not self.wait_port(port):
|
||||
code = proc.poll()
|
||||
if code is None:
|
||||
died = "the process is still running"
|
||||
else:
|
||||
died = f"the process exited with code {code}"
|
||||
if os.name == "nt" and code is not None and code & 0xFFFFFFFF == 0xC0000135:
|
||||
died += " (a DLL it needs was not found)"
|
||||
raise Failure(
|
||||
f"{name} never listened on port {port}\n"
|
||||
f"{name} never listened on port {port}: {died}\n"
|
||||
f"--- configuration ---\n{open(path).read()}"
|
||||
f"--- output ---\n{server.output()}")
|
||||
return server
|
||||
|
||||
Loading…
Reference in New Issue
Block a user