nilshenrich / TCP_ServerClient

C++ library providing an asynchronous TCP server and client. Additionally, the TCP connection can be TLS encrypted and two-way authenticated.
MIT License
0 stars 0 forks source link

Pipe error if client stops immediately after exiting start #1

Closed nilshenrich closed 1 year ago

nilshenrich commented 1 year ago

When a client stops immediately after the start() method returned, the server program throws a pipe error.

nilshenrich commented 1 year ago

This issue occurs only for TLS connections.

TCP: Screenshot_FastSend_Tcp

TLS: Screenshot_FastSend_Tls

nilshenrich commented 1 year ago

What makes it pass:

nilshenrich commented 1 year ago

This issue has nothing to do with sending a message.\ The issue comes up if the client is closed immediately after its start()-method returned

nilshenrich commented 1 year ago

The pipe error is thrown 2 times:

  1. On SSL_accept in TlsServer::connectionInit
  2. On SSL_shutdown in TlsServer::connectionDeinit
nilshenrich commented 1 year ago

Possible solution: Non-blocking sockets.\ Answer from ChatGPT:

#include <sys/select.h>
#include <unistd.h>

void ssl_accept_thread(SSL* ssl, int sockfd) {
    // Set the socket to non-blocking mode.
    int flags = fcntl(sockfd, F_GETFL, 0);
    fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);

    // Use select to monitor the socket and ensure that it stays open while SSL_accept is being executed.
    while (true) {
        fd_set readfds;
        FD_ZERO(&readfds);
        FD_SET(sockfd, &readfds);

        int ret = select(sockfd + 1, &readfds, nullptr, nullptr, nullptr);
        if (ret < 0) {
            // An error occurred. You can handle the error here or throw an exception.
            break;
        }

        if (FD_ISSET(sockfd, &readfds)) {
            // The socket is ready to be read from. Execute SSL_accept.
            int ret = SSL_accept(ssl);
            if (ret <= 0) {
                int error = SSL_get_error(ssl, ret);
                if (error == SSL_ERROR_SYSCALL) {
                    // The socket was closed from the outside. You can ignore the error here
                    // or print a message if needed.
                } else if (error == SSL_ERROR_SSL) {
                    // Another error occurred. You can handle the error here or throw an exception.
                }
                break;
            }
        }
    }
}
nilshenrich commented 1 year ago

Non-blocking won't fix this issue. This is caused by already connected sockets closed before initialized. Non-blocking would make no difference

nilshenrich commented 1 year ago

Vorschlag von ChatGPT: MSG_NOSIGNAL setzen

nilshenrich commented 1 year ago

Vorschlag von ChatGPT: MSG_NOSIGNAL setzen

Or set SO_NOSIGPIPE?

nilshenrich commented 1 year ago

Vorschlag von ChatGPT: MSG_NOSIGNAL setzen

Or set SO_NOSIGPIPE?

No, it's Apple only

nilshenrich commented 1 year ago

Not treated as an issue