Rename the project to shadowsocks-c while retaining ss-* commands, the embedding ABI, and legacy library/package lookup compatibility.
Replace libev with bundled libuv for IOCP/kqueue event backends, expand asynchronous runtime DNS coverage, and add actionlint/Ruff with strict clang-tidy failure handling. Validate native platforms, static builds, packaging, interoperability, sanitizers, and canonical/legacy consumers.
All 22 hosted checks pass at reviewed head a8493250eb.
Bundle pinned offline dependencies, remove libcork/libipset and submodule requirements, and add portable runtime helpers with relocatable static/shared library installations.
Add Clang static build validation for Linux/musl, macOS and Windows, real TCP/UDP and SIP003 interoperability coverage, and recorded performance tradeoffs. All 21 hosted checks pass at the reviewed PR head 8d504e6218.
Real bugs fixed:
- manager.c: kill_server/stop_server checked fscanf() != EOF, so malformed
pid file content left pid uninitialized and passed it to kill(). Parse
with fgets + ss_parse_int and require pid > 0.
- utils.c: get_default_conf() crashed on strlen(NULL) when HOME is unset
(e.g. daemons started by init) and left a dangling static pointer after
free(), a latent use-after-free on repeated calls. Use a static buffer
and fall back to the system config when HOME is missing.
- local.c: in UDP_ONLY mode, start_ss_local_server() passed uninitialized
listen_ctx.fd to the library callback. Initialize it to -1.
Improvements:
- Replace rand()/srand(time(NULL)) upstream-server selection in ss-local,
ss-redir and ss-tunnel with libsodium randombytes_uniform(): unbiased,
unpredictable, and no seeding required (cert-msc30/msc32).
- Mark FATAL() noreturn so both the compiler and analyzers understand
control flow (removes a family of analyzer false positives).
- Drop two dead stores (manager.c restore_sigchld, udprelay.c src_addr_len).
All remaining findings were verified as false positives and carry NOLINT
comments with rationale (uthash macro internals, symmetric back-pointer
cleanup, analyzer-invisible postconditions). clang-tidy-18 on Linux now
reports zero warnings, so MAX_WARNINGS drops from 29 to 0.
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
WITH_STATIC defaults to ON in CMakeLists.txt but CI was explicitly
disabling it. Remove -DWITH_STATIC=OFF so the static targets are
also built and linked, catching issues like the c-ares static
library rename (#3024).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add tests/test_deb_build.sh with four phases:
1. Build .deb packages via dpkg-buildpackage
2. Verify all three packages contain expected files (binaries, man
pages, shared library, headers, pkg-config)
3. Install packages and resolve dependencies
4. Smoke-test installed binaries, ldconfig, and headers
Add a Linux-only CI step in build.yml to run the test.
Statically link the bundled submodule libraries (libcork, libipset,
libbloom) into all targets instead of building them as shared libs.
These are vendored code built from git submodules, not system
libraries, so static linking is correct and eliminates
dpkg-shlibdeps warnings about missing .so files.
Pass -DWITH_STATIC=OFF in debian/rules since debian build-depends
only provide shared library dev packages.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Boot a minimal Alpine Linux guest in QEMU with iptables, ss-redir, and
ss-nat to verify the full transparent proxy chain: iptables REDIRECT →
ss-redir → ss-server (host) → internet. The host-built ss-redir binary
and its shared library dependencies are copied into the Alpine rootfs,
avoiding static linking issues. Uses QEMU user-mode networking with KVM
acceleration when available. Linux-only CI step with 8-minute timeout.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Interactive whiptail/dialog TUI for server/client config generation,
systemd service management, SIP003 plugin installation, and ss:// URI
output. Includes 131 bash unit tests covering all utility functions
(validation, JSON generation, URI encoding, config round-trip parsing).
Tests run in CTest and as a dedicated GitHub Actions step.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Modernize build: switch to CMake, add unit tests, fix man pages
Remove autotools (configure.ac, Makefile.am, m4/, autogen.sh) and make
CMake the sole build system. Enhance CMake with proper Find modules for
MbedTLS, libsodium, PCRE, and c-ares with version/feature detection.
Add support for connmarktos, nftables, stack protector, and MinGW.
Add 10 unit test suites (CTest) covering base64, buffer, cache, crypto,
jconf, json, netutils, ppbloom, rule, and utils modules. Add a Python
stress test measuring bandwidth per cipher with memory leak detection.
Fix man page typos ("Resovle" -> "Resolve"), document missing TCP buffer
options, fix ss-manager duplicate --executable entry, add example section
to ss-tunnel, and document --workdir and --nftables-sets options.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Migrate from PCRE to PCRE2
Replace legacy PCRE (libpcre3) with PCRE2 (libpcre2-8). PCRE1 has been
end-of-life since 2021.
- src/rule.h: use pcre2_code and pcre2_match_data types
- src/rule.c: pcre_compile -> pcre2_compile, pcre_exec -> pcre2_match,
pcre_free -> pcre2_code_free, with proper error message retrieval
- cmake/FindPCRE.cmake -> cmake/FindPCRE2.cmake: find libpcre2-8 via
pkg-config, pcre2-config, or manual search
- Update all CMakeLists.txt, config.h.cmake, configure.cmake, README.md
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Update Dockerfiles: use CMake build and pcre2-dev
The alpine Dockerfile still used autotools (autogen.sh/configure) which
were removed. Switch to cmake build and replace pcre-dev with pcre2-dev.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix Docker build: disable tests and remove git dep
The tests/ directory is excluded by .dockerignore, so pass
-DBUILD_TESTING=OFF to cmake. Submodules are already checked out
by actions/checkout, no need for git inside the container.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix Docker build: disable static libs (not available in alpine)
Alpine's mbedtls-dev only provides shared libraries. Disable static
build since Docker only needs shared binaries.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Rewrite GitHub Actions: build and test directly on runner
Replace Docker-based CI with direct cmake build on ubuntu-latest and
macos-latest. Install dependencies via apt/brew, build with cmake,
run unit tests with ctest.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix CI: use mbedtls@3 on macOS, disable static build
- macOS: brew's mbedtls is now v4 (incompatible), use mbedtls@3
- Disable static build since CI runners lack static lib packages
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix test build on Linux: add stdint.h and link libm
- test_ppbloom.c: add missing #include <stdint.h> for uint8_t
- test_json: link against libm for pow() used in json.c
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix test_ppbloom link: add libm for bloom's log()
On Linux, libbloom uses log() which requires explicit -lm linkage.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix Linux build: link libm for test_buffer and test_crypto, fix warnings
Both test_buffer and test_crypto link libbloom.so which uses log() from
libm. Also fix unused variable warnings in test_json.c that would fail
with -Werror.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix Linux build: link libm for test_jconf (json.c uses pow)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* CI: add unit test and stress test steps to GitHub Actions
Split the Test step into separate "Unit tests" (ctest) and "Stress test"
(stress_test.py with 10MB transfer across all AEAD ciphers) steps for
better visibility.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>