Files
s5p/PROJECT.md
user 40560ef6dd docs: document connection limit, async fetch, and connection pool
Update USAGE, CHEATSHEET, README, PROJECT, and TASKS for the three
performance improvements: max_connections semaphore, async HTTP
source fetching, and first-hop TCP connection pool.
2026-02-15 17:56:08 +01:00

69 lines
3.1 KiB
Markdown

# s5p -- Project
## Purpose
A lightweight SOCKS5 proxy server that chains connections through Tor and/or
arbitrary proxy hops (SOCKS4, SOCKS5, HTTP CONNECT).
## Motivation
Existing solutions (`proxychains-ng`) rely on `LD_PRELOAD` hacks, only work
on Linux, and intercept at the library level. s5p is a proper SOCKS5 server
that any application can use natively -- no injection required.
## Architecture
```
TCP tunnel tunnel
Client -------> s5p -------> Hop 1 -------> Hop 2 -------> Target
SOCKS5 proto1 proto2 protoN
```
- **server.py** -- asyncio SOCKS5 server, bidirectional relay, signal handling
- **proto.py** -- protocol handshakes (SOCKS5, SOCKS4/4a, HTTP CONNECT), chain builder
- **config.py** -- YAML config loading, proxy URL parsing, pool config
- **pool.py** -- managed proxy pool (multi-source, health-tested, persistent)
- **source.py** -- legacy proxy source (single HTTP API, kept for backward compat)
- **http.py** -- minimal async HTTP/1.1 client (GET/POST JSON, no external deps)
- **connpool.py** -- pre-warmed TCP connection pool to first chain hop
- **cli.py** -- argparse CLI, logging setup, cProfile support
## Deployment
| Method | Command |
|--------|---------|
| Local venv | `pip install -e .` then `s5p -c config/s5p.yaml` |
| Container | `make build && make up` (Alpine, ~59MB) |
Container mounts `./src` and `./config/s5p.yaml` read-only, plus
`~/.cache/s5p` as `/data` for pool state and profile output.
No application code is baked into the image.
## Dependencies
| Package | Purpose |
|---------|---------|
| pyyaml | Config file parsing |
All other functionality uses Python stdlib (`asyncio`, `socket`, `struct`).
## Design Decisions
- **No LD_PRELOAD** -- clean SOCKS5 server, works with any client
- **asyncio** -- single-threaded event loop, efficient for I/O-bound proxying
- **Domain passthrough** -- never resolve DNS locally to prevent leaks
- **Tor as a hop** -- no special Tor handling; it's just `socks5://127.0.0.1:9050`
- **Graceful shutdown** -- SIGTERM/SIGINT handled in the event loop for clean container stops
- **Config split** -- tracked example template, gitignored live config with real addresses
- **Proxy pool** -- multi-source (API + file), health-tested, persistent, auto-cleaned
- **Weighted selection** -- recently-tested proxies preferred via recency decay weight
- **Failure backoff** -- connection failures penalize proxy weight for 60s, avoids retry waste
- **Stale expiry** -- proxies dropped from sources evicted after 3 refresh cycles if not alive
- **Chain pre-flight** -- static chain tested before pool health tests; skip on failure
- **Warm start** -- quick-test alive subset on restart, defer full test to background
- **SIGHUP reload** -- re-read config, update pool settings, re-fetch sources
- **Dead reporting** -- POST evicted proxies to upstream API for list quality feedback
- **Connection semaphore** -- cap concurrent connections to prevent fd exhaustion
- **Async HTTP** -- native asyncio HTTP client replaces blocking urllib, parallel fetches
- **First-hop pool** -- pre-warmed TCP connections to chain[0], stale-evicted, auto-refilled