Skip to content

Commit 666fe6e

Browse files
committed
Misc performance improvements and bugfixes
- Fix CI vcpkg - Fix TLS callback issues and allow for CTX or Socket level callbacks - Made Socket virtual to ensure behavior if Tls called from Socket ref - Portable m_domain, m_protocol and m_type inference - Better move correctness - Better closing semantics, especially for TlsSockets - Fixed read performance and correctness - Handles windows error messages + thread safety
1 parent d15697a commit 666fe6e

16 files changed

Lines changed: 401 additions & 233 deletions

File tree

‎.clang-tidy‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Checks: '
66
-fuchsia*,
77
-google-readability-todo,
88
-cppcoreguidelines-init-variables,
9+
-cppcoreguidelines-owning-memory,
910
-cppcoreguidelines-pro-type-reinterpret-cast,
1011
-llvm-namespace-comment,
1112
-readability-implicit-bool-conversion,

‎.github/workflows/cmake-multi-platform.yml‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ on:
1010
jobs:
1111
build:
1212
runs-on: ${{ matrix.os }}
13+
permissions:
14+
contents: read
15+
actions: write
1316

1417
strategy:
1518
# ensure we don't stop after 1 failure to always have a complete picture of what is failing
@@ -127,6 +130,9 @@ jobs:
127130
needs: 'build'
128131
runs-on: ubuntu-latest
129132
if: always() && github.event_name == 'pull_request'
133+
permissions:
134+
contents: read
135+
pull-requests: write
130136

131137
steps:
132138
- name: Checkout Code

‎.github/workflows/code_scanning.yml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ jobs:
6060
security-events: write
6161
steps:
6262
- name: Checkout code
63-
uses: actions/checkout@v3
63+
uses: actions/checkout@v7
6464

6565
- name: flawfinder_scan
6666
uses: david-a-wheeler/flawfinder@2.0.19
@@ -93,7 +93,7 @@ jobs:
9393
- name: VCPKG Install (Windows)
9494
uses: ./.github/workflows/windows-vcpkg
9595
with:
96-
key: ${{ runner.os }}-${{ env.config }}
96+
key: vcpkg-cache-${{ runner.os }}
9797

9898
- name: Configure CMake
9999
run: cmake -B ${{ env.build }} -DCMAKE_BUILD_TYPE=${{ env.config }}

‎.github/workflows/download-cache.yml‎

Lines changed: 0 additions & 22 deletions
This file was deleted.

‎.github/workflows/windows-vcpkg/action.yml‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,19 @@ runs:
1616
1717
- name: Fetch VCPKG Cache (Windows)
1818
id: fetch-vcpkg-cache
19-
if: runner.os == 'Windows'
2019
uses: actions/cache/restore@v6
2120
with:
2221
key: ${{ inputs.key }}-vcpkg-${{ hashFiles('vcpkg.json') }}
2322
path: ${{ env.VCPKG_CACHE }}
2423

2524
- name: VCPKG Install (Windows)
26-
if: runner.os == 'Windows'
2725
shell: powershell
2826
run: |
2927
echo "CMAKE_TOOLCHAIN_FILE=${env:VCPKG_ROOT}\scripts\buildsystems\vcpkg.cmake" | Out-File -FilePath $env:GITHUB_ENV -Append
3028
vcpkg install
3129
3230
- name: Always Save VCPKG Cache (Windows)
33-
if: always() && runner.os == 'Windows' && steps.fetch-vcpkg-cache.outputs.cache-hit != 'true'
31+
if: always() && steps.fetch-vcpkg-cache.outputs.cache-hit != 'true'
3432
uses: actions/cache/save@v6
3533
with:
3634
key: ${{ steps.fetch-vcpkg-cache.outputs.cache-primary-key }}

‎CMakeLists.txt‎

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
## Author Francois Michaut
55
##
66
## Started on Sun Aug 28 19:26:51 2022 Francois Michaut
7-
## Last update Thu Jul 2 01:56:37 2026 Francois Michaut
7+
## Last update Sat Oct 24 23:32:08 2026 Francois Michaut
88
##
99
## CMakeLists.txt : CMake to build the CppSockets library
1010
##
@@ -21,6 +21,7 @@ project(LibCppSockets VERSION 0.1.0 LANGUAGES C CXX)
2121
configure_file(include/CppSockets/Version.hpp.in include/CppSockets/Version.hpp)
2222

2323
add_library(cppsockets
24+
source/Tls/Callbacks.cpp
2425
source/Tls/Certificate.cpp
2526
source/Tls/Context.cpp
2627
source/Tls/Utils.cpp
@@ -40,7 +41,14 @@ target_include_directories(cppsockets
4041
${PROJECT_SOURCE_DIR}/private
4142
)
4243

43-
target_compile_definitions(cppsockets PRIVATE CPPSOCKETS_DLL_EXPORTS=1)
44+
if(WIN32)
45+
target_compile_definitions(cppsockets PRIVATE CPPSOCKETS_DLL_EXPORTS=1)
46+
endif()
47+
48+
target_compile_options(cppsockets PRIVATE
49+
$<$<OR:$<CXX_COMPILER_ID:GNU>,$<CXX_COMPILER_ID:Clang>>:-Wall -Wextra>
50+
$<$<CXX_COMPILER_ID:MSVC>:/W4>
51+
)
4452

4553
find_package(OpenSSL 3.0 COMPONENTS SSL)
4654
target_link_libraries(cppsockets OpenSSL::SSL)

‎include/CppSockets/Socket.hpp‎

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
** Author Francois Michaut
55
**
66
** Started on Sat Jan 15 01:17:42 2022 Francois Michaut
7-
** Last update Wed Jul 1 14:20:12 2026 Francois Michaut
7+
** Last update Sun Oct 25 11:38:13 2026 Francois Michaut
88
**
99
** Socket.hpp : Portable C++ socket class
1010
*/
@@ -37,26 +37,27 @@ namespace CppSockets {
3737
Socket();
3838
Socket(int domain, int type, int protocol);
3939
Socket(RawSocketType fd, bool connected);
40-
~Socket();
40+
virtual ~Socket();
4141

4242
// TODO Maybe enable copy with dup(2) ?
4343
Socket(const Socket &other) = delete;
4444
Socket(Socket &&other) noexcept;
4545
auto operator=(const Socket &other) -> Socket & = delete;
4646
auto operator=(Socket &&other) noexcept -> Socket &;
4747

48-
auto read(std::size_t len = -1) -> std::string;
49-
auto read(char *buff, std::size_t size) -> std::size_t;
50-
auto write(const std::string &buff) -> std::size_t;
51-
auto write(const char *buff, std::size_t len) -> std::size_t;
48+
virtual void close();
49+
50+
virtual auto read(std::size_t len = -1) -> std::string;
51+
virtual auto read(char *buff, std::size_t size) -> std::size_t;
52+
virtual auto write(std::string_view buff) -> std::size_t;
53+
virtual auto write(const char *buff, std::size_t len) -> std::size_t;
5254

5355
auto set_reuseaddr(bool value) -> int;
5456
auto getsockopt(int level, int optname, SockOptType *optval, socklen_t *optlen) -> int;
5557
auto setsockopt(int level, int optname, const SockOptType *optval, socklen_t optlen) -> int;
5658

57-
void close();
58-
auto connect(const IEndpoint &endpoint) -> int;
59-
auto connect(const std::string &addr, uint16_t port) -> int;
59+
virtual auto connect(const IEndpoint &endpoint) -> int;
60+
virtual auto connect(const std::string &addr, uint16_t port) -> int;
6061

6162
auto bind(const IEndpoint &endpoint) -> int;
6263
auto bind(const std::string &addr, uint16_t port) -> int;
@@ -74,15 +75,23 @@ namespace CppSockets {
7475
[[nodiscard]] auto connected() const -> bool { return m_is_connected; }
7576

7677
static auto get_errno() -> int;
77-
static auto strerror(int err) -> char *;
78-
static auto strerror() -> char *;
78+
static auto strerror(int err) -> std::string;
79+
static auto strerror() -> std::string;
7980

8081
protected:
82+
static void throw_errno_error(std::string message);
83+
static void throw_errno_error(std::string message, int err);
84+
8185
static auto getsockopt(int fd, int level, int optname, SockOptType *optval, socklen_t *optlen) -> int;
86+
static auto getsockopt(int fd, int level, int optname, SockOptType *optval, socklen_t optlen) -> int { return Socket::getsockopt(fd, level, optname, optval, &optlen); }
87+
8288
auto bind(std::uint32_t addr, uint16_t port) -> int;
8389

8490
void set_connected(bool status) { m_is_connected = status; };
8591

92+
void create_socket();
93+
94+
virtual auto acceptImpl(void *addr_out) -> Socket *;
8695
private:
8796
int m_domain = 0;
8897
int m_type = 0;

‎include/CppSockets/Tls/Context.hpp‎

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
** Author Francois Michaut
55
**
66
** Started on Wed Aug 20 14:13:44 2025 Francois Michaut
7-
** Last update Tue Jun 30 08:19:16 2026 Francois Michaut
7+
** Last update Thu Oct 22 23:23:49 2026 Francois Michaut
88
**
99
** Context.hpp : Context for TLS sockets
1010
*/
@@ -22,7 +22,7 @@ namespace CppSockets {
2222
TlsContext(SSL_CTX_ptr ptr);
2323
TlsContext(SSL_CTX *ptr, bool own = true);
2424

25-
TlsContext(const TlsContext &other) { *this = other; }
25+
TlsContext(const TlsContext &other);
2626
TlsContext(TlsContext &&other) noexcept;
2727
auto operator=(const TlsContext &other) -> TlsContext &;
2828
auto operator=(TlsContext &&other) noexcept -> TlsContext &;
@@ -41,8 +41,5 @@ namespace CppSockets {
4141
private:
4242
SSL_CTX_ptr m_ptr;
4343
bool m_own = true;
44-
TlsVerifyCallback m_verify_callback;
45-
46-
friend struct TlsContext_Accessor;
4744
};
4845
}

‎include/CppSockets/Tls/Socket.hpp‎

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
** Author Francois Michaut
55
**
66
** Started on Wed Sep 14 20:51:23 2022 Francois Michaut
7-
** Last update Fri Aug 22 21:55:50 2025 Francois Michaut
7+
** Last update Sun Oct 25 12:00:59 2026 Francois Michaut
88
**
99
** SecureSocket.hpp : TLS socket wrapper using openssl
1010
*/
@@ -20,30 +20,31 @@ namespace CppSockets {
2020
// TODO add more TLS-related functions
2121
class TlsSocket : public Socket {
2222
public:
23-
TlsSocket() = default;
24-
// TODO: Constructor allowing application to reuse SSL_CTX objects
25-
// (Maybe even a different TLS_CTX class to manage them ?)
23+
TlsSocket() = default; // TODO: Null-init m_ssl, would segfault on any function call. Find a safer way.
2624
TlsSocket(int domain, int type, int protocol, TlsContext ctx = {});
2725
explicit TlsSocket(Socket &&other, TlsContext ctx = {});
2826
explicit TlsSocket(Socket &&other, SSL_ptr ssl = nullptr);
2927
explicit TlsSocket(RawSocketType fd, SSL_ptr ssl = nullptr);
30-
~TlsSocket() noexcept;
28+
~TlsSocket() noexcept override;
3129

3230
TlsSocket(const TlsSocket &other) = delete;
3331
TlsSocket(TlsSocket &&other) noexcept;
3432
auto operator=(const TlsSocket &other) -> TlsSocket & = delete;
3533
auto operator=(TlsSocket &&other) noexcept -> TlsSocket &;
3634

37-
void close();
35+
void close() override { this->close(false); };
36+
bool close(bool force);
3837

39-
auto read(std::size_t len = -1) -> std::string;
40-
auto read(char *buff, std::size_t size) -> std::size_t;
41-
auto write(std::string_view buff) -> std::size_t { return this->write(buff.data(), buff.size()); };
42-
auto write(const char *buff, std::size_t len) -> std::size_t;
38+
// read() with no length reads until the peer closes; use read(N) when reading from untrusted peers
39+
auto read(std::size_t len = -1) -> std::string override;
40+
auto read(char *buff, std::size_t size) -> std::size_t override;
41+
auto write(std::string_view buff) -> std::size_t override { return this->write(buff.data(), buff.size()); };
42+
auto write(const char *buff, std::size_t len) -> std::size_t override;
4343

44-
void set_verify(int mode, SSL_verify_cb verify_callback = nullptr);
44+
void set_verify(int mode, TlsVerifyCallback verify_callback = nullptr);
45+
void set_verify_depth(int depth);
4546
void set_certificate(const std::string &cert_path, const std::string &pkey_path);
46-
auto connect(const IEndpoint &endpoint) -> int;
47+
auto connect(const IEndpoint &endpoint) -> int override;
4748

4849
auto accept(void *addr_out, TlsContext ctx) -> std::unique_ptr<TlsSocket>;
4950
auto accept(void *addr_out = nullptr) -> std::unique_ptr<TlsSocket> { return accept(addr_out, m_ctx); }
@@ -54,11 +55,18 @@ namespace CppSockets {
5455
[[nodiscard]] auto get_peer_cert() const -> const X509_ptr & { return m_peer_cert; }
5556

5657
[[nodiscard]] auto tls_strerror(int ret) -> std::string;
58+
protected:
59+
auto acceptImpl(void *addr_out) -> TlsSocket * override { return acceptImpl(addr_out, m_ctx); };
60+
auto acceptImpl(void *addr_out, TlsContext ctx) -> TlsSocket *;
61+
62+
void throw_tls_error(std::string message);
63+
void throw_tls_error(std::string message, int ret);
5764
private:
5865
TlsContext m_ctx;
5966
SSL_ptr m_ssl;
6067
X509_ptr m_peer_cert;
6168

62-
void check_for_error(const std::string &error_msg, int ret);
69+
bool m_should_shutdown = false;
70+
void check_for_error(std::string error_msg, int ret);
6371
};
6472
}

‎private/CppSockets/SslMacros.hpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
** Author Francois Michaut
55
**
66
** Started on Wed Aug 20 16:54:02 2025 Francois Michaut
7-
** Last update Thu Jul 2 03:01:00 2026 Francois Michaut
7+
** Last update Thu Oct 22 22:48:57 2026 Francois Michaut
88
**
99
** SslMacros.hpp : Private Macros to define SSL wrappers
1010
*/

0 commit comments

Comments
 (0)