mirror of
https://github.com/cfal/shoes.git
synced 2026-11-06 16:14:11 +00:00
ee38ccc51a58ef5d8fdca22c8f69f3a0adb73034
* tun/tcp_stack_direct.rs: separate bounded ingress processing from TCP egress Process each incoming packet without repeatedly scanning every socket for egress. Give each socket one egress turn per iteration and recheck actionable bridge work before waiting. Reconcile timer-driven closures after egress, while retaining pending reset tuples, and use a monotonic clock for stack deadlines. * tun: wake the stack on TCP and UDP work instead of polling Poll the TUN descriptor together with a coalescing Unix wake socket. Notify after publishing TCP buffer changes, UDP responses, setup and shutdown, then acknowledge notifications before consuming shared work. Preserve timer deadlines and bounded queue draining so idle stacks no longer need a 10-ms fallback. Propagate wake and thread startup failures to the caller. * tun: carry owned UDP payloads through forwarding queues Move packet storage through ingress, parsing and both destination queues instead of copying full packets and payloads. Preserve payload-byte limit semantics by compacting explicitly capped packets, and compact oversized backing storage even without a cap. Reuse bounded pooled storage for packet construction, remove the redundant response copy, and test parsing, queue rejection and permit lifetime through flush, timeout and cancellation. * tun/tcp_stack_direct.rs: reuse transmit storage and preserve packet-atomic writes Borrow one initialized scratch buffer from the stack device for TCP egress. Write packet information and payload with one writev instead of allocating a framed copy. Retry complete packets only after EINTR. Treat short writes as errors rather than emitting a malformed suffix packet, while preserving EAGAIN and ENOBUFS drops. Cover buffer reuse, framing and injected syscall outcomes. * tun/tcp_stack_direct.rs: refresh late TCP handler setup before publishing connections A SYN may arrive after the loop snapshots setup but after another thread has already published its handler. Refresh an absent sender at connection publication so that this race does not abandon and reset a valid connection. Add a deterministic snapshot/publication interleaving regression. * tun/tcp_stack_direct.rs: amortize TCP egress across bounded complete sweeps A single packet per socket per outer iteration raised loop overhead and regressed bulk TCP in shipping-profile benchmarks. Allow up to eight complete sweeps, stopping on no progress, before reconciling sockets and revisiting ingress and wakeups. This keeps every socket eligible in each sweep, including late-index resets, without restoring an unbounded drain. Matched trials recovered throughput while preserving sparse-response latency. * tun/wake.rs: assert progress while saturating the wake socket Check successful write lengths in the saturation regression instead of ignoring them. This catches zero-progress writes and keeps the test compliant with Clippy while preserving its partial-write behavior. * tun: simplify packet handling and polling control flow Flatten UDP reader and direct-device receive paths, and make the stack's continue-before-wait decision explicit. Name the existing egress sweep bound and TCP/ICMP queue, and reuse pure size and state calculations. Keep wake ordering, ownership, control checks, error reporting, and batch limits unchanged. Add deterministic reader coverage for invalid packets followed by Pending, valid delivery, and EOF.
shoes
shoes is a high-performance multi-protocol proxy server written in Rust.
Supported Protocols
Proxy Protocols
- HTTP/HTTPS
- SOCKS5 (with UDP ASSOCIATE)
- Mixed (auto-detect HTTP/SOCKS5)
- VMess AEAD
- VLESS (with fallback support)
- Shadowsocks
- Trojan
- Snell v3
- Hysteria2
- TUIC v5
- AnyTLS
- NaiveProxy
- H2MUX (supported with VMess, VLESS, Trojan, Shadowsocks, Snell)
Transport Protocols
All server protocols plus:
- SagerNet UDP over TCP (for Shadowsocks, SOCKS5, AnyTLS, NaiveProxy)
- ShadowTLS v3
- TLS
- WebSocket (Shadowsocks SIP003)
- XTLS Reality
- XTLS Vision (for VLESS)
TUN/VPN Mode
- TUN device support - Layer 3 VPN for transparent proxying
- Supported platforms: Linux, Android, iOS
Supported Ciphers
- VMess:
aes-128-gcm,chacha20-poly1305,none - Shadowsocks:
aes-128-gcm,aes-256-gcm,chacha20-ietf-poly1305,2022-blake3-aes-128-gcm,2022-blake3-aes-256-gcm,2022-blake3-chacha20-ietf-poly1305 - Snell v3:
aes-128-gcm,aes-256-gcm,chacha20-ietf-poly1305
Features
- Multi-transport: TCP or QUIC for all protocols
- TLS with SNI routing: Route by Server Name Indication
- Upstream proxy chaining: Multi-hop chains with load balancing
- Rule-based routing: Route by IP/CIDR or hostname masks
- Named PEM certificates: Define once, reference everywhere
- TLS fingerprint authentication: Certificate pinning for TLS/QUIC
- Hot reloading: Apply config changes without restart
- Unix socket support: Bind to Unix domain sockets
For advanced access control (IP allowlist/blocklists), see tobaru.
Installation
Precompiled binaries for x86_64 and Apple aarch64 are available on Github Releases.
Or install with cargo:
cargo install shoes
Usage
shoes [OPTIONS] <config.yaml> [config.yaml...]
OPTIONS:
-t, --threads NUM Set the number of worker threads (default: CPU count)
-d, --dry-run Parse the config and exit
--no-reload Disable automatic config reloading on file changes
COMMANDS:
generate-reality-keypair Generate a new Reality X25519 keypair
generate-shadowsocks-2022-password <cipher> Generate a Shadowsocks password
Examples
# Run with a single config file
shoes config.yaml
# Run with multiple config files
shoes server1.yaml server2.yaml rules.yaml
# Run with custom thread count
shoes --threads 8 config.yaml
# Validate configuration without starting
shoes --dry-run config.yaml
# Run without hot-reloading
shoes --no-reload config.yaml
# Generate Reality keypair
shoes generate-reality-keypair
# Generate Shadowsocks 2022 cipher password
shoes generate-shadowsocks-2022-password 2022-blake3-aes-256-gcm
Configuration
See CONFIG.md for the complete YAML configuration reference.
Examples
See the examples directory for all examples.
Basic VMess Server
- address: 0.0.0.0:16823
protocol:
type: vmess
cipher: chacha20-poly1305
user_id: b0e80a62-8a51-47f0-91f1-f0f7faf8d9d4
udp_enabled: true
VLESS with Vision over TLS
- address: 0.0.0.0:443
protocol:
type: tls
tls_targets:
"vless.example.com":
cert: cert.pem
key: key.pem
vision: true
alpn_protocols: ["http/1.1"]
protocol:
type: vless
user_id: b85798ef-e9dc-46a4-9a87-8da4499d36d0
udp_enabled: true
Reality Server
- address: 0.0.0.0:443
protocol:
type: tls
reality_targets:
"www.example.com":
private_key: "YOUR_BASE64URL_PRIVATE_KEY"
short_ids: ["0123456789abcdef", ""]
dest: "www.example.com:443"
protocol:
type: vless
user_id: b85798ef-e9dc-46a4-9a87-8da4499d36d0
udp_enabled: true
Reality Client
- address: 127.0.0.1:1080
protocol:
type: socks
rules:
- masks: "0.0.0.0/0"
action: allow
client_chain:
address: "server.example.com:443"
protocol:
type: reality
public_key: "SERVER_PUBLIC_KEY"
short_id: "0123456789abcdef"
sni_hostname: "www.example.com"
protocol:
type: vless
user_id: b85798ef-e9dc-46a4-9a87-8da4499d36d0
Hysteria2 Server
- address: 0.0.0.0:443
transport: quic
quic_settings:
cert: cert.pem
key: key.pem
alpn_protocols: ["h3"]
protocol:
type: hysteria2
password: supersecret
udp_enabled: true
TUIC v5 Server
- address: 0.0.0.0:443
transport: quic
quic_settings:
cert: cert.pem
key: key.pem
protocol:
type: tuic
uuid: d685aef3-b3c4-4932-9a9d-d0c2f6727dfa
password: supersecret
Mixed HTTP/SOCKS5 Server
- address: 0.0.0.0:7890
protocol:
type: mixed
username: myuser
password: mypassword
AnyTLS Server
- address: 0.0.0.0:443
protocol:
type: tls
tls_targets:
"anytls.example.com":
cert: cert.pem
key: key.pem
protocol:
type: anytls
users:
- name: user1
password: secret123
udp_enabled: true
NaiveProxy Server
- address: 0.0.0.0:443
protocol:
type: tls
tls_targets:
"naive.example.com":
cert: cert.pem
key: key.pem
alpn_protocols: ["h2"]
protocol:
type: naiveproxy
users:
- username: user1
password: secret123
padding: true
TUN VPN
- device_name: tun0
address: 10.0.0.1
netmask: 255.255.255.0
mtu: 1500
tcp_enabled: true
udp_enabled: true
rules:
- masks: "0.0.0.0/0"
action: allow
client_chain:
address: "proxy.example.com:443"
protocol:
type: tls
protocol:
type: vless
user_id: b85798ef-e9dc-46a4-9a87-8da4499d36d0
Similar Projects
Languages
Rust
98.7%
JavaScript
0.9%
Python
0.2%
RenderScript
0.1%