Compile the crypto, config, DNS, ACL and plugin modules as C++

Rename netutils, jconf, stream, aead, aead2022, aead2022_udp, crypto,
acl, plugin, plugin_disabled and resolv from .c to .cpp without changing
their contents, and update source lists, snippet references, test
comments and debian/copyright.

The Doxygen source list and scripts/check_cli_docs.py now accept either
extension for each module, so the remaining programs can move one at a
time. The new .cpp files are added to the no-heap ratchet baseline.
This commit is contained in:
Max Lv
2026-10-14 22:51:16 +08:00
parent 3ae698f5be
commit 349d895fd2
24 changed files with 69 additions and 48 deletions
+9 -9
View File
@@ -103,23 +103,23 @@ A library `libshadowsocks-c` (legacy names `libshadowsocks-libev.*` are kept) is
**Shared by all binaries:**
- `utils.c` - logging, system utilities, `ss_malloc`/`ss_free`
- `jconf.c` / `json.cpp` - JSON config file parsing
- `netutils.c` - network address utilities
- `jconf.cpp` / `json.cpp` - JSON config file parsing
- `netutils.cpp` - network address utilities
- `cache.cpp` - uthash-based connection cache (UDP relay, AEAD-2022 tables)
- `udprelay.c` - UDP relay implementation (shared, but uses `#ifdef MODULE_*` for per-binary behavior)
- `ss_event.c` / `ss_event.h` - event loop API over libuv
- `resolv.c` - asynchronous DNS via c-ares
- `resolv.cpp` - asynchronous DNS via c-ares
**Crypto layer** (behind a common `crypto_t` function-pointer interface):
- `crypto.c` / `crypto.h` - crypto initialization, key derivation (HKDF), `buffer_t` management
- `stream.c` - legacy stream ciphers
- `aead.c` - AEAD ciphers (AES-GCM via Mbed TLS/libsodium, ChaCha20-Poly1305 via libsodium)
- `aead2022.c` / `aead2022_udp.c` - Shadowsocks 2022 (SIP022), BLAKE3 from `src/blake3`
- `crypto.cpp` / `crypto.h` - crypto initialization, key derivation (HKDF), `buffer_t` management
- `stream.cpp` - legacy stream ciphers
- `aead.cpp` - AEAD ciphers (AES-GCM via Mbed TLS/libsodium, ChaCha20-Poly1305 via libsodium)
- `aead2022.cpp` / `aead2022_udp.cpp` - Shadowsocks 2022 (SIP022), BLAKE3 from `src/blake3`
- `ppbloom.cpp` - ping-pong bloom filter for salt replay detection (`third_party/bloom`)
**ACL:** `acl.c` / `rule.cpp` / `ipset.cpp` - IP prefix sets and PCRE2/literal domain rules.
**ACL:** `acl.cpp` / `rule.cpp` / `ipset.cpp` - IP prefix sets and PCRE2/literal domain rules.
**Plugins:** `plugin.c` / `process.cpp` - SIP003 plugin subprocess management.
**Plugins:** `plugin.cpp` / `process.cpp` - SIP003 plugin subprocess management.
**C++ core:** `src/core/*.hpp` - header-only ownership and allocation primitives (pools, handles, fixed
buffers, arena, fixed hash map/LRU, intrusive list, bounded heap). See `docs/cpp-core.md`.
+1 -1
View File
@@ -49,7 +49,7 @@ Files: src/json.cpp src/json.h
Copyright: 2012-2014, James McLaughlin et al.
License: BSD-2-clause
Files: src/resolv.c src/resolv.h
Files: src/resolv.cpp src/resolv.h
Copyright: 2011-2014, Dustin Lundquist <dustin@null-ptr.net>
License: BSD-2-clause
+6 -1
View File
@@ -16,7 +16,12 @@ foreach(name IN LISTS DOC_NAMES)
endforeach()
set(DOC_SOURCES)
foreach(name local server tunnel redir manager utils aead stream)
list(APPEND DOC_SOURCES "${PROJECT_SOURCE_DIR}/src/${name}.c")
# Modules are moving from C to C++ one at a time.
if(EXISTS "${PROJECT_SOURCE_DIR}/src/${name}.cpp")
list(APPEND DOC_SOURCES "${PROJECT_SOURCE_DIR}/src/${name}.cpp")
else()
list(APPEND DOC_SOURCES "${PROJECT_SOURCE_DIR}/src/${name}.c")
endif()
endforeach()
list(APPEND DOC_SOURCES "${PROJECT_SOURCE_DIR}/src/ss-nat")
+10 -2
View File
@@ -98,13 +98,21 @@ def documented_options(source_name, sources):
return result
def module_source(sources, module):
"""Source file name for a program module; modules move from .c to .cpp."""
for suffix in ('.c', '.cpp'):
if module + suffix in sources:
return module + suffix
raise ValueError(f"No source file for module {module}")
def check(root=ROOT, rendered=None):
sources = {path.name: path.read_text(encoding='utf-8')
for path in (root / 'src').glob('*.c')}
for pattern in ('*.c', '*.cpp') for path in (root / 'src').glob(pattern)}
sources['ss-nat'] = (root / 'src/ss-nat').read_text(encoding='utf-8')
for module in PROGRAMS:
program = 'ss-' + module
filename = 'ss-nat' if module == 'nat' else module + '.c'
filename = 'ss-nat' if module == 'nat' else module_source(sources, module)
declared = options(sources[filename], shell=module == 'nat')
documented = documented_options(filename, sources)
missing = declared.keys() - documented.keys()
+8
View File
@@ -2,9 +2,17 @@
# Format: <path> <violations>. check_no_heap.py fails if a file gains
# violations, and also when it loses some, so the number here always goes
# down. Remove a file once it is rewritten on the src/core primitives.
src/aead.cpp 4
src/aead2022.cpp 3
src/aead2022_udp.cpp 5
src/cache.cpp 3
src/crypto.cpp 4
src/ipset.cpp 3
src/jconf.cpp 16
src/json.cpp 2
src/plugin.cpp 3
src/process.cpp 26
src/resolv.cpp 6
src/rule.cpp 2
src/ssurl.cpp 3
src/stream.cpp 3
+1 -1
View File
@@ -14,7 +14,7 @@ readonly CONFIG_DIR="/etc/shadowsocks-libev"
readonly SYSTEMD_UNIT_DIR="/etc/systemd/system"
readonly SYSTEMD_TEMPLATE="shadowsocks-libev-server@.service"
# AEAD ciphers supported by shadowsocks-libev (from src/aead.c)
# AEAD ciphers supported by shadowsocks-libev (from src/aead.cpp)
readonly AEAD_CIPHERS=(
"chacha20-ietf-poly1305"
"aes-256-gcm"
+12 -12
View File
@@ -9,16 +9,16 @@ endif ()
set(SS_ACL_SOURCE
acl.c
acl.cpp
ipset.cpp
rule.cpp
)
set(SS_CRYPTO_SOURCE
crypto.c
aead.c
aead2022.c
aead2022_udp.c
crypto.cpp
aead.cpp
aead2022.cpp
aead2022_udp.cpp
base64.cpp
)
@@ -40,20 +40,20 @@ target_compile_options(blake3 PRIVATE -Wno-error -Wno-unused-function)
set_target_properties(blake3 PROPERTIES POSITION_INDEPENDENT_CODE ON)
if(SS_ENABLE_LEGACY)
list(APPEND SS_CRYPTO_SOURCE stream.c)
list(APPEND SS_CRYPTO_SOURCE stream.cpp)
endif()
if(SS_ENABLE_PLUGINS)
set(SS_PLUGIN_SOURCE plugin.c process.cpp)
set(SS_PLUGIN_SOURCE plugin.cpp process.cpp)
else()
set(SS_PLUGIN_SOURCE plugin_disabled.c)
set(SS_PLUGIN_SOURCE plugin_disabled.cpp)
endif()
set(SS_SHARED_SOURCES
ppbloom.cpp
utils.c
jconf.c
jconf.cpp
json.cpp
netutils.c
netutils.cpp
)
if (MINGW)
set(SS_SHARED_SOURCES ${SS_SHARED_SOURCES} winsock.c)
@@ -64,7 +64,7 @@ set(LIBSHADOWSOCKS_LIBEV_SOURCE
udprelay.c
cache.cpp
local.c
resolv.c
resolv.cpp
ssurl.cpp
${SS_CRYPTO_SOURCE}
${SS_PLUGIN_SOURCE}
@@ -89,7 +89,7 @@ set(SS_SERVER_SOURCE
${SS_SHARED_SOURCES}
udprelay.c
cache.cpp
resolv.c
resolv.cpp
server.c
${SS_CRYPTO_SOURCE}
${SS_PLUGIN_SOURCE}
View File
View File
View File
+3 -3
View File
@@ -1,5 +1,5 @@
/*
* aead_internal.h - Internal interface shared by aead.c and aead2022.c
* aead_internal.h - Internal interface shared by aead.cpp and aead2022.cpp
*
* Copyright (C) 2013 - 2026, Max Lv <max.c.lv@gmail.com>
*
@@ -54,7 +54,7 @@ is_aead_2022(int method)
|| method == CHACHA20POLY1305IETF2022;
}
/* Low-level one-shot AEAD operations implemented in aead.c */
/* Low-level one-shot AEAD operations implemented in aead.cpp */
int aead_cipher_encrypt(cipher_ctx_t *cipher_ctx,
uint8_t *c, size_t *clen,
uint8_t *m, size_t mlen,
@@ -67,7 +67,7 @@ int aead_cipher_decrypt(cipher_ctx_t *cipher_ctx,
uint8_t *n, uint8_t *k);
void aead_cipher_ctx_set_key(cipher_ctx_t *cipher_ctx, int enc);
/* AEAD-2022 pieces implemented in aead2022.c */
/* AEAD-2022 pieces implemented in aead2022.cpp */
int aead_get_role(void);
void ss2022_derive_subkey(const uint8_t *key, size_t key_len,
const uint8_t *salt, size_t salt_len,
View File
View File
View File
View File
View File
View File
+2 -2
View File
@@ -364,11 +364,11 @@ later on the command line override the values taken from the URL.
Set the cipher. The default is `chacha20-ietf-poly1305`.
AEAD cipher names from the source (availability depends on the build):
\snippet aead.c cli-aead-ciphers
\snippet aead.cpp cli-aead-ciphers
Legacy stream cipher names recognized by the source (disabled in minimal builds;
some require backend support):
\snippet stream.c cli-stream-ciphers
\snippet stream.cpp cli-stream-ciphers
The `2022-blake3-*` ciphers implement Shadowsocks 2022 (SIP022). They require
a base64-encoded pre-shared key supplied with `--key` or `--password` (*-k*): 16 bytes for
+13 -13
View File
@@ -117,7 +117,7 @@ set(TEST_NETUTILS_LIBS
ss_cares
)
ss_add_test(test_netutils
"test_netutils.c;${PROJECT_SOURCE_DIR}/src/netutils.c;${PROJECT_SOURCE_DIR}/src/utils.c"
"test_netutils.c;${PROJECT_SOURCE_DIR}/src/netutils.cpp;${PROJECT_SOURCE_DIR}/src/utils.c"
"${TEST_NETUTILS_LIBS}")
# test_cache - expiration uses a platform monotonic clock
@@ -145,7 +145,7 @@ ss_add_test(test_rule
# test_acl - ACL precedence and prefix matching
set(TEST_ACL_LIBS ${TEST_RULE_LIBS})
ss_add_test(test_acl
"test_acl.c;${PROJECT_SOURCE_DIR}/src/acl.c;${PROJECT_SOURCE_DIR}/src/ipset.cpp;${PROJECT_SOURCE_DIR}/src/rule.cpp;${PROJECT_SOURCE_DIR}/src/utils.c"
"test_acl.c;${PROJECT_SOURCE_DIR}/src/acl.cpp;${PROJECT_SOURCE_DIR}/src/ipset.cpp;${PROJECT_SOURCE_DIR}/src/rule.cpp;${PROJECT_SOURCE_DIR}/src/utils.c"
"${TEST_ACL_LIBS}")
endif()
@@ -157,17 +157,17 @@ set(TEST_JCONF_LIBS
ss_cares
)
ss_add_test(test_jconf
"test_jconf.c;${PROJECT_SOURCE_DIR}/src/jconf.c;${PROJECT_SOURCE_DIR}/src/json.cpp;${PROJECT_SOURCE_DIR}/src/utils.c;${PROJECT_SOURCE_DIR}/src/netutils.c"
"test_jconf.c;${PROJECT_SOURCE_DIR}/src/jconf.cpp;${PROJECT_SOURCE_DIR}/src/json.cpp;${PROJECT_SOURCE_DIR}/src/utils.c;${PROJECT_SOURCE_DIR}/src/netutils.cpp"
"${TEST_JCONF_LIBS};${SS_MATH_LIBRARY}")
# Crypto sources shared by the tests that link the crypto layer. The AEAD-2022
# ciphers pull in BLAKE3 (linked as the `blake3` target) and the session-based
# UDP codec, so they must be built together with crypto.c.
# UDP codec, so they must be built together with crypto.cpp.
set(SS_CRYPTO_TEST_SOURCES
${PROJECT_SOURCE_DIR}/src/crypto.c
${PROJECT_SOURCE_DIR}/src/aead.c
${PROJECT_SOURCE_DIR}/src/aead2022.c
${PROJECT_SOURCE_DIR}/src/aead2022_udp.c
${PROJECT_SOURCE_DIR}/src/crypto.cpp
${PROJECT_SOURCE_DIR}/src/aead.cpp
${PROJECT_SOURCE_DIR}/src/aead2022.cpp
${PROJECT_SOURCE_DIR}/src/aead2022_udp.cpp
${PROJECT_SOURCE_DIR}/src/ppbloom.cpp
${PROJECT_SOURCE_DIR}/src/cache.cpp
${PROJECT_SOURCE_DIR}/src/base64.cpp
@@ -175,10 +175,10 @@ set(SS_CRYPTO_TEST_SOURCES
)
if(SS_ENABLE_LEGACY)
list(APPEND SS_CRYPTO_TEST_SOURCES ${PROJECT_SOURCE_DIR}/src/stream.c)
list(APPEND SS_CRYPTO_TEST_SOURCES ${PROJECT_SOURCE_DIR}/src/stream.cpp)
endif()
# test_buffer - needs sodium and mbedtls for crypto.c buffer functions
# test_buffer - needs sodium and mbedtls for crypto.cpp buffer functions
ss_add_test(test_buffer
"test_buffer.c;${SS_CRYPTO_TEST_SOURCES}"
"ss_sodium;;ss_mbedcrypto;ss_ev;${TEST_PPBLOOM_LIBS};blake3;${SS_MATH_LIBRARY}")
@@ -229,7 +229,7 @@ ss_add_test(test_process
set_tests_properties(test_process PROPERTIES TIMEOUT 20)
ss_add_test(test_resolv
"test_resolv.c;${PROJECT_SOURCE_DIR}/src/resolv.c;${PROJECT_SOURCE_DIR}/src/utils.c"
"test_resolv.c;${PROJECT_SOURCE_DIR}/src/resolv.cpp;${PROJECT_SOURCE_DIR}/src/utils.c"
"ss_ev;ss_cares;ss_sodium")
set_tests_properties(test_resolv PROPERTIES TIMEOUT 20)
@@ -238,13 +238,13 @@ if(SS_ENABLE_REGEX)
list(APPEND TEST_LITERAL_LIBS ss_pcre2)
endif()
ss_add_test(test_acl_literal
"test_acl_literal.c;${PROJECT_SOURCE_DIR}/src/acl.c;${PROJECT_SOURCE_DIR}/src/ipset.cpp;${PROJECT_SOURCE_DIR}/src/rule.cpp;${PROJECT_SOURCE_DIR}/src/utils.c"
"test_acl_literal.c;${PROJECT_SOURCE_DIR}/src/acl.cpp;${PROJECT_SOURCE_DIR}/src/ipset.cpp;${PROJECT_SOURCE_DIR}/src/rule.cpp;${PROJECT_SOURCE_DIR}/src/utils.c"
"${TEST_LITERAL_LIBS}")
ss_add_test(test_event "test_event.c" "ss_ev")
set_tests_properties(test_event PROPERTIES TIMEOUT 30)
ss_add_test(test_resolv_async
"test_resolv_async.c;${PROJECT_SOURCE_DIR}/src/resolv.c;${PROJECT_SOURCE_DIR}/src/utils.c"
"test_resolv_async.c;${PROJECT_SOURCE_DIR}/src/resolv.cpp;${PROJECT_SOURCE_DIR}/src/utils.c"
"ss_ev;ss_cares;ss_sodium")
set_tests_properties(test_resolv_async PROPERTIES TIMEOUT 30)
+1 -1
View File
@@ -19,7 +19,7 @@ int verbose = 0;
#include "utils.h"
#include "blake3/blake3.h"
/* Provide nonce_cache symbol needed by crypto.c */
/* Provide nonce_cache symbol needed by crypto.cpp */
struct cache *nonce_cache = NULL;
/* 32-byte and 16-byte PSKs in base64 */
+1 -1
View File
@@ -10,7 +10,7 @@ int verbose = 0;
#include "crypto.h"
/* Provide nonce_cache symbol needed by crypto.c */
/* Provide nonce_cache symbol needed by crypto.cpp */
struct cache *nonce_cache = NULL;
static void
+2 -2
View File
@@ -13,7 +13,7 @@ int verbose = 0;
#include "ppbloom.h"
#include "utils.h"
/* Provide nonce_cache symbol needed by crypto.c */
/* Provide nonce_cache symbol needed by crypto.cpp */
struct cache *nonce_cache = NULL;
static void
@@ -366,7 +366,7 @@ main(void)
#if SS_ENABLE_LEGACY
/* mbedTLS-backed ciphers and libsodium-backed ciphers use different
* code paths in stream.c, so cover both. */
* code paths in stream.cpp, so cover both. */
test_stream_multi_segment_roundtrip("aes-256-cfb");
test_stream_multi_segment_roundtrip("aes-256-ctr");
test_stream_multi_segment_roundtrip("camellia-128-cfb");