diff --git a/src/lib/arch/IArchNetwork.h b/src/lib/arch/IArchNetwork.h index 5f8c7e833..d533b37e0 100644 --- a/src/lib/arch/IArchNetwork.h +++ b/src/lib/arch/IArchNetwork.h @@ -211,6 +211,16 @@ public: */ virtual size_t writeSocket(ArchSocket s, const void *buf, size_t len) = 0; + //! Reset the writable poll hint for a socket + /*! + Tells pollSocket() to wait for a fresh writable notification instead of + assuming the socket is still writable. Needed by callers that write to a + socket without going through writeSocket(), e.g. OpenSSL's SSL_write(). + */ + virtual void resetPollWriteOnSocket(ArchSocket) + { + } + //! Check error on socket /*! If the socket \c s is in an error state then throws an appropriate diff --git a/src/lib/arch/win32/ArchNetworkWinsock.cpp b/src/lib/arch/win32/ArchNetworkWinsock.cpp index f5b7ac183..eb6e1898f 100644 --- a/src/lib/arch/win32/ArchNetworkWinsock.cpp +++ b/src/lib/arch/win32/ArchNetworkWinsock.cpp @@ -1,5 +1,6 @@ /* * Deskflow -- mouse and keyboard sharing utility + * SPDX-FileCopyrightText: (C) 2026 Deskflow Developers * SPDX-FileCopyrightText: (C) 2012 - 2016 Synergy App Ltd * SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception @@ -557,6 +558,12 @@ size_t ArchNetworkWinsock::writeSocket(ArchSocket s, const void *buf, size_t len return static_cast(n); } +void ArchNetworkWinsock::resetPollWriteOnSocket(ArchSocket s) +{ + assert(s != nullptr); + s->m_pollWrite = true; +} + void ArchNetworkWinsock::throwErrorOnSocket(ArchSocket s) { assert(s != nullptr); diff --git a/src/lib/arch/win32/ArchNetworkWinsock.h b/src/lib/arch/win32/ArchNetworkWinsock.h index b997a01de..29054e9db 100644 --- a/src/lib/arch/win32/ArchNetworkWinsock.h +++ b/src/lib/arch/win32/ArchNetworkWinsock.h @@ -1,5 +1,6 @@ /* * Deskflow -- mouse and keyboard sharing utility + * SPDX-FileCopyrightText: (C) 2026 Deskflow Developers * SPDX-FileCopyrightText: (C) 2012 - 2016 Synergy App Ltd * SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception @@ -71,6 +72,7 @@ public: void unblockPollSocket(ArchThread thread) override; size_t readSocket(ArchSocket s, void *buf, size_t len) override; size_t writeSocket(ArchSocket s, const void *buf, size_t len) override; + void resetPollWriteOnSocket(ArchSocket s) override; void throwErrorOnSocket(ArchSocket) override; bool setNoDelayOnSocket(ArchSocket, bool noDelay) override; void setKeepAliveOnSocket(ArchSocket, bool keepAlive) override; diff --git a/src/lib/net/SecureSocket.cpp b/src/lib/net/SecureSocket.cpp index c1069e691..b32b60533 100644 --- a/src/lib/net/SecureSocket.cpp +++ b/src/lib/net/SecureSocket.cpp @@ -556,8 +556,8 @@ void SecureSocket::checkResult(int status, int &retry) break; case SSL_ERROR_WANT_WRITE: - // Need to make sure the socket is known to be writable so the impending - // poll action actually triggers on a write. + // SSL_write() bypasses writeSocket(), so reset the poll hint ourselves. + ARCH->resetPollWriteOnSocket(getSocket()); setWritable(true); retry++; LOG_VERBOSE("want to write, error=%d, attempt=%d", errorCode, retry);