doWrite()'s retry/buffer state was held in function-local static
variables, shared across every SecureSocket instance in the process
rather than per connection. Move it to instance members, and simplify
secureRead()/secureWrite()'s retry counters (also static, but not
load-bearing across calls) to plain locals.
pollSocket() caches a socket's writability and skips waiting once it's
known writable, relying on writeSocket() to clear the cache on
WSAEWOULDBLOCK. SecureSocket writes via SSL_write(), bypassing
writeSocket() entirely, so the cache never clears and the multiplexer
spins at a zero timeout instead of blocking whenever TLS hits
backpressure.
Add IArchNetwork::resetPollWriteOnSocket() and call it from
checkResult()'s SSL_ERROR_WANT_WRITE case, mirroring writeSocket()'s
existing WSAEWOULDBLOCK handling.
It will fix the following warning:
In member function 'int SecureSocket::secureConnect(int)':
/build/deskflow.work/src/lib/net/SecureSocket.cpp:479:16: warning: 'int SSL_set1_host(SSL*, const char*)' is deprecated: Since OpenSSL 4.0 [
-Wdeprecated-declarations]
479 | SSL_set1_host(m_ssl->m_ssl, name.c_str());
| ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /build/deskflow.work/src/lib/net/SslLogger.h:8,
from /build/deskflow.work/src/lib/net/SecureSocket.cpp:20:
/usr/include/openssl/ssl.h:1922:34: note: declared here
1922 | OSSL_DEPRECATEDIN_4_0 __owur int SSL_set1_host(SSL *s, const char *host);
| ^~~~~~~~~~~~~
NOTE: It seems that SSL_set1_host setup params for hostname verification, but
it will not be used correctly afterward (See
SSL_CTX_set_cert_verify_callback
in SecureSocket::initContext). This implicit behavior cause misleading
and harmful.
Signed-off-by: Kentaro Hayashi <kenhys@xdump.org>
Since OpenSSL 4.0.0, X509_get_subject_name returns const X509_NAME
pointer, thus X509_NAME_add_entry_by_txt does not accept it anymore.
See /usr/include/openssl/x509.h.
Instead, explicitly operates it via mutable X509_NAME object.
It is safe operation without using X509_get_subject_name() because
subject name was not modified after cert = X509_new() assignment.
It will fix the following error.
error: invalid conversion from 'const X509_name_st*' to 'X509_NAME*' {aka 'X509_name
_st*'} [-fpermissive]
87 | X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, reinterpret_cast<const unsigned char *>("Deskflow"), -1, -1, 0);
| ^~~~
| |
| const X509_name_st*
Signed-off-by: Kentaro Hayashi <kenhys@xdump.org>
This fix addresses a busy-loop and stalled connection issue during the TLS
handshake. Previously, SecureSocket incorrectly managed its readiness flags
during negotiation, often polling for 'writability' when OpenSSL was actually
waiting for more 'read' data (or vice versa).
- Explicitly maps SSL_ERROR_WANT_READ and SSL_ERROR_WANT_WRITE to
socket multiplexer events.
- Resets readiness flags before each handshake attempt to ensure the
multiplexer receives the most accurate requirements from OpenSSL.
- Restores readability/writability flags upon a successful handshake
to allow subsequent application-layer protocol exchange.
- Removes inefficient busy-wait sleeps that were masking the loop
and slowing down handshakes.
Deskflow previously lacked support for TCP keepalive, which meant that
dead connections (such as those resulting from a terminated SSH tunnel
or an ungraceful network interruption) could remain in the system's
connection table indefinitely.
This commit adds the setKeepAliveOnSocket method to the IArchNetwork
abstraction and implements it for both BSD/Unix and Winsock/Windows
backends. Keepalive is now enabled by default in TCPSocket::init,
allowing the operating system to eventually detect and clean up
stale connections.