A self-hosted, automated proxy core written in Rust. Designed for "seamless proxying" with automatic speed testing, clustering, switching, and self-healing.
- Multi-protocol Support: Shadowsocks (AEAD, AEAD-2022) + Trojan (TLS-based)
- TUN Mode: System-wide transparent proxy (TCP + UDP)
- Smart Routing: Domain/IP-based rules with external ruleset support
- Auto Failover: Automatic node switching on failure with health tracking
- Auto Clustering: Latency-based node grouping for optimal selection
- Happy Eyeballs: Concurrent connection attempts for faster establishment
- DNS Integration: Built-in DNS server with domain-IP mapping + DNS cache
- Hot Reload: SIGHUP signal for config reloading without restart
- Performance Optimization: DNS cache + slow node filtering
# Build
cargo build --release
# Run with config (requires root for TUN mode)
sudo ./target/release/proxy-core -c config.yamlComponent-specific documentation:
- Outbound Protocols: src/outbound/README.md (Shadowsocks, Trojan, Direct, Reject)
- TUN Mode: src/inbound/tun/README.md (TCP/UDP transparent proxy)
- DNS Module: src/dns/README.md (DNS server, caching, DoT resolver)
Legacy docs:
log:
level: INFO
format: pretty
tun:
name: "tun0"
mtu: 1500
address: "10.0.0.1/24"
auto_route: true
sniff_fallback: true
excluded_routes:
- "127.0.0.0/8"
mode: auto # direct | global | rule | auto
dns:
listen: "127.0.0.1:5354"
upstream: system
subscriptions:
- key: my-airport
url: https://example.com/subscribe
user_agent: "clash-verge/v1.7.7"
rules:
- [DOMAIN-SUFFIX, cn, DIRECT]
- [DOMAIN-SUFFIX, google.com, PROXY]
- [FINAL, "", PROXY]
settings:
dns_cache:
enabled: true
ttl_sec: 600
performance:
slow_node_threshold_ms: 2000
min_success_rate: 0.7| Mode | Description |
|---|---|
direct |
All traffic connects directly |
global |
All traffic through proxy |
rule |
Route based on rules (default) |
auto |
Smart mode with clustering and learning |
src/
├── main.rs # CLI entry point
├── lib.rs # Module exports
│
├── core/ # Foundation layer (no business deps)
│ ├── error.rs # Unified error types
│ ├── config/ # Configuration parsing
│ │ ├── mod.rs # Config, Settings
│ │ ├── mode.rs # ProxyMode
│ │ ├── outbound.rs # OutboundConfig
│ │ ├── health.rs # HealthConfig
│ │ └── pool.rs # PoolConfig
│ └── types/ # Data types
│ ├── address.rs # Address
│ ├── proxy.rs # Proxy
│ └── rule.rs # MatchRule, MatchContext
│
├── protocol/ # Protocol layer
│ ├── subscription.rs # SS subscription parsing
│ └── sniffer/ # Protocol sniffing
│ ├── tls.rs # TLS SNI extraction
│ └── http.rs # HTTP Host extraction
│
├── dns/ # DNS layer
│ ├── server.rs # UDP DNS server
│ ├── mapping.rs # IP-domain mapping (for TUN)
│ ├── cache.rs # DNS cache (LRU + TTL)
│ └── outbound.rs # DoT resolver (for outbound connections)
│
├── node/ # Node layer
│ ├── registry.rs # Global node registry
│ └── health.rs # Node health cache
│
├── rule/ # Rule layer
│ ├── engine.rs # Rule matching engine
│ ├── loader.rs # Ruleset loader
│ └── learned.rs # Dynamic learned rules
│
├── outbound/ # Outbound layer (pure implementations)
│ ├── traits.rs # Outbound trait, BoxedStream
│ ├── direct.rs # DirectOutbound
│ ├── shadowsocks.rs # ShadowsocksOutbound (TCP + UDP)
│ ├── trojan.rs # TrojanOutbound (TLS-based)
│ ├── group.rs # GroupOutbound
│ ├── reject.rs # RejectOutbound
│ └── socket.rs # SO_MARK utilities
│
├── relay/ # Relay layer
│ └── mod.rs # relay(), relay_with_validation()
│
├── routing/ # Routing layer
│ ├── manager.rs # OutboundManager
│ └── happy_eyeballs.rs # Concurrent connection
│
├── learning/ # Learning layer (auto mode)
│ ├── event.rs # Event definitions + EventEmitter
│ ├── state.rs # Learning state structures
│ ├── reader.rs # StateReader (read-only)
│ ├── manager.rs # StateManager, LearningSystem
│ ├── fingerprint.rs # Node stable fingerprint
│ ├── persistence.rs # SQLite persistence
│ ├── exception.rs # Service exception definitions
│ ├── health.rs # System health detection
│ └── probe.rs # Recovery probe runner
│
├── inbound/ # Inbound layer
│ └── tun/ # TUN device + netstack
│ ├── device.rs # TUN device creation (tun2)
│ ├── stack.rs # TCP/IP stack (smoltcp)
│ ├── tcp.rs # TCP connection handling + SNI/HTTP sniffer
│ ├── udp.rs # UDP packet handling
│ ├── udp_session.rs # UDP NAT session management
│ └── route.rs # Linux routing (policy routing + iptables)
│
└── runtime/ # Runtime configuration
└── mod.rs
┌─────────────────────────────────────────────────────────────────┐
│ Business Layer (emit events) │
│ Socks5Handler / OutboundManager / ProbeTask │
└─────────────────────────────────────────────────────────────────┘
│ emit() │ read()
▼ ▼
┌─────────────────────────────────────────────────────────────────┐
│ EventEmitter │ StateReader │ StateManager │
│ (send events) │ (read-only) │ (single writer) │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ LearnedState │
│ (domain_node_map, node_health, failure_correlations) │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ SQLite Persistence │
│ (domain_mapping, node_health, correlation) │
└─────────────────────────────────────────────────────────────────┘
Key Features:
- Event-driven learning from actual connection results
- Failure correlation analysis (skip related failing nodes)
- SQLite persistence (survive restarts)
- Recovery probe for cooldown nodes
- Service exception feedback (no healthy nodes, subscription stale, etc.)
┌─────────────────┐ ┌──────────────┐ ┌────────────────┐
│ Application │────▶│ Kernel │────▶│ TUN Device │
│ (curl, etc.) │ │ (routing) │ │ (tun0) │
└─────────────────┘ └──────────────┘ └────────────────┘
│
┌────────────────────────────┼────────────────────────────┐
│ TunServer (smoltcp + sniffer) │
└────────────────────────────┼────────────────────────────┘
│
┌────────────────────────────┼────────────────────────────┐
▼ DNS Mapping ▼ SNI/HTTP Sniff ▼ IP Only
┌─────────────┐ ┌──────────────┐ ┌──────────────┐
│ RuleEngine │ │ RuleEngine │ │ RuleEngine │
└─────────────┘ └──────────────┘ └──────────────┘
│ │ │
▼ ▼ ▼
┌─────────────┐ ┌──────────────┐ ┌──────────────┐
│ DIRECT │ │ GROUP │ │ REJECT │
└─────────────┘ └──────────────┘ └──────────────┘
│ │
│ ┌────────┴────────┐
▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Target │ │ SS Node │ │ Trojan Node │
└─────────────┘ └─────────────┘ └─────────────┘
(SO_MARK 0x162) (SO_MARK 0x162)
| Component | Technology |
|---|---|
| Core | Rust + Tokio |
| Protocol | shadowsocks-rust, Trojan (self-impl) |
| TLS | tokio-rustls, rustls (ring provider) |
| DNS | hickory-dns (DoT support) |
| Storage | rusqlite (learning system) |
| E2E Test | pnpm + vitest |
- Rust 1.75+
- pnpm 10+
- Node.js 20+ (for E2E tests)
# Build
cargo build
# Run tests
cargo test
# Run with debug logging
RUST_LOG=debug cargo run -- -c config.yml
# Format code
cargo fmt
# Lint
cargo clippy
# E2E tests
pnpm test
# E2E tests with real network
PROXY_E2E_REAL=1 pnpm test- Rust Edition: 2021
- Max Line Width: 100 characters
- Indentation: 4 spaces
- Lints: clippy pedantic + nursery enabled
- Error Handling: Typed errors (
ProxyError,ConnectionError, etc.) - Async Runtime: Tokio
[lints.rust]
unsafe_code = "forbid"
[lints.clippy]
all = { level = "warn", priority = -1 }
pedantic = { level = "warn", priority = -1 }
nursery = { level = "warn", priority = -1 }-
Module Organization
core/- Foundation layer (error, config, types)protocol/- Protocol parsing (subscription, sniffer)inbound/- Incoming connection handlersoutbound/- Outgoing connection handlersrelay/- Bidirectional data relayrouting/- Route decision (OutboundManager, Happy Eyeballs)learning/- Smart learning system (auto mode)node/- Node management and health trackingrule/- Rule matching enginedns/- DNS server and resolution
-
Error Handling
- Use typed errors from
src/core/error.rs - Avoid
anyhow::bail!in library code - Let callers decide presentation
- Use typed errors from
-
Configuration
- All runtime constants should be configurable
- Use
Arc<Runtime>for shared configuration - Defaults defined in
types/config/
-
Testing
- Unit tests:
cargo test - E2E tests:
pnpm test(vitest) - Real network tests require
PROXY_E2E_REAL=1
- Unit tests:
MIT