Skip to content

fix(singbox): make shadowsocks ciphers, naive uTLS, and naive libcronet work - #104

Merged
loss-and-quick merged 4 commits into
mainfrom
fix/naive-cronet-ss-routing
Jun 22, 2026
Merged

fix(singbox): make shadowsocks ciphers, naive uTLS, and naive libcronet work#104
loss-and-quick merged 4 commits into
mainfrom
fix/naive-cronet-ss-routing

Conversation

@loss-and-quick

Copy link
Copy Markdown
Owner

Summary

Fixes three real, user-facing breakages in the sing-box data path that the config-validation harness (#103) surfaced by running generated configs through the real cores. All three meant a profile our UI happily builds would fail to launch.

  1. shadowsocks cipher routingforced_core sent every shadowsocks profile to sing-box (its default tls.security is Tls), but sing-box implements neither plain, chacha20-poly1305 nor xchacha20-poly1305, so those profiles died with unknown method. Now the three Xray-only ciphers route to Xray (which does implement them); the 2022 AEAD ciphers and the IETF chacha variant stay on sing-box.

  2. naive uTLS — sing-box rejects a naive outbound that carries uTLS (uTLS is not supported on naive outbound), but a profile's default fingerprint made the builder emit it, so every naive profile failed to initialise. uTLS is now skipped for naive (as it already was for the QUIC outbounds). Reference fixture updated.

  3. libcronet shipping — even with (2) fixed, naive failed at runtime with cronet: library not found: the sing-box desktop release is a purego build that dlopen()s libcronet.{so,dll} from the sing-box binary's own directory. The library ships inside the sing-box release archive, but fetch-cores-desktop.sh extracted only the sing-box binary and dropped it. Now staged next to sing-box, bundled as a resource (mirroring wintun.dll), and copied into the portable zips.

After all three, the full enum-driven validation matrix (every protocol × transport × security × ss cipher) is accepted by the pinned cores — naive included.

Affected layer

  • frontend/ — React Web UI
  • crates/ · src-tauri/ — Rust core / backend / Tauri desktop
  • module/ — Android installable zip
  • scripts/ — build / release helpers
  • CI / .github/
  • Docs only

Verification

Rust (crates/ · src-tauri/):

  • cargo fmt --all --check
  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo test --workspace (incl. new shadowsocks_method_routing_splits_by_core + naive_outbound_omits_utls)
  • cargo run -p kasumi-desktop --bin codegen leaves git clean

Cores (manual, pinned versions):

  • fetch-cores-desktop.sh stages libcronet.so next to sing-box
  • With the fixes, the validation harness accepts all generated configs (naive/ss now pass on the real cores)

Checklist

  • Title is a scoped Conventional Commit; commits are logically split
  • No build artifacts committed (libcronet.{so,dll} stays gitignored under binaries/, staged at build time)
  • Generated frontend/src/generated/ regenerated from Rust, not hand-edited
  • User-visible strings: n/a
  • Project-id renames: n/a

Notes for reviewers

  • Bundle placement needs a real build to confirm, per the plan to verify via nightly: the portable zips put libcronet in a flat dir next to sing-box (reliable); for the installers (deb/AppImage/NSIS/MSI) it's added as a Tauri resource mirroring wintun.dll. If nightly shows the resource doesn't land in sing-box's directory on Linux (AppImage is self-contained, and cores are spawned with a cleared env so LD_LIBRARY_PATH won't help), the follow-up is to stage it into the core directory at runtime.
  • Android sing-box ships no libcronet (its release archive has only the binary), so naive on Android is out of scope here.
  • A separate tests PR (test(rust): widen unit coverage across core, backend, desktop #103) adds the validation harness; once this merges, that branch is rebased so its naive/ss cases validate with no skips.

forced_core sent every shadowsocks profile to sing-box (its default tls.security
is Tls), but sing-box implements neither `plain`, `chacha20-poly1305` nor
`xchacha20-poly1305` — those profiles failed to launch (`unknown method`). Route
the three Xray-only ciphers to Xray; keep the 2022 AEAD + IETF chacha on sing-box.

Surfaced by validating generated configs against the real cores.
sing-box rejects a naive outbound that carries uTLS (`uTLS is not supported on
naive outbound`), but a profile's default fingerprint made the builder emit it,
so every naive profile failed to initialise. Skip uTLS for naive (as already done
for the QUIC outbounds). Reference fixture updated.

Surfaced by validating generated configs against the real cores.
The sing-box desktop release is a purego build that dlopen()s libcronet from the
sing-box binary's own directory; without it every naive profile fails with
`cronet: library not found`. The library ships inside the sing-box release archive
but fetch-cores-desktop.sh dropped it.

Stage libcronet.{so,dll} next to sing-box (script), bundle it as a resource
(tauri.{windows,linux}.conf.json, mirroring wintun.dll), and copy it into the
portable zips. Bundle placement for the installers is verified by nightly.
@github-actions github-actions Bot added backend Rust core/backend/desktop (crates/, src-tauri/) ci CI / workflows (.github/) labels Jun 22, 2026
The new tauri.linux.conf.json / tauri.windows.conf.json libcronet resources are
validated by tauri-build at compile time, but the compile-smoke jobs (rust nix
clippy/codegen, desktop-linux, desktop-windows) don't stage the cores — so the
build failed with 'resource path binaries/libcronet.{so,dll} doesn't exist'.

Stub a placeholder before each compile, mirroring the existing wintun.dll stub.
@loss-and-quick
loss-and-quick merged commit 83c876d into main Jun 22, 2026
8 checks passed
@loss-and-quick
loss-and-quick deleted the fix/naive-cronet-ss-routing branch June 22, 2026 17:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend Rust core/backend/desktop (crates/, src-tauri/) ci CI / workflows (.github/)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant