Full Code of SagerNet/sing-box for AI

testing c5bf6b3e71b6 cached
1022 files
3.6 MB
999.9k tokens
5675 symbols
1 requests
Download .txt
Showing preview only (3,979K chars total). Download the full file or copy to clipboard to get everything.
Repository: SagerNet/sing-box
Branch: testing
Commit: c5bf6b3e71b6
Files: 1022
Total size: 3.6 MB

Directory structure:
gitextract_d_trzmkv/

├── .fpm_openwrt
├── .fpm_pacman
├── .fpm_systemd
├── .github/
│   ├── CRONET_GO_VERSION
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.yml
│   │   └── bug_report_zh.yml
│   ├── build_alpine_apk.sh
│   ├── build_openwrt_apk.sh
│   ├── deb2ipk.sh
│   ├── renovate.json
│   ├── setup_go_for_macos1013.sh
│   ├── setup_go_for_windows7.sh
│   ├── update_clients.sh
│   ├── update_cronet.sh
│   ├── update_cronet_dev.sh
│   ├── update_dependencies.sh
│   └── workflows/
│       ├── build.yml
│       ├── docker.yml
│       ├── lint.yml
│       ├── linux.yml
│       └── stale.yml
├── .gitignore
├── .gitmodules
├── .golangci.yml
├── Dockerfile
├── Dockerfile.binary
├── LICENSE
├── Makefile
├── README.md
├── adapter/
│   ├── certificate.go
│   ├── connections.go
│   ├── dns.go
│   ├── endpoint/
│   │   ├── adapter.go
│   │   ├── manager.go
│   │   └── registry.go
│   ├── endpoint.go
│   ├── experimental.go
│   ├── fakeip.go
│   ├── fakeip_metadata.go
│   ├── handler.go
│   ├── inbound/
│   │   ├── adapter.go
│   │   ├── manager.go
│   │   └── registry.go
│   ├── inbound.go
│   ├── lifecycle.go
│   ├── lifecycle_legacy.go
│   ├── neighbor.go
│   ├── network.go
│   ├── outbound/
│   │   ├── adapter.go
│   │   ├── manager.go
│   │   └── registry.go
│   ├── outbound.go
│   ├── platform.go
│   ├── prestart.go
│   ├── router.go
│   ├── rule.go
│   ├── service/
│   │   ├── adapter.go
│   │   ├── manager.go
│   │   └── registry.go
│   ├── service.go
│   ├── ssm.go
│   ├── time.go
│   ├── upstream.go
│   ├── upstream_legacy.go
│   └── v2ray.go
├── box.go
├── cmd/
│   ├── internal/
│   │   ├── app_store_connect/
│   │   │   └── main.go
│   │   ├── build/
│   │   │   └── main.go
│   │   ├── build_libbox/
│   │   │   └── main.go
│   │   ├── build_shared/
│   │   │   ├── sdk.go
│   │   │   └── tag.go
│   │   ├── format_docs/
│   │   │   └── main.go
│   │   ├── protogen/
│   │   │   └── main.go
│   │   ├── read_tag/
│   │   │   └── main.go
│   │   ├── tun_bench/
│   │   │   └── main.go
│   │   ├── update_android_version/
│   │   │   └── main.go
│   │   ├── update_apple_version/
│   │   │   └── main.go
│   │   └── update_certificates/
│   │       └── main.go
│   └── sing-box/
│       ├── cmd.go
│       ├── cmd_check.go
│       ├── cmd_format.go
│       ├── cmd_generate.go
│       ├── cmd_generate_ech.go
│       ├── cmd_generate_tls.go
│       ├── cmd_generate_vapid.go
│       ├── cmd_generate_wireguard.go
│       ├── cmd_geoip.go
│       ├── cmd_geoip_export.go
│       ├── cmd_geoip_list.go
│       ├── cmd_geoip_lookup.go
│       ├── cmd_geosite.go
│       ├── cmd_geosite_export.go
│       ├── cmd_geosite_list.go
│       ├── cmd_geosite_lookup.go
│       ├── cmd_geosite_matcher.go
│       ├── cmd_merge.go
│       ├── cmd_rule_set.go
│       ├── cmd_rule_set_compile.go
│       ├── cmd_rule_set_convert.go
│       ├── cmd_rule_set_decompile.go
│       ├── cmd_rule_set_format.go
│       ├── cmd_rule_set_match.go
│       ├── cmd_rule_set_merge.go
│       ├── cmd_rule_set_upgrade.go
│       ├── cmd_run.go
│       ├── cmd_tools.go
│       ├── cmd_tools_connect.go
│       ├── cmd_tools_fetch.go
│       ├── cmd_tools_fetch_http3.go
│       ├── cmd_tools_fetch_http3_stub.go
│       ├── cmd_tools_synctime.go
│       ├── cmd_version.go
│       ├── generate_completions.go
│       └── main.go
├── common/
│   ├── badtls/
│   │   ├── raw_conn.go
│   │   ├── raw_half_conn.go
│   │   ├── read_wait.go
│   │   ├── read_wait_stub.go
│   │   ├── registry.go
│   │   └── registry_utls.go
│   ├── badversion/
│   │   ├── version.go
│   │   ├── version_json.go
│   │   └── version_test.go
│   ├── certificate/
│   │   ├── chrome.go
│   │   ├── mozilla.go
│   │   └── store.go
│   ├── compatible/
│   │   └── map.go
│   ├── convertor/
│   │   └── adguard/
│   │       ├── convertor.go
│   │       └── convertor_test.go
│   ├── dialer/
│   │   ├── default.go
│   │   ├── default_parallel_interface.go
│   │   ├── default_parallel_network.go
│   │   ├── detour.go
│   │   ├── dialer.go
│   │   ├── resolve.go
│   │   ├── router.go
│   │   ├── tfo.go
│   │   └── wireguard.go
│   ├── geoip/
│   │   └── reader.go
│   ├── geosite/
│   │   ├── compat_test.go
│   │   ├── geosite_test.go
│   │   ├── reader.go
│   │   ├── rule.go
│   │   └── writer.go
│   ├── interrupt/
│   │   ├── conn.go
│   │   ├── context.go
│   │   └── group.go
│   ├── ja3/
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── error.go
│   │   ├── ja3.go
│   │   └── parser.go
│   ├── ktls/
│   │   ├── ktls.go
│   │   ├── ktls_alert.go
│   │   ├── ktls_cipher_suites_linux.go
│   │   ├── ktls_close.go
│   │   ├── ktls_const.go
│   │   ├── ktls_handshake_messages.go
│   │   ├── ktls_key_update.go
│   │   ├── ktls_linux.go
│   │   ├── ktls_prf.go
│   │   ├── ktls_read.go
│   │   ├── ktls_read_wait.go
│   │   ├── ktls_stub_nolinkname.go
│   │   ├── ktls_stub_nonlinux.go
│   │   ├── ktls_stub_oldgo.go
│   │   └── ktls_write.go
│   ├── listener/
│   │   ├── listener.go
│   │   ├── listener_tcp.go
│   │   └── listener_udp.go
│   ├── mux/
│   │   ├── client.go
│   │   └── router.go
│   ├── pipelistener/
│   │   └── listener.go
│   ├── process/
│   │   ├── searcher.go
│   │   ├── searcher_android.go
│   │   ├── searcher_darwin.go
│   │   ├── searcher_linux.go
│   │   ├── searcher_linux_shared.go
│   │   ├── searcher_stub.go
│   │   └── searcher_windows.go
│   ├── redir/
│   │   ├── redir_darwin.go
│   │   ├── redir_linux.go
│   │   ├── redir_other.go
│   │   ├── tproxy_linux.go
│   │   └── tproxy_other.go
│   ├── settings/
│   │   ├── proxy_android.go
│   │   ├── proxy_darwin.go
│   │   ├── proxy_linux.go
│   │   ├── proxy_stub.go
│   │   ├── proxy_windows.go
│   │   ├── system_proxy.go
│   │   ├── wifi.go
│   │   ├── wifi_linux.go
│   │   ├── wifi_linux_connman.go
│   │   ├── wifi_linux_iwd.go
│   │   ├── wifi_linux_nm.go
│   │   ├── wifi_linux_wpa.go
│   │   ├── wifi_stub.go
│   │   └── wifi_windows.go
│   ├── sniff/
│   │   ├── bittorrent.go
│   │   ├── bittorrent_test.go
│   │   ├── dns.go
│   │   ├── dns_test.go
│   │   ├── dtls.go
│   │   ├── dtls_test.go
│   │   ├── http.go
│   │   ├── http_test.go
│   │   ├── internal/
│   │   │   └── qtls/
│   │   │       └── qtls.go
│   │   ├── ntp.go
│   │   ├── ntp_test.go
│   │   ├── quic.go
│   │   ├── quic_blacklist.go
│   │   ├── quic_capture_test.go
│   │   ├── quic_test.go
│   │   ├── rdp.go
│   │   ├── rdp_test.go
│   │   ├── sniff.go
│   │   ├── ssh.go
│   │   ├── ssh_test.go
│   │   ├── stun.go
│   │   ├── stun_test.go
│   │   └── tls.go
│   ├── srs/
│   │   ├── binary.go
│   │   ├── compat_test.go
│   │   ├── ip_cidr.go
│   │   └── ip_set.go
│   ├── taskmonitor/
│   │   └── monitor.go
│   ├── tls/
│   │   ├── acme.go
│   │   ├── acme_contstant.go
│   │   ├── acme_stub.go
│   │   ├── client.go
│   │   ├── common.go
│   │   ├── config.go
│   │   ├── ech.go
│   │   ├── ech_shared.go
│   │   ├── ech_tag_stub.go
│   │   ├── ktls.go
│   │   ├── mkcert.go
│   │   ├── reality_client.go
│   │   ├── reality_server.go
│   │   ├── reality_stub.go
│   │   ├── server.go
│   │   ├── std_client.go
│   │   ├── std_server.go
│   │   ├── time_wrapper.go
│   │   ├── utls_client.go
│   │   └── utls_stub.go
│   ├── tlsfragment/
│   │   ├── conn.go
│   │   ├── conn_test.go
│   │   ├── index.go
│   │   ├── index_test.go
│   │   ├── wait_darwin.go
│   │   ├── wait_linux.go
│   │   ├── wait_stub.go
│   │   └── wait_windows.go
│   ├── uot/
│   │   └── router.go
│   └── urltest/
│       └── urltest.go
├── constant/
│   ├── certificate.go
│   ├── cgo.go
│   ├── cgo_disabled.go
│   ├── dhcp.go
│   ├── dns.go
│   ├── err.go
│   ├── goos/
│   │   ├── gengoos.go
│   │   ├── goos.go
│   │   ├── zgoos_aix.go
│   │   ├── zgoos_android.go
│   │   ├── zgoos_darwin.go
│   │   ├── zgoos_dragonfly.go
│   │   ├── zgoos_freebsd.go
│   │   ├── zgoos_hurd.go
│   │   ├── zgoos_illumos.go
│   │   ├── zgoos_ios.go
│   │   ├── zgoos_js.go
│   │   ├── zgoos_linux.go
│   │   ├── zgoos_netbsd.go
│   │   ├── zgoos_openbsd.go
│   │   ├── zgoos_plan9.go
│   │   ├── zgoos_solaris.go
│   │   ├── zgoos_windows.go
│   │   └── zgoos_zos.go
│   ├── hysteria2.go
│   ├── network.go
│   ├── os.go
│   ├── path.go
│   ├── path_unix.go
│   ├── protocol.go
│   ├── proxy.go
│   ├── quic.go
│   ├── quic_stub.go
│   ├── rule.go
│   ├── speed.go
│   ├── time.go
│   ├── timeout.go
│   ├── v2ray.go
│   └── version.go
├── daemon/
│   ├── deprecated.go
│   ├── instance.go
│   ├── platform.go
│   ├── started_service.go
│   ├── started_service.pb.go
│   ├── started_service.proto
│   └── started_service_grpc.pb.go
├── debug.go
├── debug_http.go
├── debug_stub.go
├── debug_unix.go
├── dns/
│   ├── client.go
│   ├── client_log.go
│   ├── client_truncate.go
│   ├── extension_edns0_subnet.go
│   ├── rcode.go
│   ├── router.go
│   ├── transport/
│   │   ├── base.go
│   │   ├── connector.go
│   │   ├── connector_test.go
│   │   ├── dhcp/
│   │   │   ├── dhcp.go
│   │   │   └── dhcp_shared.go
│   │   ├── fakeip/
│   │   │   ├── fakeip.go
│   │   │   ├── memory.go
│   │   │   └── store.go
│   │   ├── hosts/
│   │   │   ├── hosts.go
│   │   │   ├── hosts_file.go
│   │   │   ├── hosts_test.go
│   │   │   ├── hosts_unix.go
│   │   │   ├── hosts_windows.go
│   │   │   └── testdata/
│   │   │       └── hosts
│   │   ├── https.go
│   │   ├── https_transport.go
│   │   ├── local/
│   │   │   ├── local.go
│   │   │   ├── local_darwin.go
│   │   │   ├── local_darwin_dhcp.go
│   │   │   ├── local_darwin_nodhcp.go
│   │   │   ├── local_resolved.go
│   │   │   ├── local_resolved_linux.go
│   │   │   ├── local_resolved_stub.go
│   │   │   ├── local_shared.go
│   │   │   ├── resolv.go
│   │   │   ├── resolv_default.go
│   │   │   ├── resolv_test.go
│   │   │   ├── resolv_unix.go
│   │   │   └── resolv_windows.go
│   │   ├── quic/
│   │   │   ├── http3.go
│   │   │   └── quic.go
│   │   ├── tcp.go
│   │   ├── tls.go
│   │   └── udp.go
│   ├── transport_adapter.go
│   ├── transport_dialer.go
│   ├── transport_manager.go
│   └── transport_registry.go
├── docs/
│   ├── CNAME
│   ├── changelog.md
│   ├── clients/
│   │   ├── android/
│   │   │   ├── features.md
│   │   │   └── index.md
│   │   ├── apple/
│   │   │   ├── features.md
│   │   │   └── index.md
│   │   ├── general.md
│   │   ├── index.md
│   │   ├── index.zh.md
│   │   └── privacy.md
│   ├── configuration/
│   │   ├── certificate/
│   │   │   ├── index.md
│   │   │   └── index.zh.md
│   │   ├── dns/
│   │   │   ├── fakeip.md
│   │   │   ├── fakeip.zh.md
│   │   │   ├── index.md
│   │   │   ├── index.zh.md
│   │   │   ├── rule.md
│   │   │   ├── rule.zh.md
│   │   │   ├── rule_action.md
│   │   │   ├── rule_action.zh.md
│   │   │   └── server/
│   │   │       ├── dhcp.md
│   │   │       ├── dhcp.zh.md
│   │   │       ├── fakeip.md
│   │   │       ├── fakeip.zh.md
│   │   │       ├── hosts.md
│   │   │       ├── hosts.zh.md
│   │   │       ├── http3.md
│   │   │       ├── http3.zh.md
│   │   │       ├── https.md
│   │   │       ├── https.zh.md
│   │   │       ├── index.md
│   │   │       ├── index.zh.md
│   │   │       ├── legacy.md
│   │   │       ├── legacy.zh.md
│   │   │       ├── local.md
│   │   │       ├── local.zh.md
│   │   │       ├── quic.md
│   │   │       ├── quic.zh.md
│   │   │       ├── resolved.md
│   │   │       ├── resolved.zh.md
│   │   │       ├── tailscale.md
│   │   │       ├── tailscale.zh.md
│   │   │       ├── tcp.md
│   │   │       ├── tcp.zh.md
│   │   │       ├── tls.md
│   │   │       ├── tls.zh.md
│   │   │       ├── udp.md
│   │   │       └── udp.zh.md
│   │   ├── endpoint/
│   │   │   ├── index.md
│   │   │   ├── index.zh.md
│   │   │   ├── tailscale.md
│   │   │   ├── tailscale.zh.md
│   │   │   ├── wireguard.md
│   │   │   └── wireguard.zh.md
│   │   ├── experimental/
│   │   │   ├── cache-file.md
│   │   │   ├── cache-file.zh.md
│   │   │   ├── clash-api.md
│   │   │   ├── clash-api.zh.md
│   │   │   ├── index.md
│   │   │   ├── index.zh.md
│   │   │   ├── v2ray-api.md
│   │   │   └── v2ray-api.zh.md
│   │   ├── inbound/
│   │   │   ├── anytls.md
│   │   │   ├── anytls.zh.md
│   │   │   ├── direct.md
│   │   │   ├── direct.zh.md
│   │   │   ├── http.md
│   │   │   ├── http.zh.md
│   │   │   ├── hysteria.md
│   │   │   ├── hysteria.zh.md
│   │   │   ├── hysteria2.md
│   │   │   ├── hysteria2.zh.md
│   │   │   ├── index.md
│   │   │   ├── index.zh.md
│   │   │   ├── mixed.md
│   │   │   ├── mixed.zh.md
│   │   │   ├── naive.md
│   │   │   ├── naive.zh.md
│   │   │   ├── redirect.md
│   │   │   ├── redirect.zh.md
│   │   │   ├── shadowsocks.md
│   │   │   ├── shadowsocks.zh.md
│   │   │   ├── shadowtls.md
│   │   │   ├── shadowtls.zh.md
│   │   │   ├── socks.md
│   │   │   ├── socks.zh.md
│   │   │   ├── tproxy.md
│   │   │   ├── tproxy.zh.md
│   │   │   ├── trojan.md
│   │   │   ├── trojan.zh.md
│   │   │   ├── tuic.md
│   │   │   ├── tuic.zh.md
│   │   │   ├── tun.md
│   │   │   ├── tun.zh.md
│   │   │   ├── vless.md
│   │   │   ├── vless.zh.md
│   │   │   ├── vmess.md
│   │   │   └── vmess.zh.md
│   │   ├── index.md
│   │   ├── index.zh.md
│   │   ├── log/
│   │   │   ├── index.md
│   │   │   └── index.zh.md
│   │   ├── ntp/
│   │   │   ├── index.md
│   │   │   └── index.zh.md
│   │   ├── outbound/
│   │   │   ├── anytls.md
│   │   │   ├── anytls.zh.md
│   │   │   ├── block.md
│   │   │   ├── block.zh.md
│   │   │   ├── direct.md
│   │   │   ├── direct.zh.md
│   │   │   ├── dns.md
│   │   │   ├── dns.zh.md
│   │   │   ├── http.md
│   │   │   ├── http.zh.md
│   │   │   ├── hysteria.md
│   │   │   ├── hysteria.zh.md
│   │   │   ├── hysteria2.md
│   │   │   ├── hysteria2.zh.md
│   │   │   ├── index.md
│   │   │   ├── index.zh.md
│   │   │   ├── naive.md
│   │   │   ├── naive.zh.md
│   │   │   ├── selector.md
│   │   │   ├── selector.zh.md
│   │   │   ├── shadowsocks.md
│   │   │   ├── shadowsocks.zh.md
│   │   │   ├── shadowtls.md
│   │   │   ├── shadowtls.zh.md
│   │   │   ├── socks.md
│   │   │   ├── socks.zh.md
│   │   │   ├── ssh.md
│   │   │   ├── ssh.zh.md
│   │   │   ├── tor.md
│   │   │   ├── tor.zh.md
│   │   │   ├── trojan.md
│   │   │   ├── trojan.zh.md
│   │   │   ├── tuic.md
│   │   │   ├── tuic.zh.md
│   │   │   ├── urltest.md
│   │   │   ├── urltest.zh.md
│   │   │   ├── vless.md
│   │   │   ├── vless.zh.md
│   │   │   ├── vmess.md
│   │   │   ├── vmess.zh.md
│   │   │   ├── wireguard.md
│   │   │   └── wireguard.zh.md
│   │   ├── route/
│   │   │   ├── geoip.md
│   │   │   ├── geoip.zh.md
│   │   │   ├── geosite.md
│   │   │   ├── geosite.zh.md
│   │   │   ├── index.md
│   │   │   ├── index.zh.md
│   │   │   ├── rule.md
│   │   │   ├── rule.zh.md
│   │   │   ├── rule_action.md
│   │   │   ├── rule_action.zh.md
│   │   │   ├── sniff.md
│   │   │   └── sniff.zh.md
│   │   ├── rule-set/
│   │   │   ├── adguard.md
│   │   │   ├── adguard.zh.md
│   │   │   ├── headless-rule.md
│   │   │   ├── headless-rule.zh.md
│   │   │   ├── index.md
│   │   │   ├── index.zh.md
│   │   │   ├── source-format.md
│   │   │   └── source-format.zh.md
│   │   ├── service/
│   │   │   ├── ccm.md
│   │   │   ├── ccm.zh.md
│   │   │   ├── derp.md
│   │   │   ├── derp.zh.md
│   │   │   ├── index.md
│   │   │   ├── index.zh.md
│   │   │   ├── ocm.md
│   │   │   ├── ocm.zh.md
│   │   │   ├── resolved.md
│   │   │   ├── resolved.zh.md
│   │   │   ├── ssm-api.md
│   │   │   └── ssm-api.zh.md
│   │   └── shared/
│   │       ├── dial.md
│   │       ├── dial.zh.md
│   │       ├── dns01_challenge.md
│   │       ├── dns01_challenge.zh.md
│   │       ├── listen.md
│   │       ├── listen.zh.md
│   │       ├── multiplex.md
│   │       ├── multiplex.zh.md
│   │       ├── neighbor.md
│   │       ├── neighbor.zh.md
│   │       ├── pre-match.md
│   │       ├── pre-match.zh.md
│   │       ├── tcp-brutal.md
│   │       ├── tcp-brutal.zh.md
│   │       ├── tls.md
│   │       ├── tls.zh.md
│   │       ├── udp-over-tcp.md
│   │       ├── udp-over-tcp.zh.md
│   │       ├── v2ray-transport.md
│   │       ├── v2ray-transport.zh.md
│   │       ├── wifi-state.md
│   │       └── wifi-state.zh.md
│   ├── deprecated.md
│   ├── deprecated.zh.md
│   ├── index.md
│   ├── index.zh.md
│   ├── installation/
│   │   ├── build-from-source.md
│   │   ├── build-from-source.zh.md
│   │   ├── docker.md
│   │   ├── docker.zh.md
│   │   ├── package-manager.md
│   │   ├── package-manager.zh.md
│   │   └── tools/
│   │       ├── arch-install.sh
│   │       ├── deb-install.sh
│   │       ├── install.sh
│   │       ├── rpm-install.sh
│   │       └── sing-box.repo
│   ├── manual/
│   │   ├── misc/
│   │   │   └── tunnelvision.md
│   │   ├── proxy/
│   │   │   ├── client.md
│   │   │   └── server.md
│   │   └── proxy-protocol/
│   │       ├── hysteria2.md
│   │       ├── shadowsocks.md
│   │       └── trojan.md
│   ├── migration.md
│   ├── migration.zh.md
│   ├── sponsors.md
│   ├── support.md
│   └── support.zh.md
├── experimental/
│   ├── cachefile/
│   │   ├── cache.go
│   │   ├── fakeip.go
│   │   └── rdrc.go
│   ├── clashapi/
│   │   ├── api_meta.go
│   │   ├── api_meta_group.go
│   │   ├── api_meta_upgrade.go
│   │   ├── cache.go
│   │   ├── common.go
│   │   ├── configs.go
│   │   ├── connections.go
│   │   ├── ctxkeys.go
│   │   ├── dns.go
│   │   ├── errors.go
│   │   ├── profile.go
│   │   ├── provider.go
│   │   ├── proxies.go
│   │   ├── ruleprovider.go
│   │   ├── rules.go
│   │   ├── script.go
│   │   ├── server.go
│   │   ├── server_fs.go
│   │   ├── server_resources.go
│   │   └── trafficontrol/
│   │       ├── manager.go
│   │       └── tracker.go
│   ├── clashapi.go
│   ├── deprecated/
│   │   ├── constants.go
│   │   ├── manager.go
│   │   └── stderr.go
│   ├── libbox/
│   │   ├── build_info.go
│   │   ├── command.go
│   │   ├── command_client.go
│   │   ├── command_server.go
│   │   ├── command_types.go
│   │   ├── config.go
│   │   ├── deprecated.go
│   │   ├── dns.go
│   │   ├── fdroid.go
│   │   ├── fdroid_mirrors.go
│   │   ├── ffi.json
│   │   ├── http.go
│   │   ├── internal/
│   │   │   └── procfs/
│   │   │       └── procfs.go
│   │   ├── iterator.go
│   │   ├── link_flags_stub.go
│   │   ├── link_flags_unix.go
│   │   ├── log.go
│   │   ├── memory.go
│   │   ├── monitor.go
│   │   ├── neighbor.go
│   │   ├── neighbor_darwin.go
│   │   ├── neighbor_linux.go
│   │   ├── neighbor_stub.go
│   │   ├── panic.go
│   │   ├── pidfd_android.go
│   │   ├── platform.go
│   │   ├── pprof.go
│   │   ├── profile_import.go
│   │   ├── remote_profile.go
│   │   ├── semver.go
│   │   ├── semver_test.go
│   │   ├── service.go
│   │   ├── service_other.go
│   │   ├── service_windows.go
│   │   ├── setup.go
│   │   ├── tun.go
│   │   ├── tun_darwin.go
│   │   ├── tun_name_darwin.go
│   │   ├── tun_name_linux.go
│   │   └── tun_name_other.go
│   ├── locale/
│   │   ├── locale.go
│   │   └── locale_zh_CN.go
│   ├── v2rayapi/
│   │   ├── server.go
│   │   ├── stats.go
│   │   ├── stats.pb.go
│   │   ├── stats.proto
│   │   └── stats_grpc.pb.go
│   └── v2rayapi.go
├── go.mod
├── go.sum
├── include/
│   ├── ccm.go
│   ├── ccm_stub.go
│   ├── ccm_stub_darwin.go
│   ├── clashapi.go
│   ├── clashapi_stub.go
│   ├── dhcp.go
│   ├── dhcp_stub.go
│   ├── naive_outbound.go
│   ├── naive_outbound_stub.go
│   ├── ocm.go
│   ├── ocm_stub.go
│   ├── oom_killer.go
│   ├── quic.go
│   ├── quic_stub.go
│   ├── registry.go
│   ├── tailscale.go
│   ├── tailscale_stub.go
│   ├── tz_android.go
│   ├── tz_ios.go
│   ├── v2rayapi.go
│   ├── v2rayapi_stub.go
│   ├── wireguard.go
│   └── wireguard_stub.go
├── log/
│   ├── export.go
│   ├── factory.go
│   ├── format.go
│   ├── id.go
│   ├── level.go
│   ├── log.go
│   ├── nop.go
│   ├── observable.go
│   ├── override.go
│   └── platform.go
├── mkdocs.yml
├── option/
│   ├── anytls.go
│   ├── ccm.go
│   ├── certificate.go
│   ├── debug.go
│   ├── direct.go
│   ├── dns.go
│   ├── dns_record.go
│   ├── endpoint.go
│   ├── experimental.go
│   ├── group.go
│   ├── hysteria.go
│   ├── hysteria2.go
│   ├── inbound.go
│   ├── multiplex.go
│   ├── naive.go
│   ├── ntp.go
│   ├── ocm.go
│   ├── oom_killer.go
│   ├── options.go
│   ├── outbound.go
│   ├── platform.go
│   ├── redir.go
│   ├── resolved.go
│   ├── route.go
│   ├── rule.go
│   ├── rule_action.go
│   ├── rule_dns.go
│   ├── rule_set.go
│   ├── service.go
│   ├── shadowsocks.go
│   ├── shadowsocksr.go
│   ├── shadowtls.go
│   ├── simple.go
│   ├── ssh.go
│   ├── ssmapi.go
│   ├── tailscale.go
│   ├── tls.go
│   ├── tls_acme.go
│   ├── tor.go
│   ├── trojan.go
│   ├── tuic.go
│   ├── tun.go
│   ├── tun_platform.go
│   ├── types.go
│   ├── udp_over_tcp.go
│   ├── v2ray.go
│   ├── v2ray_transport.go
│   ├── vless.go
│   ├── vmess.go
│   └── wireguard.go
├── protocol/
│   ├── anytls/
│   │   ├── inbound.go
│   │   └── outbound.go
│   ├── block/
│   │   └── outbound.go
│   ├── direct/
│   │   ├── inbound.go
│   │   ├── loopback_detect.go
│   │   └── outbound.go
│   ├── dns/
│   │   ├── handle.go
│   │   └── outbound.go
│   ├── group/
│   │   ├── selector.go
│   │   └── urltest.go
│   ├── http/
│   │   ├── inbound.go
│   │   └── outbound.go
│   ├── hysteria/
│   │   ├── inbound.go
│   │   └── outbound.go
│   ├── hysteria2/
│   │   ├── inbound.go
│   │   └── outbound.go
│   ├── mixed/
│   │   └── inbound.go
│   ├── naive/
│   │   ├── inbound.go
│   │   ├── inbound_conn.go
│   │   ├── outbound.go
│   │   └── quic/
│   │       └── inbound_init.go
│   ├── redirect/
│   │   ├── redirect.go
│   │   └── tproxy.go
│   ├── shadowsocks/
│   │   ├── inbound.go
│   │   ├── inbound_multi.go
│   │   ├── inbound_relay.go
│   │   └── outbound.go
│   ├── shadowtls/
│   │   ├── inbound.go
│   │   └── outbound.go
│   ├── socks/
│   │   ├── inbound.go
│   │   └── outbound.go
│   ├── ssh/
│   │   └── outbound.go
│   ├── tailscale/
│   │   ├── dns_transport.go
│   │   ├── endpoint.go
│   │   ├── tun_device_unix.go
│   │   └── tun_device_windows.go
│   ├── tor/
│   │   ├── outbound.go
│   │   └── proxy.go
│   ├── trojan/
│   │   ├── inbound.go
│   │   └── outbound.go
│   ├── tuic/
│   │   ├── inbound.go
│   │   └── outbound.go
│   ├── tun/
│   │   ├── hook.go
│   │   └── inbound.go
│   ├── vless/
│   │   ├── inbound.go
│   │   └── outbound.go
│   ├── vmess/
│   │   ├── inbound.go
│   │   └── outbound.go
│   └── wireguard/
│       └── endpoint.go
├── release/
│   ├── DEFAULT_BUILD_TAGS
│   ├── DEFAULT_BUILD_TAGS_OTHERS
│   ├── DEFAULT_BUILD_TAGS_WINDOWS
│   ├── LDFLAGS
│   ├── completions/
│   │   ├── sing-box.bash
│   │   ├── sing-box.fish
│   │   └── sing-box.zsh
│   ├── config/
│   │   ├── config.json
│   │   ├── openwrt.conf
│   │   ├── openwrt.init
│   │   ├── openwrt.keep
│   │   ├── openwrt.prerm
│   │   ├── sing-box-split-dns.xml
│   │   ├── sing-box.confd
│   │   ├── sing-box.initd
│   │   ├── sing-box.postinst
│   │   ├── sing-box.rules
│   │   ├── sing-box.service
│   │   ├── sing-box.sysusers
│   │   └── sing-box@.service
│   └── local/
│       ├── common.sh
│       ├── debug.sh
│       ├── enable.sh
│       ├── install.sh
│       ├── install_go.sh
│       ├── reinstall.sh
│       ├── sing-box.service
│       ├── uninstall.sh
│       └── update.sh
├── route/
│   ├── conn.go
│   ├── dns.go
│   ├── neighbor_resolver_darwin.go
│   ├── neighbor_resolver_lease.go
│   ├── neighbor_resolver_linux.go
│   ├── neighbor_resolver_parse.go
│   ├── neighbor_resolver_platform.go
│   ├── neighbor_resolver_stub.go
│   ├── neighbor_table_darwin.go
│   ├── neighbor_table_linux.go
│   ├── network.go
│   ├── platform_searcher.go
│   ├── route.go
│   ├── router.go
│   ├── rule/
│   │   ├── rule_abstract.go
│   │   ├── rule_abstract_test.go
│   │   ├── rule_action.go
│   │   ├── rule_default.go
│   │   ├── rule_default_interface_address.go
│   │   ├── rule_dns.go
│   │   ├── rule_headless.go
│   │   ├── rule_interface_address.go
│   │   ├── rule_item_adguard.go
│   │   ├── rule_item_auth_user.go
│   │   ├── rule_item_cidr.go
│   │   ├── rule_item_clash_mode.go
│   │   ├── rule_item_client.go
│   │   ├── rule_item_domain.go
│   │   ├── rule_item_domain_keyword.go
│   │   ├── rule_item_domain_regex.go
│   │   ├── rule_item_inbound.go
│   │   ├── rule_item_ip_accept_any.go
│   │   ├── rule_item_ip_is_private.go
│   │   ├── rule_item_ipversion.go
│   │   ├── rule_item_network.go
│   │   ├── rule_item_network_is_constrained.go
│   │   ├── rule_item_network_is_expensive.go
│   │   ├── rule_item_network_type.go
│   │   ├── rule_item_outbound.go
│   │   ├── rule_item_package_name.go
│   │   ├── rule_item_port.go
│   │   ├── rule_item_port_range.go
│   │   ├── rule_item_preferred_by.go
│   │   ├── rule_item_process_name.go
│   │   ├── rule_item_process_path.go
│   │   ├── rule_item_process_path_regex.go
│   │   ├── rule_item_protocol.go
│   │   ├── rule_item_query_type.go
│   │   ├── rule_item_rule_set.go
│   │   ├── rule_item_source_hostname.go
│   │   ├── rule_item_source_mac_address.go
│   │   ├── rule_item_user.go
│   │   ├── rule_item_user_id.go
│   │   ├── rule_item_wifi_bssid.go
│   │   ├── rule_item_wifi_ssid.go
│   │   ├── rule_network_interface_address.go
│   │   ├── rule_set.go
│   │   ├── rule_set_local.go
│   │   └── rule_set_remote.go
│   └── rule_conds.go
├── service/
│   ├── ccm/
│   │   ├── credential.go
│   │   ├── credential_darwin.go
│   │   ├── credential_other.go
│   │   ├── service.go
│   │   ├── service_usage.go
│   │   └── service_user.go
│   ├── derp/
│   │   └── service.go
│   ├── ocm/
│   │   ├── credential.go
│   │   ├── credential_darwin.go
│   │   ├── credential_other.go
│   │   ├── service.go
│   │   ├── service_usage.go
│   │   ├── service_user.go
│   │   └── service_websocket.go
│   ├── oomkiller/
│   │   ├── config.go
│   │   ├── service.go
│   │   ├── service_stub.go
│   │   └── service_timer.go
│   ├── resolved/
│   │   ├── resolve1.go
│   │   ├── service.go
│   │   ├── stub.go
│   │   └── transport.go
│   └── ssmapi/
│       ├── api.go
│       ├── cache.go
│       ├── server.go
│       ├── traffic.go
│       └── user.go
├── test/
│   ├── box_test.go
│   ├── brutal_test.go
│   ├── clash_darwin_test.go
│   ├── clash_other_test.go
│   ├── clash_test.go
│   ├── config/
│   │   ├── hysteria-client.json
│   │   ├── hysteria-server.json
│   │   ├── hysteria2-client.yml
│   │   ├── hysteria2-server.yml
│   │   ├── naive-nginx.conf
│   │   ├── naive-quic.json
│   │   ├── naive.json
│   │   ├── nginx.conf
│   │   ├── shadowsocksr.json
│   │   ├── trojan.json
│   │   ├── tuic-client.json
│   │   ├── tuic-server.json
│   │   ├── vless-server.json
│   │   ├── vless-tls-client.json
│   │   ├── vless-tls-server.json
│   │   ├── vmess-client.json
│   │   ├── vmess-grpc-client.json
│   │   ├── vmess-grpc-server.json
│   │   ├── vmess-mux-client.json
│   │   ├── vmess-server.json
│   │   ├── vmess-ws-client.json
│   │   ├── vmess-ws-server.json
│   │   └── wireguard.conf
│   ├── direct_test.go
│   ├── docker_test.go
│   ├── domain_inbound_test.go
│   ├── ech_test.go
│   ├── go.mod
│   ├── go.sum
│   ├── http_test.go
│   ├── hysteria2_test.go
│   ├── hysteria_test.go
│   ├── inbound_detour_test.go
│   ├── ktls_test.go
│   ├── mkcert.go
│   ├── mux_cool_test.go
│   ├── mux_test.go
│   ├── naive_self_test.go
│   ├── naive_test.go
│   ├── reality_test.go
│   ├── shadowsocks_legacy_test.go
│   ├── shadowsocks_test.go
│   ├── shadowtls_test.go
│   ├── socks_test.go
│   ├── ss_plugin_test.go
│   ├── tfo_test.go
│   ├── tls_test.go
│   ├── trojan_test.go
│   ├── tuic_test.go
│   ├── v2ray_api_test.go
│   ├── v2ray_grpc_test.go
│   ├── v2ray_httpupgrade_test.go
│   ├── v2ray_transport_test.go
│   ├── v2ray_ws_test.go
│   ├── vmess_test.go
│   └── wrapper_test.go
└── transport/
    ├── simple-obfs/
    │   ├── README.md
    │   ├── http.go
    │   └── tls.go
    ├── sip003/
    │   ├── args.go
    │   ├── obfs.go
    │   ├── plugin.go
    │   └── v2ray.go
    ├── trojan/
    │   ├── mux.go
    │   ├── protocol.go
    │   ├── protocol_wait.go
    │   ├── service.go
    │   └── service_wait.go
    ├── v2ray/
    │   ├── grpc.go
    │   ├── grpc_lite.go
    │   ├── quic.go
    │   └── transport.go
    ├── v2raygrpc/
    │   ├── client.go
    │   ├── conn.go
    │   ├── credentials/
    │   │   ├── credentials.go
    │   │   ├── spiffe.go
    │   │   ├── syscallconn.go
    │   │   └── util.go
    │   ├── custom_name.go
    │   ├── server.go
    │   ├── stream.pb.go
    │   ├── stream.proto
    │   ├── stream_grpc.pb.go
    │   └── tls_credentials.go
    ├── v2raygrpclite/
    │   ├── client.go
    │   ├── conn.go
    │   └── server.go
    ├── v2rayhttp/
    │   ├── client.go
    │   ├── conn.go
    │   ├── force_close.go
    │   ├── pool.go
    │   └── server.go
    ├── v2rayhttpupgrade/
    │   ├── client.go
    │   └── server.go
    ├── v2rayquic/
    │   ├── client.go
    │   ├── init.go
    │   ├── server.go
    │   └── stream.go
    ├── v2raywebsocket/
    │   ├── client.go
    │   ├── conn.go
    │   ├── server.go
    │   └── writer.go
    └── wireguard/
        ├── client_bind.go
        ├── device.go
        ├── device_nat.go
        ├── device_stack.go
        ├── device_stack_gonet.go
        ├── device_stack_stub.go
        ├── device_system.go
        ├── device_system_stack.go
        ├── endpoint.go
        └── endpoint_options.go

================================================
FILE CONTENTS
================================================

================================================
FILE: .fpm_openwrt
================================================
-s dir
--name sing-box
--category net
--license GPL-3.0-or-later
--description "The universal proxy platform."
--url "https://sing-box.sagernet.org/"
--maintainer "nekohasekai <contact-git@sekai.icu>"
--no-deb-generate-changes

--config-files /etc/config/sing-box
--config-files /etc/sing-box/config.json

--depends ca-bundle
--depends kmod-inet-diag
--depends kmod-tun
--depends firewall4
--depends kmod-nft-queue

--before-remove release/config/openwrt.prerm

release/config/config.json=/etc/sing-box/config.json

release/config/openwrt.conf=/etc/config/sing-box
release/config/openwrt.init=/etc/init.d/sing-box
release/config/openwrt.keep=/lib/upgrade/keep.d/sing-box

release/completions/sing-box.bash=/usr/share/bash-completion/completions/sing-box.bash
release/completions/sing-box.fish=/usr/share/fish/vendor_completions.d/sing-box.fish
release/completions/sing-box.zsh=/usr/share/zsh/site-functions/_sing-box

LICENSE=/usr/share/licenses/sing-box/LICENSE


================================================
FILE: .fpm_pacman
================================================
-s dir
--name sing-box
--category net
--license GPL-3.0-or-later
--description "The universal proxy platform."
--url "https://sing-box.sagernet.org/"
--maintainer "nekohasekai <contact-git@sekai.icu>"
--config-files etc/sing-box/config.json
--after-install release/config/sing-box.postinst

release/config/config.json=/etc/sing-box/config.json

release/config/sing-box.service=/usr/lib/systemd/system/sing-box.service
release/config/sing-box@.service=/usr/lib/systemd/system/sing-box@.service
release/config/sing-box.sysusers=/usr/lib/sysusers.d/sing-box.conf
release/config/sing-box.rules=usr/share/polkit-1/rules.d/sing-box.rules
release/config/sing-box-split-dns.xml=/usr/share/dbus-1/system.d/sing-box-split-dns.conf

release/completions/sing-box.bash=/usr/share/bash-completion/completions/sing-box.bash
release/completions/sing-box.fish=/usr/share/fish/vendor_completions.d/sing-box.fish
release/completions/sing-box.zsh=/usr/share/zsh/site-functions/_sing-box

LICENSE=/usr/share/licenses/sing-box/LICENSE


================================================
FILE: .fpm_systemd
================================================
-s dir
--name sing-box
--category net
--license GPL-3.0-or-later
--description "The universal proxy platform."
--url "https://sing-box.sagernet.org/"
--maintainer "nekohasekai <contact-git@sekai.icu>"
--deb-field "Bug: https://github.com/SagerNet/sing-box/issues"
--no-deb-generate-changes
--config-files /etc/sing-box/config.json
--after-install release/config/sing-box.postinst

release/config/config.json=/etc/sing-box/config.json

release/config/sing-box.service=/usr/lib/systemd/system/sing-box.service
release/config/sing-box@.service=/usr/lib/systemd/system/sing-box@.service
release/config/sing-box.sysusers=/usr/lib/sysusers.d/sing-box.conf
release/config/sing-box.rules=usr/share/polkit-1/rules.d/sing-box.rules
release/config/sing-box-split-dns.xml=/usr/share/dbus-1/system.d/sing-box-split-dns.conf

release/completions/sing-box.bash=/usr/share/bash-completion/completions/sing-box.bash
release/completions/sing-box.fish=/usr/share/fish/vendor_completions.d/sing-box.fish
release/completions/sing-box.zsh=/usr/share/zsh/site-functions/_sing-box

LICENSE=/usr/share/licenses/sing-box/LICENSE


================================================
FILE: .github/CRONET_GO_VERSION
================================================
ea7cd33752aed62603775af3df946c1b83f4b0b3


================================================
FILE: .github/FUNDING.yml
================================================
github: nekohasekai

================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.yml
================================================
name: Bug report
description: "Report sing-box bug"
body:
  - type: dropdown
    attributes:
      label: Operating system
      description: Operating system type
      options:
        - iOS
        - macOS
        - Apple tvOS
        - Android
        - Windows
        - Linux
        - Others
    validations:
      required: true
  - type: input
    attributes:
      label: System version
      description: Please provide the operating system version
    validations:
      required: true
  - type: dropdown
    attributes:
      label: Installation type
      description: Please provide the sing-box installation type
      options:
        - Original sing-box Command Line
        - sing-box for iOS Graphical Client
        - sing-box for macOS Graphical Client
        - sing-box for Apple tvOS Graphical Client
        - sing-box for Android Graphical Client
        - Third-party graphical clients that advertise themselves as using sing-box (Windows)
        - Third-party graphical clients that advertise themselves as using sing-box (Android)
        - Others
    validations:
      required: true
  - type: input
    attributes:
      description: Graphical client version
      label: If you are using a graphical client, please provide the version of the client.
  - type: textarea
    attributes:
      label: Version
      description: If you are using the original command line program, please provide the output of the `sing-box version` command.
      render: shell
  - type: textarea
    attributes:
      label: Description
      description: Please provide a detailed description of the error.
    validations:
      required: true
  - type: textarea
    attributes:
      label: Reproduction
      description: Please provide the steps to reproduce the error, including the configuration files and procedures that can locally (not dependent on the remote server) reproduce the error using the original command line program of sing-box.
    validations:
      required: true
  - type: textarea
    attributes:
      label: Logs
      description: |-
        In addition, if you encounter a crash with the graphical client, please also provide crash logs.
        For Apple platform clients, please check `Settings - View Service Log` for crash logs.
        For the Android client, please check the `/sdcard/Android/data/io.nekohasekai.sfa/files/stderr.log` file for crash logs.
      render: shell
  - type: checkboxes
    id: supporter
    attributes:
      label: Supporter
      options:
        - label: I am a [sponsor](https://github.com/sponsors/nekohasekai/)
  - type: checkboxes
    attributes:
      label: Integrity requirements
      description: |-
        Please check all of the following options to prove that you have read and understood the requirements, otherwise this issue will be closed.
        Sing-box is not a project aimed to please users who can't make any meaningful contributions and gain unethical influence. If you deceive here to deliberately waste the time of the developers, you will be permanently blocked.
      options:
        - label: I confirm that I have read the documentation, understand the meaning of all the configuration items I wrote, and did not pile up seemingly useful options or default values.
          required: true
        - label: I confirm that I have provided the server and client configuration files and process that can be reproduced locally, instead of a complicated client configuration file that has been stripped of sensitive data.
          required: true
        - label: I confirm that I have provided the simplest configuration that can be used to reproduce the error I reported, instead of depending on remote servers, TUN, graphical interface clients, or other closed-source software.
          required: true
        - label: I confirm that I have provided the complete configuration files and logs, rather than just providing parts I think are useful out of confidence in my own intelligence.
          required: true

================================================
FILE: .github/ISSUE_TEMPLATE/bug_report_zh.yml
================================================
name: 错误反馈
description: "提交 sing-box 漏洞"
body:
  - type: dropdown
    attributes:
      label: 操作系统
      description: 请提供操作系统类型
      options:
        - iOS
        - macOS
        - Apple tvOS
        - Android
        - Windows
        - Linux
        - 其他
    validations:
      required: true
  - type: input
    attributes:
      label: 系统版本
      description: 请提供操作系统版本
    validations:
      required: true
  - type: dropdown
    attributes:
      label: 安装类型
      description: 请提供该 sing-box 安装类型
      options:
        - sing-box 原始命令行程序
        - sing-box for iOS 图形客户端程序
        - sing-box for macOS 图形客户端程序
        - sing-box for Apple tvOS 图形客户端程序
        - sing-box for Android 图形客户端程序
        - 宣传使用 sing-box 的第三方图形客户端程序 (Windows)
        - 宣传使用 sing-box 的第三方图形客户端程序 (Android)
        - 其他
    validations:
      required: true
  - type: input
    attributes:
      description: 图形客户端版本
      label: 如果您使用图形客户端程序,请提供该程序版本。
  - type: textarea
    attributes:
      label: 版本
      description: 如果您使用原始命令行程序,请提供 `sing-box version` 命令的输出。
      render: shell
  - type: textarea
    attributes:
      label: 描述
      description: 请提供错误的详细描述。
    validations:
      required: true
  - type: textarea
    attributes:
      label: 重现方式
      description: 请提供重现错误的步骤,必须包括可以在本地(不依赖与远程服务器)使用 sing-box 原始命令行程序重现错误的配置文件与流程。
    validations:
      required: true
  - type: textarea
    attributes:
      label: 日志
      description: |-
        此外,如果您遭遇图形界面应用程序崩溃,请附加提供崩溃日志。
        对于 Apple 平台图形客户端程序,请检查 `Settings - View Service Log` 以导出崩溃日志。
        对于 Android 图形客户端程序,请检查 `/sdcard/Android/data/io.nekohasekai.sfa/files/stderr.log` 文件以导出崩溃日志。
      render: shell
  - type: checkboxes
    id: supporter
    attributes:
      label: 支持我们
      options:
        - label: 我已经 [赞助](https://github.com/sponsors/nekohasekai/)
  - type: checkboxes
    attributes:
      label: 完整性要求
      description: |-
        请勾选以下所有选项以证明您已经阅读并理解了以下要求,否则该 issue 将被关闭。
        sing-box 不是讨好无法作出任何意义上的贡献的最终用户并获取非道德影响力的项目,如果您在此处欺骗以故意浪费开发者的时间,您将被永久封锁。
      options:
        - label: 我保证阅读了文档,了解所有我编写的配置文件项的含义,而不是大量堆砌看似有用的选项或默认值。
          required: true
        - label: 我保证提供了可以在本地重现该问题的服务器、客户端配置文件与流程,而不是一个脱敏的复杂客户端配置文件。
          required: true
        - label: 我保证提供了可用于重现我报告的错误的最简配置,而不是依赖远程服务器、TUN、图形界面客户端或者其他闭源软件。
          required: true
        - label: 我保证提供了完整的配置文件与日志,而不是出于对自身智力的自信而仅提供了部分认为有用的部分。
          required: true


================================================
FILE: .github/build_alpine_apk.sh
================================================
#!/usr/bin/env bash

set -e -o pipefail

ARCHITECTURE="$1"
VERSION="$2"
BINARY_PATH="$3"
OUTPUT_PATH="$4"

if [ -z "$ARCHITECTURE" ] || [ -z "$VERSION" ] || [ -z "$BINARY_PATH" ] || [ -z "$OUTPUT_PATH" ]; then
  echo "Usage: $0 <architecture> <version> <binary_path> <output_path>"
  exit 1
fi

PROJECT=$(cd "$(dirname "$0")/.."; pwd)

# Convert version to APK format:
#   1.13.0-beta.8  -> 1.13.0_beta8-r0
#   1.13.0-rc.3    -> 1.13.0_rc3-r0
#   1.13.0         -> 1.13.0-r0
APK_VERSION=$(echo "$VERSION" | sed -E 's/-([a-z]+)\.([0-9]+)/_\1\2/')
APK_VERSION="${APK_VERSION}-r0"

ROOT_DIR=$(mktemp -d)
trap 'rm -rf "$ROOT_DIR"' EXIT

# Binary
install -Dm755 "$BINARY_PATH" "$ROOT_DIR/usr/bin/sing-box"

# Config files
install -Dm644 "$PROJECT/release/config/config.json" "$ROOT_DIR/etc/sing-box/config.json"
install -Dm755 "$PROJECT/release/config/sing-box.initd" "$ROOT_DIR/etc/init.d/sing-box"
install -Dm644 "$PROJECT/release/config/sing-box.confd" "$ROOT_DIR/etc/conf.d/sing-box"

# Service files
install -Dm644 "$PROJECT/release/config/sing-box.service" "$ROOT_DIR/usr/lib/systemd/system/sing-box.service"
install -Dm644 "$PROJECT/release/config/sing-box@.service" "$ROOT_DIR/usr/lib/systemd/system/sing-box@.service"

# Completions
install -Dm644 "$PROJECT/release/completions/sing-box.bash" "$ROOT_DIR/usr/share/bash-completion/completions/sing-box.bash"
install -Dm644 "$PROJECT/release/completions/sing-box.fish" "$ROOT_DIR/usr/share/fish/vendor_completions.d/sing-box.fish"
install -Dm644 "$PROJECT/release/completions/sing-box.zsh" "$ROOT_DIR/usr/share/zsh/site-functions/_sing-box"

# License
install -Dm644 "$PROJECT/LICENSE" "$ROOT_DIR/usr/share/licenses/sing-box/LICENSE"

# APK metadata
PACKAGES_DIR="$ROOT_DIR/lib/apk/packages"
mkdir -p "$PACKAGES_DIR"

# .conffiles
cat > "$PACKAGES_DIR/.conffiles" <<'EOF'
/etc/conf.d/sing-box
/etc/init.d/sing-box
/etc/sing-box/config.json
EOF

# .conffiles_static (sha256 checksums)
while IFS= read -r conffile; do
  sha256=$(sha256sum "$ROOT_DIR$conffile" | cut -d' ' -f1)
  echo "$conffile $sha256"
done < "$PACKAGES_DIR/.conffiles" > "$PACKAGES_DIR/.conffiles_static"

# .list (all files, excluding lib/apk/packages/ metadata)
(cd "$ROOT_DIR" && find . -type f -o -type l) \
  | sed 's|^\./|/|' \
  | grep -v '^/lib/apk/packages/' \
  | sort > "$PACKAGES_DIR/.list"

# Build APK
apk mkpkg \
  --info "name:sing-box" \
  --info "version:${APK_VERSION}" \
  --info "description:The universal proxy platform." \
  --info "arch:${ARCHITECTURE}" \
  --info "license:GPL-3.0-or-later with name use or association addition" \
  --info "origin:sing-box" \
  --info "url:https://sing-box.sagernet.org/" \
  --info "maintainer:nekohasekai <contact-git@sekai.icu>" \
  --files "$ROOT_DIR" \
  --output "$OUTPUT_PATH"


================================================
FILE: .github/build_openwrt_apk.sh
================================================
#!/usr/bin/env bash

set -e -o pipefail

ARCHITECTURE="$1"
VERSION="$2"
BINARY_PATH="$3"
OUTPUT_PATH="$4"

if [ -z "$ARCHITECTURE" ] || [ -z "$VERSION" ] || [ -z "$BINARY_PATH" ] || [ -z "$OUTPUT_PATH" ]; then
  echo "Usage: $0 <architecture> <version> <binary_path> <output_path>"
  exit 1
fi

PROJECT=$(cd "$(dirname "$0")/.."; pwd)

# Convert version to APK format:
#   1.13.0-beta.8  -> 1.13.0_beta8-r0
#   1.13.0-rc.3    -> 1.13.0_rc3-r0
#   1.13.0         -> 1.13.0-r0
APK_VERSION=$(echo "$VERSION" | sed -E 's/-([a-z]+)\.([0-9]+)/_\1\2/')
APK_VERSION="${APK_VERSION}-r0"

ROOT_DIR=$(mktemp -d)
trap 'rm -rf "$ROOT_DIR"' EXIT

# Binary
install -Dm755 "$BINARY_PATH" "$ROOT_DIR/usr/bin/sing-box"

# Config files
install -Dm644 "$PROJECT/release/config/config.json" "$ROOT_DIR/etc/sing-box/config.json"
install -Dm644 "$PROJECT/release/config/openwrt.conf" "$ROOT_DIR/etc/config/sing-box"
install -Dm755 "$PROJECT/release/config/openwrt.init" "$ROOT_DIR/etc/init.d/sing-box"
install -Dm644 "$PROJECT/release/config/openwrt.keep" "$ROOT_DIR/lib/upgrade/keep.d/sing-box"

# Completions
install -Dm644 "$PROJECT/release/completions/sing-box.bash" "$ROOT_DIR/usr/share/bash-completion/completions/sing-box.bash"
install -Dm644 "$PROJECT/release/completions/sing-box.fish" "$ROOT_DIR/usr/share/fish/vendor_completions.d/sing-box.fish"
install -Dm644 "$PROJECT/release/completions/sing-box.zsh" "$ROOT_DIR/usr/share/zsh/site-functions/_sing-box"

# License
install -Dm644 "$PROJECT/LICENSE" "$ROOT_DIR/usr/share/licenses/sing-box/LICENSE"

# APK metadata
PACKAGES_DIR="$ROOT_DIR/lib/apk/packages"
mkdir -p "$PACKAGES_DIR"

# .conffiles
cat > "$PACKAGES_DIR/.conffiles" <<'EOF'
/etc/config/sing-box
/etc/sing-box/config.json
EOF

# .conffiles_static (sha256 checksums)
while IFS= read -r conffile; do
  sha256=$(sha256sum "$ROOT_DIR$conffile" | cut -d' ' -f1)
  echo "$conffile $sha256"
done < "$PACKAGES_DIR/.conffiles" > "$PACKAGES_DIR/.conffiles_static"

# .list (all files, excluding lib/apk/packages/ metadata)
(cd "$ROOT_DIR" && find . -type f -o -type l) \
  | sed 's|^\./|/|' \
  | grep -v '^/lib/apk/packages/' \
  | sort > "$PACKAGES_DIR/.list"

# Build APK
apk mkpkg \
  --info "name:sing-box" \
  --info "version:${APK_VERSION}" \
  --info "description:The universal proxy platform." \
  --info "arch:${ARCHITECTURE}" \
  --info "license:GPL-3.0-or-later" \
  --info "origin:sing-box" \
  --info "url:https://sing-box.sagernet.org/" \
  --info "maintainer:nekohasekai <contact-git@sekai.icu>" \
  --info "depends:ca-bundle kmod-inet-diag kmod-tun firewall4 kmod-nft-queue" \
  --info "provider-priority:100" \
  --script "pre-deinstall:${PROJECT}/release/config/openwrt.prerm" \
  --files "$ROOT_DIR" \
  --output "$OUTPUT_PATH"


================================================
FILE: .github/deb2ipk.sh
================================================
#!/usr/bin/env bash
# mod from https://gist.github.com/pldubouilh/c5703052986bfdd404005951dee54683

set -e -o pipefail

PROJECT=$(dirname "$0")/../..
TMP_PATH=`mktemp -d`
cp $2 $TMP_PATH
pushd $TMP_PATH

DEB_NAME=`ls *.deb`
ar x $DEB_NAME

mkdir control
pushd control
tar xf ../control.tar.gz
rm md5sums
sed "s/Architecture:\\ \w*/Architecture:\\ $1/g" ./control -i
cat control
tar czf ../control.tar.gz ./*
popd

DEB_NAME=${DEB_NAME%.deb}
tar czf $DEB_NAME.ipk control.tar.gz data.tar.gz debian-binary
popd

cp $TMP_PATH/$DEB_NAME.ipk $3
rm -r $TMP_PATH


================================================
FILE: .github/renovate.json
================================================
{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "commitMessagePrefix": "[dependencies]",
  "extends": [
    "config:base",
    ":disableRateLimiting"
  ],
  "baseBranches": [
    "unstable"
  ],
  "golang": {
    "enabled": false
  },
  "packageRules": [
    {
      "matchManagers": [
        "github-actions"
      ],
      "groupName": "github-actions"
    },
    {
      "matchManagers": [
        "dockerfile"
      ],
      "groupName": "Dockerfile"
    }
  ]
}

================================================
FILE: .github/setup_go_for_macos1013.sh
================================================
#!/usr/bin/env bash

set -euo pipefail

VERSION="1.25.8"
PATCH_COMMITS=(
  "afe69d3cec1c6dcf0f1797b20546795730850070"
  "1ed289b0cf87dc5aae9c6fe1aa5f200a83412938"
)
CURL_ARGS=(
  -fL
  --silent
  --show-error
)

if [[ -n "${GITHUB_TOKEN:-}" ]]; then
  CURL_ARGS+=(-H "Authorization: Bearer ${GITHUB_TOKEN}")
fi

mkdir -p "$HOME/go"
cd "$HOME/go"
wget "https://dl.google.com/go/go${VERSION}.darwin-arm64.tar.gz"
tar -xzf "go${VERSION}.darwin-arm64.tar.gz"
#cp -a go go_bootstrap
mv go go_osx
cd go_osx

# these patch URLs only work on golang1.25.x
# that means after golang1.26 release it must be changed
# see: https://github.com/SagerNet/go/commits/release-branch.go1.25/
# revert:
# 33d3f603c1: "cmd/link/internal/ld: use 12.0.0 OS/SDK versions for macOS linking"
# 937368f84e: "crypto/x509: change how we retrieve chains on darwin"

for patch_commit in "${PATCH_COMMITS[@]}"; do
  curl "${CURL_ARGS[@]}" "https://github.com/SagerNet/go/commit/${patch_commit}.diff" | patch --verbose -p 1
done

# Rebuild is not needed: we build with CGO_ENABLED=1, so Apple's external
# linker handles LC_BUILD_VERSION via MACOSX_DEPLOYMENT_TARGET, and the
# stdlib (crypto/x509) is compiled from patched src automatically.
#cd src
#GOROOT_BOOTSTRAP="$HOME/go/go_bootstrap" ./make.bash
#cd ../..
#rm -rf go_bootstrap "go${VERSION}.darwin-arm64.tar.gz"


================================================
FILE: .github/setup_go_for_windows7.sh
================================================
#!/usr/bin/env bash

set -euo pipefail

VERSION="1.25.8"
PATCH_COMMITS=(
  "466f6c7a29bc098b0d4c987b803c779222894a11"
  "1bdabae205052afe1dadb2ad6f1ba612cdbc532a"
  "a90777dcf692dd2168577853ba743b4338721b06"
  "f6bddda4e8ff58a957462a1a09562924d5f3d05c"
  "bed309eff415bcb3c77dd4bc3277b682b89a388d"
  "34b899c2fb39b092db4fa67c4417e41dc046be4b"
)
CURL_ARGS=(
  -fL
  --silent
  --show-error
)

if [[ -n "${GITHUB_TOKEN:-}" ]]; then
  CURL_ARGS+=(-H "Authorization: Bearer ${GITHUB_TOKEN}")
fi

mkdir -p "$HOME/go"
cd "$HOME/go"
wget "https://dl.google.com/go/go${VERSION}.linux-amd64.tar.gz"
tar -xzf "go${VERSION}.linux-amd64.tar.gz"
mv go go_win7
cd go_win7

# modify from https://github.com/restic/restic/issues/4636#issuecomment-1896455557
# these patch URLs only work on golang1.25.x
# that means after golang1.26 release it must be changed
# see: https://github.com/MetaCubeX/go/commits/release-branch.go1.25/
# revert:
# 693def151adff1af707d82d28f55dba81ceb08e1: "crypto/rand,runtime: switch RtlGenRandom for ProcessPrng"
# 7c1157f9544922e96945196b47b95664b1e39108: "net: remove sysSocket fallback for Windows 7"
# 48042aa09c2f878c4faa576948b07fe625c4707a: "syscall: remove Windows 7 console handle workaround"
# a17d959debdb04cd550016a3501dd09d50cd62e7: "runtime: always use LoadLibraryEx to load system libraries"
# fixes:
# bed309eff415bcb3c77dd4bc3277b682b89a388d: "Fix os.RemoveAll not working on Windows7"
# 34b899c2fb39b092db4fa67c4417e41dc046be4b: "Revert \"os: remove 5ms sleep on Windows in (*Process).Wait\""

for patch_commit in "${PATCH_COMMITS[@]}"; do
  curl "${CURL_ARGS[@]}" "https://github.com/MetaCubeX/go/commit/${patch_commit}.diff" | patch --verbose -p 1
done


================================================
FILE: .github/update_clients.sh
================================================
#!/usr/bin/env bash

PROJECTS=$(dirname "$0")/../..

function updateClient() {
  pushd clients/$1
  git fetch
  git reset FETCH_HEAD --hard
  popd
  git add clients/$1
}

updateClient "apple"
updateClient "android"


================================================
FILE: .github/update_cronet.sh
================================================
#!/usr/bin/env bash

set -e -o pipefail

SCRIPT_DIR=$(dirname "$0")
PROJECTS=$SCRIPT_DIR/../..

git -C $PROJECTS/cronet-go fetch origin main
git -C $PROJECTS/cronet-go fetch origin go
go get -x github.com/sagernet/cronet-go/all@$(git -C $PROJECTS/cronet-go rev-parse origin/go)
go get -x github.com/sagernet/cronet-go@$(git -C $PROJECTS/cronet-go rev-parse origin/go)
go mod tidy
git -C $PROJECTS/cronet-go rev-parse origin/go > "$SCRIPT_DIR/CRONET_GO_VERSION"


================================================
FILE: .github/update_cronet_dev.sh
================================================
#!/usr/bin/env bash

set -e -o pipefail

SCRIPT_DIR=$(dirname "$0")
PROJECTS=$SCRIPT_DIR/../..

git -C $PROJECTS/cronet-go fetch origin dev
git -C $PROJECTS/cronet-go fetch origin go_dev
go get -x github.com/sagernet/cronet-go/all@$(git -C $PROJECTS/cronet-go rev-parse origin/go_dev)
go get -x github.com/sagernet/cronet-go@$(git -C $PROJECTS/cronet-go rev-parse origin/go_dev)
go mod tidy
git -C $PROJECTS/cronet-go rev-parse origin/dev > "$SCRIPT_DIR/CRONET_GO_VERSION"


================================================
FILE: .github/update_dependencies.sh
================================================
#!/usr/bin/env bash

PROJECTS=$(dirname "$0")/../..
go get -x github.com/sagernet/$1@$(git -C $PROJECTS/$1 rev-parse HEAD)
go mod tidy


================================================
FILE: .github/workflows/build.yml
================================================
name: Build

on:
  workflow_dispatch:
    inputs:
      version:
        description: "Version name"
        required: true
        type: string
      build:
        description: "Build type"
        required: true
        type: choice
        default: "All"
        options:
          - All
          - Binary
          - Android
          - Apple
          - app-store
          - iOS
          - macOS
          - tvOS
          - macOS-standalone
          - publish-android
  push:
    branches:
      - stable
      - testing
      - unstable

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}-${{ inputs.build }}
  cancel-in-progress: true

jobs:
  calculate_version:
    name: Calculate version
    runs-on: ubuntu-latest
    outputs:
      version: ${{ steps.outputs.outputs.version }}
    steps:
      - name: Checkout
        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
        with:
          fetch-depth: 0
      - name: Setup Go
        uses: actions/setup-go@v5
        with:
          go-version: ~1.25.8
      - name: Check input version
        if: github.event_name == 'workflow_dispatch'
        run: |-
          echo "version=${{ inputs.version }}"
          echo "version=${{ inputs.version }}" >> "$GITHUB_ENV"
      - name: Calculate version
        if: github.event_name != 'workflow_dispatch'
        run: |-
          go run -v ./cmd/internal/read_tag --ci --nightly
      - name: Set outputs
        id: outputs
        run: |-
          echo "version=$version" >> "$GITHUB_OUTPUT"
  build:
    name: Build binary
    if: github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Binary'
    runs-on: ubuntu-latest
    needs:
      - calculate_version
    strategy:
      matrix:
        include:
          - { os: linux, arch: amd64, variant: purego, naive: true }
          - { os: linux, arch: amd64, variant: glibc, naive: true }
          - { os: linux, arch: amd64, variant: musl, naive: true, debian: amd64, rpm: x86_64, pacman: x86_64, alpine: x86_64, openwrt: "x86_64" }

          - { os: linux, arch: arm64, variant: purego, naive: true }
          - { os: linux, arch: arm64, variant: glibc, naive: true }
          - { os: linux, arch: arm64, variant: musl, naive: true, debian: arm64, rpm: aarch64, pacman: aarch64, alpine: aarch64, openwrt: "aarch64_cortex-a53 aarch64_cortex-a72 aarch64_cortex-a76 aarch64_generic" }

          - { os: linux, arch: "386", go386: sse2 }
          - { os: linux, arch: "386", variant: glibc, naive: true, go386: sse2 }
          - { os: linux, arch: "386", variant: musl, naive: true, go386: sse2, debian: i386, rpm: i386, alpine: x86, openwrt: "i386_pentium4" }

          - { os: linux, arch: arm, goarm: "7" }
          - { os: linux, arch: arm, variant: glibc, naive: true, goarm: "7" }
          - { os: linux, arch: arm, variant: musl, naive: true, goarm: "7", debian: armhf, rpm: armv7hl, pacman: armv7hl, alpine: armv7, openwrt: "arm_cortex-a5_vfpv4 arm_cortex-a7_neon-vfpv4 arm_cortex-a7_vfpv4 arm_cortex-a8_vfpv3 arm_cortex-a9_neon arm_cortex-a9_vfpv3-d16 arm_cortex-a15_neon-vfpv4" }

          - { os: linux, arch: mipsle, gomips: hardfloat, naive: true, variant: glibc }
          - { os: linux, arch: mipsle, gomips: softfloat, naive: true, variant: musl, debian: mipsel, rpm: mipsel, openwrt: "mipsel_24kc mipsel_74kc mipsel_mips32" }
          - { os: linux, arch: mips64le, gomips: hardfloat, naive: true, variant: glibc, debian: mips64el, rpm: mips64el }
          - { os: linux, arch: riscv64, naive: true, variant: glibc }
          - { os: linux, arch: riscv64, naive: true, variant: musl, debian: riscv64, rpm: riscv64, alpine: riscv64, openwrt: "riscv64_generic" }
          - { os: linux, arch: loong64, naive: true, variant: glibc }
          - { os: linux, arch: loong64, naive: true, variant: musl, debian: loongarch64, rpm: loongarch64, alpine: loongarch64, openwrt: "loongarch64_generic" }

          - { os: linux, arch: "386", go386: softfloat, openwrt: "i386_pentium-mmx" }
          - { os: linux, arch: arm, goarm: "5", openwrt: "arm_arm926ej-s arm_cortex-a7 arm_cortex-a9 arm_fa526 arm_xscale" }
          - { os: linux, arch: arm, goarm: "6", debian: armel, rpm: armv6hl, openwrt: "arm_arm1176jzf-s_vfp" }
          - { os: linux, arch: mips, gomips: softfloat, openwrt: "mips_24kc mips_4kec mips_mips32" }
          - { os: linux, arch: mipsle, gomips: hardfloat, openwrt: "mipsel_24kc_24kf" }
          - { os: linux, arch: mipsle, gomips: softfloat }
          - { os: linux, arch: mips64, gomips: softfloat, openwrt: "mips64_mips64r2 mips64_octeonplus" }
          - { os: linux, arch: mips64le, gomips: hardfloat }
          - { os: linux, arch: mips64le, gomips: softfloat, openwrt: "mips64el_mips64r2" }
          - { os: linux, arch: s390x, debian: s390x, rpm: s390x }
          - { os: linux, arch: ppc64le, debian: ppc64el, rpm: ppc64le }
          - { os: linux, arch: riscv64 }
          - { os: linux, arch: loong64 }

          - { os: windows, arch: amd64, legacy_win7: true, legacy_name: "windows-7" }
          - { os: windows, arch: "386", legacy_win7: true, legacy_name: "windows-7" }

          - { os: android, arch: arm64, ndk: "aarch64-linux-android23" }
          - { os: android, arch: arm, ndk: "armv7a-linux-androideabi23" }
          - { os: android, arch: amd64, ndk: "x86_64-linux-android23" }
          - { os: android, arch: "386", ndk: "i686-linux-android23" }
    steps:
      - name: Checkout
        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
        with:
          fetch-depth: 0
      - name: Setup Go
        if: ${{ ! matrix.legacy_win7 }}
        uses: actions/setup-go@v5
        with:
          go-version: ~1.25.8
      - name: Cache Go for Windows 7
        if: matrix.legacy_win7
        id: cache-go-for-windows7
        uses: actions/cache@v4
        with:
          path: |
            ~/go/go_win7
          key: go_win7_1258
      - name: Setup Go for Windows 7
        if: matrix.legacy_win7 && steps.cache-go-for-windows7.outputs.cache-hit != 'true'
        env:
          GITHUB_TOKEN: ${{ github.token }}
        run: |-
          .github/setup_go_for_windows7.sh
      - name: Setup Go for Windows 7
        if: matrix.legacy_win7
        run: |-
          echo "PATH=$HOME/go/go_win7/bin:$PATH" >> $GITHUB_ENV
          echo "GOROOT=$HOME/go/go_win7" >> $GITHUB_ENV
      - name: Setup Android NDK
        if: matrix.os == 'android'
        uses: nttld/setup-ndk@v1
        with:
          ndk-version: r28
          local-cache: true
      - name: Clone cronet-go
        if: matrix.naive
        run: |
          set -xeuo pipefail
          CRONET_GO_VERSION=$(cat .github/CRONET_GO_VERSION)
          git init ~/cronet-go
          git -C ~/cronet-go remote add origin https://github.com/sagernet/cronet-go.git
          git -C ~/cronet-go fetch --depth=1 origin "$CRONET_GO_VERSION"
          git -C ~/cronet-go checkout FETCH_HEAD
          git -C ~/cronet-go submodule update --init --recursive --depth=1
      - name: Regenerate Debian keyring
        if: matrix.naive
        run: |
          set -xeuo pipefail
          rm -f ~/cronet-go/naiveproxy/src/build/linux/sysroot_scripts/keyring.gpg
          cd ~/cronet-go
          GPG_TTY=/dev/null ./naiveproxy/src/build/linux/sysroot_scripts/generate_keyring.sh
      - name: Cache Chromium toolchain
        if: matrix.naive
        id: cache-chromium-toolchain
        uses: actions/cache@v4
        with:
          path: |
            ~/cronet-go/naiveproxy/src/third_party/llvm-build/
            ~/cronet-go/naiveproxy/src/gn/out/
            ~/cronet-go/naiveproxy/src/chrome/build/pgo_profiles/
            ~/cronet-go/naiveproxy/src/out/sysroot-build/
          key: chromium-toolchain-${{ matrix.arch }}-${{ matrix.variant }}-${{ hashFiles('.github/CRONET_GO_VERSION') }}
      - name: Download Chromium toolchain
        if: matrix.naive
        run: |
          set -xeuo pipefail
          cd ~/cronet-go
          if [[ "${{ matrix.variant }}" == "musl" ]]; then
            go run ./cmd/build-naive --target=linux/${{ matrix.arch }} --libc=musl download-toolchain
          else
            go run ./cmd/build-naive --target=linux/${{ matrix.arch }} download-toolchain
          fi
      - name: Set Chromium toolchain environment
        if: matrix.naive
        run: |
          set -xeuo pipefail
          cd ~/cronet-go
          if [[ "${{ matrix.variant }}" == "musl" ]]; then
            go run ./cmd/build-naive --target=linux/${{ matrix.arch }} --libc=musl env >> $GITHUB_ENV
          else
            go run ./cmd/build-naive --target=linux/${{ matrix.arch }} env >> $GITHUB_ENV
          fi
      - name: Set tag
        run: |-
          git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
          git tag v${{ needs.calculate_version.outputs.version }} -f
      - name: Set build tags
        run: |
          set -xeuo pipefail
          if [[ "${{ matrix.naive }}" == "true" ]]; then
            TAGS=$(cat release/DEFAULT_BUILD_TAGS)
          else
            TAGS=$(cat release/DEFAULT_BUILD_TAGS_OTHERS)
          fi
          if [[ "${{ matrix.variant }}" == "purego" ]]; then
            TAGS="${TAGS},with_purego"
          elif [[ "${{ matrix.variant }}" == "musl" ]]; then
            TAGS="${TAGS},with_musl"
          fi
          echo "BUILD_TAGS=${TAGS}" >> "${GITHUB_ENV}"
      - name: Set shared ldflags
        run: |
          echo "LDFLAGS_SHARED=$(cat release/LDFLAGS)" >> "${GITHUB_ENV}"
      - name: Build (purego)
        if: matrix.variant == 'purego'
        run: |
          set -xeuo pipefail
          mkdir -p dist
          go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \
          -ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }}' ${LDFLAGS_SHARED} -s -w -buildid=" \
          ./cmd/sing-box
        env:
          CGO_ENABLED: "0"
          GOOS: ${{ matrix.os }}
          GOARCH: ${{ matrix.arch }}
          GO386: ${{ matrix.go386 }}
          GOARM: ${{ matrix.goarm }}
          GOMIPS: ${{ matrix.gomips }}
          GOMIPS64: ${{ matrix.gomips }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - name: Extract libcronet.so
        if: matrix.variant == 'purego' && matrix.naive
        run: |
          cd ~/cronet-go
          CGO_ENABLED=0 go run -v ./cmd/build-naive extract-lib --target ${{ matrix.os }}/${{ matrix.arch }} -o $GITHUB_WORKSPACE/dist
      - name: Build (glibc)
        if: matrix.variant == 'glibc'
        run: |
          set -xeuo pipefail
          mkdir -p dist
          go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \
          -ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }}' ${LDFLAGS_SHARED} -s -w -buildid=" \
          ./cmd/sing-box
        env:
          CGO_ENABLED: "1"
          GOOS: linux
          GOARCH: ${{ matrix.arch }}
          GO386: ${{ matrix.go386 }}
          GOARM: ${{ matrix.goarm }}
          GOMIPS: ${{ matrix.gomips }}
          GOMIPS64: ${{ matrix.gomips }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - name: Build (musl)
        if: matrix.variant == 'musl'
        run: |
          set -xeuo pipefail
          mkdir -p dist
          go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \
          -ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }}' ${LDFLAGS_SHARED} -s -w -buildid=" \
          ./cmd/sing-box
        env:
          CGO_ENABLED: "1"
          GOOS: linux
          GOARCH: ${{ matrix.arch }}
          GO386: ${{ matrix.go386 }}
          GOARM: ${{ matrix.goarm }}
          GOMIPS: ${{ matrix.gomips }}
          GOMIPS64: ${{ matrix.gomips }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - name: Build (non-variant)
        if: matrix.os != 'android' && matrix.variant == ''
        run: |
          set -xeuo pipefail
          mkdir -p dist
          go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \
          -ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }}' ${LDFLAGS_SHARED} -s -w -buildid=" \
          ./cmd/sing-box
        env:
          CGO_ENABLED: "0"
          GOOS: ${{ matrix.os }}
          GOARCH: ${{ matrix.arch }}
          GO386: ${{ matrix.go386 }}
          GOARM: ${{ matrix.goarm }}
          GOMIPS: ${{ matrix.gomips }}
          GOMIPS64: ${{ matrix.gomips }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - name: Build Android
        if: matrix.os == 'android'
        run: |
          set -xeuo pipefail
          go install -v ./cmd/internal/build
          export CC='${{ matrix.ndk }}-clang'
          export CXX="${CC}++"
          mkdir -p dist
          GOOS=$BUILD_GOOS GOARCH=$BUILD_GOARCH build go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \
          -ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }}' ${LDFLAGS_SHARED} -s -w -buildid=" \
          ./cmd/sing-box
        env:
          CGO_ENABLED: "1"
          BUILD_GOOS: ${{ matrix.os }}
          BUILD_GOARCH: ${{ matrix.arch }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - name: Set name
        run: |-
          DIR_NAME="sing-box-${{ needs.calculate_version.outputs.version }}-${{ matrix.os }}-${{ matrix.arch }}"
          if [[ -n "${{ matrix.goarm }}" ]]; then
            DIR_NAME="${DIR_NAME}v${{ matrix.goarm }}"
          elif [[ -n "${{ matrix.go386 }}" && "${{ matrix.go386 }}" != 'sse2' ]]; then
            DIR_NAME="${DIR_NAME}-${{ matrix.go386 }}"
          elif [[ -n "${{ matrix.gomips }}" && "${{ matrix.gomips }}" != 'hardfloat' ]]; then
            DIR_NAME="${DIR_NAME}-${{ matrix.gomips }}"
          elif [[ -n "${{ matrix.legacy_name }}" ]]; then
            DIR_NAME="${DIR_NAME}-legacy-${{ matrix.legacy_name }}"
          fi
          if [[ "${{ matrix.variant }}" == "glibc" ]]; then
            DIR_NAME="${DIR_NAME}-glibc"
          elif [[ "${{ matrix.variant }}" == "musl" ]]; then
            DIR_NAME="${DIR_NAME}-musl"
          fi
          echo "DIR_NAME=${DIR_NAME}" >> "${GITHUB_ENV}"
          PKG_VERSION="${{ needs.calculate_version.outputs.version }}"
          PKG_VERSION="${PKG_VERSION//-/\~}"
          echo "PKG_VERSION=${PKG_VERSION}" >> "${GITHUB_ENV}"
      - name: Package DEB
        if: matrix.debian != ''
        run: |
          set -xeuo pipefail
          sudo gem install fpm
          sudo apt-get update
          sudo apt-get install -y debsigs
          cp .fpm_systemd .fpm
          fpm -t deb \
            -v "$PKG_VERSION" \
            -p "dist/sing-box_${{ needs.calculate_version.outputs.version }}_${{ matrix.os }}_${{ matrix.debian }}.deb" \
            --architecture ${{ matrix.debian }} \
            dist/sing-box=/usr/bin/sing-box
          curl -Lo '/tmp/debsigs.diff' 'https://gitlab.com/debsigs/debsigs/-/commit/160138f5de1ec110376d3c807b60a37388bc7c90.diff'
          sudo patch /usr/bin/debsigs < '/tmp/debsigs.diff'
          rm -rf $HOME/.gnupg
          gpg --pinentry-mode loopback --passphrase "${{ secrets.GPG_PASSPHRASE }}" --import <<EOF
          ${{ secrets.GPG_KEY }}
          EOF
          debsigs --sign=origin -k ${{ secrets.GPG_KEY_ID }} --gpgopts '--pinentry-mode loopback --passphrase "${{ secrets.GPG_PASSPHRASE }}"' dist/*.deb
      - name: Package RPM
        if: matrix.rpm != ''
        run: |-
          set -xeuo pipefail
          sudo gem install fpm
          cp .fpm_systemd .fpm
          fpm -t rpm \
            -v "$PKG_VERSION" \
            -p "dist/sing-box_${{ needs.calculate_version.outputs.version }}_${{ matrix.os }}_${{ matrix.rpm }}.rpm" \
            --architecture ${{ matrix.rpm }} \
            dist/sing-box=/usr/bin/sing-box
          cat > $HOME/.rpmmacros <<EOF
          %_gpg_name ${{ secrets.GPG_KEY_ID }}
          %_gpg_sign_cmd_extra_args --pinentry-mode loopback --passphrase ${{ secrets.GPG_PASSPHRASE }}
          EOF
          gpg --pinentry-mode loopback --passphrase "${{ secrets.GPG_PASSPHRASE }}" --import <<EOF
          ${{ secrets.GPG_KEY }}
          EOF
          rpmsign --addsign dist/*.rpm
      - name: Package Pacman
        if: matrix.pacman != ''
        run: |-
          set -xeuo pipefail
          sudo gem install fpm
          sudo apt-get update
          sudo apt-get install -y libarchive-tools
          cp .fpm_pacman .fpm
          fpm -t pacman \
            -v "$PKG_VERSION" \
            -p "dist/sing-box_${{ needs.calculate_version.outputs.version }}_${{ matrix.os }}_${{ matrix.pacman }}.pkg.tar.zst" \
            --architecture ${{ matrix.pacman }} \
            dist/sing-box=/usr/bin/sing-box
      - name: Package OpenWrt
        if: matrix.openwrt != ''
        run: |-
          set -xeuo pipefail
          sudo gem install fpm
          cp .fpm_openwrt .fpm
          fpm -t deb \
            -v "$PKG_VERSION" \
            -p "dist/openwrt.deb" \
            --architecture all \
            dist/sing-box=/usr/bin/sing-box
          for architecture in ${{ matrix.openwrt }}; do
            .github/deb2ipk.sh "$architecture" "dist/openwrt.deb" "dist/sing-box_${{ needs.calculate_version.outputs.version }}_openwrt_${architecture}.ipk"
          done
          rm "dist/openwrt.deb"
      - name: Install apk-tools
        if: matrix.openwrt != '' || matrix.alpine != ''
        run: |-
          docker run --rm -v /usr/local/bin:/mnt alpine:edge sh -c "apk add --no-cache apk-tools-static && cp /sbin/apk.static /mnt/apk && chmod +x /mnt/apk"
      - name: Package OpenWrt APK
        if: matrix.openwrt != ''
        run: |-
          set -xeuo pipefail
          for architecture in ${{ matrix.openwrt }}; do
            .github/build_openwrt_apk.sh \
              "$architecture" \
              "${{ needs.calculate_version.outputs.version }}" \
              "dist/sing-box" \
              "dist/sing-box_${{ needs.calculate_version.outputs.version }}_openwrt_${architecture}.apk"
          done
      - name: Package Alpine APK
        if: matrix.alpine != ''
        run: |-
          set -xeuo pipefail
          .github/build_alpine_apk.sh \
            "${{ matrix.alpine }}" \
            "${{ needs.calculate_version.outputs.version }}" \
            "dist/sing-box" \
            "dist/sing-box_${{ needs.calculate_version.outputs.version }}_linux_${{ matrix.alpine }}.apk"
      - name: Archive
        run: |
          set -xeuo pipefail
          cd dist
          mkdir -p "${DIR_NAME}"
          cp ../LICENSE "${DIR_NAME}"
          if [ '${{ matrix.os }}' = 'windows' ]; then
            cp sing-box "${DIR_NAME}/sing-box.exe"
            zip -r "${DIR_NAME}.zip" "${DIR_NAME}"
          else
            cp sing-box "${DIR_NAME}"
            if [ -f libcronet.so ]; then
              cp libcronet.so "${DIR_NAME}"
            fi
            tar -czvf "${DIR_NAME}.tar.gz" "${DIR_NAME}"
          fi
          rm -r "${DIR_NAME}"
      - name: Cleanup
        run: rm -f dist/sing-box dist/libcronet.so
      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: binary-${{ matrix.os }}_${{ matrix.arch }}${{ matrix.goarm && format('v{0}', matrix.goarm) }}${{ matrix.go386 && format('_{0}', matrix.go386) }}${{ matrix.gomips && format('_{0}', matrix.gomips) }}${{ matrix.legacy_name && format('-legacy-{0}', matrix.legacy_name) }}${{ matrix.variant && format('-{0}', matrix.variant) }}
          path: "dist"
  build_darwin:
    name: Build Darwin binaries
    if: github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Binary'
    runs-on: macos-latest
    needs:
      - calculate_version
    strategy:
      matrix:
        include:
          - { arch: amd64 }
          - { arch: arm64 }
          - { arch: amd64, legacy_osx: true, legacy_name: "macos-10.13" }
    steps:
      - name: Checkout
        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
        with:
          fetch-depth: 0
      - name: Setup Go
        if: ${{ ! matrix.legacy_osx }}
        uses: actions/setup-go@v5
        with:
          go-version: ^1.25.3
      - name: Cache Go for macOS 10.13
        if: matrix.legacy_osx
        id: cache-go-for-macos1013
        uses: actions/cache@v4
        with:
          path: |
            ~/go/go_osx
          key: go_osx_1258
      - name: Setup Go for macOS 10.13
        if: matrix.legacy_osx && steps.cache-go-for-macos1013.outputs.cache-hit != 'true'
        env:
          GITHUB_TOKEN: ${{ github.token }}
        run: |-
          .github/setup_go_for_macos1013.sh
      - name: Setup Go for macOS 10.13
        if: matrix.legacy_osx
        run: |-
          echo "PATH=$HOME/go/go_osx/bin:$PATH" >> $GITHUB_ENV
          echo "GOROOT=$HOME/go/go_osx" >> $GITHUB_ENV
      - name: Set tag
        run: |-
          git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
          git tag v${{ needs.calculate_version.outputs.version }} -f
      - name: Set build tags
        run: |
          set -xeuo pipefail
          if [[ "${{ matrix.legacy_osx }}" != "true" ]]; then
            TAGS=$(cat release/DEFAULT_BUILD_TAGS)
          else
            TAGS=$(cat release/DEFAULT_BUILD_TAGS_OTHERS)
          fi
          echo "BUILD_TAGS=${TAGS}" >> "${GITHUB_ENV}"
      - name: Set shared ldflags
        run: |
          echo "LDFLAGS_SHARED=$(cat release/LDFLAGS)" >> "${GITHUB_ENV}"
      - name: Build
        run: |
          set -xeuo pipefail
          mkdir -p dist
          go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \
          -ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }}' ${LDFLAGS_SHARED} -s -w -buildid=" \
          ./cmd/sing-box
        env:
          CGO_ENABLED: "1"
          GOOS: darwin
          GOARCH: ${{ matrix.arch }}
          MACOSX_DEPLOYMENT_TARGET: ${{ matrix.legacy_osx && '10.13' || '' }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - name: Set name
        run: |-
          DIR_NAME="sing-box-${{ needs.calculate_version.outputs.version }}-darwin-${{ matrix.arch }}"
          if [[ -n "${{ matrix.legacy_name }}" ]]; then
            DIR_NAME="${DIR_NAME}-legacy-${{ matrix.legacy_name }}"
          fi
          echo "DIR_NAME=${DIR_NAME}" >> "${GITHUB_ENV}"
      - name: Archive
        run: |
          set -xeuo pipefail
          cd dist
          mkdir -p "${DIR_NAME}"
          cp ../LICENSE "${DIR_NAME}"
          cp sing-box "${DIR_NAME}"
          tar -czvf "${DIR_NAME}.tar.gz" "${DIR_NAME}"
          rm -r "${DIR_NAME}"
      - name: Cleanup
        run: rm dist/sing-box
      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: binary-darwin_${{ matrix.arch }}${{ matrix.legacy_name && format('-legacy-{0}', matrix.legacy_name) }}
          path: "dist"
  build_windows:
    name: Build Windows binaries
    if: github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Binary'
    runs-on: windows-latest
    needs:
      - calculate_version
    strategy:
      matrix:
        include:
          - { arch: amd64, naive: true }
          - { arch: "386" }
          - { arch: arm64, naive: true }
    steps:
      - name: Checkout
        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
        with:
          fetch-depth: 0
      - name: Setup Go
        uses: actions/setup-go@v5
        with:
          go-version: ^1.25.4
      - name: Set tag
        run: |-
          git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$env:GITHUB_ENV"
          git tag v${{ needs.calculate_version.outputs.version }} -f
      - name: Build
        if: matrix.naive
        run: |
          $TAGS = Get-Content release/DEFAULT_BUILD_TAGS_WINDOWS
          $LDFLAGS_SHARED = Get-Content release/LDFLAGS
          mkdir -p dist
          go build -v -trimpath -o dist/sing-box.exe -tags "$TAGS" `
          -ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }}' $LDFLAGS_SHARED -s -w -buildid=" `
          ./cmd/sing-box
        env:
          CGO_ENABLED: "0"
          GOOS: windows
          GOARCH: ${{ matrix.arch }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - name: Build
        if: ${{ !matrix.naive }}
        run: |
          $TAGS = Get-Content release/DEFAULT_BUILD_TAGS_OTHERS
          $LDFLAGS_SHARED = Get-Content release/LDFLAGS
          mkdir -p dist
          go build -v -trimpath -o dist/sing-box.exe -tags "$TAGS" `
          -ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }}' $LDFLAGS_SHARED -s -w -buildid=" `
          ./cmd/sing-box
        env:
          CGO_ENABLED: "0"
          GOOS: windows
          GOARCH: ${{ matrix.arch }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - name: Extract libcronet.dll
        if: matrix.naive
        run: |
          $CRONET_GO_VERSION = Get-Content .github/CRONET_GO_VERSION
          $env:CGO_ENABLED = "0"
          go run -v "github.com/sagernet/cronet-go/cmd/build-naive@$CRONET_GO_VERSION" extract-lib --target windows/${{ matrix.arch }} -o dist
      - name: Archive
        if: matrix.naive
        run: |
          $DIR_NAME = "sing-box-${{ needs.calculate_version.outputs.version }}-windows-${{ matrix.arch }}"
          mkdir "dist/$DIR_NAME"
          Copy-Item LICENSE "dist/$DIR_NAME"
          Copy-Item "dist/sing-box.exe" "dist/$DIR_NAME"
          Copy-Item "dist/libcronet.dll" "dist/$DIR_NAME"
          Compress-Archive -Path "dist/$DIR_NAME" -DestinationPath "dist/$DIR_NAME.zip"
          Remove-Item -Recurse "dist/$DIR_NAME"
      - name: Archive
        if: ${{ !matrix.naive }}
        run: |
          $DIR_NAME = "sing-box-${{ needs.calculate_version.outputs.version }}-windows-${{ matrix.arch }}"
          mkdir "dist/$DIR_NAME"
          Copy-Item LICENSE "dist/$DIR_NAME"
          Copy-Item "dist/sing-box.exe" "dist/$DIR_NAME"
          Compress-Archive -Path "dist/$DIR_NAME" -DestinationPath "dist/$DIR_NAME.zip"
          Remove-Item -Recurse "dist/$DIR_NAME"
      - name: Cleanup
        if: matrix.naive
        run: Remove-Item dist/sing-box.exe, dist/libcronet.dll
      - name: Cleanup
        if: ${{ !matrix.naive }}
        run: Remove-Item dist/sing-box.exe
      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: binary-windows_${{ matrix.arch }}
          path: "dist"
  build_android:
    name: Build Android
    if: (github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Android') && github.ref != 'refs/heads/oldstable'
    runs-on: ubuntu-latest
    needs:
      - calculate_version
    steps:
      - name: Checkout
        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
        with:
          fetch-depth: 0
          submodules: 'recursive'
      - name: Setup Go
        uses: actions/setup-go@v5
        with:
          go-version: ~1.25.8
      - name: Setup Android NDK
        id: setup-ndk
        uses: nttld/setup-ndk@v1
        with:
          ndk-version: r28
      - name: Setup OpenJDK
        run: |-
          sudo apt update && sudo apt install -y openjdk-17-jdk-headless
          /usr/lib/jvm/java-17-openjdk-amd64/bin/java --version
      - name: Set tag
        run: |-
          git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
          git tag v${{ needs.calculate_version.outputs.version }} -f
      - name: Build library
        run: |-
          make lib_install
          export PATH="$PATH:$(go env GOPATH)/bin"
          make lib_android
        env:
          JAVA_HOME: /usr/lib/jvm/java-17-openjdk-amd64
          ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
      - name: Checkout main branch
        if: github.ref == 'refs/heads/stable' && github.event_name != 'workflow_dispatch'
        run: |-
          cd clients/android
          git checkout main
      - name: Checkout dev branch
        if: github.ref == 'refs/heads/testing'
        run: |-
          cd clients/android
          git checkout dev
      - name: Gradle cache
        uses: actions/cache@v4
        with:
          path: ~/.gradle
          key: gradle-${{ hashFiles('**/*.gradle') }}
      - name: Update version
        if: github.event_name == 'workflow_dispatch'
        run: |-
          go run -v ./cmd/internal/update_android_version --ci
      - name: Update nightly version
        if: github.event_name != 'workflow_dispatch'
        run: |-
          go run -v ./cmd/internal/update_android_version --ci --nightly
      - name: Build
        run: |-
          mkdir clients/android/app/libs
          cp *.aar clients/android/app/libs
          cd clients/android
          ./gradlew :app:assembleOtherRelease :app:assembleOtherLegacyRelease
        env:
          JAVA_HOME: /usr/lib/jvm/java-17-openjdk-amd64
          ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
          LOCAL_PROPERTIES: ${{ secrets.LOCAL_PROPERTIES }}
      - name: Prepare upload
        run: |-
          mkdir -p dist
          #cp clients/android/app/build/outputs/apk/play/release/*.apk dist
          cp clients/android/app/build/outputs/apk/other/release/*.apk dist
          cp clients/android/app/build/outputs/apk/otherLegacy/release/*.apk dist
          VERSION_CODE=$(grep VERSION_CODE clients/android/version.properties | cut -d= -f2)
          VERSION_NAME=$(grep VERSION_NAME clients/android/version.properties | cut -d= -f2)
          cat > dist/SFA-version-metadata.json << EOF
          {
            "version_code": ${VERSION_CODE},
            "version_name": "${VERSION_NAME}"
          }
          EOF
          cat dist/SFA-version-metadata.json
      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: binary-android-apks
          path: 'dist'
  publish_android:
    name: Publish Android
    if: github.event_name == 'workflow_dispatch' && inputs.build == 'publish-android' && github.ref != 'refs/heads/oldstable'
    runs-on: ubuntu-latest
    needs:
      - calculate_version
    steps:
      - name: Checkout
        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
        with:
          fetch-depth: 0
          submodules: 'recursive'
      - name: Setup Go
        uses: actions/setup-go@v5
        with:
          go-version: ~1.25.8
      - name: Setup Android NDK
        id: setup-ndk
        uses: nttld/setup-ndk@v1
        with:
          ndk-version: r28
      - name: Setup OpenJDK
        run: |-
          sudo apt update && sudo apt install -y openjdk-17-jdk-headless
          /usr/lib/jvm/java-17-openjdk-amd64/bin/java --version
      - name: Set tag
        run: |-
          git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
          git tag v${{ needs.calculate_version.outputs.version }} -f
      - name: Build library
        run: |-
          make lib_install
          export PATH="$PATH:$(go env GOPATH)/bin"
          make lib_android
        env:
          JAVA_HOME: /usr/lib/jvm/java-17-openjdk-amd64
          ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
      - name: Checkout main branch
        if: github.ref == 'refs/heads/stable' && github.event_name != 'workflow_dispatch'
        run: |-
          cd clients/android
          git checkout main
      - name: Checkout dev branch
        if: github.ref == 'refs/heads/testing'
        run: |-
          cd clients/android
          git checkout dev
      - name: Gradle cache
        uses: actions/cache@v4
        with:
          path: ~/.gradle
          key: gradle-${{ hashFiles('**/*.gradle') }}
      - name: Build
        run: |-
          go run -v ./cmd/internal/update_android_version --ci
          mkdir clients/android/app/libs
          cp *.aar clients/android/app/libs
          cd clients/android
          echo -n "$SERVICE_ACCOUNT_CREDENTIALS" | base64 --decode > service-account-credentials.json
          ./gradlew :app:publishPlayReleaseBundle
        env:
          JAVA_HOME: /usr/lib/jvm/java-17-openjdk-amd64
          ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
          LOCAL_PROPERTIES: ${{ secrets.LOCAL_PROPERTIES }}
          SERVICE_ACCOUNT_CREDENTIALS: ${{ secrets.SERVICE_ACCOUNT_CREDENTIALS }}
  build_apple:
    name: Build Apple clients
    runs-on: macos-26
    if: false # github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Apple' || inputs.build == 'app-store' || inputs.build == 'iOS' || inputs.build == 'macOS' || inputs.build == 'tvOS' || inputs.build == 'macOS-standalone'
    needs:
      - calculate_version
    strategy:
      matrix:
        include:
          - name: iOS
            if: ${{ github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Apple' || inputs.build == 'app-store'|| inputs.build == 'iOS' }}
            platform: ios
            scheme: SFI
            destination: 'generic/platform=iOS'
            archive: build/SFI.xcarchive
            upload: SFI/Upload.plist
          - name: macOS
            if: ${{ github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Apple' || inputs.build == 'app-store'|| inputs.build == 'macOS' }}
            platform: macos
            scheme: SFM
            destination: 'generic/platform=macOS'
            archive: build/SFM.xcarchive
            upload: SFI/Upload.plist
          - name: tvOS
            if: ${{ github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Apple' || inputs.build == 'app-store'|| inputs.build == 'tvOS' }}
            platform: tvos
            scheme: SFT
            destination: 'generic/platform=tvOS'
            archive: build/SFT.xcarchive
            upload: SFI/Upload.plist
          - name: macOS-standalone
            if: ${{ github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Apple' || inputs.build == 'macOS-standalone' }}
            platform: macos
            scheme: SFM.System
            destination: 'generic/platform=macOS'
            archive: build/SFM.System.xcarchive
            export: SFM.System/Export.plist
            export_path: build/SFM.System
    steps:
      - name: Checkout
        if: matrix.if
        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
        with:
          fetch-depth: 0
          submodules: 'recursive'
      - name: Setup Go
        if: matrix.if
        uses: actions/setup-go@v5
        with:
          go-version: ~1.25.8
      - name: Set tag
        if: matrix.if
        run: |-
          git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
          git tag v${{ needs.calculate_version.outputs.version }} -f
          echo "VERSION=${{ needs.calculate_version.outputs.version }}" >> "$GITHUB_ENV"
      - name: Checkout main branch
        if: matrix.if && github.ref == 'refs/heads/stable' && github.event_name != 'workflow_dispatch'
        run: |-
          cd clients/apple
          git checkout main
      - name: Checkout dev branch
        if: matrix.if && github.ref == 'refs/heads/testing'
        run: |-
          cd clients/apple
          git checkout dev
      - name: Setup certificates
        if: matrix.if
        run: |-
          CERTIFICATE_PATH=$RUNNER_TEMP/Certificates.p12
          KEYCHAIN_PATH=$RUNNER_TEMP/certificates.keychain-db
          echo -n "$CERTIFICATES_P12" | base64 --decode -o $CERTIFICATE_PATH
          security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
          security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
          security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
          security import $CERTIFICATE_PATH -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
          security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
          security list-keychain -d user -s $KEYCHAIN_PATH

          PROFILES_ZIP_PATH=$RUNNER_TEMP/Profiles.zip
          echo -n "$PROVISIONING_PROFILES" | base64 --decode -o $PROFILES_ZIP_PATH

          PROFILES_PATH="$HOME/Library/MobileDevice/Provisioning Profiles"
          mkdir -p "$PROFILES_PATH"
          unzip $PROFILES_ZIP_PATH -d "$PROFILES_PATH"

          ASC_KEY_PATH=$RUNNER_TEMP/Key.p12
          echo -n "$ASC_KEY" | base64 --decode -o $ASC_KEY_PATH

          xcrun notarytool store-credentials "notarytool-password" \
            --key $ASC_KEY_PATH \
            --key-id $ASC_KEY_ID \
            --issuer $ASC_KEY_ISSUER_ID

          echo "ASC_KEY_PATH=$ASC_KEY_PATH" >> "$GITHUB_ENV"
          echo "ASC_KEY_ID=$ASC_KEY_ID" >> "$GITHUB_ENV"
          echo "ASC_KEY_ISSUER_ID=$ASC_KEY_ISSUER_ID" >> "$GITHUB_ENV"
        env:
          CERTIFICATES_P12: ${{ secrets.CERTIFICATES_P12 }}
          P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
          KEYCHAIN_PASSWORD: ${{ secrets.P12_PASSWORD }}
          PROVISIONING_PROFILES: ${{ secrets.PROVISIONING_PROFILES }}
          ASC_KEY: ${{ secrets.ASC_KEY }}
          ASC_KEY_ID: ${{ secrets.ASC_KEY_ID }}
          ASC_KEY_ISSUER_ID: ${{ secrets.ASC_KEY_ISSUER_ID }}
      - name: Build library
        if: matrix.if
        run: |-
          make lib_install
          export PATH="$PATH:$(go env GOPATH)/bin"
          go run ./cmd/internal/build_libbox -target apple -platform ${{ matrix.platform }}
          mv Libbox.xcframework clients/apple
      - name: Update macOS version
        if: matrix.if && matrix.name == 'macOS' && github.event_name == 'workflow_dispatch'
        run: |-
          MACOS_PROJECT_VERSION=$(go run -v ./cmd/internal/app_store_connect next_macos_project_version)
          echo "MACOS_PROJECT_VERSION=$MACOS_PROJECT_VERSION"
          echo "MACOS_PROJECT_VERSION=$MACOS_PROJECT_VERSION" >> "$GITHUB_ENV"
      - name: Update version
        if: matrix.if && matrix.name != 'iOS'
        run: |-
          go run -v ./cmd/internal/update_apple_version --ci
      - name: Build
        if: matrix.if
        run: |-
          cd clients/apple
          xcodebuild archive \
            -scheme "${{ matrix.scheme }}" \
            -configuration Release \
            -destination "${{ matrix.destination }}" \
            -archivePath "${{ matrix.archive }}" \
            -allowProvisioningUpdates \
            -authenticationKeyPath $ASC_KEY_PATH \
            -authenticationKeyID $ASC_KEY_ID \
            -authenticationKeyIssuerID $ASC_KEY_ISSUER_ID
      - name: Upload to App Store Connect
        if: matrix.if && matrix.name != 'macOS-standalone' && github.event_name == 'workflow_dispatch'
        run: |-
          go run -v ./cmd/internal/app_store_connect cancel_app_store ${{ matrix.platform }}
          cd clients/apple
          xcodebuild -exportArchive \
            -archivePath "${{ matrix.archive }}" \
            -exportOptionsPlist ${{ matrix.upload }} \
            -allowProvisioningUpdates \
            -authenticationKeyPath $ASC_KEY_PATH \
            -authenticationKeyID $ASC_KEY_ID \
            -authenticationKeyIssuerID $ASC_KEY_ISSUER_ID
      - name: Publish to TestFlight
        if: matrix.if && matrix.name != 'macOS-standalone' && github.event_name == 'workflow_dispatch' && github.ref =='refs/heads/testing'
        run: |-
          go run -v ./cmd/internal/app_store_connect publish_testflight ${{ matrix.platform }}
      - name: Build image
        if: matrix.if && matrix.name == 'macOS-standalone' && github.event_name == 'workflow_dispatch'
        run: |-
          pushd clients/apple
          xcodebuild -exportArchive \
          	-archivePath "${{ matrix.archive }}" \
          	-exportOptionsPlist ${{ matrix.export }} \
          	-exportPath "${{ matrix.export_path }}"
          brew install create-dmg
          create-dmg \
          	--volname "sing-box" \
          	--volicon "${{ matrix.export_path }}/SFM.app/Contents/Resources/AppIcon.icns" \
          	--icon "SFM.app" 0 0 \
          		--hide-extension "SFM.app" \
          		--app-drop-link 0 0 \
          		--skip-jenkins \
          	SFM.dmg "${{ matrix.export_path }}/SFM.app"
          xcrun notarytool submit "SFM.dmg" --wait --keychain-profile "notarytool-password"
          cd "${{ matrix.archive }}"
          zip -r SFM.dSYMs.zip dSYMs
          popd

          mkdir -p dist
          cp clients/apple/SFM.dmg "dist/SFM-${VERSION}-universal.dmg"
          cp "clients/apple/${{ matrix.archive }}/SFM.dSYMs.zip" "dist/SFM-${VERSION}-universal.dSYMs.zip"
      - name: Upload image
        if: matrix.if && matrix.name == 'macOS-standalone' && github.event_name == 'workflow_dispatch'
        uses: actions/upload-artifact@v4
        with:
          name: binary-macos-dmg
          path: 'dist'
  upload:
    name: Upload builds
    if: "!failure() && github.event_name == 'workflow_dispatch' && (inputs.build == 'All' || inputs.build == 'Binary' || inputs.build == 'Android' || inputs.build == 'Apple' || inputs.build == 'macOS-standalone')"
    runs-on: ubuntu-latest
    needs:
      - calculate_version
      - build
      - build_darwin
      - build_windows
      - build_android
      - build_apple
    steps:
      - name: Checkout
        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
        with:
          fetch-depth: 0
      - name: Cache ghr
        uses: actions/cache@v4
        id: cache-ghr
        with:
          path: |
            ~/go/bin/ghr
          key: ghr
      - name: Setup ghr
        if: steps.cache-ghr.outputs.cache-hit != 'true'
        run: |-
          cd $HOME
          git clone https://github.com/nekohasekai/ghr ghr
          cd ghr
          go install -v .
      - name: Set tag
        run: |-
          git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
          git tag v${{ needs.calculate_version.outputs.version }} -f
          echo "VERSION=${{ needs.calculate_version.outputs.version }}" >> "$GITHUB_ENV"
      - name: Download builds
        uses: actions/download-artifact@v5
        with:
          path: dist
          merge-multiple: true
      - name: Upload builds
        if: ${{ env.PUBLISHED == 'false' }}
        run: |-
          export PATH="$PATH:$HOME/go/bin"
          ghr --replace --draft --prerelease -p 5 "v${VERSION}" dist
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - name: Replace builds
        if: ${{ env.PUBLISHED != 'false' }}
        run: |-
          export PATH="$PATH:$HOME/go/bin"
          ghr --replace -p 5 "v${VERSION}" dist
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


================================================
FILE: .github/workflows/docker.yml
================================================
name: Publish Docker Images

on:
  #push:
  #  branches:
  #    - stable
  #    - testing
  release:
    types:
      - published
  workflow_dispatch:
    inputs:
      tag:
        description: "The tag version you want to build"

env:
  REGISTRY_IMAGE: ghcr.io/sagernet/sing-box

jobs:
  build_binary:
    name: Build binary
    if: github.event_name != 'release' || github.event.release.target_commitish != 'oldstable'
    runs-on: ubuntu-latest
    strategy:
      fail-fast: true
      matrix:
        include:
          # Naive-enabled builds (musl)
          - { arch: amd64, naive: true, docker_platform: "linux/amd64" }
          - { arch: arm64, naive: true, docker_platform: "linux/arm64" }
          - { arch: "386", naive: true, docker_platform: "linux/386" }
          - { arch: arm, goarm: "7", naive: true, docker_platform: "linux/arm/v7" }
          - { arch: mipsle, gomips: softfloat, naive: true, docker_platform: "linux/mipsle" }
          - { arch: riscv64, naive: true, docker_platform: "linux/riscv64" }
          - { arch: loong64, naive: true, docker_platform: "linux/loong64" }
          # Non-naive builds
          - { arch: arm, goarm: "6", docker_platform: "linux/arm/v6" }
          - { arch: ppc64le, docker_platform: "linux/ppc64le" }
          - { arch: s390x, docker_platform: "linux/s390x" }
    steps:
      - name: Get commit to build
        id: ref
        run: |-
          if [[ -z "${{ github.event.inputs.tag }}" ]]; then
            ref="${{ github.ref_name }}"
          else
            ref="${{ github.event.inputs.tag }}"
          fi
          echo "ref=$ref"
          echo "ref=$ref" >> $GITHUB_OUTPUT
      - name: Checkout
        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
        with:
          ref: ${{ steps.ref.outputs.ref }}
          fetch-depth: 0
      - name: Setup Go
        uses: actions/setup-go@v5
        with:
          go-version: ~1.25.8
      - name: Clone cronet-go
        if: matrix.naive
        run: |
          set -xeuo pipefail
          CRONET_GO_VERSION=$(cat .github/CRONET_GO_VERSION)
          git init ~/cronet-go
          git -C ~/cronet-go remote add origin https://github.com/sagernet/cronet-go.git
          git -C ~/cronet-go fetch --depth=1 origin "$CRONET_GO_VERSION"
          git -C ~/cronet-go checkout FETCH_HEAD
          git -C ~/cronet-go submodule update --init --recursive --depth=1
      - name: Regenerate Debian keyring
        if: matrix.naive
        run: |
          set -xeuo pipefail
          rm -f ~/cronet-go/naiveproxy/src/build/linux/sysroot_scripts/keyring.gpg
          cd ~/cronet-go
          GPG_TTY=/dev/null ./naiveproxy/src/build/linux/sysroot_scripts/generate_keyring.sh
      - name: Cache Chromium toolchain
        if: matrix.naive
        id: cache-chromium-toolchain
        uses: actions/cache@v4
        with:
          path: |
            ~/cronet-go/naiveproxy/src/third_party/llvm-build/
            ~/cronet-go/naiveproxy/src/gn/out/
            ~/cronet-go/naiveproxy/src/chrome/build/pgo_profiles/
            ~/cronet-go/naiveproxy/src/out/sysroot-build/
          key: chromium-toolchain-${{ matrix.arch }}-musl-${{ hashFiles('.github/CRONET_GO_VERSION') }}
      - name: Download Chromium toolchain
        if: matrix.naive
        run: |
          set -xeuo pipefail
          cd ~/cronet-go
          go run ./cmd/build-naive --target=linux/${{ matrix.arch }} --libc=musl download-toolchain
      - name: Set version
        run: |
          set -xeuo pipefail
          VERSION=$(go run ./cmd/internal/read_tag)
          echo "VERSION=${VERSION}" >> "${GITHUB_ENV}"
      - name: Set Chromium toolchain environment
        if: matrix.naive
        run: |
          set -xeuo pipefail
          cd ~/cronet-go
          go run ./cmd/build-naive --target=linux/${{ matrix.arch }} --libc=musl env >> $GITHUB_ENV
      - name: Set build tags
        run: |
          set -xeuo pipefail
          if [[ "${{ matrix.naive }}" == "true" ]]; then
            TAGS="$(cat release/DEFAULT_BUILD_TAGS),with_musl"
          else
            TAGS=$(cat release/DEFAULT_BUILD_TAGS_OTHERS)
          fi
          echo "BUILD_TAGS=${TAGS}" >> "${GITHUB_ENV}"
      - name: Set shared ldflags
        run: |
          echo "LDFLAGS_SHARED=$(cat release/LDFLAGS)" >> "${GITHUB_ENV}"
      - name: Build (naive)
        if: matrix.naive
        run: |
          set -xeuo pipefail
          go build -v -trimpath -o sing-box -tags "${BUILD_TAGS}" \
          -ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${VERSION}' ${LDFLAGS_SHARED} -s -w -buildid=" \
          ./cmd/sing-box
        env:
          CGO_ENABLED: "1"
          GOOS: linux
          GOARCH: ${{ matrix.arch }}
          GOARM: ${{ matrix.goarm }}
          GOMIPS: ${{ matrix.gomips }}
      - name: Build (non-naive)
        if: ${{ ! matrix.naive }}
        run: |
          set -xeuo pipefail
          go build -v -trimpath -o sing-box -tags "${BUILD_TAGS}" \
          -ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${VERSION}' ${LDFLAGS_SHARED} -s -w -buildid=" \
          ./cmd/sing-box
        env:
          CGO_ENABLED: "0"
          GOOS: linux
          GOARCH: ${{ matrix.arch }}
          GOARM: ${{ matrix.goarm }}
      - name: Prepare artifact
        run: |
          platform=${{ matrix.docker_platform }}
          echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
          # Rename binary to include arch info for Dockerfile.binary
          BINARY_NAME="sing-box-${{ matrix.arch }}"
          if [[ -n "${{ matrix.goarm }}" ]]; then
            BINARY_NAME="${BINARY_NAME}v${{ matrix.goarm }}"
          fi
          mv sing-box "${BINARY_NAME}"
          echo "BINARY_NAME=${BINARY_NAME}" >> $GITHUB_ENV
      - name: Upload binary
        uses: actions/upload-artifact@v4
        with:
          name: binary-${{ env.PLATFORM_PAIR }}
          path: ${{ env.BINARY_NAME }}
          if-no-files-found: error
          retention-days: 1
  build_docker:
    name: Build Docker image
    runs-on: ubuntu-latest
    needs:
      - build_binary
    strategy:
      fail-fast: true
      matrix:
        include:
          - { platform: "linux/amd64" }
          - { platform: "linux/arm/v6" }
          - { platform: "linux/arm/v7" }
          - { platform: "linux/arm64" }
          - { platform: "linux/386" }
          # mipsle: no base Docker image available for this platform
          - { platform: "linux/ppc64le" }
          - { platform: "linux/riscv64" }
          - { platform: "linux/s390x" }
          - { platform: "linux/loong64", base_image: "ghcr.io/loong64/alpine:edge" }
    steps:
      - name: Get commit to build
        id: ref
        run: |-
          if [[ -z "${{ github.event.inputs.tag }}" ]]; then
            ref="${{ github.ref_name }}"
          else
            ref="${{ github.event.inputs.tag }}"
          fi
          echo "ref=$ref"
          echo "ref=$ref" >> $GITHUB_OUTPUT
      - name: Checkout
        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
        with:
          ref: ${{ steps.ref.outputs.ref }}
          fetch-depth: 0
      - name: Prepare
        run: |
          platform=${{ matrix.platform }}
          echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
      - name: Download binary
        uses: actions/download-artifact@v5
        with:
          name: binary-${{ env.PLATFORM_PAIR }}
          path: .
      - name: Prepare binary
        run: |
          # Find and make the binary executable
          chmod +x sing-box-*
          ls -la sing-box-*
      - name: Setup QEMU
        uses: docker/setup-qemu-action@v3
      - name: Setup Docker Buildx
        uses: docker/setup-buildx-action@v3
      - name: Login to GitHub Container Registry
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - name: Docker meta
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.REGISTRY_IMAGE }}
      - name: Build and push by digest
        id: build
        uses: docker/build-push-action@v6
        with:
          platforms: ${{ matrix.platform }}
          context: .
          file: Dockerfile.binary
          build-args: |
            BASE_IMAGE=${{ matrix.base_image || 'alpine' }}
          labels: ${{ steps.meta.outputs.labels }}
          outputs: type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true
      - name: Export digest
        run: |
          mkdir -p /tmp/digests
          digest="${{ steps.build.outputs.digest }}"
          touch "/tmp/digests/${digest#sha256:}"
      - name: Upload digest
        uses: actions/upload-artifact@v4
        with:
          name: digests-${{ env.PLATFORM_PAIR }}
          path: /tmp/digests/*
          if-no-files-found: error
          retention-days: 1
  merge:
    if: github.event_name != 'push'
    runs-on: ubuntu-latest
    needs:
      - build_docker
    steps:
      - name: Get commit to build
        id: ref
        run: |-
          if [[ -z "${{ github.event.inputs.tag }}" ]]; then
            ref="${{ github.ref_name }}"
          else
            ref="${{ github.event.inputs.tag }}"
          fi
          echo "ref=$ref"
          echo "ref=$ref" >> $GITHUB_OUTPUT
          if [[ $ref == *"-"* ]]; then
            latest=latest-beta
          else
            latest=latest
          fi
          echo "latest=$latest"
          echo "latest=$latest" >> $GITHUB_OUTPUT
      - name: Download digests
        uses: actions/download-artifact@v5
        with:
          path: /tmp/digests
          pattern: digests-*
          merge-multiple: true
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
      - name: Login to GitHub Container Registry
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - name: Create manifest list and push
        if: github.event_name != 'push'
        working-directory: /tmp/digests
        run: |
          docker buildx imagetools create \
            -t "${{ env.REGISTRY_IMAGE }}:${{ steps.ref.outputs.latest }}" \
            -t "${{ env.REGISTRY_IMAGE }}:${{ steps.ref.outputs.ref }}" \
            $(printf '${{ env.REGISTRY_IMAGE }}@sha256:%s ' *)
      - name: Inspect image
        if: github.event_name != 'push'
        run: |
          docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ steps.ref.outputs.latest }}
          docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ steps.ref.outputs.ref }}


================================================
FILE: .github/workflows/lint.yml
================================================
name: Lint

on:
  push:
    branches:
      - oldstable
      - stable
      - testing
      - unstable
    paths-ignore:
      - '**.md'
      - '.github/**'
      - '!.github/workflows/lint.yml'
  pull_request:
    branches:
      - oldstable
      - stable
      - testing
      - unstable

jobs:
  build:
    name: Build
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
        with:
          fetch-depth: 0
      - name: Setup Go
        uses: actions/setup-go@v5
        with:
          go-version: ^1.25
      - name: golangci-lint
        uses: golangci/golangci-lint-action@v8
        with:
          version: latest
          args: --timeout=30m
          install-mode: binary
          verify: false


================================================
FILE: .github/workflows/linux.yml
================================================
name: Build Linux Packages

on:
  #push:
  #  branches:
  #    - stable
  #    - testing
  workflow_dispatch:
    inputs:
      version:
        description: "Version name"
        required: true
        type: string
      forceBeta:
        description: "Force beta"
        required: false
        type: boolean
        default: false
  release:
    types:
      - published

jobs:
  calculate_version:
    name: Calculate version
    if: github.event_name != 'release' || github.event.release.target_commitish != 'oldstable'
    runs-on: ubuntu-latest
    outputs:
      version: ${{ steps.outputs.outputs.version }}
    steps:
      - name: Checkout
        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
        with:
          fetch-depth: 0
      - name: Setup Go
        uses: actions/setup-go@v5
        with:
          go-version: ~1.25.8
      - name: Check input version
        if: github.event_name == 'workflow_dispatch'
        run: |-
          echo "version=${{ inputs.version }}"
          echo "version=${{ inputs.version }}" >> "$GITHUB_ENV"
      - name: Calculate version
        if: github.event_name != 'workflow_dispatch'
        run: |-
          go run -v ./cmd/internal/read_tag --ci --nightly
      - name: Set outputs
        id: outputs
        run: |-
          echo "version=$version" >> "$GITHUB_OUTPUT"
  build:
    name: Build binary
    runs-on: ubuntu-latest
    needs:
      - calculate_version
    strategy:
      matrix:
        include:
          # Naive-enabled builds (musl)
          - { os: linux, arch: amd64, naive: true, debian: amd64, rpm: x86_64, pacman: x86_64 }
          - { os: linux, arch: arm64, naive: true, debian: arm64, rpm: aarch64, pacman: aarch64 }
          - { os: linux, arch: "386", naive: true, debian: i386, rpm: i386 }
          - { os: linux, arch: arm, goarm: "7", naive: true, debian: armhf, rpm: armv7hl, pacman: armv7hl }
          - { os: linux, arch: mipsle, gomips: softfloat, naive: true, debian: mipsel, rpm: mipsel }
          - { os: linux, arch: riscv64, naive: true, debian: riscv64, rpm: riscv64 }
          - { os: linux, arch: loong64, naive: true, debian: loongarch64, rpm: loongarch64 }
          # Non-naive builds (unsupported architectures)
          - { os: linux, arch: arm, goarm: "6", debian: armel, rpm: armv6hl }
          - { os: linux, arch: mips64le, debian: mips64el, rpm: mips64el }
          - { os: linux, arch: s390x, debian: s390x, rpm: s390x }
          - { os: linux, arch: ppc64le, debian: ppc64el, rpm: ppc64le }
    steps:
      - name: Checkout
        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
        with:
          fetch-depth: 0
      - name: Setup Go
        uses: actions/setup-go@v5
        with:
          go-version: ~1.25.8
      - name: Clone cronet-go
        if: matrix.naive
        run: |
          set -xeuo pipefail
          CRONET_GO_VERSION=$(cat .github/CRONET_GO_VERSION)
          git init ~/cronet-go
          git -C ~/cronet-go remote add origin https://github.com/sagernet/cronet-go.git
          git -C ~/cronet-go fetch --depth=1 origin "$CRONET_GO_VERSION"
          git -C ~/cronet-go checkout FETCH_HEAD
          git -C ~/cronet-go submodule update --init --recursive --depth=1
      - name: Regenerate Debian keyring
        if: matrix.naive
        run: |
          set -xeuo pipefail
          rm -f ~/cronet-go/naiveproxy/src/build/linux/sysroot_scripts/keyring.gpg
          cd ~/cronet-go
          GPG_TTY=/dev/null ./naiveproxy/src/build/linux/sysroot_scripts/generate_keyring.sh
      - name: Cache Chromium toolchain
        if: matrix.naive
        id: cache-chromium-toolchain
        uses: actions/cache@v4
        with:
          path: |
            ~/cronet-go/naiveproxy/src/third_party/llvm-build/
            ~/cronet-go/naiveproxy/src/gn/out/
            ~/cronet-go/naiveproxy/src/chrome/build/pgo_profiles/
            ~/cronet-go/naiveproxy/src/out/sysroot-build/
          key: chromium-toolchain-${{ matrix.arch }}-musl-${{ hashFiles('.github/CRONET_GO_VERSION') }}
      - name: Download Chromium toolchain
        if: matrix.naive
        run: |
          set -xeuo pipefail
          cd ~/cronet-go
          go run ./cmd/build-naive --target=linux/${{ matrix.arch }} --libc=musl download-toolchain
      - name: Set Chromium toolchain environment
        if: matrix.naive
        run: |
          set -xeuo pipefail
          cd ~/cronet-go
          go run ./cmd/build-naive --target=linux/${{ matrix.arch }} --libc=musl env >> $GITHUB_ENV
      - name: Set tag
        run: |-
          git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
          git tag v${{ needs.calculate_version.outputs.version }} -f
      - name: Set build tags
        run: |
          set -xeuo pipefail
          if [[ "${{ matrix.naive }}" == "true" ]]; then
            TAGS="$(cat release/DEFAULT_BUILD_TAGS),with_musl"
          else
            TAGS=$(cat release/DEFAULT_BUILD_TAGS_OTHERS)
          fi
          echo "BUILD_TAGS=${TAGS}" >> "${GITHUB_ENV}"
      - name: Set shared ldflags
        run: |
          echo "LDFLAGS_SHARED=$(cat release/LDFLAGS)" >> "${GITHUB_ENV}"
      - name: Build (naive)
        if: matrix.naive
        run: |
          set -xeuo pipefail
          mkdir -p dist
          go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \
          -ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }}' ${LDFLAGS_SHARED} -s -w -buildid=" \
          ./cmd/sing-box
        env:
          CGO_ENABLED: "1"
          GOOS: linux
          GOARCH: ${{ matrix.arch }}
          GOARM: ${{ matrix.goarm }}
          GOMIPS: ${{ matrix.gomips }}
          GOMIPS64: ${{ matrix.gomips }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - name: Build (non-naive)
        if: ${{ ! matrix.naive }}
        run: |
          set -xeuo pipefail
          mkdir -p dist
          go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \
          -ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }}' ${LDFLAGS_SHARED} -s -w -buildid=" \
          ./cmd/sing-box
        env:
          CGO_ENABLED: "0"
          GOOS: ${{ matrix.os }}
          GOARCH: ${{ matrix.arch }}
          GOARM: ${{ matrix.goarm }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - name: Set mtime
        run: |-
          TZ=UTC touch -t '197001010000' dist/sing-box
      - name: Set name
        if: (! contains(needs.calculate_version.outputs.version, '-')) && !inputs.forceBeta
        run: |-
          echo "NAME=sing-box" >> "$GITHUB_ENV"
      - name: Set beta name
        if: contains(needs.calculate_version.outputs.version, '-') || inputs.forceBeta
        run: |-
          echo "NAME=sing-box-beta" >> "$GITHUB_ENV"
      - name: Set version
        run: |-
          PKG_VERSION="${{ needs.calculate_version.outputs.version }}"
          PKG_VERSION="${PKG_VERSION//-/\~}"
          echo "PKG_VERSION=${PKG_VERSION}" >> "${GITHUB_ENV}"
      - name: Package DEB
        if: matrix.debian != ''
        run: |
          set -xeuo pipefail
          sudo gem install fpm
          sudo apt-get install -y debsigs
          cp .fpm_systemd .fpm
          fpm -t deb \
            --name "${NAME}" \
            -v "$PKG_VERSION" \
            -p "dist/${NAME}_${{ needs.calculate_version.outputs.version }}_linux_${{ matrix.debian }}.deb" \
            --architecture ${{ matrix.debian }} \
            dist/sing-box=/usr/bin/sing-box
          curl -Lo '/tmp/debsigs.diff' 'https://gitlab.com/debsigs/debsigs/-/commit/160138f5de1ec110376d3c807b60a37388bc7c90.diff'
          sudo patch /usr/bin/debsigs < '/tmp/debsigs.diff'
          rm -rf $HOME/.gnupg
          gpg --pinentry-mode loopback --passphrase "${{ secrets.GPG_PASSPHRASE }}" --import <<EOF
          ${{ secrets.GPG_KEY }}
          EOF
          debsigs --sign=origin -k ${{ secrets.GPG_KEY_ID }} --gpgopts '--pinentry-mode loopback --passphrase "${{ secrets.GPG_PASSPHRASE }}"' dist/*.deb
      - name: Package RPM
        if: matrix.rpm != ''
        run: |-
          set -xeuo pipefail
          sudo gem install fpm
          cp .fpm_systemd .fpm
          fpm -t rpm \
            --name "${NAME}" \
            -v "$PKG_VERSION" \
            -p "dist/${NAME}_${{ needs.calculate_version.outputs.version }}_linux_${{ matrix.rpm }}.rpm" \
            --architecture ${{ matrix.rpm }} \
            dist/sing-box=/usr/bin/sing-box
          cat > $HOME/.rpmmacros <<EOF
          %_gpg_name ${{ secrets.GPG_KEY_ID }}
          %_gpg_sign_cmd_extra_args --pinentry-mode loopback --passphrase ${{ secrets.GPG_PASSPHRASE }}
          EOF
          gpg --pinentry-mode loopback --passphrase "${{ secrets.GPG_PASSPHRASE }}" --import <<EOF
          ${{ secrets.GPG_KEY }}
          EOF
          rpmsign --addsign dist/*.rpm
      - name: Cleanup
        run: rm dist/sing-box
      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: binary-${{ matrix.os }}_${{ matrix.arch }}${{ matrix.goarm && format('v{0}', matrix.goarm) }}${{ matrix.legacy_go && '-legacy' || '' }}
          path: "dist"
  upload:
    name: Upload builds
    runs-on: ubuntu-latest
    needs:
      - calculate_version
      - build
    steps:
      - name: Checkout
        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
        with:
          fetch-depth: 0
      - name: Set tag
        run: |-
          git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
          git tag v${{ needs.calculate_version.outputs.version }} -f
          echo "VERSION=${{ needs.calculate_version.outputs.version }}" >> "$GITHUB_ENV"
      - name: Download builds
        uses: actions/download-artifact@v5
        with:
          path: dist
          merge-multiple: true
      - name: Publish packages
        if: github.event_name != 'push'
        run: |-
          ls dist | xargs -I {} curl -F "package=@dist/{}" https://${{ secrets.FURY_TOKEN }}@push.fury.io/sagernet/


================================================
FILE: .github/workflows/stale.yml
================================================
name: Mark stale issues and pull requests

on:
  schedule:
    - cron: "30 1 * * *"

jobs:
  stale:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/stale@v9
        with:
          stale-issue-message: 'This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 5 days'
          days-before-stale: 60
          days-before-close: 5
          exempt-issue-labels: 'bug,enhancement'


================================================
FILE: .gitignore
================================================
/.idea/
/vendor/
/*.json
/*.srs
/*.db
/site/
/bin/
/dist/
/sing-box
/sing-box.exe
/build/
/*.jar
/*.aar
/*.xcframework/
/experimental/libbox/*.aar
/experimental/libbox/*.xcframework/
/experimental/libbox/*.nupkg
.DS_Store
/config.d/
/venv/
CLAUDE.md
AGENTS.md
/.claude/


================================================
FILE: .gitmodules
================================================
[submodule "clients/apple"]
	path = clients/apple
	url = https://github.com/SagerNet/sing-box-for-apple.git
[submodule "clients/android"]
	path = clients/android
	url = https://github.com/SagerNet/sing-box-for-android.git


================================================
FILE: .golangci.yml
================================================
version: "2"
run:
  go: "1.25"
  build-tags:
    - with_gvisor
    - with_quic
    - with_dhcp
    - with_wireguard
    - with_utls
    - with_acme
    - with_clash_api
    - with_tailscale
    - with_ccm
    - with_ocm
    - badlinkname
    - tfogo_checklinkname0
linters:
  default: none
  enable:
    - govet
    - ineffassign
    - paralleltest
    - staticcheck
  settings:
    staticcheck:
      checks:
        - all
        - -S1000
        - -S1008
        - -S1017
        - -ST1003
        - -QF1001
        - -QF1003
        - -QF1008
  exclusions:
    generated: lax
    presets:
      - comments
      - common-false-positives
      - legacy
      - std-error-handling
    paths:
      - transport/simple-obfs
      - third_party$
      - builtin$
      - examples$
formatters:
  enable:
    - gci
    - gofumpt
  settings:
    gci:
      sections:
        - standard
        - prefix(github.com/sagernet/)
        - default
      custom-order: true
  exclusions:
    generated: lax
    paths:
      - transport/simple-obfs
      - third_party$
      - builtin$
      - examples$


================================================
FILE: Dockerfile
================================================
FROM --platform=$BUILDPLATFORM golang:1.25-alpine AS builder
LABEL maintainer="nekohasekai <contact-git@sekai.icu>"
COPY . /go/src/github.com/sagernet/sing-box
WORKDIR /go/src/github.com/sagernet/sing-box
ARG TARGETOS TARGETARCH
ARG GOPROXY=""
ENV GOPROXY ${GOPROXY}
ENV CGO_ENABLED=0
ENV GOOS=$TARGETOS
ENV GOARCH=$TARGETARCH
RUN set -ex \
    && apk add git build-base \
    && export COMMIT=$(git rev-parse --short HEAD) \
    && export VERSION=$(go run ./cmd/internal/read_tag) \
    && export TAGS=$(cat release/DEFAULT_BUILD_TAGS_OTHERS) \
    && export LDFLAGS_SHARED=$(cat release/LDFLAGS) \
    && go build -v -trimpath -tags "$TAGS" \
        -o /go/bin/sing-box \
        -ldflags "-X \"github.com/sagernet/sing-box/constant.Version=$VERSION\" $LDFLAGS_SHARED -s -w -buildid=" \
        ./cmd/sing-box
FROM --platform=$TARGETPLATFORM alpine AS dist
LABEL maintainer="nekohasekai <contact-git@sekai.icu>"
RUN set -ex \
    && apk add --no-cache --upgrade bash tzdata ca-certificates nftables
COPY --from=builder /go/bin/sing-box /usr/local/bin/sing-box
ENTRYPOINT ["sing-box"]


================================================
FILE: Dockerfile.binary
================================================
ARG BASE_IMAGE=alpine
FROM ${BASE_IMAGE}
ARG TARGETARCH
ARG TARGETVARIANT
LABEL maintainer="nekohasekai <contact-git@sekai.icu>"
RUN set -ex \
    && if command -v apk > /dev/null; then \
        apk add --no-cache --upgrade bash tzdata ca-certificates nftables; \
    else \
        apt-get update && apt-get install -y --no-install-recommends bash tzdata ca-certificates nftables \
        && rm -rf /var/lib/apt/lists/*; \
    fi
COPY sing-box-${TARGETARCH}${TARGETVARIANT} /usr/local/bin/sing-box
ENTRYPOINT ["sing-box"]


================================================
FILE: LICENSE
================================================
Copyright (C) 2022 by nekohasekai <contact-sagernet@sekai.icu>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.

In addition, no derivative work may use the name or imply association
with this application without prior consent.


================================================
FILE: Makefile
================================================
NAME = sing-box
COMMIT = $(shell git rev-parse --short HEAD)
TAGS ?= $(shell cat release/DEFAULT_BUILD_TAGS_OTHERS)

GOHOSTOS = $(shell go env GOHOSTOS)
GOHOSTARCH = $(shell go env GOHOSTARCH)
VERSION=$(shell CGO_ENABLED=0 GOOS=$(GOHOSTOS) GOARCH=$(GOHOSTARCH) go run github.com/sagernet/sing-box/cmd/internal/read_tag@latest)

LDFLAGS_SHARED = $(shell cat release/LDFLAGS)
PARAMS = -v -trimpath -ldflags "-X 'github.com/sagernet/sing-box/constant.Version=$(VERSION)' $(LDFLAGS_SHARED) -s -w -buildid="
MAIN_PARAMS = $(PARAMS) -tags "$(TAGS)"
MAIN = ./cmd/sing-box
PREFIX ?= $(shell go env GOPATH)
SING_FFI ?= sing-ffi
LIBBOX_FFI_CONFIG ?= ./experimental/libbox/ffi.json

.PHONY: test release docs build

build:
	export GOTOOLCHAIN=local && \
	go build $(MAIN_PARAMS) $(MAIN)

race:
	export GOTOOLCHAIN=local && \
	go build -race $(MAIN_PARAMS) $(MAIN)

ci_build:
	export GOTOOLCHAIN=local && \
	go build $(PARAMS) $(MAIN) && \
	go build $(MAIN_PARAMS) $(MAIN)

generate_completions:
	go run -v --tags "$(TAGS),generate,generate_completions" $(MAIN)

install:
	go build -o $(PREFIX)/bin/$(NAME) $(MAIN_PARAMS) $(MAIN)

fmt:
	@gofumpt -l -w .
	@gofmt -s -w .
	@gci write --custom-order -s standard -s "prefix(github.com/sagernet/)" -s "default" .

fmt_docs:
	go run ./cmd/internal/format_docs

fmt_install:
	go install -v mvdan.cc/gofumpt@latest
	go install -v github.com/daixiang0/gci@latest

lint:
	GOOS=linux golangci-lint run ./...
	GOOS=android golangci-lint run ./...
	GOOS=windows golangci-lint run ./...
	GOOS=darwin golangci-lint run ./...
	GOOS=freebsd golangci-lint run ./...

lint_install:
	go install -v github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest

proto:
	@go run ./cmd/internal/protogen
	@gofumpt -l -w .
	@gofumpt -l -w .

proto_install:
	go install -v google.golang.org/protobuf/cmd/protoc-gen-go@latest
	go install -v google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest

update_certificates:
	go run ./cmd/internal/update_certificates

release:
	go run ./cmd/internal/build goreleaser release --clean --skip publish
	mkdir dist/release
	mv dist/*.tar.gz \
		dist/*.zip \
		dist/*.deb \
		dist/*.rpm \
		dist/*_amd64.pkg.tar.zst \
		dist/*_arm64.pkg.tar.zst \
		dist/release
	ghr --replace --draft --prerelease -p 5 "v${VERSION}" dist/release
	rm -r dist/release

release_repo:
	go run ./cmd/internal/build goreleaser release -f .goreleaser.fury.yaml --clean

release_install:
	go install -v github.com/tcnksm/ghr@latest

update_android_version:
	go run ./cmd/internal/update_android_version

build_android:
	cd ../sing-box-for-android && ./gradlew :app:clean :app:assembleOtherRelease :app:assembleOtherLegacyRelease && ./gradlew --stop

upload_android:
	mkdir -p dist/release_android
	cp ../sing-box-for-android/app/build/outputs/apk/other/release/*.apk dist/release_android
	cp ../sing-box-for-android/app/build/outputs/apk/otherLegacy/release/*.apk dist/release_android
	ghr --replace --draft --prerelease -p 5 "v${VERSION}" dist/release_android
	rm -rf dist/release_android

release_android: lib_android update_android_version build_android upload_android

publish_android:
	cd ../sing-box-for-android && ./gradlew :app:publishPlayReleaseBundle && ./gradlew --stop

# TODO: find why and remove `-destination 'generic/platform=iOS'`
# TODO: remove xcode clean when fix control widget fixed
build_ios:
	cd ../sing-box-for-apple && \
	rm -rf build/SFI.xcarchive && \
	xcodebuild clean -scheme SFI && \
	xcodebuild archive -scheme SFI -configuration Release -destination 'generic/platform=iOS' -archivePath build/SFI.xcarchive -allowProvisioningUpdates | xcbeautify | grep -A 10 -e "Archive Succeeded" -e "ARCHIVE FAILED" -e "❌"

upload_ios_app_store:
	cd ../sing-box-for-apple && \
	xcodebuild -exportArchive -archivePath build/SFI.xcarchive -exportOptionsPlist SFI/Upload.plist -allowProvisioningUpdates

export_ios_ipa:
	cd ../sing-box-for-apple && \
	xcodebuild -exportArchive -archivePath build/SFI.xcarchive -exportOptionsPlist SFI/Export.plist -allowProvisioningUpdates -exportPath build/SFI && \
	cp build/SFI/sing-box.ipa dist/SFI.ipa

upload_ios_ipa:
	cd dist && \
	cp SFI.ipa "SFI-${VERSION}.ipa" && \
	ghr --replace --draft --prerelease "v${VERSION}" "SFI-${VERSION}.ipa"

release_ios: build_ios upload_ios_app_store

build_macos:
	cd ../sing-box-for-apple && \
	rm -rf build/SFM.xcarchive && \
	xcodebuild archive -scheme SFM -configuration Release -archivePath build/SFM.xcarchive -allowProvisioningUpdates | xcbeautify | grep -A 10 -e "Archive Succeeded" -e "ARCHIVE FAILED" -e "❌"

upload_macos_app_store:
	cd ../sing-box-for-apple && \
	xcodebuild -exportArchive -archivePath build/SFM.xcarchive -exportOptionsPlist SFI/Upload.plist -allowProvisioningUpdates

release_macos: build_macos upload_macos_app_store

build_macos_standalone:
	$(MAKE) -C ../sing-box-for-apple archive_macos_standalone

build_macos_dmg:
	$(MAKE) -C ../sing-box-for-apple build_macos_dmg

build_macos_pkg:
	$(MAKE) -C ../sing-box-for-apple build_macos_pkg

notarize_macos_dmg:
	$(MAKE) -C ../sing-box-for-apple notarize_macos_dmg

notarize_macos_pkg:
	$(MAKE) -C ../sing-box-for-apple notarize_macos_pkg

upload_macos_dmg:
	mkdir -p dist/SFM
	cp ../sing-box-for-apple/build/SFM-Apple.dmg "dist/SFM/SFM-${VERSION}-Apple.dmg"
	cp ../sing-box-for-apple/build/SFM-Intel.dmg "dist/SFM/SFM-${VERSION}-Intel.dmg"
	cp ../sing-box-for-apple/build/SFM-Universal.dmg "dist/SFM/SFM-${VERSION}-Universal.dmg"
	ghr --replace --draft --prerelease "v${VERSION}" "dist/SFM/SFM-${VERSION}-Apple.dmg"
	ghr --replace --draft --prerelease "v${VERSION}" "dist/SFM/SFM-${VERSION}-Intel.dmg"
	ghr --replace --draft --prerelease "v${VERSION}" "dist/SFM/SFM-${VERSION}-Universal.dmg"

upload_macos_pkg:
	mkdir -p dist/SFM
	cp ../sing-box-for-apple/build/SFM-Apple.pkg "dist/SFM/SFM-${VERSION}-Apple.pkg"
	cp ../sing-box-for-apple/build/SFM-Intel.pkg "dist/SFM/SFM-${VERSION}-Intel.pkg"
	cp ../sing-box-for-apple/build/SFM-Universal.pkg "dist/SFM/SFM-${VERSION}-Universal.pkg"
	ghr --replace --draft --prerelease "v${VERSION}" "dist/SFM/SFM-${VERSION}-Apple.pkg"
	ghr --replace --draft --prerelease "v${VERSION}" "dist/SFM/SFM-${VERSION}-Intel.pkg"
	ghr --replace --draft --prerelease "v${VERSION}" "dist/SFM/SFM-${VERSION}-Universal.pkg"

upload_macos_dsyms:
	mkdir -p dist/SFM
	cd ../sing-box-for-apple/build/SFM.System-universal.xcarchive && zip -r SFM.dSYMs.zip dSYMs
	cp ../sing-box-for-apple/build/SFM.System-universal.xcarchive/SFM.dSYMs.zip "dist/SFM/SFM-${VERSION}.dSYMs.zip"
	ghr --replace --draft --prerelease "v${VERSION}" "dist/SFM/SFM-${VERSION}.dSYMs.zip"

release_macos_standalone: build_macos_pkg notarize_macos_pkg upload_macos_pkg upload_macos_dsyms

build_tvos:
	cd ../sing-box-for-apple && \
	rm -rf build/SFT.xcarchive && \
	xcodebuild archive -scheme SFT -configuration Release -archivePath build/SFT.xcarchive -allowProvisioningUpdates | xcbeautify | grep -A 10 -e "Archive Succeeded" -e "ARCHIVE FAILED" -e "❌"

upload_tvos_app_store:
	cd ../sing-box-for-apple && \
	xcodebuild -exportArchive -archivePath "build/SFT.xcarchive" -exportOptionsPlist SFI/Upload.plist -allowProvisioningUpdates

export_tvos_ipa:
	cd ../sing-box-for-apple && \
	xcodebuild -exportArchive -archivePath "build/SFT.xcarchive" -exportOptionsPlist SFI/Export.plist -allowProvisioningUpdates -exportPath build/SFT && \
	cp build/SFT/sing-box.ipa dist/SFT.ipa

upload_tvos_ipa:
	cd dist && \
	cp SFT.ipa "SFT-${VERSION}.ipa" && \
	ghr --replace --draft --prerelease "v${VERSION}" "SFT-${VERSION}.ipa"

release_tvos: build_tvos upload_tvos_app_store

update_apple_version:
	go run ./cmd/internal/update_apple_version

update_macos_version:
	MACOS_PROJECT_VERSION=$(shell go run -v ./cmd/internal/app_store_connect next_macos_project_version) go run ./cmd/internal/update_apple_version

release_apple: lib_apple update_apple_version release_ios release_macos release_tvos release_macos_standalone

release_apple_beta: update_apple_version release_ios release_macos release_tvos

publish_testflight:
	go run -v ./cmd/internal/app_store_connect publish_testflight $(filter-out $@,$(MAKECMDGOALS))

prepare_app_store:
	go run -v ./cmd/internal/app_store_connect prepare_app_store

publish_app_store:
	go run -v ./cmd/internal/app_store_connect publish_app_store

test:
	@go test -v ./... && \
	cd test && \
	go mod tidy && \
	go test -v -tags "$(TAGS_TEST)" .

test_stdio:
	@go test -v ./... && \
	cd test && \
	go mod tidy && \
	go test -v -tags "$(TAGS_TEST),force_stdio" .

lib_android:
	go run ./cmd/internal/build_libbox -target android

lib_apple:
	go run ./cmd/internal/build_libbox -target apple

lib_windows:
	$(SING_FFI) generate --config $(LIBBOX_FFI_CONFIG) --platform-type csharp

lib_android_new:
	$(SING_FFI) generate --config $(LIBBOX_FFI_CONFIG) --platform-type android

lib_apple_new:
	$(SING_FFI) generate --config $(LIBBOX_FFI_CONFIG) --platform-type apple

lib_install:
	go install -v github.com/sagernet/gomobile/cmd/gomobile@v0.1.12
	go install -v github.com/sagernet/gomobile/cmd/gobind@v0.1.12

docs:
	venv/bin/mkdocs serve

publish_docs:
	venv/bin/mkdocs gh-deploy -m "Update" --force --ignore-version --no-history

docs_install:
	python3 -m venv venv
	source ./venv/bin/activate && pip install --force-reinstall mkdocs-material=="9.7.2" mkdocs-static-i18n=="1.2.*"

clean:
	rm -rf bin dist sing-box
	rm -f $(shell go env GOPATH)/sing-box

update:
	git fetch
	git reset FETCH_HEAD --hard
	git clean -fdx

%:
	@:


================================================
FILE: README.md
================================================
> Sponsored by [Warp](https://go.warp.dev/sing-box), built for coding with multiple AI agents

<a href="https://go.warp.dev/sing-box">
<img alt="Warp sponsorship" width="400" src="https://github.com/warpdotdev/brand-assets/raw/refs/heads/main/Github/Sponsor/Warp-Github-LG-02.png">
</a>

---

# sing-box

The universal proxy platform.

[![Packaging status](https://repology.org/badge/vertical-allrepos/sing-box.svg)](https://repology.org/project/sing-box/versions)

## Documentation

https://sing-box.sagernet.org

## License

```
Copyright (C) 2022 by nekohasekai <contact-sagernet@sekai.icu>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.

In addition, no derivative work may use the name or imply association
with this application without prior consent.
```

================================================
FILE: adapter/certificate.go
================================================
package adapter

import (
	"context"
	"crypto/x509"

	"github.com/sagernet/sing/service"
)

type CertificateStore interface {
	LifecycleService
	Pool() *x509.CertPool
}

func RootPoolFromContext(ctx context.Context) *x509.CertPool {
	store := service.FromContext[CertificateStore](ctx)
	if store == nil {
		return nil
	}
	return store.Pool()
}


================================================
FILE: adapter/connections.go
================================================
package adapter

import (
	"context"
	"net"

	N "github.com/sagernet/sing/common/network"
)

type ConnectionManager interface {
	Lifecycle
	Count() int
	CloseAll()
	TrackConn(conn net.Conn) net.Conn
	TrackPacketConn(conn net.PacketConn) net.PacketConn
	NewConnection(ctx context.Context, this N.Dialer, conn net.Conn, metadata InboundContext, onClose N.CloseHandlerFunc)
	NewPacketConnection(ctx context.Context, this N.Dialer, conn N.PacketConn, metadata InboundContext, onClose N.CloseHandlerFunc)
}


================================================
FILE: adapter/dns.go
================================================
package adapter

import (
	"context"
	"net/netip"

	C "github.com/sagernet/sing-box/constant"
	"github.com/sagernet/sing-box/log"
	"github.com/sagernet/sing-box/option"
	E "github.com/sagernet/sing/common/exceptions"
	"github.com/sagernet/sing/common/logger"
	"github.com/sagernet/sing/service"

	"github.com/miekg/dns"
)

type DNSRouter interface {
	Lifecycle
	Exchange(ctx context.Context, message *dns.Msg, options DNSQueryOptions) (*dns.Msg, error)
	Lookup(ctx context.Context, domain string, options DNSQueryOptions) ([]netip.Addr, error)
	ClearCache()
	LookupReverseMapping(ip netip.Addr) (string, bool)
	ResetNetwork()
}

type DNSClient interface {
	Start()
	Exchange(ctx context.Context, transport DNSTransport, message *dns.Msg, options DNSQueryOptions, responseChecker func(responseAddrs []netip.Addr) bool) (*dns.Msg, error)
	Lookup(ctx context.Context, transport DNSTransport, domain string, options DNSQueryOptions, responseChecker func(responseAddrs []netip.Addr) bool) ([]netip.Addr, error)
	ClearCache()
}

type DNSQueryOptions struct {
	Transport      DNSTransport
	Strategy       C.DomainStrategy
	LookupStrategy C.DomainStrategy
	DisableCache   bool
	RewriteTTL     *uint32
	ClientSubnet   netip.Prefix
}

func DNSQueryOptionsFrom(ctx context.Context, options *option.DomainResolveOptions) (*DNSQueryOptions, error) {
	if options == nil {
		return &DNSQueryOptions{}, nil
	}
	transportManager := service.FromContext[DNSTransportManager](ctx)
	transport, loaded := transportManager.Transport(options.Server)
	if !loaded {
		return nil, E.New("domain resolver not found: " + options.Server)
	}
	return &DNSQueryOptions{
		Transport:    transport,
		Strategy:     C.DomainStrategy(options.Strategy),
		DisableCache: options.DisableCache,
		RewriteTTL:   options.RewriteTTL,
		ClientSubnet: options.ClientSubnet.Build(netip.Prefix{}),
	}, nil
}

type RDRCStore interface {
	LoadRDRC(transportName string, qName string, qType uint16) (rejected bool)
	SaveRDRC(transportName string, qName string, qType uint16) error
	SaveRDRCAsync(transportName string, qName string, qType uint16, logger logger.Logger)
}

type DNSTransport interface {
	Lifecycle
	Type() string
	Tag() string
	Dependencies() []string
	Reset()
	Exchange(ctx context.Context, message *dns.Msg) (*dns.Msg, error)
}

type LegacyDNSTransport interface {
	LegacyStrategy() C.DomainStrategy
	LegacyClientSubnet() netip.Prefix
}

type DNSTransportRegistry interface {
	option.DNSTransportOptionsRegistry
	CreateDNSTransport(ctx context.Context, logger log.ContextLogger, tag string, transportType string, options any) (DNSTransport, error)
}

type DNSTransportManager interface {
	Lifecycle
	Transports() []DNSTransport
	Transport(tag string) (DNSTransport, bool)
	Default() DNSTransport
	FakeIP() FakeIPTransport
	Remove(tag string) error
	Create(ctx context.Context, logger log.ContextLogger, tag string, outboundType string, options any) error
}


================================================
FILE: adapter/endpoint/adapter.go
================================================
package endpoint

import "github.com/sagernet/sing-box/option"

type Adapter struct {
	endpointType string
	endpointTag  string
	network      []string
	dependencies []string
}

func NewAdapter(endpointType string, endpointTag string, network []string, dependencies []string) Adapter {
	return Adapter{
		endpointType: endpointType,
		endpointTag:  endpointTag,
		network:      network,
		dependencies: dependencies,
	}
}

func NewAdapterWithDialerOptions(endpointType string, endpointTag string, network []string, dialOptions option.DialerOptions) Adapter {
	var dependencies []string
	if dialOptions.Detour != "" {
		dependencies = []string{dialOptions.Detour}
	}
	return NewAdapter(endpointType, endpointTag, network, dependencies)
}

func (a *Adapter) Type() string {
	return a.endpointType
}

func (a *Adapter) Tag() string {
	return a.endpointTag
}

func (a *Adapter) Network() []string {
	return a.network
}

func (a *Adapter) Dependencies() []string {
	return a.dependencies
}


================================================
FILE: adapter/endpoint/manager.go
================================================
package endpoint

import (
	"context"
	"os"
	"sync"
	"time"

	"github.com/sagernet/sing-box/adapter"
	"github.com/sagernet/sing-box/common/taskmonitor"
	C "github.com/sagernet/sing-box/constant"
	"github.com/sagernet/sing-box/log"
	"github.com/sagernet/sing/common"
	E "github.com/sagernet/sing/common/exceptions"
	F "github.com/sagernet/sing/common/format"
)

var _ adapter.EndpointManager = (*Manager)(nil)

type Manager struct {
	logger        log.ContextLogger
	registry      adapter.EndpointRegistry
	access        sync.Mutex
	started       bool
	stage         adapter.StartStage
	endpoints     []adapter.Endpoint
	endpointByTag map[string]adapter.Endpoint
}

func NewManager(logger log.ContextLogger, registry adapter.EndpointRegistry) *Manager {
	return &Manager{
		logger:        logger,
		registry:      registry,
		endpointByTag: make(map[string]adapter.Endpoint),
	}
}

func (m *Manager) Start(stage adapter.StartStage) error {
	m.access.Lock()
	defer m.access.Unlock()
	if m.started && m.stage >= stage {
		panic("already started")
	}
	m.started = true
	m.stage = stage
	if stage == adapter.StartStateStart {
		// started with outbound manager
		return nil
	}
	for _, endpoint := range m.endpoints {
		name := "endpoint/" + endpoint.Type() + "[" + endpoint.Tag() + "]"
		m.logger.Trace(stage, " ", name)
		startTime := time.Now()
		err := adapter.LegacyStart(endpoint, stage)
		if err != nil {
			return E.Cause(err, stage, " ", name)
		}
		m.logger.Trace(stage, " ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
	}
	return nil
}

func (m *Manager) Close() error {
	m.access.Lock()
	defer m.access.Unlock()
	if !m.started {
		return nil
	}
	m.started = false
	endpoints := m.endpoints
	m.endpoints = nil
	monitor := taskmonitor.New(m.logger, C.StopTimeout)
	var err error
	for _, endpoint := range endpoints {
		name := "endpoint/" + endpoint.Type() + "[" + endpoint.Tag() + "]"
		m.logger.Trace("close ", name)
		startTime := time.Now()
		monitor.Start("close ", name)
		err = E.Append(err, endpoint.Close(), func(err error) error {
			return E.Cause(err, "close ", name)
		})
		monitor.Finish()
		m.logger.Trace("close ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
	}
	return nil
}

func (m *Manager) Endpoints() []adapter.Endpoint {
	m.access.Lock()
	defer m.access.Unlock()
	return m.endpoints
}

func (m *Manager) Get(tag string) (adapter.Endpoint, bool) {
	m.access.Lock()
	defer m.access.Unlock()
	endpoint, found := m.endpointByTag[tag]
	return endpoint, found
}

func (m *Manager) Remove(tag string) error {
	m.access.Lock()
	endpoint, found := m.endpointByTag[tag]
	if !found {
		m.access.Unlock()
		return os.ErrInvalid
	}
	delete(m.endpointByTag, tag)
	index := common.Index(m.endpoints, func(it adapter.Endpoint) bool {
		return it == endpoint
	})
	if index == -1 {
		panic("invalid endpoint index")
	}
	m.endpoints = append(m.endpoints[:index], m.endpoints[index+1:]...)
	started := m.started
	m.access.Unlock()
	if started {
		return endpoint.Close()
	}
	return nil
}

func (m *Manager) Create(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, outboundType string, options any) error {
	endpoint, err := m.registry.Create(ctx, router, logger, tag, outboundType, options)
	if err != nil {
		return err
	}
	m.access.Lock()
	defer m.access.Unlock()
	if m.started {
		name := "endpoint/" + endpoint.Type() + "[" + endpoint.Tag() + "]"
		for _, stage := range adapter.ListStartStages {
			m.logger.Trace(stage, " ", name)
			startTime := time.Now()
			err = adapter.LegacyStart(endpoint, stage)
			if err != nil {
				return E.Cause(err, stage, " ", name)
			}
			m.logger.Trace(stage, " ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
		}
	}
	if existsEndpoint, loaded := m.endpointByTag[tag]; loaded {
		if m.started {
			err = existsEndpoint.Close()
			if err != nil {
				return E.Cause(err, "close endpoint/", existsEndpoint.Type(), "[", existsEndpoint.Tag(), "]")
			}
		}
		existsIndex := common.Index(m.endpoints, func(it adapter.Endpoint) bool {
			return it == existsEndpoint
		})
		if existsIndex == -1 {
			panic("invalid endpoint index")
		}
		m.endpoints = append(m.endpoints[:existsIndex], m.endpoints[existsIndex+1:]...)
	}
	m.endpoints = append(m.endpoints, endpoint)
	m.endpointByTag[tag] = endpoint
	return nil
}


================================================
FILE: adapter/endpoint/registry.go
================================================
package endpoint

import (
	"context"
	"sync"

	"github.com/sagernet/sing-box/adapter"
	"github.com/sagernet/sing-box/log"
	"github.com/sagernet/sing/common"
	E "github.com/sagernet/sing/common/exceptions"
)

type ConstructorFunc[T any] func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options T) (adapter.Endpoint, error)

func Register[Options any](registry *Registry, outboundType string, constructor ConstructorFunc[Options]) {
	registry.register(outboundType, func() any {
		return new(Options)
	}, func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, rawOptions any) (adapter.Endpoint, error) {
		var options *Options
		if rawOptions != nil {
			options = rawOptions.(*Options)
		}
		return constructor(ctx, router, logger, tag, common.PtrValueOrDefault(options))
	})
}

var _ adapter.EndpointRegistry = (*Registry)(nil)

type (
	optionsConstructorFunc func() any
	constructorFunc        func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options any) (adapter.Endpoint, error)
)

type Registry struct {
	access      sync.Mutex
	optionsType map[string]optionsConstructorFunc
	constructor map[string]constructorFunc
}

func NewRegistry() *Registry {
	return &Registry{
		optionsType: make(map[string]optionsConstructorFunc),
		constructor: make(map[string]constructorFunc),
	}
}

func (m *Registry) CreateOptions(outboundType string) (any, bool) {
	m.access.Lock()
	defer m.access.Unlock()
	optionsConstructor, loaded := m.optionsType[outboundType]
	if !loaded {
		return nil, false
	}
	return optionsConstructor(), true
}

func (m *Registry) Create(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, outboundType string, options any) (adapter.Endpoint, error) {
	m.access.Lock()
	defer m.access.Unlock()
	constructor, loaded := m.constructor[outboundType]
	if !loaded {
		return nil, E.New("outbound type not found: " + outboundType)
	}
	return constructor(ctx, router, logger, tag, options)
}

func (m *Registry) register(outboundType string, optionsConstructor optionsConstructorFunc, constructor constructorFunc) {
	m.access.Lock()
	defer m.access.Unlock()
	m.optionsType[outboundType] = optionsConstructor
	m.constructor[outboundType] = constructor
}


================================================
FILE: adapter/endpoint.go
================================================
package adapter

import (
	"context"

	"github.com/sagernet/sing-box/log"
	"github.com/sagernet/sing-box/option"
)

type Endpoint interface {
	Lifecycle
	Type() string
	Tag() string
	Outbound
}

type EndpointRegistry interface {
	option.EndpointOptionsRegistry
	Create(ctx context.Context, router Router, logger log.ContextLogger, tag string, endpointType string, options any) (Endpoint, error)
}

type EndpointManager interface {
	Lifecycle
	Endpoints() []Endpoint
	Get(tag string) (Endpoint, bool)
	Remove(tag string) error
	Create(ctx context.Context, router Router, logger log.ContextLogger, tag string, endpointType string, options any) error
}


================================================
FILE: adapter/experimental.go
================================================
package adapter

import (
	"bytes"
	"context"
	"encoding/binary"
	"io"
	"time"

	"github.com/sagernet/sing/common/observable"
	"github.com/sagernet/sing/common/varbin"
)

type ClashServer interface {
	LifecycleService
	ConnectionTracker
	Mode() string
	ModeList() []string
	SetModeUpdateHook(hook *observable.Subscriber[struct{}])
	HistoryStorage() URLTestHistoryStorage
}

type URLTestHistory struct {
	Time  time.Time `json:"time"`
	Delay uint16    `json:"delay"`
}

type URLTestHistoryStorage interface {
	SetHook(hook *observable.Subscriber[struct{}])
	LoadURLTestHistory(tag string) *URLTestHistory
	DeleteURLTestHistory(tag string)
	StoreURLTestHistory(tag string, history *URLTestHistory)
	Close() error
}

type V2RayServer interface {
	LifecycleService
	StatsService() ConnectionTracker
}

type CacheFile interface {
	LifecycleService

	StoreFakeIP() bool
	FakeIPStorage

	StoreRDRC() bool
	RDRCStore

	LoadMode() string
	StoreMode(mode string) error
	LoadSelected(group string) string
	StoreSelected(group string, selected string) error
	LoadGroupExpand(group string) (isExpand bool, loaded bool)
	StoreGroupExpand(group string, expand bool) error
	LoadRuleSet(tag string) *SavedBinary
	SaveRuleSet(tag string, set *SavedBinary) error
}

type SavedBinary struct {
	Content     []byte
	LastUpdated time.Time
	LastEtag    string
}

func (s *SavedBinary) MarshalBinary() ([]byte, error) {
	var buffer bytes.Buffer
	err := binary.Write(&buffer, binary.BigEndian, uint8(1))
	if err != nil {
		return nil, err
	}
	_, err = varbin.WriteUvarint(&buffer, uint64(len(s.Content)))
	if err != nil {
		return nil, err
	}
	_, err = buffer.Write(s.Content)
	if err != nil {
		return nil, err
	}
	err = binary.Write(&buffer, binary.BigEndian, s.LastUpdated.Unix())
	if err != nil {
		return nil, err
	}
	_, err = varbin.WriteUvarint(&buffer, uint64(len(s.LastEtag)))
	if err != nil {
		return nil, err
	}
	_, err = buffer.WriteString(s.LastEtag)
	if err != nil {
		return nil, err
	}
	return buffer.Bytes(), nil
}

func (s *SavedBinary) UnmarshalBinary(data []byte) error {
	reader := bytes.NewReader(data)
	var version uint8
	err := binary.Read(reader, binary.BigEndian, &version)
	if err != nil {
		return err
	}
	contentLength, err := binary.ReadUvarint(reader)
	if err != nil {
		return err
	}
	s.Content = make([]byte, contentLength)
	_, err = io.ReadFull(reader, s.Content)
	if err != nil {
		return err
	}
	var lastUpdated int64
	err = binary.Read(reader, binary.BigEndian, &lastUpdated)
	if err != nil {
		return err
	}
	s.LastUpdated = time.Unix(lastUpdated, 0)
	etagLength, err := binary.ReadUvarint(reader)
	if err != nil {
		return err
	}
	etagBytes := make([]byte, etagLength)
	_, err = io.ReadFull(reader, etagBytes)
	if err != nil {
		return err
	}
	s.LastEtag = string(etagBytes)
	return nil
}

type OutboundGroup interface {
	Outbound
	Now() string
	All() []string
}

type URLTestGroup interface {
	OutboundGroup
	URLTest(ctx context.Context) (map[string]uint16, error)
}

func OutboundTag(detour Outbound) string {
	if group, isGroup := detour.(OutboundGroup); isGroup {
		return group.Now()
	}
	return detour.Tag()
}


================================================
FILE: adapter/fakeip.go
================================================
package adapter

import (
	"net/netip"

	"github.com/sagernet/sing/common/logger"
)

type FakeIPStore interface {
	SimpleLifecycle
	Contains(address netip.Addr) bool
	Create(domain string, isIPv6 bool) (netip.Addr, error)
	Lookup(address netip.Addr) (string, bool)
	Reset() error
}

type FakeIPStorage interface {
	FakeIPMetadata() *FakeIPMetadata
	FakeIPSaveMetadata(metadata *FakeIPMetadata) error
	FakeIPSaveMetadataAsync(metadata *FakeIPMetadata)
	FakeIPStore(address netip.Addr, domain string) error
	FakeIPStoreAsync(address netip.Addr, domain string, logger logger.Logger)
	FakeIPLoad(address netip.Addr) (string, bool)
	FakeIPLoadDomain(domain string, isIPv6 bool) (netip.Addr, bool)
	FakeIPReset() error
}

type FakeIPTransport interface {
	DNSTransport
	Store() FakeIPStore
}


================================================
FILE: adapter/fakeip_metadata.go
================================================
package adapter

import (
	"bytes"
	"encoding"
	"encoding/binary"
	"io"
	"net/netip"

	"github.com/sagernet/sing/common"
)

type FakeIPMetadata struct {
	Inet4Range   netip.Prefix
	Inet6Range   netip.Prefix
	Inet4Current netip.Addr
	Inet6Current netip.Addr
}

func (m *FakeIPMetadata) MarshalBinary() (data []byte, err error) {
	var buffer bytes.Buffer
	for _, marshaler := range []encoding.BinaryMarshaler{m.Inet4Range, m.Inet6Range, m.Inet4Current, m.Inet6Current} {
		data, err = marshaler.MarshalBinary()
		if err != nil {
			return
		}
		common.Must(binary.Write(&buffer, binary.BigEndian, uint16(len(data))))
		buffer.Write(data)
	}
	data = buffer.Bytes()
	return
}

func (m *FakeIPMetadata) UnmarshalBinary(data []byte) error {
	reader := bytes.NewReader(data)
	for _, unmarshaler := range []encoding.BinaryUnmarshaler{&m.Inet4Range, &m.Inet6Range, &m.Inet4Current, &m.Inet6Current} {
		var length uint16
		common.Must(binary.Read(reader, binary.BigEndian, &length))
		element := make([]byte, length)
		_, err := io.ReadFull(reader, element)
		if err != nil {
			return err
		}
		err = unmarshaler.UnmarshalBinary(element)
		if err != nil {
			return err
		}
	}
	return nil
}


================================================
FILE: adapter/handler.go
================================================
package adapter

import (
	"context"
	"net"

	"github.com/sagernet/sing/common/buf"
	E "github.com/sagernet/sing/common/exceptions"
	M "github.com/sagernet/sing/common/metadata"
	N "github.com/sagernet/sing/common/network"
)

// Deprecated
type ConnectionHandler interface {
	NewConnection(ctx context.Context, conn net.Conn, metadata InboundContext) error
}

type ConnectionHandlerEx interface {
	NewConnectionEx(ctx context.Context, conn net.Conn, metadata InboundContext, onClose N.CloseHandlerFunc)
}

// Deprecated: use PacketHandlerEx instead
type PacketHandler interface {
	NewPacket(ctx context.Context, conn N.PacketConn, buffer *buf.Buffer, metadata InboundContext) error
}

type PacketHandlerEx interface {
	NewPacketEx(buffer *buf.Buffer, source M.Socksaddr)
}

// Deprecated: use OOBPacketHandlerEx instead
type OOBPacketHandler interface {
	NewPacket(ctx context.Context, conn N.PacketConn, buffer *buf.Buffer, oob []byte, metadata InboundContext) error
}

type OOBPacketHandlerEx interface {
	NewPacketEx(buffer *buf.Buffer, oob []byte, source M.Socksaddr)
}

// Deprecated
type PacketConnectionHandler interface {
	NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata InboundContext) error
}

type PacketConnectionHandlerEx interface {
	NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, metadata InboundContext, onClose N.CloseHandlerFunc)
}

// Deprecated: use TCPConnectionHandlerEx instead
//
//nolint:staticcheck
type UpstreamHandlerAdapter interface {
	N.TCPConnectionHandler
	N.UDPConnectionHandler
	E.Handler
}

type UpstreamHandlerAdapterEx interface {
	N.TCPConnectionHandlerEx
	N.UDPConnectionHandlerEx
}


================================================
FILE: adapter/inbound/adapter.go
================================================
package inbound

type Adapter struct {
	inboundType string
	inboundTag  string
}

func NewAdapter(inboundType string, inboundTag string) Adapter {
	return Adapter{
		inboundType: inboundType,
		inboundTag:  inboundTag,
	}
}

func (a *Adapter) Type() string {
	return a.inboundType
}

func (a *Adapter) Tag() string {
	return a.inboundTag
}


================================================
FILE: adapter/inbound/manager.go
================================================
package inbound

import (
	"context"
	"os"
	"sync"
	"time"

	"github.com/sagernet/sing-box/adapter"
	"github.com/sagernet/sing-box/common/taskmonitor"
	C "github.com/sagernet/sing-box/constant"
	"github.com/sagernet/sing-box/log"
	"github.com/sagernet/sing/common"
	E "github.com/sagernet/sing/common/exceptions"
	F "github.com/sagernet/sing/common/format"
)

var _ adapter.InboundManager = (*Manager)(nil)

type Manager struct {
	logger       log.ContextLogger
	registry     adapter.InboundRegistry
	endpoint     adapter.EndpointManager
	access       sync.Mutex
	started      bool
	stage        adapter.StartStage
	inbounds     []adapter.Inbound
	inboundByTag map[string]adapter.Inbound
}

func NewManager(logger log.ContextLogger, registry adapter.InboundRegistry, endpoint adapter.EndpointManager) *Manager {
	return &Manager{
		logger:       logger,
		registry:     registry,
		endpoint:     endpoint,
		inboundByTag: make(map[string]adapter.Inbound),
	}
}

func (m *Manager) Start(stage adapter.StartStage) error {
	m.access.Lock()
	if m.started && m.stage >= stage {
		panic("already started")
	}
	m.started = true
	m.stage = stage
	inbounds := m.inbounds
	m.access.Unlock()
	for _, inbound := range inbounds {
		name := "inbound/" + inbound.Type() + "[" + inbound.Tag() + "]"
		m.logger.Trace(stage, " ", name)
		startTime := time.Now()
		err := adapter.LegacyStart(inbound, stage)
		if err != nil {
			return E.Cause(err, stage, " ", name)
		}
		m.logger.Trace(stage, " ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
	}
	return nil
}

func (m *Manager) Close() error {
	m.access.Lock()
	defer m.access.Unlock()
	if !m.started {
		return nil
	}
	m.started = false
	inbounds := m.inbounds
	m.inbounds = nil
	monitor := taskmonitor.New(m.logger, C.StopTimeout)
	var err error
	for _, inbound := range inbounds {
		name := "inbound/" + inbound.Type() + "[" + inbound.Tag() + "]"
		m.logger.Trace("close ", name)
		startTime := time.Now()
		monitor.Start("close ", name)
		err = E.Append(err, inbound.Close(), func(err error) error {
			return E.Cause(err, "close ", name)
		})
		monitor.Finish()
		m.logger.Trace("close ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
	}
	return nil
}

func (m *Manager) Inbounds() []adapter.Inbound {
	m.access.Lock()
	defer m.access.Unlock()
	return m.inbounds
}

func (m *Manager) Get(tag string) (adapter.Inbound, bool) {
	m.access.Lock()
	inbound, found := m.inboundByTag[tag]
	m.access.Unlock()
	if found {
		return inbound, true
	}
	return m.endpoint.Get(tag)
}

func (m *Manager) Remove(tag string) error {
	m.access.Lock()
	inbound, found := m.inboundByTag[tag]
	if !found {
		m.access.Unlock()
		return os.ErrInvalid
	}
	delete(m.inboundByTag, tag)
	index := common.Index(m.inbounds, func(it adapter.Inbound) bool {
		return it == inbound
	})
	if index == -1 {
		panic("invalid inbound index")
	}
	m.inbounds = append(m.inbounds[:index], m.inbounds[index+1:]...)
	started := m.started
	m.access.Unlock()
	if started {
		return inbound.Close()
	}
	return nil
}

func (m *Manager) Create(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, outboundType string, options any) error {
	inbound, err := m.registry.Create(ctx, router, logger, tag, outboundType, options)
	if err != nil {
		return err
	}
	m.access.Lock()
	defer m.access.Unlock()
	if m.started {
		name := "inbound/" + inbound.Type() + "[" + inbound.Tag() + "]"
		for _, stage := range adapter.ListStartStages {
			m.logger.Trace(stage, " ", name)
			startTime := time.Now()
			err = adapter.LegacyStart(inbound, stage)
			if err != nil {
				return E.Cause(err, stage, " ", name)
			}
			m.logger.Trace(stage, " ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
		}
	}
	if existsInbound, loaded := m.inboundByTag[tag]; loaded {
		if m.started {
			err = existsInbound.Close()
			if err != nil {
				return E.Cause(err, "close inbound/", existsInbound.Type(), "[", existsInbound.Tag(), "]")
			}
		}
		existsIndex := common.Index(m.inbounds, func(it adapter.Inbound) bool {
			return it == existsInbound
		})
		if existsIndex == -1 {
			panic("invalid inbound index")
		}
		m.inbounds = append(m.inbounds[:existsIndex], m.inbounds[existsIndex+1:]...)
	}
	m.inbounds = append(m.inbounds, inbound)
	m.inboundByTag[tag] = inbound
	return nil
}


================================================
FILE: adapter/inbound/registry.go
================================================
package inbound

import (
	"context"
	"sync"

	"github.com/sagernet/sing-box/adapter"
	"github.com/sagernet/sing-box/log"
	"github.com/sagernet/sing/common"
	E "github.com/sagernet/sing/common/exceptions"
)

type ConstructorFunc[T any] func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options T) (adapter.Inbound, error)

func Register[Options any](registry *Registry, outboundType string, constructor ConstructorFunc[Options]) {
	registry.register(outboundType, func() any {
		return new(Options)
	}, func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, rawOptions any) (adapter.Inbound, error) {
		var options *Options
		if rawOptions != nil {
			options = rawOptions.(*Options)
		}
		return constructor(ctx, router, logger, tag, common.PtrValueOrDefault(options))
	})
}

var _ adapter.InboundRegistry = (*Registry)(nil)

type (
	optionsConstructorFunc func() any
	constructorFunc        func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options any) (adapter.Inbound, error)
)

type Registry struct {
	access      sync.Mutex
	optionsType map[string]optionsConstructorFunc
	constructor map[string]constructorFunc
}

func NewRegistry() *Registry {
	return &Registry{
		optionsType: make(map[string]optionsConstructorFunc),
		constructor: make(map[string]constructorFunc),
	}
}

func (m *Registry) CreateOptions(outboundType string) (any, bool) {
	m.access.Lock()
	defer m.access.Unlock()
	optionsConstructor, loaded := m.optionsType[outboundType]
	if !loaded {
		return nil, false
	}
	return optionsConstructor(), true
}

func (m *Registry) Create(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, outboundType string, options any) (adapter.Inbound, error) {
	m.access.Lock()
	defer m.access.Unlock()
	constructor, loaded := m.constructor[outboundType]
	if !loaded {
		return nil, E.New("outbound type not found: " + outboundType)
	}
	return constructor(ctx, router, logger, tag, options)
}

func (m *Registry) register(outboundType string, optionsConstructor optionsConstructorFunc, constructor constructorFunc) {
	m.access.Lock()
	defer m.access.Unlock()
	m.optionsType[outboundType] = optionsConstructor
	m.constructor[outboundType] = constructor
}


================================================
FILE: adapter/inbound.go
================================================
package adapter

import (
	"context"
	"net"
	"net/netip"
	"time"

	C "github.com/sagernet/sing-box/constant"
	"github.com/sagernet/sing-box/log"
	"github.com/sagernet/sing-box/option"
	M "github.com/sagernet/sing/common/metadata"
)

type Inbound interface {
	Lifecycle
	Type() string
	Tag() string
}

type TCPInjectableInbound interface {
	Inbound
	ConnectionHandlerEx
}

type UDPInjectableInbound interface {
	Inbound
	PacketConnectionHandlerEx
}

type InboundRegistry interface {
	option.InboundOptionsRegistry
	Create(ctx context.Context, router Router, logger log.ContextLogger, tag string, inboundType string, options any) (Inbound, error)
}

type InboundManager interface {
	Lifecycle
	Inbounds() []Inbound
	Get(tag string) (Inbound, bool)
	Remove(tag string) error
	Create(ctx context.Context, router Router, logger log.ContextLogger, tag string, inboundType string, options any) error
}

type InboundContext struct {
	Inbound     string
	InboundType string
	IPVersion   uint8
	Network     string
	Source      M.Socksaddr
	Destination M.Socksaddr
	User        string
	Outbound    string

	// sniffer

	Protocol     string
	Domain       string
	Client       string
	SniffContext any
	SnifferNames []string
	SniffError   error

	// cache

	// Deprecated: implement in rule action
	InboundDetour             string
	LastInbound               string
	OriginDestination         M.Socksaddr
	RouteOriginalDestination  M.Socksaddr
	UDPDisableDomainUnmapping bool
	UDPConnect                bool
	UDPTimeout                time.Duration
	TLSFragment               bool
	TLSFragmentFallbackDelay  time.Duration
	TLSRecordFragment         bool

	NetworkStrategy     *C.NetworkStrategy
	NetworkType         []C.InterfaceType
	FallbackNetworkType []C.InterfaceType
	FallbackDelay       time.Duration

	DestinationAddresses []netip.Addr
	SourceGeoIPCode      string
	GeoIPCode            string
	ProcessInfo          *ConnectionOwner
	SourceMACAddress     net.HardwareAddr
	SourceHostname       string
	QueryType            uint16
	FakeIP               bool

	// rule cache

	IPCIDRMatchSource bool
	IPCIDRAcceptEmpty bool

	SourceAddressMatch           bool
	SourcePortMatch              bool
	DestinationAddressMatch      bool
	DestinationPortMatch         bool
	DidMatch                     bool
	IgnoreDestinationIPCIDRMatch bool
}

func (c *InboundContext) ResetRuleCache() {
	c.IPCIDRMatchSource = false
	c.IPCIDRAcceptEmpty = false
	c.SourceAddressMatch = false
	c.SourcePortMatch = false
	c.DestinationAddressMatch = false
	c.DestinationPortMatch = false
	c.DidMatch = false
}

type inboundContextKey struct{}

func WithContext(ctx context.Context, inboundContext *InboundContext) context.Context {
	return context.WithValue(ctx, (*inboundContextKey)(nil), inboundContext)
}

func ContextFrom(ctx context.Context) *InboundContext {
	metadata := ctx.Value((*inboundContextKey)(nil))
	if metadata == nil {
		return nil
	}
	return metadata.(*InboundContext)
}

func ExtendContext(ctx context.Context) (context.Context, *InboundContext) {
	var newMetadata InboundContext
	if metadata := ContextFrom(ctx); metadata != nil {
		newMetadata = *metadata
	}
	return WithContext(ctx, &newMetadata), &newMetadata
}

func OverrideContext(ctx context.Context) context.Context {
	if metadata := ContextFrom(ctx); metadata != nil {
		newMetadata := *metadata
		return WithContext(ctx, &newMetadata)
	}
	return ctx
}


================================================
FILE: adapter/lifecycle.go
================================================
package adapter

import (
	"reflect"
	"strings"
	"time"

	"github.com/sagernet/sing-box/log"
	E "github.com/sagernet/sing/common/exceptions"
	F "github.com/sagernet/sing/common/format"
)

type SimpleLifecycle interface {
	Start() error
	Close() error
}

type StartStage uint8

const (
	StartStateInitialize StartStage = iota
	StartStateStart
	StartStatePostStart
	StartStateStarted
)

var ListStartStages = []StartStage{
	StartStateInitialize,
	StartStateStart,
	StartStatePostStart,
	StartStateStarted,
}

func (s StartStage) String() string {
	switch s {
	case StartStateInitialize:
		return "initialize"
	case StartStateStart:
		return "start"
	case StartStatePostStart:
		return "post-start"
	case StartStateStarted:
		return "finish-start"
	default:
		panic("unknown stage")
	}
}

type Lifecycle interface {
	Start(stage StartStage) error
	Close() error
}

type LifecycleService interface {
	Name() string
	Lifecycle
}

func getServiceName(service any) string {
	if named, ok := service.(interface {
		Type() string
		Tag() string
	}); ok {
		tag := named.Tag()
		if tag != "" {
			return named.Type() + "[" + tag + "]"
		}
		return named.Type()
	}
	t := reflect.TypeOf(service)
	if t.Kind() == reflect.Ptr {
		t = t.Elem()
	}
	return strings.ToLower(t.Name())
}

func Start(logger log.ContextLogger, stage StartStage, services ...Lifecycle) error {
	for _, service := range services {
		name := getServiceName(service)
		logger.Trace(stage, " ", name)
		startTime := time.Now()
		err := service.Start(stage)
		if err != nil {
			return err
		}
		logger.Trace(stage, " ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
	}
	return nil
}

func StartNamed(logger log.ContextLogger, stage StartStage, services []LifecycleService) error {
	for _, service := range services {
		logger.Trace(stage, " ", service.Name())
		startTime := time.Now()
		err := service.Start(stage)
		if err != nil {
			return E.Cause(err, stage.String(), " ", service.Name())
		}
		logger.Trace(stage, " ", service.Name(), " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
	}
	return nil
}


================================================
FILE: adapter/lifecycle_legacy.go
================================================
package adapter

func LegacyStart(starter any, stage StartStage) error {
	if lifecycle, isLifecycle := starter.(Lifecycle); isLifecycle {
		return lifecycle.Start(stage)
	}
	switch stage {
	case StartStateInitialize:
		if preStarter, isPreStarter := starter.(interface {
			PreStart() error
		}); isPreStarter {
			return preStarter.PreStart()
		}
	case StartStateStart:
		if starter, isStarter := starter.(interface {
			Start() error
		}); isStarter {
			return starter.Start()
		}
	case StartStateStarted:
		if postStarter, isPostStarter := starter.(interface {
			PostStart() error
		}); isPostStarter {
			return postStarter.PostStart()
		}
	}
	return nil
}

type lifecycleServiceWrapper struct {
	SimpleLifecycle
	name string
}

func NewLifecycleService(service SimpleLifecycle, name string) LifecycleService {
	return &lifecycleServiceWrapper{
		SimpleLifecycle: service,
		name:            name,
	}
}

func (l *lifecycleServiceWrapper) Name() string {
	return l.name
}

func (l *lifecycleServiceWrapper) Start(stage StartStage) error {
	return LegacyStart(l.SimpleLifecycle, stage)
}

func (l *lifecycleServiceWrapper) Close() error {
	return l.SimpleLifecycle.Close()
}


================================================
FILE: adapter/neighbor.go
================================================
package adapter

import (
	"net"
	"net/netip"
)

type NeighborEntry struct {
	Address    netip.Addr
	MACAddress net.HardwareAddr
	Hostname   string
}

type NeighborResolver interface {
	LookupMAC(address netip.Addr) (net.HardwareAddr, bool)
	LookupHostname(address netip.Addr) (string, bool)
	Start() error
	Close() error
}

type NeighborUpdateListener interface {
	UpdateNeighborTable(entries []NeighborEntry)
}


================================================
FILE: adapter/network.go
================================================
package adapter

import (
	"time"

	C "github.com/sagernet/sing-box/constant"
	"github.com/sagernet/sing-tun"
	"github.com/sagernet/sing/common/control"
)

type NetworkManager interface {
	Lifecycle
	Initialize(ruleSets []RuleSet)
	InterfaceFinder() control.InterfaceFinder
	UpdateInterfaces() error
	DefaultNetworkInterface() *NetworkInterface
	NetworkInterfaces() []NetworkInterface
	AutoDetectInterface() bool
	AutoDetectInterfaceFunc() control.Func
	ProtectFunc() control.Func
	DefaultOptions() NetworkOptions
	RegisterAutoRedirectOutputMark(mark uint32) error
	AutoRedirectOutputMark() uint32
	AutoRedirectOutputMarkFunc() control.Func
	NetworkMonitor() tun.NetworkUpdateMonitor
	InterfaceMonitor() tun.DefaultInterfaceMonitor
	PackageManager() tun.PackageManager
	NeedWIFIState() bool
	WIFIState() WIFIState
	UpdateWIFIState()
	ResetNetwork()
}

type NetworkOptions struct {
	BindInterface        string
	RoutingMark          uint32
	DomainResolver       string
	DomainResolveOptions DNSQueryOptions
	NetworkStrategy      *C.NetworkStrategy
	NetworkType          []C.InterfaceType
	FallbackNetworkType  []C.InterfaceType
	FallbackDelay        time.Duration
}

type InterfaceUpdateListener interface {
	InterfaceUpdated()
}

type WIFIState struct {
	SSID  string
	BSSID string
}

type NetworkInterface struct {
	control.Interface
	Type        C.InterfaceType
	DNSServers  []string
	Expensive   bool
	Constrained bool
}


================================================
FILE: adapter/outbound/adapter.go
================================================
package outbound

import (
	"github.com/sagernet/sing-box/option"
)

type Adapter struct {
	outboundType string
	outboundTag  string
	network      []string
	dependencies []string
}

func NewAdapter(outboundType string, outboundTag string, network []string, dependencies []string) Adapter {
	return Adapter{
		outboundType: outboundType,
		outboundTag:  outboundTag,
		network:      network,
		dependencies: dependencies,
	}
}

func NewAdapterWithDialerOptions(outboundType string, outboundTag string, network []string, dialOptions option.DialerOptions) Adapter {
	var dependencies []string
	if dialOptions.Detour != "" {
		dependencies = []string{dialOptions.Detour}
	}
	return NewAdapter(outboundType, outboundTag, network, dependencies)
}

func (a *Adapter) Type() string {
	return a.outboundType
}

func (a *Adapter) Tag() string {
	return a.outboundTag
}

func (a *Adapter) Network() []string {
	return a.network
}

func (a *Adapter) Dependencies() []string {
	return a.dependencies
}


================================================
FILE: adapter/outbound/manager.go
================================================
package outbound

import (
	"context"
	"io"
	"os"
	"strings"
	"sync"
	"time"

	"github.com/sagernet/sing-box/adapter"
	"github.com/sagernet/sing-box/common/taskmonitor"
	C "github.com/sagernet/sing-box/constant"
	"github.com/sagernet/sing-box/log"
	"github.com/sagernet/sing/common"
	E "github.com/sagernet/sing/common/exceptions"
	F "github.com/sagernet/sing/common/format"
	"github.com/sagernet/sing/common/logger"
)

var _ adapter.OutboundManager = (*Manager)(nil)

type Manager struct {
	logger                  log.ContextLogger
	registry                adapter.OutboundRegistry
	endpoint                adapter.EndpointManager
	defaultTag              string
	access                  sync.RWMutex
	started                 bool
	stage                   adapter.StartStage
	outbounds               []adapter.Outbound
	outboundByTag           map[string]adapter.Outbound
	dependByTag             map[string][]string
	defaultOutbound         adapter.Outbound
	defaultOutboundFallback func() (adapter.Outbound, error)
}

func NewManager(logger logger.ContextLogger, registry adapter.OutboundRegistry, endpoint adapter.EndpointManager, defaultTag string) *Manager {
	return &Manager{
		logger:        logger,
		registry:      registry,
		endpoint:      endpoint,
		defaultTag:    defaultTag,
		outboundByTag: make(map[string]adapter.Outbound),
		dependByTag:   make(map[string][]string),
	}
}

func (m *Manager) Initialize(defaultOutboundFallback func() (adapter.Outbound, error)) {
	m.defaultOutboundFallback = defaultOutboundFallback
}

func (m *Manager) Start(stage adapter.StartStage) error {
	m.access.Lock()
	if m.started && m.stage >= stage {
		panic("already started")
	}
	m.started = true
	m.stage = stage
	if stage == adapter.StartStateStart {
		if m.defaultTag != "" && m.defaultOutbound == nil {
			defaultEndpoint, loaded := m.endpoint.Get(m.defaultTag)
			if !loaded {
				m.access.Unlock()
				return E.New("default outbound not found: ", m.defaultTag)
			}
			m.defaultOutbound = defaultEndpoint
		}
		if m.defaultOutbound == nil {
			directOutbound, err := m.defaultOutboundFallback()
			if err != nil {
				m.access.Unlock()
				return E.Cause(err, "create direct outbound for fallback")
			}
			m.outbounds = append(m.outbounds, directOutbound)
			m.outboundByTag[directOutbound.Tag()] = directOutbound
			m.defaultOutbound = directOutbound
		}
		outbounds := m.outbounds
		m.access.Unlock()
		return m.startOutbounds(append(outbounds, common.Map(m.endpoint.Endpoints(), func(it adapter.Endpoint) adapter.Outbound { return it })...))
	} else {
		outbounds := m.outbounds
		m.access.Unlock()
		for _, outbound := range outbounds {
			name := "outbound/" + outbound.Type() + "[" + outbound.Tag() + "]"
			m.logger.Trace(stage, " ", name)
			startTime := time.Now()
			err := adapter.LegacyStart(outbound, stage)
			if err != nil {
				return E.Cause(err, stage, " ", name)
			}
			m.logger.Trace(stage, " ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
		}
	}
	return nil
}

func (m *Manager) startOutbounds(outbounds []adapter.Outbound) error {
	monitor := taskmonitor.New(m.logger, C.StartTimeout)
	started := make(map[string]bool)
	for {
		canContinue := false
	startOne:
		for _, outboundToStart := range outbounds {
			outboundTag := outboundToStart.Tag()
			if started[outboundTag] {
				continue
			}
			dependencies := outboundToStart.Dependencies()
			for _, dependency := range dependencies {
				if !started[dependency] {
					continue startOne
				}
			}
			started[outboundTag] = true
			canContinue = true
			name := "outbound/" + outboundToStart.Type() + "[" + outboundTag + "]"
			if starter, isStarter := outboundToStart.(adapter.Lifecycle); isStarter {
				m.logger.Trace("start ", name)
				startTime := time.Now()
				monitor.Start("start ", name)
				err := starter.Start(adapter.StartStateStart)
				monitor.Finish()
				if err != nil {
					return E.Cause(err, "start ", name)
				}
				m.logger.Trace("start ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
			} else if starter, isStarter := outboundToStart.(interface {
				Start() error
			}); isStarter {
				m.logger.Trace("start ", name)
				startTime := time.Now()
				monitor.Start("start ", name)
				err := starter.Start()
				monitor.Finish()
				if err != nil {
					return E.Cause(err, "start ", name)
				}
				m.logger.Trace("start ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
			}
		}
		if len(started) == len(outbounds) {
			break
		}
		if canContinue {
			continue
		}
		currentOutbound := common.Find(outbounds, func(it adapter.Outbound) bool {
			return !started[it.Tag()]
		})
		var lintOutbound func(oTree []string, oCurrent adapter.Outbound) error
		lintOutbound = func(oTree []string, oCurrent adapter.Outbound) error {
			problemOutboundTag := common.Find(oCurrent.Dependencies(), func(it string) bool {
				return !started[it]
			})
			if common.Contains(oTree, problemOutboundTag) {
				return E.New("circular outbound dependency: ", strings.Join(oTree, " -> "), " -> ", problemOutboundTag)
			}
			m.access.Lock()
			problemOutbound := m.outboundByTag[problemOutboundTag]
			m.access.Unlock()
			if problemOutbound == nil {
				return E.New("dependency[", problemOutboundTag, "] not found for outbound[", oCurrent.Tag(), "]")
			}
			return lintOutbound(append(oTree, problemOutboundTag), problemOutbound)
		}
		return lintOutbound([]string{currentOutbound.Tag()}, currentOutbound)
	}
	return nil
}

func (m *Manager) Close() error {
	monitor := taskmonitor.New(m.logger, C.StopTimeout)
	m.access.Lock()
	if !m.started {
		m.access.Unlock()
		return nil
	}
	m.started = false
	outbounds := m.outbounds
	m.outbounds = nil
	m.access.Unlock()
	var err error
	for _, outbound := range outbounds {
		if closer, isCloser := outbound.(io.Closer); isCloser {
			name := "outbound/" + outbound.Type() + "[" + outbound.Tag() + "]"
			m.logger.Trace("close ", name)
			startTime := time.Now()
			monitor.Start("close ", name)
			err = E.Append(err, closer.Close(), func(err error) error {
				return E.Cause(err, "close ", name)
			})
			monitor.Finish()
			m.logger.Trace("close ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
		}
	}
	return nil
}

func (m *Manager) Outbounds() []adapter.Outbound {
	m.access.RLock()
	defer m.access.RUnlock()
	return m.outbounds
}

func (m *Manager) Outbound(tag string) (adapter.Outbound, bool) {
	m.access.RLock()
	outbound, found := m.outboundByTag[tag]
	m.access.RUnlock()
	if found {
		return outbound, true
	}
	return m.endpoint.Get(tag)
}

func (m *Manager) Default() adapter.Outbound {
	m.access.RLock()
	defer m.access.RUnlock()
	return m.defaultOutbound
}

func (m *Manager) Remove(tag string) error {
	m.access.Lock()
	defer m.access.Unlock()
	outbound, found := m.outboundByTag[tag]
	if !found {
		return os.ErrInvalid
	}
	delete(m.outboundByTag, tag)
	index := common.Index(m.outbounds, func(it adapter.Outbound) bool {
		return it == outbound
	})
	if index == -1 {
		panic("invalid inbound index")
	}
	m.outbounds = append(m.outbounds[:index], m.outbounds[index+1:]...)
	started := m.started
	if m.defaultOutbound == outbound {
		if len(m.outbounds) > 0 {
			m.defaultOutbound = m.outbounds[0]
			m.logger.Info("updated default outbound to ", m.defaultOutbound.Tag())
		} else {
			m.defaultOutbound = nil
		}
	}
	dependBy := m.dependByTag[tag]
	if len(dependBy) > 0 {
		return E.New("outbound[", tag, "] is depended by ", strings.Join(dependBy, ", "))
	}
	dependencies := outbound.Dependencies()
	for _, dependency := range dependencies {
		if len(m.dependByTag[dependency]) == 1 {
			delete(m.dependByTag, dependency)
		} else {
			m.dependByTag[dependency] = common.Filter(m.dependByTag[dependency], func(it string) bool {
				return it != tag
			})
		}
	}
	if started {
		return common.Close(outbound)
	}
	return nil
}

func (m *Manager) Create(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, inboundType string, options any) error {
	if tag == "" {
		return os.ErrInvalid
	}
	outbound, err := m.registry.CreateOutbound(ctx, router, logger, tag, inboundType, options)
	if err != nil {
		return err
	}
	if m.started {
		name := "outbound/" + outbound.Type() + "[" + outbound.Tag() + "]"
		for _, stage := range adapter.ListStartStages {
			m.logger.Trace(stage, " ", name)
			startTime := time.Now()
			err = adapter.LegacyStart(outbound, stage)
			if err != nil {
				return E.Cause(err, stage, " ", name)
			}
			m.logger.Trace(stage, " ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
		}
	}
	m.access.Lock()
	defer m.access.Unlock()
	if existsOutbound, loaded := m.outboundByTag[tag]; loaded {
		if m.started {
			err = common.Close(existsOutbound)
			if err != nil {
				return E.Cause(err, "close outbound/", existsOutbound.Type(), "[", existsOutbound.Tag(), "]")
			}
		}
		existsIndex := common.Index(m.outbounds, func(it adapter.Outbound) bool {
			return it == existsOutbound
		})
		if existsIndex == -1 {
			panic("invalid inbound index")
		}
		m.outbounds = append(m.outbounds[:existsIndex], m.outbounds[existsIndex+1:]...)
	}
	m.outbounds = append(m.outbounds, outbound)
	m.outboundByTag[tag] = outbound
	dependencies := outbound.Dependencies()
	for _, dependency := range dependencies {
		m.dependByTag[dependency] = append(m.dependByTag[dependency], tag)
	}
	if tag == m.defaultTag || (m.defaultTag == "" && m.defaultOutbound == nil) {
		m.defaultOutbound = outbound
		if m.started {
			m.logger.Info("updated default outbound to ", outbound.Tag())
		}
	}
	return nil
}


================================================
FILE: adapter/outbound/registry.go
================================================
package outbound

import (
	"context"
	"sync"

	"github.com/sagernet/sing-box/adapter"
	"github.com/sagernet/sing-box/log"
	"github.com/sagernet/sing/common"
	E "github.com/sagernet/sing/common/exceptions"
)

type ConstructorFunc[T any] func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options T) (adapter.Outbound, error)

func Register[Options any](registry *Registry, outboundType string, constructor ConstructorFunc[Options]) {
	registry.register(outboundType, func() any {
		return new(Options)
	}, func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, rawOptions any) (adapter.Outbound, error) {
		var options *Options
		if rawOptions != nil {
			options = rawOptions.(*Options)
		}
		return constructor(ctx, router, logger, tag, common.PtrValueOrDefault(options))
	})
}

var _ adapter.OutboundRegistry = (*Registry)(nil)

type (
	optionsConstructorFunc func() any
	constructorFunc        func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options any) (adapter.Outbound, error)
)

type Registry struct {
	access       sync.Mutex
	optionsType  map[string]optionsConstructorFunc
	constructors map[string]constructorFunc
}

func NewRegistry() *Registry {
	return &Registry{
		optionsType:  make(map[string]optionsConstructorFunc),
		constructors: make(map[string]constructorFunc),
	}
}

func (r *Registry) CreateOptions(outboundType string) (any, bool) {
	r.access.Lock()
	defer r.access.Unlock()
	optionsConstructor, loaded := r.optionsType[outboundType]
	if !loaded {
		return nil, false
	}
	return optionsConstructor(), true
}

func (r *Registry) CreateOutbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, outboundType string, options any) (adapter.Outbound, error) {
	r.access.Lock()
	defer r.access.Unlock()
	constructor, loaded := r.constructors[outboundType]
	if !loaded {
		return nil, E.New("outbound type not found: " + outboundType)
	}
	return constructor(ctx, router, logger, tag, options)
}

func (r *Registry) register(outboundType string, optionsConstructor optionsConstructorFunc, constructor constructorFunc) {
	r.access.Lock()
	defer r.access.Unlock()
	r.optionsType[outboundType] = optionsConstructor
	r.constructors[outboundType] = constructor
}


================================================
FILE: adapter/outbound.go
================================================
package adapter

import (
	"context"
	"net/netip"
	"time"

	"github.com/sagernet/sing-box/log"
	"github.com/sagernet/sing-box/option"
	"github.com/sagernet/sing-tun"
	N "github.com/sagernet/sing/common/network"
)

// Note: for proxy protocols, outbound creates early connections by default.

type Outbound interface {
	Type() string
	Tag() string
	Network() []string
	Dependencies() []string
	N.Dialer
}

type OutboundWithPreferredRoutes interface {
	Outbound
	PreferredDomain(domain string) bool
	PreferredAddress(address netip.Addr) bool
}

type DirectRouteOutbound interface {
	Outbound
	NewDirectRouteConnection(metadata InboundContext, routeContext tun.DirectRouteContext, timeout time.Duration) (tun.DirectRouteDestination, error)
}

type OutboundRegistry interface {
	option.OutboundOptionsRegistry
	CreateOutbound(ctx context.Context, router Router, logger log.ContextLogger, tag string, outboundType string, options any) (Outbound, error)
}

type OutboundManager interface {
	Lifecycle
	Outbounds() []Outbound
	Outbound(tag string) (Outbound, bool)
	Default() Outbound
	Remove(tag string) error
	Create(ctx context.Context, router Router, logger log.ContextLogger, tag string, outboundType string, options any) error
}


================================================
FILE: adapter/platform.go
================================================
package adapter

import (
	"github.com/sagernet/sing-box/option"
	"github.com/sagernet/sing-tun"
	"github.com/sagernet/sing/common/logger"
)

type PlatformInterface interface {
	Initialize(networkManager NetworkManager) error

	UsePlatformAutoDetectInterfaceControl() bool
	AutoDetectInterfaceControl(fd int) error

	UsePlatformInterface() bool
	OpenInterface(options *tun.Options, platformOptions option.TunPlatformOptions) (tun.Tun, error)

	UsePlatformDefaultInterfaceMonitor() bool
	CreateDefaultInterfaceMonitor(logger logger.Logger) tun.DefaultInterfaceMonitor

	UsePlatformNetworkInterfaces() bool
	NetworkInterfaces() ([]NetworkInterface, error)

	UnderNetworkExtension() bool
	NetworkExtensionIncludeAllNetworks() bool

	ClearDNSCache()
	RequestPermissionForWIFIState() error
	ReadWIFIState() WIFIState
	SystemCertificates() []string

	UsePlatformConnectionOwnerFinder() bool
	FindConnectionOwner(request *FindConnectionOwnerRequest) (*ConnectionOwner, error)

	UsePlatformWIFIMonitor() bool

	UsePlatformNotification() bool
	SendNotification(notification *Notification) error

	UsePlatformNeighborResolver() bool
	StartNeighborMonitor(listener NeighborUpdateListener) error
	CloseNeighborMonitor(listener NeighborUpdateListener) error
}

type FindConnectionOwnerRequest struct {
	IpProtocol         int32
	SourceAddress      string
	SourcePort         int32
	DestinationAddress string
	DestinationPort    int32
}

type ConnectionOwner struct {
	ProcessID          uint32
	UserId             int32
	UserName           string
	ProcessPath        string
	AndroidPackageName string
}

type Notification struct {
	Identifier string
	TypeName   string
	TypeID     int32
	Title      string
	Subtitle   string
	Body       string
	OpenURL    string
}

type SystemProxyStatus struct {
	Available bool
	Enabled   bool
}


================================================
FILE: adapter/prestart.go
================================================
package adapter


================================================
FILE: adapter/router.go
================================================
package adapter

import (
	"context"
	"crypto/tls"
	"net"
	"net/http"
	"sync"
	"time"

	C "github.com/sagernet/sing-box/constant"
	"github.com/sagernet/sing-tun"
	M "github.com/sagernet/sing/common/metadata"
	N "github.com/sagernet/sing/common/network"
	"github.com/sagernet/sing/common/ntp"
	"github.com/sagernet/sing/common/x/list"

	"go4.org/netipx"
)

type Router interface {
	Lifecycle
	ConnectionRouter
	PreMatch(metadata InboundContext, context tun.DirectRouteContext, timeout time.Duration, supportBypass bool) (tun.DirectRouteDestination, error)
	ConnectionRouterEx
	RuleSet(tag string) (RuleSet, bool)
	Rules() []Rule
	NeedFindProcess() bool
	NeedFindNeighbor() bool
	NeighborResolver() NeighborResolver
	AppendTracker(tracker ConnectionTracker)
	ResetNetwork()
}

type ConnectionTracker interface {
	RoutedConnection(ctx context.Context, conn net.Conn, metadata InboundContext, matchedRule Rule, matchOutbound Outbound) net.Conn
	RoutedPacketConnection(ctx context.Context, conn N.PacketConn, metadata InboundContext, matchedRule Rule, matchOutbound Outbound) N.PacketConn
}

// Deprecated: Use ConnectionRouterEx instead.
type ConnectionRouter interface {
	RouteConnection(ctx context.Context, conn net.Conn, metadata InboundContext) error
	RoutePacketConnection(ctx context.Context, conn N.PacketConn, metadata InboundContext) error
}

type ConnectionRouterEx interface {
	ConnectionRouter
	RouteConnectionEx(ctx context.Context, conn net.Conn, metadata InboundContext, onClose N.CloseHandlerFunc)
	RoutePacketConnectionEx(ctx context.Context, conn N.PacketConn, metadata InboundContext, onClose N.CloseHandlerFunc)
}

type RuleSet interface {
	Name() string
	StartContext(ctx context.Context, startContext *HTTPStartContext) error
	PostStart() error
	Metadata() RuleSetMetadata
	ExtractIPSet() []*netipx.IPSet
	IncRef()
	DecRef()
	Cleanup()
	RegisterCallback(callback RuleSetUpdateCallback) *list.Element[RuleSetUpdateCallback]
	UnregisterCallback(element *list.Element[RuleSetUpdateCallback])
	Close() error
	HeadlessRule
}

type RuleSetUpdateCallback func(it RuleSet)

type RuleSetMetadata struct {
	ContainsProcessRule bool
	ContainsWIFIRule    bool
	ContainsIPCIDRRule  bool
}
type HTTPStartContext struct {
	ctx             context.Context
	access          sync.Mutex
	httpClientCache map[string]*http.Client
}

func NewHTTPStartContext(ctx context.Context) *HTTPStartContext {
	return &HTTPStartContext{
		ctx:             ctx,
		httpClientCache: make(map[string]*http.Client),
	}
}

func (c *HTTPStartContext) HTTPClient(detour string, dialer N.Dialer) *http.Client {
	c.access.Lock()
	defer c.access.Unlock()
	if httpClient, loaded := c.httpClientCache[detour]; loaded {
		return httpClient
	}
	httpClient := &http.Client{
		Transport: &http.Transport{
			ForceAttemptHTTP2:   true,
			TLSHandshakeTimeout: C.TCPTimeout,
			DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
				return dialer.DialContext(ctx, network, M.ParseSocksaddr(addr))
			},
			TLSClientConfig: &tls.Config{
				Time:    ntp.TimeFuncFromContext(c.ctx),
				RootCAs: RootPoolFromContext(c.ctx),
			},
		},
	}
	c.httpClientCache[detour] = httpClient
	return httpClient
}

func (c *HTTPStartContext) Close() {
	c.access.Lock()
	defer c.access.Unlock()
	for _, client := range c.httpClientCache {
		client.CloseIdleConnections()
	}
}


================================================
FILE: adapter/rule.go
================================================
package adapter

import (
	C "github.com/sagernet/sing-box/constant"
)

type HeadlessRule interface {
	Match(metadata *InboundContext) bool
	String() string
}

type Rule interface {
	HeadlessRule
	SimpleLifecycle
	Type() string
	Action() RuleAction
}

type DNSRule interface {
	Rule
	WithAddressLimit() bool
	MatchAddressLimit(metadata *InboundContext) bool
}

type RuleAction interface {
	Type() string
	String() string
}

func IsFinalAction(action RuleAction) bool {
	switch action.Type() {
	case C.RuleActionTypeSniff, C.RuleActionTypeResolve:
		return false
	default:
		return true
	}
}


================================================
FILE: adapter/service/adapter.go
================================================
package service

type Adapter struct {
	serviceType string
	serviceTag  string
}

func NewAdapter(serviceType string, serviceTag string) Adapter {
	return Adapter{
		serviceType: serviceType,
		serviceTag:  serviceTag,
	}
}

func (a *Adapter) Type() string {
	return a.serviceType
}

func (a *Adapter) Tag() string {
	return a.serviceTag
}


================================================
FILE: adapter/service/manager.go
================================================
package service

import (
	"context"
	"os"
	"sync"
	"time"

	"github.com/sagernet/sing-box/adapter"
	"github.com/sagernet/sing-box/common/taskmonitor"
	C "github.com/sagernet/sing-box/constant"
	"github.com/sagernet/sing-box/log"
	"github.com/sagernet/sing/common"
	E "github.com/sagernet/sing/common/exceptions"
	F "github.com/sagernet/sing/common/format"
)

var _ adapter.ServiceManager = (*Manager)(nil)

type Manager struct {
	logger       log.ContextLogger
	registry     adapter.ServiceRegistry
	access       sync.Mutex
	started      bool
	stage        adapter.StartStage
	services     []adapter.Service
	serviceByTag map[string]adapter.Service
}

func NewManager(logger log.ContextLogger, registry adapter.ServiceRegistry) *Manager {
	return &Manager{
		logger:       logger,
		registry:     registry,
		serviceByTag: make(map[string]adapter.Service),
	}
}

func (m *Manager) Start(stage adapter.StartStage) error {
	m.access.Lock()
	if m.started && m.stage >= stage {
		panic("already started")
	}
	m.started = true
	m.stage = stage
	services := m.services
	m.access.Unlock()
	for _, service := range services {
		name := "service/" + service.Type() + "[" + service.Tag() + "]"
		m.logger.Trace(stage, " ", name)
		startTime := time.Now()
		err := adapter.LegacyStart(service, stage)
		if err != nil {
			return E.Cause(err, stage, " ", name)
		}
		m.logger.Trace(stage, " ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
	}
	return nil
}

func (m *Manager) Close() error {
	m.access.Lock()
	defer m.access.Unlock()
	if !m.started {
		return nil
	}
	m.started = false
	services := m.services
	m.services = nil
	monitor := taskmonitor.New(m.logger, C.StopTimeout)
	var err error
	for _, service := range services {
		name := "service/" + service.Type() + "[" + service.Tag() + "]"
		m.logger.Trace("close ", name)
		startTime := time.Now()
		monitor.Start("close ", name)
		err = E.Append(err, service.Close(), func(err error) error {
			return E.Cause(err, "close ", name)
		})
		monitor.Finish()
		m.logger.Trace("close ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
	}
	return nil
}

func (m *Manager) Services() []adapter.Service {
	m.access.Lock()
	defer m.access.Unlock()
	return m.services
}

func (m *Manager) Get(tag string) (adapter.Service, bool) {
	m.access.Lock()
	service, found := m.serviceByTag[tag]
	m.access.Unlock()
	return service, found
}

func (m *Manager) Remove(tag string) error {
	m.access.Lock()
	service, found := m.serviceByTag[tag]
	if !found {
		m.access.Unlock()
		return os.ErrInvalid
	}
	delete(m.serviceByTag, tag)
	index := common.Index(m.services, func(it adapter.Service) bool {
		return it == service
	})
	if index == -1 {
		panic("invalid service index")
	}
	m.services = append(m.services[:index], m.services[index+1:]...)
	started := m.started
	m.access.Unlock()
	if started {
		return service.Close()
	}
	return nil
}

func (m *Manager) Create(ctx context.Context, logger log.ContextLogger, tag string, serviceType string, options any) error {
	service, err := m.registry.Create(ctx, logger, tag, serviceType, options)
	if err != nil {
		return err
	}
	m.access.Lock()
	defer m.access.Unlock()
	if m.started {
		name := "service/" + service.Type() + "[" + service.Tag() + "]"
		for _, stage := range adapter.ListStartStages {
			m.logger.Trace(stage, " ", name)
			startTime := time.Now()
			err = adapter.LegacyStart(service, stage)
			if err != nil {
				return E.Cause(err, stage, " ", name)
			}
			m.logger.Trace(stage, " ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
		}
	}
	if existsService, loaded := m.serviceByTag[tag]; loaded {
		if m.started {
			err = existsService.Close()
			if err != nil {
				return E.Cause(err, "close service/", existsService.Type(), "[", existsService.Tag(), "]")
			}
		}
		existsIndex := common.Index(m.services, func(it adapter.Service) bool {
			return it == existsService
		})
		if existsIndex == -1 {
			panic("invalid service index")
		}
		m.services = append(m.services[:existsIndex], m.services[existsIndex+1:]...)
	}
	m.services = append(m.services, service)
	m.serviceByTag[tag] = service
	return nil
}


================================================
FILE: adapter/service/registry.go
================================================
package service

import (
	"context"
	"sync"

	"github.com/sagernet/sing-box/adapter"
	"github.com/sagernet/sing-box/log"
	"github.com/sagernet/sing/common"
	E "github.com/sagernet/sing/common/exceptions"
)

type ConstructorFunc[T any] func(ctx context.Context, logger log.ContextLogger, tag string, options T) (adapter.Service, error)

func Register[Options any](registry *Registry, outboundType string, constructor ConstructorFunc[Options]) {
	registry.register(outboundType, func() any {
		return new(Options)
	}, func(ctx context.Context, logger log.ContextLogger, tag string, rawOptions any) (adapter.Service, error) {
		var options *Options
		if rawOptions != nil {
			options = rawOptions.(*Options)
		}
		return constructor(ctx, logger, tag, common.PtrValueOrDefault(options))
	})
}

var _ adapter.ServiceRegistry = (*Registry)(nil)

type (
	optionsConstructorFunc func() any
	constructorFunc        func(ctx context.Context, logger log.ContextLogger, tag string, options any) (adapter.Service, error)
)

type Registry struct {
	access      sync.Mutex
	optionsType map[string]optionsConstructorFunc
	constructor map[string]constructorFunc
}

func NewRegistry() *Registry {
	return &Registry{
		optionsType: make(map[string]optionsConstructorFunc),
		constructor: make(map[string]constructorFunc),
	}
}

func (m *Registry) CreateOptions(outboundType string) (any, bool) {
	m.access.Lock()
	defer m.access.Unlock()
	optionsConstructor, loaded := m.optionsType[outboundType]
	if !loaded {
		return nil, false
	}
	return optionsConstructor(), true
}

func (m *Registry) Create(ctx context.Context, logger log.ContextLogger, tag string, outboundType string, options any) (adapter.Service, error) {
	m.access.Lock()
	defer m.access.Unlock()
	constructor, loaded := m.constructor[outboundType]
	if !loaded {
		return nil, E.New("outbound type not found: " + outboundType)
	}
	return constructor(ctx, logger, tag, options)
}

func (m *Registry) register(outboundType string, optionsConstructor optionsConstructorFunc, constructor constructorFunc) {
	m.access.Lock()
	defer m.access.Unlock()
	m.optionsType[outboundType] = optionsConstructor
	m.constructor[outboundType] = constructor
}


================================================
FILE: adapter/service.go
================================================
package adapter

import (
	"context"

	"github.com/sagernet/sing-box/log"
	"github.com/sagernet/sing-box/option"
)

type Service interface {
	Lifecycle
	Type() string
	Tag() string
}

type ServiceRegistry interface {
	option.ServiceOptionsRegistry
	Create(ctx context.Context, logger log.ContextLogger, tag string, serviceType string, options any) (Service, error)
}

type ServiceManager interface {
	Lifecycle
	Services() []Service
	Get(tag string) (Service, bool)
	Remove(tag string) error
	Create(ctx context.Context, logger log.ContextLogger, tag string, serviceType string, options any) error
}


================================================
FILE: adapter/ssm.go
================================================
package adapter

import (
	"net"

	N "github.com/sagernet/sing/common/network"
)

type ManagedSSMServer interface {
	Inbound
	SetTracker(tracker SSMTracker)
	UpdateUsers(users []string, uPSKs []string) error
}

type SSMTracker interface {
	TrackConnection(conn net.Conn, metadata InboundContext) net.Conn
	TrackPacketConnection(conn N.PacketConn, metadata InboundContext) N.PacketConn
}


================================================
FILE: adapter/time.go
================================================
package adapter

import "time"

type TimeService interface {
	SimpleLifecycle
	TimeFunc() func() time.Time
}


================================================
FILE: adapter/upstream.go
================================================
package adapter

import (
	"context"
	"net"

	M "github.com/sagernet/sing/common/metadata"
	N "github.com/sagernet/sing/common/network"
)

type (
	ConnectionHandlerFuncEx       = func(ctx context.Context, conn net.Conn, metadata InboundContext, onClose N.CloseHandlerFunc)
	PacketConnectionHandlerFuncEx = func(ctx context.Context, conn N.PacketConn, metadata InboundContext, onClose N.CloseHandlerFunc)
)

func NewUpstreamHandlerEx(
	metadata InboundContext,
	connectionHandler ConnectionHandlerFuncEx,
	packetHandler PacketConnectionHandlerFuncEx,
) UpstreamHandlerAdapterEx {
	return &myUpstreamHandlerWrapperEx{
		metadata:          metadata,
		connectionHandler: connectionHandler,
		packetHandler:     packetHandler,
	}
}

var _ UpstreamHandlerAdapterEx = (*myUpstreamHandlerWrapperEx)(nil)

type myUpstreamHandlerWrapperEx struct {
	metadata          InboundContext
	connectionHandler ConnectionHandlerFuncEx
	packetHandler     PacketConnectionHandlerFuncEx
}

func (w *myUpstreamHandlerWrapperEx) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
	myMetadata := w.metadata
	if source.IsValid() {
		myMetadata.Source = source
	}
	if destination.IsValid() {
		myMetadata.Destination = destination
	}
	w.connectionHandler(ctx, conn, myMetadata, onClose)
}

func (w *myUpstreamHandlerWrapperEx) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
	myMetadata := w.metadata
	if source.IsValid() {
		myMetadata.Source = source
	}
	if destination.IsValid() {
		myMetadata.Destination = destination
	}
	w.packetHandler(ctx, conn, myMetadata, onClose)
}

var _ UpstreamHandlerAdapterEx = (*myUpstreamContextHandlerWrapperEx)(nil)

type myUpstreamContextHandlerWrapperEx struct {
	connectionHandler ConnectionHandlerFuncEx
	packetHandler     PacketConnectionHandlerFuncEx
}

func NewUpstreamContextHandlerEx(
	connectionHandler ConnectionHandlerFuncEx,
	packetHandler PacketConnectionHandlerFuncEx,
) UpstreamHandlerAdapterEx {
	return &myUpstreamContextHandlerWrapperEx{
		connectionHandler: connectionHandler,
		packetHandler:     packetHandler,
	}
}

func (w *myUpstreamContextHandlerWrapperEx) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
	_, myMetadata := ExtendContext(ctx)
	if source.IsValid() {
		myMetadata.Source = source
	}
	if destination.IsValid() {
		myMetadata.Destination = destination
	}
	w.connectionHandler(ctx, conn, *myMetadata, onClose)
}

func (w *myUpstreamContextHandlerWrapperEx) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
	_, myMetadata := ExtendContext(ctx)
	if source.IsValid() {
		myMetadata.Source = source
	}
	if destination.IsValid() {
		myMetadata.Destination = destination
	}
	w.packetHandler(ctx, conn, *myMetadata, onClose)
}

func NewRouteHandlerEx(
	metadata InboundContext,
	router ConnectionRouterEx,
) UpstreamHandlerAdapterEx {
	return &routeHandlerWrapperEx{
		metadata: metadata,
		router:   router,
	}
}

var _ UpstreamHandlerAdapterEx = (*routeHandlerWrapperEx)(nil)

type routeHandlerWrapperEx struct {
	metadata InboundContext
	router   ConnectionRouterEx
}

func (r *routeHandlerWrapperEx) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
	if source.IsValid() {
		r.metadata.Source = source
	}
	if destination.IsValid() {
		r.metadata.Destination = destination
	}
	r.router.RouteConnectionEx(ctx, conn, r.metadata, onClose)
}

func (r *routeHandlerWrapperEx) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
	if source.IsValid() {
		r.metadata.Source = source
	}
	if destination.IsValid() {
		r.metadata.Destination = destination
	}
	r.router.RoutePacketConnectionEx(ctx, conn, r.metadata, onClose)
}

func NewRouteContextHandlerEx(
	router ConnectionRouterEx,
) UpstreamHandlerAdapterEx {
	return &routeContextHandlerWrapperEx{
		router: router,
	}
}

var _ UpstreamHandlerAdapterEx = (*routeContextHandlerWrapperEx)(nil)

type routeContextHandlerWrapperEx struct {
	router ConnectionRouterEx
}

func (r *routeContextHandlerWrapperEx) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
	_, metadata := ExtendContext(ctx)
	if source.IsValid() {
		metadata.Source = source
	}
	if destination.IsValid() {
		metadata.Destination = destination
	}
	r.router.RouteConnectionEx(ctx, conn, *metadata, onClose)
}

func (r *routeContextHandlerWrapperEx) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
	_, metadata := ExtendContext(ctx)
	if source.IsValid() {
		metadata.Source = source
	}
	if destination.IsValid() {
		metadata.Destination = destination
	}
	r.router.RoutePacketConnectionEx(ctx, conn, *metadata, onClose)
}


================================================
FILE: adapter/upstream_legacy.go
================================================
package adapter

import (
	"context"
	"net"

	E "github.com/sagernet/sing/common/exceptions"
	"github.com/sagernet/sing/common/logger"
	M "github.com/sagernet/sing/common/metadata"
	N "github.com/sagernet/sing/common/network"
)

type (
	// Deprecated
	ConnectionHandlerFunc = func(ctx context.Context, conn net.Conn, metadata InboundContext) error
	// Deprecated
	PacketConnectionHandlerFunc = func(ctx context.Context, conn N.PacketConn, metadata InboundContext) error
)

// Deprecated
//
//nolint:staticcheck
func NewUpstreamHandler(
	metadata InboundContext,
	connectionHandler ConnectionHandlerFunc,
	packetHandler PacketConnectionHandlerFunc,
	errorHandler E.Handler,
) UpstreamHandlerAdapter {
	return &myUpstreamHandlerWrapper{
		metadata:          metadata,
		connectionHandler: connectionHandler,
		packetHandler:     packetHandler,
		errorHandler:      errorHandler,
	}
}

var _ UpstreamHandlerAdapter = (*myUpstreamHandlerWrapper)(nil)

// Deprecated: use myUpstreamHandlerWrapperEx instead.
//
//nolint:staticcheck
type myUpstreamHandlerWrapper struct {
	metadata          InboundContext
	connectionHandler ConnectionHandlerFunc
	packetHandler     PacketConnectionHandlerFunc
	errorHandler      E.Handler
}

// Deprecated: use myUpstreamHandlerWrapperEx instead.
func (w *myUpstreamHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
	myMetadata := w.metadata
	if metadata.Source.IsValid() {
		myMetadata.Source = metadata.Source
	}
	if metadata.Destination.IsValid() {
		myMetadata.Destination = metadata.Destination
	}
	return w.connectionHandler(ctx, conn, myMetadata)
}

// Deprecated: use myUpstreamHandlerWrapperEx instead.
func (w *myUpstreamHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
	myMetadata := w.metadata
	if metadata.Source.IsValid() {
		myMetadata.Source = metadata.Source
	}
	if metadata.Destination.IsValid() {
		myMetadata.Destination = metadata.Destination
	}
	return w.packetHandler(ctx, conn, myMetadata)
}

// Deprecated: use myUpstreamHandlerWrapperEx instead.
func (w *myUpstreamHandlerWrapper) NewError(ctx context.Context, err error) {
	w.errorHandler.NewError(ctx, err)
}

// Deprecated: removed
func UpstreamMetadata(metadata InboundContext) M.Metadata {
	return M.Metadata{
		Source:      metadata.Source.Unwrap(),
		Destination: metadata.Destination.Unwrap(),
	}
}

// Deprecated: Use NewUpstreamContextHandlerEx instead.
type myUpstreamContextHandlerWrapper struct {
	connectionHandler ConnectionHandlerFunc
	packetHandler     PacketConnectionHandlerFunc
	errorHandler      E.Handler
}

// Deprecated: Use NewUpstreamContextHandlerEx instead.
func NewUpstreamContextHandler(
	connectionHandler ConnectionHandlerFunc,
	packetHandler PacketConnectionHandlerFunc,
	errorHandler E.Handler,
) UpstreamHandlerAdapter {
	return &myUpstreamContextHandlerWrapper{
		connectionHandler: connectionHandler,
		packetHandler:     packetHandler,
		errorHandler:      errorHandler,
	}
}

// Deprecated: Use NewUpstreamContextHandlerEx instead.
func (w *myUpstreamContextHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
	myMetadata := ContextFrom(ctx)
	if metadata.Source.IsValid() {
		myMetadata.Source = metadata.Source
	}
	if metadata.Destination.IsValid() {
		myMetadata.Destination = metadata.Destination
	}
	return w.connectionHandler(ctx, conn, *myMetadata)
}

// Deprecated: Use NewUpstreamContextHandlerEx instead.
func (w *myUpstreamContextHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
	myMetadata := ContextFrom(ctx)
	if metadata.Source.IsValid() {
		myMetadata.Source = metadata.Source
	}
	if metadata.Destination.IsValid() {
		myMetadata.Destination = metadata.Destination
	}
	return w.packetHandler(ctx, conn, *myMetadata)
}

// Deprecated: Use NewUpstreamContextHandlerEx instead.
func (w *myUpstreamContextHandlerWrapper) NewError(ctx context.Context, err error) {
	w.errorHandler.NewError(ctx, err)
}

// Deprecated: Use ConnectionRouterEx instead.
func NewRouteHandler(
	metadata InboundContext,
	router ConnectionRouter,
	logger logger.ContextLogger,
) UpstreamHandlerAdapter {
	return &routeHandlerWrapper{
		metadata: metadata,
		router:   router,
		logger:   logger,
	}
}

// Deprecated: Use ConnectionRouterEx instead.
func NewRouteContextHandler(
	router ConnectionRouter,
	logger logger.ContextLogger,
) UpstreamHandlerAdapter {
	return &routeContextHandlerWrapper{
		router: router,
		logger: logger,
	}
}

var _ UpstreamHandlerAdapter = (*routeHandlerWrapper)(nil)

// Deprecated: Use ConnectionRouterEx instead.
//
//nolint:staticcheck
type routeHandlerWrapper struct {
	metadata InboundContext
	router   ConnectionRouter
	logger   logger.ContextLogger
}

// Deprecated: Use ConnectionRouterEx instead.
func (w *routeHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
	myMetadata := w.metadata
	if metadata.Source.IsValid() {
		myMetadata.Source = metadata.Source
	}
	if metadata.Destination.IsValid() {
		myMetadata.Destination = metadata.Destination
	}
	return w.router.RouteConnection(ctx, conn, myMetadata)
}

// Deprecated: Use ConnectionRouterEx instead.
func (w *routeHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
	myMetadata := w.metadata
	if metadata.Source.IsValid() {
		myMetadata.Source = metadata.Source
	}
	if metadata.Destination.IsValid() {
		myMetadata.Destination = metadata.Destination
	}
	return w.router.RoutePacketConnection(ctx, conn, myMetadata)
}

// Deprecated: Use ConnectionRouterEx instead.
func (w *routeHandlerWrapper) NewError(ctx context.Context, err error) {
	w.logger.ErrorContext(ctx, err)
}

var _ UpstreamHandlerAdapter = (*routeContextHandlerWrapper)(nil)

// Deprecated: Use ConnectionRouterEx instead.
type routeContextHandlerWrapper struct {
	router ConnectionRouter
	logger logger.ContextLogger
}

// Deprecated: Use ConnectionRouterEx instead.
func (w *routeContextHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
	myMetadata := ContextFrom(ctx)
	if metadata.Source.IsValid() {
		myMetadata.Source = metadata.Source
	}
	if metadata.Destination.IsValid() {
		myMetadata.Destination = metadata.Destination
	}
	return w.router.RouteConnection(ctx, conn, *myMetadata)
}

// Deprecated: Use ConnectionRouterEx instead.
func (w *routeContextHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
	myMetadata := ContextFrom(ctx)
	if metadata.Source.IsValid() {
		myMetadata.Source = metadata.Source
	}
	if metadata.Destination.IsValid() {
		myMetadata.Destination = metadata.Destination
	}
	return w.router.RoutePacketConnection(ctx, conn, *myMetadata)
}

// Deprecated: Use ConnectionRouterEx instead.
func (w *routeContextHandlerWrapper) NewError(ctx context.Context, err error) {
	w.logger.ErrorContext(ctx, err)
}


================================================
FILE: adapter/v2ray.go
================================================
package adapter

import (
	"context"
	"net"

	N "github.com/sagernet/sing/common/network"
)

type V2RayServerTransport interface {
	Network() []string
	Serve(listener net.Listener) error
	ServePacket(listener net.PacketConn) error
	Close() error
}

type V2RayServerTransportHandler interface {
	N.TCPConnectionHandlerEx
}

type V2RayClientTransport interface {
	DialContext(ctx context.Context) (net.Conn, error)
	Close() error
}


================================================
FILE: box.go
================================================
package box

import (
	"context"
	"fmt"
	"io"
	"os"
	"runtime/debug"
	"time"

	"github.com/sagernet/sing-box/adapter"
	"github.com/sagernet/sing-box/adapter/endpoint"
	"github.com/sagernet/sing-box/adapter/inbound"
	"github.com/sagernet/sing-box/adapter/outbound"
	boxService "github.com/sagernet/sing-box/adapter/service"
	"github.com/sagernet/sing-box/common/certificate"
	"github.com/sagernet/sing-box/common/dialer"
	"github.com/sagernet/sing-box/common/taskmonitor"
	"github.com/sagernet/sing-box/common/tls"
	C "github.com/sagernet/sing-box/constant"
	"github.com/sagernet/sing-box/dns"
	"github.com/sagernet/sing-box/dns/transport/local"
	"github.com/sagernet/sing-box/experimental"
	"github.com/sagernet/sing-box/experimental/cachefile"
	"github.com/sagernet/sing-box/log"
	"github.com/sagernet/sing-box/option"
	"github.com/sagernet/sing-box/protocol/direct"
	"github.com/sagernet/sing-box/route"
	"github.com/sagernet/sing/common"
	E "github.com/sagernet/sing/common/exceptions"
	F "github.com/sagernet/sing/common/format"
	"github.com/sagernet/sing/common/ntp"
	"github.com/sagernet/sing/service"
	"github.com/sagernet/sing/service/pause"
)

var _ adapter.SimpleLifecycle = (*Box)(nil)

type Box struct {
	createdAt       time.Time
	logFactory      log.Factory
	logger          log.ContextLogger
	network         *route.NetworkManager
	endpoint        *endpoint.Manager
	inbound         *inbound.Manager
	outbound        *outbound.Manager
	service         *boxService.Manager
	dnsTransport    *dns.TransportManager
	dnsRouter       *dns.Router
	connection      *route.ConnectionManager
	router          *route.Router
	internalService []adapter.LifecycleService
	done            chan struct{}
}

type Options struct {
	option.Options
	Context           context.Context
	PlatformLogWriter log.PlatformWriter
}

func Context(
	ctx context.Context,
	inboundRegistry adapter.InboundRegistry,
	outboundRegistry adapter.OutboundRegistry,
	endpointRegistry adapter.EndpointRegistry,
	dnsTransportRegistry adapter.DNSTransportRegistry,
	serviceRegistry adapter.ServiceRegistry,
) context.Context {
	if service.FromContext[option.InboundOptionsRegistry](ctx) == nil ||
		service.FromContext[adapter.InboundRegistry](ctx) == nil {
		ctx = service.ContextWith[option.InboundOptionsRegistry](ctx, inboundRegistry)
		ctx = service.ContextWith[adapter.InboundRegistry](ctx, inboundRegistry)
	}
	if service.FromContext[option.OutboundOptionsRegistry](ctx) == nil ||
		service.FromContext[adapter.OutboundRegistry](ctx) == nil {
		ctx = service.ContextWith[option.OutboundOptionsRegistry](ctx, outboundRegistry)
		ctx = service.ContextWith[adapter.OutboundRegistry](ctx, outboundRegistry)
	}
	if service.FromContext[option.EndpointOptionsRegistry](ctx) == nil ||
		service.FromContext[adapter.EndpointRegistry](ctx) == nil {
		ctx = service.ContextWith[option.EndpointOptionsRegistry](ctx, endpointRegistry)
		ctx = service.ContextWith[adapter.EndpointRegistry](ctx, endpointRegistry)
	}
	if service.FromContext[adapter.DNSTransportRegistry](ctx) == nil {
		ctx = service.ContextWith[option.DNSTransportOptionsRegistry](ctx, dnsTransportRegistry)
		ctx = service.ContextWith[adapter.DNSTransportRegistry](ctx, dnsTransportRegistry)
	}
	if service.FromContext[adapter.ServiceRegistry](ctx) == nil {
		ctx = service.ContextWith[option.ServiceOptionsRegistry](ctx, serviceRegistry)
		ctx = service.ContextWith[adapter.ServiceRegistry](ctx, serviceRegistry)
	}
	return ctx
}

func New(options Options) (*Box, error) {
	createdAt := time.Now()
	ctx := options.Context
	if ctx == nil {
		ctx = context.Background()
	}
	ctx = service.ContextWithDefaultRegistry(ctx)

	endpointRegistry := service.FromContext[adapter.EndpointRegistry](ctx)
	inboundRegistry := service.FromContext[adapter.InboundRegistry](ctx)
	outboundRegistry := service.FromContext[adapter.OutboundRegistry](ctx)
	dnsTransportRegistry := service.FromContext[adapter.DNSTransportRegistry](ctx)
	serviceRegistry := service.FromContext[adapter.ServiceRegistry](ctx)

	if endpointRegistry == nil {
		return nil, E.New("missing endpoint registry in context")
	}
	if inboundRegistry == nil {
		return nil, E.New("missing inbound registry in context")
	}
	if outboundRegistry == nil {
		return nil, E.New("missing outbound registry in context")
	}
	if dnsTransportRegistry == nil {
		return nil, E.New("missing DNS transport registry in context")
	}
	if serviceRegistry == nil {
		return nil, E.New("missing service registry in context")
	}

	ctx = pause.WithDefaultManager(ctx)
	experimentalOptions := common.PtrValueOrDefault(options.Experimental)
	err := applyDebugOptions(common.PtrValueOrDefault(experimentalOptions.Debug))
	if err != nil {
		return nil, err
	}
	var needCacheFile bool
	var needClashAPI bool
	var needV2RayAPI bool
	if experimentalOptions.CacheFile != nil && experimentalOptions.CacheFile.Enabled || options.PlatformLogWriter != nil {
		needCacheFile = true
	}
	if experimentalOptions.ClashAPI != nil || options.PlatformLogWriter != nil {
		needClashAPI = true
	}
	if experimentalOptions.V2RayAPI != nil && experimentalOptions.V2RayAPI.Listen != "" {
		needV2RayAPI = true
	}
	platformInterface := service.FromContext[adapter.PlatformInterface](ctx)
	var defaultLogWriter io.Writer
	if platformInterface != nil {
		defaultLogWriter = io.Discard
	}
	logFactory, err := log.New(log.Options{
		Context:        ctx,
		Options:        common.PtrValueOrDefault(options.Log),
		Observable:     needClashAPI,
		DefaultWriter:  defaultLogWriter,
		BaseTime:       createdAt,
		PlatformWriter: options.PlatformLogWriter,
	})
	if err != nil {
		return nil, E.Cause(err, "create log factory")
	}

	var internalServices []adapter.LifecycleService
	certificateOptions := common.PtrValueOrDefault(options.Certificate)
	if C.IsAndroid || certificateOptions.Store != "" && certificateOptions.Store != C.CertificateStoreSystem ||
		len(certificateOptions.Certificate) > 0 ||
		len(certificateOptions.CertificatePath) > 0 ||
		len(certificateOptions.CertificateDirectoryPath) > 0 {
		certificateStore, err := certificate.NewStore(ctx, logFactory.NewLogger("certificate"), certificateOptions)
		if err != nil {
			return nil, err
		}
		service.MustRegister[adapter.CertificateStore](ctx, certificateStore)
		internalServices = append(internalServices, certificateStore)
	}

	routeOptions := common.PtrValueOrDefault(options.Route)
	dnsOptions := common.PtrValueOrDefault(options.DNS)
	endpointManager := endpoint.NewManager(logFactory.NewLogger("endpoint"), endpointRegistry)
	inboundManager := inbound.NewManager(logFactory.NewLogger("inbound"), inboundRegistry, endpointManager)
	outboundManager := outbound.NewManager(logFactory.NewLogger("outbound"), outboundRegistry, endpointManager, routeOptions.Final)
	dnsTransportManager := dns.NewTransportManager(logFactory.NewLogger("dns/transport"), dnsTransportRegistry, outboundManager, dnsOptions.Final)
	serviceManager := boxService.NewManager(logFactory.NewLogger("service"), serviceRegistry)
	service.MustRegister[adapter.EndpointManager](ctx, endpointManager)
	service.MustRegister[adapter.InboundManager](ctx, inboundManager)
	service.MustRegister[adapter.OutboundManager](ctx, outboundManager)
	service.MustRegister[adapter.DNSTransportManager](ctx, dnsTransportManager)
	service.MustRegister[adapter.ServiceManager](ctx, serviceManager)
	dnsRouter := dns.NewRouter(ctx, logFactory, dnsOptions)
	service.MustRegister[adapter.DNSRouter](ctx, dnsRouter)
	networkManager, err := route.NewNetworkManager(ctx, logFactory.NewLogger("network"), routeOptions, dnsOptions)
	if err != nil {
		return nil, E.Cause(err, "initialize network manager")
	}
	service.MustRegister[adapter.NetworkManager](ctx, networkManager)
	connectionManager := route.NewConnectionManager(logFactory.NewLogger("connection"))
	service.MustRegister[adapter.ConnectionManager](ctx, connectionManager)
	router := route.NewRouter(ctx, logFactory, routeOptions, dnsOptions)
	service.MustRegister[adapter.Router](ctx, router)
	err = router.Initialize(routeOptions.Rules, routeOptions.RuleSet)
	if err != nil {
		return nil, E.Cause(err, "initialize router")
	}
	ntpOptions := common.PtrValueOrDefault(options.NTP)
	var timeService *tls.TimeServiceWrapper
	if ntpOptions.Enabled {
		timeService = new(tls.TimeServiceWrapper)
		service.MustRegister[ntp.TimeService](ctx, timeService)
	}
	for i, transportOptions := range dnsOptions.Servers {
		var tag string
		if transportOptions.Tag != "" {
			tag = transportOptions.Tag
		} else {
			tag = F.ToString(i)
		}
		err = dnsTransportManager.Create(
			ctx,
			logFactory.NewLogger(F.ToString("dns/", transportOptions.Type, "[", tag, "]")),
			tag,
			transportOptions.Type,
			transportOptions.Options,
		)
		if err != nil {
			return nil, E.Cause(err, "initialize DNS server[", i, "]")
		}
	}
	err = dnsRouter.Initialize(dnsOptions.Rules)
	if err != nil {
		return nil, E.Cause(err, "initialize dns router")
	}
	for i, endpointOptions := range options.Endpoints {
		var tag string
		if endpointOptions.Tag != "" {
			tag = endpointOptions.Tag
		} else {
			tag = F.ToString(i)
		}
		endpointCtx := ctx
		if tag != "" {
			// TODO: remove this
			endpointCtx = adapter.WithContext(endpointCtx, &adapter.InboundContext{
				Outbound: tag,
			})
		}
		err = endpointManager.Create(
			endpointCtx,
			router,
			logFactory.NewLogger(F.ToString("endpoint/", endpointOptions.Type, "[", tag, "]")),
			tag,
			endpointOptions.Type,
			endpointOptions.Options,
		)
		if err != nil {
			return nil, E.Cause(err, "initialize endpoint[", i, "]")
		}
	}
	for i, inboundOptions := range options.Inbounds {
		var tag string
		if inboundOptions.Tag != "" {
			tag = inboundOptions.Tag
		} else {
			tag = F.ToString(i)
		}
		err = inboundManager.Create(
			ctx,
			router,
			logFactory.NewLogger(F.ToString("inbound/", inboundOptions.Type, "[", tag, "]")),
			tag,
			inboundOptions.Type,
			inboundOptions.Options,
		)
		if err != nil {
			return nil, E.Cause(err, "initialize inbound[", i, "]")
		}
	}
	for i, outboundOptions := range options.Outbounds {
		var tag string
		if outboundOptions.Tag != "" {
			tag = outboundOptions.Tag
		} else {
			tag = F.ToString(i)
		}
		outboundCtx := ctx
		if tag != "" {
			// TODO: remove this
			outboundCtx = adapter.WithContext(outboundCtx, &adapter.InboundContext{
				Outbound: tag,
			})
		}
		err = outboundManager.Create(
			outboundCtx,
			router,
			logFactory.NewLogger(F.ToString("outbound/", outboundOptions.Type, "[", tag, "]")),
			tag,
			outboundOptions.Type,
			outboundOptions.Options,
		)
		if err != nil {
			return nil, E.Cause(err, "initialize outbound[", i, "]")
		}
	}
	for i, serviceOptions := range options.Services {
		var tag string
		if serviceOptions.Tag != "" {
			tag = serviceOptions.Tag
		} else {
			tag = F.ToString(i)
		}
		err = serviceManager.Create(
			ctx,
			logFactory.NewLogger(F.ToString("service/", serviceOptions.Type, "[", tag, "]")),
			tag,
			serviceOptions.Type,
			serviceOptions.Options,
		)
		if err != nil {
			return nil, E.Cause(err, "initialize service[", i, "]")
		}
	}
	outboundManager.Initialize(func() (adapter.Outbound, error) {
		return direct.NewOutbound(
			ctx,
			router,
			logFactory.NewLogger("outbound/direct"),
			"direct",
			option.DirectOutboundOptions{},
		)
	})
	dnsTransportManager.Initialize(func() (adapter.DNSTransport, error) {
		return local.NewTransport(
			ctx,
			logFactory.NewLogger("dns/local"),
			"local",
			option.LocalDNSServerOptions{},
		)
	})
	if platformInterface != nil {
		err = platformInterface.Initialize(networkManager)
		if err != nil {
			return nil, E.Cause(err, "initialize platform interface")
		}
	}
	if needCacheFile {
		cacheFile := cachefile.New(ctx, common.PtrValueOrDefault(experimentalOptions.CacheFile))
		service.MustRegister[adapter.CacheFile](ctx, cacheFile)
		internalServices = append(internalServices, cacheFile)
	}
	if needClashAPI {
		clashAPIOptions := common.PtrValueOrDefault(experimentalOptions.ClashAPI)
		clashAPIOptions.ModeList = experimental.CalculateClashModeList(options.Options)
		clashServer, err := experimental.NewClashServer(ctx, logFactory.(log.ObservableFactory), clashAPIOptions)
		if err != nil {
			return nil, E.Cause(err, "create clash-server")
		}
		router.AppendTracker(clashServer)
		service.MustRegister[adapter.ClashServer](ctx, clashServer)
		internalServices = append(internalServices, clashServer)
	}
	if needV2RayAPI {
		v2rayServer, err := experimental.NewV2RayServer(logFactory.NewLogger("v2ray-api"), common.PtrValueOrDefault(experimentalOptions.V2RayAPI))
		if err != nil {
			return nil, E.Cause(err, "create v2ray-server")
		}
		if v2rayServer.StatsService() != nil {
			router.AppendTracker(v2rayServer.StatsService())
			internalServices = append(internalServices, v2rayServer)
			service.MustRegister[adapter.V2RayServer](ctx, v2rayServer)
		}
	}
	if ntpOptions.Enabled {
		ntpDialer, err := dialer.New(ctx, ntpOptions.DialerOptions, ntpOptions.ServerIsDomain())
		if err != nil {
			return nil, E.Cause(err, "create NTP service")
		}
		ntpService := ntp.NewService(ntp.Options{
			Context:       ctx,
			Dialer:        ntpDialer,
			Logger:        logFactory.NewLogger("ntp"),
			Server:        ntpOptions.ServerOptions.Build(),
			Interval:      time.Duration(ntpOptions.Interval),
			WriteToSystem: ntpOptions.WriteToSystem,
		})
		timeService.TimeService = ntpService
		internalServices = append(internalServices, adapter.NewLifecycleService(ntpService, "ntp service"))
	}
	return &Box{
		network:         networkManager,
		endpoint:        endpointManager,
		inbound:         inboundManager,
		outbound:        outboundManager,
		dnsTransport:    dnsTransportManager,
		service:         serviceManager,
		dnsRouter:       dnsRouter,
		connection:      connectionManager,
		router:          router,
		createdAt:       createdAt,
		logFactory:      logFactory,
		logger:          logFactory.Logger(),
		internalService: internalServices,
		done:            make(chan struct{}),
	}, nil
}

func (s *Box) PreStart() error {
	err := s.preStart()
	if err != nil {
		// TODO: remove catch error
		defer func() {
			v := recover()
			if v != nil {
				println(err.Error())
				debug.PrintStack()
				panic("panic on early close: " + fmt.Sprint(v))
			}
		}()
		s.Close()
		return err
	}
	s.logger.Info("sing-box pre-started (", F.Seconds(time.Since(s.createdAt).Seconds()), "s)")
	return nil
}

func (s *Box) Start() error {
	err := s.start()
	if err != nil {
		// TODO: remove catch error
		defer func() {
			v := recover()
			if v != nil {
				println(err.Error())
				debug.PrintStack()
				println("panic on early start: " + fmt.Sprint(v))
			}
		}()
		s.Close()
		return err
	}
	s.logger.Info("sing-box started (", F.Seconds(time.Since(s.createdAt).Seconds()), "s)")
	return nil
}

func (s *Box) preStart() error {
	monitor := taskmonitor.New(s.logger, C.StartTimeout)
	monitor.Start("start logger")
	err := s.logFactory.Start()
	monitor.Finish()
	if err != nil {
		return E.Cause(err, "start logger")
	}
	err = adapter.StartNamed(s.logger, adapter.StartStateInitialize, s.internalService) // cache-file clash-api v2ray-api
	if err != nil {
		return err
	}
	err = adapter.Start(s.logger, adapter.StartStateInitialize, s.network, s.dnsTransport, s.dnsRouter, s.connection, s.router, s.outbound, s.inbound, s.endpoint, s.service)
	if err != nil {
		return err
	}
	err = adapter.Start(s.logger, adapter.StartStateStart, s.outbound, s.dnsTransport, s.dnsRouter, s.network, s.connection, s.router)
	if err != nil {
		return err
	}
	return nil
}

func (s *Box) start() error {
	err := s.preStart()
	if err != nil {
		return err
	}
	err = adapter.StartNamed(s.logger, adapter.StartStateStart, s.internalService)
	if err != nil {
		retur
Download .txt
gitextract_d_trzmkv/

├── .fpm_openwrt
├── .fpm_pacman
├── .fpm_systemd
├── .github/
│   ├── CRONET_GO_VERSION
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.yml
│   │   └── bug_report_zh.yml
│   ├── build_alpine_apk.sh
│   ├── build_openwrt_apk.sh
│   ├── deb2ipk.sh
│   ├── renovate.json
│   ├── setup_go_for_macos1013.sh
│   ├── setup_go_for_windows7.sh
│   ├── update_clients.sh
│   ├── update_cronet.sh
│   ├── update_cronet_dev.sh
│   ├── update_dependencies.sh
│   └── workflows/
│       ├── build.yml
│       ├── docker.yml
│       ├── lint.yml
│       ├── linux.yml
│       └── stale.yml
├── .gitignore
├── .gitmodules
├── .golangci.yml
├── Dockerfile
├── Dockerfile.binary
├── LICENSE
├── Makefile
├── README.md
├── adapter/
│   ├── certificate.go
│   ├── connections.go
│   ├── dns.go
│   ├── endpoint/
│   │   ├── adapter.go
│   │   ├── manager.go
│   │   └── registry.go
│   ├── endpoint.go
│   ├── experimental.go
│   ├── fakeip.go
│   ├── fakeip_metadata.go
│   ├── handler.go
│   ├── inbound/
│   │   ├── adapter.go
│   │   ├── manager.go
│   │   └── registry.go
│   ├── inbound.go
│   ├── lifecycle.go
│   ├── lifecycle_legacy.go
│   ├── neighbor.go
│   ├── network.go
│   ├── outbound/
│   │   ├── adapter.go
│   │   ├── manager.go
│   │   └── registry.go
│   ├── outbound.go
│   ├── platform.go
│   ├── prestart.go
│   ├── router.go
│   ├── rule.go
│   ├── service/
│   │   ├── adapter.go
│   │   ├── manager.go
│   │   └── registry.go
│   ├── service.go
│   ├── ssm.go
│   ├── time.go
│   ├── upstream.go
│   ├── upstream_legacy.go
│   └── v2ray.go
├── box.go
├── cmd/
│   ├── internal/
│   │   ├── app_store_connect/
│   │   │   └── main.go
│   │   ├── build/
│   │   │   └── main.go
│   │   ├── build_libbox/
│   │   │   └── main.go
│   │   ├── build_shared/
│   │   │   ├── sdk.go
│   │   │   └── tag.go
│   │   ├── format_docs/
│   │   │   └── main.go
│   │   ├── protogen/
│   │   │   └── main.go
│   │   ├── read_tag/
│   │   │   └── main.go
│   │   ├── tun_bench/
│   │   │   └── main.go
│   │   ├── update_android_version/
│   │   │   └── main.go
│   │   ├── update_apple_version/
│   │   │   └── main.go
│   │   └── update_certificates/
│   │       └── main.go
│   └── sing-box/
│       ├── cmd.go
│       ├── cmd_check.go
│       ├── cmd_format.go
│       ├── cmd_generate.go
│       ├── cmd_generate_ech.go
│       ├── cmd_generate_tls.go
│       ├── cmd_generate_vapid.go
│       ├── cmd_generate_wireguard.go
│       ├── cmd_geoip.go
│       ├── cmd_geoip_export.go
│       ├── cmd_geoip_list.go
│       ├── cmd_geoip_lookup.go
│       ├── cmd_geosite.go
│       ├── cmd_geosite_export.go
│       ├── cmd_geosite_list.go
│       ├── cmd_geosite_lookup.go
│       ├── cmd_geosite_matcher.go
│       ├── cmd_merge.go
│       ├── cmd_rule_set.go
│       ├── cmd_rule_set_compile.go
│       ├── cmd_rule_set_convert.go
│       ├── cmd_rule_set_decompile.go
│       ├── cmd_rule_set_format.go
│       ├── cmd_rule_set_match.go
│       ├── cmd_rule_set_merge.go
│       ├── cmd_rule_set_upgrade.go
│       ├── cmd_run.go
│       ├── cmd_tools.go
│       ├── cmd_tools_connect.go
│       ├── cmd_tools_fetch.go
│       ├── cmd_tools_fetch_http3.go
│       ├── cmd_tools_fetch_http3_stub.go
│       ├── cmd_tools_synctime.go
│       ├── cmd_version.go
│       ├── generate_completions.go
│       └── main.go
├── common/
│   ├── badtls/
│   │   ├── raw_conn.go
│   │   ├── raw_half_conn.go
│   │   ├── read_wait.go
│   │   ├── read_wait_stub.go
│   │   ├── registry.go
│   │   └── registry_utls.go
│   ├── badversion/
│   │   ├── version.go
│   │   ├── version_json.go
│   │   └── version_test.go
│   ├── certificate/
│   │   ├── chrome.go
│   │   ├── mozilla.go
│   │   └── store.go
│   ├── compatible/
│   │   └── map.go
│   ├── convertor/
│   │   └── adguard/
│   │       ├── convertor.go
│   │       └── convertor_test.go
│   ├── dialer/
│   │   ├── default.go
│   │   ├── default_parallel_interface.go
│   │   ├── default_parallel_network.go
│   │   ├── detour.go
│   │   ├── dialer.go
│   │   ├── resolve.go
│   │   ├── router.go
│   │   ├── tfo.go
│   │   └── wireguard.go
│   ├── geoip/
│   │   └── reader.go
│   ├── geosite/
│   │   ├── compat_test.go
│   │   ├── geosite_test.go
│   │   ├── reader.go
│   │   ├── rule.go
│   │   └── writer.go
│   ├── interrupt/
│   │   ├── conn.go
│   │   ├── context.go
│   │   └── group.go
│   ├── ja3/
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── error.go
│   │   ├── ja3.go
│   │   └── parser.go
│   ├── ktls/
│   │   ├── ktls.go
│   │   ├── ktls_alert.go
│   │   ├── ktls_cipher_suites_linux.go
│   │   ├── ktls_close.go
│   │   ├── ktls_const.go
│   │   ├── ktls_handshake_messages.go
│   │   ├── ktls_key_update.go
│   │   ├── ktls_linux.go
│   │   ├── ktls_prf.go
│   │   ├── ktls_read.go
│   │   ├── ktls_read_wait.go
│   │   ├── ktls_stub_nolinkname.go
│   │   ├── ktls_stub_nonlinux.go
│   │   ├── ktls_stub_oldgo.go
│   │   └── ktls_write.go
│   ├── listener/
│   │   ├── listener.go
│   │   ├── listener_tcp.go
│   │   └── listener_udp.go
│   ├── mux/
│   │   ├── client.go
│   │   └── router.go
│   ├── pipelistener/
│   │   └── listener.go
│   ├── process/
│   │   ├── searcher.go
│   │   ├── searcher_android.go
│   │   ├── searcher_darwin.go
│   │   ├── searcher_linux.go
│   │   ├── searcher_linux_shared.go
│   │   ├── searcher_stub.go
│   │   └── searcher_windows.go
│   ├── redir/
│   │   ├── redir_darwin.go
│   │   ├── redir_linux.go
│   │   ├── redir_other.go
│   │   ├── tproxy_linux.go
│   │   └── tproxy_other.go
│   ├── settings/
│   │   ├── proxy_android.go
│   │   ├── proxy_darwin.go
│   │   ├── proxy_linux.go
│   │   ├── proxy_stub.go
│   │   ├── proxy_windows.go
│   │   ├── system_proxy.go
│   │   ├── wifi.go
│   │   ├── wifi_linux.go
│   │   ├── wifi_linux_connman.go
│   │   ├── wifi_linux_iwd.go
│   │   ├── wifi_linux_nm.go
│   │   ├── wifi_linux_wpa.go
│   │   ├── wifi_stub.go
│   │   └── wifi_windows.go
│   ├── sniff/
│   │   ├── bittorrent.go
│   │   ├── bittorrent_test.go
│   │   ├── dns.go
│   │   ├── dns_test.go
│   │   ├── dtls.go
│   │   ├── dtls_test.go
│   │   ├── http.go
│   │   ├── http_test.go
│   │   ├── internal/
│   │   │   └── qtls/
│   │   │       └── qtls.go
│   │   ├── ntp.go
│   │   ├── ntp_test.go
│   │   ├── quic.go
│   │   ├── quic_blacklist.go
│   │   ├── quic_capture_test.go
│   │   ├── quic_test.go
│   │   ├── rdp.go
│   │   ├── rdp_test.go
│   │   ├── sniff.go
│   │   ├── ssh.go
│   │   ├── ssh_test.go
│   │   ├── stun.go
│   │   ├── stun_test.go
│   │   └── tls.go
│   ├── srs/
│   │   ├── binary.go
│   │   ├── compat_test.go
│   │   ├── ip_cidr.go
│   │   └── ip_set.go
│   ├── taskmonitor/
│   │   └── monitor.go
│   ├── tls/
│   │   ├── acme.go
│   │   ├── acme_contstant.go
│   │   ├── acme_stub.go
│   │   ├── client.go
│   │   ├── common.go
│   │   ├── config.go
│   │   ├── ech.go
│   │   ├── ech_shared.go
│   │   ├── ech_tag_stub.go
│   │   ├── ktls.go
│   │   ├── mkcert.go
│   │   ├── reality_client.go
│   │   ├── reality_server.go
│   │   ├── reality_stub.go
│   │   ├── server.go
│   │   ├── std_client.go
│   │   ├── std_server.go
│   │   ├── time_wrapper.go
│   │   ├── utls_client.go
│   │   └── utls_stub.go
│   ├── tlsfragment/
│   │   ├── conn.go
│   │   ├── conn_test.go
│   │   ├── index.go
│   │   ├── index_test.go
│   │   ├── wait_darwin.go
│   │   ├── wait_linux.go
│   │   ├── wait_stub.go
│   │   └── wait_windows.go
│   ├── uot/
│   │   └── router.go
│   └── urltest/
│       └── urltest.go
├── constant/
│   ├── certificate.go
│   ├── cgo.go
│   ├── cgo_disabled.go
│   ├── dhcp.go
│   ├── dns.go
│   ├── err.go
│   ├── goos/
│   │   ├── gengoos.go
│   │   ├── goos.go
│   │   ├── zgoos_aix.go
│   │   ├── zgoos_android.go
│   │   ├── zgoos_darwin.go
│   │   ├── zgoos_dragonfly.go
│   │   ├── zgoos_freebsd.go
│   │   ├── zgoos_hurd.go
│   │   ├── zgoos_illumos.go
│   │   ├── zgoos_ios.go
│   │   ├── zgoos_js.go
│   │   ├── zgoos_linux.go
│   │   ├── zgoos_netbsd.go
│   │   ├── zgoos_openbsd.go
│   │   ├── zgoos_plan9.go
│   │   ├── zgoos_solaris.go
│   │   ├── zgoos_windows.go
│   │   └── zgoos_zos.go
│   ├── hysteria2.go
│   ├── network.go
│   ├── os.go
│   ├── path.go
│   ├── path_unix.go
│   ├── protocol.go
│   ├── proxy.go
│   ├── quic.go
│   ├── quic_stub.go
│   ├── rule.go
│   ├── speed.go
│   ├── time.go
│   ├── timeout.go
│   ├── v2ray.go
│   └── version.go
├── daemon/
│   ├── deprecated.go
│   ├── instance.go
│   ├── platform.go
│   ├── started_service.go
│   ├── started_service.pb.go
│   ├── started_service.proto
│   └── started_service_grpc.pb.go
├── debug.go
├── debug_http.go
├── debug_stub.go
├── debug_unix.go
├── dns/
│   ├── client.go
│   ├── client_log.go
│   ├── client_truncate.go
│   ├── extension_edns0_subnet.go
│   ├── rcode.go
│   ├── router.go
│   ├── transport/
│   │   ├── base.go
│   │   ├── connector.go
│   │   ├── connector_test.go
│   │   ├── dhcp/
│   │   │   ├── dhcp.go
│   │   │   └── dhcp_shared.go
│   │   ├── fakeip/
│   │   │   ├── fakeip.go
│   │   │   ├── memory.go
│   │   │   └── store.go
│   │   ├── hosts/
│   │   │   ├── hosts.go
│   │   │   ├── hosts_file.go
│   │   │   ├── hosts_test.go
│   │   │   ├── hosts_unix.go
│   │   │   ├── hosts_windows.go
│   │   │   └── testdata/
│   │   │       └── hosts
│   │   ├── https.go
│   │   ├── https_transport.go
│   │   ├── local/
│   │   │   ├── local.go
│   │   │   ├── local_darwin.go
│   │   │   ├── local_darwin_dhcp.go
│   │   │   ├── local_darwin_nodhcp.go
│   │   │   ├── local_resolved.go
│   │   │   ├── local_resolved_linux.go
│   │   │   ├── local_resolved_stub.go
│   │   │   ├── local_shared.go
│   │   │   ├── resolv.go
│   │   │   ├── resolv_default.go
│   │   │   ├── resolv_test.go
│   │   │   ├── resolv_unix.go
│   │   │   └── resolv_windows.go
│   │   ├── quic/
│   │   │   ├── http3.go
│   │   │   └── quic.go
│   │   ├── tcp.go
│   │   ├── tls.go
│   │   └── udp.go
│   ├── transport_adapter.go
│   ├── transport_dialer.go
│   ├── transport_manager.go
│   └── transport_registry.go
├── docs/
│   ├── CNAME
│   ├── changelog.md
│   ├── clients/
│   │   ├── android/
│   │   │   ├── features.md
│   │   │   └── index.md
│   │   ├── apple/
│   │   │   ├── features.md
│   │   │   └── index.md
│   │   ├── general.md
│   │   ├── index.md
│   │   ├── index.zh.md
│   │   └── privacy.md
│   ├── configuration/
│   │   ├── certificate/
│   │   │   ├── index.md
│   │   │   └── index.zh.md
│   │   ├── dns/
│   │   │   ├── fakeip.md
│   │   │   ├── fakeip.zh.md
│   │   │   ├── index.md
│   │   │   ├── index.zh.md
│   │   │   ├── rule.md
│   │   │   ├── rule.zh.md
│   │   │   ├── rule_action.md
│   │   │   ├── rule_action.zh.md
│   │   │   └── server/
│   │   │       ├── dhcp.md
│   │   │       ├── dhcp.zh.md
│   │   │       ├── fakeip.md
│   │   │       ├── fakeip.zh.md
│   │   │       ├── hosts.md
│   │   │       ├── hosts.zh.md
│   │   │       ├── http3.md
│   │   │       ├── http3.zh.md
│   │   │       ├── https.md
│   │   │       ├── https.zh.md
│   │   │       ├── index.md
│   │   │       ├── index.zh.md
│   │   │       ├── legacy.md
│   │   │       ├── legacy.zh.md
│   │   │       ├── local.md
│   │   │       ├── local.zh.md
│   │   │       ├── quic.md
│   │   │       ├── quic.zh.md
│   │   │       ├── resolved.md
│   │   │       ├── resolved.zh.md
│   │   │       ├── tailscale.md
│   │   │       ├── tailscale.zh.md
│   │   │       ├── tcp.md
│   │   │       ├── tcp.zh.md
│   │   │       ├── tls.md
│   │   │       ├── tls.zh.md
│   │   │       ├── udp.md
│   │   │       └── udp.zh.md
│   │   ├── endpoint/
│   │   │   ├── index.md
│   │   │   ├── index.zh.md
│   │   │   ├── tailscale.md
│   │   │   ├── tailscale.zh.md
│   │   │   ├── wireguard.md
│   │   │   └── wireguard.zh.md
│   │   ├── experimental/
│   │   │   ├── cache-file.md
│   │   │   ├── cache-file.zh.md
│   │   │   ├── clash-api.md
│   │   │   ├── clash-api.zh.md
│   │   │   ├── index.md
│   │   │   ├── index.zh.md
│   │   │   ├── v2ray-api.md
│   │   │   └── v2ray-api.zh.md
│   │   ├── inbound/
│   │   │   ├── anytls.md
│   │   │   ├── anytls.zh.md
│   │   │   ├── direct.md
│   │   │   ├── direct.zh.md
│   │   │   ├── http.md
│   │   │   ├── http.zh.md
│   │   │   ├── hysteria.md
│   │   │   ├── hysteria.zh.md
│   │   │   ├── hysteria2.md
│   │   │   ├── hysteria2.zh.md
│   │   │   ├── index.md
│   │   │   ├── index.zh.md
│   │   │   ├── mixed.md
│   │   │   ├── mixed.zh.md
│   │   │   ├── naive.md
│   │   │   ├── naive.zh.md
│   │   │   ├── redirect.md
│   │   │   ├── redirect.zh.md
│   │   │   ├── shadowsocks.md
│   │   │   ├── shadowsocks.zh.md
│   │   │   ├── shadowtls.md
│   │   │   ├── shadowtls.zh.md
│   │   │   ├── socks.md
│   │   │   ├── socks.zh.md
│   │   │   ├── tproxy.md
│   │   │   ├── tproxy.zh.md
│   │   │   ├── trojan.md
│   │   │   ├── trojan.zh.md
│   │   │   ├── tuic.md
│   │   │   ├── tuic.zh.md
│   │   │   ├── tun.md
│   │   │   ├── tun.zh.md
│   │   │   ├── vless.md
│   │   │   ├── vless.zh.md
│   │   │   ├── vmess.md
│   │   │   └── vmess.zh.md
│   │   ├── index.md
│   │   ├── index.zh.md
│   │   ├── log/
│   │   │   ├── index.md
│   │   │   └── index.zh.md
│   │   ├── ntp/
│   │   │   ├── index.md
│   │   │   └── index.zh.md
│   │   ├── outbound/
│   │   │   ├── anytls.md
│   │   │   ├── anytls.zh.md
│   │   │   ├── block.md
│   │   │   ├── block.zh.md
│   │   │   ├── direct.md
│   │   │   ├── direct.zh.md
│   │   │   ├── dns.md
│   │   │   ├── dns.zh.md
│   │   │   ├── http.md
│   │   │   ├── http.zh.md
│   │   │   ├── hysteria.md
│   │   │   ├── hysteria.zh.md
│   │   │   ├── hysteria2.md
│   │   │   ├── hysteria2.zh.md
│   │   │   ├── index.md
│   │   │   ├── index.zh.md
│   │   │   ├── naive.md
│   │   │   ├── naive.zh.md
│   │   │   ├── selector.md
│   │   │   ├── selector.zh.md
│   │   │   ├── shadowsocks.md
│   │   │   ├── shadowsocks.zh.md
│   │   │   ├── shadowtls.md
│   │   │   ├── shadowtls.zh.md
│   │   │   ├── socks.md
│   │   │   ├── socks.zh.md
│   │   │   ├── ssh.md
│   │   │   ├── ssh.zh.md
│   │   │   ├── tor.md
│   │   │   ├── tor.zh.md
│   │   │   ├── trojan.md
│   │   │   ├── trojan.zh.md
│   │   │   ├── tuic.md
│   │   │   ├── tuic.zh.md
│   │   │   ├── urltest.md
│   │   │   ├── urltest.zh.md
│   │   │   ├── vless.md
│   │   │   ├── vless.zh.md
│   │   │   ├── vmess.md
│   │   │   ├── vmess.zh.md
│   │   │   ├── wireguard.md
│   │   │   └── wireguard.zh.md
│   │   ├── route/
│   │   │   ├── geoip.md
│   │   │   ├── geoip.zh.md
│   │   │   ├── geosite.md
│   │   │   ├── geosite.zh.md
│   │   │   ├── index.md
│   │   │   ├── index.zh.md
│   │   │   ├── rule.md
│   │   │   ├── rule.zh.md
│   │   │   ├── rule_action.md
│   │   │   ├── rule_action.zh.md
│   │   │   ├── sniff.md
│   │   │   └── sniff.zh.md
│   │   ├── rule-set/
│   │   │   ├── adguard.md
│   │   │   ├── adguard.zh.md
│   │   │   ├── headless-rule.md
│   │   │   ├── headless-rule.zh.md
│   │   │   ├── index.md
│   │   │   ├── index.zh.md
│   │   │   ├── source-format.md
│   │   │   └── source-format.zh.md
│   │   ├── service/
│   │   │   ├── ccm.md
│   │   │   ├── ccm.zh.md
│   │   │   ├── derp.md
│   │   │   ├── derp.zh.md
│   │   │   ├── index.md
│   │   │   ├── index.zh.md
│   │   │   ├── ocm.md
│   │   │   ├── ocm.zh.md
│   │   │   ├── resolved.md
│   │   │   ├── resolved.zh.md
│   │   │   ├── ssm-api.md
│   │   │   └── ssm-api.zh.md
│   │   └── shared/
│   │       ├── dial.md
│   │       ├── dial.zh.md
│   │       ├── dns01_challenge.md
│   │       ├── dns01_challenge.zh.md
│   │       ├── listen.md
│   │       ├── listen.zh.md
│   │       ├── multiplex.md
│   │       ├── multiplex.zh.md
│   │       ├── neighbor.md
│   │       ├── neighbor.zh.md
│   │       ├── pre-match.md
│   │       ├── pre-match.zh.md
│   │       ├── tcp-brutal.md
│   │       ├── tcp-brutal.zh.md
│   │       ├── tls.md
│   │       ├── tls.zh.md
│   │       ├── udp-over-tcp.md
│   │       ├── udp-over-tcp.zh.md
│   │       ├── v2ray-transport.md
│   │       ├── v2ray-transport.zh.md
│   │       ├── wifi-state.md
│   │       └── wifi-state.zh.md
│   ├── deprecated.md
│   ├── deprecated.zh.md
│   ├── index.md
│   ├── index.zh.md
│   ├── installation/
│   │   ├── build-from-source.md
│   │   ├── build-from-source.zh.md
│   │   ├── docker.md
│   │   ├── docker.zh.md
│   │   ├── package-manager.md
│   │   ├── package-manager.zh.md
│   │   └── tools/
│   │       ├── arch-install.sh
│   │       ├── deb-install.sh
│   │       ├── install.sh
│   │       ├── rpm-install.sh
│   │       └── sing-box.repo
│   ├── manual/
│   │   ├── misc/
│   │   │   └── tunnelvision.md
│   │   ├── proxy/
│   │   │   ├── client.md
│   │   │   └── server.md
│   │   └── proxy-protocol/
│   │       ├── hysteria2.md
│   │       ├── shadowsocks.md
│   │       └── trojan.md
│   ├── migration.md
│   ├── migration.zh.md
│   ├── sponsors.md
│   ├── support.md
│   └── support.zh.md
├── experimental/
│   ├── cachefile/
│   │   ├── cache.go
│   │   ├── fakeip.go
│   │   └── rdrc.go
│   ├── clashapi/
│   │   ├── api_meta.go
│   │   ├── api_meta_group.go
│   │   ├── api_meta_upgrade.go
│   │   ├── cache.go
│   │   ├── common.go
│   │   ├── configs.go
│   │   ├── connections.go
│   │   ├── ctxkeys.go
│   │   ├── dns.go
│   │   ├── errors.go
│   │   ├── profile.go
│   │   ├── provider.go
│   │   ├── proxies.go
│   │   ├── ruleprovider.go
│   │   ├── rules.go
│   │   ├── script.go
│   │   ├── server.go
│   │   ├── server_fs.go
│   │   ├── server_resources.go
│   │   └── trafficontrol/
│   │       ├── manager.go
│   │       └── tracker.go
│   ├── clashapi.go
│   ├── deprecated/
│   │   ├── constants.go
│   │   ├── manager.go
│   │   └── stderr.go
│   ├── libbox/
│   │   ├── build_info.go
│   │   ├── command.go
│   │   ├── command_client.go
│   │   ├── command_server.go
│   │   ├── command_types.go
│   │   ├── config.go
│   │   ├── deprecated.go
│   │   ├── dns.go
│   │   ├── fdroid.go
│   │   ├── fdroid_mirrors.go
│   │   ├── ffi.json
│   │   ├── http.go
│   │   ├── internal/
│   │   │   └── procfs/
│   │   │       └── procfs.go
│   │   ├── iterator.go
│   │   ├── link_flags_stub.go
│   │   ├── link_flags_unix.go
│   │   ├── log.go
│   │   ├── memory.go
│   │   ├── monitor.go
│   │   ├── neighbor.go
│   │   ├── neighbor_darwin.go
│   │   ├── neighbor_linux.go
│   │   ├── neighbor_stub.go
│   │   ├── panic.go
│   │   ├── pidfd_android.go
│   │   ├── platform.go
│   │   ├── pprof.go
│   │   ├── profile_import.go
│   │   ├── remote_profile.go
│   │   ├── semver.go
│   │   ├── semver_test.go
│   │   ├── service.go
│   │   ├── service_other.go
│   │   ├── service_windows.go
│   │   ├── setup.go
│   │   ├── tun.go
│   │   ├── tun_darwin.go
│   │   ├── tun_name_darwin.go
│   │   ├── tun_name_linux.go
│   │   └── tun_name_other.go
│   ├── locale/
│   │   ├── locale.go
│   │   └── locale_zh_CN.go
│   ├── v2rayapi/
│   │   ├── server.go
│   │   ├── stats.go
│   │   ├── stats.pb.go
│   │   ├── stats.proto
│   │   └── stats_grpc.pb.go
│   └── v2rayapi.go
├── go.mod
├── go.sum
├── include/
│   ├── ccm.go
│   ├── ccm_stub.go
│   ├── ccm_stub_darwin.go
│   ├── clashapi.go
│   ├── clashapi_stub.go
│   ├── dhcp.go
│   ├── dhcp_stub.go
│   ├── naive_outbound.go
│   ├── naive_outbound_stub.go
│   ├── ocm.go
│   ├── ocm_stub.go
│   ├── oom_killer.go
│   ├── quic.go
│   ├── quic_stub.go
│   ├── registry.go
│   ├── tailscale.go
│   ├── tailscale_stub.go
│   ├── tz_android.go
│   ├── tz_ios.go
│   ├── v2rayapi.go
│   ├── v2rayapi_stub.go
│   ├── wireguard.go
│   └── wireguard_stub.go
├── log/
│   ├── export.go
│   ├── factory.go
│   ├── format.go
│   ├── id.go
│   ├── level.go
│   ├── log.go
│   ├── nop.go
│   ├── observable.go
│   ├── override.go
│   └── platform.go
├── mkdocs.yml
├── option/
│   ├── anytls.go
│   ├── ccm.go
│   ├── certificate.go
│   ├── debug.go
│   ├── direct.go
│   ├── dns.go
│   ├── dns_record.go
│   ├── endpoint.go
│   ├── experimental.go
│   ├── group.go
│   ├── hysteria.go
│   ├── hysteria2.go
│   ├── inbound.go
│   ├── multiplex.go
│   ├── naive.go
│   ├── ntp.go
│   ├── ocm.go
│   ├── oom_killer.go
│   ├── options.go
│   ├── outbound.go
│   ├── platform.go
│   ├── redir.go
│   ├── resolved.go
│   ├── route.go
│   ├── rule.go
│   ├── rule_action.go
│   ├── rule_dns.go
│   ├── rule_set.go
│   ├── service.go
│   ├── shadowsocks.go
│   ├── shadowsocksr.go
│   ├── shadowtls.go
│   ├── simple.go
│   ├── ssh.go
│   ├── ssmapi.go
│   ├── tailscale.go
│   ├── tls.go
│   ├── tls_acme.go
│   ├── tor.go
│   ├── trojan.go
│   ├── tuic.go
│   ├── tun.go
│   ├── tun_platform.go
│   ├── types.go
│   ├── udp_over_tcp.go
│   ├── v2ray.go
│   ├── v2ray_transport.go
│   ├── vless.go
│   ├── vmess.go
│   └── wireguard.go
├── protocol/
│   ├── anytls/
│   │   ├── inbound.go
│   │   └── outbound.go
│   ├── block/
│   │   └── outbound.go
│   ├── direct/
│   │   ├── inbound.go
│   │   ├── loopback_detect.go
│   │   └── outbound.go
│   ├── dns/
│   │   ├── handle.go
│   │   └── outbound.go
│   ├── group/
│   │   ├── selector.go
│   │   └── urltest.go
│   ├── http/
│   │   ├── inbound.go
│   │   └── outbound.go
│   ├── hysteria/
│   │   ├── inbound.go
│   │   └── outbound.go
│   ├── hysteria2/
│   │   ├── inbound.go
│   │   └── outbound.go
│   ├── mixed/
│   │   └── inbound.go
│   ├── naive/
│   │   ├── inbound.go
│   │   ├── inbound_conn.go
│   │   ├── outbound.go
│   │   └── quic/
│   │       └── inbound_init.go
│   ├── redirect/
│   │   ├── redirect.go
│   │   └── tproxy.go
│   ├── shadowsocks/
│   │   ├── inbound.go
│   │   ├── inbound_multi.go
│   │   ├── inbound_relay.go
│   │   └── outbound.go
│   ├── shadowtls/
│   │   ├── inbound.go
│   │   └── outbound.go
│   ├── socks/
│   │   ├── inbound.go
│   │   └── outbound.go
│   ├── ssh/
│   │   └── outbound.go
│   ├── tailscale/
│   │   ├── dns_transport.go
│   │   ├── endpoint.go
│   │   ├── tun_device_unix.go
│   │   └── tun_device_windows.go
│   ├── tor/
│   │   ├── outbound.go
│   │   └── proxy.go
│   ├── trojan/
│   │   ├── inbound.go
│   │   └── outbound.go
│   ├── tuic/
│   │   ├── inbound.go
│   │   └── outbound.go
│   ├── tun/
│   │   ├── hook.go
│   │   └── inbound.go
│   ├── vless/
│   │   ├── inbound.go
│   │   └── outbound.go
│   ├── vmess/
│   │   ├── inbound.go
│   │   └── outbound.go
│   └── wireguard/
│       └── endpoint.go
├── release/
│   ├── DEFAULT_BUILD_TAGS
│   ├── DEFAULT_BUILD_TAGS_OTHERS
│   ├── DEFAULT_BUILD_TAGS_WINDOWS
│   ├── LDFLAGS
│   ├── completions/
│   │   ├── sing-box.bash
│   │   ├── sing-box.fish
│   │   └── sing-box.zsh
│   ├── config/
│   │   ├── config.json
│   │   ├── openwrt.conf
│   │   ├── openwrt.init
│   │   ├── openwrt.keep
│   │   ├── openwrt.prerm
│   │   ├── sing-box-split-dns.xml
│   │   ├── sing-box.confd
│   │   ├── sing-box.initd
│   │   ├── sing-box.postinst
│   │   ├── sing-box.rules
│   │   ├── sing-box.service
│   │   ├── sing-box.sysusers
│   │   └── sing-box@.service
│   └── local/
│       ├── common.sh
│       ├── debug.sh
│       ├── enable.sh
│       ├── install.sh
│       ├── install_go.sh
│       ├── reinstall.sh
│       ├── sing-box.service
│       ├── uninstall.sh
│       └── update.sh
├── route/
│   ├── conn.go
│   ├── dns.go
│   ├── neighbor_resolver_darwin.go
│   ├── neighbor_resolver_lease.go
│   ├── neighbor_resolver_linux.go
│   ├── neighbor_resolver_parse.go
│   ├── neighbor_resolver_platform.go
│   ├── neighbor_resolver_stub.go
│   ├── neighbor_table_darwin.go
│   ├── neighbor_table_linux.go
│   ├── network.go
│   ├── platform_searcher.go
│   ├── route.go
│   ├── router.go
│   ├── rule/
│   │   ├── rule_abstract.go
│   │   ├── rule_abstract_test.go
│   │   ├── rule_action.go
│   │   ├── rule_default.go
│   │   ├── rule_default_interface_address.go
│   │   ├── rule_dns.go
│   │   ├── rule_headless.go
│   │   ├── rule_interface_address.go
│   │   ├── rule_item_adguard.go
│   │   ├── rule_item_auth_user.go
│   │   ├── rule_item_cidr.go
│   │   ├── rule_item_clash_mode.go
│   │   ├── rule_item_client.go
│   │   ├── rule_item_domain.go
│   │   ├── rule_item_domain_keyword.go
│   │   ├── rule_item_domain_regex.go
│   │   ├── rule_item_inbound.go
│   │   ├── rule_item_ip_accept_any.go
│   │   ├── rule_item_ip_is_private.go
│   │   ├── rule_item_ipversion.go
│   │   ├── rule_item_network.go
│   │   ├── rule_item_network_is_constrained.go
│   │   ├── rule_item_network_is_expensive.go
│   │   ├── rule_item_network_type.go
│   │   ├── rule_item_outbound.go
│   │   ├── rule_item_package_name.go
│   │   ├── rule_item_port.go
│   │   ├── rule_item_port_range.go
│   │   ├── rule_item_preferred_by.go
│   │   ├── rule_item_process_name.go
│   │   ├── rule_item_process_path.go
│   │   ├── rule_item_process_path_regex.go
│   │   ├── rule_item_protocol.go
│   │   ├── rule_item_query_type.go
│   │   ├── rule_item_rule_set.go
│   │   ├── rule_item_source_hostname.go
│   │   ├── rule_item_source_mac_address.go
│   │   ├── rule_item_user.go
│   │   ├── rule_item_user_id.go
│   │   ├── rule_item_wifi_bssid.go
│   │   ├── rule_item_wifi_ssid.go
│   │   ├── rule_network_interface_address.go
│   │   ├── rule_set.go
│   │   ├── rule_set_local.go
│   │   └── rule_set_remote.go
│   └── rule_conds.go
├── service/
│   ├── ccm/
│   │   ├── credential.go
│   │   ├── credential_darwin.go
│   │   ├── credential_other.go
│   │   ├── service.go
│   │   ├── service_usage.go
│   │   └── service_user.go
│   ├── derp/
│   │   └── service.go
│   ├── ocm/
│   │   ├── credential.go
│   │   ├── credential_darwin.go
│   │   ├── credential_other.go
│   │   ├── service.go
│   │   ├── service_usage.go
│   │   ├── service_user.go
│   │   └── service_websocket.go
│   ├── oomkiller/
│   │   ├── config.go
│   │   ├── service.go
│   │   ├── service_stub.go
│   │   └── service_timer.go
│   ├── resolved/
│   │   ├── resolve1.go
│   │   ├── service.go
│   │   ├── stub.go
│   │   └── transport.go
│   └── ssmapi/
│       ├── api.go
│       ├── cache.go
│       ├── server.go
│       ├── traffic.go
│       └── user.go
├── test/
│   ├── box_test.go
│   ├── brutal_test.go
│   ├── clash_darwin_test.go
│   ├── clash_other_test.go
│   ├── clash_test.go
│   ├── config/
│   │   ├── hysteria-client.json
│   │   ├── hysteria-server.json
│   │   ├── hysteria2-client.yml
│   │   ├── hysteria2-server.yml
│   │   ├── naive-nginx.conf
│   │   ├── naive-quic.json
│   │   ├── naive.json
│   │   ├── nginx.conf
│   │   ├── shadowsocksr.json
│   │   ├── trojan.json
│   │   ├── tuic-client.json
│   │   ├── tuic-server.json
│   │   ├── vless-server.json
│   │   ├── vless-tls-client.json
│   │   ├── vless-tls-server.json
│   │   ├── vmess-client.json
│   │   ├── vmess-grpc-client.json
│   │   ├── vmess-grpc-server.json
│   │   ├── vmess-mux-client.json
│   │   ├── vmess-server.json
│   │   ├── vmess-ws-client.json
│   │   ├── vmess-ws-server.json
│   │   └── wireguard.conf
│   ├── direct_test.go
│   ├── docker_test.go
│   ├── domain_inbound_test.go
│   ├── ech_test.go
│   ├── go.mod
│   ├── go.sum
│   ├── http_test.go
│   ├── hysteria2_test.go
│   ├── hysteria_test.go
│   ├── inbound_detour_test.go
│   ├── ktls_test.go
│   ├── mkcert.go
│   ├── mux_cool_test.go
│   ├── mux_test.go
│   ├── naive_self_test.go
│   ├── naive_test.go
│   ├── reality_test.go
│   ├── shadowsocks_legacy_test.go
│   ├── shadowsocks_test.go
│   ├── shadowtls_test.go
│   ├── socks_test.go
│   ├── ss_plugin_test.go
│   ├── tfo_test.go
│   ├── tls_test.go
│   ├── trojan_test.go
│   ├── tuic_test.go
│   ├── v2ray_api_test.go
│   ├── v2ray_grpc_test.go
│   ├── v2ray_httpupgrade_test.go
│   ├── v2ray_transport_test.go
│   ├── v2ray_ws_test.go
│   ├── vmess_test.go
│   └── wrapper_test.go
└── transport/
    ├── simple-obfs/
    │   ├── README.md
    │   ├── http.go
    │   └── tls.go
    ├── sip003/
    │   ├── args.go
    │   ├── obfs.go
    │   ├── plugin.go
    │   └── v2ray.go
    ├── trojan/
    │   ├── mux.go
    │   ├── protocol.go
    │   ├── protocol_wait.go
    │   ├── service.go
    │   └── service_wait.go
    ├── v2ray/
    │   ├── grpc.go
    │   ├── grpc_lite.go
    │   ├── quic.go
    │   └── transport.go
    ├── v2raygrpc/
    │   ├── client.go
    │   ├── conn.go
    │   ├── credentials/
    │   │   ├── credentials.go
    │   │   ├── spiffe.go
    │   │   ├── syscallconn.go
    │   │   └── util.go
    │   ├── custom_name.go
    │   ├── server.go
    │   ├── stream.pb.go
    │   ├── stream.proto
    │   ├── stream_grpc.pb.go
    │   └── tls_credentials.go
    ├── v2raygrpclite/
    │   ├── client.go
    │   ├── conn.go
    │   └── server.go
    ├── v2rayhttp/
    │   ├── client.go
    │   ├── conn.go
    │   ├── force_close.go
    │   ├── pool.go
    │   └── server.go
    ├── v2rayhttpupgrade/
    │   ├── client.go
    │   └── server.go
    ├── v2rayquic/
    │   ├── client.go
    │   ├── init.go
    │   ├── server.go
    │   └── stream.go
    ├── v2raywebsocket/
    │   ├── client.go
    │   ├── conn.go
    │   ├── server.go
    │   └── writer.go
    └── wireguard/
        ├── client_bind.go
        ├── device.go
        ├── device_nat.go
        ├── device_stack.go
        ├── device_stack_gonet.go
        ├── device_stack_stub.go
        ├── device_system.go
        ├── device_system_stack.go
        ├── endpoint.go
        └── endpoint_options.go
Download .txt
Showing preview only (507K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (5675 symbols across 689 files)

FILE: adapter/certificate.go
  type CertificateStore (line 10) | type CertificateStore interface
  function RootPoolFromContext (line 15) | func RootPoolFromContext(ctx context.Context) *x509.CertPool {

FILE: adapter/connections.go
  type ConnectionManager (line 10) | type ConnectionManager interface

FILE: adapter/dns.go
  type DNSRouter (line 17) | type DNSRouter interface
  type DNSClient (line 26) | type DNSClient interface
  type DNSQueryOptions (line 33) | type DNSQueryOptions struct
  function DNSQueryOptionsFrom (line 42) | func DNSQueryOptionsFrom(ctx context.Context, options *option.DomainReso...
  type RDRCStore (line 60) | type RDRCStore interface
  type DNSTransport (line 66) | type DNSTransport interface
  type LegacyDNSTransport (line 75) | type LegacyDNSTransport interface
  type DNSTransportRegistry (line 80) | type DNSTransportRegistry interface
  type DNSTransportManager (line 85) | type DNSTransportManager interface

FILE: adapter/endpoint.go
  type Endpoint (line 10) | type Endpoint interface
  type EndpointRegistry (line 17) | type EndpointRegistry interface
  type EndpointManager (line 22) | type EndpointManager interface

FILE: adapter/endpoint/adapter.go
  type Adapter (line 5) | type Adapter struct
    method Type (line 29) | func (a *Adapter) Type() string {
    method Tag (line 33) | func (a *Adapter) Tag() string {
    method Network (line 37) | func (a *Adapter) Network() []string {
    method Dependencies (line 41) | func (a *Adapter) Dependencies() []string {
  function NewAdapter (line 12) | func NewAdapter(endpointType string, endpointTag string, network []strin...
  function NewAdapterWithDialerOptions (line 21) | func NewAdapterWithDialerOptions(endpointType string, endpointTag string...

FILE: adapter/endpoint/manager.go
  type Manager (line 20) | type Manager struct
    method Start (line 38) | func (m *Manager) Start(stage adapter.StartStage) error {
    method Close (line 63) | func (m *Manager) Close() error {
    method Endpoints (line 88) | func (m *Manager) Endpoints() []adapter.Endpoint {
    method Get (line 94) | func (m *Manager) Get(tag string) (adapter.Endpoint, bool) {
    method Remove (line 101) | func (m *Manager) Remove(tag string) error {
    method Create (line 124) | func (m *Manager) Create(ctx context.Context, router adapter.Router, l...
  function NewManager (line 30) | func NewManager(logger log.ContextLogger, registry adapter.EndpointRegis...

FILE: adapter/endpoint/registry.go
  type ConstructorFunc (line 13) | type ConstructorFunc
  function Register (line 15) | func Register[Options any](registry *Registry, outboundType string, cons...
  type optionsConstructorFunc (line 30) | type optionsConstructorFunc
  type constructorFunc (line 31) | type constructorFunc
  type Registry (line 34) | type Registry struct
    method CreateOptions (line 47) | func (m *Registry) CreateOptions(outboundType string) (any, bool) {
    method Create (line 57) | func (m *Registry) Create(ctx context.Context, router adapter.Router, ...
    method register (line 67) | func (m *Registry) register(outboundType string, optionsConstructor op...
  function NewRegistry (line 40) | func NewRegistry() *Registry {

FILE: adapter/experimental.go
  type ClashServer (line 14) | type ClashServer interface
  type URLTestHistory (line 23) | type URLTestHistory struct
  type URLTestHistoryStorage (line 28) | type URLTestHistoryStorage interface
  type V2RayServer (line 36) | type V2RayServer interface
  type CacheFile (line 41) | type CacheFile interface
  type SavedBinary (line 60) | type SavedBinary struct
    method MarshalBinary (line 66) | func (s *SavedBinary) MarshalBinary() ([]byte, error) {
    method UnmarshalBinary (line 95) | func (s *SavedBinary) UnmarshalBinary(data []byte) error {
  type OutboundGroup (line 130) | type OutboundGroup interface
  type URLTestGroup (line 136) | type URLTestGroup interface
  function OutboundTag (line 141) | func OutboundTag(detour Outbound) string {

FILE: adapter/fakeip.go
  type FakeIPStore (line 9) | type FakeIPStore interface
  type FakeIPStorage (line 17) | type FakeIPStorage interface
  type FakeIPTransport (line 28) | type FakeIPTransport interface

FILE: adapter/fakeip_metadata.go
  type FakeIPMetadata (line 13) | type FakeIPMetadata struct
    method MarshalBinary (line 20) | func (m *FakeIPMetadata) MarshalBinary() (data []byte, err error) {
    method UnmarshalBinary (line 34) | func (m *FakeIPMetadata) UnmarshalBinary(data []byte) error {

FILE: adapter/handler.go
  type ConnectionHandler (line 14) | type ConnectionHandler interface
  type ConnectionHandlerEx (line 18) | type ConnectionHandlerEx interface
  type PacketHandler (line 23) | type PacketHandler interface
  type PacketHandlerEx (line 27) | type PacketHandlerEx interface
  type OOBPacketHandler (line 32) | type OOBPacketHandler interface
  type OOBPacketHandlerEx (line 36) | type OOBPacketHandlerEx interface
  type PacketConnectionHandler (line 41) | type PacketConnectionHandler interface
  type PacketConnectionHandlerEx (line 45) | type PacketConnectionHandlerEx interface
  type UpstreamHandlerAdapter (line 52) | type UpstreamHandlerAdapter interface
  type UpstreamHandlerAdapterEx (line 58) | type UpstreamHandlerAdapterEx interface

FILE: adapter/inbound.go
  type Inbound (line 15) | type Inbound interface
  type TCPInjectableInbound (line 21) | type TCPInjectableInbound interface
  type UDPInjectableInbound (line 26) | type UDPInjectableInbound interface
  type InboundRegistry (line 31) | type InboundRegistry interface
  type InboundManager (line 36) | type InboundManager interface
  type InboundContext (line 44) | type InboundContext struct
    method ResetRuleCache (line 104) | func (c *InboundContext) ResetRuleCache() {
  type inboundContextKey (line 114) | type inboundContextKey struct
  function WithContext (line 116) | func WithContext(ctx context.Context, inboundContext *InboundContext) co...
  function ContextFrom (line 120) | func ContextFrom(ctx context.Context) *InboundContext {
  function ExtendContext (line 128) | func ExtendContext(ctx context.Context) (context.Context, *InboundContex...
  function OverrideContext (line 136) | func OverrideContext(ctx context.Context) context.Context {

FILE: adapter/inbound/adapter.go
  type Adapter (line 3) | type Adapter struct
    method Type (line 15) | func (a *Adapter) Type() string {
    method Tag (line 19) | func (a *Adapter) Tag() string {
  function NewAdapter (line 8) | func NewAdapter(inboundType string, inboundTag string) Adapter {

FILE: adapter/inbound/manager.go
  type Manager (line 20) | type Manager struct
    method Start (line 40) | func (m *Manager) Start(stage adapter.StartStage) error {
    method Close (line 62) | func (m *Manager) Close() error {
    method Inbounds (line 87) | func (m *Manager) Inbounds() []adapter.Inbound {
    method Get (line 93) | func (m *Manager) Get(tag string) (adapter.Inbound, bool) {
    method Remove (line 103) | func (m *Manager) Remove(tag string) error {
    method Create (line 126) | func (m *Manager) Create(ctx context.Context, router adapter.Router, l...
  function NewManager (line 31) | func NewManager(logger log.ContextLogger, registry adapter.InboundRegist...

FILE: adapter/inbound/registry.go
  type ConstructorFunc (line 13) | type ConstructorFunc
  function Register (line 15) | func Register[Options any](registry *Registry, outboundType string, cons...
  type optionsConstructorFunc (line 30) | type optionsConstructorFunc
  type constructorFunc (line 31) | type constructorFunc
  type Registry (line 34) | type Registry struct
    method CreateOptions (line 47) | func (m *Registry) CreateOptions(outboundType string) (any, bool) {
    method Create (line 57) | func (m *Registry) Create(ctx context.Context, router adapter.Router, ...
    method register (line 67) | func (m *Registry) register(outboundType string, optionsConstructor op...
  function NewRegistry (line 40) | func NewRegistry() *Registry {

FILE: adapter/lifecycle.go
  type SimpleLifecycle (line 13) | type SimpleLifecycle interface
  type StartStage (line 18) | type StartStage
    method String (line 34) | func (s StartStage) String() string {
  constant StartStateInitialize (line 21) | StartStateInitialize StartStage = iota
  constant StartStateStart (line 22) | StartStateStart
  constant StartStatePostStart (line 23) | StartStatePostStart
  constant StartStateStarted (line 24) | StartStateStarted
  type Lifecycle (line 49) | type Lifecycle interface
  type LifecycleService (line 54) | type LifecycleService interface
  function getServiceName (line 59) | func getServiceName(service any) string {
  function Start (line 77) | func Start(logger log.ContextLogger, stage StartStage, services ...Lifec...
  function StartNamed (line 91) | func StartNamed(logger log.ContextLogger, stage StartStage, services []L...

FILE: adapter/lifecycle_legacy.go
  function LegacyStart (line 3) | func LegacyStart(starter any, stage StartStage) error {
  type lifecycleServiceWrapper (line 30) | type lifecycleServiceWrapper struct
    method Name (line 42) | func (l *lifecycleServiceWrapper) Name() string {
    method Start (line 46) | func (l *lifecycleServiceWrapper) Start(stage StartStage) error {
    method Close (line 50) | func (l *lifecycleServiceWrapper) Close() error {
  function NewLifecycleService (line 35) | func NewLifecycleService(service SimpleLifecycle, name string) Lifecycle...

FILE: adapter/neighbor.go
  type NeighborEntry (line 8) | type NeighborEntry struct
  type NeighborResolver (line 14) | type NeighborResolver interface
  type NeighborUpdateListener (line 21) | type NeighborUpdateListener interface

FILE: adapter/network.go
  type NetworkManager (line 11) | type NetworkManager interface
  type NetworkOptions (line 34) | type NetworkOptions struct
  type InterfaceUpdateListener (line 45) | type InterfaceUpdateListener interface
  type WIFIState (line 49) | type WIFIState struct
  type NetworkInterface (line 54) | type NetworkInterface struct

FILE: adapter/outbound.go
  type Outbound (line 16) | type Outbound interface
  type OutboundWithPreferredRoutes (line 24) | type OutboundWithPreferredRoutes interface
  type DirectRouteOutbound (line 30) | type DirectRouteOutbound interface
  type OutboundRegistry (line 35) | type OutboundRegistry interface
  type OutboundManager (line 40) | type OutboundManager interface

FILE: adapter/outbound/adapter.go
  type Adapter (line 7) | type Adapter struct
    method Type (line 31) | func (a *Adapter) Type() string {
    method Tag (line 35) | func (a *Adapter) Tag() string {
    method Network (line 39) | func (a *Adapter) Network() []string {
    method Dependencies (line 43) | func (a *Adapter) Dependencies() []string {
  function NewAdapter (line 14) | func NewAdapter(outboundType string, outboundTag string, network []strin...
  function NewAdapterWithDialerOptions (line 23) | func NewAdapterWithDialerOptions(outboundType string, outboundTag string...

FILE: adapter/outbound/manager.go
  type Manager (line 23) | type Manager struct
    method Initialize (line 49) | func (m *Manager) Initialize(defaultOutboundFallback func() (adapter.O...
    method Start (line 53) | func (m *Manager) Start(stage adapter.StartStage) error {
    method startOutbounds (line 99) | func (m *Manager) startOutbounds(outbounds []adapter.Outbound) error {
    method Close (line 173) | func (m *Manager) Close() error {
    method Outbounds (line 201) | func (m *Manager) Outbounds() []adapter.Outbound {
    method Outbound (line 207) | func (m *Manager) Outbound(tag string) (adapter.Outbound, bool) {
    method Default (line 217) | func (m *Manager) Default() adapter.Outbound {
    method Remove (line 223) | func (m *Manager) Remove(tag string) error {
    method Create (line 267) | func (m *Manager) Create(ctx context.Context, router adapter.Router, l...
  function NewManager (line 38) | func NewManager(logger logger.ContextLogger, registry adapter.OutboundRe...

FILE: adapter/outbound/registry.go
  type ConstructorFunc (line 13) | type ConstructorFunc
  function Register (line 15) | func Register[Options any](registry *Registry, outboundType string, cons...
  type optionsConstructorFunc (line 30) | type optionsConstructorFunc
  type constructorFunc (line 31) | type constructorFunc
  type Registry (line 34) | type Registry struct
    method CreateOptions (line 47) | func (r *Registry) CreateOptions(outboundType string) (any, bool) {
    method CreateOutbound (line 57) | func (r *Registry) CreateOutbound(ctx context.Context, router adapter....
    method register (line 67) | func (r *Registry) register(outboundType string, optionsConstructor op...
  function NewRegistry (line 40) | func NewRegistry() *Registry {

FILE: adapter/platform.go
  type PlatformInterface (line 9) | type PlatformInterface interface
  type FindConnectionOwnerRequest (line 45) | type FindConnectionOwnerRequest struct
  type ConnectionOwner (line 53) | type ConnectionOwner struct
  type Notification (line 61) | type Notification struct
  type SystemProxyStatus (line 71) | type SystemProxyStatus struct

FILE: adapter/router.go
  type Router (line 21) | type Router interface
  type ConnectionTracker (line 35) | type ConnectionTracker interface
  type ConnectionRouter (line 41) | type ConnectionRouter interface
  type ConnectionRouterEx (line 46) | type ConnectionRouterEx interface
  type RuleSet (line 52) | type RuleSet interface
  type RuleSetUpdateCallback (line 67) | type RuleSetUpdateCallback
  type RuleSetMetadata (line 69) | type RuleSetMetadata struct
  type HTTPStartContext (line 74) | type HTTPStartContext struct
    method HTTPClient (line 87) | func (c *HTTPStartContext) HTTPClient(detour string, dialer N.Dialer) ...
    method Close (line 110) | func (c *HTTPStartContext) Close() {
  function NewHTTPStartContext (line 80) | func NewHTTPStartContext(ctx context.Context) *HTTPStartContext {

FILE: adapter/rule.go
  type HeadlessRule (line 7) | type HeadlessRule interface
  type Rule (line 12) | type Rule interface
  type DNSRule (line 19) | type DNSRule interface
  type RuleAction (line 25) | type RuleAction interface
  function IsFinalAction (line 30) | func IsFinalAction(action RuleAction) bool {

FILE: adapter/service.go
  type Service (line 10) | type Service interface
  type ServiceRegistry (line 16) | type ServiceRegistry interface
  type ServiceManager (line 21) | type ServiceManager interface

FILE: adapter/service/adapter.go
  type Adapter (line 3) | type Adapter struct
    method Type (line 15) | func (a *Adapter) Type() string {
    method Tag (line 19) | func (a *Adapter) Tag() string {
  function NewAdapter (line 8) | func NewAdapter(serviceType string, serviceTag string) Adapter {

FILE: adapter/service/manager.go
  type Manager (line 20) | type Manager struct
    method Start (line 38) | func (m *Manager) Start(stage adapter.StartStage) error {
    method Close (line 60) | func (m *Manager) Close() error {
    method Services (line 85) | func (m *Manager) Services() []adapter.Service {
    method Get (line 91) | func (m *Manager) Get(tag string) (adapter.Service, bool) {
    method Remove (line 98) | func (m *Manager) Remove(tag string) error {
    method Create (line 121) | func (m *Manager) Create(ctx context.Context, logger log.ContextLogger...
  function NewManager (line 30) | func NewManager(logger log.ContextLogger, registry adapter.ServiceRegist...

FILE: adapter/service/registry.go
  type ConstructorFunc (line 13) | type ConstructorFunc
  function Register (line 15) | func Register[Options any](registry *Registry, outboundType string, cons...
  type optionsConstructorFunc (line 30) | type optionsConstructorFunc
  type constructorFunc (line 31) | type constructorFunc
  type Registry (line 34) | type Registry struct
    method CreateOptions (line 47) | func (m *Registry) CreateOptions(outboundType string) (any, bool) {
    method Create (line 57) | func (m *Registry) Create(ctx context.Context, logger log.ContextLogge...
    method register (line 67) | func (m *Registry) register(outboundType string, optionsConstructor op...
  function NewRegistry (line 40) | func NewRegistry() *Registry {

FILE: adapter/ssm.go
  type ManagedSSMServer (line 9) | type ManagedSSMServer interface
  type SSMTracker (line 15) | type SSMTracker interface

FILE: adapter/time.go
  type TimeService (line 5) | type TimeService interface

FILE: adapter/upstream.go
  function NewUpstreamHandlerEx (line 16) | func NewUpstreamHandlerEx(
  type myUpstreamHandlerWrapperEx (line 30) | type myUpstreamHandlerWrapperEx struct
    method NewConnectionEx (line 36) | func (w *myUpstreamHandlerWrapperEx) NewConnectionEx(ctx context.Conte...
    method NewPacketConnectionEx (line 47) | func (w *myUpstreamHandlerWrapperEx) NewPacketConnectionEx(ctx context...
  type myUpstreamContextHandlerWrapperEx (line 60) | type myUpstreamContextHandlerWrapperEx struct
    method NewConnectionEx (line 75) | func (w *myUpstreamContextHandlerWrapperEx) NewConnectionEx(ctx contex...
    method NewPacketConnectionEx (line 86) | func (w *myUpstreamContextHandlerWrapperEx) NewPacketConnectionEx(ctx ...
  function NewUpstreamContextHandlerEx (line 65) | func NewUpstreamContextHandlerEx(
  function NewRouteHandlerEx (line 97) | func NewRouteHandlerEx(
  type routeHandlerWrapperEx (line 109) | type routeHandlerWrapperEx struct
    method NewConnectionEx (line 114) | func (r *routeHandlerWrapperEx) NewConnectionEx(ctx context.Context, c...
    method NewPacketConnectionEx (line 124) | func (r *routeHandlerWrapperEx) NewPacketConnectionEx(ctx context.Cont...
  function NewRouteContextHandlerEx (line 134) | func NewRouteContextHandlerEx(
  type routeContextHandlerWrapperEx (line 144) | type routeContextHandlerWrapperEx struct
    method NewConnectionEx (line 148) | func (r *routeContextHandlerWrapperEx) NewConnectionEx(ctx context.Con...
    method NewPacketConnectionEx (line 159) | func (r *routeContextHandlerWrapperEx) NewPacketConnectionEx(ctx conte...

FILE: adapter/upstream_legacy.go
  function NewUpstreamHandler (line 23) | func NewUpstreamHandler(
  type myUpstreamHandlerWrapper (line 42) | type myUpstreamHandlerWrapper struct
    method NewConnection (line 50) | func (w *myUpstreamHandlerWrapper) NewConnection(ctx context.Context, ...
    method NewPacketConnection (line 62) | func (w *myUpstreamHandlerWrapper) NewPacketConnection(ctx context.Con...
    method NewError (line 74) | func (w *myUpstreamHandlerWrapper) NewError(ctx context.Context, err e...
  function UpstreamMetadata (line 79) | func UpstreamMetadata(metadata InboundContext) M.Metadata {
  type myUpstreamContextHandlerWrapper (line 87) | type myUpstreamContextHandlerWrapper struct
    method NewConnection (line 107) | func (w *myUpstreamContextHandlerWrapper) NewConnection(ctx context.Co...
    method NewPacketConnection (line 119) | func (w *myUpstreamContextHandlerWrapper) NewPacketConnection(ctx cont...
    method NewError (line 131) | func (w *myUpstreamContextHandlerWrapper) NewError(ctx context.Context...
  function NewUpstreamContextHandler (line 94) | func NewUpstreamContextHandler(
  function NewRouteHandler (line 136) | func NewRouteHandler(
  function NewRouteContextHandler (line 149) | func NewRouteContextHandler(
  type routeHandlerWrapper (line 164) | type routeHandlerWrapper struct
    method NewConnection (line 171) | func (w *routeHandlerWrapper) NewConnection(ctx context.Context, conn ...
    method NewPacketConnection (line 183) | func (w *routeHandlerWrapper) NewPacketConnection(ctx context.Context,...
    method NewError (line 195) | func (w *routeHandlerWrapper) NewError(ctx context.Context, err error) {
  type routeContextHandlerWrapper (line 202) | type routeContextHandlerWrapper struct
    method NewConnection (line 208) | func (w *routeContextHandlerWrapper) NewConnection(ctx context.Context...
    method NewPacketConnection (line 220) | func (w *routeContextHandlerWrapper) NewPacketConnection(ctx context.C...
    method NewError (line 232) | func (w *routeContextHandlerWrapper) NewError(ctx context.Context, err...

FILE: adapter/v2ray.go
  type V2RayServerTransport (line 10) | type V2RayServerTransport interface
  type V2RayServerTransportHandler (line 17) | type V2RayServerTransportHandler interface
  type V2RayClientTransport (line 21) | type V2RayClientTransport interface

FILE: box.go
  type Box (line 39) | type Box struct
    method PreStart (line 403) | func (s *Box) PreStart() error {
    method Start (line 422) | func (s *Box) Start() error {
    method preStart (line 441) | func (s *Box) preStart() error {
    method start (line 464) | func (s *Box) start() error {
    method Close (line 496) | func (s *Box) Close() error {
    method Network (line 542) | func (s *Box) Network() adapter.NetworkManager {
    method Router (line 546) | func (s *Box) Router() adapter.Router {
    method Inbound (line 550) | func (s *Box) Inbound() adapter.InboundManager {
    method Outbound (line 554) | func (s *Box) Outbound() adapter.OutboundManager {
    method LogFactory (line 558) | func (s *Box) LogFactory() log.Factory {
  type Options (line 56) | type Options struct
  function Context (line 62) | func Context(
  function New (line 96) | func New(options Options) (*Box, error) {

FILE: cmd/internal/app_store_connect/main.go
  function main (line 19) | func main() {
  constant appID (line 53) | appID   = "6673731168"
  constant groupID (line 54) | groupID = "5c5f3b78-b7a0-40c0-bcad-e6ef87bbefda"
  function createClient (line 57) | func createClient(expireDuration time.Duration) *asc.Client {
  function fetchMacOSVersion (line 69) | func fetchMacOSVersion(ctx context.Context) error {
  function publishTestflight (line 102) | func publishTestflight(ctx context.Context) error {
  function cancelAppStore (line 213) | func cancelAppStore(ctx context.Context, platform string) error {
  function prepareAppStore (line 262) | func prepareAppStore(ctx context.Context) error {
  function publishAppStore (line 402) | func publishAppStore(ctx context.Context) error {
  function isRetryable (line 442) | func isRetryable(response *asc.Response) bool {

FILE: cmd/internal/build/main.go
  function main (line 12) | func main() {

FILE: cmd/internal/build_libbox/main.go
  function init (line 26) | func init() {
  function main (line 33) | func main() {
  function init (line 56) | func init() {
  type AndroidBuildConfig (line 74) | type AndroidBuildConfig struct
  function filterTags (line 80) | func filterTags(tags []string, exclude ...string) []string {
  function checkJavaVersion (line 94) | func checkJavaVersion() {
  function getAndroidBindTarget (line 112) | func getAndroidBindTarget() string {
  function buildAndroidVariant (line 121) | func buildAndroidVariant(config AndroidBuildConfig, bindTarget string) {
  function buildAndroid (line 160) | func buildAndroid() {
  function buildApple (line 191) | func buildApple() {

FILE: cmd/internal/build_shared/sdk.go
  function FindSDK (line 22) | func FindSDK() {
  function findNDK (line 50) | func findNDK() bool {
  function FindMobile (line 94) | func FindMobile() {

FILE: cmd/internal/build_shared/tag.go
  function ReadTag (line 9) | func ReadTag() (string, error) {
  function ReadTagVersionRev (line 23) | func ReadTagVersionRev() (badversion.Version, error) {
  function ReadTagVersion (line 28) | func ReadTagVersion() (badversion.Version, error) {

FILE: cmd/internal/format_docs/main.go
  function main (line 12) | func main() {
  function processFile (line 30) | func processFile(path string) error {

FILE: cmd/internal/protogen/main.go
  function envFile (line 18) | func envFile() (string, error) {
  function GetRuntimeEnv (line 37) | func GetRuntimeEnv(key string) (string, error) {
  function GetGOBIN (line 63) | func GetGOBIN() string {
  function main (line 82) | func main() {
  function NormalizeGeneratedProtoFile (line 184) | func NormalizeGeneratedProtoFile(path string) error {

FILE: cmd/internal/read_tag/main.go
  function init (line 17) | func init() {
  function main (line 22) | func main() {
  function setGitHubEnv (line 55) | func setGitHubEnv(name string, value string) error {

FILE: cmd/internal/tun_bench/main.go
  function main (line 26) | func main() {
  function main0 (line 33) | func main0() error {
  function runTests (line 47) | func runTests() ([]TestResult, error) {
  type TestResult (line 93) | type TestResult struct
  function testOnce (line 103) | func testOnce(boxPath string, stackName string, mtu int, multiThread boo...
  type stderrWriter (line 280) | type stderrWriter struct
    method Write (line 282) | func (w *stderrWriter) Write(p []byte) (n int, err error) {

FILE: cmd/internal/update_android_version/main.go
  function init (line 21) | func init() {
  function main (line 26) | func main() {

FILE: cmd/internal/update_apple_version/main.go
  function init (line 19) | func init() {
  function main (line 23) | func main() {
  function findAndReplace (line 60) | func findAndReplace(objectsMap map[string]any, projectContent string, bu...
  function findAndReplaceProjectVersion (line 84) | func findAndReplaceProjectVersion(objectsMap map[string]any, projectCont...
  function findObjectKey (line 108) | func findObjectKey(objectsMap map[string]any, bundleIDList []string) []s...
  function findObjectKeyByDirectory (line 126) | func findObjectKeyByDirectory(objectsMap map[string]any, directoryList [...

FILE: cmd/internal/update_certificates/main.go
  function main (line 15) | func main() {
  function updateMozillaIncludedRootCAs (line 26) | func updateMozillaIncludedRootCAs() error {
  function fetchChinaFingerprints (line 77) | func fetchChinaFingerprints() (map[string]bool, error) {
  function updateChromeIncludedRootCAs (line 106) | func updateChromeIncludedRootCAs() error {

FILE: cmd/sing-box/cmd.go
  function init (line 32) | func init() {
  function preRun (line 39) | func preRun(cmd *cobra.Command, args []string) {

FILE: cmd/sing-box/cmd_check.go
  function init (line 24) | func init() {
  function check (line 28) | func check() error {

FILE: cmd/sing-box/cmd_format.go
  function init (line 30) | func init() {
  function format (line 35) | func format() error {

FILE: cmd/sing-box/cmd_generate.go
  function init (line 21) | func init() {
  function init (line 45) | func init() {
  function generateRandom (line 50) | func generateRandom(args []string) error {
  function generateUUID (line 85) | func generateUUID() error {

FILE: cmd/sing-box/cmd_generate_ech.go
  function init (line 24) | func init() {
  function generateECHKeyPair (line 28) | func generateECHKeyPair(serverName string) error {

FILE: cmd/sing-box/cmd_generate_tls.go
  function init (line 27) | func init() {
  function generateTLSKeyPair (line 32) | func generateTLSKeyPair(serverName string) error {

FILE: cmd/sing-box/cmd_generate_vapid.go
  function init (line 27) | func init() {
  function generateVAPIDKeyPair (line 31) | func generateVAPIDKeyPair() error {

FILE: cmd/sing-box/cmd_generate_wireguard.go
  function init (line 13) | func init() {
  function generateWireGuardKey (line 30) | func generateWireGuardKey() error {
  function generateRealityKey (line 52) | func generateRealityKey() error {

FILE: cmd/sing-box/cmd_geoip.go
  function init (line 27) | func init() {
  function geoipPreRun (line 32) | func geoipPreRun() error {

FILE: cmd/sing-box/cmd_geoip_export.go
  constant flagGeoipExportDefaultOutput (line 21) | flagGeoipExportDefaultOutput = "geoip-<country>.srs"
  function init (line 35) | func init() {
  function geoipExport (line 40) | func geoipExport(countryCode string) error {

FILE: cmd/sing-box/cmd_geoip_list.go
  function init (line 22) | func init() {
  function listGeoip (line 26) | func listGeoip() error {

FILE: cmd/sing-box/cmd_geoip_lookup.go
  function init (line 26) | func init() {
  function geoipLookup (line 30) | func geoipLookup(address string) error {

FILE: cmd/sing-box/cmd_geosite.go
  function init (line 28) | func init() {
  function geositePreRun (line 33) | func geositePreRun() error {

FILE: cmd/sing-box/cmd_geosite_export.go
  constant commandGeositeExportDefaultOutput (line 18) | commandGeositeExportDefaultOutput = "geosite-<category>.json"
  function init (line 32) | func init() {
  function geositeExport (line 37) | func geositeExport(category string) error {

FILE: cmd/sing-box/cmd_geosite_list.go
  function init (line 24) | func init() {
  function geositeList (line 28) | func geositeList() error {

FILE: cmd/sing-box/cmd_geosite_lookup.go
  function init (line 36) | func init() {
  function geositeLookup (line 40) | func geositeLookup(source string, target string) error {

FILE: cmd/sing-box/cmd_geosite_matcher.go
  type searchGeositeMatcher (line 10) | type searchGeositeMatcher struct
    method Match (line 32) | func (r *searchGeositeMatcher) Match(domain string) string {
  function newSearchGeositeMatcher (line 17) | func newSearchGeositeMatcher(items []geosite.Item) (*searchGeositeMatche...

FILE: cmd/sing-box/cmd_merge.go
  function init (line 32) | func init() {
  function merge (line 36) | func merge(outputPath string) error {
  function mergePathResources (line 70) | func mergePathResources(options *option.Options) error {
  function mergeTLSInboundOptions (line 88) | func mergeTLSInboundOptions(options *option.InboundTLSOptions) *option.I...
  function mergeTLSOutboundOptions (line 112) | func mergeTLSOutboundOptions(options *option.OutboundTLSOptions) *option...
  function mergeSSHOutboundOptions (line 131) | func mergeSSHOutboundOptions(options *option.SSHOutboundOptions) {
  function trimStringArray (line 139) | func trimStringArray(array []string) []string {

FILE: cmd/sing-box/cmd_rule_set.go
  function init (line 12) | func init() {

FILE: cmd/sing-box/cmd_rule_set_compile.go
  constant flagRuleSetCompileDefaultOutput (line 20) | flagRuleSetCompileDefaultOutput = "<file_name>.srs"
  function init (line 34) | func init() {
  function compileRuleSet (line 39) | func compileRuleSet(sourcePath string) error {
  function downgradeRuleSetVersion (line 84) | func downgradeRuleSetVersion(version uint8, options option.PlainRuleSet)...

FILE: cmd/sing-box/cmd_rule_set_convert.go
  function init (line 35) | func init() {
  function convertRuleSet (line 41) | func convertRuleSet(sourcePath string) error {

FILE: cmd/sing-box/cmd_rule_set_decompile.go
  constant flagRuleSetDecompileDefaultOutput (line 20) | flagRuleSetDecompileDefaultOutput = "<file_name>.json"
  function init (line 34) | func init() {
  function decompileRuleSet (line 39) | func decompileRuleSet(sourcePath string) error {
  function hasRule (line 87) | func hasRule(rules []option.HeadlessRule, cond func(rule option.DefaultH...

FILE: cmd/sing-box/cmd_rule_set_format.go
  function init (line 31) | func init() {
  function formatRuleSet (line 36) | func formatRuleSet(sourcePath string) error {

FILE: cmd/sing-box/cmd_rule_set_match.go
  function init (line 38) | func init() {
  function ruleSetMatch (line 43) | func ruleSetMatch(sourcePath string, domain string) error {

FILE: cmd/sing-box/cmd_rule_set_merge.go
  function init (line 38) | func init() {
  type RuleSetEntry (line 44) | type RuleSetEntry struct
  function readRuleSetAt (line 50) | func readRuleSetAt(path string) (*RuleSetEntry, error) {
  function readRuleSet (line 74) | func readRuleSet() ([]*RuleSetEntry, error) {
  function readRuleSetAndMerge (line 105) | func readRuleSetAndMerge() (option.PlainRuleSetCompat, error) {
  function mergeRuleSet (line 134) | func mergeRuleSet(outputPath string) error {

FILE: cmd/sing-box/cmd_rule_set_upgrade.go
  function init (line 32) | func init() {
  function upgradeRuleSet (line 37) | func upgradeRuleSet(sourcePath string) error {

FILE: cmd/sing-box/cmd_run.go
  function init (line 37) | func init() {
  type OptionsEntry (line 41) | type OptionsEntry struct
  function readConfigAt (line 47) | func readConfigAt(path string) (*OptionsEntry, error) {
  function readConfig (line 71) | func readConfig() ([]*OptionsEntry, error) {
  function readConfigAndMerge (line 102) | func readConfigAndMerge() (option.Options, error) {
  function create (line 125) | func create() (*box.Box, context.CancelFunc, error) {
  function run (line 169) | func run() error {
  function closeMonitor (line 204) | func closeMonitor(ctx context.Context) {

FILE: cmd/sing-box/cmd_tools.go
  function init (line 21) | func init() {
  function createPreStartedClient (line 26) | func createPreStartedClient() (*box.Box, error) {
  function createDialer (line 44) | func createDialer(instance *box.Box, outboundTag string) (N.Dialer, erro...

FILE: cmd/sing-box/cmd_tools_connect.go
  function init (line 32) | func init() {
  function connect (line 37) | func connect(address string) error {

FILE: cmd/sing-box/cmd_tools_fetch.go
  function init (line 33) | func init() {
  function fetch (line 42) | func fetch(args []string) error {
  function fetchHTTP (line 99) | func fetchHTTP(httpClient *http.Client, parsedURL *url.URL) error {

FILE: cmd/sing-box/cmd_tools_fetch_http3.go
  function initializeHTTP3Client (line 18) | func initializeHTTP3Client(instance *box.Box) error {

FILE: cmd/sing-box/cmd_tools_fetch_http3_stub.go
  function initializeHTTP3Client (line 12) | func initializeHTTP3Client(instance *box.Box) error {
  function fetchHTTP3 (line 16) | func fetchHTTP3(parsedURL *url.URL) error {

FILE: cmd/sing-box/cmd_tools_synctime.go
  function init (line 34) | func init() {
  function syncTime (line 41) | func syncTime() error {

FILE: cmd/sing-box/cmd_version.go
  function init (line 22) | func init() {
  function printVersion (line 27) | func printVersion(cmd *cobra.Command, args []string) {

FILE: cmd/sing-box/generate_completions.go
  function main (line 7) | func main() {
  function generateCompletions (line 14) | func generateCompletions() error {

FILE: cmd/sing-box/main.go
  function main (line 7) | func main() {

FILE: common/badtls/raw_conn.go
  type RawConn (line 16) | type RawConn struct
    method ReadRecord (line 166) | func (c *RawConn) ReadRecord() error {
    method HandlePostHandshakeMessage (line 170) | func (c *RawConn) HandlePostHandshakeMessage() error {
    method WriteRecordLocked (line 174) | func (c *RawConn) WriteRecordLocked(typ uint16, data []byte) (int, err...
  function NewRawConn (line 42) | func NewRawConn(rawTLSConn tls.Conn) (*RawConn, error) {

FILE: common/badtls/raw_half_conn.go
  type RawHalfConn (line 14) | type RawHalfConn struct
    method Decrypt (line 107) | func (hc *RawHalfConn) Decrypt(record []byte) ([]byte, uint8, error) {
    method SetErrorLocked (line 111) | func (hc *RawHalfConn) SetErrorLocked(err error) error {
    method SetTrafficSecret (line 115) | func (hc *RawHalfConn) SetTrafficSecret(suite unsafe.Pointer, level in...
    method ExplicitNonceLen (line 119) | func (hc *RawHalfConn) ExplicitNonceLen() int {
  function NewRawHalfConn (line 30) | func NewRawHalfConn(rawHalfConn reflect.Value, methods *Methods) (*RawHa...

FILE: common/badtls/read_wait.go
  type ReadWaitConn (line 13) | type ReadWaitConn struct
    method InitializeReadWaiter (line 33) | func (c *ReadWaitConn) InitializeReadWaiter(options N.ReadWaitOptions)...
    method WaitReadBuffer (line 38) | func (c *ReadWaitConn) WaitReadBuffer() (buffer *buf.Buffer, err error) {
    method Upstream (line 76) | func (c *ReadWaitConn) Upstream() any {
    method ReaderReplaceable (line 80) | func (c *ReadWaitConn) ReaderReplaceable() bool {
  function NewReadWaitConn (line 19) | func NewReadWaitConn(conn tls.Conn) (tls.Conn, error) {

FILE: common/badtls/read_wait_stub.go
  function NewReadWaitConn (line 11) | func NewReadWaitConn(conn tls.Conn) (tls.Conn, error) {

FILE: common/badtls/registry.go
  type Methods (line 11) | type Methods struct
  function init (line 24) | func init() {
  function stdTLSReadRecord (line 44) | func stdTLSReadRecord(c unsafe.Pointer) error
  function stdTLSHandlePostHandshakeMessage (line 47) | func stdTLSHandlePostHandshakeMessage(c unsafe.Pointer) error
  function stdWriteRecordLocked (line 50) | func stdWriteRecordLocked(c unsafe.Pointer, typ uint16, data []byte) (in...
  function stdSetErrorLocked (line 53) | func stdSetErrorLocked(hc unsafe.Pointer, err error) error
  function stdDecrypt (line 56) | func stdDecrypt(hc unsafe.Pointer, record []byte) ([]byte, uint8, error)
  function stdSetTrafficSecret (line 59) | func stdSetTrafficSecret(hc unsafe.Pointer, suite unsafe.Pointer, level ...
  function stdExplicitNonceLen (line 62) | func stdExplicitNonceLen(hc unsafe.Pointer) int

FILE: common/badtls/registry_utls.go
  function init (line 14) | func init() {
  function utlsReadRecord (line 38) | func utlsReadRecord(c unsafe.Pointer) error
  function utlsHandlePostHandshakeMessage (line 41) | func utlsHandlePostHandshakeMessage(c unsafe.Pointer) error
  function utlsWriteRecordLocked (line 44) | func utlsWriteRecordLocked(hc unsafe.Pointer, typ uint16, data []byte) (...
  function utlsSetErrorLocked (line 47) | func utlsSetErrorLocked(hc unsafe.Pointer, err error) error
  function utlsDecrypt (line 50) | func utlsDecrypt(hc unsafe.Pointer, record []byte) ([]byte, uint8, error)
  function utlsSetTrafficSecret (line 53) | func utlsSetTrafficSecret(hc unsafe.Pointer, suite unsafe.Pointer, level...
  function utlsExplicitNonceLen (line 56) | func utlsExplicitNonceLen(hc unsafe.Pointer) int

FILE: common/badversion/version.go
  type Version (line 12) | type Version struct
    method LessThan (line 21) | func (v Version) LessThan(anotherVersion Version) bool {
    method LessThanOrEqual (line 25) | func (v Version) LessThanOrEqual(anotherVersion Version) bool {
    method GreaterThanOrEqual (line 29) | func (v Version) GreaterThanOrEqual(anotherVersion Version) bool {
    method GreaterThan (line 33) | func (v Version) GreaterThan(anotherVersion Version) bool {
    method VersionString (line 84) | func (v Version) VersionString() string {
    method String (line 88) | func (v Version) String() string {
    method BadString (line 96) | func (v Version) BadString() string {
  function parsePreReleaseIdentifier (line 73) | func parsePreReleaseIdentifier(identifier string) int {
  function IsValid (line 110) | func IsValid(versionName string) bool {
  function Parse (line 114) | func Parse(versionName string) (version Version) {

FILE: common/badversion/version_json.go
  method MarshalJSON (line 5) | func (v Version) MarshalJSON() ([]byte, error) {
  method UnmarshalJSON (line 9) | func (v *Version) UnmarshalJSON(data []byte) error {

FILE: common/badversion/version_test.go
  function TestCompareVersion (line 9) | func TestCompareVersion(t *testing.T) {

FILE: common/certificate/chrome.go
  function init (line 9) | func init() {

FILE: common/certificate/mozilla.go
  function init (line 9) | func init() {

FILE: common/certificate/store.go
  type Store (line 23) | type Store struct
    method Name (line 99) | func (s *Store) Name() string {
    method Start (line 103) | func (s *Store) Start(stage adapter.StartStage) error {
    method Close (line 113) | func (s *Store) Close() error {
    method Pool (line 120) | func (s *Store) Pool() *x509.CertPool {
    method update (line 126) | func (s *Store) update() error {
  function NewStore (line 33) | func NewStore(ctx context.Context, logger logger.Logger, options option....
  function readUniqueDirectoryEntries (line 172) | func readUniqueDirectoryEntries(dir string) ([]fs.DirEntry, error) {
  function isSameDirSymlink (line 186) | func isSameDirSymlink(f fs.DirEntry, dir string) bool {

FILE: common/compatible/map.go
  type Map (line 6) | type Map struct
  method Len (line 10) | func (m *Map[K, V]) Len() int {
  method Load (line 19) | func (m *Map[K, V]) Load(key K) (V, bool) {
  method Store (line 28) | func (m *Map[K, V]) Store(key K, value V) {
  method Delete (line 32) | func (m *Map[K, V]) Delete(key K) {
  method Range (line 36) | func (m *Map[K, V]) Range(f func(key K, value V) bool) {
  method LoadOrStore (line 42) | func (m *Map[K, V]) LoadOrStore(key K, value V) (V, bool) {
  method LoadAndDelete (line 47) | func (m *Map[K, V]) LoadAndDelete(key K) (V, bool) {
  function New (line 56) | func New[K comparable, V any]() *Map[K, V] {

FILE: common/convertor/adguard/convertor.go
  type agdguardRuleLine (line 20) | type agdguardRuleLine struct
  function ToOptions (line 31) | func ToOptions(reader io.Reader, logger logger.Logger) ([]option.Headles...
  function FromOptions (line 306) | func FromOptions(rules []option.HeadlessRule) ([]byte, error) {
  function ignoreIPCIDRRegexp (line 404) | func ignoreIPCIDRRegexp(ruleLine string) bool {
  function parseAdGuardHostLine (line 416) | func parseAdGuardHostLine(ruleLine string) (string, error) {
  function parseADGuardIPCIDRLine (line 435) | func parseADGuardIPCIDRLine(ruleLine string) (netip.Prefix, error) {

FILE: common/convertor/adguard/convertor_test.go
  function TestConverter (line 15) | func TestConverter(t *testing.T) {
  function TestHosts (line 84) | func TestHosts(t *testing.T) {
  function TestSimpleHosts (line 115) | func TestSimpleHosts(t *testing.T) {

FILE: common/dialer/default.go
  type DefaultDialer (line 30) | type DefaultDialer struct
    method DialContext (line 239) | func (d *DefaultDialer) DialContext(ctx context.Context, network strin...
    method DialParallelInterface (line 266) | func (d *DefaultDialer) DialParallelInterface(ctx context.Context, net...
    method ListenPacket (line 314) | func (d *DefaultDialer) ListenPacket(ctx context.Context, destination ...
    method DialerForICMPDestination (line 330) | func (d *DefaultDialer) DialerForICMPDestination(destination netip.Add...
    method ListenSerialInterfacePacket (line 338) | func (d *DefaultDialer) ListenSerialInterfacePacket(ctx context.Contex...
    method WireGuardControl (line 371) | func (d *DefaultDialer) WireGuardControl() control.Func {
    method trackConn (line 375) | func (d *DefaultDialer) trackConn(conn net.Conn, err error) (net.Conn,...
    method trackPacketConn (line 382) | func (d *DefaultDialer) trackPacketConn(conn net.PacketConn, err error...
  function NewDefault (line 49) | func NewDefault(ctx context.Context, options option.DialerOptions) (*Def...
  function setMarkWrapper (line 223) | func setMarkWrapper(networkManager adapter.NetworkManager, mark uint32, ...

FILE: common/dialer/default_parallel_interface.go
  method dialParallelInterface (line 16) | func (d *DefaultDialer) dialParallelInterface(ctx context.Context, diale...
  method dialParallelInterfaceFastFallback (line 90) | func (d *DefaultDialer) dialParallelInterfaceFastFallback(ctx context.Co...
  method listenSerialInterfacePacket (line 153) | func (d *DefaultDialer) listenSerialInterfacePacket(ctx context.Context,...
  function selectInterfaces (line 185) | func selectInterfaces(networkManager adapter.NetworkManager, strategy C....

FILE: common/dialer/default_parallel_network.go
  function DialSerialNetwork (line 16) | func DialSerialNetwork(ctx context.Context, dialer N.Dialer, network str...
  function DialParallelNetwork (line 47) | func DialParallelNetwork(ctx context.Context, dialer ParallelInterfaceDi...
  function ListenSerialNetworkPacket (line 132) | func ListenSerialNetworkPacket(ctx context.Context, dialer N.Dialer, des...

FILE: common/dialer/detour.go
  type DirectDialer (line 15) | type DirectDialer interface
  type DetourDialer (line 19) | type DetourDialer struct
    method Dialer (line 44) | func (d *DetourDialer) Dialer() (N.Dialer, error) {
    method init (line 49) | func (d *DetourDialer) init() {
    method DialContext (line 66) | func (d *DetourDialer) DialContext(ctx context.Context, network string...
    method ListenPacket (line 74) | func (d *DetourDialer) ListenPacket(ctx context.Context, destination M...
    method Upstream (line 82) | func (d *DetourDialer) Upstream() any {
  function NewDetour (line 28) | func NewDetour(outboundManager adapter.OutboundManager, detour string, l...
  function InitializeDetour (line 36) | func InitializeDetour(dialer N.Dialer) error {

FILE: common/dialer/dialer.go
  type Options (line 19) | type Options struct
  function New (line 31) | func New(ctx context.Context, options option.DialerOptions, remoteIsDoma...
  function NewWithOptions (line 39) | func NewWithOptions(options Options) (N.Dialer, error) {
  type ParallelInterfaceDialer (line 138) | type ParallelInterfaceDialer interface
  type ParallelNetworkDialer (line 144) | type ParallelNetworkDialer interface
  type PacketDialerWithDestination (line 149) | type PacketDialerWithDestination interface

FILE: common/dialer/resolve.go
  type ResolveDialer (line 24) | type ResolveDialer interface
  type ParallelInterfaceResolveDialer (line 29) | type ParallelInterfaceResolveDialer interface
  type resolveDialer (line 34) | type resolveDialer struct
    method initialize (line 77) | func (d *resolveDialer) initialize() error {
    method initServer (line 82) | func (d *resolveDialer) initServer() {
    method DialContext (line 94) | func (d *resolveDialer) DialContext(ctx context.Context, network strin...
    method ListenPacket (line 114) | func (d *resolveDialer) ListenPacket(ctx context.Context, destination ...
    method QueryOptions (line 134) | func (d *resolveDialer) QueryOptions() adapter.DNSQueryOptions {
    method Upstream (line 138) | func (d *resolveDialer) Upstream() any {
  function NewResolveDialer (line 46) | func NewResolveDialer(ctx context.Context, dialer N.Dialer, parallel boo...
  type resolveParallelNetworkDialer (line 72) | type resolveParallelNetworkDialer struct
    method DialParallelInterface (line 142) | func (d *resolveParallelNetworkDialer) DialParallelInterface(ctx conte...
    method ListenSerialInterfacePacket (line 165) | func (d *resolveParallelNetworkDialer) ListenSerialInterfacePacket(ctx...
    method QueryOptions (line 188) | func (d *resolveParallelNetworkDialer) QueryOptions() adapter.DNSQuery...
    method Upstream (line 192) | func (d *resolveParallelNetworkDialer) Upstream() any {

FILE: common/dialer/router.go
  type DefaultOutboundDialer (line 13) | type DefaultOutboundDialer struct
    method DialContext (line 23) | func (d *DefaultOutboundDialer) DialContext(ctx context.Context, netwo...
    method ListenPacket (line 27) | func (d *DefaultOutboundDialer) ListenPacket(ctx context.Context, dest...
    method Upstream (line 31) | func (d *DefaultOutboundDialer) Upstream() any {
  function NewDefaultOutbound (line 17) | func NewDefaultOutbound(ctx context.Context) N.Dialer {

FILE: common/dialer/tfo.go
  type slowOpenConn (line 20) | type slowOpenConn struct
    method Read (line 52) | func (c *slowOpenConn) Read(b []byte) (n int, err error) {
    method Write (line 68) | func (c *slowOpenConn) Write(b []byte) (n int, err error) {
    method Close (line 96) | func (c *slowOpenConn) Close() error {
    method LocalAddr (line 107) | func (c *slowOpenConn) LocalAddr() net.Addr {
    method RemoteAddr (line 115) | func (c *slowOpenConn) RemoteAddr() net.Addr {
    method SetDeadline (line 123) | func (c *slowOpenConn) SetDeadline(t time.Time) error {
    method SetReadDeadline (line 131) | func (c *slowOpenConn) SetReadDeadline(t time.Time) error {
    method SetWriteDeadline (line 139) | func (c *slowOpenConn) SetWriteDeadline(t time.Time) error {
    method Upstream (line 147) | func (c *slowOpenConn) Upstream() any {
    method ReaderReplaceable (line 151) | func (c *slowOpenConn) ReaderReplaceable() bool {
    method WriterReplaceable (line 155) | func (c *slowOpenConn) WriterReplaceable() bool {
    method LazyHeadroom (line 159) | func (c *slowOpenConn) LazyHeadroom() bool {
    method NeedHandshake (line 163) | func (c *slowOpenConn) NeedHandshake() bool {
    method WriteTo (line 167) | func (c *slowOpenConn) WriteTo(w io.Writer) (n int64, err error) {
  function DialSlowContext (line 33) | func DialSlowContext(dialer *tfo.Dialer, ctx context.Context, network st...

FILE: common/dialer/wireguard.go
  type WireGuardListener (line 7) | type WireGuardListener interface

FILE: common/geoip/reader.go
  type Reader (line 11) | type Reader struct
    method Lookup (line 27) | func (r *Reader) Lookup(addr netip.Addr) string {
    method Close (line 36) | func (r *Reader) Close() error {
  function Open (line 15) | func Open(path string) (*Reader, []string, error) {

FILE: common/geosite/compat_test.go
  function oldWriteString (line 17) | func oldWriteString(writer varbin.Writer, value string) error {
  function oldWriteItem (line 22) | func oldWriteItem(writer varbin.Writer, item Item) error {
  function oldReadString (line 27) | func oldReadString(reader varbin.Reader) (string, error) {
  function oldReadItem (line 32) | func oldReadItem(reader varbin.Reader) (Item, error) {
  function TestStringCompat (line 37) | func TestStringCompat(t *testing.T) {
  function TestItemCompat (line 86) | func TestItemCompat(t *testing.T) {
  function TestGeositeWriteReadCompat (line 140) | func TestGeositeWriteReadCompat(t *testing.T) {
  function generateLargeItems (line 225) | func generateLargeItems(count int) map[string][]Item {

FILE: common/geosite/geosite_test.go
  function TestGeosite (line 12) | func TestGeosite(t *testing.T) {

FILE: common/geosite/reader.go
  type Reader (line 14) | type Reader struct
    method readMetadata (line 57) | func (r *Reader) readMetadata() error {
    method Read (line 103) | func (r *Reader) Read(code string) ([]Item, error) {
    method Upstream (line 128) | func (r *Reader) Upstream() any {
  function Open (line 23) | func Open(path string) (*Reader, []string, error) {
  function NewReader (line 36) | func NewReader(readSeeker io.ReadSeeker) (*Reader, []string, error) {
  type geositeMetadata (line 51) | type geositeMetadata struct
  type readCounter (line 132) | type readCounter struct
    method Read (line 137) | func (r *readCounter) Read(p []byte) (n int, err error) {
  function readString (line 145) | func readString(reader io.ByteReader) (string, error) {

FILE: common/geosite/rule.go
  constant RuleTypeDomain (line 8) | RuleTypeDomain ItemType = iota
  constant RuleTypeDomainSuffix (line 9) | RuleTypeDomainSuffix
  constant RuleTypeDomainKeyword (line 10) | RuleTypeDomainKeyword
  constant RuleTypeDomainRegex (line 11) | RuleTypeDomainRegex
  type Item (line 14) | type Item struct
  function Compile (line 19) | func Compile(code []Item) option.DefaultRule {
  function Merge (line 64) | func Merge(rules []option.DefaultRule) option.DefaultRule {

FILE: common/geosite/writer.go
  function Write (line 10) | func Write(writer varbin.Writer, domains map[string][]Item) error {
  function writeString (line 66) | func writeString(writer varbin.Writer, value string) error {

FILE: common/interrupt/conn.go
  type Conn (line 19) | type Conn struct
    method Close (line 29) | func (c *Conn) Close() error {
    method ReaderReplaceable (line 36) | func (c *Conn) ReaderReplaceable() bool {
    method WriterReplaceable (line 40) | func (c *Conn) WriterReplaceable() bool {
    method Upstream (line 44) | func (c *Conn) Upstream() any {
  type PacketConn (line 48) | type PacketConn struct
    method Close (line 58) | func (c *PacketConn) Close() error {
    method ReaderReplaceable (line 65) | func (c *PacketConn) ReaderReplaceable() bool {
    method WriterReplaceable (line 69) | func (c *PacketConn) WriterReplaceable() bool {
    method Upstream (line 73) | func (c *PacketConn) Upstream() any {

FILE: common/interrupt/context.go
  type contextKeyIsExternalConnection (line 5) | type contextKeyIsExternalConnection struct
  function ContextWithIsExternalConnection (line 7) | func ContextWithIsExternalConnection(ctx context.Context) context.Context {
  function IsExternalConnectionFromContext (line 11) | func IsExternalConnectionFromContext(ctx context.Context) bool {

FILE: common/interrupt/group.go
  type Group (line 11) | type Group struct
    method NewConn (line 25) | func (g *Group) NewConn(conn net.Conn, isExternal bool) net.Conn {
    method NewPacketConn (line 32) | func (g *Group) NewPacketConn(conn net.PacketConn, isExternal bool) ne...
    method Interrupt (line 39) | func (g *Group) Interrupt(interruptExternalConnections bool) {
  type groupConnItem (line 16) | type groupConnItem struct
  function NewGroup (line 21) | func NewGroup() *Group {

FILE: common/ja3/error.go
  constant LengthErr (line 13) | LengthErr        string = "length check %v failed"
  constant ContentTypeErr (line 14) | ContentTypeErr   string = "content type not matching"
  constant VersionErr (line 15) | VersionErr       string = "version check %v failed"
  constant HandshakeTypeErr (line 16) | HandshakeTypeErr string = "handshake type not matching"
  constant SNITypeErr (line 17) | SNITypeErr       string = "SNI type not supported"
  type ParseError (line 21) | type ParseError struct
    method Error (line 26) | func (e *ParseError) Error() string {

FILE: common/ja3/ja3.go
  type ClientHello (line 16) | type ClientHello struct
    method Equals (line 29) | func (j *ClientHello) Equals(another *ClientHello, ignoreExtensionsSeq...
    method sortedExtensions (line 54) | func (j *ClientHello) sortedExtensions() []uint16 {
    method String (line 67) | func (j *ClientHello) String() string {
    method Hash (line 74) | func (j *ClientHello) Hash() string {
  function Compute (line 61) | func Compute(payload []byte) (*ClientHello, error) {

FILE: common/ja3/parser.go
  constant recordLayerHeaderLen (line 16) | recordLayerHeaderLen                  int    = 5
  constant handshakeHeaderLen (line 17) | handshakeHeaderLen                    int    = 6
  constant randomDataLen (line 18) | randomDataLen                         int    = 32
  constant sessionIDHeaderLen (line 19) | sessionIDHeaderLen                    int    = 1
  constant cipherSuiteHeaderLen (line 20) | cipherSuiteHeaderLen                  int    = 2
  constant compressMethodHeaderLen (line 21) | compressMethodHeaderLen               int    = 1
  constant extensionsHeaderLen (line 22) | extensionsHeaderLen                   int    = 2
  constant extensionHeaderLen (line 23) | extensionHeaderLen                    int    = 4
  constant sniExtensionHeaderLen (line 24) | sniExtensionHeaderLen                 int    = 5
  constant ecExtensionHeaderLen (line 25) | ecExtensionHeaderLen                  int    = 2
  constant ecpfExtensionHeaderLen (line 26) | ecpfExtensionHeaderLen                int    = 1
  constant versionExtensionHeaderLen (line 27) | versionExtensionHeaderLen             int    = 1
  constant signatureAlgorithmsExtensionHeaderLen (line 28) | signatureAlgorithmsExtensionHeaderLen int    = 2
  constant contentType (line 29) | contentType                           uint8  = 22
  constant handshakeType (line 30) | handshakeType                         uint8  = 1
  constant sniExtensionType (line 31) | sniExtensionType                      uint16 = 0
  constant sniNameDNSHostnameType (line 32) | sniNameDNSHostnameType                uint8  = 0
  constant ecExtensionType (line 33) | ecExtensionType                       uint16 = 10
  constant ecpfExtensionType (line 34) | ecpfExtensionType                     uint16 = 11
  constant versionExtensionType (line 35) | versionExtensionType                  uint16 = 43
  constant signatureAlgorithmsExtensionType (line 36) | signatureAlgorithmsExtensionType      uint16 = 13
  constant tlsVersionBitmask (line 40) | tlsVersionBitmask uint16 = 0xFFFC
  constant tls13 (line 41) | tls13             uint16 = 0x0304
  constant GreaseBitmask (line 45) | GreaseBitmask uint16 = 0x0F0F
  constant dashByte (line 48) | dashByte  = byte(45)
  constant commaByte (line 49) | commaByte = byte(44)
  method parseSegment (line 53) | func (j *ClientHello) parseSegment(segment []byte) error {
  method parseHandshake (line 85) | func (j *ClientHello) parseHandshake(hs []byte) error {
  method parseExtensions (line 155) | func (j *ClientHello) parseExtensions(exs []byte) error {
  method marshalJA3 (line 291) | func (j *ClientHello) marshalJA3() {

FILE: common/ktls/ktls.go
  type Conn (line 24) | type Conn struct
    method Upstream (line 89) | func (c *Conn) Upstream() any {
    method SyscallConnForRead (line 93) | func (c *Conn) SyscallConnForRead() syscall.RawConn {
    method HandleSyscallReadError (line 105) | func (c *Conn) HandleSyscallReadError(inputErr error) ([]byte, error) {
    method SyscallConnForWrite (line 127) | func (c *Conn) SyscallConnForWrite() syscall.RawConn {
  function NewConn (line 38) | func NewConn(ctx context.Context, logger logger.ContextLogger, conn aTLS...

FILE: common/ktls/ktls_alert.go
  constant alertLevelWarning (line 16) | alertLevelWarning = 1
  constant alertLevelError (line 17) | alertLevelError   = 2
  constant alertCloseNotify (line 21) | alertCloseNotify                  = 0
  constant alertUnexpectedMessage (line 22) | alertUnexpectedMessage            = 10
  constant alertBadRecordMAC (line 23) | alertBadRecordMAC                 = 20
  constant alertDecryptionFailed (line 24) | alertDecryptionFailed             = 21
  constant alertRecordOverflow (line 25) | alertRecordOverflow               = 22
  constant alertDecompressionFailure (line 26) | alertDecompressionFailure         = 30
  constant alertHandshakeFailure (line 27) | alertHandshakeFailure             = 40
  constant alertBadCertificate (line 28) | alertBadCertificate               = 42
  constant alertUnsupportedCertificate (line 29) | alertUnsupportedCertificate       = 43
  constant alertCertificateRevoked (line 30) | alertCertificateRevoked           = 44
  constant alertCertificateExpired (line 31) | alertCertificateExpired           = 45
  constant alertCertificateUnknown (line 32) | alertCertificateUnknown           = 46
  constant alertIllegalParameter (line 33) | alertIllegalParameter             = 47
  constant alertUnknownCA (line 34) | alertUnknownCA                    = 48
  constant alertAccessDenied (line 35) | alertAccessDenied                 = 49
  constant alertDecodeError (line 36) | alertDecodeError                  = 50
  constant alertDecryptError (line 37) | alertDecryptError                 = 51
  constant alertExportRestriction (line 38) | alertExportRestriction            = 60
  constant alertProtocolVersion (line 39) | alertProtocolVersion              = 70
  constant alertInsufficientSecurity (line 40) | alertInsufficientSecurity         = 71
  constant alertInternalError (line 41) | alertInternalError                = 80
  constant alertInappropriateFallback (line 42) | alertInappropriateFallback        = 86
  constant alertUserCanceled (line 43) | alertUserCanceled                 = 90
  constant alertNoRenegotiation (line 44) | alertNoRenegotiation              = 100
  constant alertMissingExtension (line 45) | alertMissingExtension             = 109
  constant alertUnsupportedExtension (line 46) | alertUnsupportedExtension         = 110
  constant alertCertificateUnobtainable (line 47) | alertCertificateUnobtainable      = 111
  constant alertUnrecognizedName (line 48) | alertUnrecognizedName             = 112
  constant alertBadCertificateStatusResponse (line 49) | alertBadCertificateStatusResponse = 113
  constant alertBadCertificateHashValue (line 50) | alertBadCertificateHashValue      = 114
  constant alertUnknownPSKIdentity (line 51) | alertUnknownPSKIdentity           = 115
  constant alertCertificateRequired (line 52) | alertCertificateRequired          = 116
  constant alertNoApplicationProtocol (line 53) | alertNoApplicationProtocol        = 120
  constant alertECHRequired (line 54) | alertECHRequired                  = 121
  method sendAlertLocked (line 57) | func (c *Conn) sendAlertLocked(err uint8) error {
  method sendAlert (line 76) | func (c *Conn) sendAlert(err uint8) error {

FILE: common/ktls/ktls_cipher_suites_linux.go
  type kernelCryptoCipherType (line 16) | type kernelCryptoCipherType
  constant TLS_CIPHER_AES_GCM_128 (line 19) | TLS_CIPHER_AES_GCM_128              kernelCryptoCipherType = 51
  constant TLS_CIPHER_AES_GCM_128_IV_SIZE (line 20) | TLS_CIPHER_AES_GCM_128_IV_SIZE      kernelCryptoCipherType = 8
  constant TLS_CIPHER_AES_GCM_128_KEY_SIZE (line 21) | TLS_CIPHER_AES_GCM_128_KEY_SIZE     kernelCryptoCipherType = 16
  constant TLS_CIPHER_AES_GCM_128_SALT_SIZE (line 22) | TLS_CIPHER_AES_GCM_128_SALT_SIZE    kernelCryptoCipherType = 4
  constant TLS_CIPHER_AES_GCM_128_TAG_SIZE (line 23) | TLS_CIPHER_AES_GCM_128_TAG_SIZE     kernelCryptoCipherType = 16
  constant TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE (line 24) | TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE kernelCryptoCipherType = 8
  constant TLS_CIPHER_AES_GCM_256 (line 26) | TLS_CIPHER_AES_GCM_256              kernelCryptoCipherType = 52
  constant TLS_CIPHER_AES_GCM_256_IV_SIZE (line 27) | TLS_CIPHER_AES_GCM_256_IV_SIZE      kernelCryptoCipherType = 8
  constant TLS_CIPHER_AES_GCM_256_KEY_SIZE (line 28) | TLS_CIPHER_AES_GCM_256_KEY_SIZE     kernelCryptoCipherType = 32
  constant TLS_CIPHER_AES_GCM_256_SALT_SIZE (line 29) | TLS_CIPHER_AES_GCM_256_SALT_SIZE    kernelCryptoCipherType = 4
  constant TLS_CIPHER_AES_GCM_256_TAG_SIZE (line 30) | TLS_CIPHER_AES_GCM_256_TAG_SIZE     kernelCryptoCipherType = 16
  constant TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE (line 31) | TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE kernelCryptoCipherType = 8
  constant TLS_CIPHER_AES_CCM_128 (line 33) | TLS_CIPHER_AES_CCM_128              kernelCryptoCipherType = 53
  constant TLS_CIPHER_AES_CCM_128_IV_SIZE (line 34) | TLS_CIPHER_AES_CCM_128_IV_SIZE      kernelCryptoCipherType = 8
  constant TLS_CIPHER_AES_CCM_128_KEY_SIZE (line 35) | TLS_CIPHER_AES_CCM_128_KEY_SIZE     kernelCryptoCipherType = 16
  constant TLS_CIPHER_AES_CCM_128_SALT_SIZE (line 36) | TLS_CIPHER_AES_CCM_128_SALT_SIZE    kernelCryptoCipherType = 4
  constant TLS_CIPHER_AES_CCM_128_TAG_SIZE (line 37) | TLS_CIPHER_AES_CCM_128_TAG_SIZE     kernelCryptoCipherType = 16
  constant TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE (line 38) | TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE kernelCryptoCipherType = 8
  constant TLS_CIPHER_CHACHA20_POLY1305 (line 40) | TLS_CIPHER_CHACHA20_POLY1305              kernelCryptoCipherType = 54
  constant TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE (line 41) | TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE      kernelCryptoCipherType = 12
  constant TLS_CIPHER_CHACHA20_POLY1305_KEY_SIZE (line 42) | TLS_CIPHER_CHACHA20_POLY1305_KEY_SIZE     kernelCryptoCipherType = 32
  constant TLS_CIPHER_CHACHA20_POLY1305_SALT_SIZE (line 43) | TLS_CIPHER_CHACHA20_POLY1305_SALT_SIZE    kernelCryptoCipherType = 0
  constant TLS_CIPHER_CHACHA20_POLY1305_TAG_SIZE (line 44) | TLS_CIPHER_CHACHA20_POLY1305_TAG_SIZE     kernelCryptoCipherType = 16
  constant TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE (line 45) | TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE kernelCryptoCipherType = 8
  constant TLS_CIPHER_ARIA_GCM_128 (line 61) | TLS_CIPHER_ARIA_GCM_128              kernelCryptoCipherType = 57
  constant TLS_CIPHER_ARIA_GCM_128_IV_SIZE (line 62) | TLS_CIPHER_ARIA_GCM_128_IV_SIZE      kernelCryptoCipherType = 8
  constant TLS_CIPHER_ARIA_GCM_128_KEY_SIZE (line 63) | TLS_CIPHER_ARIA_GCM_128_KEY_SIZE     kernelCryptoCipherType = 16
  constant TLS_CIPHER_ARIA_GCM_128_SALT_SIZE (line 64) | TLS_CIPHER_ARIA_GCM_128_SALT_SIZE    kernelCryptoCipherType = 4
  constant TLS_CIPHER_ARIA_GCM_128_TAG_SIZE (line 65) | TLS_CIPHER_ARIA_GCM_128_TAG_SIZE     kernelCryptoCipherType = 16
  constant TLS_CIPHER_ARIA_GCM_128_REC_SEQ_SIZE (line 66) | TLS_CIPHER_ARIA_GCM_128_REC_SEQ_SIZE kernelCryptoCipherType = 8
  constant TLS_CIPHER_ARIA_GCM_256 (line 68) | TLS_CIPHER_ARIA_GCM_256              kernelCryptoCipherType = 58
  constant TLS_CIPHER_ARIA_GCM_256_IV_SIZE (line 69) | TLS_CIPHER_ARIA_GCM_256_IV_SIZE      kernelCryptoCipherType = 8
  constant TLS_CIPHER_ARIA_GCM_256_KEY_SIZE (line 70) | TLS_CIPHER_ARIA_GCM_256_KEY_SIZE     kernelCryptoCipherType = 32
  constant TLS_CIPHER_ARIA_GCM_256_SALT_SIZE (line 71) | TLS_CIPHER_ARIA_GCM_256_SALT_SIZE    kernelCryptoCipherType = 4
  constant TLS_CIPHER_ARIA_GCM_256_TAG_SIZE (line 72) | TLS_CIPHER_ARIA_GCM_256_TAG_SIZE     kernelCryptoCipherType = 16
  constant TLS_CIPHER_ARIA_GCM_256_REC_SEQ_SIZE (line 73) | TLS_CIPHER_ARIA_GCM_256_REC_SEQ_SIZE kernelCryptoCipherType = 8
  type kernelCrypto (line 76) | type kernelCrypto interface
  type kernelCryptoInfo (line 80) | type kernelCryptoInfo struct
  type kernelCryptoAES128GCM (line 87) | type kernelCryptoAES128GCM struct
    method String (line 95) | func (crypto *kernelCryptoAES128GCM) String() string {
  type kernelCryptoAES256GCM (line 102) | type kernelCryptoAES256GCM struct
    method String (line 110) | func (crypto *kernelCryptoAES256GCM) String() string {
  type kernelCryptoAES128CCM (line 117) | type kernelCryptoAES128CCM struct
    method String (line 125) | func (crypto *kernelCryptoAES128CCM) String() string {
  type kernelCryptoChacha20Poly1035 (line 132) | type kernelCryptoChacha20Poly1035 struct
    method String (line 140) | func (crypto *kernelCryptoChacha20Poly1035) String() string {
  type kernelCryptoARIA128GCM (line 177) | type kernelCryptoARIA128GCM struct
    method String (line 185) | func (crypto *kernelCryptoARIA128GCM) String() string {
  type kernelCryptoARIA256GCM (line 192) | type kernelCryptoARIA256GCM struct
    method String (line 200) | func (crypto *kernelCryptoARIA256GCM) String() string {
  function kernelCipher (line 205) | func kernelCipher(kernel *Support, hc *badtls.RawHalfConn, cipherSuite u...

FILE: common/ktls/ktls_close.go
  method Close (line 15) | func (c *Conn) Close() error {
  method closeNotify (line 54) | func (c *Conn) closeNotify() error {

FILE: common/ktls/ktls_const.go
  constant maxPlaintext (line 10) | maxPlaintext               = 16384
  constant maxCiphertext (line 11) | maxCiphertext              = 16384 + 2048
  constant maxCiphertextTLS13 (line 12) | maxCiphertextTLS13         = 16384 + 256
  constant recordHeaderLen (line 13) | recordHeaderLen            = 5
  constant maxHandshake (line 14) | maxHandshake               = 65536
  constant maxHandshakeCertificateMsg (line 15) | maxHandshakeCertificateMsg = 262144
  constant maxUselessRecords (line 16) | maxUselessRecords          = 16
  constant recordTypeChangeCipherSpec (line 20) | recordTypeChangeCipherSpec = 20
  constant recordTypeAlert (line 21) | recordTypeAlert            = 21
  constant recordTypeHandshake (line 22) | recordTypeHandshake        = 22
  constant recordTypeApplicationData (line 23) | recordTypeApplicationData  = 23

FILE: common/ktls/ktls_handshake_messages.go
  type marshalingFunction (line 17) | type marshalingFunction
    method Marshal (line 19) | func (f marshalingFunction) Marshal(b *cryptobyte.Builder) error {
  function addBytesWithLength (line 25) | func addBytesWithLength(b *cryptobyte.Builder, v []byte, n int) {
  function addUint64 (line 36) | func addUint64(b *cryptobyte.Builder, v uint64) {
  function readUint64 (line 43) | func readUint64(s *cryptobyte.String, out *uint64) bool {
  function readUint8LengthPrefixed (line 54) | func readUint8LengthPrefixed(s *cryptobyte.String, out *[]byte) bool {
  function readUint16LengthPrefixed (line 60) | func readUint16LengthPrefixed(s *cryptobyte.String, out *[]byte) bool {
  function readUint24LengthPrefixed (line 66) | func readUint24LengthPrefixed(s *cryptobyte.String, out *[]byte) bool {
  type keyUpdateMsg (line 70) | type keyUpdateMsg struct
    method marshal (line 74) | func (m *keyUpdateMsg) marshal() ([]byte, error) {
    method unmarshal (line 88) | func (m *keyUpdateMsg) unmarshal(data []byte) bool {
  constant typeHelloRequest (line 109) | typeHelloRequest          uint8 = 0
  constant typeClientHello (line 110) | typeClientHello           uint8 = 1
  constant typeServerHello (line 111) | typeServerHello           uint8 = 2
  constant typeNewSessionTicket (line 112) | typeNewSessionTicket      uint8 = 4
  constant typeEndOfEarlyData (line 113) | typeEndOfEarlyData        uint8 = 5
  constant typeEncryptedExtensions (line 114) | typeEncryptedExtensions   uint8 = 8
  constant typeCertificate (line 115) | typeCertificate           uint8 = 11
  constant typeServerKeyExchange (line 116) | typeServerKeyExchange     uint8 = 12
  constant typeCertificateRequest (line 117) | typeCertificateRequest    uint8 = 13
  constant typeServerHelloDone (line 118) | typeServerHelloDone       uint8 = 14
  constant typeCertificateVerify (line 119) | typeCertificateVerify     uint8 = 15
  constant typeClientKeyExchange (line 120) | typeClientKeyExchange     uint8 = 16
  constant typeFinished (line 121) | typeFinished              uint8 = 20
  constant typeCertificateStatus (line 122) | typeCertificateStatus     uint8 = 22
  constant typeKeyUpdate (line 123) | typeKeyUpdate             uint8 = 24
  constant typeCompressedCertificate (line 124) | typeCompressedCertificate uint8 = 25
  constant typeMessageHash (line 125) | typeMessageHash           uint8 = 254
  constant compressionNone (line 130) | compressionNone uint8 = 0
  constant extensionServerName (line 135) | extensionServerName              uint16 = 0
  constant extensionStatusRequest (line 136) | extensionStatusRequest           uint16 = 5
  constant extensionSupportedCurves (line 137) | extensionSupportedCurves         uint16 = 10
  constant extensionSupportedPoints (line 138) | extensionSupportedPoints         uint16 = 11
  constant extensionSignatureAlgorithms (line 139) | extensionSignatureAlgorithms     uint16 = 13
  constant extensionALPN (line 140) | extensionALPN                    uint16 = 16
  constant extensionSCT (line 141) | extensionSCT                     uint16 = 18
  constant extensionPadding (line 142) | extensionPadding                 uint16 = 21
  constant extensionExtendedMasterSecret (line 143) | extensionExtendedMasterSecret    uint16 = 23
  constant extensionCompressCertificate (line 144) | extensionCompressCertificate     uint16 = 27
  constant extensionSessionTicket (line 145) | extensionSessionTicket           uint16 = 35
  constant extensionPreSharedKey (line 146) | extensionPreSharedKey            uint16 = 41
  constant extensionEarlyData (line 147) | extensionEarlyData               uint16 = 42
  constant extensionSupportedVersions (line 148) | extensionSupportedVersions       uint16 = 43
  constant extensionCookie (line 149) | extensionCookie                  uint16 = 44
  constant extensionPSKModes (line 150) | extensionPSKModes                uint16 = 45
  constant extensionCertificateAuthorities (line 151) | extensionCertificateAuthorities  uint16 = 47
  constant extensionSignatureAlgorithmsCert (line 152) | extensionSignatureAlgorithmsCert uint16 = 50
  constant extensionKeyShare (line 153) | extensionKeyShare                uint16 = 51
  constant extensionQUICTransportParameters (line 154) | extensionQUICTransportParameters uint16 = 57
  constant extensionALPS (line 155) | extensionALPS                    uint16 = 17513
  constant extensionRenegotiationInfo (line 156) | extensionRenegotiationInfo       uint16 = 0xff01
  constant extensionECHOuterExtensions (line 157) | extensionECHOuterExtensions      uint16 = 0xfd00
  constant extensionEncryptedClientHello (line 158) | extensionEncryptedClientHello    uint16 = 0xfe0d
  type handshakeMessage (line 161) | type handshakeMessage interface
  type newSessionTicketMsgTLS13 (line 165) | type newSessionTicketMsgTLS13 struct
    method marshal (line 173) | func (m *newSessionTicketMsgTLS13) marshal() ([]byte, error) {
    method unmarshal (line 199) | func (m *newSessionTicketMsgTLS13) unmarshal(data []byte) bool {

FILE: common/ktls/ktls_key_update.go
  method handlePostHandshakeMessage (line 19) | func (c *Conn) handlePostHandshakeMessage() error {
  method handleKeyUpdate (line 49) | func (c *Conn) handleKeyUpdate(keyUpdate *keyUpdateMsg) error {
  method readHandshakeBytes (line 103) | func (c *Conn) readHandshakeBytes(n int) error {
  method readHandshake (line 115) | func (c *Conn) readHandshake(transcript io.Writer) (any, error) {
  method unmarshalHandshakeMessage (line 144) | func (c *Conn) unmarshalHandshakeMessage(data []byte, transcript io.Writ...

FILE: common/ktls/ktls_linux.go
  constant TLS_TX (line 26) | TLS_TX               = 1
  constant TLS_RX (line 27) | TLS_RX               = 2
  constant TLS_TX_ZEROCOPY_RO (line 28) | TLS_TX_ZEROCOPY_RO   = 3
  constant TLS_RX_EXPECT_NO_PAD (line 29) | TLS_RX_EXPECT_NO_PAD = 4
  constant TLS_SET_RECORD_TYPE (line 31) | TLS_SET_RECORD_TYPE = 1
  constant TLS_GET_RECORD_TYPE (line 32) | TLS_GET_RECORD_TYPE = 2
  type Support (line 35) | type Support struct
  function Load (line 114) | func Load() error {
  method setupKernel (line 125) | func (c *Conn) setupKernel(txOffload, rxOffload bool) error {
  method resetupTX (line 193) | func (c *Conn) resetupTX() (func() error, error) {
  method resetupRX (line 215) | func (c *Conn) resetupRX() error {
  method readKernelRecord (line 235) | func (c *Conn) readKernelRecord() (uint8, []byte, error) {
  method writeKernelRecord (line 290) | func (c *Conn) writeKernelRecord(typ uint16, data []byte) (int, error) {
  function recvmsg (line 326) | func recvmsg(fd int, msg *unix.Msghdr, flags int) (n int, err error)
  function sendmsg (line 329) | func sendmsg(fd int, msg *unix.Msghdr, flags int) (n int, err error)

FILE: common/ktls/ktls_prf.go
  function cipherSuiteByID (line 12) | func cipherSuiteByID(id uint16) unsafe.Pointer
  function keysFromMasterSecret (line 15) | func keysFromMasterSecret(version uint16, suite unsafe.Pointer, masterSe...
  function cipherSuiteTLS13ByID (line 18) | func cipherSuiteTLS13ByID(id uint16) unsafe.Pointer
  function nextTrafficSecret (line 21) | func nextTrafficSecret(cs unsafe.Pointer, trafficSecret []byte) []byte
  function trafficKey (line 24) | func trafficKey(cs unsafe.Pointer, trafficSecret []byte) (key, iv []byte)

FILE: common/ktls/ktls_read.go
  method Read (line 18) | func (c *Conn) Read(b []byte) (int, error) {
  method readRecord (line 62) | func (c *Conn) readRecord() error {
  method readRawRecord (line 170) | func (c *Conn) readRawRecord() (typ uint8, data []byte, err error) {
  method retryReadRecord (line 241) | func (c *Conn) retryReadRecord( /*expectChangeCipherSpec bool*/ ) error {
  type atLeastReader (line 253) | type atLeastReader struct
    method Read (line 258) | func (r *atLeastReader) Read(p []byte) (int, error) {
  method readFromUntil (line 275) | func (c *Conn) readFromUntil(r io.Reader, n int) error {
  method newRecordHeaderError (line 288) | func (c *Conn) newRecordHeaderError(conn net.Conn, msg string) (err tls....

FILE: common/ktls/ktls_read_wait.go
  method InitializeReadWaiter (line 14) | func (c *Conn) InitializeReadWaiter(options N.ReadWaitOptions) (needCopy...
  method WaitReadBuffer (line 19) | func (c *Conn) WaitReadBuffer() (buffer *buf.Buffer, err error) {

FILE: common/ktls/ktls_stub_nolinkname.go
  function NewConn (line 13) | func NewConn(ctx context.Context, logger logger.ContextLogger, conn aTLS...

FILE: common/ktls/ktls_stub_nonlinux.go
  function NewConn (line 13) | func NewConn(ctx context.Context, logger logger.ContextLogger, conn aTLS...

FILE: common/ktls/ktls_stub_oldgo.go
  function NewConn (line 13) | func NewConn(ctx context.Context, logger logger.ContextLogger, conn aTLS...

FILE: common/ktls/ktls_write.go
  method Write (line 16) | func (c *Conn) Write(b []byte) (int, error) {
  method writeRecordLocked (line 76) | func (c *Conn) writeRecordLocked(typ uint16, data []byte) (n int, err er...
  constant tcpMSSEstimate (line 101) | tcpMSSEstimate = 1208
  constant recordSizeBoostThreshold (line 106) | recordSizeBoostThreshold = 128 * 1024
  method maxPayloadSizeForWrite (line 109) | func (c *Conn) maxPayloadSizeForWrite(typ uint16) int {

FILE: common/listener/listener.go
  type Listener (line 23) | type Listener struct
    method Start (line 80) | func (l *Listener) Start() error {
    method Close (line 122) | func (l *Listener) Close() error {
    method TCPListener (line 134) | func (l *Listener) TCPListener() net.Listener {
    method UDPConn (line 138) | func (l *Listener) UDPConn() *net.UDPConn {
    method ListenOptions (line 142) | func (l *Listener) ListenOptions() option.ListenOptions {
  type Options (line 46) | type Options struct
  function New (line 61) | func New(
  function ListenNetworkNamespace (line 146) | func ListenNetworkNamespace[T any](nameOrPath string, block func() (T, e...

FILE: common/listener/listener_tcp.go
  method ListenTCP (line 23) | func (l *Listener) ListenTCP() (net.Listener, error) {
  method loopTCPIn (line 82) | func (l *Listener) loopTCPIn() {

FILE: common/listener/listener_udp.go
  method ListenUDP (line 21) | func (l *Listener) ListenUDP() (net.PacketConn, error) {
  method DialContext (line 61) | func (l *Listener) DialContext(dialer net.Dialer, ctx context.Context, n...
  method ListenPacket (line 76) | func (l *Listener) ListenPacket(listenConfig net.ListenConfig, ctx conte...
  method UDPAddr (line 91) | func (l *Listener) UDPAddr() M.Socksaddr {
  method PacketWriter (line 95) | func (l *Listener) PacketWriter() N.PacketWriter {
  method loopUDPIn (line 99) | func (l *Listener) loopUDPIn() {
  method loopUDPOut (line 156) | func (l *Listener) loopUDPOut() {
  type packetWriter (line 186) | type packetWriter
    method WritePacket (line 188) | func (w *packetWriter) WritePacket(buffer *buf.Buffer, destination M.S...
    method WriteIsThreadUnsafe (line 206) | func (w *packetWriter) WriteIsThreadUnsafe() {

FILE: common/mux/client.go
  function NewClientWithOptions (line 19) | func NewClientWithOptions(dialer N.Dialer, logger logger.Logger, options...
  type clientDialer (line 49) | type clientDialer struct
    method DialContext (line 53) | func (d *clientDialer) DialContext(ctx context.Context, network string...
    method ListenPacket (line 57) | func (d *clientDialer) ListenPacket(ctx context.Context, destination M...

FILE: common/mux/router.go
  type Router (line 17) | type Router struct
    method RouteConnection (line 56) | func (r *Router) RouteConnection(ctx context.Context, conn net.Conn, m...
    method RoutePacketConnection (line 66) | func (r *Router) RoutePacketConnection(ctx context.Context, conn N.Pac...
    method RouteConnectionEx (line 70) | func (r *Router) RouteConnectionEx(ctx context.Context, conn net.Conn,...
    method RoutePacketConnectionEx (line 78) | func (r *Router) RoutePacketConnectionEx(ctx context.Context, conn N.P...
  function NewRouterWithOptions (line 22) | func NewRouterWithOptions(router adapter.ConnectionRouterEx, logger logg...

FILE: common/pipelistener/listener.go
  type Listener (line 10) | type Listener struct
    method Serve (line 22) | func (l *Listener) Serve(conn net.Conn) {
    method Accept (line 26) | func (l *Listener) Accept() (net.Conn, error) {
    method Close (line 35) | func (l *Listener) Close() error {
    method Addr (line 45) | func (l *Listener) Addr() net.Addr {
  function New (line 15) | func New(channelSize int) *Listener {
  type addr (line 49) | type addr struct
    method Network (line 51) | func (a addr) Network() string {
    method String (line 55) | func (a addr) String() string {

FILE: common/process/searcher.go
  type Searcher (line 15) | type Searcher interface
  type Config (line 21) | type Config struct
  function FindProcessInfo (line 26) | func FindProcessInfo(searcher Searcher, ctx context.Context, network str...

FILE: common/process/searcher_android.go
  type androidSearcher (line 13) | type androidSearcher struct
    method FindProcessInfo (line 21) | func (s *androidSearcher) FindProcessInfo(ctx context.Context, network...
  function NewSearcher (line 17) | func NewSearcher(config Config) (Searcher, error) {

FILE: common/process/searcher_darwin.go
  type darwinSearcher (line 21) | type darwinSearcher struct
    method FindProcessInfo (line 27) | func (d *darwinSearcher) FindProcessInfo(ctx context.Context, network ...
  function NewSearcher (line 23) | func NewSearcher(_ Config) (Searcher, error) {
  function findProcessName (line 51) | func findProcessName(network string, ip netip.Addr, port int) (string, e...
  function getExecPathFromPID (line 129) | func getExecPathFromPID(pid uint32) (string, error) {
  function readNativeUint32 (line 151) | func readNativeUint32(b []byte) uint32 {

FILE: common/process/searcher_linux.go
  type linuxSearcher (line 15) | type linuxSearcher struct
    method FindProcessInfo (line 23) | func (s *linuxSearcher) FindProcessInfo(ctx context.Context, network s...
  function NewSearcher (line 19) | func NewSearcher(config Config) (Searcher, error) {

FILE: common/process/searcher_linux_shared.go
  constant sizeOfSocketDiagRequest (line 34) | sizeOfSocketDiagRequest = syscall.SizeofNlMsghdr + 8 + 48
  constant socketDiagByFamily (line 35) | socketDiagByFamily      = 20
  constant pathProc (line 36) | pathProc                = "/proc"
  function resolveSocketByNetlink (line 39) | func resolveSocketByNetlink(network string, source netip.AddrPort, desti...
  function packSocketDiagRequest (line 110) | func packSocketDiagRequest(family, protocol byte, source netip.AddrPort)...
  function unpackSocketDiagResponse (line 140) | func unpackSocketDiagResponse(msg *syscall.NetlinkMessage) (inode, uid u...
  function resolveProcessNameByProcSearch (line 153) | func resolveProcessNameByProcSearch(inode, uid uint32) (string, error) {
  function isPid (line 198) | func isPid(s string) bool {

FILE: common/process/searcher_stub.go
  function NewSearcher (line 9) | func NewSearcher(_ Config) (Searcher, error) {

FILE: common/process/searcher_windows.go
  type windowsSearcher (line 17) | type windowsSearcher struct
    method FindProcessInfo (line 31) | func (s *windowsSearcher) FindProcessInfo(ctx context.Context, network...
  function NewSearcher (line 19) | func NewSearcher(_ Config) (Searcher, error) {
  function initWin32API (line 27) | func initWin32API() error {
  function getProcessPath (line 43) | func getProcessPath(pid uint32) (string, error) {

FILE: common/redir/redir_darwin.go
  constant PF_OUT (line 13) | PF_OUT      = 0x2
  constant DIOCNATLOOK (line 14) | DIOCNATLOOK = 0xc0544417
  function GetOriginalDestination (line 17) | func GetOriginalDestination(conn net.Conn) (destination netip.AddrPort, ...

FILE: common/redir/redir_linux.go
  function GetOriginalDestination (line 15) | func GetOriginalDestination(conn net.Conn) (destination netip.AddrPort, ...

FILE: common/redir/redir_other.go
  function GetOriginalDestination (line 11) | func GetOriginalDestination(conn net.Conn) (destination netip.AddrPort, ...

FILE: common/redir/tproxy_linux.go
  function TProxy (line 15) | func TProxy(fd uintptr, isIPv6 bool, isUDP bool) error {
  function TProxyWriteBack (line 34) | func TProxyWriteBack() control.Func {
  function GetOriginalDestinationFromOOB (line 46) | func GetOriginalDestinationFromOOB(oob []byte) (netip.AddrPort, error) {

FILE: common/redir/tproxy_other.go
  function TProxy (line 12) | func TProxy(fd uintptr, isIPv6 bool, isUDP bool) error {
  function TProxyWriteBack (line 16) | func TProxyWriteBack() control.Func {
  function GetOriginalDestinationFromOOB (line 20) | func GetOriginalDestinationFromOOB(oob []byte) (netip.AddrPort, error) {

FILE: common/settings/proxy_android.go
  type AndroidSystemProxy (line 15) | type AndroidSystemProxy struct
    method IsEnabled (line 45) | func (p *AndroidSystemProxy) IsEnabled() bool {
    method Enable (line 49) | func (p *AndroidSystemProxy) Enable() error {
    method Disable (line 58) | func (p *AndroidSystemProxy) Disable() error {
    method runAndroidShell (line 67) | func (p *AndroidSystemProxy) runAndroidShell(name string, args ...stri...
  function NewSystemProxy (line 23) | func NewSystemProxy(ctx context.Context, serverAddr M.Socksaddr, support...

FILE: common/settings/proxy_darwin.go
  type DarwinSystemProxy (line 18) | type DarwinSystemProxy struct
    method IsEnabled (line 41) | func (p *DarwinSystemProxy) IsEnabled() bool {
    method Enable (line 45) | func (p *DarwinSystemProxy) Enable() error {
    method Disable (line 49) | func (p *DarwinSystemProxy) Disable() error {
    method routeUpdate (line 69) | func (p *DarwinSystemProxy) routeUpdate(defaultInterface *control.Inte...
    method update0 (line 76) | func (p *DarwinSystemProxy) update0() error {
  function NewSystemProxy (line 27) | func NewSystemProxy(ctx context.Context, serverAddr M.Socksaddr, support...
  function getInterfaceDisplayName (line 107) | func getInterfaceDisplayName(name string) (string, error) {

FILE: common/settings/proxy_linux.go
  type LinuxSystemProxy (line 18) | type LinuxSystemProxy struct
    method IsEnabled (line 56) | func (p *LinuxSystemProxy) IsEnabled() bool {
    method Enable (line 60) | func (p *LinuxSystemProxy) Enable() error {
    method Disable (line 109) | func (p *LinuxSystemProxy) Disable() error {
    method runAsUser (line 130) | func (p *LinuxSystemProxy) runAsUser(name string, args ...string) error {
    method setGnomeProxy (line 140) | func (p *LinuxSystemProxy) setGnomeProxy(proxyTypes ...string) error {
    method setKDEProxy (line 154) | func (p *LinuxSystemProxy) setKDEProxy(proxyTypes ...string) error {
  function NewSystemProxy (line 27) | func NewSystemProxy(ctx context.Context, serverAddr M.Socksaddr, support...

FILE: common/settings/proxy_stub.go
  function NewSystemProxy (line 12) | func NewSystemProxy(ctx context.Context, serverAddr M.Socksaddr, support...

FILE: common/settings/proxy_windows.go
  type WindowsSystemProxy (line 10) | type WindowsSystemProxy struct
    method IsEnabled (line 23) | func (p *WindowsSystemProxy) IsEnabled() bool {
    method Enable (line 27) | func (p *WindowsSystemProxy) Enable() error {
    method Disable (line 36) | func (p *WindowsSystemProxy) Disable() error {
  function NewSystemProxy (line 16) | func NewSystemProxy(ctx context.Context, serverAddr M.Socksaddr, support...

FILE: common/settings/system_proxy.go
  type SystemProxy (line 3) | type SystemProxy interface

FILE: common/settings/wifi.go
  type WIFIMonitor (line 5) | type WIFIMonitor interface

FILE: common/settings/wifi_linux.go
  type LinuxWIFIMonitor (line 8) | type LinuxWIFIMonitor struct
    method ReadWIFIState (line 30) | func (m *LinuxWIFIMonitor) ReadWIFIState() adapter.WIFIState {
    method Start (line 34) | func (m *LinuxWIFIMonitor) Start() error {
    method Close (line 41) | func (m *LinuxWIFIMonitor) Close() error {
  function NewWIFIMonitor (line 12) | func NewWIFIMonitor(callback func(adapter.WIFIState)) (WIFIMonitor, erro...

FILE: common/settings/wifi_linux_connman.go
  type connmanMonitor (line 15) | type connmanMonitor struct
    method ReadWIFIState (line 38) | func (m *connmanMonitor) ReadWIFIState() adapter.WIFIState {
    method Start (line 105) | func (m *connmanMonitor) Start() error {
    method monitorSignals (line 130) | func (m *connmanMonitor) monitorSignals(ctx context.Context, signalCha...
    method Close (line 152) | func (m *connmanMonitor) Close() error {
  function newConnManMonitor (line 22) | func newConnManMonitor(callback func(adapter.WIFIState)) (WIFIMonitor, e...

FILE: common/settings/wifi_linux_iwd.go
  type iwdMonitor (line 15) | type iwdMonitor struct
    method ReadWIFIState (line 38) | func (m *iwdMonitor) ReadWIFIState() adapter.WIFIState {
    method Start (line 129) | func (m *iwdMonitor) Start() error {
    method monitorSignals (line 154) | func (m *iwdMonitor) monitorSignals(ctx context.Context, signalChan ch...
    method Close (line 174) | func (m *iwdMonitor) Close() error {
  function newIWDMonitor (line 22) | func newIWDMonitor(callback func(adapter.WIFIState)) (WIFIMonitor, error) {

FILE: common/settings/wifi_linux_nm.go
  type networkManagerMonitor (line 15) | type networkManagerMonitor struct
    method ReadWIFIState (line 39) | func (m *networkManagerMonitor) ReadWIFIState() adapter.WIFIState {
    method Start (line 104) | func (m *networkManagerMonitor) Start() error {
    method monitorSignals (line 129) | func (m *networkManagerMonitor) monitorSignals(ctx context.Context, si...
    method Close (line 149) | func (m *networkManagerMonitor) Close() error {
  function newNetworkManagerMonitor (line 22) | func newNetworkManagerMonitor(callback func(adapter.WIFIState)) (WIFIMon...

FILE: common/settings/wifi_linux_wpa.go
  type wpaSupplicantMonitor (line 20) | type wpaSupplicantMonitor struct
    method ReadWIFIState (line 54) | func (m *wpaSupplicantMonitor) ReadWIFIState() adapter.WIFIState {
    method sendCommand (line 99) | func (m *wpaSupplicantMonitor) sendCommand(conn *net.UnixConn, command...
    method Start (line 119) | func (m *wpaSupplicantMonitor) Start() error {
    method monitorEvents (line 133) | func (m *wpaSupplicantMonitor) monitorEvents(ctx context.Context, last...
    method Close (line 215) | func (m *wpaSupplicantMonitor) Close() error {
  function newWpaSupplicantMonitor (line 28) | func newWpaSupplicantMonitor(callback func(adapter.WIFIState)) (WIFIMoni...

FILE: common/settings/wifi_stub.go
  type stubWIFIMonitor (line 11) | type stubWIFIMonitor struct
    method ReadWIFIState (line 17) | func (m *stubWIFIMonitor) ReadWIFIState() adapter.WIFIState {
    method Start (line 21) | func (m *stubWIFIMonitor) Start() error {
    method Close (line 25) | func (m *stubWIFIMonitor) Close() error {
  function NewWIFIMonitor (line 13) | func NewWIFIMonitor(callback func(adapter.WIFIState)) (WIFIMonitor, erro...

FILE: common/settings/wifi_windows.go
  type windowsWIFIMonitor (line 18) | type windowsWIFIMonitor struct
    method ReadWIFIState (line 48) | func (m *windowsWIFIMonitor) ReadWIFIState() adapter.WIFIState {
    method Start (line 87) | func (m *windowsWIFIMonitor) Start() error {
    method checkAndNotify (line 125) | func (m *windowsWIFIMonitor) checkAndNotify() {
    method Close (line 138) | func (m *windowsWIFIMonitor) Close() error {
  function NewWIFIMonitor (line 26) | func NewWIFIMonitor(callback func(adapter.WIFIState)) (WIFIMonitor, erro...
  function formatBSSID (line 82) | func formatBSSID(mac winwlanapi.Dot11MacAddress) string {

FILE: common/sniff/bittorrent.go
  constant trackerConnectFlag (line 16) | trackerConnectFlag    = 0
  constant trackerProtocolID (line 17) | trackerProtocolID     = 0x41727101980
  constant trackerConnectMinSize (line 18) | trackerConnectMinSize = 16
  function BitTorrent (line 23) | func BitTorrent(_ context.Context, metadata *adapter.InboundContext, rea...
  function UTP (line 56) | func UTP(_ context.Context, metadata *adapter.InboundContext, packet []b...
  function UDPTracker (line 95) | func UDPTracker(_ context.Context, metadata *adapter.InboundContext, pac...

FILE: common/sniff/bittorrent_test.go
  function TestSniffBittorrent (line 16) | func TestSniffBittorrent(t *testing.T) {
  function TestSniffIncompleteBittorrent (line 35) | func TestSniffIncompleteBittorrent(t *testing.T) {
  function TestSniffNotBittorrent (line 45) | func TestSniffNotBittorrent(t *testing.T) {
  function TestSniffUTP (line 56) | func TestSniffUTP(t *testing.T) {
  function TestSniffUDPTracker (line 76) | func TestSniffUDPTracker(t *testing.T) {
  function TestSniffNotUTP (line 96) | func TestSniffNotUTP(t *testing.T) {

FILE: common/sniff/dns.go
  function StreamDomainNameQuery (line 17) | func StreamDomainNameQuery(readCtx context.Context, metadata *adapter.In...
  function DomainNameQuery (line 49) | func DomainNameQuery(ctx context.Context, metadata *adapter.InboundConte...

FILE: common/sniff/dns_test.go
  function TestSniffDNS (line 16) | func TestSniffDNS(t *testing.T) {
  function TestSniffStreamDNS (line 26) | func TestSniffStreamDNS(t *testing.T) {
  function TestSniffIncompleteStreamDNS (line 36) | func TestSniffIncompleteStreamDNS(t *testing.T) {
  function TestSniffNotStreamDNS (line 45) | func TestSniffNotStreamDNS(t *testing.T) {

FILE: common/sniff/dtls.go
  function DTLSRecord (line 11) | func DTLSRecord(ctx context.Context, metadata *adapter.InboundContext, p...

FILE: common/sniff/dtls_test.go
  function TestSniffDTLSClientHello (line 15) | func TestSniffDTLSClientHello(t *testing.T) {
  function TestSniffDTLSClientApplicationData (line 25) | func TestSniffDTLSClientApplicationData(t *testing.T) {

FILE: common/sniff/http.go
  function HTTPHost (line 16) | func HTTPHost(_ context.Context, metadata *adapter.InboundContext, reade...

FILE: common/sniff/http_test.go
  function TestSniffHTTP1 (line 14) | func TestSniffHTTP1(t *testing.T) {
  function TestSniffHTTP1WithPort (line 23) | func TestSniffHTTP1WithPort(t *testing.T) {

FILE: common/sniff/internal/qtls/qtls.go
  constant VersionDraft29 (line 14) | VersionDraft29 = 0xff00001d
  constant Version1 (line 15) | Version1       = 0x1
  constant Version2 (line 16) | Version2       = 0x6b3343cf
  constant HKDFLabelKeyV1 (line 26) | HKDFLabelKeyV1              = "quic key"
  constant HKDFLabelKeyV2 (line 27) | HKDFLabelKeyV2              = "quicv2 key"
  constant HKDFLabelIVV1 (line 28) | HKDFLabelIVV1               = "quic iv"
  constant HKDFLabelIVV2 (line 29) | HKDFLabelIVV2               = "quicv2 iv"
  constant HKDFLabelHeaderProtectionV1 (line 30) | HKDFLabelHeaderProtectionV1 = "quic hp"
  constant HKDFLabelHeaderProtectionV2 (line 31) | HKDFLabelHeaderProtectionV2 = "quicv2 hp"
  function AEADAESGCMTLS13 (line 34) | func AEADAESGCMTLS13(key, nonceMask []byte) cipher.AEAD {
  type xorNonceAEAD (line 52) | type xorNonceAEAD struct
    method NonceSize (line 57) | func (f *xorNonceAEAD) NonceSize() int        { return 8 }
    method Overhead (line 58) | func (f *xorNonceAEAD) Overhead() int         { return f.aead.Overhead...
    method explicitNonceLen (line 59) | func (f *xorNonceAEAD) explicitNonceLen() int { return 0 }
    method Seal (line 61) | func (f *xorNonceAEAD) Seal(out, nonce, plaintext, additionalData []by...
    method Open (line 73) | func (f *xorNonceAEAD) Open(out, nonce, ciphertext, additionalData []b...
  function HKDFExpandLabel (line 85) | func HKDFExpandLabel(hash crypto.Hash, secret, context []byte, label str...
  function ReadUvarint (line 102) | func ReadUvarint(r io.ByteReader) (uint64, error) {

FILE: common/sniff/ntp.go
  function NTP (line 12) | func NTP(ctx context.Context, metadata *adapter.InboundContext, packet [...

FILE: common/sniff/ntp_test.go
  function TestSniffNTP (line 16) | func TestSniffNTP(t *testing.T) {
  function TestSniffNTPFailed (line 26) | func TestSniffNTPFailed(t *testing.T) {

FILE: common/sniff/quic.go
  function QUICClientHello (line 23) | func QUICClientHello(ctx context.Context, metadata *adapter.InboundConte...
  function isZero (line 350) | func isZero(slices []uint8) bool {
  function count (line 359) | func count(slices []uint8, value uint8) int {
  type qCryptoFragment (line 369) | type qCryptoFragment struct

FILE: common/sniff/quic_blacklist.go
  constant x25519Kyber768Draft00 (line 9) | x25519Kyber768Draft00 uint16 = 0x11EC
  constant extensionRenegotiationInfo (line 11) | extensionRenegotiationInfo uint16 = 0xFF01
  function isQUICGo (line 17) | func isQUICGo(fingerprint *ja3.ClientHello) bool {

FILE: common/sniff/quic_capture_test.go
  function TestSniffQUICQuicGoFingerprint (line 19) | func TestSniffQUICQuicGoFingerprint(t *testing.T) {
  function TestSniffQUICInitialFromQuicGo (line 88) | func TestSniffQUICInitialFromQuicGo(t *testing.T) {

FILE: common/sniff/quic_test.go
  function TestSniffQUICChromeNew (line 15) | func TestSniffQUICChromeNew(t *testing.T) {
  function TestSniffQUICChromium (line 35) | func TestSniffQUICChromium(t *testing.T) {
  function TestSniffUQUICChrome115 (line 51) | func TestSniffUQUICChrome115(t *testing.T) {
  function TestSniffQUICFirefox (line 63) | func TestSniffQUICFirefox(t *testing.T) {
  function TestSniffQUICSafari (line 75) | func TestSniffQUICSafari(t *testing.T) {
  function FuzzSniffQUIC (line 87) | func FuzzSniffQUIC(f *testing.F) {

FILE: common/sniff/rdp.go
  function RDP (line 15) | func RDP(_ context.Context, metadata *adapter.InboundContext, reader io....

FILE: common/sniff/rdp_test.go
  function TestSniffRDP (line 16) | func TestSniffRDP(t *testing.T) {

FILE: common/sniff/sniff.go
  function Skip (line 25) | func Skip(metadata *adapter.InboundContext) bool {
  function PeekStream (line 41) | func PeekStream(ctx context.Context, metadata *adapter.InboundContext, c...
  function PeekPacket (line 78) | func PeekPacket(ctx context.Context, metadata *adapter.InboundContext, p...

FILE: common/sniff/ssh.go
  function SSH (line 14) | func SSH(_ context.Context, metadata *adapter.InboundContext, reader io....

FILE: common/sniff/ssh_test.go
  function TestSniffSSH (line 16) | func TestSniffSSH(t *testing.T) {
  function TestSniffIncompleteSSH (line 28) | func TestSniffIncompleteSSH(t *testing.T) {
  function TestSniffNotSSH (line 38) | func TestSniffNotSSH(t *testing.T) {

FILE: common/sniff/stun.go
  function STUNMessage (line 12) | func STUNMessage(_ context.Context, metadata *adapter.InboundContext, pa...

FILE: common/sniff/stun_test.go
  function TestSniffSTUN (line 15) | func TestSniffSTUN(t *testing.T) {
  function FuzzSniffSTUN (line 25) | func FuzzSniffSTUN(f *testing.F) {

FILE: common/sniff/tls.go
  function TLSClientHello (line 15) | func TLSClientHello(ctx context.Context, metadata *adapter.InboundContex...

FILE: common/srs/binary.go
  constant ruleItemQueryType (line 26) | ruleItemQueryType uint8 = iota
  constant ruleItemNetwork (line 27) | ruleItemNetwork
  constant ruleItemDomain (line 28) | ruleItemDomain
  constant ruleItemDomainKeyword (line 29) | ruleItemDomainKeyword
  constant ruleItemDomainRegex (line 30) | ruleItemDomainRegex
  constant ruleItemSourceIPCIDR (line 31) | ruleItemSourceIPCIDR
  constant ruleItemIPCIDR (line 32) | ruleItemIPCIDR
  constant ruleItemSourcePort (line 33) | ruleItemSourcePort
  constant ruleItemSourcePortRange (line 34) | ruleItemSourcePortRange
  constant ruleItemPort (line 35) | ruleItemPort
  constant ruleItemPortRange (line 36) | ruleItemPortRange
  constant ruleItemProcessName (line 37) | ruleItemProcessName
  constant ruleItemProcessPath (line 38) | ruleItemProcessPath
  constant ruleItemPackageName (line 39) | ruleItemPackageName
  constant ruleItemWIFISSID (line 40) | ruleItemWIFISSID
  constant ruleItemWIFIBSSID (line 41) | ruleItemWIFIBSSID
  constant ruleItemAdGuardDomain (line 42) | ruleItemAdGuardDomain
  constant ruleItemProcessPathRegex (line 43) | ruleItemProcessPathRegex
  constant ruleItemNetworkType (line 44) | ruleItemNetworkType
  constant ruleItemNetworkIsExpensive (line 45) | ruleItemNetworkIsExpensive
  constant ruleItemNetworkIsConstrained (line 46) | ruleItemNetworkIsConstrained
  constant ruleItemNetworkInterfaceAddress (line 47) | ruleItemNetworkInterfaceAddress
  constant ruleItemDefaultInterfaceAddress (line 48) | ruleItemDefaultInterfaceAddress
  constant ruleItemFinal (line 49) | ruleItemFinal uint8 = 0xFF
  function Read (line 52) | func Read(reader io.Reader, recover bool) (ruleSetCompat option.PlainRul...
  function Write (line 91) | func Write(writer io.Writer, ruleSet option.PlainRuleSet, generateVersio...
  function readRule (line 122) | func readRule(reader varbin.Reader, recover bool) (rule option.HeadlessR...
  function writeRule (line 141) | func writeRule(writer varbin.Writer, rule option.HeadlessRule, generateV...
  function readDefaultRule (line 152) | func readDefaultRule(reader varbin.Reader, recover bool) (rule option.De...
  function writeDefaultRule (line 296) | func writeDefaultRule(writer varbin.Writer, rule option.DefaultHeadlessR...
  function readRuleItemString (line 508) | func readRuleItemString(reader varbin.Reader) ([]string, error) {
  function writeRuleItemString (line 529) | func writeRuleItemString(writer varbin.Writer, itemType uint8, value []s...
  function readRuleItemUint8 (line 551) | func readRuleItemUint8[E ~uint8](reader varbin.Reader) ([]E, error) {
  function writeRuleItemUint8 (line 564) | func writeRuleItemUint8[E ~uint8](writer varbin.Writer, itemType uint8, ...
  function readRuleItemUint16 (line 577) | func readRuleItemUint16(reader varbin.Reader) ([]uint16, error) {
  function writeRuleItemUint16 (line 590) | func writeRuleItemUint16(writer varbin.Writer, itemType uint8, value []u...
  function writeRuleItemCIDR (line 602) | func writeRuleItemCIDR(writer varbin.Writer, itemType uint8, value []str...
  function readLogicalRule (line 628) | func readLogicalRule(reader varbin.Reader, recovery bool) (logicalRule o...
  function writeLogicalRule (line 661) | func writeLogicalRule(writer varbin.Writer, logicalRule option.LogicalHe...

FILE: common/srs/compat_test.go
  function oldWriteStringSlice (line 21) | func oldWriteStringSlice(writer varbin.Writer, value []string) error {
  function oldReadStringSlice (line 26) | func oldReadStringSlice(reader varbin.Reader) ([]string, error) {
  function oldWriteUint8Slice (line 31) | func oldWriteUint8Slice[E ~uint8](writer varbin.Writer, value []E) error {
  function oldReadUint8Slice (line 36) | func oldReadUint8Slice[E ~uint8](reader varbin.Reader) ([]E, error) {
  function oldWriteUint16Slice (line 41) | func oldWriteUint16Slice(writer varbin.Writer, value []uint16) error {
  function oldReadUint16Slice (line 46) | func oldReadUint16Slice(reader varbin.Reader) ([]uint16, error) {
  function oldWritePrefix (line 51) | func oldWritePrefix(writer varbin.Writer, prefix netip.Prefix) error {
  type oldIPRangeData (line 60) | type oldIPRangeData struct
  function oldReadIPSet (line 78) | func oldReadIPSet(reader varbin.Reader) (*netipx.IPSet, error) {
  function newWriteStringSlice (line 109) | func newWriteStringSlice(writer varbin.Writer, value []string) error {
  function newWriteUint8Slice (line 127) | func newWriteUint8Slice[E ~uint8](writer varbin.Writer, value []E) error {
  function newWriteUint16Slice (line 136) | func newWriteUint16Slice(writer varbin.Writer, value []uint16) error {
  function newWritePrefix (line 144) | func newWritePrefix(writer varbin.Writer, prefix netip.Prefix) error {
  function TestStringSliceCompat (line 159) | func TestStringSliceCompat(t *testing.T) {
  function TestUint8SliceCompat (line 212) | func TestUint8SliceCompat(t *testing.T) {
  function TestUint16SliceCompat (line 261) | func TestUint16SliceCompat(t *testing.T) {
  function TestPrefixCompat (line 310) | func TestPrefixCompat(t *testing.T) {
  function TestIPSetCompat (line 361) | func TestIPSetCompat(t *testing.T) {
  function generateStrings (line 409) | func generateStrings(count int) []string {
  function generateUint8Slice (line 417) | func generateUint8Slice(count int) []uint8 {
  function generateUint16Slice (line 425) | func generateUint16Slice(count int) []uint16 {
  function buildIPSet (line 433) | func buildIPSet(cidrs ...string) *netipx.IPSet {
  function buildLargeIPSet (line 451) | func buildLargeIPSet(count int) *netipx.IPSet {
  function requireStringSliceEqual (line 461) | func requireStringSliceEqual(t *testing.T, expected, actual []string) {
  function requireUint8SliceEqual (line 469) | func requireUint8SliceEqual(t *testing.T, expected, actual []uint8) {
  function requireUint16SliceEqual (line 477) | func requireUint16SliceEqual(t *testing.T, expected, actual []uint16) {
  function requireIPSetEqual (line 485) | func requireIPSetEqual(t *testing.T, expected, actual *netipx.IPSet) {

FILE: common/srs/ip_cidr.go
  function readPrefix (line 12) | func readPrefix(reader varbin.Reader) (netip.Prefix, error) {
  function writePrefix (line 29) | func writePrefix(writer varbin.Writer, prefix netip.Prefix) error {

FILE: common/srs/ip_set.go
  type myIPSet (line 16) | type myIPSet struct
  type myIPRange (line 20) | type myIPRange struct
  function readIPSet (line 25) | func readIPSet(reader varbin.Reader) (*netipx.IPSet, error) {
  function writeIPSet (line 67) | func writeIPSet(writer varbin.Writer, set *netipx.IPSet) error {

FILE: common/taskmonitor/monitor.go
  type Monitor (line 10) | type Monitor struct
    method Start (line 23) | func (m *Monitor) Start(taskName ...any) {
    method Finish (line 29) | func (m *Monitor) Finish() {
  function New (line 16) | func New(logger logger.Logger, timeout time.Duration) *Monitor {

FILE: common/tls/acme.go
  type acmeWrapper (line 25) | type acmeWrapper struct
    method Start (line 32) | func (w *acmeWrapper) Start() error {
    method Close (line 36) | func (w *acmeWrapper) Close() error {
  type acmeLogWriter (line 41) | type acmeLogWriter struct
    method Write (line 45) | func (w *acmeLogWriter) Write(p []byte) (n int, err error) {
    method Sync (line 62) | func (w *acmeLogWriter) Sync() error {
  function encoderConfig (line 66) | func encoderConfig() zapcore.EncoderConfig {
  function startACME (line 72) | func startACME(ctx context.Context, logger logger.Logger, options option...

FILE: common/tls/acme_contstant.go
  constant ACMETLS1Protocol (line 3) | ACMETLS1Protocol = "acme-tls/1"

FILE: common/tls/acme_stub.go
  function startACME (line 15) | func startACME(ctx context.Context, logger logger.Logger, options option...

FILE: common/tls/client.go
  function NewDialerFromOptions (line 19) | func NewDialerFromOptions(ctx context.Context, logger logger.ContextLogg...
  function NewClient (line 35) | func NewClient(ctx context.Context, logger logger.ContextLogger, serverA...
  type ClientOptions (line 44) | type ClientOptions struct
  function NewClientWithOptions (line 52) | func NewClientWithOptions(options ClientOptions) (Config, error) {
  function ClientHandshake (line 72) | func ClientHandshake(ctx context.Context, conn net.Conn, config Config) ...
  type Dialer (line 88) | type Dialer interface
  type defaultDialer (line 93) | type defaultDialer struct
    method DialContext (line 102) | func (d *defaultDialer) DialContext(ctx context.Context, network strin...
    method ListenPacket (line 109) | func (d *defaultDialer) ListenPacket(ctx context.Context, destination ...
    method DialTLSContext (line 113) | func (d *defaultDialer) DialTLSContext(ctx context.Context, destinatio...
    method dialContext (line 117) | func (d *defaultDialer) dialContext(ctx context.Context, destination M...
    method Upstream (line 137) | func (d *defaultDialer) Upstream() any {
  function NewDialer (line 98) | func NewDialer(dialer N.Dialer, config Config) Dialer {

FILE: common/tls/common.go
  constant VersionTLS10 (line 4) | VersionTLS10 = 0x0301
  constant VersionTLS11 (line 5) | VersionTLS11 = 0x0302
  constant VersionTLS12 (line 6) | VersionTLS12 = 0x0303
  constant VersionTLS13 (line 7) | VersionTLS13 = 0x0304
  constant VersionSSL30 (line 11) | VersionSSL30 = 0x0300

FILE: common/tls/config.go
  function ParseTLSVersion (line 24) | func ParseTLSVersion(version string) (uint16, error) {

FILE: common/tls/ech.go
  function parseECHClientConfig (line 27) | func parseECHClientConfig(ctx context.Context, clientConfig ECHCapableCo...
  function parseECHServerConfig (line 58) | func parseECHServerConfig(ctx context.Context, options option.InboundTLS...
  method setECHServerConfig (line 84) | func (c *STDServerConfig) setECHServerConfig(echKey []byte) error {
  function parseECHKeys (line 97) | func parseECHKeys(echKey []byte) ([]tls.EncryptedClientHelloKey, error) {
  type ECHClientConfig (line 109) | type ECHClientConfig struct
    method ClientHandshake (line 118) | func (s *ECHClientConfig) ClientHandshake(ctx context.Context, conn ne...
    method fetchAndHandshake (line 130) | func (s *ECHClientConfig) fetchAndHandshake(ctx context.Context, conn ...
    method Clone (line 182) | func (s *ECHClientConfig) Clone() Config {
  function UnmarshalECHKeys (line 191) | func UnmarshalECHKeys(raw []byte) ([]tls.EncryptedClientHelloKey, error) {

FILE: common/tls/ech_shared.go
  type ECHCapableConfig (line 11) | type ECHCapableConfig interface
  function ECHKeygenDefault (line 17) | func ECHKeygenDefault(publicName string) (configPem string, keyPem strin...
  function marshalECHConfig (line 50) | func marshalECHConfig(id uint8, pubKey []byte, publicName string, maxNam...

FILE: common/tls/ktls.go
  type KTLSClientConfig (line 13) | type KTLSClientConfig struct
    method ClientHandshake (line 19) | func (w *KTLSClientConfig) ClientHandshake(ctx context.Context, conn n...
    method Clone (line 32) | func (w *KTLSClientConfig) Clone() Config {
  type KTlSServerConfig (line 41) | type KTlSServerConfig struct
    method ServerHandshake (line 47) | func (w *KTlSServerConfig) ServerHandshake(ctx context.Context, conn n...
    method Clone (line 60) | func (w *KTlSServerConfig) Clone() Config {

FILE: common/tls/mkcert.go
  function GenerateKeyPair (line 14) | func GenerateKeyPair(parent *x509.Certificate, parentKey any, timeFunc f...
  function GenerateCertificate (line 29) | func GenerateCertificate(parent *x509.Certificate, parentKey any, timeFu...

FILE: common/tls/reality_client.go
  type RealityClientConfig (line 47) | type RealityClientConfig struct
    method ServerName (line 95) | func (e *RealityClientConfig) ServerName() string {
    method SetServerName (line 99) | func (e *RealityClientConfig) SetServerName(serverName string) {
    method NextProtos (line 103) | func (e *RealityClientConfig) NextProtos() []string {
    method SetNextProtos (line 107) | func (e *RealityClientConfig) SetNextProtos(nextProto []string) {
    method STDConfig (line 111) | func (e *RealityClientConfig) STDConfig() (*STDConfig, error) {
    method Client (line 115) | func (e *RealityClientConfig) Client(conn net.Conn) (Conn, error) {
    method ClientHandshake (line 119) | func (e *RealityClientConfig) ClientHandshake(ctx context.Context, con...
    method Clone (line 253) | func (e *RealityClientConfig) Clone() Config {
  function NewRealityClient (line 54) | func NewRealityClient(ctx context.Context, logger logger.ContextLogger, ...
  function realityClientFallback (line 229) | func realityClientFallback(ctx context.Context, uConn net.Conn, serverNa...
  type realityVerifier (line 262) | type realityVerifier struct
    method VerifyPeerCertificate (line 269) | func (c *realityVerifier) VerifyPeerCertificate(rawCerts [][]byte, ver...
  type realityClientConnWrapper (line 293) | type realityClientConnWrapper struct
    method ConnectionState (line 297) | func (c *realityClientConnWrapper) ConnectionState() tls.ConnectionSta...
    method Upstream (line 316) | func (c *realityClientConnWrapper) Upstream() any {
    method CloseWrite (line 322) | func (c *realityClientConnWrapper) CloseWrite() error {
    method ReaderReplaceable (line 326) | func (c *realityClientConnWrapper) ReaderReplaceable() bool {
    method WriterReplaceable (line 330) | func (c *realityClientConnWrapper) WriterReplaceable() bool {

FILE: common/tls/reality_server.go
  type RealityServerConfig (line 28) | type RealityServerConfig struct
    method ServerName (line 144) | func (c *RealityServerConfig) ServerName() string {
    method SetServerName (line 148) | func (c *RealityServerConfig) SetServerName(serverName string) {
    method NextProtos (line 152) | func (c *RealityServerConfig) NextProtos() []string {
    method SetNextProtos (line 156) | func (c *RealityServerConfig) SetNextProtos(nextProto []string) {
    method STDConfig (line 160) | func (c *RealityServerConfig) STDConfig() (*tls.Config, error) {
    method Client (line 164) | func (c *RealityServerConfig) Client(conn net.Conn) (Conn, error) {
    method Start (line 168) | func (c *RealityServerConfig) Start() error {
    method Close (line 172) | func (c *RealityServerConfig) Close() error {
    method Server (line 176) | func (c *RealityServerConfig) Server(conn net.Conn) (Conn, error) {
    method ServerHandshake (line 180) | func (c *RealityServerConfig) ServerHandshake(ctx context.Context, con...
    method Clone (line 188) | func (c *RealityServerConfig) Clone() Config {
  function NewRealityServer (line 32) | func NewRealityServer(ctx context.Context, logger log.ContextLogger, opt...
  type realityConnWrapper (line 196) | type realityConnWrapper struct
    method ConnectionState (line 200) | func (c *realityConnWrapper) ConnectionState() ConnectionState {
    method Upstream (line 219) | func (c *realityConnWrapper) Upstream() any {
    method CloseWrite (line 225) | func (c *realityConnWrapper) CloseWrite() error {
    method ReaderReplaceable (line 229) | func (c *realityConnWrapper) ReaderReplaceable() bool {
    method WriterReplaceable (line 233) | func (c *realityConnWrapper) WriterReplaceable() bool {

FILE: common/tls/server.go
  type ServerOptions (line 15) | type ServerOptions struct
  function NewServer (line 22) | func NewServer(ctx context.Context, logger log.ContextLogger, options op...
  function NewServerWithOptions (line 30) | func NewServerWithOptions(options ServerOptions) (ServerConfig, error) {
  function ServerHandshake (line 48) | func ServerHandshake(ctx context.Context, conn net.Conn, config ServerCo...

FILE: common/tls/std_client.go
  type STDClientConfig (line 24) | type STDClientConfig struct
    method ServerName (line 32) | func (c *STDClientConfig) ServerName() string {
    method SetServerName (line 36) | func (c *STDClientConfig) SetServerName(serverName string) {
    method NextProtos (line 40) | func (c *STDClientConfig) NextProtos() []string {
    method SetNextProtos (line 44) | func (c *STDClientConfig) SetNextProtos(nextProto []string) {
    method STDConfig (line 48) | func (c *STDClientConfig) STDConfig() (*STDConfig, error) {
    method Client (line 52) | func (c *STDClientConfig) Client(conn net.Conn) (Conn, error) {
    method Clone (line 59) | func (c *STDClientConfig) Clone() Config {
    method ECHConfigList (line 69) | func (c *STDClientConfig) ECHConfigList() []byte {
    method SetECHConfigList (line 73) | func (c *STDClientConfig) SetECHConfigList(EncryptedClientHelloConfigL...
  function NewSTDClient (line 77) | func NewSTDClient(ctx context.Context, logger logger.ContextLogger, serv...
  function verifyPublicKeySHA256 (line 223) | func verifyPublicKeySHA256(knownHashValues [][]byte, rawCerts [][]byte, ...

FILE: common/tls/std_server.go
  type STDServerConfig (line 25) | type STDServerConfig struct
    method ServerName (line 39) | func (c *STDServerConfig) ServerName() string {
    method SetServerName (line 45) | func (c *STDServerConfig) SetServerName(serverName string) {
    method NextProtos (line 53) | func (c *STDServerConfig) NextProtos() []string {
    method SetNextProtos (line 63) | func (c *STDServerConfig) SetNextProtos(nextProto []string) {
    method STDConfig (line 75) | func (c *STDServerConfig) STDConfig() (*STDConfig, error) {
    method Client (line 79) | func (c *STDServerConfig) Client(conn net.Conn) (Conn, error) {
    method Server (line 83) | func (c *STDServerConfig) Server(conn net.Conn) (Conn, error) {
    method Clone (line 87) | func (c *STDServerConfig) Clone() Config {
    method Start (line 93) | func (c *STDServerConfig) Start() error {
    method startWatcher (line 105) | func (c *STDServerConfig) startWatcher() error {
    method certificateUpdated (line 142) | func (c *STDServerConfig) certificateUpdated(path string) error {
    method Close (line 205) | func (c *STDServerConfig) Close() error {
  function NewSTDServer (line 215) | func NewSTDServer(ctx context.Context, logger log.ContextLogger, options...

FILE: common/tls/time_wrapper.go
  type TimeServiceWrapper (line 9) | type TimeServiceWrapper struct
    method TimeFunc (line 13) | func (w *TimeServiceWrapper) TimeFunc() func() time.Time {
    method Upstream (line 23) | func (w *TimeServiceWrapper) Upstream() any {

FILE: common/tls/utls_client.go
  type UTLSClientConfig (line 28) | type UTLSClientConfig struct
    method ServerName (line 37) | func (c *UTLSClientConfig) ServerName() string {
    method SetServerName (line 41) | func (c *UTLSClientConfig) SetServerName(serverName string) {
    method NextProtos (line 45) | func (c *UTLSClientConfig) NextProtos() []string {
    method SetNextProtos (line 49) | func (c *UTLSClientConfig) SetNextProtos(nextProto []string) {
    method STDConfig (line 56) | func (c *UTLSClientConfig) STDConfig() (*STDConfig, error) {
    method Client (line 60) | func (c *UTLSClientConfig) Client(conn net.Conn) (Conn, error) {
    method SetSessionIDGenerator (line 67) | func (c *UTLSClientConfig) SetSessionIDGenerator(generator func(client...
    method Clone (line 71) | func (c *UTLSClientConfig) Clone() Config {
    method ECHConfigList (line 77) | func (c *UTLSClientConfig) ECHConfigList() []byte {
    method SetECHConfigList (line 81) | func (c *UTLSClientConfig) SetECHConfigList(EncryptedClientHelloConfig...
  type utlsConnWrapper (line 85) | type utlsConnWrapper struct
    method ConnectionState (line 89) | func (c *utlsConnWrapper) ConnectionState() tls.ConnectionState {
    method Upstream (line 108) | func (c *utlsConnWrapper) Upstream() any {
    method ReaderReplaceable (line 112) | func (c *utlsConnWrapper) ReaderReplaceable() bool {
    method WriterReplaceable (line 116) | func (c *utlsConnWrapper) WriterReplaceable() bool {
  type utlsALPNWrapper (line 120) | type utlsALPNWrapper struct
    method HandshakeContext (line 125) | func (c *utlsALPNWrapper) HandshakeContext(ctx context.Context) error {
  function NewUTLSClient (line 145) | func NewUTLSClient(ctx context.Context, logger logger.ContextLogger, ser...
  function init (line 287) | func init() {
  function uTLSClientHelloID (line 305) | func uTLSClientHelloID(name string) (utls.ClientHelloID, error) {

FILE: common/tls/utls_stub.go
  function NewUTLSClient (line 14) | func NewUTLSClient(ctx context.Context, logger logger.ContextLogger, ser...
  function NewRealityClient (line 18) | func NewRealityClient(ctx context.Context, logger logger.ContextLogger, ...
  function NewRealityServer (line 22) | func NewRealityServer(ctx context.Context, logger log.Logger, options op...

FILE: common/tlsfragment/conn.go
  type Conn (line 18) | type Conn struct
    method Write (line 43) | func (c *Conn) Write(b []byte) (n int, err error) {
    method ReaderReplaceable (line 136) | func (c *Conn) ReaderReplaceable() bool {
    method WriterReplaceable (line 140) | func (c *Conn) WriterReplaceable() bool {
    method Upstream (line 144) | func (c *Conn) Upstream() any {
  function NewConn (line 28) | func NewConn(conn net.Conn, ctx context.Context, splitPacket bool, split...

FILE: common/tlsfragment/conn_test.go
  function TestTLSFragment (line 14) | func TestTLSFragment(t *testing.T) {
  function TestTLSRecordFragment (line 24) | func TestTLSRecordFragment(t *testing.T) {
  function TestTLS2Fragment (line 34) | func TestTLS2Fragment(t *testing.T) {

FILE: common/tlsfragment/index.go
  constant recordLayerHeaderLen (line 8) | recordLayerHeaderLen    int    = 5
  constant handshakeHeaderLen (line 9) | handshakeHeaderLen      int    = 6
  constant randomDataLen (line 10) | randomDataLen           int    = 32
  constant sessionIDHeaderLen (line 11) | sessionIDHeaderLen      int    = 1
  constant cipherSuiteHeaderLen (line 12) | cipherSuiteHeaderLen    int    = 2
  constant compressMethodHeaderLen (line 13) | compressMethodHeaderLen int    = 1
  constant extensionsHeaderLen (line 14) | extensionsHeaderLen     int    = 2
  constant extensionHeaderLen (line 15) | extensionHeaderLen      int    = 4
  constant sniExtensionHeaderLen (line 16) | sniExtensionHeaderLen   int    = 5
  constant contentType (line 17) | contentType             uint8  = 22
  constant handshakeType (line 18) | handshakeType           uint8  = 1
  constant sniExtensionType (line 19) | sniExtensionType        uint16 = 0
  constant sniNameDNSHostnameType (line 20) | sniNameDNSHostnameType  uint8  = 0
  constant tlsVersionBitmask (line 21) | tlsVersionBitmask       uint16 = 0xFFFC
  constant tls13 (line 22) | tls13                   uint16 = 0x0304
  type MyServerName (line 25) | type MyServerName struct
  function IndexTLSServerName (line 31) | func IndexTLSServerName(payload []byte) *MyServerName {
  function indexTLSServerNameFromHandshake (line 47) | func indexTLSServerNameFromHandshake(handshake []byte) *MyServerName {
  function indexTLSServerNameFromExtensions (line 88) | func indexTLSServerNameFromExtensions(exs []byte) *MyServerName {

FILE: common/tlsfragment/index_test.go
  function TestIndexTLSServerName (line 12) | func TestIndexTLSServerName(t *testing.T) {

FILE: common/tlsfragment/wait_darwin.go
  function writeAndWaitAck (line 66) | func writeAndWaitAck(ctx context.Context, conn *net.TCPConn, payload []b...

FILE: common/tlsfragment/wait_linux.go
  function writeAndWaitAck (line 13) | func writeAndWaitAck(ctx context.Context, conn *net.TCPConn, payload []b...

FILE: common/tlsfragment/wait_stub.go
  function writeAndWaitAck (line 11) | func writeAndWaitAck(ctx context.Context, conn *net.TCPConn, payload []b...

FILE: common/tlsfragment/wait_windows.go
  function writeAndWaitAck (line 14) | func writeAndWaitAck(ctx context.Context, conn *net.TCPConn, payload []b...

FILE: common/uot/router.go
  type Router (line 18) | type Router struct
    method RouteConnection (line 27) | func (r *Router) RouteConnection(ctx context.Context, conn net.Conn, m...
    method RoutePacketConnection (line 51) | func (r *Router) RoutePacketConnection(ctx context.Context, conn N.Pac...
    method RouteConnectionEx (line 55) | func (r *Router) RouteConnectionEx(ctx context.Context, conn net.Conn,...
    method RoutePacketConnectionEx (line 84) | func (r *Router) RoutePacketConnectionEx(ctx context.Context, conn N.P...
  function NewRouter (line 23) | func NewRouter(router adapter.ConnectionRouterEx, logger logger.ContextL...

FILE: common/urltest/urltest.go
  type HistoryStorage (line 22) | type HistoryStorage struct
    method SetHook (line 34) | func (s *HistoryStorage) SetHook(hook *observable.Subscriber[struct{}]) {
    method LoadURLTestHistory (line 38) | func (s *HistoryStorage) LoadURLTestHistory(tag string) *adapter.URLTe...
    method DeleteURLTestHistory (line 47) | func (s *HistoryStorage) DeleteURLTestHistory(tag string) {
    method StoreURLTestHistory (line 54) | func (s *HistoryStorage) StoreURLTestHistory(tag string, history *adap...
    method notifyUpdated (line 61) | func (s *HistoryStorage) notifyUpdated() {
    method Close (line 68) | func (s *HistoryStorage) Close() error {
  function NewHistoryStorage (line 28) | func NewHistoryStorage() *HistoryStorage {
  function URLTest (line 75) | func URLTest(ctx context.Context, link string, detour N.Dialer) (t uint1...

FILE: constant/certificate.go
  constant CertificateStoreSystem (line 4) | CertificateStoreSystem  = "system"
  constant CertificateStoreMozilla (line 5) | CertificateStoreMozilla = "mozilla"
  constant CertificateStoreChrome (line 6) | CertificateStoreChrome  = "chrome"
  constant CertificateStoreNone (line 7) | CertificateStoreNone    = "none"

FILE: constant/cgo.go
  constant CGO_ENABLED (line 5) | CGO_ENABLED = true

FILE: constant/cgo_disabled.go
  constant CGO_ENABLED (line 5) | CGO_ENABLED = false

FILE: constant/dhcp.go
  constant DHCPTTL (line 6) | DHCPTTL     = time.Hour
  constant DHCPTimeout (line 7) | DHCPTimeout = 5 * time.Second

FILE: constant/dns.go
  constant DefaultDNSTTL (line 4) | DefaultDNSTTL = 600
  constant DomainStrategyAsIS (line 10) | DomainStrategyAsIS DomainStrategy = iota
  constant DomainStrategyPreferIPv4 (line 11) | DomainStrategyPreferIPv4
  constant DomainStrategyPreferIPv6 (line 12) | DomainStrategyPreferIPv6
  constant DomainStrategyIPv4Only (line 13) | DomainStrategyIPv4Only
  constant DomainStrategyIPv6Only (line 14) | DomainStrategyIPv6Only
  constant DNSTypeLegacy (line 18) | DNSTypeLegacy      = "legacy"
  constant DNSTypeLegacyRcode (line 19) | DNSTypeLegacyRcode = "legacy_rcode"
  constant DNSTypeUDP (line 20) | DNSTypeUDP         = "udp"
  constant DNSTypeTCP (line 21) | DNSTypeTCP         = "tcp"
  constant DNSTypeTLS (line 22) | DNSTypeTLS         = "tls"
  constant DNSTypeHTTPS (line 23) | DNSTypeHTTPS       = "https"
  constant DNSTypeQUIC (line 24) | DNSTypeQUIC        = "quic"
  constant DNSTypeHTTP3 (line 25) | DNSTypeHTTP3       = "h3"
  constant DNSTypeLocal (line 26) | DNSTypeLocal       = "local"
  constant DNSTypeHosts (line 27) | DNSTypeHosts       = "hosts"
  constant DNSTypeFakeIP (line 28) | DNSTypeFakeIP      = "fakeip"
  constant DNSTypeDHCP (line 29) | DNSTypeDHCP        = "dhcp"
  constant DNSTypeTailscale (line 30) | DNSTypeTailscale   = "tailscale"
  constant DNSProviderAliDNS (line 34) | DNSProviderAliDNS     = "alidns"
  constant DNSProviderCloudflare (line 35) | DNSProviderCloudflare = "cloudflare"
  constant DNSProviderACMEDNS (line 36) | DNSProviderACMEDNS    = "acmedns"

FILE: constant/goos/gengoos.go
  function main (line 20) | func main() {

FILE: constant/goos/zgoos_aix.go
  constant GOOS (line 7) | GOOS = `aix`
  constant IsAix (line 9) | IsAix = 1
  constant IsAndroid (line 10) | IsAndroid = 0
  constant IsDarwin (line 11) | IsDarwin = 0
  constant IsDragonfly (line 12) | IsDragonfly = 0
  constant IsFreebsd (line 13) | IsFreebsd = 0
  constant IsHurd (line 14) | IsHurd = 0
  constant IsIllumos (line 15) | IsIllumos = 0
  constant IsIos (line 16) | IsIos = 0
  constant IsJs (line 17) | IsJs = 0
  constant IsLinux (line 18) | IsLinux = 0
  constant IsNacl (line 19) | IsNacl = 0
  constant IsNetbsd (line 20) | IsNetbsd = 0
  constant IsOpenbsd (line 21) | IsOpenbsd = 0
  constant IsPlan9 (line 22) | IsPlan9 = 0
  constant IsSolaris (line 23) | IsSolaris = 0
  constant IsWindows (line 24) | IsWindows = 0
  constant IsZos (line 25) | IsZos = 0

FILE: constant/goos/zgoos_android.go
  constant GOOS (line 7) | GOOS = `android`
  constant IsAix (line 9) | IsAix = 0
  constant IsAndroid (line 10) | IsAndroid = 1
  constant IsDarwin (line 11) | IsDarwin = 0
  constant IsDragonfly (line 12) | IsDragonfly = 0
  constant IsFreebsd (line 13) | IsFreebsd = 0
  constant IsHurd (line 14) | IsHurd = 0
  constant IsIllumos (line 15) | IsIllumos = 0
  constant IsIos (line 16) | IsIos = 0
  constant IsJs (line 17) | IsJs = 0
  constant IsLinux (line 18) | IsLinux = 0
  constant IsNacl (line 19) | IsNacl = 0
  constant IsNetbsd (line 20) | IsNetbsd = 0
  constant IsOpenbsd (line 21) | IsOpenbsd = 0
  constant IsPlan9 (line 22) | IsPlan9 = 0
  constant IsSolaris (line 23) | IsSolaris = 0
  constant IsWindows (line 24) | IsWindows = 0
  constant IsZos (line 25) | IsZos = 0

FILE: constant/goos/zgoos_darwin.go
  constant GOOS (line 7) | GOOS = `darwin`
  constant IsAix (line 9) | IsAix = 0
  constant IsAndroid (line 10) | IsAndroid = 0
  constant IsDarwin (line 11) | IsDarwin = 1
  constant IsDragonfly (line 12) | IsDragonfly = 0
  constant IsFreebsd (line 13) | IsFreebsd = 0
  constant IsHurd (line 14) | IsHurd = 0
  constant IsIllumos (line 15) | IsIllumos = 0
  constant IsIos (line 16) | IsIos = 0
  constant IsJs (line 17) | IsJs = 0
  constant IsLinux (line 18) | IsLinux = 0
  constant IsNacl (line 19) | IsNacl = 0
  constant IsNetbsd (line 20) | IsNetbsd = 0
  constant IsOpenbsd (line 21) | IsOpenbsd = 0
  constant IsPlan9 (line 22) | IsPlan9 = 0
  constant IsSolaris (line 23) | IsSolaris = 0
  constant IsWindows (line 24) | IsWindows = 0
  constant IsZos (line 25) | IsZos = 0

FILE: constant/goos/zgoos_dragonfly.go
  constant GOOS (line 7) | GOOS = `dragonfly`
  constant IsAix (line 9) | IsAix = 0
  constant IsAndroid (line 10) | IsAndroid = 0
  constant IsDarwin (line 11) | IsDarwin = 0
  constant IsDragonfly (line 12) | IsDragonfly = 1
  constant IsFreebsd (line 13) | IsFreebsd = 0
  constant IsHurd (line 14) | IsHurd = 0
  constant IsIllumos (line 15) | IsIllumos = 0
  constant IsIos (line 16) | IsIos = 0
  constant IsJs (line 17) | IsJs = 0
  constant IsLinux (line 18) | IsLinux = 0
  constant IsNacl (line 19) | IsNacl = 0
  constant IsNetbsd (line 20) | IsNetbsd = 0
  constant IsOpenbsd (line 21) | IsOpenbsd = 0
  constant IsPlan9 (line 22) | IsPlan9 = 0
  constant IsSolaris (line 23) | IsSolaris = 0
  constant IsWindows (line 24) | IsWindows = 0
  constant IsZos (line 25) | IsZos = 0

FILE: constant/goos/zgoos_freebsd.go
  constant GOOS (line 7) | GOOS = `freebsd`
  constant IsAix (line 9) | IsAix = 0
  constant IsAndroid (line 10) | IsAndroid = 0
  constant IsDarwin (line 11) | IsDarwin = 0
  constant IsDragonfly (line 12) | IsDragonfly = 0
  constant IsFreebsd (line 13) | IsFreebsd = 1
  constant IsHurd (line 14) | IsHurd = 0
  constant IsIllumos (line 15) | IsIllumos = 0
  constant IsIos (line 16) | IsIos = 0
  constant IsJs (line 17) | IsJs = 0
  constant IsLinux (line 18) | IsLinux = 0
  constant IsNacl (line 19) | IsNacl = 0
  constant IsNetbsd (line 20) | IsNetbsd = 0
  constant IsOpenbsd (line 21) | IsOpenbsd = 0
  constant IsPlan9 (line 22) | IsPlan9 = 0
  constant IsSolaris (line 23) | IsSolaris = 0
  constant IsWindows (line 24) | IsWindows = 0
  constant IsZos (line 25) | IsZos = 0

FILE: constant/goos/zgoos_hurd.go
  constant GOOS (line 7) | GOOS = `hurd`
  constant IsAix (line 9) | IsAix = 0
  constant IsAndroid (line 10) | IsAndroid = 0
  constant IsDarwin (line 11) | IsDarwin = 0
  constant IsDragonfly (line 12) | IsDragonfly = 0
  constant IsFreebsd (line 13) | IsFreebsd = 0
  constant IsHurd (line 14) | IsHurd = 1
  constant IsIllumos (line 15) | IsIllumos = 0
  constant IsIos (line 16) | IsIos = 0
  constant IsJs (line 17) | IsJs = 0
  constant IsLinux (line 18) | IsLinux = 0
  constant IsNacl (line 19) | IsNacl = 0
  constant IsNetbsd (line 20) | IsNetbsd = 0
  constant IsOpenbsd (line 21) | IsOpenbsd = 0
  constant IsPlan9 (line 22) | IsPlan9 = 0
  constant IsSolaris (line 23) | IsSolaris = 0
  constant IsWindows (line 24) | IsWindows = 0
  constant IsZos (line 25) | IsZos = 0

FILE: constant/goos/zgoos_illumos.go
  constant GOOS (line 7) | GOOS = `illumos`
  constant IsAix (line 9) | IsAix = 0
  constant IsAndroid (line 10) | IsAndroid = 0
  constant IsDarwin (line 11) | IsDarwin = 0
  constant IsDragonfly (line 12) | IsDragonfly = 0
  constant IsFreebsd (line 13) | IsFreebsd = 0
  constant IsHurd (line 14) | IsHurd = 0
  constant IsIllumos (line 15) | IsIllumos = 1
  constant IsIos (line 16) | IsIos = 0
  constant IsJs (line 17) | IsJs = 0
  constant IsLinux (line 18) | IsLinux = 0
  constant IsNacl (line 19) | IsNacl = 0
  constant IsNetbsd (line 20) | IsNetbsd = 0
  constant IsOpenbsd (line 21) | IsOpenbsd = 0
  constant IsPlan9 (line 22) | IsPlan9 = 0
  constant IsSolaris (line 23) | IsSolaris = 0
  constant IsWindows (line 24) | IsWindows = 0
  constant IsZos (line 25) | IsZos = 0

FILE: constant/goos/zgoos_ios.go
  constant GOOS (line 7) | GOOS = `ios`
  constant IsAix (line 9) | IsAix = 0
  constant IsAndroid (line 10) | IsAndroid = 0
  constant IsDarwin (line 11) | IsDarwin = 0
  constant IsDragonfly (line 12) | IsDragonfly = 0
  constant IsFreebsd (line 13) | IsFreebsd = 0
  constant IsHurd (line 14) | IsHurd = 0
  constant IsIllumos (line 15) | IsIllumos = 0
  constant IsIos (line 16) | IsIos = 1
  constant IsJs (line 17) | IsJs = 0
  constant IsLinux (line 18) | IsLinux = 0
  constant IsNacl (line 19) | IsNacl = 0
  constant IsNetbsd (line 20) | IsNetbsd = 0
  constant IsOpenbsd (line 21) | IsOpenbsd = 0
  constant IsPlan9 (line 22) | IsPlan9 = 0
  constant IsSolaris (line 23) | IsSolaris = 0
  constant IsWindows (line 24) | IsWindows = 0
  constant IsZos (line 25) | IsZos = 0

FILE: constant/goos/zgoos_js.go
  constant GOOS (line 7) | GOOS = `js`
  constant IsAix (line 9) | IsAix = 0
  constant IsAndroid (line 10) | IsAndroid = 0
  constant IsDarwin (line 11) | IsDarwin = 0
  constant IsDragonfly (line 12) | IsDragonfly = 0
  constant IsFreebsd (line 13) | IsFreebsd = 0
  constant IsHurd (line 14) | IsHurd = 0
  constant IsIllumos (line 15) | IsIllumos = 0
  constant IsIos (line 16) | IsIos = 0
  constant IsJs (line 17) | IsJs = 1
  constant IsLinux (line 18) | IsLinux = 0
  constant IsNacl (line 19) | IsNacl = 0
  constant IsNetbsd (line 20) | IsNetbsd = 0
  constant IsOpenbsd (line 21) | IsOpenbsd = 0
  constant IsPlan9 (line 22) | IsPlan9 = 0
  constant IsSolaris (line 23) | IsSolaris = 0
  constant IsWindows (line 24) | IsWindows = 0
  constant IsZos (line 25) | IsZos = 0

FILE: constant/goos/zgoos_linux.go
  constant GOOS (line 7) | GOOS = `linux`
  constant IsAix (line 9) | IsAix = 0
  constant IsAndroid (line 10) | IsAndroid = 0
  constant IsDarwin (line 11) | IsDarwin = 0
  constant IsDragonfly (line 12) | IsDragonfly = 0
  constant IsFreebsd (line 13) | IsFreebsd = 0
  constant IsHurd (line 14) | IsHurd = 0
  constant IsIllumos (line 15) | IsIllumos = 0
  constant IsIos (line 16) | IsIos = 0
  constant IsJs (line 17) | IsJs = 0
  constant IsLinux (line 18) | IsLinux = 1
  constant IsNacl (line 19) | IsNacl = 0
  constant IsNetbsd (line 20) | IsNetbsd = 0
  constant IsOpenbsd (line 21) | IsOpenbsd = 0
  constant IsPlan9 (line 22) | IsPlan9 = 0
  constant IsSolaris (line 23) | IsSolaris = 0
  constant IsWindows (line 24) | IsWindows = 0
  constant IsZos (line 25) | IsZos = 0

FILE: constant/goos/zgoos_netbsd.go
  constant GOOS (line 7) | GOOS = `netbsd`
  constant IsAix (line 9) | IsAix = 0
  constant IsAndroid (line 10) | IsAndroid = 0
  constant IsDarwin (line 11) | IsDarwin = 0
  constant IsDragonfly (line 12) | IsDragonfly = 0
  constant IsFreebsd (line 13) | IsFreebsd = 0
  constant IsHurd (line 14) | IsHurd = 0
  constant IsIllumos (line 15) | IsIllumos = 0
  constant IsIos (line 16) | IsIos = 0
  constant IsJs (line 17) | IsJs = 0
  constant IsLinux (line 18) | IsLinux = 0
  constant IsNacl (line 19) | IsNacl = 0
  constant IsNetbsd (line 20) | IsNetbsd = 1
  constant IsOpenbsd (line 21) | IsOpenbsd = 0
  constant IsPlan9 (line 22) | IsPlan9 = 0
  constant IsSolaris (line 23) | IsSolaris = 0
  constant IsWindows (line 24) | IsWindows = 0
  constant IsZos (line 25) | IsZos = 0

FILE: constant/goos/zgoos_openbsd.go
  constant GOOS (line 7) | GOOS = `openbsd`
  constant IsAix (line 9) | IsAix = 0
  constant IsAndroid (line 10) | IsAndroid = 0
  constant IsDarwin (line 11) | IsDarwin = 0
  constant IsDragonfly (line 12) | IsDragonfly = 0
  constant IsFreebsd (line 13) | IsFreebsd = 0
  constant IsHurd (line 14) | IsHurd = 0
  constant IsIllumos (line 15) | IsIllumos = 0
  constant IsIos (line 16) | IsIos = 0
  constant IsJs (line 17) | IsJs = 0
  constant IsLinux (line 18) | IsLinux = 0
  constant IsNacl (line 19) | IsNacl = 0
  constant IsNetbsd (line 20) | IsNetbsd = 0
  constant IsOpenbsd (line 21) | IsOpenbsd = 1
  constant IsPlan9 (line 22) | IsPlan9 = 0
  constant IsSolaris (line 23) | IsSolaris = 0
  constant IsWindows (line 24) | IsWindows = 0
  constant IsZos (line 25) | IsZos = 0

FILE: constant/goos/zgoos_plan9.go
  constant GOOS (line 7) | GOOS = `plan9`
  constant IsAix (line 9) | IsAix = 0
  constant IsAndroid (line 10) | IsAndroid = 0
  constant IsDarwin (line 11) | IsDarwin = 0
  constant IsDragonfly (line 12) | IsDragonfly = 0
  constant IsFreebsd (line 13) | IsFreebsd = 0
  constant IsHurd (line 14) | IsHurd = 0
  constant IsIllumos (line 15) | IsIllumos = 0
  constant IsIos (line 16) | IsIos = 0
  constant IsJs (line 17) | IsJs = 0
  constant IsLinux (line 18) | IsLinux = 0
  constant IsNacl (line 19) | IsNacl = 0
  constant IsNetbsd (line 20) | IsNetbsd = 0
  constant IsOpenbsd (line 21) | IsOpenbsd = 0
  constant IsPlan9 (line 22) | IsPlan9 = 1
  constant IsSolaris (line 23) | IsSolaris = 0
  constant IsWindows (line 24) | IsWindows = 0
  constant IsZos (line 25) | IsZos = 0

FILE: constant/goos/zgoos_solaris.go
  constant GOOS (line 7) | GOOS = `solaris`
  constant IsAix (line 9) | IsAix = 0
  constant IsAndroid (line 10) | IsAndroid = 0
  constant IsDarwin (line 11) | IsDarwin = 0
  constant IsDragonfly (line 12) | IsDragonfly = 0
  constant IsFreebsd (line 13) | IsFreebsd = 0
  constant IsHurd (line 14) | IsHurd = 0
  constant IsIllumos (line 15) | IsIllumos = 0
  constant IsIos (line 16) | IsIos = 0
  constant IsJs (line 17) | IsJs = 0
  constant IsLinux (line 18) | IsLinux = 0
  constant IsNacl (line 19) | IsNacl = 0
  constant IsNetbsd (line 20) | IsNetbsd = 0
  constant IsOpenbsd (line 21) | IsOpenbsd = 0
  constant IsPlan9 (line 22) | IsPlan9 = 0
  constant IsSolaris (line 23) | IsSolaris = 1
  constant IsWindows (line 24) | IsWindows = 0
  constant IsZos (line 25) | IsZos = 0

FILE: constant/goos/zgoos_windows.go
  constant GOOS (line 7) | GOOS = `windows`
  constant IsAix (line 9) | IsAix = 0
  constant IsAndroid (line 10) | IsAndroid = 0
  constant IsDarwin (line 11) | IsDarwin = 0
  constant IsDragonfly (line 12) | IsDragonfly = 0
  constant IsFreebsd (line 13) | IsFreebsd = 0
  constant IsHurd (line 14) | IsHurd = 0
  constant IsIllumos (line 15) | IsIllumos = 0
  constant IsIos (line 16) | IsIos = 0
  constant IsJs (line 17) | IsJs = 0
  constant IsLinux (line 18) | IsLinux = 0
  constant IsNacl (line 19) | IsNacl = 0
  constant IsNetbsd (line 20) | IsNetbsd = 0
  constant IsOpenbsd (line 21) | IsOpenbsd = 0
  constant IsPlan9 (line 22) | IsPlan9 = 0
  constant IsSolaris (line 23) | IsSolaris = 0
  constant IsWindows (line 24) | IsWindows = 1
  constant IsZos (line 25) | IsZos = 0

FILE: constant/goos/zgoos_zos.go
  constant GOOS (line 7) | GOOS = `zos`
  constant IsAix (line 9) | IsAix = 0
  constant IsAndroid (line 10) | IsAndroid = 0
  constant IsDarwin (line 11) | IsDarwin = 0
  constant IsDragonfly (line 12) | IsDragonfly = 0
  constant IsFreebsd (line 13) | IsFreebsd = 0
  constant IsHurd (line 14) | IsHurd = 0
  constant IsIllumos (line 15) | IsIllumos = 0
  constant IsIos (line 16) | IsIos = 0
  constant IsJs (line 17) | IsJs = 0
  constant IsLinux (line 18) | IsLinux = 0
  constant IsNacl (line 19) | IsNacl = 0
  constant IsNetbsd (line 20) | IsNetbsd = 0
  constant IsOpenbsd (line 21) | IsOpenbsd = 0
  constant IsPlan9 (line 22) | IsPlan9 = 0
  constant IsSolaris (line 23) | IsSolaris = 0
  constant IsWindows (line 24) | IsWindows = 0
  constant IsZos (line 25) | IsZos = 1

FILE: constant/hysteria2.go
  constant Hysterai2MasqueradeTypeFile (line 4) | Hysterai2MasqueradeTypeFile   = "file"
  constant Hysterai2MasqueradeTypeProxy (line 5) | Hysterai2MasqueradeTypeProxy  = "proxy"
  constant Hysterai2MasqueradeTypeString (line 6) | Hysterai2MasqueradeTypeString = "string"

FILE: constant/network.go
  type InterfaceType (line 8) | type InterfaceType
    method String (line 27) | func (t InterfaceType) String() string {
  constant InterfaceTypeWIFI (line 11) | InterfaceTypeWIFI InterfaceType = iota
  constant InterfaceTypeCellular (line 12) | InterfaceTypeCellular
  constant InterfaceTypeEthernet (line 13) | InterfaceTypeEthernet
  constant InterfaceTypeOther (line 14) | InterfaceTypeOther
  type NetworkStrategy (line 35) | type NetworkStrategy
    method String (line 52) | func (s NetworkStrategy) String() string {
  constant NetworkStrategyDefault (line 38) | NetworkStrategyDefault NetworkStrategy = iota
  constant NetworkStrategyFallback (line 39) | NetworkStrategyFallback
  constant NetworkStrategyHybrid (line 40) | NetworkStrategyHybrid

FILE: constant/os.go
  constant IsAndroid (line 7) | IsAndroid = goos.IsAndroid == 1
  constant IsDarwin (line 9) | IsDarwin = goos.IsDarwin == 1 || goos.IsIos == 1
  constant IsDragonfly (line 11) | IsDragonfly = goos.IsDragonfly == 1
  constant IsFreebsd (line 13) | IsFreebsd = goos.IsFreebsd == 1
  constant IsHurd (line 15) | IsHurd = goos.IsHurd == 1
  constant IsIllumos (line 17) | IsIllumos = goos.IsIllumos == 1
  constant IsIos (line 19) | IsIos = goos.IsIos == 1
  constant IsJs (line 21) | IsJs = goos.IsJs == 1
  constant IsLinux (line 23) | IsLinux = goos.IsLinux == 1 || goos.IsAndroid == 1
  constant IsNacl (line 25) | IsNacl = goos.IsNacl == 1
  constant IsNetbsd (line 27) | IsNetbsd = goos.IsNetbsd == 1
  constant IsOpenbsd (line 29) | IsOpenbsd = goos.IsOpenbsd == 1
  constant IsPlan9 (line 31) | IsPlan9 = goos.IsPlan9 == 1
  constant IsSolaris (line 33) | IsSolaris = goos.IsSolaris == 1
  constant IsWindows (line 35) | IsWindows = goos.IsWindows == 1
  constant IsZos (line 37) | IsZos = goos.IsZos == 1

FILE: constant/path.go
  constant dirName (line 10) | dirName = "sing-box"
  function FindPath (line 14) | func FindPath(name string) (string, bool) {
  function init (line 30) | func init() {

FILE: constant/path_unix.go
  function init (line 9) | func init() {

FILE: constant/protocol.go
  constant ProtocolTLS (line 4) | ProtocolTLS        = "tls"
  constant ProtocolHTTP (line 5) | ProtocolHTTP       = "http"
  constant ProtocolQUIC (line 6) | ProtocolQUIC       = "quic"
  constant ProtocolDNS (line 7) | ProtocolDNS        = "dns"
  constant ProtocolSTUN (line 8) | ProtocolSTUN       = "stun"
  constant ProtocolBitTorrent (line 9) | ProtocolBitTorrent = "bittorrent"
  constant ProtocolDTLS (line 10) | ProtocolDTLS       = "dtls"
  constant ProtocolSSH (line 11) | ProtocolSSH        = "ssh"
  constant ProtocolRDP (line 12) | ProtocolRDP        = "rdp"
  constant ProtocolNTP (line 13) | ProtocolNTP        = "ntp"
  constant ClientChromium (line 17) | ClientChromium = "chromium"
  constant ClientSafari (line 18) | ClientSafari   = "safari"
  constant ClientFirefox (line 19) | ClientFirefox  = "firefox"
  constant ClientQUICGo (line 20) | ClientQUICGo   = "quic-go"
  constant ClientUnknown (line 21) | ClientUnknown  = "unknown"

FILE: constant/proxy.go
  constant TypeTun (line 4) | TypeTun          = "tun"
  constant TypeRedirect (line 5) | TypeRedirect     = "redirect"
  constant TypeTProxy (line 6) | TypeTProxy       = "tproxy"
  constant TypeDirect (line 7) | TypeDirect       = "direct"
  constant TypeBlock (line 8) | TypeBlock        = "block"
  constant TypeDNS (line 9) | TypeDNS          = "dns"
  constant TypeSOCKS (line 10) | TypeSOCKS        = "socks"
  constant TypeHTTP (line 11) | TypeHTTP         = "http"
  constant TypeMixed (line 12) | TypeMixed        = "mixed"
  constant TypeShadowsocks (line 13) | TypeShadowsocks  = "shadowsocks"
  constant TypeVMess (line 14) | TypeVMess        = "vmess"
  constant TypeTrojan (line 15) | TypeTrojan       = "trojan"
  constant TypeNaive (line 16) | TypeNaive        = "naive"
  constant TypeWireGuard (line 17) | TypeWireGuard    = "wireguard"
  constant TypeHysteria (line 18) | TypeHysteria     = "hysteria"
  constant TypeTor (line 19) | TypeTor          = "tor"
  constant TypeSSH (line 20) | TypeSSH          = "ssh"
  constant TypeShadowTLS (line 21) | TypeShadowTLS    = "shadowtls"
  constant TypeAnyTLS (line 22) | TypeAnyTLS       = "anytls"
  constant TypeShadowsocksR (line 23) | TypeShadowsocksR = "shadowsocksr"
  constant TypeVLESS (line 24) | TypeVLESS        = "vless"
  constant TypeTUIC (line 25) | TypeTUIC         = "tuic"
  constant TypeHysteria2 (line 26) | TypeHysteria2    = "hysteria2"
  constant TypeTailscale (line 27) | TypeTailscale    = "tailscale"
  constant TypeDERP (line 28) | TypeDERP         = "derp"
  constant TypeResolved (line 29) | TypeResolved     = "resolved"
  constant TypeSSMAPI (line 30) | TypeSSMAPI       = "ssm-api"
  constant TypeCCM (line 31) | TypeCCM          = "ccm"
  constant TypeOCM (line 32) | TypeOCM          = "ocm"
  constant TypeOOMKiller (line 33) | TypeOOMKiller    = "oom-killer"
  constant TypeSelector (line 37) | TypeSelector = "selector"
  constant TypeURLTest (line 38) | TypeURLTest  = "urltest"
  function ProxyDisplayName (line 41) | func ProxyDisplayName(proxyType string) string {

FILE: constant/quic.go
  constant WithQUIC (line 5) | WithQUIC = true

FILE: constant/quic_stub.go
  constant WithQUIC (line 5) | WithQUIC = false

FILE: constant/rule.go
  constant RuleTypeDefault (line 4) | RuleTypeDefault = "default"
  constant RuleTypeLogical (line 5) | RuleTypeLogical = "logical"
  constant LogicalTypeAnd (line 9) | LogicalTypeAnd = "and"
  constant LogicalTypeOr (line 10) | LogicalTypeOr  = "or"
  constant RuleSetTypeInline (line 14) | RuleSetTypeInline   = "inline"
  constant RuleSetTypeLocal (line 15) | RuleSetTypeLocal    = "local"
  constant RuleSetTypeRemote (line 16) | RuleSetTypeRemote   = "remote"
  constant RuleSetFormatSource (line 17) | RuleSetFormatSource = "source"
  constant RuleSetFormatBinary (line 18) | RuleSetFormatBinary = "binary"
  constant RuleSetVersion1 (line 22) | RuleSetVersion1 = 1 + iota
  constant RuleSetVersion2 (line 23) | RuleSetVersion2
  constant RuleSetVersion3 (line 24) | RuleSetVersion3
  constant RuleSetVersion4 (line 25) | RuleSetVersion4
  constant RuleSetVersionCurrent (line 26) | RuleSetVersionCurrent = RuleSetVersion4
  constant RuleActionTypeRoute (line 30) | RuleActionTypeRoute        = "route"
  constant RuleActionTypeRouteOptions (line 31) | RuleActionTypeRouteOptions = "route-options"
  constant RuleActionTypeDirect (line 32) | RuleActionTypeDirect       = "direct"
  constant RuleActionTypeBypass (line 33) | RuleActionTypeBypass       = "bypass"
  constant RuleActionTypeReject (line 34) | RuleActionTypeReject       = "reject"
  constant RuleActionTypeHijackDNS (line 35) | RuleActionTypeHijackDNS    = "hijack-dns"
  constant RuleActionTypeSniff (line 36) | RuleActionTypeSniff        = "sniff"
  constant RuleActionTypeResolve (line 37) | RuleActionTypeResolve      = "resolve"
  constant RuleActionTypePredefined (line 38) | RuleActionTypePredefined   = "predefined"
  constant RuleActionRejectMethodDefault (line 42) | RuleActionRejectMethodDefault = "default"
  constant RuleActionRejectMethodDrop (line 43) | RuleActionRejectMethodDrop    = "drop"
  constant RuleActionRejectMethodReply (line 44) | RuleActionRejectMethodReply   = "reply"

FILE: constant/speed.go
  constant MbpsToBps (line 3) | MbpsToBps = 125000

FILE: constant/time.go
  constant TimeLayout (line 3) | TimeLayout = "2006-01-02 15:04:05 -0700"

FILE: constant/timeout.go
  constant TCPKeepAliveInitial (line 6) | TCPKeepAliveInitial        = 5 * time.Minute
  constant TCPKeepAliveInterval (line 7) | TCPKeepAliveInterval       = 75 * time.Second
  constant TCPConnectTimeout (line 8) | TCPConnectTimeout          = 5 * time.Second
  constant TCPTimeout (line 9) | TCPTimeout                 = 15 * time.Second
  constant ReadPayloadTimeout (line 10) | ReadPayloadTimeout         = 300 * time.Millisecond
  constant DNSTimeout (line 11) | DNSTimeout                 = 10 * time.Second
  constant UDPTimeout (line 12) | UDPTimeout                 = 5 * time.Minute
  constant DefaultURLTestInterval (line 13) | DefaultURLTestInterval     = 3 * time.Minute
  constant DefaultURLTestIdleTimeout (line 14) | DefaultURLTestIdleTimeout  = 30 * time.Minute
  constant StartTimeout (line 15) | StartTimeout               = 10 * time.Second
  constant StopTimeout (line 16) | StopTimeout                = 5 * time.Second
  constant FatalStopTimeout (line 17) | FatalStopTimeout           = 10 * time.Second
  constant FakeIPMetadataSaveInterval (line 18) | FakeIPMetadataSaveInterval = 10 * time.Second
  constant TLSFragmentFallbackDelay (line 19) | TLSFragmentFallbackDelay   = 500 * time.Millisecond

FILE: constant/v2ray.go
  constant V2RayTransportTypeHTTP (line 4) | V2RayTransportTypeHTTP        = "http"
  constant V2RayTransportTypeWebsocket (line 5) | V2RayTransportTypeWebsocket   = "ws"
  constant V2RayTransportTypeQUIC (line 6) | V2RayTransportTypeQUIC        = "quic"
  constant V2RayTransportTypeGRPC (line 7) | V2RayTransportTypeGRPC        = "grpc"
  constant V2RayTransportTypeHTTPUpgrade (line 8) | V2RayTransportTypeHTTPUpgrade = "httpupgrade"

FILE: daemon/deprecated.go
  type deprecatedManager (line 12) | type deprecatedManager struct
    method ReportDeprecated (line 17) | func (m *deprecatedManager) ReportDeprecated(feature deprecated.Note) {
    method Get (line 23) | func (m *deprecatedManager) Get() []deprecated.Note {

FILE: daemon/instance.go
  type Instance (line 22) | type Instance struct
    method Start (line 124) | func (i *Instance) Start() error {
    method Close (line 128) | func (i *Instance) Close() error {
    method Box (line 134) | func (i *Instance) Box() *box.Box {
    method PauseManager (line 138) | func (i *Instance) PauseManager() pause.Manager {
  method CheckConfig (line 33) | func (s *StartedService) CheckConfig(configContent string) error {
  method FormatConfig (line 50) | func (s *StartedService) FormatConfig(configContent string) (string, err...
  type OverrideOptions (line 65) | type OverrideOptions struct
  method newInstance (line 71) | func (s *StartedService) newInstance(profileContent string, overrideOpti...
  function parseConfig (line 142) | func parseConfig(ctx context.Context, configContent string) (option.Opti...

FILE: daemon/platform.go
  type PlatformHandler (line 3) | type PlatformHandler interface

FILE: daemon/started_service.go
  type StartedService (line 32) | type StartedService struct
    method resetLogs (line 107) | func (s *StartedService) resetLogs() {
    method updateStatus (line 114) | func (s *StartedService) updateStatus(newStatus ServiceStatus_Type) {
    method updateStatusError (line 120) | func (s *StartedService) updateStatusError(err error) error {
    method waitForStarted (line 128) | func (s *StartedService) waitForStarted(ctx context.Context) error {
    method StartOrReloadService (line 168) | func (s *StartedService) StartOrReloadService(profileContent string, o...
    method Close (line 212) | func (s *StartedService) Close() {
    method CloseService (line 220) | func (s *StartedService) CloseService() error {
    method SetError (line 243) | func (s *StartedService) SetError(err error) {
    method StopService (line 249) | func (s *StartedService) StopService(ctx context.Context, empty *empty...
    method ReloadService (line 257) | func (s *StartedService) ReloadService(ctx context.Context, empty *emp...
    method SubscribeServiceStatus (line 265) | func (s *StartedService) SubscribeServiceStatus(empty *emptypb.Empty, ...
    method SubscribeLog (line 292) | func (s *StartedService) SubscribeLog(empty *emptypb.Empty, server grp...
    method GetDefaultLogLevel (line 360) | func (s *StartedService) GetDefaultLogLevel(ctx context.Context, empty...
    method ClearLogs (line 373) | func (s *StartedService) ClearLogs(ctx context.Context, empty *emptypb...
    method SubscribeStatus (line 378) | func (s *StartedService) SubscribeStatus(request *SubscribeStatusReque...
    method readStatus (line 410) | func (s *StartedService) readStatus() *Status {
    method SubscribeGroups (line 431) | func (s *StartedService) SubscribeGroups(empty *emptypb.Empty, server ...
    method readGroups (line 465) | func (s *StartedService) readGroups() *Groups {
    method GetClashModeStatus (line 511) | func (s *StartedService) GetClashModeStatus(ctx context.Context, empty...
    method SubscribeClashMode (line 528) | func (s *StartedService) SubscribeClashMode(empty *emptypb.Empty, serv...
    method SetClashMode (line 562) | func (s *StartedService) SetClashMode(ctx context.Context, request *Cl...
    method URLTest (line 574) | func (s *StartedService) URLTest(ctx context.Context, request *URLTest...
    method SelectOutbound (line 631) | func (s *StartedService) SelectOutbound(ctx context.Context, request *...
    method SetGroupExpand (line 656) | func (s *StartedService) SetGroupExpand(ctx context.Context, request *...
    method GetSystemProxyStatus (line 675) | func (s *StartedService) GetSystemProxyStatus(ctx context.Context, emp...
    method SetSystemProxyEnabled (line 679) | func (s *StartedService) SetSystemProxyEnabled(ctx context.Context, re...
    method SubscribeConnections (line 687) | func (s *StartedService) SubscribeConnections(request *SubscribeConnec...
    method buildInitialConnectionState (line 776) | func (s *StartedService) buildInitialConnectionState(manager *traffico...
    method applyConnectionEvent (line 804) | func (s *StartedService) applyConnectionEvent(event trafficontrol.Conn...
    method buildTrafficUpdates (line 844) | func (s *StartedService) buildTrafficUpdates(manager *trafficontrol.Ma...
    method CloseConnection (line 982) | func (s *StartedService) CloseConnection(ctx context.Context, request ...
    method CloseAllConnections (line 999) | func (s *StartedService) CloseAllConnections(ctx context.Context, empt...
    method GetDeprecatedWarnings (line 1009) | func (s *StartedService) GetDeprecatedWarnings(ctx context.Context, em...
    method GetStartedAt (line 1029) | func (s *StartedService) GetStartedAt(ctx context.Context, empty *empt...
    method mustEmbedUnimplementedStartedServiceServer (line 1035) | func (s *StartedService) mustEmbedUnimplementedStartedServiceServer() {
    method WriteMessage (line 1038) | func (s *StartedService) WriteMessage(level log.Level, message string) {
    method Instance (line 1052) | func (s *StartedService) Instance() *Instance {
  type ServiceOptions (line 64) | type ServiceOptions struct
  function NewStartedService (line 78) | func NewStartedService(options ServiceOptions) *StartedService {
  type connectionSnapshot (line 770) | type connectionSnapshot struct
  function buildConnectionProto (line 942) | func buildConnectionProto(metadata *trafficontrol.TrackerMetadata) *Conn...

FILE: daemon/started_service.pb.go
  constant _ (line 15) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 17) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  type LogLevel (line 20) | type LogLevel
    method Enum (line 54) | func (x LogLevel) Enum() *LogLevel {
    method String (line 60) | func (x LogLevel) String() string {
    method Descriptor (line 64) | func (LogLevel) Descriptor() protoreflect.EnumDescriptor {
    method Type (line 68) | func (LogLevel) Type() protoreflect.EnumType {
    method Number (line 72) | func (x LogLevel) Number() protoreflect.EnumNumber {
    method EnumDescriptor (line 77) | func (LogLevel) EnumDescriptor() ([]byte, []int) {
  constant LogLevel_PANIC (line 23) | LogLevel_PANIC LogLevel = 0
  constant LogLevel_FATAL (line 24) | LogLevel_FATAL LogLevel = 1
  constant LogLevel_ERROR (line 25) | LogLevel_ERROR LogLevel = 2
  constant LogLevel_WARN (line 26) | LogLevel_WARN  LogLevel = 3
  constant LogLevel_INFO (line 27) | LogLevel_INFO  LogLevel = 4
  constant LogLevel_DEBUG (line 28) | LogLevel_DEBUG LogLevel = 5
  constant LogLevel_TRACE (line 29) | LogLevel_TRACE LogLevel = 6
  type ConnectionEventType (line 81) | type ConnectionEventType
    method Enum (line 103) | func (x ConnectionEventType) Enum() *ConnectionEventType {
    method String (line 109) | func (x ConnectionEventType) String() string {
    method Descriptor (line 113) | func (ConnectionEventType) Descriptor() protoreflect.EnumDescriptor {
    method Type (line 117) | func (ConnectionEventType) Type() protoreflect.EnumType {
    method Number (line 121) | func (x ConnectionEventType) Number() protoreflect.EnumNumber {
    method EnumDescriptor (line 126) | func (ConnectionEventType) EnumDescriptor() ([]byte, []int) {
  constant ConnectionEventType_CONNECTION_EVENT_NEW (line 84) | ConnectionEventType_CONNECTION_EVENT_NEW    ConnectionEventType = 0
  constant ConnectionEventType_CONNECTION_EVENT_UPDATE (line 85) | ConnectionEventType_CONNECTION_EVENT_UPDATE ConnectionEventType = 1
  constant ConnectionEventType_CONNECTION_EVENT_CLOSED (line 86) | ConnectionEventType_CONNECTION_EVENT_CLOSED ConnectionEventType = 2
  type ServiceStatus_Type (line 130) | type ServiceStatus_Type
    method Enum (line 158) | func (x ServiceStatus_Type) Enum() *ServiceStatus_Type {
    method String (line 164) | func (x ServiceStatus_Type) String() string {
    method Descriptor (line 168) | func (ServiceStatus_Type) Descriptor() protoreflect.EnumDescriptor {
    method Type (line 172) | func (ServiceStatus_Type) Type() protoreflect.EnumType {
    method Number (line 176) | func (x ServiceStatus_Type) Number() protoreflect.EnumNumber {
    method EnumDescriptor (line 181) | func (ServiceStatus_Type) EnumDescriptor() ([]byte, []int) {
  constant ServiceStatus_IDLE (line 133) | ServiceStatus_IDLE     ServiceStatus_Type = 0
  constant ServiceStatus_STARTING (line 134) | ServiceStatus_STARTING ServiceStatus_Type = 1
  constant ServiceStatus_STARTED (line 135) | ServiceStatus_STARTED  ServiceStatus_Type = 2
  constant ServiceStatus_STOPPING (line 136) | ServiceStatus_STOPPING ServiceStatus_Type = 3
  constant ServiceStatus_FATAL (line 137) | ServiceStatus_FATAL    ServiceStatus_Type = 4
  type ServiceStatus (line 185) | type ServiceStatus struct
    method Reset (line 193) | func (x *ServiceStatus) Reset() {
    method String (line 200) | func (x *ServiceStatus) String() string {
    method ProtoMessage (line 204) | func (*ServiceStatus) ProtoMessage() {}
    method ProtoReflect (line 206) | func (x *ServiceStatus) ProtoReflect() protoreflect.Message {
    method Descriptor (line 219) | func (*ServiceStatus) Descriptor() ([]byte, []int) {
    method GetStatus (line 223) | func (x *ServiceStatus) GetStatus() ServiceStatus_Type {
    method GetErrorMessage (line 230) | func (x *ServiceStatus) GetErrorMessage() string {
  type ReloadServiceRequest (line 237) | type ReloadServiceRequest struct
    method Reset (line 244) | func (x *ReloadServiceRequest) Reset() {
    method String (line 251) | func (x *ReloadServiceRequest) String() string {
    method ProtoMessage (line 255) | func (*ReloadServiceRequest) ProtoMessage() {}
    method ProtoReflect (line 257) | func (x *ReloadServiceRequest) ProtoReflect() protoreflect.Message {
    method Descriptor (line 270) | func (*ReloadServiceRequest) Descriptor() ([]byte, []int) {
    method GetNewProfileContent (line 274) | func (x *ReloadServiceRequest) GetNewProfileContent() string {
  type SubscribeStatusRequest (line 281) | type SubscribeStatusRequest struct
    method Reset (line 288) | func (x *SubscribeStatusRequest) Reset() {
    method String (line 295) | func (x *SubscribeStatusRequest) String() string {
    method ProtoMessage (line 299) | func (*SubscribeStatusRequest) ProtoMessage() {}
    method ProtoReflect (line 301) | func (x *SubscribeStatusRequest) ProtoReflect() protoreflect.Message {
    method Descriptor (line 314) | func (*SubscribeStatusRequest) Descriptor() ([]byte, []int) {
    method GetInterval (line 318) | func (x *SubscribeStatusRequest) GetInterval() int64 {
  type Log (line 325) | type Log struct
    method Reset (line 333) | func (x *Log) Reset() {
    method String (line 340) | func (x *Log) String() string {
    method ProtoMessage (line 344) | func (*Log) ProtoMessage() {}
    method ProtoReflect (line 346) | func (x *Log) ProtoReflect() protoreflect.Message {
    method Descriptor (line 359) | func (*Log) Descriptor() ([]byte, []int) {
    method GetMessages (line 363) | func (x *Log) GetMessages() []*Log_Message {
    method GetReset_ (line 370) | func (x *Log) GetReset_() bool {
  type DefaultLogLevel (line 377) | type DefaultLogLevel struct
    method Reset (line 384) | func (x *DefaultLogLevel) Reset() {
    method String (line 391) | func (x *DefaultLogLevel) String() string {
    method ProtoMessage (line 395) | func (*DefaultLogLevel) ProtoMessage() {}
    method ProtoReflect (line 397) | func (x *DefaultLogLevel) ProtoReflect() protoreflect.Message {
    method Descriptor (line 410) | func (*DefaultLogLevel) Descriptor() ([]byte, []int) {
    method GetLevel (line 414) | func (x *DefaultLogLevel) GetLevel() LogLevel {
  type Status (line 421) | type Status struct
    method Reset (line 436) | func (x *Status) Reset() {
    method String (line 443) | func (x *Status) String() string {
    method ProtoMessage (line 447) | func (*Status) ProtoMessage() {}
    method ProtoReflect (line 449) | func (x *Status) ProtoReflect() protoreflect.Message {
    method Descriptor (line 462) | func (*Status) Descriptor() ([]byte, []int) {
    method GetMemory (line 466) | func (x *Status) GetMemory() uint64 {
    method GetGoroutines (line 473) | func (x *Status) GetGoroutines() int32 {
    method GetConnectionsIn (line 480) | func (x *Status) GetConnectionsIn() int32 {
    method GetConnectionsOut (line 487) | func (x *Status) GetConnectionsOut() int32 {
    method GetTrafficAvailable (line 494) | func (x *Status) GetTrafficAvailable() bool {
    method GetUplink (line 501) | func (x *Status) GetUplink() int64 {
    method GetDownlink (line 508) | func (x *Status) GetDownlink() int64 {
    method GetUplinkTotal (line 515) | func (x *Status) GetUplinkTotal() int64 {
    method GetDownlinkTotal (line 522) | func (x *Status) GetDownlinkTotal() int64 {
  type Groups (line 529) | type Groups struct
    method Reset (line 536) | func (x *Groups) Reset() {
    method String (line 543) | func (x *Groups) String() string {
    method ProtoMessage (line 547) | func (*Groups) ProtoMessage() {}
    method ProtoReflect (line 549) | func (x *Groups) ProtoReflect() protoreflect.Message {
    method Descriptor (line 562) | func (*Groups) Descriptor() ([]byte, []int) {
    method GetGroup (line 566) | func (x *Groups) GetGroup() []*Group {
  type Group (line 573) | type Group struct
    method Reset (line 585) | func (x *Group) Reset() {
    method String (line 592) | func (x *Group) String() string {
    method ProtoMessage (line 596) | func (*Group) ProtoMessage() {}
    method ProtoReflect (line 598) | func (x *Group) ProtoReflect() protoreflect.Message {
    method Descriptor (line 611) | func (*Group) Descriptor() ([]byte, []int) {
    method GetTag (line 615) | func (x *Group) GetTag() string {
    method GetType (line 622) | func (x *Group) GetType() string {
    method GetSelectable (line 629) | func (x *Group) GetSelectable() bool {
    method GetSelected (line 636) | func (x *Group) GetSelected() string {
    method GetIsExpand (line 643) | func (x *Group) GetIsExpand() bool {
    method GetItems (line 650) | func (x *Group) GetItems() []*GroupItem {
  type GroupItem (line 657) | type GroupItem struct
    method Reset (line 667) | func (x *GroupItem) Reset() {
    method String (line 674) | func (x *GroupItem) String() string {
    method ProtoMessage (line 678) | func (*GroupItem) ProtoMessage() {}
    method ProtoReflect (line 680) | func (x *GroupItem) ProtoReflect() protoreflect.Message {
    method Descriptor (line 693) | func (*GroupItem) Descriptor() ([]byte, []int) {
    method GetTag (line 697) | func (x *GroupItem) GetTag() string {
    method GetType (line 704) | func (x *GroupItem) GetType() string {
    method GetUrlTestTime (line 711) | func (x *GroupItem) GetUrlTestTime() int64 {
    method GetUrlTestDelay (line 718) | func (x *GroupItem) GetUrlTestDelay() int32 {
  type URLTestRequest (line 725) | type URLTestRequest struct
    method Reset (line 732) | func (x *URLTestRequest) Reset() {
    method String (line 739) | func (x *URLTestRequest) String() string {
    method ProtoMessage (line 743) | func (*URLTestRequest) ProtoMessage() {}
    method ProtoReflect (line 745) | func (x *URLTestRequest) ProtoReflect() protoreflect.Message {
    method Descriptor (line 758) | func (*URLTestRequest) Descriptor() ([]byte, []int) {
    method GetOutboundTag (line 762) | func (x *URLTestRequest) GetOutboundTag() string {
  type SelectOutboundRequest (line 769) | type SelectOutboundRequest struct
    method Reset (line 777) | func (x *SelectOutboundRequest) Reset() {
    method String (line 784) | func (x *SelectOutboundRequest) String() string {
    method ProtoMessage (line 788) | func (*SelectOutboundRequest) ProtoMessage() {}
    method ProtoReflect (line 790) | func (x *SelectOutboundRequest) ProtoReflect() protoreflect.Message {
    method Descriptor (line 803) | func (*SelectOutboundRequest) Descriptor() ([]byte, []int) {
    method GetGroupTag (line 807) | func (x *SelectOutboundRequest) GetGroupTag() string {
    method GetOutboundTag (line 814) | func (x *SelectOutboundRequest) GetOutboundTag() string {
  type SetGroupExpandRequest (line 821) | type SetGroupExpandRequest struct
    method Reset (line 829) | func (x *SetGroupExpandRequest) Reset() {
    method String (line 836) | func (x *SetGroupExpandRequest) String() string {
    method ProtoMessage (line 840) | func (*SetGroupExpandRequest) ProtoMessage() {}
    method ProtoReflect (line 842) | func (x *SetGroupExpandRequest) ProtoReflect() protoreflect.Message {
    method Descriptor (line 855) | func (*SetGroupExpandRequest) Descriptor() ([]byte, []int) {
    method GetGroupTag (line 859) | func (x *SetGroupExpandRequest) GetGroupTag() string {
    method GetIsExpand (line 866) | func (x *SetGroupExpandRequest) GetIsExpand() bool {
  type ClashMode (line 873) | type ClashMode struct
    method Reset (line 880) | func (x *ClashMode) Reset() {
    method String (line 887) | func (x *ClashMode) String() string {
    method ProtoMessage (line 891) | func (*ClashMode) ProtoMessage() {}
    method ProtoReflect (line 893) | func (x *ClashMode) ProtoReflect() protoreflect.Message {
    method Descriptor (line 906) | func (*ClashMode) Descriptor() ([]byte, []int) {
    method GetMode (line 910) | func (x *ClashMode) GetMode() string {
  type ClashModeStatus (line 917) | type ClashModeStatus struct
    method Reset (line 925) | func (x *ClashModeStatus) Reset() {
    method String (line 932) | func (x *ClashModeStatus) String() string {
    method ProtoMessage (line 936) | func (*ClashModeStatus) ProtoMessage() {}
    method ProtoReflect (line 938) | func (x *ClashModeStatus) ProtoReflect() protoreflect.Message {
    method Descriptor (line 951) | func (*ClashModeStatus) Descriptor() ([]byte, []int) {
    method GetModeList (line 955) | func (x *ClashModeStatus) GetModeList() []string {
    method GetCurrentMode (line 962) | func (x *ClashModeStatus) GetCurrentMode() string {
  type SystemProxyStatus (line 969) | type SystemProxyStatus struct
    method Reset (line 977) | func (x *SystemProxyStatus) Reset() {
    method String (line 984) | func (x *SystemProxyStatus) String() string {
    method ProtoMessage (line 988) | func (*SystemProxyStatus) ProtoMessage() {}
    method ProtoReflect (line 990) | func (x *SystemProxyStatus) ProtoReflect() protoreflect.Message {
    method Descriptor (line 1003) | func (*SystemProxyStatus) Descriptor() ([]byte, []int) {
    method GetAvailable (line 1007) | func (x *SystemProxyStatus) GetAvailable() bool {
    method GetEnabled (line 1014) | func (x *SystemProxyStatus) GetEnabled() bool {
  type SetSystemProxyEnabledRequest (line 1021) | type SetSystemProxyEnabledRequest struct
    method Reset (line 1028) | func (x *SetSystemProxyEnabledRequest) Reset() {
    method String (line 1035) | func (x *SetSystemProxyEnabledRequest) String() string {
    method ProtoMessage (line 1039) | func (*SetSystemProxyEnabledRequest) ProtoMessage() {}
    method ProtoReflect (line 1041) | func (x *SetSystemProxyEnabledRequest) ProtoReflect() protoreflect.Mes...
    method Descriptor (line 1054) | func (*SetSystemProxyEnabledRequest) Descriptor() ([]byte, []int) {
    method GetEnabled (line 1058) | func (x *SetSystemProxyEnabledRequest) GetEnabled() bool {
  type SubscribeConnectionsRequest (line 1065) | type SubscribeConnectionsRequest struct
    method Reset (line 1072) | func (x *SubscribeConnectionsRequest) Reset() {
    method String (line 1079) | func (x *SubscribeConnectionsRequest) String() string {
    method ProtoMessage (line 1083) | func (*SubscribeConnectionsRequest) ProtoMessage() {}
    method ProtoReflect (line 1085) | func (x *SubscribeConnectionsRequest) ProtoReflect() protoreflect.Mess...
    method Descriptor (line 1098) | func (*SubscribeConnectionsRequest) Descriptor() ([]byte, []int) {
    method GetInterval (line 1102) | func (x *SubscribeConnectionsRequest) GetInterval() int64 {
  type ConnectionEvent (line 1109) | type ConnectionEvent struct
    method Reset (line 1121) | func (x *ConnectionEvent) Reset() {
    method String (line 1128) | func (x *ConnectionEvent) String() string {
    method ProtoMessage (line 1132) | func (*ConnectionEvent) ProtoMessage() {}
    method ProtoReflect (line 1134) | func (x *ConnectionEvent) ProtoReflect() protoreflect.Message {
    method Descriptor (line 1147) | func (*ConnectionEvent) Descriptor() ([]byte, []int) {
    method GetType (line 1151) | func (x *ConnectionEvent) GetType() ConnectionEventType {
    method GetId (line 1158) | func (x *ConnectionEvent) GetId() string {
    method GetConnection (line 1165) | func (x *ConnectionEvent) GetConnection() *Connection {
    method GetUplinkDelta (line 1172) | func (x *ConnectionEvent) GetUplinkDelta() int64 {
    method GetDownlinkDelta (line 1179) | func (x *ConnectionEvent) GetDownlinkDelta() int64 {
    method GetClosedAt (line 1186) | func (x *ConnectionEvent) GetClosedAt() int64 {
  type ConnectionEvents (line 1193) | type ConnectionEvents struct
    method Reset (line 1201) | func (x *ConnectionEvents) Reset() {
    method String (line 1208) | func (x *ConnectionEvents) String() string {
    method ProtoMessage (line 1212) | func (*ConnectionEvents) ProtoMessage() {}
    method ProtoReflect (line 1214) | func (x *ConnectionEvents) ProtoReflect() protoreflect.Message {
    method Descriptor (line 1227) | func (*ConnectionEvents) Descriptor() ([]byte, []int) {
    method GetEvents (line 1231) | func (x *ConnectionEvents) GetEvents() []*ConnectionEvent {
    method GetReset_ (line 1238) | func (x *ConnectionEvents) GetReset_() bool {
  type Connection (line 1245) | type Connection struct
    method Reset (line 1273) | func (x *Connection) Reset() {
    method String (line 1280) | func (x *Connection) String() string {
    method ProtoMessage (line 1284) | func (*Connection) ProtoMessage() {}
    method ProtoReflect (line 1286) | func (x *Connection) ProtoReflect() protoreflect.Message {
    method Descriptor (line 1299) | func (*Connection) Descriptor() ([]byte, []int) {
    method GetId (line 1303) | func (x *Connection) GetId() string {
    method GetInbound (line 1310) | func (x *Connection) GetInbound() string {
    method GetInboundType (line 1317) | func (x *Connection) GetInboundType() string {
    method GetIpVersion (line 1324) | func (x *Connection) GetIpVersion() int32 {
    method GetNetwork (line 1331) | func (x *Connection) GetNetwork() string {
    method GetSource (line 1338) | func (x *Connection) GetSource() string {
    method GetDestination (line 1345) | func (x *Connection) GetDestination() string {
    method GetDomain (line 1352) | func (x *Connection) GetDomain() string {
    method GetProtocol (line 1359) | func (x *Connection) GetProtocol() string {
    method GetUser (line 1366) | func (x *Connection) GetUser() string {
    method GetFromOutbound (line 1373) | func (x *Connection) GetFromOutbound() string {
    method GetCreatedAt (line 1380) | func (x *Connection) GetCreatedAt() int64 {
    method GetClosedAt (line 1387) | func (x *Connection) GetClosedAt() int64 {
    method GetUplink (line 1394) | func (x *Connection) GetUplink() int64 {
    method GetDownlink (line 1401) | func (x *Connection) GetDownlink() int64 {
    method GetUplinkTotal (line 1408) | func (x *Connection) GetUplinkTotal() int64 {
    method GetDownlinkTotal (line 1415) | func (x *Connection) GetDownlinkTotal() int64 {
    method GetRule (line 1422) | func (x *Connection) GetRule() string {
    method GetOutbound (line 1429) | func (x *Connection) GetOutbound() string {
    method GetOutboundType (line 1436) | func (x *Connection) GetOutboundType() string {
    method GetChainList (line 1443) | func (x *Connection) GetChainList() []string {
    method GetProcessInfo (line 1450) | func (x *Connection) GetProcessInfo() *ProcessInfo {
  type ProcessInfo (line 1457) | type ProcessInfo struct
    method Reset (line 1468) | func (x *ProcessInfo) Reset() {
    method String (line 1475) | func (x *ProcessInfo) String() string {
    method ProtoMessage (line 1479) | func (*ProcessInfo) ProtoMessage() {}
    method ProtoReflect (line 1481) | func (x *ProcessInfo) ProtoReflect() protoreflect.Message {
    method Descriptor (line 1494) | func (*ProcessInfo) Descriptor() ([]byte, []int) {
    method GetProcessId (line 1498) | func (x *ProcessInfo) GetProcessId() uint32 {
    method GetUserId (line 1505) | func (x *ProcessInfo) GetUserId() int32 {
    method GetUserName (line 1512) | func (x *ProcessInfo) GetUserName() string {
    method GetProcessPath (line 1519) | func (x *ProcessInfo) GetProcessPath() string {
    method GetPackageName (line 1526) | func (x *ProcessInfo) GetPackageName() string {
  type CloseConnectionRequest (line 1533) | type CloseConnectionRequest struct
    method Reset (line 1540) | func (x *CloseConnectionRequest) Reset() {
    method String (line 1547) | func (x *CloseConnectionRequest) String() string {
    method ProtoMessage (line 1551) | func (*CloseConnectionRequest) ProtoMessage() {}
    method ProtoReflect (line 1553) | func (x *CloseConnectionRequest) ProtoReflect() protoreflect.Message {
    method Descriptor (line 1566) | func (*CloseConnectionRequest) Descriptor() ([]byte, []int) {
    method GetId (line 1570) | func (x *CloseConnectionRequest) GetId() string {
  type DeprecatedWarnings (line 1577) | type DeprecatedWarnings struct
    method Reset (line 1584) | func (x *DeprecatedWarnings) Reset() {
    method String (line 1591) | func (x *DeprecatedWarnings) String() string {
    method ProtoMessage (line 1595) | func (*DeprecatedWarnings) ProtoMessage() {}
    method ProtoReflect (line 1597) | func (x *DeprecatedWarnings) ProtoReflect() protoreflect.Message {
    method Descriptor (line 1610) | func (*DeprecatedWarnings) Descriptor() ([]byte, []int) {
    method GetWarnings (line 1614) | func (x *DeprecatedWarnings) GetWarnings() []*DeprecatedWarning {
  type DeprecatedWarning (line 1621) | type DeprecatedWarning struct
    method Reset (line 1630) | func (x *DeprecatedWarning) Reset() {
    method String (line 1637) | func (x *DeprecatedWarning) String() string {
    method ProtoMessage (line 1641) | func (*DeprecatedWarning) ProtoMessage() {}
    method ProtoReflect (line 1643) | func (x *DeprecatedWarning) ProtoReflect() protoreflect.Message {
    method Descriptor (line 1656) | func (*DeprecatedWarning) Descriptor() ([]byte, []int) {
    method GetMessage (line 1660) | func (x *DeprecatedWarning) GetMessage() string {
    method GetImpending (line 1667) | func (x *DeprecatedWarning) GetImpending() bool {
    method GetMigrationLink (line 1674) | func (x *DeprecatedWarning) GetMigrationLink() string {
  type StartedAt (line 1681) | type StartedAt struct
    method Reset (line 1688) | func (x *StartedAt) Reset() {
    method String (line 1695) | func (x *StartedAt) String() string {
    method ProtoMessage (line 1699) | func (*StartedAt) ProtoMessage() {}
    method ProtoReflect (line 1701) | func (x *StartedAt) ProtoReflect() protoreflect.Message {
    method Descriptor (line 1714) | func (*StartedAt) Descriptor() ([]byte, []int) {
    method GetStartedAt (line 1718) | func (x *StartedAt) GetStartedAt() int64 {
  type Log_Message (line 1725) | type Log_Message struct
    method Reset (line 1733) | func (x *Log_Message) Reset() {
    method String (line 1740) | func (x *Log_Message) String() string {
    method ProtoMessage (line 1744) | func (*Log_Message) ProtoMessage() {}
    method ProtoReflect (line 1746) | func (x *Log_Message) ProtoReflect() protoreflect.Message {
    method Descriptor (line 1759) | func (*Log_Message) Descriptor() ([]byte, []int) {
    method GetLevel (line 1763) | func (x *Log_Message) GetLevel() LogLevel {
    method GetMessage (line 1770) | func (x *Log_Message) GetMessage() string {
  constant file_daemon_started_service_proto_rawDesc (line 1779) | file_daemon_started_service_proto_rawDesc = "" +
  function file_daemon_started_service_proto_rawDescGZIP (line 1944) | func file_daemon_started_service_proto_rawDescGZIP() []byte {
  function init (line 2049) | func init() { file_daemon_started_service_proto_init() }
  function file_daemon_started_service_proto_init (line 2050) | func file_daemon_started_service_proto_init() {

FILE: daemon/started_service_grpc.pb.go
  constant _ (line 15) | _ = grpc.SupportPackageIsVersion9
  constant StartedService_StopService_FullMethodName (line 18) | StartedService_StopService_FullMethodName            = "/daemon.StartedS...
  constant StartedService_ReloadService_FullMethodName (line 19) | StartedService_ReloadService_FullMethodName          = "/daemon.StartedS...
  constant StartedService_SubscribeServiceStatus_FullMethodName (line 20) | StartedService_SubscribeServiceStatus_FullMethodName = "/daemon.StartedS...
  constant StartedService_SubscribeLog_FullMethodName (line 21) | StartedService_SubscribeLog_FullMethodName           = "/daemon.StartedS...
  constant StartedService_GetDefaultLogLevel_FullMethodName (line 22) | StartedService_GetDefaultLogLevel_FullMethodName     = "/daemon.StartedS...
  constant StartedService_ClearLogs_FullMethodName (line 23) | StartedService_ClearLogs_FullMethodName              = "/daemon.StartedS...
  constant StartedService_SubscribeStatus_FullMethodName (line 24) | StartedService_SubscribeStatus_FullMethodName        = "/daemon.StartedS...
  constant StartedService_SubscribeGroups_FullMethodName (line 25) | StartedService_SubscribeGroups_FullMethodName        = "/daemon.StartedS...
  constant StartedService_GetClashModeStatus_FullMethodName (line 26) | StartedService_GetClashModeStatus_FullMethodName     = "/daemon.StartedS...
  constant StartedService_SubscribeClashMode_FullMethodName (line 27) | StartedService_SubscribeClashMode_FullMethodName     = "/daemon.StartedS...
  constant StartedService_SetClashMode_FullMethodName (line 28) | StartedService_SetClashMode_FullMethodName           = "/daemon.StartedS...
  constant StartedService_URLTest_FullMethodName (line 29) | StartedService_URLTest_FullMethodName                = "/daemon.StartedS...
  constant StartedService_SelectOutbound_FullMethodName (line 30) | StartedService_SelectOutbound_FullMethodName         = "/daemon.StartedS...
  constant StartedService_SetGroupExpand_FullMethodName (line 31) | StartedService_SetGroupExpand_FullMethodName         = "/daemon.StartedS...
  constant StartedService_GetSystemProxyStatus_FullMethodName (line 32) | StartedService_GetSystemProxyStatus_FullMethodName   = "/daemon.StartedS...
  constant StartedService_SetSystemProxyEnabled_FullMethodName (line 33) | StartedService_SetSystemProxyEnabled_FullMethodName  = "/daemon.StartedS...
  constant StartedService_SubscribeConnections_FullMethodName (line 34) | StartedService_SubscribeConnections_FullMethodName   = "/daemon.StartedS...
  constant StartedService_CloseConnection_FullMethodName (line 35) | StartedService_CloseConnection_FullMethodName        = "/daemon.StartedS...
  constant StartedService_CloseAllConnections_FullMethodName (line 36) | StartedService_CloseAllConnections_FullMethodName    = "/daemon.StartedS...
  constant StartedService_GetDeprecatedWarnings_FullMethodName (line 37) | StartedService_GetDeprecatedWarnings_FullMethodName  = "/daemon.StartedS...
  constant StartedService_GetStartedAt_FullMethodName (line 38) | StartedService_GetStartedAt_FullMethodName           = "/daemon.StartedS...
  type StartedServiceClient (line 44) | type StartedServiceClient interface
  type startedServiceClient (line 68) | type startedServiceClient struct
    method StopService (line 76) | func (c *startedServiceClient) StopService(ctx context.Context, in *em...
    method ReloadService (line 86) | func (c *startedServiceClient) ReloadService(ctx context.Context, in *...
    method SubscribeServiceStatus (line 96) | func (c *startedServiceClient) SubscribeServiceStatus(ctx context.Cont...
    method SubscribeLog (line 115) | func (c *startedServiceClient) SubscribeLog(ctx context.Context, in *e...
    method GetDefaultLogLevel (line 134) | func (c *startedServiceClient) GetDefaultLogLevel(ctx context.Context,...
    method ClearLogs (line 144) | func (c *startedServiceClient) ClearLogs(ctx context.Context, in *empt...
    method SubscribeStatus (line 154) | func (c *startedServiceClient) SubscribeStatus(ctx context.Context, in...
    method SubscribeGroups (line 173) | func (c *startedServiceClient) SubscribeGroups(ctx context.Context, in...
    method GetClashModeStatus (line 192) | func (c *startedServiceClient) GetClashModeStatus(ctx context.Context,...
    method SubscribeClashMode (line 202) | func (c *startedServiceClient) SubscribeClashMode(ctx context.Context,...
    method SetClashMode (line 221) | func (c *startedServiceClient) SetClashMode(ctx context.Context, in *C...
    method URLTest (line 231) | func (c *startedServiceClient) URLTest(ctx context.Context, in *URLTes...
    method SelectOutbound (line 241) | func (c *startedServiceClient) SelectOutbound(ctx context.Context, in ...
    method SetGroupExpand (line 251) | func (c *startedServiceClient) SetGroupExpand(ctx context.Context, in ...
    method GetSystemProxyStatus (line 261) | func (c *startedServiceClient) GetSystemProxyStatus(ctx context.Contex...
    method SetSystemProxyEnabled (line 271) | func (c *startedServiceClient) SetSystemProxyEnabled(ctx context.Conte...
    method SubscribeConnections (line 281) | func (c *startedServiceClient) SubscribeConnections(ctx context.Contex...
    method CloseConnection (line 300) | func (c *startedServiceClient) CloseConnection(ctx context.Context, in...
    method CloseAllConnections (line 310) | func (c *startedServiceClient) CloseAllConnections(ctx context.Context...
    method GetDeprecatedWarnings (line 320) | func (c *startedServiceClient) GetDeprecatedWarnings(ctx context.Conte...
    method GetStartedAt (line 330) | func (c *startedServiceClient) GetStartedAt(ctx context.Context, in *e...
  function NewStartedServiceClient (line 72) | func NewStartedServiceClient(cc grpc.ClientConnInterface) StartedService...
  type StartedServiceServer (line 343) | type StartedServiceServer interface
  type UnimplementedStartedServiceServer (line 373) | type UnimplementedStartedServiceServer struct
    method StopService (line 375) | func (UnimplementedStartedServiceServer) StopService(context.Context, ...
    method ReloadService (line 379) | func (UnimplementedStartedServiceServer) ReloadService(context.Context...
    method SubscribeServiceStatus (line 383) | func (UnimplementedStartedServiceServer) SubscribeServiceStatus(*empty...
    method SubscribeLog (line 387) | func (UnimplementedStartedServiceServer) SubscribeLog(*emptypb.Empty, ...
    method GetDefaultLogLevel (line 391) | func (UnimplementedStartedServiceServer) GetDefaultLogLevel(context.Co...
    method ClearLogs (line 395) | func (UnimplementedStartedServiceServer) ClearLogs(context.Context, *e...
    method SubscribeStatus (line 399) | func (UnimplementedStartedServiceServer) SubscribeStatus(*SubscribeSta...
    method SubscribeGroups (line 403) | func (UnimplementedStartedServiceServer) SubscribeGroups(*emptypb.Empt...
    method GetClashModeStatus (line 407) | func (UnimplementedStartedServiceServer) GetClashModeStatus(context.Co...
    method SubscribeClashMode (line 411) | func (UnimplementedStartedServiceServer) SubscribeClashMode(*emptypb.E...
    method SetClashMode (line 415) | func (UnimplementedStartedServiceServer) SetClashMode(context.Context,...
    method URLTest (line 419) | func (UnimplementedStartedServiceServer) URLTest(context.Context, *URL...
    method SelectOutbound (line 423) | func (UnimplementedStartedServiceServer) SelectOutbound(context.Contex...
    method SetGroupExpand (line 427) | func (UnimplementedStartedServiceServer) SetGroupExpand(context.Contex...
    method GetSystemProxyStatus (line 431) | func (UnimplementedStartedServiceServer) GetSystemProxyStatus(context....
    method SetSystemProxyEnabled (line 435) | func (UnimplementedStartedServiceServer) SetSystemProxyEnabled(context...
    method SubscribeConnections (line 439) | func (UnimplementedStartedServiceServer) SubscribeConnections(*Subscri...
    method CloseConnection (line 443) | func (UnimplementedStartedServiceServer) CloseConnection(context.Conte...
    method CloseAllConnections (line 447) | func (UnimplementedStartedServiceServer) CloseAllConnections(context.C...
    method GetDeprecatedWarnings (line 451) | func (UnimplementedStartedServiceServer) GetDeprecatedWarnings(context...
    method GetStartedAt (line 455) | func (UnimplementedStartedServiceServer) GetStartedAt(context.Context,...
    method mustEmbedUnimplementedStartedServiceServer (line 458) | func (UnimplementedStartedServiceServer) mustEmbedUnimplementedStarted...
    method testEmbeddedByValue (line 459) | func (UnimplementedStartedServiceServer) testEmbeddedByValue()        ...
  type UnsafeStartedServiceServer (line 464) | type UnsafeStartedServiceServer interface
  function RegisterStartedServiceServer (line 468) | func RegisterStartedServiceServer(s grpc.ServiceRegistrar, srv StartedSe...
  function _StartedService_StopService_Handler (line 479) | func _StartedService_StopService_Handler(srv interface{}, ctx context.Co...
  function _StartedService_ReloadService_Handler (line 497) | func _StartedService_ReloadService_Handler(srv interface{}, ctx context....
  function _StartedService_SubscribeServiceStatus_Handler (line 515) | func _StartedService_SubscribeServiceStatus_Handler(srv interface{}, str...
  function _StartedService_SubscribeLog_Handler (line 526) | func _StartedService_SubscribeLog_Handler(srv interface{}, stream grpc.S...
  function _StartedService_GetDefaultLogLevel_Handler (line 537) | func _StartedService_GetDefaultLogLevel_Handler(srv interface{}, ctx con...
  function _StartedService_ClearLogs_Handler (line 555) | func _StartedService_ClearLogs_Handler(srv interface{}, ctx context.Cont...
  function _StartedService_SubscribeStatus_Handler (line 573) | func _StartedService_SubscribeStatus_Handler(srv interface{}, stream grp...
  function _StartedService_SubscribeGroups_Handler (line 584) | func _StartedService_SubscribeGroups_Handler(srv interface{}, stream grp...
  function _StartedService_GetClashModeStatus_Handler (line 595) | func _StartedService_GetClashModeStatus_Handler(srv interface{}, ctx con...
  function _StartedService_SubscribeClashMode_Handler (line 613) | func _StartedService_SubscribeClashMode_Handler(srv interface{}, stream ...
  function _StartedService_SetClashMode_Handler (line 624) | func _StartedService_SetClashMode_Handler(srv interface{}, ctx context.C...
  function _StartedService_URLTest_Handler (line 642) | func _StartedService_URLTest_Handler(srv interface{}, ctx context.Contex...
  function _StartedService_SelectOutbound_Handler (line 660) | func _StartedService_SelectOutbound_Handler(srv interface{}, ctx context...
  function _StartedService_SetGroupExpand_Handler (line 678) | func _StartedService_SetGroupExpand_Handler(srv interface{}, ctx context...
  function _StartedService_GetSystemProxyStatus_Handler (line 696) | func _StartedService_GetSystemProxyStatus_Handler(srv interface{}, ctx c...
  function _StartedService_SetSystemProxyEnabled_Handler (line 714) | func _StartedService_SetSystemProxyEnabled_Handler(srv interface{}, ctx ...
  function _StartedService_SubscribeConnections_Handler (line 732) | func _StartedService_SubscribeConnections_Handler(srv interface{}, strea...
  function _StartedService_CloseConnection_Handler (line 743) | func _StartedService_CloseConnection_Handler(srv interface{}, ctx contex...
  function _StartedService_CloseAllConnections_Handler (line 761) | func _StartedService_CloseAllConnections_Handler(srv interface{}, ctx co...
  function _StartedService_GetDeprecatedWarnings_Handler (line 779) | func _StartedService_GetDeprecatedWarnings_Handler(srv interface{}, ctx ...
  function _StartedService_GetStartedAt_Handler (line 797) | func _StartedService_GetStartedAt_Handler(srv interface{}, ctx context.C...

FILE: debug.go
  function applyDebugOptions (line 10) | func applyDebugOptions(options option.DebugOptions) error {

FILE: debug_http.go
  function applyDebugListenOption (line 22) | func applyDebugListenOption(options option.DebugOptions) {

FILE: debug_stub.go
  function rusageMaxRSS (line 5) | func rusageMaxRSS() float64 {

FILE: debug_unix.go
  function rusageMaxRSS (line 10) | func rusageMaxRSS() float64 {

FILE: dns/client.go
  type Client (line 34) | type Client struct
    method Start (line 92) | func (c *Client) Start() {
    method Exchange (line 112) | func (c *Client) Exchange(ctx context.Context, transport adapter.DNSTr...
    method Lookup (line 318) | func (c *Client) Lookup(ctx context.Context, transport adapter.DNSTran...
    method ClearCache (line 362) | func (c *Client) ClearCache() {
    method storeCache (line 378) | func (c *Client) storeCache(transport adapter.DNSTransport, question d...
    method lookupToExchange (line 403) | func (c *Client) lookupToExchange(ctx context.Context, transport adapt...
    method questionCache (line 432) | func (c *Client) questionCache(question dns.Question, transport adapte...
    method loadResponse (line 443) | func (c *Client) loadResponse(question dns.Question, transport adapter...
  type ClientOptions (line 49) | type ClientOptions struct
  function NewClient (line 60) | func NewClient(options ClientOptions) *Client {
  type transportCacheKey (line 87) | type transportCacheKey struct
  function extractNegativeTTL (line 98) | func extractNegativeTTL(response *dns.Msg) (uint32, bool) {
  function sortAddresses (line 370) | func sortAddresses(response4 []netip.Addr, response6 []netip.Addr, strat...
  function MessageToAddresses (line 517) | func MessageToAddresses(response *dns.Msg) []netip.Addr {
  function wrapError (line 539) | func wrapError(err error) error {
  type transportKey (line 551) | type transportKey struct
  function contextWithTransportTag (line 553) | func contextWithTransportTag(ctx context.Context, transportTag string) c...
  function transportTagFromContext (line 557) | func transportTagFromContext(ctx context.Context) (string, bool) {
  function FixedResponseStatus (line 562) | func FixedResponseStatus(message *dns.Msg, rcode int) *dns.Msg {
  function FixedResponse (line 576) | func FixedResponse(id uint16, question dns.Question, addresses []netip.A...
  function FixedResponseCNAME (line 614) | func FixedResponseCNAME(id uint16, question dns.Question, record string,...
  function FixedResponseTXT (line 640) | func FixedResponseTXT(id uint16, question dns.Question, records []string...
  function FixedResponseMX (line 666) | func FixedResponseMX(id uint16, question dns.Question, records []*net.MX...

FILE: dns/client_log.go
  function logCachedResponse (line 12) | func logCachedResponse(logger logger.ContextLogger, ctx context.Context,...
  function logExchangedResponse (line 25) | func logExchangedResponse(logger logger.ContextLogger, ctx context.Conte...
  function logRejectedResponse (line 38) | func logRejectedResponse(logger logger.ContextLogger, ctx context.Contex...
  function FqdnToDomain (line 49) | func FqdnToDomain(fqdn string) string {
  function FormatQuestion (line 56) | func FormatQuestion(string string) string {

FILE: dns/client_truncate.go
  function TruncateDNSMessage (line 9) | func TruncateDNSMessage(request *dns.Msg, response *dns.Msg, headroom in...

FILE: dns/extension_edns0_subnet.go
  function SetClientSubnet (line 9) | func SetClientSubnet(message *dns.Msg, clientSubnet netip.Prefix) *dns.M...
  function setClientSubnet (line 13) | func setClientSubnet(message *dns.Msg, clientSubnet netip.Prefix, clone ...

FILE: dns/rcode.go
  constant RcodeSuccess (line 8) | RcodeSuccess     RcodeError = mDNS.RcodeSuccess
  constant RcodeFormatError (line 9) | RcodeFormatError RcodeError = mDNS.RcodeFormatError
  constant RcodeNameError (line 10) | RcodeNameError   RcodeError = mDNS.RcodeNameError
  constant RcodeRefused (line 11) | RcodeRefused     RcodeError = mDNS.RcodeRefused
  type RcodeError (line 14) | type RcodeError
    method Error (line 16) | func (e RcodeError) Error() string {

FILE: dns/router.go
  type Router (line 31) | type Router struct
    method Initialize (line 76) | func (r *Router) Initialize(rules []option.DNSRule) error {
    method Start (line 87) | func (r *Router) Start(stage adapter.StartStage) error {
    method Close (line 107) | func (r *Router) Close() error {
    method matchDNS (line 120) | func (r *Router) matchDNS(ctx context.Context, allowFakeIP bool, ruleI...
    method Exchange (line 210) | func (r *Router) Exchange(ctx context.Context, message *mDNS.Msg, opti...
    method Lookup (line 327) | func (r *Router) Lookup(ctx context.Context, domain string, options ad...
    method ClearCache (line 440) | func (r *Router) ClearCache() {
    method LookupReverseMapping (line 447) | func (r *Router) LookupReverseMapping(ip netip.Addr) (string, bool) {
    method ResetNetwork (line 455) | func (r *Router) ResetNetwork() {
  function NewRouter (line 43) | func NewRouter(ctx context.Context, logFactory log.Factory, options opti...
  function isAddressQuery (line 419) | func isAddressQuery(message *mDNS.Msg) bool {
  function addressLimitResponseCheck (line 428) | func addressLimitResponseCheck(rule adapter.DNSRule, metadata *adapter.I...

FILE: dns/transport/base.go
  type TransportState (line 14) | type TransportState
  constant StateNew (line 17) | StateNew TransportState = iota
  constant StateStarted (line 18) | StateStarted
  constant StateClosing (line 19) | StateClosing
  constant StateClosed (line 20) | StateClosed
  type BaseTransport (line 28) | type BaseTransport struct
    method State (line 51) | func (t *BaseTransport) State() TransportState {
    method SetStarted (line 57) | func (t *BaseTransport) SetStarted() error {
    method BeginQuery (line 71) | func (t *BaseTransport) BeginQuery() bool {
    method EndQuery (line 81) | func (t *BaseTransport) EndQuery() {
    method CloseContext (line 93) | func (t *BaseTransport) CloseContext() context.Context {
    method Shutdown (line 97) | func (t *BaseTransport) Shutdown(ctx context.Context) error {
    method Close (line 141) | func (t *BaseTransport) Close() error {
  function NewBaseTransport (line 40) | func NewBaseTransport(adapter dns.TransportAdapter, logger logger.Contex...

FILE: dns/transport/connector.go
  type ConnectorCallbacks (line 12) | type ConnectorCallbacks struct
  type Connector (line 18) | type Connector struct
  function NewConnector (line 32) | func NewConnector[T any](closeCtx context.Context, dial func(context.Con...
  function NewSingleflightConnector (line 40) | func NewSingleflightConnector(closeCtx context.Context, dial func(contex...
  type contextKeyConnecting (line 54) | type contextKeyConnecting struct
  type connectorDialResult (line 58) | type connectorDialResult struct
  method Get (line 64) | func (c *Connector[T]) Get(ctx context.Context) (T, error) {
  function isRecursiveConnectorDial (line 143) | func isRecursiveConnectorDial[T any](ctx context.Context, connector *Con...
  method completeDial (line 148) | func (c *Connector[T]) completeDial(ctx context.Context, connecting chan...
  method dialWithCancellation (line 180) | func (c *Connector[T]) dialWithCancellation(ctx context.Context) (T, con...
  type valueContext (line 221) | type valueContext struct
    method Value (line 226) | func (v valueContext) Value(key any) any {
    method Deadline (line 230) | func (v valueContext) Deadline() (time.Time, bool) {
  method Close (line 234) | func (c *Connector[T]) Close() error {
  method Reset (line 255) | func (c *Connector[T]) Reset() {
  type Connection (line 269) | type Connection struct
    method Done (line 284) | func (c *Connection) Done() <-chan struct{} {
    method IsClosed (line 288) | func (c *Connection) IsClosed() bool {
    method CloseError (line 297) | func (c *Connection) CloseError() error {
    method Close (line 309) | func (c *Connection) Close() error {
    method CloseWithError (line 313) | func (c *Connection) CloseWithError(err error) error {
  function WrapConnection (line 277) | func WrapConnection(conn net.Conn) *Connection {

FILE: dns/transport/connector_test.go
  type testConnectorConnection (line 12) | type testConnectorConnection struct
  function TestConnectorRecursiveGetFailsFast (line 14) | func TestConnectorRecursiveGetFailsFast(t *testing.T) {
  function TestConnectorRecursiveGetAcrossConnectorsAllowed (line 50) | func TestConnectorRecursiveGetAcrossConnectorsAllowed(t *testing.T) {
  function TestConnectorDialContextPreservesValueAndDeadline (line 92) | func TestConnectorDialContextPreservesValueAndDeadline(t *testing.T) {
  function TestConnectorDialSkipsCanceledRequest (line 126) | func TestConnectorDialSkipsCanceledRequest(t *testing.T) {
  function TestConnectorCanceledRequestDoesNotCacheConnection (line 149) | func TestConnectorCanceledRequestDoesNotCacheConnection(t *testing.T) {
  function TestConnectorCanceledRequestReturnsBeforeIgnoredDialCompletes (line 200) | func TestConnectorCanceledRequestReturnsBeforeIgnoredDialCompletes(t *te...
  function TestConnectorWaiterDoesNotStartNewDialBeforeCanceledDialCompletes (line 259) | func TestConnectorWaiterDoesNotStartNewDialBeforeCanceledDialCompletes(t...
  function TestConnectorDialContextNotCanceledByRequestContextAfterDial (line 342) | func TestConnectorDialContextNotCanceledByRequestContextAfterDial(t *tes...
  function TestConnectorDialContextCanceledOnClose (line 374) | func TestConnectorDialContextCanceledOnClose(t *testing.T) {

FILE: dns/transport/dhcp/dhcp.go
  function RegisterTransport (line 36) | func RegisterTransport(registry *dns.TransportRegistry) {
  type Transport (line 42) | type Transport struct
    method Start (line 88) | func (t *Transport) Start(stage adapter.StartStage) error {
    method Close (line 104) | func (t *Transport) Close() error {
    method Reset (line 111) | func (t *Transport) Reset() {
    method Exchange (line 118) | func (t *Transport) Exchange(ctx context.Context, message *mDNS.Msg) (...
    method Exchange0 (line 129) | func (t *Transport) Exchange0(ctx context.Context, message *mDNS.Msg, ...
    method Fetch (line 139) | func (t *Transport) Fetch() []M.Socksaddr {
    method fetch (line 144) | func (t *Transport) fetch() ([]M.Socksaddr, error) {
    method fetchInterface (line 168) | func (t *Transport) fetchInterface() (*control.Interface, error) {
    method updateServers (line 183) | func (t *Transport) updateServers() error {
    method interfaceUpdated (line 206) | func (t *Transport) interfaceUpdated(defaultInterface *control.Interfa...
    method fetchServers0 (line 213) | func (t *Transport) fetchServers0(ctx context.Context, iface *control....
    method fetchServersResponse (line 261) | func (t *Transport) fetchServersResponse(iface *control.Interface, pac...
    method recreateServers (line 295) | func (t *Transport) recreateServers(iface *control.Interface, dhcpPack...
  function NewTransport (line 59) | func NewTransport(ctx context.Context, logger log.ContextLogger, tag str...
  function NewRawTransport (line 76) | func NewRawTransport(transportAdapter dns.TransportAdapter, ctx context....

FILE: dns/transport/dhcp/dhcp_shared.go
  method exchangeSingleRequest (line 20) | func (t *Transport) exchangeSingleRequest(ctx context.Context, servers [...
  method exchangeParallel (line 33) | func (t *Transport) exchangeParallel(ctx context.Context, servers []M.So...
  method tryOneName (line 79) | func (t *Transport) tryOneName(ctx context.Context, servers []M.Socksadd...
  method exchangeOne (line 98) | func (
Condensed preview — 1022 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (4,171K chars).
[
  {
    "path": ".fpm_openwrt",
    "chars": 963,
    "preview": "-s dir\n--name sing-box\n--category net\n--license GPL-3.0-or-later\n--description \"The universal proxy platform.\"\n--url \"ht"
  },
  {
    "path": ".fpm_pacman",
    "chars": 1013,
    "preview": "-s dir\n--name sing-box\n--category net\n--license GPL-3.0-or-later\n--description \"The universal proxy platform.\"\n--url \"ht"
  },
  {
    "path": ".fpm_systemd",
    "chars": 1103,
    "preview": "-s dir\n--name sing-box\n--category net\n--license GPL-3.0-or-later\n--description \"The universal proxy platform.\"\n--url \"ht"
  },
  {
    "path": ".github/CRONET_GO_VERSION",
    "chars": 41,
    "preview": "ea7cd33752aed62603775af3df946c1b83f4b0b3\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 19,
    "preview": "github: nekohasekai"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.yml",
    "chars": 4024,
    "preview": "name: Bug report\ndescription: \"Report sing-box bug\"\nbody:\n  - type: dropdown\n    attributes:\n      label: Operating syst"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report_zh.yml",
    "chars": 2413,
    "preview": "name: 错误反馈\ndescription: \"提交 sing-box 漏洞\"\nbody:\n  - type: dropdown\n    attributes:\n      label: 操作系统\n      description: 请"
  },
  {
    "path": ".github/build_alpine_apk.sh",
    "chars": 2762,
    "preview": "#!/usr/bin/env bash\n\nset -e -o pipefail\n\nARCHITECTURE=\"$1\"\nVERSION=\"$2\"\nBINARY_PATH=\"$3\"\nOUTPUT_PATH=\"$4\"\n\nif [ -z \"$ARC"
  },
  {
    "path": ".github/build_openwrt_apk.sh",
    "chars": 2738,
    "preview": "#!/usr/bin/env bash\n\nset -e -o pipefail\n\nARCHITECTURE=\"$1\"\nVERSION=\"$2\"\nBINARY_PATH=\"$3\"\nOUTPUT_PATH=\"$4\"\n\nif [ -z \"$ARC"
  },
  {
    "path": ".github/deb2ipk.sh",
    "chars": 555,
    "preview": "#!/usr/bin/env bash\n# mod from https://gist.github.com/pldubouilh/c5703052986bfdd404005951dee54683\n\nset -e -o pipefail\n\n"
  },
  {
    "path": ".github/renovate.json",
    "chars": 489,
    "preview": "{\n  \"$schema\": \"https://docs.renovatebot.com/renovate-schema.json\",\n  \"commitMessagePrefix\": \"[dependencies]\",\n  \"extend"
  },
  {
    "path": ".github/setup_go_for_macos1013.sh",
    "chars": 1338,
    "preview": "#!/usr/bin/env bash\n\nset -euo pipefail\n\nVERSION=\"1.25.8\"\nPATCH_COMMITS=(\n  \"afe69d3cec1c6dcf0f1797b20546795730850070\"\n  "
  },
  {
    "path": ".github/setup_go_for_windows7.sh",
    "chars": 1687,
    "preview": "#!/usr/bin/env bash\n\nset -euo pipefail\n\nVERSION=\"1.25.8\"\nPATCH_COMMITS=(\n  \"466f6c7a29bc098b0d4c987b803c779222894a11\"\n  "
  },
  {
    "path": ".github/update_clients.sh",
    "chars": 215,
    "preview": "#!/usr/bin/env bash\n\nPROJECTS=$(dirname \"$0\")/../..\n\nfunction updateClient() {\n  pushd clients/$1\n  git fetch\n  git rese"
  },
  {
    "path": ".github/update_cronet.sh",
    "chars": 461,
    "preview": "#!/usr/bin/env bash\n\nset -e -o pipefail\n\nSCRIPT_DIR=$(dirname \"$0\")\nPROJECTS=$SCRIPT_DIR/../..\n\ngit -C $PROJECTS/cronet-"
  },
  {
    "path": ".github/update_cronet_dev.sh",
    "chars": 473,
    "preview": "#!/usr/bin/env bash\n\nset -e -o pipefail\n\nSCRIPT_DIR=$(dirname \"$0\")\nPROJECTS=$SCRIPT_DIR/../..\n\ngit -C $PROJECTS/cronet-"
  },
  {
    "path": ".github/update_dependencies.sh",
    "chars": 135,
    "preview": "#!/usr/bin/env bash\n\nPROJECTS=$(dirname \"$0\")/../..\ngo get -x github.com/sagernet/$1@$(git -C $PROJECTS/$1 rev-parse HEA"
  },
  {
    "path": ".github/workflows/build.yml",
    "chars": 43490,
    "preview": "name: Build\n\non:\n  workflow_dispatch:\n    inputs:\n      version:\n        description: \"Version name\"\n        required: t"
  },
  {
    "path": ".github/workflows/docker.yml",
    "chars": 10793,
    "preview": "name: Publish Docker Images\n\non:\n  #push:\n  #  branches:\n  #    - stable\n  #    - testing\n  release:\n    types:\n      - "
  },
  {
    "path": ".github/workflows/lint.yml",
    "chars": 801,
    "preview": "name: Lint\n\non:\n  push:\n    branches:\n      - oldstable\n      - stable\n      - testing\n      - unstable\n    paths-ignore"
  },
  {
    "path": ".github/workflows/linux.yml",
    "chars": 10283,
    "preview": "name: Build Linux Packages\n\non:\n  #push:\n  #  branches:\n  #    - stable\n  #    - testing\n  workflow_dispatch:\n    inputs"
  },
  {
    "path": ".github/workflows/stale.yml",
    "chars": 462,
    "preview": "name: Mark stale issues and pull requests\n\non:\n  schedule:\n    - cron: \"30 1 * * *\"\n\njobs:\n  stale:\n    runs-on: ubuntu-"
  },
  {
    "path": ".gitignore",
    "chars": 270,
    "preview": "/.idea/\n/vendor/\n/*.json\n/*.srs\n/*.db\n/site/\n/bin/\n/dist/\n/sing-box\n/sing-box.exe\n/build/\n/*.jar\n/*.aar\n/*.xcframework/\n"
  },
  {
    "path": ".gitmodules",
    "chars": 222,
    "preview": "[submodule \"clients/apple\"]\n\tpath = clients/apple\n\turl = https://github.com/SagerNet/sing-box-for-apple.git\n[submodule \""
  },
  {
    "path": ".golangci.yml",
    "chars": 1094,
    "preview": "version: \"2\"\nrun:\n  go: \"1.25\"\n  build-tags:\n    - with_gvisor\n    - with_quic\n    - with_dhcp\n    - with_wireguard\n    "
  },
  {
    "path": "Dockerfile",
    "chars": 1087,
    "preview": "FROM --platform=$BUILDPLATFORM golang:1.25-alpine AS builder\nLABEL maintainer=\"nekohasekai <contact-git@sekai.icu>\"\nCOPY"
  },
  {
    "path": "Dockerfile.binary",
    "chars": 525,
    "preview": "ARG BASE_IMAGE=alpine\nFROM ${BASE_IMAGE}\nARG TARGETARCH\nARG TARGETVARIANT\nLABEL maintainer=\"nekohasekai <contact-git@sek"
  },
  {
    "path": "LICENSE",
    "chars": 791,
    "preview": "Copyright (C) 2022 by nekohasekai <contact-sagernet@sekai.icu>\n\nThis program is free software: you can redistribute it a"
  },
  {
    "path": "Makefile",
    "chars": 9430,
    "preview": "NAME = sing-box\nCOMMIT = $(shell git rev-parse --short HEAD)\nTAGS ?= $(shell cat release/DEFAULT_BUILD_TAGS_OTHERS)\n\nGOH"
  },
  {
    "path": "README.md",
    "chars": 1325,
    "preview": "> Sponsored by [Warp](https://go.warp.dev/sing-box), built for coding with multiple AI agents\n\n<a href=\"https://go.warp."
  },
  {
    "path": "adapter/certificate.go",
    "chars": 344,
    "preview": "package adapter\n\nimport (\n\t\"context\"\n\t\"crypto/x509\"\n\n\t\"github.com/sagernet/sing/service\"\n)\n\ntype CertificateStore interf"
  },
  {
    "path": "adapter/connections.go",
    "chars": 502,
    "preview": "package adapter\n\nimport (\n\t\"context\"\n\t\"net\"\n\n\tN \"github.com/sagernet/sing/common/network\"\n)\n\ntype ConnectionManager inte"
  },
  {
    "path": "adapter/dns.go",
    "chars": 2922,
    "preview": "package adapter\n\nimport (\n\t\"context\"\n\t\"net/netip\"\n\n\tC \"github.com/sagernet/sing-box/constant\"\n\t\"github.com/sagernet/sing"
  },
  {
    "path": "adapter/endpoint/adapter.go",
    "chars": 984,
    "preview": "package endpoint\n\nimport \"github.com/sagernet/sing-box/option\"\n\ntype Adapter struct {\n\tendpointType string\n\tendpointTag "
  },
  {
    "path": "adapter/endpoint/manager.go",
    "chars": 4369,
    "preview": "package endpoint\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.com/sagern"
  },
  {
    "path": "adapter/endpoint/registry.go",
    "chars": 2300,
    "preview": "package endpoint\n\nimport (\n\t\"context\"\n\t\"sync\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.com/sagernet/sing-box/lo"
  },
  {
    "path": "adapter/endpoint.go",
    "chars": 650,
    "preview": "package adapter\n\nimport (\n\t\"context\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\t\"github.com/sagernet/sing-box/option\"\n)\n\ntype"
  },
  {
    "path": "adapter/experimental.go",
    "chars": 3129,
    "preview": "package adapter\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/binary\"\n\t\"io\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing/common/observ"
  },
  {
    "path": "adapter/fakeip.go",
    "chars": 786,
    "preview": "package adapter\n\nimport (\n\t\"net/netip\"\n\n\t\"github.com/sagernet/sing/common/logger\"\n)\n\ntype FakeIPStore interface {\n\tSimpl"
  },
  {
    "path": "adapter/fakeip_metadata.go",
    "chars": 1183,
    "preview": "package adapter\n\nimport (\n\t\"bytes\"\n\t\"encoding\"\n\t\"encoding/binary\"\n\t\"io\"\n\t\"net/netip\"\n\n\t\"github.com/sagernet/sing/common\""
  },
  {
    "path": "adapter/handler.go",
    "chars": 1659,
    "preview": "package adapter\n\nimport (\n\t\"context\"\n\t\"net\"\n\n\t\"github.com/sagernet/sing/common/buf\"\n\tE \"github.com/sagernet/sing/common/"
  },
  {
    "path": "adapter/inbound/adapter.go",
    "chars": 340,
    "preview": "package inbound\n\ntype Adapter struct {\n\tinboundType string\n\tinboundTag  string\n}\n\nfunc NewAdapter(inboundType string, in"
  },
  {
    "path": "adapter/inbound/manager.go",
    "chars": 4357,
    "preview": "package inbound\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.com/sagerne"
  },
  {
    "path": "adapter/inbound/registry.go",
    "chars": 2294,
    "preview": "package inbound\n\nimport (\n\t\"context\"\n\t\"sync\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.com/sagernet/sing-box/log"
  },
  {
    "path": "adapter/inbound.go",
    "chars": 3402,
    "preview": "package adapter\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"net/netip\"\n\t\"time\"\n\n\tC \"github.com/sagernet/sing-box/constant\"\n\t\"github.co"
  },
  {
    "path": "adapter/lifecycle.go",
    "chars": 2107,
    "preview": "package adapter\n\nimport (\n\t\"reflect\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\tE \"github.com/sagernet/sin"
  },
  {
    "path": "adapter/lifecycle_legacy.go",
    "chars": 1179,
    "preview": "package adapter\n\nfunc LegacyStart(starter any, stage StartStage) error {\n\tif lifecycle, isLifecycle := starter.(Lifecycl"
  },
  {
    "path": "adapter/neighbor.go",
    "chars": 413,
    "preview": "package adapter\n\nimport (\n\t\"net\"\n\t\"net/netip\"\n)\n\ntype NeighborEntry struct {\n\tAddress    netip.Addr\n\tMACAddress net.Hard"
  },
  {
    "path": "adapter/network.go",
    "chars": 1424,
    "preview": "package adapter\n\nimport (\n\t\"time\"\n\n\tC \"github.com/sagernet/sing-box/constant\"\n\t\"github.com/sagernet/sing-tun\"\n\t\"github.c"
  },
  {
    "path": "adapter/outbound/adapter.go",
    "chars": 989,
    "preview": "package outbound\n\nimport (\n\t\"github.com/sagernet/sing-box/option\"\n)\n\ntype Adapter struct {\n\toutboundType string\n\toutboun"
  },
  {
    "path": "adapter/outbound/manager.go",
    "chars": 9615,
    "preview": "package outbound\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\""
  },
  {
    "path": "adapter/outbound/registry.go",
    "chars": 2315,
    "preview": "package outbound\n\nimport (\n\t\"context\"\n\t\"sync\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.com/sagernet/sing-box/lo"
  },
  {
    "path": "adapter/outbound.go",
    "chars": 1228,
    "preview": "package adapter\n\nimport (\n\t\"context\"\n\t\"net/netip\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\t\"github.com/sagernet/sin"
  },
  {
    "path": "adapter/platform.go",
    "chars": 1819,
    "preview": "package adapter\n\nimport (\n\t\"github.com/sagernet/sing-box/option\"\n\t\"github.com/sagernet/sing-tun\"\n\t\"github.com/sagernet/s"
  },
  {
    "path": "adapter/prestart.go",
    "chars": 16,
    "preview": "package adapter\n"
  },
  {
    "path": "adapter/router.go",
    "chars": 3356,
    "preview": "package adapter\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"net\"\n\t\"net/http\"\n\t\"sync\"\n\t\"time\"\n\n\tC \"github.com/sagernet/sing-box/"
  },
  {
    "path": "adapter/rule.go",
    "chars": 591,
    "preview": "package adapter\n\nimport (\n\tC \"github.com/sagernet/sing-box/constant\"\n)\n\ntype HeadlessRule interface {\n\tMatch(metadata *I"
  },
  {
    "path": "adapter/service/adapter.go",
    "chars": 340,
    "preview": "package service\n\ntype Adapter struct {\n\tserviceType string\n\tserviceTag  string\n}\n\nfunc NewAdapter(serviceType string, se"
  },
  {
    "path": "adapter/service/manager.go",
    "chars": 4183,
    "preview": "package service\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.com/sagerne"
  },
  {
    "path": "adapter/service/registry.go",
    "chars": 2186,
    "preview": "package service\n\nimport (\n\t\"context\"\n\t\"sync\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.com/sagernet/sing-box/log"
  },
  {
    "path": "adapter/service.go",
    "chars": 600,
    "preview": "package adapter\n\nimport (\n\t\"context\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\t\"github.com/sagernet/sing-box/option\"\n)\n\ntype"
  },
  {
    "path": "adapter/ssm.go",
    "chars": 387,
    "preview": "package adapter\n\nimport (\n\t\"net\"\n\n\tN \"github.com/sagernet/sing/common/network\"\n)\n\ntype ManagedSSMServer interface {\n\tInb"
  },
  {
    "path": "adapter/time.go",
    "chars": 109,
    "preview": "package adapter\n\nimport \"time\"\n\ntype TimeService interface {\n\tSimpleLifecycle\n\tTimeFunc() func() time.Time\n}\n"
  },
  {
    "path": "adapter/upstream.go",
    "chars": 5132,
    "preview": "package adapter\n\nimport (\n\t\"context\"\n\t\"net\"\n\n\tM \"github.com/sagernet/sing/common/metadata\"\n\tN \"github.com/sagernet/sing/"
  },
  {
    "path": "adapter/upstream_legacy.go",
    "chars": 7018,
    "preview": "package adapter\n\nimport (\n\t\"context\"\n\t\"net\"\n\n\tE \"github.com/sagernet/sing/common/exceptions\"\n\t\"github.com/sagernet/sing/"
  },
  {
    "path": "adapter/v2ray.go",
    "chars": 430,
    "preview": "package adapter\n\nimport (\n\t\"context\"\n\t\"net\"\n\n\tN \"github.com/sagernet/sing/common/network\"\n)\n\ntype V2RayServerTransport i"
  },
  {
    "path": "box.go",
    "chars": 18306,
    "preview": "package box\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"runtime/debug\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\""
  },
  {
    "path": "cmd/internal/app_store_connect/main.go",
    "chars": 13764,
    "preview": "package main\n\nimport (\n\t\"context\"\n\t\"net/http\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/sagernet/asc-go/asc\"\n\t\"g"
  },
  {
    "path": "cmd/internal/build/main.go",
    "chars": 439,
    "preview": "package main\n\nimport (\n\t\"go/build\"\n\t\"os\"\n\t\"os/exec\"\n\n\t\"github.com/sagernet/sing-box/cmd/internal/build_shared\"\n\t\"github."
  },
  {
    "path": "cmd/internal/build_libbox/main.go",
    "chars": 6289,
    "preview": "package main\n\nimport (\n\t\"flag\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"strconv\"\n\t\"strings\"\n\n\t_ \"github.com/sagernet/gomobile"
  },
  {
    "path": "cmd/internal/build_shared/sdk.go",
    "chars": 2774,
    "preview": "package build_shared\n\nimport (\n\t\"go/build\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com"
  },
  {
    "path": "cmd/internal/build_shared/tag.go",
    "chars": 1260,
    "preview": "package build_shared\n\nimport (\n\t\"github.com/sagernet/sing-box/common/badversion\"\n\t\"github.com/sagernet/sing/common\"\n\t\"gi"
  },
  {
    "path": "cmd/internal/format_docs/main.go",
    "chars": 2667,
    "preview": "package main\n\nimport (\n\t\"bytes\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/sagernet/sing-box/log\"\n)\n\nfunc main() {\n"
  },
  {
    "path": "cmd/internal/protogen/main.go",
    "chars": 4966,
    "preview": "package main\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"go/build\"\n\t\"io\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"strings"
  },
  {
    "path": "cmd/internal/read_tag/main.go",
    "chars": 1375,
    "preview": "package main\n\nimport (\n\t\"flag\"\n\t\"os\"\n\n\t\"github.com/sagernet/sing-box/cmd/internal/build_shared\"\n\t\"github.com/sagernet/si"
  },
  {
    "path": "cmd/internal/tun_bench/main.go",
    "chars": 6881,
    "preview": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/netip\"\n\t\"os\"\n\t\"os/exec\"\n\t\"strings\"\n\t\"syscall\"\n\t\"time\"\n\n\tC \"github.c"
  },
  {
    "path": "cmd/internal/update_android_version/main.go",
    "chars": 2158,
    "preview": "package main\n\nimport (\n\t\"flag\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/sagernet/sing-box/c"
  },
  {
    "path": "cmd/internal/update_apple_version/main.go",
    "chars": 5178,
    "preview": "package main\n\nimport (\n\t\"flag\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"strings\"\n\n\t\"github.com/sagernet/sing-box/cmd/internal/"
  },
  {
    "path": "cmd/internal/update_certificates/main.go",
    "chars": 4055,
    "preview": "package main\n\nimport (\n\t\"encoding/csv\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\n\t\"golang"
  },
  {
    "path": "cmd/sing-box/cmd.go",
    "chars": 2202,
    "preview": "package main\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"os/user\"\n\t\"strconv\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/experimental/depre"
  },
  {
    "path": "cmd/sing-box/cmd_check.go",
    "chars": 684,
    "preview": "package main\n\nimport (\n\t\"context\"\n\n\t\"github.com/sagernet/sing-box\"\n\t\"github.com/sagernet/sing-box/log\"\n\n\t\"github.com/spf"
  },
  {
    "path": "cmd/sing-box/cmd_format.go",
    "chars": 1733,
    "preview": "package main\n\nimport (\n\t\"bytes\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\tE \"github.com/sagernet/sing"
  },
  {
    "path": "cmd/sing-box/cmd_generate.go",
    "chars": 1820,
    "preview": "package main\n\nimport (\n\t\"crypto/rand\"\n\t\"encoding/base64\"\n\t\"encoding/hex\"\n\t\"os\"\n\t\"strconv\"\n\n\t\"github.com/sagernet/sing-bo"
  },
  {
    "path": "cmd/sing-box/cmd_generate_ech.go",
    "chars": 722,
    "preview": "package main\n\nimport (\n\t\"os\"\n\n\t\"github.com/sagernet/sing-box/common/tls\"\n\t\"github.com/sagernet/sing-box/log\"\n\n\t\"github.c"
  },
  {
    "path": "cmd/sing-box/cmd_generate_tls.go",
    "chars": 1005,
    "preview": "package main\n\nimport (\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/common/tls\"\n\t\"github.com/sagernet/sing-box/log\"\n\n\t\""
  },
  {
    "path": "cmd/sing-box/cmd_generate_vapid.go",
    "chars": 860,
    "preview": "//go:build go1.20\n\npackage main\n\nimport (\n\t\"crypto/ecdh\"\n\t\"crypto/rand\"\n\t\"encoding/base64\"\n\t\"os\"\n\n\t\"github.com/sagernet/"
  },
  {
    "path": "cmd/sing-box/cmd_generate_wireguard.go",
    "chars": 1469,
    "preview": "package main\n\nimport (\n\t\"encoding/base64\"\n\t\"os\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\n\t\"github.com/spf13/cobra\"\n\t\"golang"
  },
  {
    "path": "cmd/sing-box/cmd_geoip.go",
    "chars": 940,
    "preview": "package main\n\nimport (\n\t\"github.com/sagernet/sing-box/log\"\n\tE \"github.com/sagernet/sing/common/exceptions\"\n\n\t\"github.com"
  },
  {
    "path": "cmd/sing-box/cmd_geoip_export.go",
    "chars": 2478,
    "preview": "package main\n\nimport (\n\t\"io\"\n\t\"net\"\n\t\"os\"\n\t\"strings\"\n\n\tC \"github.com/sagernet/sing-box/constant\"\n\t\"github.com/sagernet/s"
  },
  {
    "path": "cmd/sing-box/cmd_geoip_list.go",
    "chars": 497,
    "preview": "package main\n\nimport (\n\t\"os\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\n\t\"github.com/spf13/cobra\"\n)\n\nvar commandGeoipList = &"
  },
  {
    "path": "cmd/sing-box/cmd_geoip_lookup.go",
    "chars": 960,
    "preview": "package main\n\nimport (\n\t\"net/netip\"\n\t\"os\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\tE \"github.com/sagernet/sing/common/excep"
  },
  {
    "path": "cmd/sing-box/cmd_geosite.go",
    "chars": 902,
    "preview": "package main\n\nimport (\n\t\"github.com/sagernet/sing-box/common/geosite\"\n\t\"github.com/sagernet/sing-box/log\"\n\tE \"github.com"
  },
  {
    "path": "cmd/sing-box/cmd_geosite_export.go",
    "chars": 2128,
    "preview": "package main\n\nimport (\n\t\"io\"\n\t\"os\"\n\n\t\"github.com/sagernet/sing-box/common/geosite\"\n\tC \"github.com/sagernet/sing-box/cons"
  },
  {
    "path": "cmd/sing-box/cmd_geosite_list.go",
    "chars": 1016,
    "preview": "package main\n\nimport (\n\t\"os\"\n\t\"sort\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\tF \"github.com/sagernet/sing/common/format\"\n\n\t"
  },
  {
    "path": "cmd/sing-box/cmd_geosite_lookup.go",
    "chars": 2084,
    "preview": "package main\n\nimport (\n\t\"os\"\n\t\"sort\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\tE \"github.com/sagernet/sing/common/exceptions"
  },
  {
    "path": "cmd/sing-box/cmd_geosite_matcher.go",
    "chars": 1220,
    "preview": "package main\n\nimport (\n\t\"regexp\"\n\t\"strings\"\n\n\t\"github.com/sagernet/sing-box/common/geosite\"\n)\n\ntype searchGeositeMatcher"
  },
  {
    "path": "cmd/sing-box/cmd_merge.go",
    "chars": 3876,
    "preview": "package main\n\nimport (\n\t\"bytes\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\tC \"github.com/sagernet/sing-box/constant\"\n\t\"github.c"
  },
  {
    "path": "cmd/sing-box/cmd_rule_set.go",
    "chars": 196,
    "preview": "package main\n\nimport (\n\t\"github.com/spf13/cobra\"\n)\n\nvar commandRuleSet = &cobra.Command{\n\tUse:   \"rule-set\",\n\tShort: \"Ma"
  },
  {
    "path": "cmd/sing-box/cmd_rule_set_compile.go",
    "chars": 2538,
    "preview": "package main\n\nimport (\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/sagernet/sing-box/common/srs\"\n\tC \"github.com/sagernet/sing-b"
  },
  {
    "path": "cmd/sing-box/cmd_rule_set_convert.go",
    "chars": 2140,
    "preview": "package main\n\nimport (\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/sagernet/sing-box/common/convertor/adguard\"\n\t\"github.com/sag"
  },
  {
    "path": "cmd/sing-box/cmd_rule_set_decompile.go",
    "chars": 2354,
    "preview": "package main\n\nimport (\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/sagernet/sing-box/common/srs\"\n\tC \"github.com/sagernet/sing-b"
  },
  {
    "path": "cmd/sing-box/cmd_rule_set_format.go",
    "chars": 1853,
    "preview": "package main\n\nimport (\n\t\"bytes\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\t\"github.com/sagernet/"
  },
  {
    "path": "cmd/sing-box/cmd_rule_set_match.go",
    "chars": 2674,
    "preview": "package main\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"githu"
  },
  {
    "path": "cmd/sing-box/cmd_rule_set_merge.go",
    "chars": 4185,
    "preview": "package main\n\nimport (\n\t\"bytes\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"sort\"\n\t\"strings\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\t\"g"
  },
  {
    "path": "cmd/sing-box/cmd_rule_set_upgrade.go",
    "chars": 2190,
    "preview": "package main\n\nimport (\n\t\"bytes\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\n\tC \"github.com/sagernet/sing-box/constant\"\n\t\"github.com/sa"
  },
  {
    "path": "cmd/sing-box/cmd_run.go",
    "chars": 4783,
    "preview": "package main\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"os\"\n\t\"os/signal\"\n\t\"path/filepath\"\n\truntimeDebug \"runtime/debug\"\n\t\"sort\"\n\t\"stri"
  },
  {
    "path": "cmd/sing-box/cmd_tools.go",
    "chars": 1357,
    "preview": "package main\n\nimport (\n\t\"errors\"\n\t\"os\"\n\n\t\"github.com/sagernet/sing-box\"\n\tE \"github.com/sagernet/sing/common/exceptions\"\n"
  },
  {
    "path": "cmd/sing-box/cmd_tools_connect.go",
    "chars": 1791,
    "preview": "package main\n\nimport (\n\t\"context\"\n\t\"os\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\t\"github.com/sagernet/sing/common\"\n\t\"github"
  },
  {
    "path": "cmd/sing-box/cmd_tools_fetch.go",
    "chars": 2375,
    "preview": "package main\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"os\"\n\n\tC \"github.com/sagernet/sing-box/"
  },
  {
    "path": "cmd/sing-box/cmd_tools_fetch_http3.go",
    "chars": 935,
    "preview": "//go:build with_quic\n\npackage main\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"net/http\"\n\n\t\"github.com/sagernet/quic-go\"\n\t\"gith"
  },
  {
    "path": "cmd/sing-box/cmd_tools_fetch_http3_stub.go",
    "chars": 250,
    "preview": "//go:build !with_quic\n\npackage main\n\nimport (\n\t\"net/url\"\n\t\"os\"\n\n\tbox \"github.com/sagernet/sing-box\"\n)\n\nfunc initializeHT"
  },
  {
    "path": "cmd/sing-box/cmd_tools_synctime.go",
    "chars": 1718,
    "preview": "package main\n\nimport (\n\t\"context\"\n\t\"os\"\n\n\tC \"github.com/sagernet/sing-box/constant\"\n\t\"github.com/sagernet/sing-box/log\"\n"
  },
  {
    "path": "cmd/sing-box/cmd_version.go",
    "chars": 1252,
    "preview": "package main\n\nimport (\n\t\"os\"\n\t\"runtime\"\n\t\"runtime/debug\"\n\n\tC \"github.com/sagernet/sing-box/constant\"\n\n\t\"github.com/spf13"
  },
  {
    "path": "cmd/sing-box/generate_completions.go",
    "chars": 573,
    "preview": "//go:build generate && generate_completions\n\npackage main\n\nimport \"github.com/sagernet/sing-box/log\"\n\nfunc main() {\n\terr"
  },
  {
    "path": "cmd/sing-box/main.go",
    "chars": 162,
    "preview": "//go:build !generate\n\npackage main\n\nimport \"github.com/sagernet/sing-box/log\"\n\nfunc main() {\n\tif err := mainCommand.Exec"
  },
  {
    "path": "common/badtls/raw_conn.go",
    "chars": 5218,
    "preview": "//go:build go1.25 && badlinkname\n\npackage badtls\n\nimport (\n\t\"bytes\"\n\t\"os\"\n\t\"reflect\"\n\t\"sync/atomic\"\n\t\"unsafe\"\n\n\tE \"githu"
  },
  {
    "path": "common/badtls/raw_half_conn.go",
    "chars": 4200,
    "preview": "//go:build go1.25 && badlinkname\n\npackage badtls\n\nimport (\n\t\"hash\"\n\t\"reflect\"\n\t\"sync\"\n\t\"unsafe\"\n\n\tE \"github.com/sagernet"
  },
  {
    "path": "common/badtls/read_wait.go",
    "chars": 1768,
    "preview": "//go:build go1.25 && badlinkname\n\npackage badtls\n\nimport (\n\t\"github.com/sagernet/sing/common/buf\"\n\tN \"github.com/sagerne"
  },
  {
    "path": "common/badtls/read_wait_stub.go",
    "chars": 195,
    "preview": "//go:build !go1.25 || !badlinkname\n\npackage badtls\n\nimport (\n\t\"os\"\n\n\t\"github.com/sagernet/sing/common/tls\"\n)\n\nfunc NewRe"
  },
  {
    "path": "common/badtls/registry.go",
    "chars": 2219,
    "preview": "//go:build go1.25 && badlinkname\n\npackage badtls\n\nimport (\n\t\"crypto/tls\"\n\t\"net\"\n\t\"unsafe\"\n)\n\ntype Methods struct {\n\tread"
  },
  {
    "path": "common/badtls/registry_utls.go",
    "chars": 1989,
    "preview": "//go:build go1.25 && badlinkname\n\npackage badtls\n\nimport (\n\t\"net\"\n\t\"unsafe\"\n\n\tN \"github.com/sagernet/sing/common/network"
  },
  {
    "path": "common/badversion/version.go",
    "chars": 4215,
    "preview": "package badversion\n\nimport (\n\t\"strconv\"\n\t\"strings\"\n\n\tF \"github.com/sagernet/sing/common/format\"\n\n\t\"golang.org/x/mod/semv"
  },
  {
    "path": "common/badversion/version_json.go",
    "chars": 332,
    "preview": "package badversion\n\nimport \"github.com/sagernet/sing/common/json\"\n\nfunc (v Version) MarshalJSON() ([]byte, error) {\n\tret"
  },
  {
    "path": "common/badversion/version_test.go",
    "chars": 596,
    "preview": "package badversion\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestCompareVersion(t *testing.T)"
  },
  {
    "path": "common/certificate/chrome.go",
    "chars": 170799,
    "preview": "// Code generated by 'make update_certificates'. DO NOT EDIT.\n\npackage certificate\n\nimport \"crypto/x509\"\n\nvar chromeIncl"
  },
  {
    "path": "common/certificate/mozilla.go",
    "chars": 271452,
    "preview": "// Code generated by 'make update_certificates'. DO NOT EDIT.\n\npackage certificate\n\nimport \"crypto/x509\"\n\nvar mozillaInc"
  },
  {
    "path": "common/certificate/store.go",
    "chars": 4782,
    "preview": "package certificate\n\nimport (\n\t\"context\"\n\t\"crypto/x509\"\n\t\"io/fs\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com"
  },
  {
    "path": "common/compatible/map.go",
    "chars": 982,
    "preview": "package compatible\n\nimport \"sync\"\n\n// Map is a generics sync.Map\ntype Map[K comparable, V any] struct {\n\tm sync.Map\n}\n\nf"
  },
  {
    "path": "common/convertor/adguard/convertor.go",
    "chars": 14015,
    "preview": "package adguard\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"io\"\n\t\"net/netip\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\n\tC \"github.com/sagernet/sing"
  },
  {
    "path": "common/convertor/adguard/convertor_test.go",
    "chars": 3234,
    "preview": "package adguard\n\nimport (\n\t\"context\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.com/sagerne"
  },
  {
    "path": "common/dialer/default.go",
    "chars": 14224,
    "preview": "package dialer\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"net\"\n\t\"net/netip\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/ada"
  },
  {
    "path": "common/dialer/default_parallel_interface.go",
    "chars": 8815,
    "preview": "package dialer\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\tC \"github.com/sagernet/sing"
  },
  {
    "path": "common/dialer/default_parallel_network.go",
    "chars": 5487,
    "preview": "package dialer\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"net/netip\"\n\t\"time\"\n\n\tC \"github.com/sagernet/sing-box/constant\"\n\t\"github.com"
  },
  {
    "path": "common/dialer/detour.go",
    "chars": 1996,
    "preview": "package dialer\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"sync\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.com/sagernet/sing/c"
  },
  {
    "path": "common/dialer/dialer.go",
    "chars": 5961,
    "preview": "package dialer\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"net/netip\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\tC \"github.com/"
  },
  {
    "path": "common/dialer/resolve.go",
    "chars": 6091,
    "preview": "package dialer\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\tC \"github.com/sager"
  },
  {
    "path": "common/dialer/router.go",
    "chars": 901,
    "preview": "package dialer\n\nimport (\n\t\"context\"\n\t\"net\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\tM \"github.com/sagernet/sing/common/"
  },
  {
    "path": "common/dialer/tfo.go",
    "chars": 3613,
    "preview": "package dialer\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"net\"\n\t\"os\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing/common"
  },
  {
    "path": "common/dialer/wireguard.go",
    "chars": 141,
    "preview": "package dialer\n\nimport (\n\t\"github.com/sagernet/sing/common/control\"\n)\n\ntype WireGuardListener interface {\n\tWireGuardCont"
  },
  {
    "path": "common/geoip/reader.go",
    "chars": 789,
    "preview": "package geoip\n\nimport (\n\t\"net/netip\"\n\n\tE \"github.com/sagernet/sing/common/exceptions\"\n\n\t\"github.com/oschwald/maxminddb-g"
  },
  {
    "path": "common/geosite/compat_test.go",
    "chars": 6397,
    "preview": "package geosite\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/sagernet/sing/common/"
  },
  {
    "path": "common/geosite/geosite_test.go",
    "chars": 699,
    "preview": "package geosite_test\n\nimport (\n\t\"bytes\"\n\t\"testing\"\n\n\t\"github.com/sagernet/sing-box/common/geosite\"\n\n\t\"github.com/stretch"
  },
  {
    "path": "common/geosite/reader.go",
    "chars": 3244,
    "preview": "package geosite\n\nimport (\n\t\"bufio\"\n\t\"encoding/binary\"\n\t\"io\"\n\t\"os\"\n\t\"sync\"\n\t\"sync/atomic\"\n\n\tE \"github.com/sagernet/sing/c"
  },
  {
    "path": "common/geosite/rule.go",
    "chars": 2763,
    "preview": "package geosite\n\nimport \"github.com/sagernet/sing-box/option\"\n\ntype ItemType = uint8\n\nconst (\n\tRuleTypeDomain ItemType ="
  },
  {
    "path": "common/geosite/writer.go",
    "chars": 1358,
    "preview": "package geosite\n\nimport (\n\t\"bytes\"\n\t\"sort\"\n\n\t\"github.com/sagernet/sing/common/varbin\"\n)\n\nfunc Write(writer varbin.Writer"
  },
  {
    "path": "common/interrupt/conn.go",
    "chars": 1289,
    "preview": "package interrupt\n\nimport (\n\t\"net\"\n\n\t\"github.com/sagernet/sing/common/x/list\"\n)\n\n/*type GroupedConn interface {\n\tMarkAsI"
  },
  {
    "path": "common/interrupt/context.go",
    "chars": 359,
    "preview": "package interrupt\n\nimport \"context\"\n\ntype contextKeyIsExternalConnection struct{}\n\nfunc ContextWithIsExternalConnection("
  },
  {
    "path": "common/interrupt/group.go",
    "chars": 1232,
    "preview": "package interrupt\n\nimport (\n\t\"io\"\n\t\"net\"\n\t\"sync\"\n\n\t\"github.com/sagernet/sing/common/x/list\"\n)\n\ntype Group struct {\n\tacce"
  },
  {
    "path": "common/ja3/LICENSE",
    "chars": 1515,
    "preview": "BSD 3-Clause License\n\nCopyright (c) 2018, Open Systems AG\nAll rights reserved.\n\nRedistribution and use in source and bin"
  },
  {
    "path": "common/ja3/README.md",
    "chars": 47,
    "preview": "# JA3\n\nmod from: https://github.com/open-ch/ja3"
  },
  {
    "path": "common/ja3/error.go",
    "chars": 809,
    "preview": "// Copyright (c) 2018, Open Systems AG. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style li"
  },
  {
    "path": "common/ja3/ja3.go",
    "chars": 1938,
    "preview": "// Copyright (c) 2018, Open Systems AG. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style li"
  },
  {
    "path": "common/ja3/parser.go",
    "chars": 10722,
    "preview": "// Copyright (c) 2018, Open Systems AG. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style li"
  },
  {
    "path": "common/ktls/ktls.go",
    "chars": 3091,
    "preview": "//go:build linux && go1.25 && badlinkname\n\npackage ktls\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/tls\"\n\t\"errors\"\n\t\"io\"\n\t\"ne"
  },
  {
    "path": "common/ktls/ktls_alert.go",
    "chars": 2389,
    "preview": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "common/ktls/ktls_cipher_suites_linux.go",
    "chars": 10804,
    "preview": "// Copyright 2010 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "common/ktls/ktls_close.go",
    "chars": 1682,
    "preview": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "common/ktls/ktls_const.go",
    "chars": 965,
    "preview": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "common/ktls/ktls_handshake_messages.go",
    "chars": 6728,
    "preview": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "common/ktls/ktls_key_update.go",
    "chars": 5162,
    "preview": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "common/ktls/ktls_linux.go",
    "chars": 8784,
    "preview": "//go:build linux && go1.25 && badlinkname\n\npackage ktls\n\nimport (\n\t\"crypto/tls\"\n\t\"errors\"\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n\t\"sync\""
  },
  {
    "path": "common/ktls/ktls_prf.go",
    "chars": 1108,
    "preview": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "common/ktls/ktls_read.go",
    "chars": 9946,
    "preview": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "common/ktls/ktls_read_wait.go",
    "chars": 1014,
    "preview": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "common/ktls/ktls_stub_nolinkname.go",
    "chars": 469,
    "preview": "//go:build linux && go1.25 && !badlinkname\n\npackage ktls\n\nimport (\n\t\"context\"\n\n\tE \"github.com/sagernet/sing/common/excep"
  },
  {
    "path": "common/ktls/ktls_stub_nonlinux.go",
    "chars": 374,
    "preview": "//go:build !linux\n\npackage ktls\n\nimport (\n\t\"context\"\n\n\tE \"github.com/sagernet/sing/common/exceptions\"\n\t\"github.com/sager"
  },
  {
    "path": "common/ktls/ktls_stub_oldgo.go",
    "chars": 413,
    "preview": "//go:build linux && !go1.25\n\npackage ktls\n\nimport (\n\t\"context\"\n\n\tE \"github.com/sagernet/sing/common/exceptions\"\n\t\"github"
  },
  {
    "path": "common/ktls/ktls_write.go",
    "chars": 4195,
    "preview": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "common/listener/listener.go",
    "chars": 4817,
    "preview": "package listener\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"net/netip\"\n\t\"runtime\"\n\t\"strings\"\n\t\"sync/atomic\"\n\n\t\"github.com/sagernet/si"
  },
  {
    "path": "common/listener/listener_tcp.go",
    "chars": 3683,
    "preview": "package listener\n\nimport (\n\t\"net\"\n\t\"net/netip\"\n\t\"strings\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\""
  },
  {
    "path": "common/listener/listener_udp.go",
    "chars": 6372,
    "preview": "package listener\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"net/netip\"\n\t\"os\"\n\t\"strings\"\n\t\"syscall\"\n\n\t\"github.com/sagernet/sing-box/ad"
  },
  {
    "path": "common/mux/client.go",
    "chars": 1832,
    "preview": "package mux\n\nimport (\n\t\"context\"\n\t\"net\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\tC \"github.com/sagernet/sing-box/consta"
  },
  {
    "path": "common/mux/router.go",
    "chars": 2805,
    "preview": "package mux\n\nimport (\n\t\"context\"\n\t\"net\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\tC \"github.com/sagernet/sing-box/consta"
  },
  {
    "path": "common/pipelistener/listener.go",
    "chars": 806,
    "preview": "package pipelistener\n\nimport (\n\t\"io\"\n\t\"net\"\n)\n\nvar _ net.Listener = (*Listener)(nil)\n\ntype Listener struct {\n\tpipe chan "
  },
  {
    "path": "common/process/searcher.go",
    "chars": 1009,
    "preview": "package process\n\nimport (\n\t\"context\"\n\t\"net/netip\"\n\t\"os/user\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.com/sager"
  },
  {
    "path": "common/process/searcher_android.go",
    "chars": 1083,
    "preview": "package process\n\nimport (\n\t\"context\"\n\t\"net/netip\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.com/sagernet/sing-tu"
  },
  {
    "path": "common/process/searcher_darwin.go",
    "chars": 3624,
    "preview": "package process\n\nimport (\n\t\"context\"\n\t\"encoding/binary\"\n\t\"net/netip\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\t\"syscall\"\n\t\"unsafe\"\n\n\t"
  },
  {
    "path": "common/process/searcher_linux.go",
    "chars": 870,
    "preview": "//go:build linux && !android\n\npackage process\n\nimport (\n\t\"context\"\n\t\"net/netip\"\n\n\t\"github.com/sagernet/sing-box/adapter\""
  },
  {
    "path": "common/process/searcher_linux_shared.go",
    "chars": 4605,
    "preview": "//go:build linux\n\npackage process\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/netip\"\n\t\"os\"\n\t\"path\"\n\t\"strin"
  },
  {
    "path": "common/process/searcher_stub.go",
    "chars": 153,
    "preview": "//go:build !linux && !windows && !darwin\n\npackage process\n\nimport (\n\t\"os\"\n)\n\nfunc NewSearcher(_ Config) (Searcher, error"
  },
  {
    "path": "common/process/searcher_windows.go",
    "chars": 1554,
    "preview": "package process\n\nimport (\n\t\"context\"\n\t\"net/netip\"\n\t\"syscall\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\tE \"github.com/sag"
  },
  {
    "path": "common/redir/redir_darwin.go",
    "chars": 1642,
    "preview": "package redir\n\nimport (\n\t\"net\"\n\t\"net/netip\"\n\t\"syscall\"\n\t\"unsafe\"\n\n\tM \"github.com/sagernet/sing/common/metadata\"\n)\n\nconst"
  },
  {
    "path": "common/redir/redir_linux.go",
    "chars": 1146,
    "preview": "package redir\n\nimport (\n\t\"encoding/binary\"\n\t\"net\"\n\t\"net/netip\"\n\t\"os\"\n\t\"syscall\"\n\n\t\"github.com/sagernet/sing/common\"\n\t\"gi"
  },
  {
    "path": "common/redir/redir_other.go",
    "chars": 210,
    "preview": "//go:build !linux && !darwin\n\npackage redir\n\nimport (\n\t\"net\"\n\t\"net/netip\"\n\t\"os\"\n)\n\nfunc GetOriginalDestination(conn net."
  },
  {
    "path": "common/redir/tproxy_linux.go",
    "chars": 1953,
    "preview": "package redir\n\nimport (\n\t\"encoding/binary\"\n\t\"net/netip\"\n\t\"syscall\"\n\n\t\"github.com/sagernet/sing/common/control\"\n\tE \"githu"
  },
  {
    "path": "common/redir/tproxy_other.go",
    "chars": 359,
    "preview": "//go:build !linux\n\npackage redir\n\nimport (\n\t\"net/netip\"\n\t\"os\"\n\n\t\"github.com/sagernet/sing/common/control\"\n)\n\nfunc TProxy"
  },
  {
    "path": "common/settings/proxy_android.go",
    "chars": 1746,
    "preview": "package settings\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"strings\"\n\n\tC \"github.com/sagernet/sing-box/constant\"\n\tE \"github.com/sagern"
  },
  {
    "path": "common/settings/proxy_darwin.go",
    "chars": 3582,
    "preview": "package settings\n\nimport (\n\t\"context\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.com/sagern"
  },
  {
    "path": "common/settings/proxy_linux.go",
    "chars": 4558,
    "preview": "//go:build linux && !android\n\npackage settings\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"os/exec\"\n\t\"strings\"\n\n\t\"github.com/sagernet/s"
  },
  {
    "path": "common/settings/proxy_stub.go",
    "chars": 272,
    "preview": "//go:build !(windows || linux || darwin)\n\npackage settings\n\nimport (\n\t\"context\"\n\t\"os\"\n\n\tM \"github.com/sagernet/sing/comm"
  },
  {
    "path": "common/settings/proxy_windows.go",
    "chars": 847,
    "preview": "package settings\n\nimport (\n\t\"context\"\n\n\tM \"github.com/sagernet/sing/common/metadata\"\n\t\"github.com/sagernet/sing/common/w"
  },
  {
    "path": "common/settings/system_proxy.go",
    "chars": 100,
    "preview": "package settings\n\ntype SystemProxy interface {\n\tIsEnabled() bool\n\tEnable() error\n\tDisable() error\n}\n"
  },
  {
    "path": "common/settings/wifi.go",
    "chars": 161,
    "preview": "package settings\n\nimport \"github.com/sagernet/sing-box/adapter\"\n\ntype WIFIMonitor interface {\n\tReadWIFIState() adapter.W"
  },
  {
    "path": "common/settings/wifi_linux.go",
    "chars": 1013,
    "preview": "package settings\n\nimport (\n\t\"github.com/sagernet/sing-box/adapter\"\n\tE \"github.com/sagernet/sing/common/exceptions\"\n)\n\nty"
  },
  {
    "path": "common/settings/wifi_linux_connman.go",
    "chars": 3745,
    "preview": "//go:build linux\n\npackage settings\n\nimport (\n\t\"context\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\n\t\"g"
  },
  {
    "path": "common/settings/wifi_linux_iwd.go",
    "chars": 4355,
    "preview": "//go:build linux\n\npackage settings\n\nimport (\n\t\"context\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\n\t\"g"
  },
  {
    "path": "common/settings/wifi_linux_nm.go",
    "chars": 4618,
    "preview": "//go:build linux\n\npackage settings\n\nimport (\n\t\"context\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\n\t\"g"
  },
  {
    "path": "common/settings/wifi_linux_wpa.go",
    "chars": 5515,
    "preview": "package settings\n\nimport (\n\t\"bufio\"\n\t\"context\"\n\t\"fmt\"\n\t\"net\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\""
  },
  {
    "path": "common/settings/wifi_stub.go",
    "chars": 452,
    "preview": "//go:build !linux && !windows\n\npackage settings\n\nimport (\n\t\"os\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n)\n\ntype stubWIF"
  },
  {
    "path": "common/settings/wifi_windows.go",
    "chars": 3083,
    "preview": "//go:build windows\n\npackage settings\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"strings\"\n\t\"sync\"\n\t\"syscall\"\n\n\t\"github.com/sagernet/si"
  }
]

// ... and 822 more files (download for full content)

About this extraction

This page contains the full source code of the SagerNet/sing-box GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1022 files (3.6 MB), approximately 999.9k tokens, and a symbol index with 5675 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!