From f3c86d2a8effecf62d20a6f8c260c565132a4fec Mon Sep 17 00:00:00 2001 From: Bryan Biedenkapp Date: Sun, 26 Jan 2025 21:42:04 -0500 Subject: [PATCH] support configuring SSL TCP sockets for non-blocking operations; --- src/common/network/tcp/SecureTcpClient.h | 40 ++++++++++++++++------ src/common/network/tcp/SecureTcpListener.h | 7 ++-- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/src/common/network/tcp/SecureTcpClient.h b/src/common/network/tcp/SecureTcpClient.h index 8c7c5a14..40e5938c 100644 --- a/src/common/network/tcp/SecureTcpClient.h +++ b/src/common/network/tcp/SecureTcpClient.h @@ -4,7 +4,7 @@ * GPLv2 Open Source. Use is subject to license terms. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright (C) 2024 Bryan Biedenkapp, N2PLL + * Copyright (C) 2024-2025 Bryan Biedenkapp, N2PLL * */ /** @@ -56,8 +56,9 @@ namespace network * @param sslCtx Instance of the OpenSSL context. * @param client Address for client. * @param clientLen Length of sockaddr_in structure. + * @param nonBlocking Flag indicating socket operations should be non-blocking. */ - SecureTcpClient(const int fd, SSL_CTX* sslCtx, sockaddr_in& client, int clientLen) : Socket(fd), + SecureTcpClient(const int fd, SSL_CTX* sslCtx, sockaddr_in& client, int clientLen, bool nonBlocking) : Socket(fd), m_sockaddr(), m_pSSL(nullptr), m_pSSLCtx(nullptr) @@ -135,23 +136,26 @@ namespace network } while (status == 1 && !SSL_is_init_finished(m_pSSL)); // reset socket blocking operations - flags = fcntl(fd, F_GETFL, 0); - if (flags < 0) { - LogError(LOG_NET, "failed fcntl(F_GETFL), err: %d", errno); - throw std::runtime_error("Cannot accept SSL client"); - } + if (!nonBlocking) { + flags = fcntl(fd, F_GETFL, 0); + if (flags < 0) { + LogError(LOG_NET, "failed fcntl(F_GETFL), err: %d", errno); + throw std::runtime_error("Cannot accept SSL client"); + } - if (fcntl(fd, F_SETFL, flags & (~O_NONBLOCK)) < 0) { - LogError(LOG_NET, "failed fcntl(F_SETFL), err: %d", errno); - throw std::runtime_error("Cannot accept SSL client"); + if (fcntl(fd, F_SETFL, flags & (~O_NONBLOCK)) < 0) { + LogError(LOG_NET, "failed fcntl(F_SETFL), err: %d", errno); + throw std::runtime_error("Cannot accept SSL client"); + } } } /** * @brief Initializes a new instance of the SecureTcpClient class. * @param address IP Address. * @param port Port. + * @param nonBlocking Flag indicating socket operations should be non-blocking. */ - SecureTcpClient(const std::string& address, const uint16_t port) : + SecureTcpClient(const std::string& address, const uint16_t port, bool nonBlocking) : m_pSSL(nullptr), m_pSSLCtx(nullptr) { @@ -180,6 +184,20 @@ namespace network LogError(LOG_NET, "Failed to connect to server, %s err: %d", ERR_error_string(ERR_get_error(), NULL), errno); throw std::runtime_error("Failed to SSL connect to server"); } + + // setup socket for non-blocking operations + if (nonBlocking) { + int flags = fcntl(m_fd, F_GETFL, 0); + if (flags < 0) { + LogError(LOG_NET, "failed fcntl(F_GETFL), err: %d", errno); + throw std::runtime_error("Failed to set SSL server connection to non-blocking"); + } + + if (fcntl(m_fd, F_SETFL, flags | O_NONBLOCK) < 0) { + LogError(LOG_NET, "failed fcntl(F_SETFL), err: %d", errno); + throw std::runtime_error("Failed to set SSL server connection to non-blocking"); + } + } } /** * @brief Finalizes a instance of the SecureTcpClient class. diff --git a/src/common/network/tcp/SecureTcpListener.h b/src/common/network/tcp/SecureTcpListener.h index c1fc14c9..a94a7833 100644 --- a/src/common/network/tcp/SecureTcpListener.h +++ b/src/common/network/tcp/SecureTcpListener.h @@ -7,7 +7,7 @@ * @package DVM / Common Library * @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) * -* Copyright (C) 2024 Bryan Biedenkapp, N2PLL +* Copyright (C) 2024-2025 Bryan Biedenkapp, N2PLL * */ /** @@ -109,9 +109,10 @@ namespace network /** * @brief Accept a new TCP connection either secure or unsecure. + * @param nonBlocking Flag indicating accepted TCP connections should use non-blocking sockets. * @returns SecureTcpClient* Newly accepted TCP connection. */ - [[nodiscard]] SecureTcpClient* accept() + [[nodiscard]] SecureTcpClient* accept(bool nonBlocking = false) { sockaddr_in client = {}; socklen_t clientLen = sizeof(client); @@ -120,7 +121,7 @@ namespace network return nullptr; } - return new SecureTcpClient(fd, m_pSSLCtx, client, clientLen); + return new SecureTcpClient(fd, m_pSSLCtx, client, clientLen, nonBlocking); } private: