mirror of
https://github.com/3proxy/3proxy.git
synced 2026-10-24 12:05:47 +08:00
sockrecvfrom: poll again when a readable socket has nothing to read
Some checks are pending
C/C++ CI Linux / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Waiting to run
C/C++ CI Linux / ${{ matrix.target }} (ubuntu-latest) (push) Waiting to run
C/C++ CI MacOS / ${{ matrix.target }} (macos-15) (push) Waiting to run
C/C++ CI Windows / ${{ matrix.target }} (windows-2022) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (macos-15) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (ubuntu-latest) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (windows-2022) (push) Waiting to run
C/C++ CI cmake / ubuntu-latest (wolfSSL) (push) Waiting to run
Some checks are pending
C/C++ CI Linux / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Waiting to run
C/C++ CI Linux / ${{ matrix.target }} (ubuntu-latest) (push) Waiting to run
C/C++ CI MacOS / ${{ matrix.target }} (macos-15) (push) Waiting to run
C/C++ CI Windows / ${{ matrix.target }} (windows-2022) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (macos-15) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (ubuntu-latest) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (windows-2022) (push) Waiting to run
C/C++ CI cmake / ubuntu-latest (wolfSSL) (push) Waiting to run
sockrecvfrom() polled once and then read in a loop for as long as the read failed with EAGAIN. Over TLS a socket is readable when only a part of a record has come, and the read fails with EAGAIN until the rest does: a client sending half a record and then nothing kept a thread taking all of a CPU, and the read never timed out. On EAGAIN the socket is now polled again, the read repeated at once only for EINTR. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
94a83d126f
commit
99795d8dfe
@ -60,15 +60,21 @@ int sockrecvfrom(struct clientparam *param, SOCKET sock, struct sockaddr * sin,
|
||||
|
||||
fds.fd = sock;
|
||||
fds.events = POLLIN;
|
||||
if(conf.timetoexit) return EOF;
|
||||
res = param?param->srv->so._poll(param->sostate, &fds, 1, to):so._poll(so.state, &fds, 1, to);
|
||||
if (res<1) return 0;
|
||||
sasize = sizeof(PROXYSOCKADDRTYPE);
|
||||
/* sin NULL for a stream socket: nothing to learn the address into */
|
||||
do {
|
||||
res = param?param->srv->so._recvfrom(param->sostate, sock, (char *)buf, bufsize, 0, (struct sockaddr *)sin, sin? &sasize : NULL):so._recvfrom(so.state, sock, (char *)buf, bufsize, 0, (struct sockaddr *)sin, sin? &sasize : NULL);
|
||||
} while (res < 0 && (errno == EAGAIN || errno == EINTR));
|
||||
return res;
|
||||
for(;;){
|
||||
if(conf.timetoexit) return EOF;
|
||||
res = param?param->srv->so._poll(param->sostate, &fds, 1, to):so._poll(so.state, &fds, 1, to);
|
||||
if (res<1) return 0;
|
||||
sasize = sizeof(PROXYSOCKADDRTYPE);
|
||||
/* sin NULL for a stream socket: nothing to learn the address into */
|
||||
do {
|
||||
res = param?param->srv->so._recvfrom(param->sostate, sock, (char *)buf, bufsize, 0, (struct sockaddr *)sin, sin? &sasize : NULL):so._recvfrom(so.state, sock, (char *)buf, bufsize, 0, (struct sockaddr *)sin, sin? &sasize : NULL);
|
||||
} while (res < 0 && errno == EINTR);
|
||||
/* readable and still nothing to read: over TLS a record not yet
|
||||
whole. Read again, without polling, it would only be the same until
|
||||
the rest came, a loop taking all of a CPU and never timing out: the
|
||||
socket is polled for it instead. */
|
||||
if(res >= 0 || errno != EAGAIN) return res;
|
||||
}
|
||||
}
|
||||
|
||||
int sockgetcharcli(struct clientparam * param, int timeosec, int timeousec){
|
||||
|
||||
Loading…
Reference in New Issue
Block a user