mirror of
https://github.com/3proxy/3proxy.git
synced 2026-10-17 00:55:47 +08:00
Fix socket draining / lingering
Some checks failed
C/C++ CI Linux / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Has been cancelled
C/C++ CI Linux / ${{ matrix.target }} (ubuntu-latest) (push) Has been cancelled
C/C++ CI MacOS / ${{ matrix.target }} (macos-15) (push) Has been cancelled
C/C++ CI Windows / ${{ matrix.target }} (windows-2022) (push) Has been cancelled
C/C++ CI cmake / ${{ matrix.target }} (macos-15) (push) Has been cancelled
C/C++ CI cmake / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Has been cancelled
C/C++ CI cmake / ${{ matrix.target }} (ubuntu-latest) (push) Has been cancelled
C/C++ CI cmake / ${{ matrix.target }} (windows-2022) (push) Has been cancelled
C/C++ CI cmake / ubuntu-latest (wolfSSL) (push) Has been cancelled
Some checks failed
C/C++ CI Linux / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Has been cancelled
C/C++ CI Linux / ${{ matrix.target }} (ubuntu-latest) (push) Has been cancelled
C/C++ CI MacOS / ${{ matrix.target }} (macos-15) (push) Has been cancelled
C/C++ CI Windows / ${{ matrix.target }} (windows-2022) (push) Has been cancelled
C/C++ CI cmake / ${{ matrix.target }} (macos-15) (push) Has been cancelled
C/C++ CI cmake / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Has been cancelled
C/C++ CI cmake / ${{ matrix.target }} (ubuntu-latest) (push) Has been cancelled
C/C++ CI cmake / ${{ matrix.target }} (windows-2022) (push) Has been cancelled
C/C++ CI cmake / ubuntu-latest (wolfSSL) (push) Has been cancelled
(cherry picked from commit 1cea4fef4b,
without httpsrv.c, which 0.9 does not have)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
1e6adae3cd
commit
86457c3024
@ -414,7 +414,6 @@ int
|
|||||||
return shutdown(s, how);
|
return shutdown(s, how);
|
||||||
}
|
}
|
||||||
int WINAPI def_closesocket(void* state, SOCKET s){
|
int WINAPI def_closesocket(void* state, SOCKET s){
|
||||||
usleep(SLEEPTIME);
|
|
||||||
return closesocket(s);
|
return closesocket(s);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@ -736,7 +735,9 @@ int doconnect(struct clientparam * param){
|
|||||||
if(param->srv->so._getpeername(param->sostate, param->remsock, (struct sockaddr *)¶m->sinsr, &size)==-1) {return (14);}
|
if(param->srv->so._getpeername(param->sostate, param->remsock, (struct sockaddr *)¶m->sinsr, &size)==-1) {return (14);}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
#ifndef _WIN32
|
||||||
struct linger lg = {1,conf.timeouts[LINGER_TO]};
|
struct linger lg = {1,conf.timeouts[LINGER_TO]};
|
||||||
|
#endif
|
||||||
|
|
||||||
if(SAISNULL(¶m->sinsr)){
|
if(SAISNULL(¶m->sinsr)){
|
||||||
if(SAISNULL(¶m->req)) {
|
if(SAISNULL(¶m->req)) {
|
||||||
@ -766,7 +767,10 @@ int doconnect(struct clientparam * param){
|
|||||||
*SAPORT(¶m->sinsl) = 0;
|
*SAPORT(¶m->sinsl) = 0;
|
||||||
setopts(param->remsock, param->srv->srvsockopts);
|
setopts(param->remsock, param->srv->srvsockopts);
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
/* not on Windows, see the accepting side in proxymain.c */
|
||||||
param->srv->so._setsockopt(param->sostate, param->remsock, SOL_SOCKET, SO_LINGER, (char *)&lg, sizeof(lg));
|
param->srv->so._setsockopt(param->sostate, param->remsock, SOL_SOCKET, SO_LINGER, (char *)&lg, sizeof(lg));
|
||||||
|
#endif
|
||||||
if(extbindtodevice(param, param->remsock)) return 12;
|
if(extbindtodevice(param, param->remsock)) return 12;
|
||||||
#ifdef WITH_UN
|
#ifdef WITH_UN
|
||||||
if(*SAFAMILY(¶m->sinsl) != AF_UNIX)
|
if(*SAFAMILY(¶m->sinsl) != AF_UNIX)
|
||||||
|
|||||||
@ -21,14 +21,18 @@ void * ftpprchild(struct clientparam* param) {
|
|||||||
SOCKET sc = INVALID_SOCKET, ss = INVALID_SOCKET, clidatasock = INVALID_SOCKET;
|
SOCKET sc = INVALID_SOCKET, ss = INVALID_SOCKET, clidatasock = INVALID_SOCKET;
|
||||||
SASIZETYPE sasize;
|
SASIZETYPE sasize;
|
||||||
char * req = NULL;
|
char * req = NULL;
|
||||||
|
#ifndef _WIN32
|
||||||
struct linger lg;
|
struct linger lg;
|
||||||
|
#endif
|
||||||
struct pollfd fds;
|
struct pollfd fds;
|
||||||
|
|
||||||
if(!(buf = malloc(BUFSIZE))) RETURN(876);
|
if(!(buf = malloc(BUFSIZE))) RETURN(876);
|
||||||
param->ctrlsock = param->clisock;
|
param->ctrlsock = param->clisock;
|
||||||
param->operation = CONNECT;
|
param->operation = CONNECT;
|
||||||
|
#ifndef _WIN32
|
||||||
lg.l_onoff = 1;
|
lg.l_onoff = 1;
|
||||||
lg.l_linger = conf.timeouts[STRING_L];;
|
lg.l_linger = conf.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, conf.timeouts[STRING_S])!=11) {RETURN (801);}
|
||||||
for(;;){
|
for(;;){
|
||||||
i = sockgetlinebuf(param, CLIENT, buf, BUFSIZE - 10, '\n', conf.timeouts[CONNECTION_S]);
|
i = sockgetlinebuf(param, CLIENT, buf, BUFSIZE - 10, '\n', conf.timeouts[CONNECTION_S]);
|
||||||
@ -260,8 +264,11 @@ void * ftpprchild(struct clientparam* param) {
|
|||||||
}
|
}
|
||||||
sc = param->remsock;
|
sc = param->remsock;
|
||||||
param->remsock = ss;
|
param->remsock = ss;
|
||||||
|
#ifndef _WIN32
|
||||||
|
/* not on Windows, see the accepting side in proxymain.c */
|
||||||
param->srv->so._setsockopt(param->sostate, param->remsock, SOL_SOCKET, SO_LINGER, (char *)&lg, sizeof(lg));
|
param->srv->so._setsockopt(param->sostate, param->remsock, SOL_SOCKET, SO_LINGER, (char *)&lg, sizeof(lg));
|
||||||
param->srv->so._setsockopt(param->sostate, clidatasock, SOL_SOCKET, SO_LINGER, (char *)&lg, sizeof(lg));
|
param->srv->so._setsockopt(param->sostate, clidatasock, SOL_SOCKET, SO_LINGER, (char *)&lg, sizeof(lg));
|
||||||
|
#endif
|
||||||
param->clisock = clidatasock;
|
param->clisock = clidatasock;
|
||||||
res = mapsocket(param, conf.timeouts[CONNECTION_S]);
|
res = mapsocket(param, conf.timeouts[CONNECTION_S]);
|
||||||
if(param->remsock != INVALID_SOCKET) {
|
if(param->remsock != INVALID_SOCKET) {
|
||||||
|
|||||||
@ -306,7 +306,9 @@ int MODULEMAINFUNC (int argc, char** argv){
|
|||||||
unsigned char *cbc_string = NULL, *cbl_string = NULL;
|
unsigned char *cbc_string = NULL, *cbl_string = NULL;
|
||||||
PROXYSOCKADDRTYPE cbsa;
|
PROXYSOCKADDRTYPE cbsa;
|
||||||
FILE *fp = NULL;
|
FILE *fp = NULL;
|
||||||
|
#ifndef _WIN32
|
||||||
struct linger lg;
|
struct linger lg;
|
||||||
|
#endif
|
||||||
int nlog = 5000;
|
int nlog = 5000;
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
int saved_nsfd = -1;
|
int saved_nsfd = -1;
|
||||||
@ -1093,10 +1095,14 @@ int MODULEMAINFUNC (int argc, char** argv){
|
|||||||
#else
|
#else
|
||||||
fcntl(new_sock,F_SETFL,O_NONBLOCK | fcntl(new_sock,F_GETFL));
|
fcntl(new_sock,F_SETFL,O_NONBLOCK | fcntl(new_sock,F_GETFL));
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef _WIN32
|
||||||
|
/* Not on Windows: there closesocket() on a non-blocking socket with a linger
|
||||||
|
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_onoff = 1;
|
||||||
lg.l_linger = conf.timeouts[STRING_L];
|
lg.l_linger = conf.timeouts[STRING_L];
|
||||||
|
|
||||||
srv.so._setsockopt(srv.so.state, new_sock, SOL_SOCKET, SO_LINGER, (char *)&lg, sizeof(lg));
|
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));
|
srv.so._setsockopt(srv.so.state, new_sock, SOL_SOCKET, SO_OOBINLINE, (char *)&opt, sizeof(int));
|
||||||
}
|
}
|
||||||
#ifndef NOUDPMAIN
|
#ifndef NOUDPMAIN
|
||||||
@ -1382,21 +1388,34 @@ void freeparam(struct clientparam * param) {
|
|||||||
}
|
}
|
||||||
if(param->clibuf) free(param->clibuf);
|
if(param->clibuf) free(param->clibuf);
|
||||||
if(param->srvbuf) free(param->srvbuf);
|
if(param->srvbuf) free(param->srvbuf);
|
||||||
|
/* Not shut down on Windows: there shutting down receiving resets the
|
||||||
|
connection as soon as the peer sends anything more, and close()
|
||||||
|
alone sends whatever is queued before its FIN. Elsewhere it stays:
|
||||||
|
on the BSDs it discards what is left unread, so the close that
|
||||||
|
follows is not turned into a reset. */
|
||||||
if(param->srv) {
|
if(param->srv) {
|
||||||
if(param->ctrlsocksrv != INVALID_SOCKET && param->ctrlsocksrv != param->remsock) {
|
if(param->ctrlsocksrv != INVALID_SOCKET && param->ctrlsocksrv != param->remsock) {
|
||||||
|
#ifndef _WIN32
|
||||||
param->srv->so._shutdown(param->sostate, param->ctrlsocksrv, SHUT_RDWR);
|
param->srv->so._shutdown(param->sostate, param->ctrlsocksrv, SHUT_RDWR);
|
||||||
|
#endif
|
||||||
param->srv->so._closesocket(param->sostate, param->ctrlsocksrv);
|
param->srv->so._closesocket(param->sostate, param->ctrlsocksrv);
|
||||||
}
|
}
|
||||||
if(param->ctrlsock != INVALID_SOCKET && param->ctrlsock != param->clisock) {
|
if(param->ctrlsock != INVALID_SOCKET && param->ctrlsock != param->clisock) {
|
||||||
|
#ifndef _WIN32
|
||||||
param->srv->so._shutdown(param->sostate, param->ctrlsock, SHUT_RDWR);
|
param->srv->so._shutdown(param->sostate, param->ctrlsock, SHUT_RDWR);
|
||||||
|
#endif
|
||||||
param->srv->so._closesocket(param->sostate, param->ctrlsock);
|
param->srv->so._closesocket(param->sostate, param->ctrlsock);
|
||||||
}
|
}
|
||||||
if(param->remsock != INVALID_SOCKET) {
|
if(param->remsock != INVALID_SOCKET) {
|
||||||
|
#ifndef _WIN32
|
||||||
param->srv->so._shutdown(param->sostate, param->remsock, SHUT_RDWR);
|
param->srv->so._shutdown(param->sostate, param->remsock, SHUT_RDWR);
|
||||||
|
#endif
|
||||||
param->srv->so._closesocket(param->sostate, param->remsock);
|
param->srv->so._closesocket(param->sostate, param->remsock);
|
||||||
}
|
}
|
||||||
if(param->clisock != INVALID_SOCKET) {
|
if(param->clisock != INVALID_SOCKET) {
|
||||||
|
#ifndef _WIN32
|
||||||
param->srv->so._shutdown(param->sostate, param->clisock, SHUT_RDWR);
|
param->srv->so._shutdown(param->sostate, param->clisock, SHUT_RDWR);
|
||||||
|
#endif
|
||||||
param->srv->so._closesocket(param->sostate, param->clisock);
|
param->srv->so._closesocket(param->sostate, param->clisock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -868,9 +868,6 @@ log("timeout");
|
|||||||
else if(inclientpipe || inserverpipe) res = 94;
|
else if(inclientpipe || inserverpipe) res = 94;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if((param->nwrites > 0 && !SERVERTERMWRITE) || (param->nreads > 0 && !CLIENTTERMWRITE))
|
|
||||||
usleep(SLEEPTIME * 10);
|
|
||||||
|
|
||||||
CLEANRET:
|
CLEANRET:
|
||||||
|
|
||||||
#ifdef WITHSPLICE
|
#ifdef WITHSPLICE
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user