mirror of
https://github.com/3proxy/3proxy.git
synced 2026-10-16 00:25:48 +08:00
Write to a peer that hung up while it still reads, on Windows
sockmap() took a hang-up on a socket it had data to write to for a peer it could no longer write to. With poll() a hang-up comes once both sides are shut down, so that held. WSAPoll reports one as soon as the peer has half-closed, still reading, and a half-closed client got nothing on Windows: the test added with the previous fix failed there. The write is now tried, and a peer really gone makes it fail, which ends the connection as before. WSAPoll keeps reporting the hang-up whether the socket has room or not, so on Windows room is waited for with select() first unless poll() reported it too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
5d1cdf8e59
commit
9f46558d0b
@ -71,6 +71,28 @@ ssize_t splice(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, size_t le
|
||||
#define CLIROOM ROOM(param->clibufsize, param->cliinbuf)
|
||||
#define SRVROOM ROOM(param->srvbufsize, param->srvinbuf)
|
||||
|
||||
/* A hang-up on a socket there is data to write to. With poll() it comes
|
||||
once both sides are shut down, and the write tried then fails, which ends
|
||||
it. WSAPoll reports it as soon as the peer has half-closed, a peer still
|
||||
reading, and keeps reporting it whether the socket has room or not: room
|
||||
is waited for with select() then, up to timeo seconds. Returns whether to
|
||||
try the write. */
|
||||
static int hupwrite(SOCKET s, short revents, int timeo){
|
||||
#ifdef _WIN32
|
||||
if(!(revents & POLLOUT)){
|
||||
fd_set wfd;
|
||||
struct timeval tv;
|
||||
|
||||
FD_ZERO(&wfd);
|
||||
FD_SET(s, &wfd);
|
||||
tv.tv_sec = timeo;
|
||||
tv.tv_usec = 0;
|
||||
if(select(0, NULL, &wfd, NULL, &tv) < 1) return 0;
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* usesplice is a mask of the directions passed with splice() rather than
|
||||
through a buffer: SPLICE_DOWNLOAD, server to client, and SPLICE_UPLOAD,
|
||||
client to server. */
|
||||
@ -676,7 +698,10 @@ log("ready to write to client");
|
||||
}
|
||||
if(fds[fdsc].revents & (POLLHUP)) {
|
||||
if(fds[fdsc].events & POLLIN) FROMCLIENT = 1;
|
||||
if(fds[fdsc].events & POLLOUT) CLIENTTERMWRITE = 1;
|
||||
if(fds[fdsc].events & POLLOUT){
|
||||
if(hupwrite(param->clisock, fds[fdsc].revents, timeo)) TOCLIENT = 1;
|
||||
else CLIENTTERMWRITE = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if(fds[fdsc].revents & (POLLERR|POLLNVAL)) {
|
||||
@ -741,7 +766,10 @@ log("ready to write to server");
|
||||
log("server terminated connection");
|
||||
#endif
|
||||
if(fds[fdsc].events & POLLIN) FROMSERVER = 1;
|
||||
if(fds[fdsc].events & POLLOUT) SERVERTERMWRITE = 1;
|
||||
if(fds[fdsc].events & POLLOUT){
|
||||
if(hupwrite(param->remsock, fds[fdsc].revents, timeo)) TOSERVER = 1;
|
||||
else SERVERTERMWRITE = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if(fds[fdsc].revents & (POLLERR|POLLNVAL)) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user