Bump sing-quic pin; drop the Hysteria2 client binary#113
Conversation
Bump the sing-quic replace pin to the current hawkff HEAD (configurable BBR profiles, random hop interval, shared QUIC options, realm support, gecko obfs on the migrated base, and a salamander data-race fix; built on sing v0.8.10 + quic-go v0.59-mod.5). The shared-QUIC-options refactor moves the per-window / MTU knobs into qtls.QUICOptions; the matching sing-box change is pinned via COMMIT_SING_BOX. Hysteria2 (incl. gecko obfs) runs natively in the core, so the bundled client binary is no longer reachable. Remove its build step, env, cache-key segment and ABI checks across the workflows, the native-executable entry, the plugin mapping, the dead config builder, and the now-redundant external plugin branch. canUseSingBox() now routes all Hysteria2 to the native outbound and reserves the external path for the Hysteria1 transports. Hysteria1 support is unchanged.
📝 WalkthroughNote: range_5422f22f88d4 appears under dependency updates as the relevant standalone checkpoint. WalkthroughThis PR removes the Hysteria2 sidecar entirely: deletes the build script, removes the native plugin mapping and sidecar config generator, simplifies Hysteria plugin/protocol selection logic, drops libhysteria2.so from process termination and CI verification, and updates GitHub/Depot CI workflows. It also bumps pinned sing-box and sing-quic dependency versions. ChangesHysteria2 Sidecar Removal
Dependency Pin Updates
Sequence Diagram(s)Not applicable — these changes are configuration/build-pipeline removals and simplification of conditional logic, not new multi-component control flow. Estimated code review effort🎯 2 (Simple) | ⏱️ ~15 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@app/src/main/java/io/nekohasekai/sagernet/fmt/hysteria/HysteriaFmt.kt`:
- Around line 378-383: Hysteria2 is now routed through the native sing-box
outbound, but Hysteria2-specific profile fields are still being parsed and shown
without being serialized. Update the Hysteria2 builder in HysteriaFmt/Hysteria2
to either emit disableMtuDiscovery, streamReceiveWindow, and
connectionReceiveWindow into the native outbound config or clear/hide those
settings before they reach that path, so the values are not silently dropped
when canUseSingBox() returns true for protocolVersion == 2.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 0faa0a74-76b5-4712-93f0-9f02cab39bb7
⛔ Files ignored due to path filters (1)
libcore/go.sumis excluded by!**/*.sum
📒 Files selected for processing (12)
.depot/workflows/build-apk.yml.github/workflows/build.yml.github/workflows/ci.yml.github/workflows/preview.yml.github/workflows/release.ymlapp/src/main/java/io/nekohasekai/sagernet/bg/Executable.ktapp/src/main/java/io/nekohasekai/sagernet/fmt/ConfigBuilder.ktapp/src/main/java/io/nekohasekai/sagernet/fmt/hysteria/HysteriaFmt.ktapp/src/main/java/io/nekohasekai/sagernet/plugin/PluginManager.ktbuildScript/lib/core/get_source_env.shbuildScript/lib/hysteria2.shlibcore/go.mod
💤 Files with no reviewable changes (3)
- app/src/main/java/io/nekohasekai/sagernet/plugin/PluginManager.kt
- buildScript/lib/hysteria2.sh
- app/src/main/java/io/nekohasekai/sagernet/bg/Executable.kt
| // Hysteria2 always uses the native sing-box outbound; the faketcp / wechat-video | ||
| // transports are a Hysteria1-only concept, and gecko obfs is handled natively by | ||
| // this fork's core (via the hawkff/sing-quic gecko backport). | ||
| if (protocolVersion == 2) return true | ||
| // Hysteria1 falls back to the external plugin for the non-UDP transports. | ||
| return protocol == HysteriaBean.PROTOCOL_UDP |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
fmt=$(fd -p 'HysteriaFmt.kt' app/src/main/java | head -n1)
bean=$(fd -p 'HysteriaBean.kt' app/src/main/java | head -n1)
proxy=$(fd -p 'ProxyEntity.kt' app/src/main/java | head -n1)
echo "=== canUseSingBox() and Hysteria2 outbound ==="
nl -ba "$fmt" | sed -n '377,480p'
echo
echo "=== Hysteria bean fields still present ==="
rg -n -C2 'disableMtuDiscovery|streamReceiveWindow|connectionReceiveWindow|protocolVersion' "$bean"
echo
echo "=== downstream needExternal() selection ==="
rg -n -C2 'TYPE_HYSTERIA|needExternal\(' "$proxy"
echo
echo "=== other references to the affected Hysteria fields ==="
rg -n -C2 'disableMtuDiscovery|streamReceiveWindow|connectionReceiveWindow' app/src/main/javaRepository: hawkff/NekoBoxForAndroid
Length of output: 249
🏁 Script executed:
#!/bin/bash
set -euo pipefail
fmt=$(fd -p 'HysteriaFmt.kt' app/src/main/java | head -n1)
bean=$(fd -p 'HysteriaBean.kt' app/src/main/java | head -n1)
proxy=$(fd -p 'ProxyEntity.kt' app/src/main/java | head -n1)
echo "FMT=$fmt"
echo "BEAN=$bean"
echo "PROXY=$proxy"
echo
echo "=== HysteriaFmt.kt relevant section ==="
sed -n '370,490p' "$fmt"
echo
echo "=== HysteriaBean.kt relevant declarations ==="
sed -n '1,260p' "$bean"
echo
echo "=== ProxyEntity.kt relevant selection logic ==="
sed -n '330,390p' "$proxy"
echo
echo "=== Other references to affected fields ==="
rg -n -C2 'disableMtuDiscovery|streamReceiveWindow|connectionReceiveWindow' app/src/main/javaRepository: hawkff/NekoBoxForAndroid
Length of output: 5545
🏁 Script executed:
#!/bin/bash
set -euo pipefail
fmt=$(fd -p 'HysteriaFmt.kt' app/src/main/java | head -n1)
bean=$(fd -p 'HysteriaBean.kt' app/src/main/java | head -n1)
proxy=$(fd -p 'ProxyEntity.kt' app/src/main/java | head -n1)
printf 'FMT=%s\nBEAN=%s\nPROXY=%s\n' "$fmt" "$bean" "$proxy"
echo
echo "=== HysteriaFmt.kt relevant section ==="
sed -n '370,490p' "$fmt" | cat -n
echo
echo "=== HysteriaBean.kt relevant declarations ==="
sed -n '1,260p' "$bean" | cat -n
echo
echo "=== ProxyEntity.kt relevant selection logic ==="
sed -n '330,390p' "$proxy" | cat -n
echo
echo "=== Other references to affected fields ==="
rg -n -C2 'disableMtuDiscovery|streamReceiveWindow|connectionReceiveWindow' app/src/main/javaRepository: hawkff/NekoBoxForAndroid
Length of output: 6392
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Locate the bean definition and all references to the three fields.
bean=$(rg -l --hidden --glob '*.kt' 'class HysteriaBean|data class HysteriaBean' app/src/main/java | head -n1)
echo "BEAN=$bean"
echo
echo "=== Bean definition ==="
sed -n '1,260p' "$bean" | cat -n
echo
echo "=== Field references across the app ==="
rg -n -C2 'disableMtuDiscovery|streamReceiveWindow|connectionReceiveWindow' app/src/main/java
echo
echo "=== Hysteria-related UI / serialization references ==="
rg -n -C2 'Hysteria2|hysteria2ObfsType|disableMtuDiscovery|streamReceiveWindow|connectionReceiveWindow' app/src/main/javaRepository: hawkff/NekoBoxForAndroid
Length of output: 162
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Candidate Hysteria files ==="
fd -a -i 'hysteria' app/src/main/java
echo
echo "=== Definitions / references for the three fields ==="
rg -n -C2 'disableMtuDiscovery|streamReceiveWindow|connectionReceiveWindow' app/src/main/java
echo
echo "=== Hysteria bean class declarations ==="
rg -n -C2 'class HysteriaBean|data class HysteriaBean' app/src/main/javaRepository: hawkff/NekoBoxForAndroid
Length of output: 12480
Hysteria2 native path still drops profile settings
canUseSingBox() now sends every v2 profile through the native outbound, but the Hysteria2 builder still omits disableMtuDiscovery, streamReceiveWindow, and connectionReceiveWindow. Those values are still parsed, stored, and exposed in the UI, so they’ll be silently ignored for Hysteria2 profiles unless the native outbound starts serializing them or the fields are hidden/cleared first.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@app/src/main/java/io/nekohasekai/sagernet/fmt/hysteria/HysteriaFmt.kt` around
lines 378 - 383, Hysteria2 is now routed through the native sing-box outbound,
but Hysteria2-specific profile fields are still being parsed and shown without
being serialized. Update the Hysteria2 builder in HysteriaFmt/Hysteria2 to
either emit disableMtuDiscovery, streamReceiveWindow, and
connectionReceiveWindow into the native outbound config or clear/hide those
settings before they reach that path, so the values are not silently dropped
when canUseSingBox() returns true for protocolVersion == 2.
|
Declining this finding on merit (pre-existing, not a regression in this PR):
No code change needed. |
Summary
sing-quicreplace pin to the current hawkff HEAD. This pulls inconfigurable BBR profiles, a random hop interval, shared QUIC options, realm
support, gecko obfs on the migrated base, and a salamander data-race fix, built
on
sing v0.8.10+quic-go v0.59-mod.5.qtls.QUICOptions; the matching sing-box change is pinned viaCOMMIT_SING_BOX(
buildScript/lib/core/get_source_env.sh).core, so the binary is no longer reachable. Removed: the build step + env +
cache-key segment + ABI checks across all workflows, the native-executable
entry, the plugin mapping, the dead config builder, and the redundant external
plugin branch.
canUseSingBox()now routes all Hysteria2 to the native outbound and reservesthe external plugin path for the Hysteria1 transports. Hysteria1 support is
unchanged.
Testing
go mod tidyinlibcore/; the version triple is unchanged.:app:compileOssDebugKotlinandspotlessKotlinCheckpass.build-apkrun is green end-to-end: libcore built from sourceagainst the new pins (gomobile bind OK), sidecars built without the dropped
binary, app compiled + APK assembled and signed (BUILD SUCCESSFUL in ~3m).
instrumentation; test bodies pass, only teardown trips).
Notes
feat/sing-quic-shared-quic-options(adopts the shared QUIC options); pinned here via
COMMIT_SING_BOX.Greptile Summary
This PR drops the bundled Hysteria2 client binary (
libhysteria2.so) now that its functionality is handled natively by the sing-box core, and bumps thesing-quicreplace pin to pull in BBR profiles, a random hop interval, shared QUIC options, realm support, gecko obfs, and a salamander data-race fix.Executable.kt, andPluginManager.ktall have theirhysteria2/libhysteria2.soreferences removed; the deadbuildHysteria2SidecarConfigfunction is deleted.canUseSingBox()now explicitly returnstruefor all Hysteria2 beans (previously implicit becauseprotocolalways defaulted toPROTOCOL_UDPfor v2), andConfigBuilder.kthardcodes\"hysteria-plugin\"for theHysteriaBeanexternal-plugin branch (a code path only reachable for Hysteria1 non-UDP transports).libcore/go.modadvancessing-quictov0.6.2-0.20260630192917-42e8810bc4b8;get_source_env.shbumpsCOMMIT_SING_BOXto8bac84d6…(version1.13.13-10-g8bac84d6).Confidence Score: 5/5
All changes are self-consistent and fully tested according to the PR description; no functional regressions are expected.
The removal of the Hysteria2 sidecar is complete and consistent across all five workflow files, Executable.kt, PluginManager.kt, and the build scripts. The canUseSingBox() rewrite makes an implicit invariant (Hysteria2 always had protocol == PROTOCOL_UDP) explicit, producing identical runtime behaviour. The ConfigBuilder hardcoding of "hysteria-plugin" is safe because that branch is only reachable when needExternal() is true, which requires canUseSingBox() == false, which cannot happen for Hysteria2. Dead code (buildHysteria2SidecarConfig) is cleanly removed. The go.mod and sing-box commit pins advance together as a matched pair.
No files require special attention. The logic change in HysteriaFmt.kt is worth a quick read to confirm the canUseSingBox equivalence, but it is correct.
Important Files Changed
Reviews (1): Last reviewed commit: "core: bump sing-quic pin; drop the Hyste..." | Re-trigger Greptile