mirror of
https://github.com/shadowsocks/shadowsocks-libev.git
synced 2026-10-21 22:43:48 +00:00
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.
51 lines
2.0 KiB
Python
51 lines
2.0 KiB
Python
#!/usr/bin/env python3
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
"""Run a test program under the alloc_counter shim and check a steady phase.
|
|
|
|
The program calls ss::test::alloc_mark() (tests/alloc_audit/alloc_probe.hpp)
|
|
before and after the code that must not allocate. This script preloads the
|
|
shim, runs the program, and fails unless exactly two marks were recorded and
|
|
no allocation happened between them.
|
|
|
|
Usage: check_steady.py --shim LIB [--max N] -- PROGRAM [ARGS...]
|
|
"""
|
|
import argparse
|
|
import os
|
|
from pathlib import Path
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
|
parser.add_argument("--shim", required=True)
|
|
parser.add_argument("--max", type=int, default=0, help="allocations allowed between the marks")
|
|
parser.add_argument("command", nargs=argparse.REMAINDER)
|
|
args = parser.parse_args()
|
|
command = args.command[1:] if args.command[:1] == ["--"] else args.command
|
|
if not command:
|
|
parser.error("missing program to run")
|
|
|
|
with tempfile.TemporaryDirectory(prefix="ss-steady-") as temp:
|
|
out = Path(temp) / "counts"
|
|
env = os.environ.copy()
|
|
env["DYLD_INSERT_LIBRARIES" if sys.platform == "darwin" else "LD_PRELOAD"] = str(Path(args.shim).resolve())
|
|
env["SS_ALLOC_AUDIT_OUT"] = str(out)
|
|
result = subprocess.run(command, env=env)
|
|
if result.returncode != 0:
|
|
print(f"{command[0]} exited with {result.returncode}")
|
|
return 1
|
|
lines = out.read_text().splitlines() if out.exists() else []
|
|
if len(lines) != 2:
|
|
print(f"expected 2 allocation marks, got {len(lines)}")
|
|
return 1
|
|
before, after = ([int(v) for v in line.split()] for line in lines)
|
|
allocations = after[1] - before[1]
|
|
print(f"steady phase: {allocations} allocation(s), {after[3] - before[3]} bytes (allowed: {args.max})")
|
|
return 0 if allocations <= args.max else 1
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|