sbr

features

The details behind each of these are in the README, which also lists what is not supported yet.

configuration

sbr takes a sing-box JSON config as it is, with sing-box's flags: sbr run -c config.json, sbr check, and the rule-set compile, decompile, match and format subcommands. Routing follows sing-box's rule semantics, and binary rule-sets (.srs v1–5) are read and written in sing-box's format.

The parser is as strict as sing-box's: an unknown field is an error reported with its JSON path. A field sing-box accepts and sbr has not implemented is also an error, unless it cannot change where traffic goes, in which case it is a warning. The app runs every profile through this parser when it is imported.

protocols

Also socks, http, direct, selector, urltest and detour chains, and the ws, httpupgrade, grpc and http transports. Each is tested against real sing-box servers, and REALITY, Vision, XHTTP and hysteria2 also against Xray-core and apernet hysteria.

browser tls fingerprints

Every TLS client over TCP (trojan, VLESS, VMess, the transports, ShadowTLS's camouflage handshake, AnyTLS and DNS over HTTPS) sends a browser's ClientHello by default, and utls.fingerprint picks which:

fingerprintsourceja4
chromeChrome 155, captured from the browsert13d1517h2_8daaf6152771_cb7bf5808d99
safari, ioscaptured from macOS 27 URLSessiont13d2013h2_a09f3c656075_7f0f34a4126d
firefoxFirefox 148t13d1715h2_5b57614c22b0_a54fffd0eb61

sing-box 1.14.4 and Xray 26.10 still send Chrome 133's ClientHello for chrome, which current Chrome no longer matches. Fingerprints sbr does not have are refused rather than mapped to another browser.

failover that sees blocking after the handshake

Censors now let a connection start and then stop it: Russia's TSPU freezes a flow after about 16–20 KB, and the GFW has reset all of TCP/443 for over an hour. A handshake still succeeds, so sing-box's urltest keeps choosing the dead server. sbr adds two checks to every urltest member without new config fields: a 64 KiB data probe after each latency probe, and passive detection of resets, unanswered requests and stalls in live traffic. A failing member is skipped for 120 s, doubling to 30 minutes on each relapse; stalled connections on it are closed so apps retry on the new path at once.

Probes to members that share a server are spaced 200–1200 ms apart and their period varies by up to 20%, so a profile with six identities on one server does not open six handshakes in the same millisecond on a fixed clock.

automatic clienthello fragmentation

When a TLS or REALITY handshake is reset before the server sends a byte, which is what SNI filtering looks like from the client, sbr retries it at once with the ClientHello split across TLS records, and then across TCP segments as well. The server name is cut inside every label, so no record or segment holds a whole label of it. The setting lasts until the network changes. fragment and record_fragment set it by hand, as in sing-box.

For QUIC, hysteria2 without Salamander and TUIC put the two halves of the server name in different Initial packets, as quic-go does.

dns failover

When a DNS server errors, times out or answers SERVFAIL or REFUSED, the query goes to the profile's next network resolver, after at most 4 s. The failed server is skipped for later queries and probed in the background, about once a minute, until it answers. sing-box does not fail over, so a profile whose first resolver is unreachable through the current path resolves nothing.

userspace tcp stack

sbr has its own TCP stack for the TUN, which the app uses on iOS and tvOS. Each segment crosses the kernel once instead of twice, which at MTU 1280 gave 1.5–1.75× the throughput of the kernel stack at about 40% less CPU per byte (benchmarks). An app's connect completes only once the outbound has connected, so a failed connect or a reject rule makes it fall back immediately. Buffers grow with use, idle connections hold none, and on iOS they are capped at 128 KiB per direction per connection and 8 MiB in total, inside the extension's memory limit. IPv4 and IPv6 fragments are reassembled, so a VPN nested inside the tunnel keeps working.

the app

On the command line, experimental.clash_api serves the endpoints yacd, metacubexd and zashboard use.