|
| 1 | +# Hysteria2 Gecko obfs — deferral note |
| 2 | + |
| 3 | +Date: 2026-06-15 |
| 4 | +Status: **Deferred** (blocked on upstream availability) |
| 5 | + |
| 6 | +## Goal |
| 7 | +Add Hysteria2 "Gecko" QUIC obfuscation (from Hysteria app/v2.9.2) to this fork — |
| 8 | +`obfs.type=gecko` with `min_packet_size` / `max_packet_size`. |
| 9 | + |
| 10 | +## Why it is deferred |
| 11 | +Gecko obfs does **not** exist in any stable sing-box / sing-quic release, nor in this |
| 12 | +fork's pinned core. It currently lives only in pre-release code: |
| 13 | + |
| 14 | +| Component | This fork's pin | Where Gecko actually is | |
| 15 | +|---|---|---| |
| 16 | +| sing-box | `starifly/sing-box` @ `4998428…` = **1.12.19-neko-1** (Salamander only) | upstream **`v1.14.0-alpha.31`** (`Hysteria2ObfsGecko`, `Hysteria2ObfsTypeGecko`) | |
| 17 | +| sing-quic | `v0.5.2` (only `salamander.go`) | untagged commit **`9467ede27fb7`** (`hysteria2/gecko.go`), required by sing-box 1.14.0-alpha.31 (`sing-quic v0.6.2-0.20260525051024-9467ede27fb7`) | |
| 18 | + |
| 19 | +Verified (2026-06-15): |
| 20 | +- `option/hysteria2.go` on sing-box `main` has **no** gecko reference; only `v1.14.0-alpha.31` does. |
| 21 | +- sing-quic tags up to `v0.6.1` / `main` contain only `salamander.go`; `gecko.go` appears |
| 22 | + only in commit `9467ede27fb7`. |
| 23 | +- The runtime obfuscator lives in sing-quic, not sing-box — so this is a sing-quic feature, |
| 24 | + not just a sing-box option struct. |
| 25 | + |
| 26 | +## Options considered |
| 27 | +- **A. Pin to upstream sing-box 1.14.0-alpha.31** — rejected. Switches from |
| 28 | + `starifly/sing-box` to upstream, dropping all starifly protocol additions (Snell, |
| 29 | + Juicity, AnyTLS/AnyReality, ShadowsocksR, XHTTP, mux extensions) and shipping on an alpha. |
| 30 | +- **B. Backport `gecko.go` into a forked sing-quic + bump sing-quic 0.5.2→0.6.x inside |
| 31 | + starifly/sing-box** — rejected for now. Large cross-repo Go effort (sing-quic 0.5→0.6 |
| 32 | + changed QUIC internals), high regression risk to Hysteria2/TUIC, and adds a forked |
| 33 | + sing-quic to maintain. |
| 34 | +- **C. Defer** — chosen. Wait until Gecko lands in a stable `starifly/sing-box` (or upstream |
| 35 | + sing-box stable that starifly rebases onto). Then it becomes a clean pin bump plus a small |
| 36 | + Android UI change. |
| 37 | + |
| 38 | +## When Gecko becomes available (future work) |
| 39 | +1. `core/singbox-gecko-base`: bump `COMMIT_SING_BOX` (and transitively sing-quic) in |
| 40 | + `buildScript/lib/core/get_source_env.sh` to a starifly commit that includes Gecko; |
| 41 | + rebuild `libcore.aar`; confirm a minimal `obfs.type=gecko` Hysteria2 outbound is accepted |
| 42 | + and existing Salamander/no-obfs profiles still work. |
| 43 | +2. `feature/hy2-gecko-obfs`: Android side — |
| 44 | + - `HysteriaBean`: add an obfs-type field + `geckoMinPacketSize` / `geckoMaxPacketSize` |
| 45 | + (bump the kryo serialization version, currently 7, with deserialize handling). |
| 46 | + - `HysteriaFmt.kt`: stop hardcoding `type="salamander"` (line ~330); branch on obfs type; |
| 47 | + emit `min_packet_size`/`max_packet_size` for gecko. |
| 48 | + - `SingBoxOptions.java`: extend `Hysteria2Obfs` (currently `type`+`password`) to carry the |
| 49 | + gecko packet-size fields, matching the core's schema at that version. |
| 50 | + - URI parse/build: handle `obfs=gecko`, `obfs-min-packet-size`, `obfs-max-packet-size`. |
| 51 | + - UI (`hysteria_preferences.xml` + `HysteriaSettingsActivity.kt`): add an obfs-type |
| 52 | + selector; show min/max only for gecko. |
| 53 | + - Validation: password required for salamander/gecko; `1 <= min <= max <= 2048`; |
| 54 | + defaults 512 / 1200. |
0 commit comments