mirror of
https://github.com/shadowsocks/shadowsocks-libev.git
synced 2026-10-31 06:23:52 +00:00
fix/audit-findings
4
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
a22281b1ac |
C++20 port 12/14: seal the heap, capacity limits (#3078)
* Seal the heap: bounded library heaps and zero-allocation program tests The programs point libuv, c-ares and Mbed TLS (MBEDTLS_PLATFORM_MEMORY in the bundled build) at their own FixedHeap before anything runs, mark the end of startup with heap_seal(), and in verbose mode report heap use and any allocation after it at exit. The library build keeps the host's allocator. measure_alloc.py gains --udp, and the alloc_steady_programs_* tests now fail on any malloc per relayed TCP connection (by name and by address) or UDP association, for every cipher family. * Fix GCC -Wsign-compare errors in the converted C modules GCC enables -Wsign-compare with -Wall for C++ (clang does not), which turned a few signed/unsigned comparisons in base64, netutils, server and manager into errors; udp.cpp needed <ctime>. * Add --max-connections and --max-udp-sessions The TCP connection pool and the UDP session table are sized from these options (or max_connections / max_udp_sessions in the configuration file) at startup instead of fixed constants; the DNS query pool follows the connection limit. test_limits.py checks that a connection beyond the limit is refused and that accepting resumes once one closes. |
||
|
|
5c62b2544e |
C++20 port 11/14: one TCP and UDP relay engine for all programs (#3075)
* Rewrite the resolver in C++ on a fixed query pool Queries live in pool slots with their first A and AAAA answer inline, c-ares sockets are watched from a fixed table, and answers reach the waiter through a callback plus opaque words instead of a back-pointer. resolv.cpp keeps the C API as a shim. The event Loop can now adopt the ss_event loop, and a Poll can stop watching a socket it does not own. * Add the C++ TCP relay engine and run ss-tunnel on it One engine (src/relay/tcp) for the four TCP relays: connections live in a fixed pool owned through PoolPtr, handshake, cipher state and buffers are inline, timeouts are intrusive deadline lists on one timer and DNS answers come back through generation-checked handles. A full pool refuses new connections and pauses accepting until a slot frees. ss-tunnel is the first user; its hand-written relay callbacks are gone. tests/tunnel_interop.py covers every method against ss-server and shadowsocks-rust. * Run ss-local and libshadowsocks-c on the C++ TCP relay engine The SOCKS5 handshake, the ACL bypass decision (with its own resolver for host-name rules) and the short wait for a first payload are now engine code; local.cpp keeps only option parsing and startup. The library entry points start the same engine. * Run ss-server on the C++ TCP relay engine The request header, outbound ACL, target resolution through the relay's resolver, the anti-probing stop stage and the manager traffic counters are engine code now; the connmark-to-TOS tracker becomes a pair of relay hooks. server.cpp keeps option parsing, nftables and the stats timer. * Fix the build with GCC and libstdc++ crypto.h's min/max macros broke <algorithm> in C++ sources that include it first, netutils.h's linux/tcp.h clashed with the netinet/tcp.h libuv includes, and GCC rejects memcpy into crypto_t. Apple clang accepted all three. * Run ss-redir and every UDP relay on the C++ engines ss-redir's TCP side moves onto the relay engine (per-listener TOS for the DSCP ports). src/relay/udp replaces udprelay.cpp: sessions keyed by client address own their upstream socket and live in a fixed LRU, AEAD-2022 server sessions are shared through RefPtr between the session-ID table and the relays using them, and datagrams waiting for DNS sit in pool slots. Packets are received into and built in relay-owned buffers instead of a 64 KiB allocation per datagram. The programs no longer call crypto_init(); Method sets up libsodium and the replay filter. * Let the allocation audit target an IP so DNS costs show separately * Copy the literal ACL address without strncpy GCC 13 at -O3 rejects the strncpy from the 256-byte host into the INET6_ADDRSTRLEN buffer (-Wstringop-truncation) on glibc and UCRT64. * Include <ctime> for std::time in the UDP relay (libstdc++) * Build the UDP relay with Clang on musl musl's CMSG_NXTHDR compares a size_t with a ptrdiff_t, which Clang's -Wsign-compare rejects in C++. Call it from one helper that suppresses the warning there. * Keep clang-tidy clean in the relay engine |
||
|
|
8d39cd7569 |
C++20 port 6/14: allocation-free AEAD codecs (#3070)
* Add allocation-free C++ AEAD codecs src/crypto/aead.hpp implements the SIP004/SIP007 AEAD ciphers as value types: AeadEngine holds the libsodium or Mbed TLS GCM state by value, AeadTcpEncryptor/AeadTcpDecryptor frame the chunk stream with a fixed reassembly buffer, and aead_udp_seal/open handle packets. HKDF-SHA1 runs on stack SHA-1 state instead of Mbed TLS's allocating HMAC API. The bundled Mbed TLS config now enables MBEDTLS_BLOCK_CIPHER_C, which keeps the AES context inside mbedtls_gcm_context, so GCM key setup no longer allocates. That alone saves the C programs two allocations per connection. test_crypto_aead_cpp checks HKDF against RFC 5869 and crypto_hkdf, runs TCP streams and UDP packets between the C and C++ implementations in both directions for all five AEAD methods, and covers tampering, framing and salt replay. alloc_steady_crypto_aead runs it under the malloc counter and requires zero allocations across 600 new connections and 600 packets (tests/alloc_audit/check_steady.py). ss_strict_warnings() now applies -Wextra per source file so targets mixing new C++ with converted C modules keep the latter at -Wall, and Result gains move assignment. * Include <algorithm> for std::min in test_crypto_aead_cpp.cpp * Build the C++ AEAD codecs against Mbed TLS 2.x Mbed TLS 2 returns void from mbedtls_sha1_starts/update/finish (the int versions are the _ret variants), which the system-library build on Ubuntu (2.28) rejects. crypto/mbedtls_compat.hpp gives one int-returning spelling for both. * Include C++ headers before crypto.h in test_crypto_aead_cpp.cpp crypto.h defines min/max macros for the C sources; libstdc++ headers included after it fail to parse. * Disable the zero-allocation checks with a system Mbed TLS They hold for the bundled Mbed TLS (MBEDTLS_BLOCK_CIPHER_C); a system one may allocate in GCM key setup, as the Debian package build shows. |
||
|
|
bcb3731968 |
C++20 port 1/14: build, ownership core and allocation audit (#3065)
* Enable C++20 alongside C11 in the build Add CXX to the project with C++20 (no extensions) and build C++ sources with -Wextra -fno-exceptions -fno-rtti -fno-threadsafe-statics on top of the existing warning flags. Give every toolchain a C++ compiler: the zig Windows toolchain, the static macOS/Windows CI jobs, the static musl image (clang++ plus libstdc++ headers) and the RPM spec. * Add C++20 ownership and allocation core Header-only primitives for the no-heap-after-startup design: Result/Status, Region, ObjectPool with PoolPtr (std::unique_ptr with a pool deleter), generation-checked Handle and asynchronous close support, intrusive RefPtr, FixedBuffer, MonotonicArena, FixedHashMap and FixedLru, IntrusiveList, and a bounded FixedHeap for third-party allocator hooks. Unit tests cover each primitive (test_core_*). scripts/check_no_heap.py rejects heap allocation in C++ sources under src/ and runs as a ctest. clang-tidy now also analyses C++ sources and the core headers. * Add heap allocation audit for relayed connections alloc_counter is a preloadable malloc counter (glibc, macOS) that writes a snapshot on SIGUSR2. measure_alloc.py warms ss-local and ss-server up, snapshots both, relays more connections and reports allocations per connection. It runs report-only as the alloc_audit_report ctest. interop.peers() now yields the started processes. * Document the C++20 port and allocation baseline docs/cpp-core.md describes the language profile, the core primitives, the phase plan and the measured C baseline (77-89 allocations per connection in ss-server, 27-39 in ss-local). The compatibility contract now keeps the C11 public header instead of a C11 code base. CLAUDE.md drops stale libev, submodule and gnu99 references. * Fix CI for the C++ core: libstdc++ headers, static unwinder, newer clang - docker/static: Alpine's libstdc++ headers come with g++, and the C++ tests' static libstdc++ needs an unwinder that compiler-rt lacks; add g++ and llvm-libunwind. - FixedBuffer: drop the unused kCapacity (clang-tidy 18 reports it as a dynamically initialized header static). - ss-server on Windows: manager_addr was only read in POSIX-only code, which newer clang rejects (-Wunused-but-set-global); say that the option is ignored there. * CI: allow running the test and build workflows by hand Stacked PRs target their parent branch, which these workflows do not trigger on; workflow_dispatch lets each layer run the full matrix. * CI: let clang-tidy ignore GCC-only warning flags The compile database comes from a GCC build, whose flags (for example -Wno-class-memaccess) clang-tidy does not know and reports as errors. |