mirror of
https://github.com/3proxy/3proxy.git
synced 2026-10-28 22:05:48 +08:00
Sockets read after a wait are non-blocking, and a read finding nothing waits again
A wait may end with nothing to read: a TLS record not yet whole, a connection gone before it is accepted, and, once clients share a thread, nothing more than a chance to try. Where a read or an accept() followed a wait on a blocking socket, or ended the operation when it found nothing, the socket is non-blocking and the wait is made again: the listening sockets of SOCKS BIND and of FTP passive mode, httpsrv reading what is left of a request body, and the RADIUS client, which reads with sockrecvfrom(). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
7718ffa9f7
commit
0d6b2950f0
@ -294,10 +294,8 @@ int radsend(struct clientparam * param, int auth, int stop){
|
|||||||
int total_length;
|
int total_length;
|
||||||
int len;
|
int len;
|
||||||
PROXYSOCKADDRTYPE saremote;
|
PROXYSOCKADDRTYPE saremote;
|
||||||
struct pollfd fds[1];
|
|
||||||
char vector[AUTH_VECTOR_LEN];
|
char vector[AUTH_VECTOR_LEN];
|
||||||
radius_packet_t packet, rpacket;
|
radius_packet_t packet, rpacket;
|
||||||
SASIZETYPE salen;
|
|
||||||
int data_len;
|
int data_len;
|
||||||
int count=0;
|
int count=0;
|
||||||
uint8_t *attr;
|
uint8_t *attr;
|
||||||
@ -545,6 +543,7 @@ int radsend(struct clientparam * param, int auth, int stop){
|
|||||||
if ((sockfd = so._socket(so.state, SASOCK(&saremote), SOCK_DGRAM, 0)) < 0) {
|
if ((sockfd = so._socket(so.state, SASOCK(&saremote), SOCK_DGRAM, 0)) < 0) {
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
nonblock(sockfd);
|
||||||
remsock = sockfd;
|
remsock = sockfd;
|
||||||
/*
|
/*
|
||||||
}
|
}
|
||||||
@ -557,17 +556,8 @@ int radsend(struct clientparam * param, int auth, int stop){
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(fds, 0, sizeof(fds));
|
data_len = sockrecvfrom(NULL, remsock, (struct sockaddr *)&saremote, (unsigned char *)&rpacket,
|
||||||
fds[0].fd = remsock;
|
sizeof(packet)-16, param->srv->config->timeouts[SINGLEBYTE_L]*1000);
|
||||||
fds[0].events = POLLIN;
|
|
||||||
if(sockpoll(&so, so.state, fds, 1, param->srv->config->timeouts[SINGLEBYTE_L]*1000) <= 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
salen = sizeof(saremote);
|
|
||||||
|
|
||||||
data_len = so._recvfrom(so.state, remsock, (char *)&rpacket, sizeof(packet)-16,
|
|
||||||
0, (struct sockaddr *)&saremote, &salen);
|
|
||||||
|
|
||||||
|
|
||||||
if (data_len < 20) {
|
if (data_len < 20) {
|
||||||
|
|||||||
15
src/ftppr.c
15
src/ftppr.c
@ -138,6 +138,7 @@ void * ftpprchild(struct clientparam* param) {
|
|||||||
if(bindwithrange(param, clidatasock, ¶m->sincl, param->intport)){RETURN(822);}
|
if(bindwithrange(param, clidatasock, ¶m->sincl, param->intport)){RETURN(822);}
|
||||||
if (pasv) {
|
if (pasv) {
|
||||||
if(param->srv->so._listen(param->sostate, clidatasock, 1)) {RETURN(823);}
|
if(param->srv->so._listen(param->sostate, clidatasock, 1)) {RETURN(823);}
|
||||||
|
nonblock(clidatasock);
|
||||||
sasize = sizeof(param->sincl);
|
sasize = sizeof(param->sincl);
|
||||||
if(param->srv->so._getsockname(param->sostate, clidatasock, (struct sockaddr *)¶m->sincl, &sasize)){RETURN(824);}
|
if(param->srv->so._getsockname(param->sostate, clidatasock, (struct sockaddr *)¶m->sincl, &sasize)){RETURN(824);}
|
||||||
if(pasv == 1){
|
if(pasv == 1){
|
||||||
@ -222,12 +223,14 @@ void * ftpprchild(struct clientparam* param) {
|
|||||||
fds.fd = clidatasock;
|
fds.fd = clidatasock;
|
||||||
fds.events = POLLIN;
|
fds.events = POLLIN;
|
||||||
|
|
||||||
res = sockpoll(¶m->srv->so, param->sostate, &fds, 1, param->srv->timeouts[STRING_L]*1000);
|
do {
|
||||||
if(res != 1) {
|
res = sockpoll(¶m->srv->so, param->sostate, &fds, 1, param->srv->timeouts[STRING_L]*1000);
|
||||||
RETURN(857);
|
if(res != 1) {
|
||||||
}
|
RETURN(857);
|
||||||
sasize = sizeof(param->sincr);
|
}
|
||||||
ss = param->srv->so._accept(param->sostate, clidatasock, (struct sockaddr *)¶m->sincr, &sasize);
|
sasize = sizeof(param->sincr);
|
||||||
|
ss = param->srv->so._accept(param->sostate, clidatasock, (struct sockaddr *)¶m->sincr, &sasize);
|
||||||
|
} while (ss == INVALID_SOCKET && acceptagain());
|
||||||
if (ss == INVALID_SOCKET) { RETURN (858);}
|
if (ss == INVALID_SOCKET) { RETURN (858);}
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
{ unsigned long ul = 1; ioctlsocket(ss, FIONBIO, &ul); }
|
{ unsigned long ul = 1; ioctlsocket(ss, FIONBIO, &ul); }
|
||||||
|
|||||||
@ -1189,6 +1189,7 @@ static void httpsrv_linger(struct clientparam *param)
|
|||||||
if(sockpoll(¶m->srv->so, param->sostate, &fd, 1, timeo * 1000) <= 0) break;
|
if(sockpoll(¶m->srv->so, param->sostate, &fd, 1, timeo * 1000) <= 0) break;
|
||||||
got = (int)param->srv->so._recv(param->sostate, param->clisock, buf,
|
got = (int)param->srv->so._recv(param->sostate, param->clisock, buf,
|
||||||
(left > HTTPSRV_BLOCK)? (int)HTTPSRV_BLOCK : (int)left, 0);
|
(left > HTTPSRV_BLOCK)? (int)HTTPSRV_BLOCK : (int)left, 0);
|
||||||
|
if(got < 0 && (errno == EAGAIN || errno == EINTR)) continue;
|
||||||
if(got <= 0) break;
|
if(got <= 0) break;
|
||||||
left -= (uint64_t)got;
|
left -= (uint64_t)got;
|
||||||
}
|
}
|
||||||
|
|||||||
10
src/socks.c
10
src/socks.c
@ -351,17 +351,21 @@ fflush(stderr);
|
|||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
param->srv->so._listen (param->sostate, param->remsock, 1);
|
param->srv->so._listen (param->sostate, param->remsock, 1);
|
||||||
|
nonblock(param->remsock);
|
||||||
|
|
||||||
fds[0].fd = param->remsock;
|
fds[0].fd = param->remsock;
|
||||||
fds[1].fd = param->clisock;
|
fds[1].fd = param->clisock;
|
||||||
fds[0].events = fds[1].events = POLLIN;
|
fds[0].events = fds[1].events = POLLIN;
|
||||||
res = sockpoll(¶m->srv->so, param->sostate, fds, 2, param->srv->timeouts[CONNECTION_L] * 1000);
|
do {
|
||||||
|
res = sockpoll(¶m->srv->so, param->sostate, fds, 2, param->srv->timeouts[CONNECTION_L] * 1000);
|
||||||
|
if (res < 1 || fds[1].revents) break;
|
||||||
|
sasize = sizeof(param->sinsr);
|
||||||
|
s = param->srv->so._accept(param->sostate, param->remsock, (struct sockaddr *)¶m->sinsr, &sasize);
|
||||||
|
} while (s == INVALID_SOCKET && acceptagain());
|
||||||
if (res < 1 || fds[1].revents) {
|
if (res < 1 || fds[1].revents) {
|
||||||
res = 460;
|
res = 460;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sasize = sizeof(param->sinsr);
|
|
||||||
s = param->srv->so._accept(param->sostate, param->remsock, (struct sockaddr *)¶m->sinsr, &sasize);
|
|
||||||
param->srv->so._closesocket(param->sostate, param->remsock);
|
param->srv->so._closesocket(param->sostate, param->remsock);
|
||||||
param->remsock = s;
|
param->remsock = s;
|
||||||
if(s == INVALID_SOCKET) {
|
if(s == INVALID_SOCKET) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user