Expand Shadowsocks runtime compatibility
This commit is contained in:
parent
d1638726ca
commit
4d1f589280
167 changed files with 57173 additions and 1640 deletions
|
|
@ -134,7 +134,7 @@ The first packet-tunnel implementation follows the Mihomo adapter shape but keep
|
|||
- On Apple, node selection and refresh are applied to both the app-facing control daemon and, while connected, the packet-tunnel daemon over `burrow-packet-tunnel.sock`. The packet daemon swaps the active proxy outbound inside the existing packet bridge, so new TCP and UDP flows use the selected node without restarting the Network Extension. Existing flows may continue on the outbound they opened with until they close.
|
||||
- TCP and UDP packets are reconstructed with the existing smoltcp userspace stack.
|
||||
- Trojan TCP nodes are dialed over TLS and use Trojan TCP and UDP request framing directly.
|
||||
- Shadowsocks AEAD nodes are dialed directly for TCP and UDP using SIP004-style salt, HKDF subkeys, and AEAD chunks/datagrams.
|
||||
- Shadowsocks nodes are dialed directly for TCP and UDP through Burrow's Shadowsocks runtime adapter. `BEP-0012` refines the Mihomo-compatible Shadowsocks runtime path, including expanded cipher families, UDP gating, and staged plugin/UDP-over-TCP support.
|
||||
- Unsupported runtime transports such as Trojan `ws`/`grpc`, Shadowsocks plugins, and Shadowsocks UDP-over-TCP are still parsed and preserved from subscriptions, but they are rejected by runtime selection until those adapter transports are implemented. If no node is explicitly selected, Burrow chooses the first runtime-supported node instead of starting an unsupported transport.
|
||||
- Apple SwiftUI and Linux GTK import flows preview nodes, restrict the picker to runtime-supported nodes, and pass the chosen node ordinal to the daemon when applying an import.
|
||||
- Proxy-subscription tunnel settings point DNS at the daemon-owned tunnel address. The packet runtime answers ordinary A queries with fake IPs and records the fake-IP to hostname mapping so later TCP flows can send hostname-form proxy requests. This avoids making website DNS depend on outbound UDP support while preserving hostname metadata for Trojan and Shadowsocks dialing.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,356 @@
|
|||
# `BEP-0012` - Mihomo-Compatible Shadowsocks Runtime
|
||||
|
||||
```text
|
||||
Status: Draft
|
||||
Proposal: BEP-0012
|
||||
Authors: Codex
|
||||
Coordinator: Jett Chen
|
||||
Reviewers: Pending
|
||||
Constitution Sections: 2, 4, 5
|
||||
Implementation PRs: Pending
|
||||
Decision Date: Pending
|
||||
```
|
||||
|
||||
## Summary
|
||||
|
||||
Burrow's proxy subscription runtime should move from a narrow hand-written
|
||||
Shadowsocks AEAD implementation toward Mihomo-compatible Shadowsocks behavior
|
||||
for imported nodes. Mihomo remains the reference for accepted ciphers, URI
|
||||
conversion, plugins, UDP-over-TCP, and packet tunnel outbound semantics, while
|
||||
Burrow keeps the daemon-owned packet runtime and Apple gRPC boundary described
|
||||
by `BEP-0005` and `BEP-0010`.
|
||||
|
||||
This proposal covers the compatibility path for Shadowsocks outbounds. It starts
|
||||
by delegating protocol crypto and stream/datagram framing to a maintained Rust
|
||||
Shadowsocks implementation, adds Burrow-owned adapters for Mihomo cipher gaps
|
||||
where Rust crates are available, and implements Mihomo-compatible UDP-over-TCP.
|
||||
Plugin transports remain staged behind explicit lifecycle and security controls.
|
||||
|
||||
## Motivation
|
||||
|
||||
- Subscriptions that work in Mihomo commonly use more than `aes-128-gcm`,
|
||||
`aes-256-gcm`, or `chacha20-ietf-poly1305`.
|
||||
- Mihomo supports legacy stream ciphers, AEAD extra ciphers, AEAD 2022 methods,
|
||||
SIP003-style plugins, ShadowTLS/restls/kcptun transports, and UDP-over-TCP.
|
||||
- Burrow's previous hand-written Shadowsocks runtime made unsupported ciphers
|
||||
appear like permanent product choices rather than implementation gaps.
|
||||
- Protocol crypto and framing are security-sensitive. Burrow should use a
|
||||
maintained Rust crate where it can do so without shelling out to Mihomo or
|
||||
weakening the daemon packet-runtime boundary.
|
||||
|
||||
## Detailed Design
|
||||
|
||||
- Use the Rust `shadowsocks` crate as Burrow's default Shadowsocks protocol
|
||||
adapter for supported cipher families, TCP stream framing, and UDP datagram
|
||||
framing.
|
||||
- Add Burrow-owned AEAD adapters backed by Rust crypto crates for Mihomo methods
|
||||
missing from the default adapter when their wire behavior is straightforward.
|
||||
The first such methods are `aes-192-gcm`, `aes-192-ccm`,
|
||||
`chacha8-ietf-poly1305`, `xchacha8-ietf-poly1305`, `rabbit128-poly1305`,
|
||||
`aegis-128l`, `aegis-256`, `aez-384`, `deoxys-ii-256-128`, `ascon128`,
|
||||
`ascon128a`, `lea-*-gcm`, `2022-blake3-aes-128-ccm`, and
|
||||
`2022-blake3-aes-256-ccm`.
|
||||
- Add Burrow-owned legacy stream adapters for Mihomo's `chacha20` and
|
||||
`xchacha20` methods. They use the same Shadowsocks v1 IV-plus-stream shape as
|
||||
Mihomo's `sing-shadowsocks2` implementation, backed by Rust `chacha20`
|
||||
primitives.
|
||||
- Keep Burrow-owned socket creation, route exclusion, and Apple physical
|
||||
interface binding behavior. The Shadowsocks adapter wraps already-connected
|
||||
Burrow sockets where needed instead of taking over tunnel ownership.
|
||||
- Runtime-supported ciphers include the compiled Rust crate feature set:
|
||||
legacy stream methods, AEAD methods, AEAD extra methods, and AEAD 2022
|
||||
methods, plus an explicit Mihomo-compatible `none` transport, custom
|
||||
ChaCha20/XChaCha20 stream, AES-192 GCM/CCM, ChaCha8-Poly1305,
|
||||
Rabbit128-Poly1305, AEGIS, AEZ-384, Deoxys-II-256-128, Ascon128, Ascon128a,
|
||||
LEA-GCM, and AEAD 2022 AES-CCM adapters. `none` stays Burrow-owned because
|
||||
the upstream Rust crate accepts the method name during validation but cannot
|
||||
build a client runtime for it.
|
||||
AEAD 2022 password handling follows Mihomo's base64 key parsing rule:
|
||||
every decoded password segment must be exactly the method key length, with
|
||||
no hashing or truncation fallback for oversized material. Burrow pre-validates
|
||||
the delegated GCM/ChaCha 2022 methods so the upstream Rust adapter cannot
|
||||
accept unpadded key material that Mihomo's `base64.StdEncoding` would reject.
|
||||
Burrow keeps legacy aliases such as `aead_aes_128_gcm` and
|
||||
`chacha20-poly1305` for previously imported payloads.
|
||||
Burrow also preserves Mihomo's top-level Shadowsocks `smux` option during
|
||||
import. The packet runtime supports TCP and UDP `protocol: h2mux`, `protocol:
|
||||
smux`, and `protocol: yamux` paths for delegated standard ciphers, `none`, Burrow's custom ciphers,
|
||||
and AEAD 2022 CCM by dialing Mihomo's `sp.mux.sing-box.arpa:444` control
|
||||
destination through Shadowsocks, writing the sing-mux protocol preface, and
|
||||
opening mux streams with Mihomo's per-stream SOCKS destination request. Burrow
|
||||
also supports Mihomo's top-level sing-mux padding shape: the version 1 session
|
||||
preface carries a padding flag and 256-767 bytes of skipped padding, then the
|
||||
first 16 mux reads and writes are length-prefixed padded frames before the
|
||||
stream falls back to raw mux bytes. UDP-over-sing-mux uses Mihomo's packet
|
||||
stream shape: UDP stream flags, one SOCKS destination, one status byte, and
|
||||
length-prefixed datagrams. Brutal mode performs Mihomo's `_BrutalBwExchange`
|
||||
stream handshake and negotiates the same send-rate cap; OS-level TCP Brutal
|
||||
congestion control remains a runtime best-effort because it is
|
||||
Linux-kernel-module dependent in Mihomo and unavailable through every Burrow
|
||||
plugin wrapper.
|
||||
The remaining Mihomo compatibility gaps for Shadowsocks are advanced plugin
|
||||
transports and live interop coverage for additional external permutations,
|
||||
not base Shadowsocks cipher, UDP-over-TCP framing, or top-level sing-mux
|
||||
negotiation.
|
||||
- Honor the Shadowsocks `udp` flag at runtime. Clash/Mihomo YAML imports default
|
||||
omitted `udp` to false like Mihomo's `ShadowSocksOption` zero value, while
|
||||
`ss://` URI conversion keeps Mihomo's converter behavior of setting `udp` to
|
||||
true. UDP-disabled nodes must reject UDP sessions instead of silently
|
||||
attempting native UDP relay.
|
||||
- Honor `udp-over-tcp` for Shadowsocks nodes by opening a Shadowsocks TCP stream
|
||||
to Mihomo's UOT magic destination. Burrow supports both Mihomo's legacy
|
||||
version 1 destination, `sp.udp-over-tcp.arpa`, and version 2 destination,
|
||||
`sp.v2.udp-over-tcp.arpa`; absent or zero versions normalize to legacy v1 to
|
||||
match Mihomo config defaults. Runtime UDP sessions are allowed when
|
||||
`udp-over-tcp` is active even if native UDP is disabled, because packets are
|
||||
carried over the selected TCP plugin path instead of a native Shadowsocks UDP
|
||||
relay.
|
||||
- Support Mihomo's `obfs` plugin for HTTP and TLS simple-obfs by wrapping the
|
||||
already-connected TCP socket before the Shadowsocks stream handshake. Native
|
||||
UDP remains direct Shadowsocks UDP, while `udp-over-tcp` uses the same wrapped
|
||||
TCP path. The plugin mode must be explicit, matching Mihomo's `obfs` option
|
||||
decoder: simple-obfs accepts only `http` and `tls`. Burrow normalizes SIP002
|
||||
URI plugin names that contain `obfs` into Mihomo's YAML/runtime plugin name
|
||||
`obfs` during import only when the plugin string has semicolon-delimited
|
||||
SIP002 options; bare `ss://` plugin names and non-Mihomo-converted URI plugin
|
||||
names are ignored like Mihomo's converter. Daemon runtime and Apple usability
|
||||
checks intentionally require Mihomo's exact, case-sensitive plugin names. YAML
|
||||
`plugin: obfs-local`, `plugin: Obfs`, `plugin: shadowtls`, and other
|
||||
unrecognized plugin names therefore fall through to plain Shadowsocks like
|
||||
Mihomo's outbound constructor instead of being treated as supported plugin
|
||||
transports.
|
||||
- Support Mihomo's `v2ray-plugin` websocket mode, including the lightweight
|
||||
v2ray-plugin mux preface enabled by Mihomo's default `mux: true`, optional
|
||||
TLS, custom path, host, and `v2ray-http-upgrade` raw-upgrade mode. Burrow also supports Mihomo's
|
||||
`v2ray-http-upgrade-fast-open` behavior by returning the upgraded raw stream
|
||||
after sending the HTTP request and validating the 101 response on first read.
|
||||
Imported `ss://` v2ray-plugin strings preserve Mihomo's SIP002 aliases such
|
||||
as `obfs=websocket`, `obfs-host`, and bare `tls` flags, while also
|
||||
materializing Mihomo's converted `mode`, `host`, and boolean `tls` option
|
||||
shape.
|
||||
For websocket paths with Mihomo's `ed=` query option, Burrow removes `ed`
|
||||
from the request path and moves the first payload bytes into the
|
||||
`Sec-WebSocket-Protocol` header with unpadded URL-safe base64 encoding.
|
||||
When TLS is enabled, Burrow accepts Mihomo's `certificate` and `private-key`
|
||||
plugin options as a PEM client
|
||||
certificate/key pair for mTLS, and enforces Mihomo's `fingerprint`
|
||||
certificate pin option on both Rustls and Apple native TLS paths. Burrow also
|
||||
supports Mihomo's `ech-opts` for websocket TLS by passing inline ECH config
|
||||
lists to Rustls, or by resolving HTTPS records through the physical DNS
|
||||
resolver when `ech-opts.enable` is set without an inline config.
|
||||
- Support Mihomo's `gost-plugin` websocket mode, including the Go-smux client
|
||||
stream enabled by Mihomo's default `mux: true` and `mux=false` raw websocket
|
||||
mode. `v2ray-plugin` and `gost-plugin` require explicit `mode: websocket` or
|
||||
the imported `obfs=websocket` alias, because Mihomo rejects those plugin nodes
|
||||
when the mode field is omitted. TLS-enabled gost websocket nodes use the same
|
||||
Mihomo-compatible client certificate/key and certificate pin handling,
|
||||
including websocket ECH support.
|
||||
- Support Mihomo's `shadow-tls` plugin for versions 1, 2, and 3 by performing the
|
||||
cover TLS handshake in-process with Rustls, then exposing the post-handshake
|
||||
stream to the Shadowsocks adapter. Version 2 wraps application data in
|
||||
ShadowTLS application-data records and prepends the first client payload with
|
||||
the handshake HMAC, matching Mihomo's `sing-shadowtls` client behavior.
|
||||
Version 3 uses a ShadowTLS-capable Rustls fork for the ClientHello session ID
|
||||
HMAC, then verifies and emits the four-byte HMAC application-data frames used
|
||||
by Mihomo's `sing-shadowtls` v3 client. Version 1 follows Mihomo's option
|
||||
shape and does not require a plugin password.
|
||||
Burrow also parses and enforces Mihomo's ShadowTLS `fingerprint` certificate
|
||||
pin option and supports Mihomo's `certificate` and `private-key` mTLS client
|
||||
certificate options. `client-fingerprint` is preserved from subscriptions.
|
||||
ShadowTLS v1 ignores `client-fingerprint` like Mihomo because it always uses a
|
||||
normal TLS 1.2 handshake. For ShadowTLS v2/v3, unknown fingerprint names fall
|
||||
back to the normal TLS ClientHello, while names that Mihomo maps to uTLS
|
||||
profiles are rejected by the default runtime and Apple usability filter until
|
||||
Burrow has uTLS-style ClientHello impersonation. Burrow carries an optional
|
||||
`boring-browser-fingerprints` feature that wires ShadowTLS v2 active browser
|
||||
fingerprints through Rama's BoringSSL-backed embedded browser TLS profiles.
|
||||
ShadowTLS ALPN defaults to `h2,http/1.1` only when the option is absent;
|
||||
explicitly empty `alpn` remains empty like Mihomo's decoded option struct.
|
||||
The same feature also provides the ShadowTLS v3 browser-profile path by
|
||||
signing the first ClientHello record's 32-byte session ID before it reaches
|
||||
the wire, matching Mihomo's uTLS `SessionIDGenerator` shape. The BoringSSL
|
||||
browser-profile paths also load Mihomo-compatible `certificate` and
|
||||
`private-key` client-auth material, so ShadowTLS v2/v3 browser fingerprints
|
||||
and mTLS can be combined the same way Mihomo passes those options into
|
||||
`sing-shadowtls`. For ShadowTLS `client-fingerprint: random`, Burrow follows
|
||||
Mihomo's initial random selection shape by choosing one process-wide browser
|
||||
profile with the same chrome/safari/ios/firefox weights instead of re-rolling
|
||||
each connection. The ShadowTLS v2 browser-profile path also removes the
|
||||
`X25519MLKEM768` supported group before building the BoringSSL connector,
|
||||
matching Mihomo's v2-only workaround for servers that fail with that hybrid
|
||||
key-share. These paths are intentionally not default yet because they add
|
||||
a CMake/BoringSSL toolchain requirement, still need CI coverage, and still need
|
||||
live interop coverage. The optional browser-profile path covers Mihomo's
|
||||
common `chrome`, `firefox`, `safari`, `ios`, `android`, `edge`, `random`, and
|
||||
`safari16` names where Rama has matching embedded profiles; older fixed
|
||||
aliases such as `chrome120` and `firefox120` remain gated until Burrow has
|
||||
exact matching ClientHello profiles instead of approximate fallbacks.
|
||||
- Support Mihomo's `kcptun` plugin in-process with Rust KCP, snappy, and smux
|
||||
crates. Burrow parses Mihomo's kcptun option names and defaults, forces
|
||||
UDP-over-TCP for kcptun nodes like Mihomo, and opens Shadowsocks TCP streams
|
||||
over KCP plus optional snappy plus smux. Burrow maintains a Mihomo-style
|
||||
round-robin smux session pool for `conn` and rotates expired sessions using
|
||||
`autoexpire` plus delayed `scavengettl` cleanup. Burrow mirrors Mihomo's smux
|
||||
keepalive timeout shape: the default timeout remains 30 seconds unless the
|
||||
keepalive interval is at least that value, in which case timeout becomes three
|
||||
times the interval. Burrow also applies Mihomo-style best-effort `dscp` and
|
||||
`sockbuf` settings to the underlying UDP socket. For `ratelimit`, Burrow
|
||||
honors Mihomo's bytes-per-second value with
|
||||
the same `64 * 1500` byte burst shape at the KCP stream boundary; this is the
|
||||
closest in-process equivalent available through the selected Rust KCP crate,
|
||||
which does not expose kcp-go's exact queued UDP packet transmit hook.
|
||||
- Plugin support landed in stages and must stay covered:
|
||||
- `obfs`, matching Mihomo URI conversion and option shapes for
|
||||
`mode`/`obfs`, `host`/`obfs-host`, and the default `bing.com` host.
|
||||
- `v2ray-plugin` websocket and its lightweight mux.
|
||||
- `gost-plugin` websocket and smux.
|
||||
- TLS client certificate/key support for websocket plugins and `shadow-tls`
|
||||
v1/v2.
|
||||
- `kcptun` with Rust KCP, snappy, and smux transport code.
|
||||
- ShadowTLS v3 with a Rustls fork that exposes the session ID generator
|
||||
required by the protocol.
|
||||
- Websocket `ech-opts` on Rustls-backed TLS paths.
|
||||
- `v2ray-http-upgrade-fast-open` for v2ray-plugin raw upgrade mode.
|
||||
- Websocket early data via the `ed=` path query option.
|
||||
- `restls` after its TLS ClientHello, authentication, and traffic-shaping
|
||||
behavior are mapped to audited Rust code. Burrow now parses Mihomo's
|
||||
`restls` option shape, including `host`, `password`, `version-hint`,
|
||||
`restls-script`, top-level `client-fingerprint` preservation, Mihomo's
|
||||
case-sensitive Restls client ID lookup with Chrome fallback, Mihomo's TLS
|
||||
1.3 session ticket disablement rule, and the BLAKE3-derived traffic secret.
|
||||
The default runtime still rejects non-`none` uTLS fingerprints, while the
|
||||
optional `boring-browser-fingerprints` feature can run TLS 1.3 Restls over a
|
||||
BoringSSL-backed browser profile and signs the first ClientHello record's
|
||||
session ID using Mihomo's Restls TLS 1.3 auth material. It also
|
||||
ports and tests Mihomo's BLAKE3-authenticated ClientHello session-ID
|
||||
material for TLS 1.2 and TLS 1.3, extraction of TLS 1.3 key-share and PSK
|
||||
identity labels from the serialized ClientHello shape exposed by Burrow's
|
||||
Rustls session-ID hook, the server-auth record unmasking offsets, a
|
||||
handshake stream shim that captures ServerHello random, unmasks the first
|
||||
server-auth record, and captures the encrypted ClientFinished record for
|
||||
later application-data authentication, the application-data record header,
|
||||
masked length/command bytes, one-shot ClientFinished binding on the first
|
||||
client application record,
|
||||
script-driven padding target, TLS 1.2 GCM explicit counter shape, Mihomo's
|
||||
signed one-byte response-interrupt count behavior, and the post-auth stream
|
||||
state machine for buffering blocked writes, resuming them after server data,
|
||||
and emitting response-interrupt records. The Restls
|
||||
post-handshake state machine is also covered by an async stream wrapper that
|
||||
turns user writes into authenticated TLS application-data records, decodes
|
||||
server records back into plaintext reads, and flushes resumed uploads plus
|
||||
response-interrupt records before surfacing server plaintext. Burrow now
|
||||
wires TLS 1.3 Restls nodes into the Shadowsocks outbound path through the
|
||||
Rustls session-ID hook, the server-auth handshake shim, and the async Restls
|
||||
stream wrapper. Burrow vendors the ShadowTLS Rustls fork and its Tokio
|
||||
adapter so TLS 1.2 Restls can pre-generate the ECDHE keys used in Mihomo's
|
||||
session-ID HMAC material and then reuse the matching private key when
|
||||
emitting ClientKeyExchange. TLS 1.2 Restls nodes are now accepted by runtime
|
||||
support checks, surfaced as selectable Apple subscription nodes, and use the
|
||||
TLS 1.2 GCM Restls application-record codec.
|
||||
Restls still needs end-to-end interop coverage before it can be claimed as
|
||||
full Mihomo parity.
|
||||
- `Scripts/burrow-proxy-selftest` exercises daemon packet streaming against a
|
||||
controlled local Trojan/Shadowsocks harness and asserts observed TCP, native
|
||||
UDP, legacy UDP-over-TCP, version 2 UDP-over-TCP, simple-obfs HTTP/TLS,
|
||||
v2ray HTTP-upgrade/websocket/mux/early-data, and gost raw websocket shapes.
|
||||
- `Scripts/burrow-shadowsocks-singmux-interop` drives Burrow's daemon against a
|
||||
temporary Go peer built from Mihomo's `github.com/metacubex/sing-mux` module
|
||||
and asserts top-level Shadowsocks `smux`, `yamux`, and `h2mux` TCP and UDP
|
||||
behavior through the daemon with both unpadded and padded sing-mux sessions,
|
||||
including the `sp.mux.sing-box.arpa:444` control destination, per-stream TCP
|
||||
destination metadata, UDP packet destination metadata, and UDP packet echo
|
||||
delivery. The interop matrix intentionally leaves the underlying Shadowsocks
|
||||
`udp` flag false so Burrow matches Mihomo's behavior: top-level sing-mux
|
||||
carries UDP unless `only-tcp` is set.
|
||||
Remaining compatibility evidence still needs live interop against full
|
||||
Mihomo/sing-box deployments for plugin combinations that the local harness
|
||||
does not cover, especially Restls post-handshake behavior and
|
||||
kernel-dependent TCP Brutal socket behavior.
|
||||
- Keep UDP-over-TCP packet framing compatible with Mihomo's
|
||||
`udp-over-tcp-version` handling, including the version 2 request prefix and
|
||||
per-packet address framing.
|
||||
- UI runtime-support checks must not hard-code stale cipher lists that disagree
|
||||
with the daemon. When local decoding is unavoidable, the local list must be
|
||||
updated with the daemon-supported cipher families or replaced with daemon
|
||||
preview/list-node data.
|
||||
|
||||
## Security and Operational Considerations
|
||||
|
||||
- Shadowsocks passwords and subscription URLs remain secrets. Error messages and
|
||||
logs must not include decoded credentials or bearer tokens.
|
||||
- Plugin support must stay within Burrow's daemon-owned socket lifecycle unless
|
||||
a later BEP explicitly introduces subprocess management. Shelling out to
|
||||
SIP003 plugins would add lifecycle and supply-chain risk and must include
|
||||
teardown and selected-network scoping if introduced.
|
||||
- `none` and legacy stream methods exist for compatibility, not as a security
|
||||
recommendation. UI warnings may be added later for weak ciphers without
|
||||
rejecting Mihomo-compatible imports.
|
||||
- AEAD 2022 passwords may be encoded keys. Validation must report malformed keys
|
||||
without logging the raw password.
|
||||
- Rollback is a code rollback plus re-importing affected subscriptions if stored
|
||||
payload shape changes.
|
||||
|
||||
## Contributor Playbook
|
||||
|
||||
1. Compare behavior against `/Users/jettchen/dev/vpn-ref/mihomo` on the `Alpha`
|
||||
branch before changing Shadowsocks protocol semantics.
|
||||
2. Keep Apple UI subscription operations behind daemon gRPC.
|
||||
3. Prefer maintained Rust crates for Shadowsocks crypto/framing rather than
|
||||
hand-rolled protocol code.
|
||||
4. Preserve Burrow socket binding and proxy-server route exclusion behavior.
|
||||
5. Add tests for each parity expansion:
|
||||
- cipher acceptance and legacy aliases
|
||||
- `udp` gating
|
||||
- plugin parsing and runtime gating
|
||||
- UDP-over-TCP version handling and packet framing
|
||||
- AEAD 2022 TCP/UDP packet framing for custom adapters
|
||||
- end-to-end local Shadowsocks TCP, native UDP, UDP-over-TCP, and plugin
|
||||
selftests; the proxy selftest must switch the daemon from a Trojan node to
|
||||
Shadowsocks nodes, prove both selected outbounds can carry a TCP probe,
|
||||
prove the selected Shadowsocks outbounds can carry native UDP, legacy
|
||||
UDP-over-TCP, and version 2 UDP-over-TCP echo probes, and prove the
|
||||
simple-obfs HTTP/TLS plugins, v2ray-plugin websocket/default-mux/
|
||||
HTTP-upgrade/early-data modes, and gost-plugin raw websocket mode wrap
|
||||
selected Shadowsocks TCP probes
|
||||
- top-level sing-mux Shadowsocks TCP and UDP interop against Mihomo's Go
|
||||
`sing-mux` module
|
||||
6. Run:
|
||||
|
||||
```bash
|
||||
uv run python Scripts/check-bep-metadata.py
|
||||
cargo fmt -p burrow
|
||||
cargo test -p burrow proxy_subscription::tests::
|
||||
cargo test -p burrow proxy_runtime::tests::
|
||||
cargo check -p burrow
|
||||
Scripts/burrow-proxy-selftest
|
||||
Scripts/burrow-shadowsocks-singmux-interop
|
||||
```
|
||||
|
||||
## Alternatives Considered
|
||||
|
||||
- Keep the hand-written AEAD-only implementation. Rejected because it locks
|
||||
Burrow into a narrow subset and makes Mihomo parity much slower.
|
||||
- Shell out to Mihomo. Rejected for the same reasons recorded in `BEP-0010`:
|
||||
Burrow would inherit a separate runtime, control plane, and lifecycle surface.
|
||||
- Implement plugins before cipher parity. Rejected because cipher parity is a
|
||||
lower-risk foundation and reduces custom crypto code first.
|
||||
|
||||
## Impact on Other Work
|
||||
|
||||
- Refines the Shadowsocks runtime portion of `BEP-0010`.
|
||||
- Complements `BEP-0011`, which covers Trojan-specific Mihomo compatibility.
|
||||
- Future plugin work may require a dedicated subprocess lifecycle BEP if the
|
||||
runtime cannot stay within the existing daemon teardown model.
|
||||
|
||||
## Decision
|
||||
|
||||
Pending review.
|
||||
|
||||
## References
|
||||
|
||||
- `evolution/proposals/BEP-0005-daemon-ipc-and-apple-boundary.md`
|
||||
- `evolution/proposals/BEP-0010-proxy-subscriptions-as-packet-tunnel-networks.md`
|
||||
- `evolution/proposals/BEP-0011-mihomo-compatible-trojan-runtime.md`
|
||||
- `/Users/jettchen/dev/vpn-ref/mihomo/adapter/outbound/shadowsocks.go`
|
||||
- `/Users/jettchen/dev/vpn-ref/mihomo/common/convert/converter.go`
|
||||
- Rust `shadowsocks` crate: https://crates.io/crates/shadowsocks
|
||||
Loading…
Add table
Add a link
Reference in a new issue