Naive — sing-box
Naive is a TCP/HTTP-mux proxy designed to look like ordinary HTTPS or HTTP/3 traffic. sing-box implements both sides and adds direct knobs for the bundled quiche QUIC stack's congestion controller and flow-control windows.
Inbound
type: "naive":
| Field | Type | Default | Allowed values | Description |
|---|---|---|---|---|
users | []auth.User | [] | [{username, password}] | Accepted users. |
network | NetworkList | (tcp+udp) | tcp | udp | | Restrict to TCP-only or UDP-only. |
quic_congestion_control | string | bbr | bbr | cubic | reno | Congestion controller for the HTTP/3 (QUIC) listener: bbr (default; empty means bbr), cubic or reno. Any other value fails at startup. |
Source: option/naive.go:9-15 · pinned at v1.14.2 (af6e64c)
The struct embeds ListenOptions and InboundTLSOptionsContainer. A TLS configuration is required — Naive is always TLS-wrapped on the wire.
Outbound
type: "naive":
| Field | Type | Default | Allowed values | Description |
|---|---|---|---|---|
username | string | (unset) | <string> | Upstream-proxy auth username. |
password | string | (unset) | <string> | Upstream-proxy auth password. |
insecure_concurrency | int | 0 | <int> | Number of concurrent HTTP/2 streams allowed per connection. 0 uses the stack default. |
extra_headers | badoption.HTTPHeader | {} | {<header>: <value or list>} | Extra headers added to every request. |
stream_receive_window | *byteformats.MemoryBytes | (stack default) | <bytes / MiB / GiB> | Per-stream flow-control window. Suffixed strings like "4MiB" are accepted. |
udp_over_tcp | *UDPOverTCPOptions | (disabled) | UDPOverTCPOptions | Wrap UDP packets inside the TCP-style Naive stream when the upstream does not speak QUIC datagrams. |
quic | bool | false | true | false | Use HTTP/3 (QUIC) instead of HTTP/2 as the transport. The server must support both for clients to fall back correctly. |
quic_congestion_control | string | (stack default) | bbr | bbr2 | cubic | reno | Congestion controller the client's QUIC stack uses when quic is true: bbr (BBRv1), bbr2, cubic or reno. Empty keeps the stack default; any other value fails at startup. |
quic_session_receive_window | *byteformats.MemoryBytes | (stack default) | <bytes / MiB / GiB> | Per-session (not per-stream) QUIC flow-control window. |
Source: option/naive.go:17-30 · pinned at v1.14.2 (af6e64c)
Embeds DialerOptions, ServerOptions, and OutboundTLSOptionsContainer.
Examples
Inbound (HTTP/2 over TLS):
json
{
"inbounds": [
{
"type": "naive",
"tag": "naive-in",
"listen": "::",
"listen_port": 443,
"users": [{ "username": "alice", "password": "<password>" }],
"tls": {
"enabled": true,
"alpn": ["h2", "http/1.1"],
"certificate_path": "/etc/ssl/cert.pem",
"key_path": "/etc/ssl/key.pem"
}
}
]
}Outbound switching to HTTP/3 with BBRv2 congestion control:
json
{
"outbounds": [
{
"type": "naive",
"tag": "naive-out",
"server": "example.com",
"server_port": 443,
"username": "alice",
"password": "<password>",
"quic": true,
"quic_congestion_control": "bbr2",
"quic_session_receive_window": "16MiB",
"tls": {
"enabled": true,
"server_name": "example.com",
"alpn": ["h3", "h2", "http/1.1"]
}
}
]
}Notes
quic_congestion_controltakes lowercase names. The outbound (Cronet QUIC client) acceptsbbr,bbr2,cubicandreno; the inbound (HTTP/3 listener) acceptsbbr,cubicandreno, withbbras its default. The quiche 4-letter codes (TBBR,B2ON,QBIC,RENO) are not accepted.stream_receive_windowandquic_session_receive_windowaccept suffixed byte literals via thebyteformats.MemoryBytesparser —"4MiB","16MiB","1GiB". Plain integers are treated as raw bytes.insecure_concurrencyis the original Naive client's experimental multi-stream flag. Setting it above ~8 typically gives no further speedup but does cost more memory per connection.- The
udp_over_tcpshape is the same as the Shadowsocks / TUIC variant —{enabled, version}.
Cross-core notes
- Xray-core does not implement Naive. See Naive — Xray-core.
- mihomo does not implement Naive. See Naive — mihomo.
Source: option/naive.go:9-30 · v1.14.2 (af6e64c)
