mirror of https://github.com/wolfSSL/wolfssh.git
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 sessionpull/1258/head
parent
dc03049a13
commit
10d97e151f
|
|
@ -113,12 +113,14 @@
|
||||||
#define SOCKET_ECONNRESET ECONNRESET
|
#define SOCKET_ECONNRESET ECONNRESET
|
||||||
#define SOCKET_ECONNABORTED ECONNABORTED
|
#define SOCKET_ECONNABORTED ECONNABORTED
|
||||||
#define SOCKET_EWOULDBLOCK EWOULDBLOCK
|
#define SOCKET_EWOULDBLOCK EWOULDBLOCK
|
||||||
|
#define SOCKET_EINTR EINTR
|
||||||
#else
|
#else
|
||||||
#include <WS2tcpip.h>
|
#include <WS2tcpip.h>
|
||||||
#define SOCKET_ERRNO WSAGetLastError()
|
#define SOCKET_ERRNO WSAGetLastError()
|
||||||
#define SOCKET_ECONNRESET WSAECONNRESET
|
#define SOCKET_ECONNRESET WSAECONNRESET
|
||||||
#define SOCKET_ECONNABORTED WSAECONNABORTED
|
#define SOCKET_ECONNABORTED WSAECONNABORTED
|
||||||
#define SOCKET_EWOULDBLOCK WSAEWOULDBLOCK
|
#define SOCKET_EWOULDBLOCK WSAEWOULDBLOCK
|
||||||
|
#define SOCKET_EINTR WSAEINTR
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WOLFSSH_WINDOWS_CERT_STORE
|
#ifdef WOLFSSH_WINDOWS_CERT_STORE
|
||||||
|
|
@ -1839,6 +1841,16 @@ static int sftp_worker(thread_ctx_t* threadCtx)
|
||||||
error == WS_WINDOW_FULL)
|
error == WS_WINDOW_FULL)
|
||||||
ret = error;
|
ret = error;
|
||||||
if (error == WS_WANT_WRITE || wolfSSH_SFTP_PendingSend(ssh)) {
|
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
|
continue; /* no need to spend time attempting to pull data
|
||||||
* if there is still pending sends */
|
* if there is still pending sends */
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue