echoserver: wait to write in the SFTP loop

A send the socket refused leaves WS_WANT_WRITE, and the retry branch
continues past the only tcp_select() in the iteration, which watches
reads. Wait on write readiness there, so a peer that has stopped
reading costs a descriptor wait rather than a spin.

- a buffered send with a willing socket still goes straight around
- an error-ready or failed descriptor ends the loop
- an interrupted select() retries instead of ending the session
pull/1258/head
John Safranek 2026-09-14 11:33:34 -07:00 committed by Paul Adelsbach
parent dc03049a13
commit 10d97e151f
1 changed files with 12 additions and 0 deletions

View File

@ -113,12 +113,14 @@
#define SOCKET_ECONNRESET ECONNRESET
#define SOCKET_ECONNABORTED ECONNABORTED
#define SOCKET_EWOULDBLOCK EWOULDBLOCK
#define SOCKET_EINTR EINTR
#else
#include <WS2tcpip.h>
#define SOCKET_ERRNO WSAGetLastError()
#define SOCKET_ECONNRESET WSAECONNRESET
#define SOCKET_ECONNABORTED WSAECONNABORTED
#define SOCKET_EWOULDBLOCK WSAEWOULDBLOCK
#define SOCKET_EINTR WSAEINTR
#endif
#ifdef WOLFSSH_WINDOWS_CERT_STORE
@ -1839,6 +1841,16 @@ static int sftp_worker(thread_ctx_t* threadCtx)
error == WS_WINDOW_FULL)
ret = error;
if (error == WS_WANT_WRITE || wolfSSH_SFTP_PendingSend(ssh)) {
/* The tcp_select() this skips watches reads only. */
if (error == WS_WANT_WRITE) {
selected = tcp_select_write(s, TEST_SFTP_TIMEOUT);
/* An interrupted select() is not a dead socket. */
if (selected == WS_SELECT_ERROR_READY
|| (selected == WS_SELECT_FAIL
&& SOCKET_ERRNO != SOCKET_EINTR)) {
break;
}
}
continue; /* no need to spend time attempting to pull data
* if there is still pending sends */
}