Full Code of reF1nd/sing-box for AI

testing 6b07a229185d cached
1205 files
5.1 MB
1.4M tokens
7773 symbols
1 requests
Download .txt
Showing preview only (5,622K chars total). Download the full file or copy to clipboard to get everything.
Repository: reF1nd/sing-box
Branch: testing
Commit: 6b07a229185d
Files: 1205
Total size: 5.1 MB

Directory structure:
gitextract_yza4ly9v/

├── .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
│   ├── detect_track.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
│       └── test.yml
├── .gitignore
├── .gitmodules
├── .golangci.yml
├── Dockerfile
├── Dockerfile.binary
├── LICENSE
├── Makefile
├── README.md
├── adapter/
│   ├── certificate/
│   │   ├── adapter.go
│   │   ├── manager.go
│   │   └── registry.go
│   ├── certificate.go
│   ├── certificate_darwin.go
│   ├── certificate_provider.go
│   ├── connections.go
│   ├── dns.go
│   ├── endpoint/
│   │   ├── adapter.go
│   │   ├── manager.go
│   │   └── registry.go
│   ├── endpoint.go
│   ├── experimental.go
│   ├── fakeip.go
│   ├── fakeip_metadata.go
│   ├── handler.go
│   ├── http.go
│   ├── inbound/
│   │   ├── adapter.go
│   │   ├── manager.go
│   │   └── registry.go
│   ├── inbound.go
│   ├── inbound_test.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
│   ├── tailscale.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_networkquality.go
│       ├── cmd_tools_stun.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/
│   │   ├── anchors_darwin.h
│   │   ├── anchors_darwin.m
│   │   ├── chrome.go
│   │   ├── chrome.pem
│   │   ├── mozilla.go
│   │   ├── mozilla.pem
│   │   ├── store.go
│   │   ├── store_darwin.go
│   │   └── store_other.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
│   ├── httpclient/
│   │   ├── apple_transport_darwin.go
│   │   ├── apple_transport_darwin.h
│   │   ├── apple_transport_darwin.m
│   │   ├── apple_transport_darwin_test.go
│   │   ├── apple_transport_stub.go
│   │   ├── client.go
│   │   ├── context.go
│   │   ├── helpers.go
│   │   ├── helpers_test.go
│   │   ├── http1_transport.go
│   │   ├── http2_config.go
│   │   ├── http2_fallback_transport.go
│   │   ├── http2_fallback_transport_test.go
│   │   ├── http2_transport.go
│   │   ├── http3_transport.go
│   │   ├── http3_transport_stub.go
│   │   ├── http3_transport_test.go
│   │   ├── managed_transport.go
│   │   └── manager.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
│   ├── networkquality/
│   │   ├── http.go
│   │   ├── http3.go
│   │   ├── http3_stub.go
│   │   └── networkquality.go
│   ├── pipelistener/
│   │   └── listener.go
│   ├── process/
│   │   ├── searcher.go
│   │   ├── searcher_android.go
│   │   ├── searcher_darwin.go
│   │   ├── searcher_darwin_shared.go
│   │   ├── searcher_linux.go
│   │   ├── searcher_linux_shared.go
│   │   ├── searcher_linux_shared_test.go
│   │   ├── searcher_stub.go
│   │   └── searcher_windows.go
│   ├── proxybridge/
│   │   └── bridge.go
│   ├── redir/
│   │   ├── redir_darwin.go
│   │   ├── redir_linux.go
│   │   ├── redir_other.go
│   │   ├── tproxy_linux.go
│   │   └── tproxy_other.go
│   ├── schannel/
│   │   ├── doc.go
│   │   ├── schannel_windows.go
│   │   ├── schannel_windows_test.go
│   │   ├── syscall_windows.go
│   │   ├── types_windows.go
│   │   └── zsyscall_windows.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
│   ├── stun/
│   │   └── stun.go
│   ├── taskmonitor/
│   │   └── monitor.go
│   ├── tls/
│   │   ├── acme.go
│   │   ├── acme_logger.go
│   │   ├── acme_stub.go
│   │   ├── apple_client.go
│   │   ├── apple_client_platform.go
│   │   ├── apple_client_platform_benchmark_test.go
│   │   ├── apple_client_platform_darwin.h
│   │   ├── apple_client_platform_darwin.m
│   │   ├── apple_client_platform_dispatch_test.go
│   │   ├── apple_client_platform_dispatch_testhelper_darwin.go
│   │   ├── apple_client_platform_test.go
│   │   ├── apple_client_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
│   │   ├── system_client.go
│   │   ├── system_client_engine.go
│   │   ├── time_wrapper.go
│   │   ├── utls_client.go
│   │   ├── utls_client_test.go
│   │   ├── utls_stub.go
│   │   ├── windows_client.go
│   │   ├── windows_client_stub.go
│   │   └── windows_client_test.go
│   ├── tlsfragment/
│   │   ├── conn.go
│   │   ├── conn_test.go
│   │   ├── index.go
│   │   ├── index_test.go
│   │   ├── wait_darwin.go
│   │   ├── wait_linux.go
│   │   ├── wait_stub.go
│   │   └── wait_windows.go
│   ├── tlsspoof/
│   │   ├── README.md
│   │   ├── client_hello.go
│   │   ├── endpoints.go
│   │   ├── integration_darwin_test.go
│   │   ├── integration_linux_test.go
│   │   ├── integration_test.go
│   │   ├── integration_tls_test.go
│   │   ├── integration_unix_test.go
│   │   ├── integration_windows_test.go
│   │   ├── packet.go
│   │   ├── packet_darwin.go
│   │   ├── raw_darwin.go
│   │   ├── raw_linux.go
│   │   ├── raw_stub.go
│   │   ├── raw_unix.go
│   │   ├── raw_windows.go
│   │   ├── spoof.go
│   │   └── testdata_test.go
│   ├── uot/
│   │   └── router.go
│   ├── urltest/
│   │   └── urltest.go
│   └── windivert/
│       ├── address_test.go
│       ├── assets/
│       │   ├── LICENSE.txt
│       │   ├── WinDivert32.sys
│       │   └── WinDivert64.sys
│       ├── assets_386.go
│       ├── assets_amd64.go
│       ├── assets_unsupported.go
│       ├── driver_windows.go
│       ├── filter.go
│       ├── filter_test.go
│       ├── handle_windows.go
│       ├── handle_windows_test.go
│       ├── integration_windows_test.go
│       └── windivert.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
│   ├── tls.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
│   ├── repro_test.go
│   ├── router.go
│   ├── router_test.go
│   ├── transport/
│   │   ├── conn_pool.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_cgo.go
│   │   │   ├── local_darwin_stun.go
│   │   │   ├── local_dhcp.go
│   │   │   ├── local_neighbor.go
│   │   │   ├── local_nodhcp.go
│   │   │   ├── local_other.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
│   │   ├── mdns/
│   │   │   └── mdns.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
│   │   │       ├── mdns.md
│   │   │       ├── mdns.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
│   │   │   ├── cloudflared.md
│   │   │   ├── cloudflared.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
│   │   │   ├── hysteria-realm.md
│   │   │   ├── hysteria-realm.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/
│   │       ├── certificate-provider/
│   │       │   ├── acme.md
│   │       │   ├── acme.zh.md
│   │       │   ├── cloudflare-origin-ca.md
│   │       │   ├── cloudflare-origin-ca.zh.md
│   │       │   ├── index.md
│   │       │   ├── index.zh.md
│   │       │   ├── tailscale.md
│   │       │   └── tailscale.zh.md
│   │       ├── dial.md
│   │       ├── dial.zh.md
│   │       ├── dns01_challenge.md
│   │       ├── dns01_challenge.zh.md
│   │       ├── http-client.md
│   │       ├── http-client.zh.md
│   │       ├── http2.md
│   │       ├── http2.zh.md
│   │       ├── listen.md
│   │       ├── listen.zh.md
│   │       ├── multiplex.md
│   │       ├── multiplex.zh.md
│   │       ├── neighbor.md
│   │       ├── neighbor.zh.md
│   │       ├── pre-match.md
│   │       ├── pre-match.zh.md
│   │       ├── quic.md
│   │       ├── quic.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
│   │   ├── dns_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
│   │   ├── command_types_nq.go
│   │   ├── command_types_stun.go
│   │   ├── command_types_tailscale.go
│   │   ├── command_types_tailscale_ping.go
│   │   ├── config.go
│   │   ├── connection_owner_darwin.go
│   │   ├── debug.go
│   │   ├── deprecated.go
│   │   ├── dns.go
│   │   ├── fdroid.go
│   │   ├── fdroid_mirrors.go
│   │   ├── ffi.json
│   │   ├── http.go
│   │   ├── internal/
│   │   │   ├── oomprofile/
│   │   │   │   ├── builder.go
│   │   │   │   ├── defs_darwin_amd64.go
│   │   │   │   ├── defs_darwin_arm64.go
│   │   │   │   ├── linkname.go
│   │   │   │   ├── mapping_darwin.go
│   │   │   │   ├── mapping_linux.go
│   │   │   │   ├── mapping_windows.go
│   │   │   │   ├── oomprofile.go
│   │   │   │   └── protobuf.go
│   │   │   └── procfs/
│   │   │       └── procfs.go
│   │   ├── iterator.go
│   │   ├── link_flags_stub.go
│   │   ├── link_flags_unix.go
│   │   ├── log.go
│   │   ├── monitor.go
│   │   ├── neighbor.go
│   │   ├── neighbor_darwin.go
│   │   ├── neighbor_linux.go
│   │   ├── neighbor_stub.go
│   │   ├── neighbor_unix.go
│   │   ├── networkquality.go
│   │   ├── oom_report.go
│   │   ├── panic.go
│   │   ├── pidfd_android.go
│   │   ├── platform.go
│   │   ├── pprof.go
│   │   ├── profile_import.go
│   │   ├── remote_profile.go
│   │   ├── report.go
│   │   ├── semver.go
│   │   ├── semver_test.go
│   │   ├── service.go
│   │   ├── service_other.go
│   │   ├── service_windows.go
│   │   ├── setup.go
│   │   ├── signal_handler_darwin.go
│   │   ├── signal_handler_stub.go
│   │   ├── stun.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/
│   ├── acme.go
│   ├── acme_stub.go
│   ├── ccm.go
│   ├── ccm_stub.go
│   ├── ccm_stub_darwin.go
│   ├── clashapi.go
│   ├── clashapi_stub.go
│   ├── cloudflared.go
│   ├── cloudflared_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/
│   ├── acme.go
│   ├── anytls.go
│   ├── ccm.go
│   ├── certificate.go
│   ├── certificate_provider.go
│   ├── cloudflared.go
│   ├── debug.go
│   ├── direct.go
│   ├── dns.go
│   ├── dns_record.go
│   ├── dns_record_test.go
│   ├── dns_test.go
│   ├── endpoint.go
│   ├── experimental.go
│   ├── group.go
│   ├── http.go
│   ├── hysteria.go
│   ├── hysteria2.go
│   ├── inbound.go
│   ├── multiplex.go
│   ├── naive.go
│   ├── ntp.go
│   ├── ocm.go
│   ├── oom_killer.go
│   ├── options.go
│   ├── origin_ca.go
│   ├── outbound.go
│   ├── platform.go
│   ├── redir.go
│   ├── resolved.go
│   ├── route.go
│   ├── rule.go
│   ├── rule_action.go
│   ├── rule_action_test.go
│   ├── rule_dns.go
│   ├── rule_nested.go
│   ├── rule_nested_test.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
│   ├── cloudflare/
│   │   └── inbound.go
│   ├── direct/
│   │   ├── inbound.go
│   │   └── outbound.go
│   ├── dns/
│   │   ├── handle.go
│   │   └── outbound.go
│   ├── group/
│   │   ├── selector.go
│   │   └── urltest.go
│   ├── http/
│   │   ├── inbound.go
│   │   └── outbound.go
│   ├── hysteria/
│   │   ├── inbound.go
│   │   ├── outbound.go
│   │   └── quic.go
│   ├── hysteria2/
│   │   ├── inbound.go
│   │   ├── outbound.go
│   │   ├── realm.go
│   │   └── realm_server.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/
│   │   ├── certificate_provider.go
│   │   ├── dns_transport.go
│   │   ├── endpoint.go
│   │   ├── hostinfo_tvos.go
│   │   ├── ping.go
│   │   ├── status.go
│   │   ├── tun_device_unix.go
│   │   └── tun_device_windows.go
│   ├── tor/
│   │   └── outbound.go
│   ├── trojan/
│   │   ├── inbound.go
│   │   └── outbound.go
│   ├── tuic/
│   │   ├── inbound.go
│   │   └── outbound.go
│   ├── tun/
│   │   └── 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_hostname.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
│   ├── process_cache.go
│   ├── route.go
│   ├── router.go
│   ├── rule/
│   │   ├── match_state.go
│   │   ├── 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_package_name_regex.go
│   │   ├── rule_item_port.go
│   │   ├── rule_item_port_range.go
│   │   ├── rule_item_preferred_by.go
│   │   ├── rule_item_preferred_by_dns.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_response_rcode.go
│   │   ├── rule_item_response_record.go
│   │   ├── rule_item_rule_set.go
│   │   ├── rule_item_rule_set_test.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_nested_action.go
│   │   ├── rule_nested_action_test.go
│   │   ├── rule_network_interface_address.go
│   │   ├── rule_set.go
│   │   ├── rule_set_local.go
│   │   ├── rule_set_remote.go
│   │   ├── rule_set_semantics_test.go
│   │   └── rule_set_update_validation_test.go
│   └── rule_conds.go
├── service/
│   ├── acme/
│   │   ├── service.go
│   │   └── stub.go
│   ├── 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/
│   │   ├── badcleanup.go
│   │   ├── badcleanup_stub.go
│   │   ├── policy.go
│   │   ├── service.go
│   │   ├── service_darwin.go
│   │   ├── service_stub.go
│   │   ├── timer.go
│   │   └── timer_darwin.go
│   ├── origin_ca/
│   │   └── service.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/"
--vendor SagerNet
--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
================================================
2faf34666c2cc8234f10f2ab6d4c4d6104d34ae2


================================================
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

prepare_apk_root() {
  # apk mkpkg resolves owner/group names through --root/etc/{passwd,group}.
  APK_ROOT_DIR=$(mktemp -d)
  mkdir -p "$APK_ROOT_DIR/etc"
  cat > "$APK_ROOT_DIR/etc/passwd" <<EOF
root:x:$(id -u):$(id -g):root:/root:/sbin/nologin
EOF
  cat > "$APK_ROOT_DIR/etc/group" <<EOF
root:x:$(id -g):root
EOF
}

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)
prepare_apk_root
trap 'rm -rf "$ROOT_DIR" "$APK_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 --root "$APK_ROOT_DIR" 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

prepare_apk_root() {
  # apk mkpkg resolves owner/group names through --root/etc/{passwd,group}.
  APK_ROOT_DIR=$(mktemp -d)
  mkdir -p "$APK_ROOT_DIR/etc"
  cat > "$APK_ROOT_DIR/etc/passwd" <<EOF
root:x:$(id -u):$(id -g):root:/root:/sbin/nologin
EOF
  cat > "$APK_ROOT_DIR/etc/group" <<EOF
root:x:$(id -g):root
EOF
}

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)
prepare_apk_root
trap 'rm -rf "$ROOT_DIR" "$APK_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 --root "$APK_ROOT_DIR" 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/detect_track.sh
================================================
#!/usr/bin/env bash
set -euo pipefail

branches=$(git branch -r --contains HEAD)
if echo "$branches" | grep -q 'origin/stable'; then
  track=stable
elif echo "$branches" | grep -q 'origin/testing'; then
  track=testing
elif echo "$branches" | grep -q 'origin/oldstable'; then
  track=oldstable
else
  echo "ERROR: HEAD is not on any known release branch (stable/testing/oldstable)" >&2
  exit 1
fi

if [[ "$track" == "stable" ]]; then
  tag=$(git describe --tags --exact-match HEAD 2>/dev/null || true)
  if [[ -n "$tag" && "$tag" == *"-"* ]]; then
    track=beta
  fi
fi

case "$track" in
  stable)    name=sing-box;           docker_tag=latest ;;
  beta)      name=sing-box-beta;      docker_tag=latest-beta ;;
  testing)   name=sing-box-testing;   docker_tag=latest-testing ;;
  oldstable) name=sing-box-oldstable; docker_tag=latest-oldstable ;;
esac

echo "track=${track} name=${name} docker_tag=${docker_tag}" >&2
echo "TRACK=${track}" >> "$GITHUB_ENV"
echo "NAME=${name}" >> "$GITHUB_ENV"
echo "DOCKER_TAG=${docker_tag}" >> "$GITHUB_ENV"


================================================
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.9"
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.9"
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.9
      - 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.9
      - 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.9
      - 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.9
      - 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.9
      - 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
    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.9
      - 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
      - name: Checkout
        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
        with:
          ref: ${{ steps.ref.outputs.ref }}
          fetch-depth: 0
      - name: Detect track
        run: bash .github/detect_track.sh
      - 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 }}:${{ env.DOCKER_TAG }}" \
            -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 }}:${{ env.DOCKER_TAG }}
          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

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

jobs:
  build:
    name: Lint ${{ matrix.goos }}/${{ matrix.goarch }}
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        include:
          - goos: windows
            goarch: amd64
          - goos: windows
            goarch: '386'
          - goos: windows
            goarch: arm64
          - goos: linux
            goarch: amd64
          - goos: linux
            goarch: arm64
          - goos: linux
            goarch: arm
          - goos: linux
            goarch: '386'
          - goos: darwin
            goarch: amd64
          - goos: darwin
            goarch: arm64
          - goos: android
            goarch: arm64
        #  - goos: freebsd
        #    goarch: amd64
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - name: Setup Go
        uses: actions/setup-go@v5
        with:
          go-version: ^1.25
      - name: Cache go module
        uses: actions/cache@v4
        with:
          path: |
            ~/go/pkg/mod
          key: go-${{ hashFiles('**/go.sum') }}
      - name: golangci-lint
        uses: golangci/golangci-lint-action@v8
        env:
          GOOS: ${{ matrix.goos }}
          GOARCH: ${{ matrix.goarch }}
        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
  release:
    types:
      - published

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.9
      - 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.9
      - 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: Detect track
        run: bash .github/detect_track.sh
      - 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: .github/workflows/test.yml
================================================
name: Test

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

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

jobs:
  test:
    name: Test
    strategy:
      fail-fast: false
      matrix:
        os:
          - ubuntu-latest
          - windows-latest
          - macos-latest
        go:
          - ~1.24
          - ~1.25
    runs-on: ${{ matrix.os }}
    steps:
      - name: Checkout
        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
      - name: Setup Go
        uses: actions/setup-go@v5
        with:
          go-version: ${{ matrix.go }}
      - name: Set build tags and ldflags
        shell: bash
        run: |
          echo "BUILD_TAGS=$(cat release/DEFAULT_BUILD_TAGS_OTHERS)" >> "$GITHUB_ENV"
          echo "LDFLAGS_SHARED=$(cat release/LDFLAGS)" >> "$GITHUB_ENV"
      - name: Test (unix)
        if: matrix.os != 'windows-latest'
        run: go test -v -exec sudo -tags "$BUILD_TAGS" -ldflags "$LDFLAGS_SHARED" ./...
      - name: Test (windows)
        if: matrix.os == 'windows-latest'
        shell: bash
        run: go test -v -tags "$BUILD_TAGS" -ldflags "$LDFLAGS_SHARED" ./...


================================================
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.24"
  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:
    - ineffassign
    - staticcheck
    - unused
    - modernize
  settings:
    modernize:
      disable:
        - omitzero # nested struct omitempty -> omitzero changes JSON output semantics
    staticcheck:
      checks:
        - all
        - -QF1008 # could remove embedded field "<interface>" from selector
        - -ST1003 # should not use ALL_CAPS in Go names; use CamelCase instead
        - -QF1001 # could apply De Morgan's law
  exclusions:
    generated: lax
    presets:
      - comments
      - common-false-positives
    paths:
      - transport/simple-obfs
      - \.pb\.go$
      - third_party$
      - builtin$
      - examples$
formatters:
  enable:
    - gci
    - gofumpt
  settings:
    gci:
      sections:
        - standard
        - prefix(github.com/sagernet/)
        - default
      custom-order: true


================================================
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:
	@golangci-lint fmt

fmt_docs:
	go run ./cmd/internal/format_docs

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"

replace_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 "v${VERSION}" "dist/SFM/SFM-${VERSION}-Apple.pkg"
	ghr --replace "v${VERSION}" "dist/SFM/SFM-${VERSION}-Intel.pkg"
	ghr --replace "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"

replace_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 "v${VERSION}" "dist/SFM/SFM-${VERSION}.dSYMs.zip"

release_macos_standalone: build_macos_pkg notarize_macos_pkg upload_macos_pkg upload_macos_dsyms

replace_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
================================================
# 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/adapter.go
================================================
package certificate

type Adapter struct {
	providerType string
	providerTag  string
}

func NewAdapter(providerType string, providerTag string) Adapter {
	return Adapter{
		providerType: providerType,
		providerTag:  providerTag,
	}
}

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

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


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

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.CertificateProviderManager = (*Manager)(nil)

type Manager struct {
	logger        log.ContextLogger
	registry      adapter.CertificateProviderRegistry
	access        sync.Mutex
	started       bool
	stage         adapter.StartStage
	providers     []adapter.CertificateProviderService
	providerByTag map[string]adapter.CertificateProviderService
}

func NewManager(logger log.ContextLogger, registry adapter.CertificateProviderRegistry) *Manager {
	return &Manager{
		logger:        logger,
		registry:      registry,
		providerByTag: make(map[string]adapter.CertificateProviderService),
	}
}

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
	providers := m.providers
	m.access.Unlock()
	for _, provider := range providers {
		name := "certificate-provider/" + provider.Type() + "[" + provider.Tag() + "]"
		m.logger.Trace(stage, " ", name)
		startTime := time.Now()
		err := adapter.LegacyStart(provider, 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
	providers := m.providers
	m.providers = nil
	monitor := taskmonitor.New(m.logger, C.StopTimeout)
	var err error
	for _, provider := range providers {
		name := "certificate-provider/" + provider.Type() + "[" + provider.Tag() + "]"
		m.logger.Trace("close ", name)
		startTime := time.Now()
		monitor.Start("close ", name)
		err = E.Append(err, provider.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 err
}

func (m *Manager) CertificateProviders() []adapter.CertificateProviderService {
	m.access.Lock()
	defer m.access.Unlock()
	return m.providers
}

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

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

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


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

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.CertificateProviderService, error)

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

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

type (
	optionsConstructorFunc func() any
	constructorFunc        func(ctx context.Context, logger log.ContextLogger, tag string, options any) (adapter.CertificateProviderService, 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(providerType string) (any, bool) {
	m.access.Lock()
	defer m.access.Unlock()
	optionsConstructor, loaded := m.optionsType[providerType]
	if !loaded {
		return nil, false
	}
	return optionsConstructor(), true
}

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

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


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

import (
	"context"
	"crypto/x509"

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

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

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


================================================
FILE: adapter/certificate_darwin.go
================================================
//go:build darwin && cgo

package adapter

import "unsafe"

type AppleAnchors interface {
	Retain() AppleAnchors
	Release()
	// Ref returns the underlying CFArrayRef, or nil if the anchor set is empty.
	Ref() unsafe.Pointer
}

type AppleCertificateStore interface {
	CertificateStore
	AppleAnchors() AppleAnchors
}


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

import (
	"context"
	"crypto/tls"

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

type CertificateProvider interface {
	GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate, error)
}

type ACMECertificateProvider interface {
	CertificateProvider
	GetACMENextProtos() []string
}

type CertificateProviderService interface {
	Lifecycle
	Type() string
	Tag() string
	CertificateProvider
}

type CertificateProviderRegistry interface {
	option.CertificateProviderOptionsRegistry
	Create(ctx context.Context, logger log.ContextLogger, tag string, providerType string, options any) (CertificateProviderService, error)
}

type CertificateProviderManager interface {
	Lifecycle
	CertificateProviders() []CertificateProviderService
	Get(tag string) (CertificateProviderService, bool)
	Remove(tag string) error
	Create(ctx context.Context, logger log.ContextLogger, tag string, providerType string, options any) error
}


================================================
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"
	"time"

	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(response *dns.Msg) bool) (*dns.Msg, error)
	Lookup(ctx context.Context, transport DNSTransport, domain string, options DNSQueryOptions, responseChecker func(response *dns.Msg) bool) ([]netip.Addr, error)
	ClearCache()
}

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

func DNSQueryOptionsFrom(ctx context.Context, options *option.DomainResolveOptions) (DNSQueryOptions, error) {
	if options == nil || options.Server == "" {
		return DNSQueryOptions{}, nil
	}
	transportManager := service.FromContext[DNSTransportManager](ctx)
	transport, loaded := transportManager.Transport(options.Server)
	if !loaded {
		return DNSQueryOptions{}, E.New("domain resolver not found: " + options.Server)
	}
	return DNSQueryOptions{
		Transport:              transport,
		Strategy:               C.DomainStrategy(options.Strategy),
		DisableCache:           options.DisableCache,
		DisableOptimisticCache: options.DisableOptimisticCache,
		RewriteTTL:             options.RewriteTTL,
		Timeout:                time.Duration(options.Timeout),
		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 DNSCacheStore interface {
	LoadDNSCache(transportName string, qName string, qType uint16) (rawMessage []byte, expireAt time.Time, loaded bool)
	SaveDNSCache(transportName string, qName string, qType uint16, rawMessage []byte, expireAt time.Time) error
	SaveDNSCacheAsync(transportName string, qName string, qType uint16, rawMessage []byte, expireAt time.Time, logger logger.Logger)
	ClearDNSCache() error
}

type DNSTransport interface {
	Lifecycle
	Type() string
	Tag() string
	Dependencies() []string
	// Reset closes the transport's existing connections so later requests use fresh connections.
	// Exchanges that are currently using those connections may fail.
	Reset()
	Exchange(ctx context.Context, message *dns.Msg) (*dns.Msg, error)
}

type DNSTransportWithPreferredDomain interface {
	DNSTransport
	PreferredDomain(domain string) bool
}

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"

	"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"
)

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() + "]"
		done := adapter.LogElapsed(m.logger, stage, " ", name)
		err := adapter.LegacyStart(endpoint, stage)
		done()
		if err != nil {
			return E.Cause(err, stage, " ", name)
		}
	}
	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() + "]"
		done := adapter.LogElapsed(m.logger, "close ", name)
		monitor.Start("close ", name)
		err = E.Append(err, endpoint.Close(), func(err error) error {
			return E.Cause(err, "close ", name)
		})
		monitor.Finish()
		done()
	}
	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 {
			done := adapter.LogElapsed(m.logger, stage, " ", name)
			err = adapter.LegacyStart(endpoint, stage)
			done()
			if err != nil {
				return E.Cause(err, stage, " ", name)
			}
		}
	}
	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

	StoreDNS() bool
	DNSCacheStore

	SetDisableExpire(disableExpire bool)
	SetOptimisticTimeout(timeout time.Duration)

	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"
	M "github.com/sagernet/sing/common/metadata"
	N "github.com/sagernet/sing/common/network"
)

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

type PacketHandler interface {
	NewPacket(buffer *buf.Buffer, source M.Socksaddr)
}

type PacketBatchHandler interface {
	NewPacketBatch(buffers []*buf.Buffer, sources []M.Socksaddr)
}

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

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

type UpstreamHandlerAdapter interface {
	N.TCPConnectionHandlerEx
	N.UDPConnectionHandlerEx
}


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

import (
	"context"
	"net/http"
	"sync"

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

type HTTPTransport interface {
	http.RoundTripper
	CloseIdleConnections()
	Reset()
}

type HTTPClientManager interface {
	ResolveTransport(ctx context.Context, logger logger.ContextLogger, options option.HTTPClientOptions) (HTTPTransport, error)
	DefaultTransport() HTTPTransport
	ResetNetwork()
}

type HTTPStartContext struct {
	access     sync.Mutex
	transports []HTTPTransport
}

func NewHTTPStartContext() *HTTPStartContext {
	return &HTTPStartContext{}
}

func (c *HTTPStartContext) Register(transport HTTPTransport) {
	c.access.Lock()
	defer c.access.Unlock()
	c.transports = append(c.transports, transport)
}

func (c *HTTPStartContext) Close() {
	for _, transport := range c.transports {
		transport.CloseIdleConnections()
	}
}


================================================
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"

	"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"
)

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() + "]"
		done := adapter.LogElapsed(m.logger, stage, " ", name)
		err := adapter.LegacyStart(inbound, stage)
		done()
		if err != nil {
			return E.Cause(err, stage, " ", name)
		}
	}
	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() + "]"
		done := adapter.LogElapsed(m.logger, "close ", name)
		monitor.Start("close ", name)
		err = E.Append(err, inbound.Close(), func(err error) error {
			return E.Cause(err, "close ", name)
		})
		monitor.Finish()
		done()
	}
	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 {
			done := adapter.LogElapsed(m.logger, stage, " ", name)
			err = adapter.LegacyStart(inbound, stage)
			done()
			if err != nil {
				return E.Cause(err, stage, " ", name)
			}
		}
	}
	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"

	"github.com/sagernet/sing-box/common/tlsspoof"
	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"

	"github.com/miekg/dns"
)

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

type TCPInjectableInbound interface {
	Inbound
	ConnectionHandler
}

type UDPInjectableInbound interface {
	Inbound
	PacketConnectionHandler
}

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
	TLSSpoof                  string
	TLSSpoofMethod            tlsspoof.Method

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

	DestinationAddresses                []netip.Addr
	DNSResponse                         *dns.Msg
	DestinationAddressMatchFromResponse bool
	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.ResetRuleMatchCache()
}

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

func (c *InboundContext) DNSResponseAddressesForMatch() []netip.Addr {
	return DNSResponseAddresses(c.DNSResponse)
}

func DNSResponseAddresses(response *dns.Msg) []netip.Addr {
	if response == nil || response.Rcode != dns.RcodeSuccess {
		return nil
	}
	addresses := make([]netip.Addr, 0, len(response.Answer))
	for _, rawRecord := range response.Answer {
		switch record := rawRecord.(type) {
		case *dns.A:
			addr := M.AddrFromIP(record.A)
			if addr.IsValid() {
				addresses = append(addresses, addr)
			}
		case *dns.AAAA:
			addr := M.AddrFromIP(record.AAAA)
			if addr.IsValid() {
				addresses = append(addresses, addr)
			}
		case *dns.HTTPS:
			for _, value := range record.SVCB.Value {
				switch hint := value.(type) {
				case *dns.SVCBIPv4Hint:
					for _, ip := range hint.Hint {
						addr := M.AddrFromIP(ip).Unmap()
						if addr.IsValid() {
							addresses = append(addresses, addr)
						}
					}
				case *dns.SVCBIPv6Hint:
					for _, ip := range hint.Hint {
						addr := M.AddrFromIP(ip)
						if addr.IsValid() {
							addresses = append(addresses, addr)
						}
					}
				}
			}
		}
	}
	return addresses
}

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/inbound_test.go
================================================
package adapter

import (
	"net"
	"net/netip"
	"testing"

	"github.com/miekg/dns"
	"github.com/stretchr/testify/require"
)

func TestDNSResponseAddressesUnmapsHTTPSIPv4Hints(t *testing.T) {
	t.Parallel()

	ipv4Hint := net.ParseIP("1.1.1.1")
	require.NotNil(t, ipv4Hint)

	response := &dns.Msg{
		MsgHdr: dns.MsgHdr{
			Response: true,
			Rcode:    dns.RcodeSuccess,
		},
		Answer: []dns.RR{
			&dns.HTTPS{
				SVCB: dns.SVCB{
					Hdr: dns.RR_Header{
						Name:   dns.Fqdn("example.com"),
						Rrtype: dns.TypeHTTPS,
						Class:  dns.ClassINET,
						Ttl:    60,
					},
					Priority: 1,
					Target:   ".",
					Value: []dns.SVCBKeyValue{
						&dns.SVCBIPv4Hint{Hint: []net.IP{ipv4Hint}},
					},
				},
			},
		},
	}

	addresses := DNSResponseAddresses(response)
	require.Equal(t, []netip.Addr{netip.MustParseAddr("1.1.1.1")}, addresses)
	require.True(t, addresses[0].Is4())
}


================================================
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)
		done := LogElapsed(logger, stage, " ", name)
		err := service.Start(stage)
		done()
		if err != nil {
			return err
		}
	}
	return nil
}

func StartNamed(logger log.ContextLogger, stage StartStage, services []LifecycleService) error {
	for _, service := range services {
		done := LogElapsed(logger, stage, " ", service.Name())
		err := service.Start(stage)
		done()
		if err != nil {
			return E.Cause(err, stage.String(), " ", service.Name())
		}
	}
	return nil
}

func LogElapsed(logger log.ContextLogger, description ...any) func() {
	prefix := F.ToString(description...)
	startTime := time.Now()
	timer := time.AfterFunc(time.Second, func() {
		logger.Trace(prefix, "...")
	})
	return func() {
		if timer.Stop() {
			return
		}
		logger.Trace(prefix, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
	}
}


================================================
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)
	LookupAddresses(hostname string) []netip.Addr
	Start() error
	Close() error
}

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


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

import (
	"encoding/hex"
	"net"
	"strings"
	"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
}

func NormalizeWIFIBSSID(bssid string) string {
	bssid = strings.TrimSpace(bssid)
	if bssid == "" {
		return ""
	}
	parsed, err := net.ParseMAC(bssid)
	if err == nil && len(parsed) == 6 {
		return parsed.String()
	}
	if len(bssid) == 12 {
		decoded, err := hex.DecodeString(bssid)
		if err == nil {
			return net.HardwareAddr(decoded).String()
		}
	}
	return bssid
}

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"

	"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"
	"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() + "]"
			done := adapter.LogElapsed(m.logger, stage, " ", name)
			err := adapter.LegacyStart(outbound, stage)
			done()
			if err != nil {
				return E.Cause(err, stage, " ", name)
			}
		}
	}
	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 {
				done := adapter.LogElapsed(m.logger, "start ", name)
				monitor.Start("start ", name)
				err := starter.Start(adapter.StartStateStart)
				monitor.Finish()
				done()
				if err != nil {
					return E.Cause(err, "start ", name)
				}
			} else if starter, isStarter := outboundToStart.(interface {
				Start() error
			}); isStarter {
				done := adapter.LogElapsed(m.logger, "start ", name)
				monitor.Start("start ", name)
				err := starter.Start()
				monitor.Finish()
				done()
				if err != nil {
					return E.Cause(err, "start ", name)
				}
			}
		}
		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() + "]"
			done := adapter.LogElapsed(m.logger, "close ", name)
			monitor.Start("close ", name)
			err = E.Append(err, closer.Close(), func(err error) error {
				return E.Cause(err, "close ", name)
			})
			monitor.Finish()
			done()
		}
	}
	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 {
			done := adapter.LogElapsed(m.logger, stage, " ", name)
			err = adapter.LegacyStart(outbound, stage)
			done()
			if err != nil {
				return E.Cause(err, stage, " ", name)
			}
		}
	}
	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 (
	"net/netip"

	"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

	MyInterfaceAddress() []netip.Addr

	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
	AndroidPackageNames []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"
	"net"
	"time"

	"github.com/sagernet/sing-tun"
	N "github.com/sagernet/sing/common/network"
	"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 DNSRuleSetUpdateValidator interface {
	ValidateRuleSetMetadataUpdate(tag string, metadata RuleSetMetadata) error
}

// ip_version is not a headless-rule item, so ContainsIPVersionRule is intentionally absent.
type RuleSetMetadata struct {
	ContainsProcessRule      bool
	ContainsWIFIRule         bool
	ContainsIPCIDRRule       bool
	ContainsDNSQueryTypeRule bool
	// ContainsNonIPCIDRRule signals that the rule-set carries at least one sub-rule
	// with a predicate other than destination ip_cidr / ip_set, so it can contribute
	// to DNS pre-response matching. A rule-set where this is false and
	// ContainsIPCIDRRule is true is "pure-IP" and matches nothing before a DNS
	// response is available.
	ContainsNonIPCIDRRule bool
}


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

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

	"github.com/miekg/dns"
)

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

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

type DNSRule interface {
	Rule
	LegacyPreMatch(metadata *InboundContext) bool
	WithAddressLimit() bool
	MatchAddressLimit(metadata *InboundContext, response *dns.Msg) bool
}

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

func IsFinalAction(action RuleAction) bool {
	switch action.Type() {
	case C.RuleActionTypeSniff, C.RuleActionTypeResolve, C.RuleActionTypeEvaluate:
		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"

	"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"
)

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() + "]"
		done := adapter.LogElapsed(m.logger, stage, " ", name)
		err := adapter.LegacyStart(service, stage)
		done()
		if err != nil {
			return E.Cause(err, stage, " ", name)
		}
	}
	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() + "]"
		done := adapter.LogElapsed(m.logger, "close ", name)
		monitor.Start("close ", name)
		err = E.Append(err, service.Close(), func(err error) error {
			return E.Cause(err, "close ", name)
		})
		monitor.Finish()
		done()
	}
	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 {
			done := adapter.LogElapsed(m.logger, stage, " ", name)
			err = adapter.LegacyStart(service, stage)
			done()
			if err != nil {
				return E.Cause(err, stage, " ", name)
			}
		}
	}
	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/tailscale.go
================================================
package adapter

import "context"

type TailscaleEndpoint interface {
	SubscribeTailscaleStatus(ctx context.Context, fn func(*TailscaleEndpointStatus)) error
	StartTailscalePing(ctx context.Context, peerIP string, fn func(*TailscalePingResult)) error
}

type TailscalePingResult struct {
	LatencyMs      float64
	IsDirect       bool
	Endpoint       string
	DERPRegionID   int32
	DERPRegionCode string
	Error          string
}

type TailscaleEndpointStatus struct {
	BackendState   string
	AuthURL        string
	NetworkName    string
	MagicDNSSuffix string
	Self           *TailscalePeer
	UserGroups     []*TailscaleUserGroup
}

type TailscaleUserGroup struct {
	UserID        int64
	LoginName     string
	DisplayName   string
	ProfilePicURL string
	Peers         []*TailscalePeer
}

type TailscalePeer struct {
	HostName       string
	DNSName        string
	OS             string
	TailscaleIPs   []string
	Online         bool
	ExitNode       bool
	ExitNodeOption bool
	Active         bool
	RxBytes        int64
	TxBytes        int64
	UserID         int64
	KeyExpiry      int64
}


================================================
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 (
	ConnectionHandlerFunc       = func(ctx context.Context, conn net.Conn, metadata InboundContext, onClose N.CloseHandlerFunc)
	PacketConnectionHandlerFunc = func(ctx context.Context, conn N.PacketConn, metadata InboundContext, onClose N.CloseHandlerFunc)
)

func NewUpstreamHandler(
	metadata InboundContext,
	connectionHandler ConnectionHandlerFunc,
	packetHandler PacketConnectionHandlerFunc,
) UpstreamHandlerAdapter {
	return &myUpstreamHandlerWrapper{
		metadata:          metadata,
		connectionHandler: connectionHandler,
		packetHandler:     packetHandler,
	}
}

var _ UpstreamHandlerAdapter = (*myUpstreamHandlerWrapper)(nil)

type myUpstreamHandlerWrapper struct {
	metadata          InboundContext
	connectionHandler ConnectionHandlerFunc
	packetHandler     PacketConnectionHandlerFunc
}

func (w *myUpstreamHandlerWrapper) 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 *myUpstreamHandlerWrapper) 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 _ UpstreamHandlerAdapter = (*myUpstreamContextHandlerWrapper)(nil)

type myUpstreamContextHandlerWrapper struct {
	connectionHandler ConnectionHandlerFunc
	packetHandler     PacketConnectionHandlerFunc
}

func NewUpstreamContextHandler(
	connectionHandler ConnectionHandlerFunc,
	packetHandler PacketConnectionHandlerFunc,
) UpstreamHandlerAdapter {
	return &myUpstreamContextHandlerWrapper{
		connectionHandler: connectionHandler,
		packetHandler:     packetHandler,
	}
}

func (w *myUpstreamContextHandlerWrapper) 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 *myUpstreamContextHandlerWrapper) 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 NewRouteHandler(
	metadata InboundContext,
	router ConnectionRouterEx,
) UpstreamHandlerAdapter {
	return &routeHandlerWrapper{
		metadata: metadata,
		router:   router,
	}
}

var _ UpstreamHandlerAdapter = (*routeHandlerWrapper)(nil)

type routeHandlerWrapper struct {
	metadata InboundContext
	router   ConnectionRouterEx
}

func (r *routeHandlerWrapper) 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 *routeHandlerWrapper) 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 NewRouteContextHandler(
	router ConnectionRouterEx,
) UpstreamHandlerAdapter {
	return &routeContextHandlerWrapper{
		router: router,
	}
}

var _ UpstreamHandlerAdapter = (*routeContextHandlerWrapper)(nil)

type routeContextHandlerWrapper struct {
	router ConnectionRouterEx
}

func (r *routeContextHandlerWrapper) 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 *routeContextHandlerWrapper) 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
	LegacyConnectionHandlerFunc = func(ctx context.Context, conn net.Conn, metadata InboundContext) error
	// Deprecated
	LegacyPacketConnectionHandlerFunc = func(ctx context.Context, conn N.PacketConn, metadata InboundContext) error
)

// Deprecated
//
//nolint:staticcheck
type LegacyUpstreamHandlerAdapter interface {
	N.TCPConnectionHandler
	N.UDPConnectionHandler
	E.Handler
}

// Deprecated
//
//nolint:staticcheck
func NewLegacyUpstreamHandler(
	metadata InboundContext,
	connectionHandler LegacyConnectionHandlerFunc,
	packetHandler LegacyPacketConnectionHandlerFunc,
	errorHandler E.Handler,
) LegacyUpstreamHandlerAdapter {
	return &legacyUpstreamHandlerWrapper{
		metadata:          metadata,
		connectionHandler: connectionHandler,
		packetHandler:     packetHandler,
		errorHandler:      errorHandler,
	}
}

var _ LegacyUpstreamHandlerAdapter = (*legacyUpstreamHandlerWrapper)(nil)

// Deprecated: use NewUpstreamHandler instead.
//
//nolint:staticcheck
type legacyUpstreamHandlerWrapper struct {
	metadata          InboundContext
	connectionHandler LegacyConnectionHandlerFunc
	packetHandler     LegacyPacketConnectionHandlerFunc
	errorHandler      E.Handler
}

// Deprecated: use NewUpstreamHandler instead.
func (w *legacyUpstreamHandlerWrapper) 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 NewUpstreamHandler instead.
func (w *legacyUpstreamHandlerWrapper) 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 NewUpstreamHandler instead.
func (w *legacyUpstreamHandlerWrapper) 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 NewUpstreamContextHandler instead.
type legacyUpstreamContextHandlerWrapper struct {
	connectionHandler LegacyConnectionHandlerFunc
	packetHandler     LegacyPacketConnectionHandlerFunc
	errorHandler      E.Handler
}

// Deprecated: Use NewUpstreamContextHandler instead.
func NewLegacyUpstreamContextHandler(
	connectionHandler LegacyConnectionHandlerFunc,
	packetHandler LegacyPacketConnectionHandlerFunc,
	errorHandler E.Handler,
) LegacyUpstreamHandlerAdapter {
	return &legacyUpstreamContextHandlerWrapper{
		connectionHandler: connectionHandler,
		packetHandler:     packetHandler,
		errorHandler:      errorHandler,
	}
}

// Deprecated: Use NewUpstreamContextHandler instead.
func (w *legacyUpstreamContextHandlerWrapper) 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 NewUpstreamContextHandler instead.
func (w *legacyUpstreamContextHandlerWrapper) 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 NewUpstreamContextHandler instead.
func (w *legacyUpstreamContextHandlerWrapper) NewError(ctx context.Context, err error) {
	w.errorHandler.NewError(ctx, err)
}

// Deprecated: Use ConnectionRouterEx instead.
func NewLegacyRouteHandler(
	metadata InboundContext,
	router ConnectionRouter,
	logger logger.ContextLogger,
) LegacyUpstreamHandlerAdapter {
	return &legacyRouteHandlerWrapper{
		metadata: metadata,
		router:   router,
		logger:   logger,
	}
}

// Deprecated: Use ConnectionRouterEx instead.
func NewLegacyRouteContextHandler(
	router ConnectionRouter,
	logger logger.ContextLogger,
) LegacyUpstreamHandlerAdapter {
	return &legacyRouteContextHandlerWrapper{
		router: router,
		logger: logger,
	}
}

var _ LegacyUpstreamHandlerAdapter = (*legacyRouteHandlerWrapper)(nil)

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

// Deprecated: Use ConnectionRouterEx instead.
func (w *legacyRouteHandlerWrapper) 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 *legacyRouteHandlerWrapper) 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 *legacyRouteHandlerWrapper) NewError(ctx context.Context, err error) {
	w.logger.ErrorContext(ctx, err)
}

var _ LegacyUpstreamHandlerAdapter = (*legacyRouteContextHandlerWrapper)(nil)

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

// Deprecated: Use ConnectionRouterEx instead.
func (w *legacyRouteContextHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata
Download .txt
gitextract_yza4ly9v/

├── .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
│   ├── detect_track.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
│       └── test.yml
├── .gitignore
├── .gitmodules
├── .golangci.yml
├── Dockerfile
├── Dockerfile.binary
├── LICENSE
├── Makefile
├── README.md
├── adapter/
│   ├── certificate/
│   │   ├── adapter.go
│   │   ├── manager.go
│   │   └── registry.go
│   ├── certificate.go
│   ├── certificate_darwin.go
│   ├── certificate_provider.go
│   ├── connections.go
│   ├── dns.go
│   ├── endpoint/
│   │   ├── adapter.go
│   │   ├── manager.go
│   │   └── registry.go
│   ├── endpoint.go
│   ├── experimental.go
│   ├── fakeip.go
│   ├── fakeip_metadata.go
│   ├── handler.go
│   ├── http.go
│   ├── inbound/
│   │   ├── adapter.go
│   │   ├── manager.go
│   │   └── registry.go
│   ├── inbound.go
│   ├── inbound_test.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
│   ├── tailscale.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_networkquality.go
│       ├── cmd_tools_stun.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/
│   │   ├── anchors_darwin.h
│   │   ├── anchors_darwin.m
│   │   ├── chrome.go
│   │   ├── chrome.pem
│   │   ├── mozilla.go
│   │   ├── mozilla.pem
│   │   ├── store.go
│   │   ├── store_darwin.go
│   │   └── store_other.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
│   ├── httpclient/
│   │   ├── apple_transport_darwin.go
│   │   ├── apple_transport_darwin.h
│   │   ├── apple_transport_darwin.m
│   │   ├── apple_transport_darwin_test.go
│   │   ├── apple_transport_stub.go
│   │   ├── client.go
│   │   ├── context.go
│   │   ├── helpers.go
│   │   ├── helpers_test.go
│   │   ├── http1_transport.go
│   │   ├── http2_config.go
│   │   ├── http2_fallback_transport.go
│   │   ├── http2_fallback_transport_test.go
│   │   ├── http2_transport.go
│   │   ├── http3_transport.go
│   │   ├── http3_transport_stub.go
│   │   ├── http3_transport_test.go
│   │   ├── managed_transport.go
│   │   └── manager.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
│   ├── networkquality/
│   │   ├── http.go
│   │   ├── http3.go
│   │   ├── http3_stub.go
│   │   └── networkquality.go
│   ├── pipelistener/
│   │   └── listener.go
│   ├── process/
│   │   ├── searcher.go
│   │   ├── searcher_android.go
│   │   ├── searcher_darwin.go
│   │   ├── searcher_darwin_shared.go
│   │   ├── searcher_linux.go
│   │   ├── searcher_linux_shared.go
│   │   ├── searcher_linux_shared_test.go
│   │   ├── searcher_stub.go
│   │   └── searcher_windows.go
│   ├── proxybridge/
│   │   └── bridge.go
│   ├── redir/
│   │   ├── redir_darwin.go
│   │   ├── redir_linux.go
│   │   ├── redir_other.go
│   │   ├── tproxy_linux.go
│   │   └── tproxy_other.go
│   ├── schannel/
│   │   ├── doc.go
│   │   ├── schannel_windows.go
│   │   ├── schannel_windows_test.go
│   │   ├── syscall_windows.go
│   │   ├── types_windows.go
│   │   └── zsyscall_windows.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
│   ├── stun/
│   │   └── stun.go
│   ├── taskmonitor/
│   │   └── monitor.go
│   ├── tls/
│   │   ├── acme.go
│   │   ├── acme_logger.go
│   │   ├── acme_stub.go
│   │   ├── apple_client.go
│   │   ├── apple_client_platform.go
│   │   ├── apple_client_platform_benchmark_test.go
│   │   ├── apple_client_platform_darwin.h
│   │   ├── apple_client_platform_darwin.m
│   │   ├── apple_client_platform_dispatch_test.go
│   │   ├── apple_client_platform_dispatch_testhelper_darwin.go
│   │   ├── apple_client_platform_test.go
│   │   ├── apple_client_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
│   │   ├── system_client.go
│   │   ├── system_client_engine.go
│   │   ├── time_wrapper.go
│   │   ├── utls_client.go
│   │   ├── utls_client_test.go
│   │   ├── utls_stub.go
│   │   ├── windows_client.go
│   │   ├── windows_client_stub.go
│   │   └── windows_client_test.go
│   ├── tlsfragment/
│   │   ├── conn.go
│   │   ├── conn_test.go
│   │   ├── index.go
│   │   ├── index_test.go
│   │   ├── wait_darwin.go
│   │   ├── wait_linux.go
│   │   ├── wait_stub.go
│   │   └── wait_windows.go
│   ├── tlsspoof/
│   │   ├── README.md
│   │   ├── client_hello.go
│   │   ├── endpoints.go
│   │   ├── integration_darwin_test.go
│   │   ├── integration_linux_test.go
│   │   ├── integration_test.go
│   │   ├── integration_tls_test.go
│   │   ├── integration_unix_test.go
│   │   ├── integration_windows_test.go
│   │   ├── packet.go
│   │   ├── packet_darwin.go
│   │   ├── raw_darwin.go
│   │   ├── raw_linux.go
│   │   ├── raw_stub.go
│   │   ├── raw_unix.go
│   │   ├── raw_windows.go
│   │   ├── spoof.go
│   │   └── testdata_test.go
│   ├── uot/
│   │   └── router.go
│   ├── urltest/
│   │   └── urltest.go
│   └── windivert/
│       ├── address_test.go
│       ├── assets/
│       │   ├── LICENSE.txt
│       │   ├── WinDivert32.sys
│       │   └── WinDivert64.sys
│       ├── assets_386.go
│       ├── assets_amd64.go
│       ├── assets_unsupported.go
│       ├── driver_windows.go
│       ├── filter.go
│       ├── filter_test.go
│       ├── handle_windows.go
│       ├── handle_windows_test.go
│       ├── integration_windows_test.go
│       └── windivert.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
│   ├── tls.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
│   ├── repro_test.go
│   ├── router.go
│   ├── router_test.go
│   ├── transport/
│   │   ├── conn_pool.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_cgo.go
│   │   │   ├── local_darwin_stun.go
│   │   │   ├── local_dhcp.go
│   │   │   ├── local_neighbor.go
│   │   │   ├── local_nodhcp.go
│   │   │   ├── local_other.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
│   │   ├── mdns/
│   │   │   └── mdns.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
│   │   │       ├── mdns.md
│   │   │       ├── mdns.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
│   │   │   ├── cloudflared.md
│   │   │   ├── cloudflared.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
│   │   │   ├── hysteria-realm.md
│   │   │   ├── hysteria-realm.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/
│   │       ├── certificate-provider/
│   │       │   ├── acme.md
│   │       │   ├── acme.zh.md
│   │       │   ├── cloudflare-origin-ca.md
│   │       │   ├── cloudflare-origin-ca.zh.md
│   │       │   ├── index.md
│   │       │   ├── index.zh.md
│   │       │   ├── tailscale.md
│   │       │   └── tailscale.zh.md
│   │       ├── dial.md
│   │       ├── dial.zh.md
│   │       ├── dns01_challenge.md
│   │       ├── dns01_challenge.zh.md
│   │       ├── http-client.md
│   │       ├── http-client.zh.md
│   │       ├── http2.md
│   │       ├── http2.zh.md
│   │       ├── listen.md
│   │       ├── listen.zh.md
│   │       ├── multiplex.md
│   │       ├── multiplex.zh.md
│   │       ├── neighbor.md
│   │       ├── neighbor.zh.md
│   │       ├── pre-match.md
│   │       ├── pre-match.zh.md
│   │       ├── quic.md
│   │       ├── quic.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
│   │   ├── dns_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
│   │   ├── command_types_nq.go
│   │   ├── command_types_stun.go
│   │   ├── command_types_tailscale.go
│   │   ├── command_types_tailscale_ping.go
│   │   ├── config.go
│   │   ├── connection_owner_darwin.go
│   │   ├── debug.go
│   │   ├── deprecated.go
│   │   ├── dns.go
│   │   ├── fdroid.go
│   │   ├── fdroid_mirrors.go
│   │   ├── ffi.json
│   │   ├── http.go
│   │   ├── internal/
│   │   │   ├── oomprofile/
│   │   │   │   ├── builder.go
│   │   │   │   ├── defs_darwin_amd64.go
│   │   │   │   ├── defs_darwin_arm64.go
│   │   │   │   ├── linkname.go
│   │   │   │   ├── mapping_darwin.go
│   │   │   │   ├── mapping_linux.go
│   │   │   │   ├── mapping_windows.go
│   │   │   │   ├── oomprofile.go
│   │   │   │   └── protobuf.go
│   │   │   └── procfs/
│   │   │       └── procfs.go
│   │   ├── iterator.go
│   │   ├── link_flags_stub.go
│   │   ├── link_flags_unix.go
│   │   ├── log.go
│   │   ├── monitor.go
│   │   ├── neighbor.go
│   │   ├── neighbor_darwin.go
│   │   ├── neighbor_linux.go
│   │   ├── neighbor_stub.go
│   │   ├── neighbor_unix.go
│   │   ├── networkquality.go
│   │   ├── oom_report.go
│   │   ├── panic.go
│   │   ├── pidfd_android.go
│   │   ├── platform.go
│   │   ├── pprof.go
│   │   ├── profile_import.go
│   │   ├── remote_profile.go
│   │   ├── report.go
│   │   ├── semver.go
│   │   ├── semver_test.go
│   │   ├── service.go
│   │   ├── service_other.go
│   │   ├── service_windows.go
│   │   ├── setup.go
│   │   ├── signal_handler_darwin.go
│   │   ├── signal_handler_stub.go
│   │   ├── stun.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/
│   ├── acme.go
│   ├── acme_stub.go
│   ├── ccm.go
│   ├── ccm_stub.go
│   ├── ccm_stub_darwin.go
│   ├── clashapi.go
│   ├── clashapi_stub.go
│   ├── cloudflared.go
│   ├── cloudflared_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/
│   ├── acme.go
│   ├── anytls.go
│   ├── ccm.go
│   ├── certificate.go
│   ├── certificate_provider.go
│   ├── cloudflared.go
│   ├── debug.go
│   ├── direct.go
│   ├── dns.go
│   ├── dns_record.go
│   ├── dns_record_test.go
│   ├── dns_test.go
│   ├── endpoint.go
│   ├── experimental.go
│   ├── group.go
│   ├── http.go
│   ├── hysteria.go
│   ├── hysteria2.go
│   ├── inbound.go
│   ├── multiplex.go
│   ├── naive.go
│   ├── ntp.go
│   ├── ocm.go
│   ├── oom_killer.go
│   ├── options.go
│   ├── origin_ca.go
│   ├── outbound.go
│   ├── platform.go
│   ├── redir.go
│   ├── resolved.go
│   ├── route.go
│   ├── rule.go
│   ├── rule_action.go
│   ├── rule_action_test.go
│   ├── rule_dns.go
│   ├── rule_nested.go
│   ├── rule_nested_test.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
│   ├── cloudflare/
│   │   └── inbound.go
│   ├── direct/
│   │   ├── inbound.go
│   │   └── outbound.go
│   ├── dns/
│   │   ├── handle.go
│   │   └── outbound.go
│   ├── group/
│   │   ├── selector.go
│   │   └── urltest.go
│   ├── http/
│   │   ├── inbound.go
│   │   └── outbound.go
│   ├── hysteria/
│   │   ├── inbound.go
│   │   ├── outbound.go
│   │   └── quic.go
│   ├── hysteria2/
│   │   ├── inbound.go
│   │   ├── outbound.go
│   │   ├── realm.go
│   │   └── realm_server.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/
│   │   ├── certificate_provider.go
│   │   ├── dns_transport.go
│   │   ├── endpoint.go
│   │   ├── hostinfo_tvos.go
│   │   ├── ping.go
│   │   ├── status.go
│   │   ├── tun_device_unix.go
│   │   └── tun_device_windows.go
│   ├── tor/
│   │   └── outbound.go
│   ├── trojan/
│   │   ├── inbound.go
│   │   └── outbound.go
│   ├── tuic/
│   │   ├── inbound.go
│   │   └── outbound.go
│   ├── tun/
│   │   └── 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_hostname.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
│   ├── process_cache.go
│   ├── route.go
│   ├── router.go
│   ├── rule/
│   │   ├── match_state.go
│   │   ├── 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_package_name_regex.go
│   │   ├── rule_item_port.go
│   │   ├── rule_item_port_range.go
│   │   ├── rule_item_preferred_by.go
│   │   ├── rule_item_preferred_by_dns.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_response_rcode.go
│   │   ├── rule_item_response_record.go
│   │   ├── rule_item_rule_set.go
│   │   ├── rule_item_rule_set_test.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_nested_action.go
│   │   ├── rule_nested_action_test.go
│   │   ├── rule_network_interface_address.go
│   │   ├── rule_set.go
│   │   ├── rule_set_local.go
│   │   ├── rule_set_remote.go
│   │   ├── rule_set_semantics_test.go
│   │   └── rule_set_update_validation_test.go
│   └── rule_conds.go
├── service/
│   ├── acme/
│   │   ├── service.go
│   │   └── stub.go
│   ├── 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/
│   │   ├── badcleanup.go
│   │   ├── badcleanup_stub.go
│   │   ├── policy.go
│   │   ├── service.go
│   │   ├── service_darwin.go
│   │   ├── service_stub.go
│   │   ├── timer.go
│   │   └── timer_darwin.go
│   ├── origin_ca/
│   │   └── service.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 (717K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (7773 symbols across 839 files)

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

FILE: adapter/certificate/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(providerType string, providerTag string) Adapter {

FILE: adapter/certificate/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 CertificateProviders (line 85) | func (m *Manager) CertificateProviders() []adapter.CertificateProvider...
    method Get (line 91) | func (m *Manager) Get(tag string) (adapter.CertificateProviderService,...
    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.CertificatePr...

FILE: adapter/certificate/registry.go
  type ConstructorFunc (line 13) | type ConstructorFunc
  function Register (line 15) | func Register[Options any](registry *Registry, providerType 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(providerType 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(providerType string, optionsConstructor op...
  function NewRegistry (line 40) | func NewRegistry() *Registry {

FILE: adapter/certificate_darwin.go
  type AppleAnchors (line 7) | type AppleAnchors interface
  type AppleCertificateStore (line 14) | type AppleCertificateStore interface

FILE: adapter/certificate_provider.go
  type CertificateProvider (line 11) | type CertificateProvider interface
  type ACMECertificateProvider (line 15) | type ACMECertificateProvider interface
  type CertificateProviderService (line 20) | type CertificateProviderService interface
  type CertificateProviderRegistry (line 27) | type CertificateProviderRegistry interface
  type CertificateProviderManager (line 32) | type CertificateProviderManager interface

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

FILE: adapter/dns.go
  type DNSRouter (line 18) | type DNSRouter interface
  type DNSClient (line 27) | type DNSClient interface
  type DNSQueryOptions (line 34) | type DNSQueryOptions struct
  function DNSQueryOptionsFrom (line 45) | func DNSQueryOptionsFrom(ctx context.Context, options *option.DomainReso...
  type RDRCStore (line 65) | type RDRCStore interface
  type DNSCacheStore (line 71) | type DNSCacheStore interface
  type DNSTransport (line 78) | type DNSTransport interface
  type DNSTransportWithPreferredDomain (line 89) | type DNSTransportWithPreferredDomain interface
  type DNSTransportRegistry (line 94) | type DNSTransportRegistry interface
  type DNSTransportManager (line 99) | 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 18) | type Manager struct
    method Start (line 36) | func (m *Manager) Start(stage adapter.StartStage) error {
    method Close (line 60) | func (m *Manager) Close() error {
    method Endpoints (line 84) | func (m *Manager) Endpoints() []adapter.Endpoint {
    method Get (line 90) | func (m *Manager) Get(tag string) (adapter.Endpoint, bool) {
    method Remove (line 97) | func (m *Manager) Remove(tag string) error {
    method Create (line 120) | func (m *Manager) Create(ctx context.Context, router adapter.Router, l...
  function NewManager (line 28) | 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 66) | type SavedBinary struct
    method MarshalBinary (line 72) | func (s *SavedBinary) MarshalBinary() ([]byte, error) {
    method UnmarshalBinary (line 101) | func (s *SavedBinary) UnmarshalBinary(data []byte) error {
  type OutboundGroup (line 136) | type OutboundGroup interface
  type URLTestGroup (line 142) | type URLTestGroup interface
  function OutboundTag (line 147) | 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 12) | type ConnectionHandler interface
  type PacketHandler (line 16) | type PacketHandler interface
  type PacketBatchHandler (line 20) | type PacketBatchHandler interface
  type OOBPacketHandler (line 24) | type OOBPacketHandler interface
  type PacketConnectionHandler (line 28) | type PacketConnectionHandler interface
  type UpstreamHandlerAdapter (line 32) | type UpstreamHandlerAdapter interface

FILE: adapter/http.go
  type HTTPTransport (line 12) | type HTTPTransport interface
  type HTTPClientManager (line 18) | type HTTPClientManager interface
  type HTTPStartContext (line 24) | type HTTPStartContext struct
    method Register (line 33) | func (c *HTTPStartContext) Register(transport HTTPTransport) {
    method Close (line 39) | func (c *HTTPStartContext) Close() {
  function NewHTTPStartContext (line 29) | func NewHTTPStartContext() *HTTPStartContext {

FILE: adapter/inbound.go
  type Inbound (line 18) | type Inbound interface
  type TCPInjectableInbound (line 24) | type TCPInjectableInbound interface
  type UDPInjectableInbound (line 29) | type UDPInjectableInbound interface
  type InboundRegistry (line 34) | type InboundRegistry interface
  type InboundManager (line 39) | type InboundManager interface
  type InboundContext (line 47) | type InboundContext struct
    method ResetRuleCache (line 111) | func (c *InboundContext) ResetRuleCache() {
    method ResetRuleMatchCache (line 117) | func (c *InboundContext) ResetRuleMatchCache() {
    method DNSResponseAddressesForMatch (line 125) | func (c *InboundContext) DNSResponseAddressesForMatch() []netip.Addr {
  function DNSResponseAddresses (line 129) | func DNSResponseAddresses(response *dns.Msg) []netip.Addr {
  type inboundContextKey (line 170) | type inboundContextKey struct
  function WithContext (line 172) | func WithContext(ctx context.Context, inboundContext *InboundContext) co...
  function ContextFrom (line 176) | func ContextFrom(ctx context.Context) *InboundContext {
  function ExtendContext (line 184) | func ExtendContext(ctx context.Context) (context.Context, *InboundContex...
  function OverrideContext (line 192) | 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 18) | type Manager struct
    method Start (line 38) | func (m *Manager) Start(stage adapter.StartStage) error {
    method Close (line 59) | func (m *Manager) Close() error {
    method Inbounds (line 83) | func (m *Manager) Inbounds() []adapter.Inbound {
    method Get (line 89) | func (m *Manager) Get(tag string) (adapter.Inbound, bool) {
    method Remove (line 99) | func (m *Manager) Remove(tag string) error {
    method Create (line 122) | func (m *Manager) Create(ctx context.Context, router adapter.Router, l...
  function NewManager (line 29) | 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/inbound_test.go
  function TestDNSResponseAddressesUnmapsHTTPSIPv4Hints (line 12) | func TestDNSResponseAddressesUnmapsHTTPSIPv4Hints(t *testing.T) {

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 90) | func StartNamed(logger log.ContextLogger, stage StartStage, services []L...
  function LogElapsed (line 102) | func LogElapsed(logger log.ContextLogger, description ...any) func() {

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 22) | type NeighborUpdateListener interface

FILE: adapter/network.go
  type NetworkManager (line 14) | type NetworkManager interface
  type NetworkOptions (line 37) | type NetworkOptions struct
  type InterfaceUpdateListener (line 48) | type InterfaceUpdateListener interface
  type WIFIState (line 52) | type WIFIState struct
  function NormalizeWIFIBSSID (line 57) | func NormalizeWIFIBSSID(bssid string) string {
  type NetworkInterface (line 75) | 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 21) | type Manager struct
    method Initialize (line 47) | func (m *Manager) Initialize(defaultOutboundFallback func() (adapter.O...
    method Start (line 51) | func (m *Manager) Start(stage adapter.StartStage) error {
    method startOutbounds (line 96) | func (m *Manager) startOutbounds(outbounds []adapter.Outbound) error {
    method Close (line 168) | func (m *Manager) Close() error {
    method Outbounds (line 195) | func (m *Manager) Outbounds() []adapter.Outbound {
    method Outbound (line 201) | func (m *Manager) Outbound(tag string) (adapter.Outbound, bool) {
    method Default (line 211) | func (m *Manager) Default() adapter.Outbound {
    method Remove (line 217) | func (m *Manager) Remove(tag string) error {
    method Create (line 261) | func (m *Manager) Create(ctx context.Context, router adapter.Router, l...
  function NewManager (line 36) | 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 11) | type PlatformInterface interface
  type FindConnectionOwnerRequest (line 49) | type FindConnectionOwnerRequest struct
  type ConnectionOwner (line 57) | type ConnectionOwner struct
  type Notification (line 65) | type Notification struct
  type SystemProxyStatus (line 75) | type SystemProxyStatus struct

FILE: adapter/router.go
  type Router (line 15) | type Router interface
  type ConnectionTracker (line 29) | type ConnectionTracker interface
  type ConnectionRouter (line 35) | type ConnectionRouter interface
  type ConnectionRouterEx (line 40) | type ConnectionRouterEx interface
  type RuleSet (line 46) | type RuleSet interface
  type RuleSetUpdateCallback (line 61) | type RuleSetUpdateCallback
  type DNSRuleSetUpdateValidator (line 63) | type DNSRuleSetUpdateValidator interface
  type RuleSetMetadata (line 68) | type RuleSetMetadata struct

FILE: adapter/rule.go
  type HeadlessRule (line 9) | type HeadlessRule interface
  type Rule (line 14) | type Rule interface
  type DNSRule (line 21) | type DNSRule interface
  type RuleAction (line 28) | type RuleAction interface
  function IsFinalAction (line 33) | 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 18) | type Manager struct
    method Start (line 36) | func (m *Manager) Start(stage adapter.StartStage) error {
    method Close (line 57) | func (m *Manager) Close() error {
    method Services (line 81) | func (m *Manager) Services() []adapter.Service {
    method Get (line 87) | func (m *Manager) Get(tag string) (adapter.Service, bool) {
    method Remove (line 94) | func (m *Manager) Remove(tag string) error {
    method Create (line 117) | func (m *Manager) Create(ctx context.Context, logger log.ContextLogger...
  function NewManager (line 28) | 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/tailscale.go
  type TailscaleEndpoint (line 5) | type TailscaleEndpoint interface
  type TailscalePingResult (line 10) | type TailscalePingResult struct
  type TailscaleEndpointStatus (line 19) | type TailscaleEndpointStatus struct
  type TailscaleUserGroup (line 28) | type TailscaleUserGroup struct
  type TailscalePeer (line 36) | type TailscalePeer struct

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

FILE: adapter/upstream.go
  function NewUpstreamHandler (line 16) | func NewUpstreamHandler(
  type myUpstreamHandlerWrapper (line 30) | type myUpstreamHandlerWrapper struct
    method NewConnectionEx (line 36) | func (w *myUpstreamHandlerWrapper) NewConnectionEx(ctx context.Context...
    method NewPacketConnectionEx (line 47) | func (w *myUpstreamHandlerWrapper) NewPacketConnectionEx(ctx context.C...
  type myUpstreamContextHandlerWrapper (line 60) | type myUpstreamContextHandlerWrapper struct
    method NewConnectionEx (line 75) | func (w *myUpstreamContextHandlerWrapper) NewConnectionEx(ctx context....
    method NewPacketConnectionEx (line 86) | func (w *myUpstreamContextHandlerWrapper) NewPacketConnectionEx(ctx co...
  function NewUpstreamContextHandler (line 65) | func NewUpstreamContextHandler(
  function NewRouteHandler (line 97) | func NewRouteHandler(
  type routeHandlerWrapper (line 109) | type routeHandlerWrapper struct
    method NewConnectionEx (line 114) | func (r *routeHandlerWrapper) NewConnectionEx(ctx context.Context, con...
    method NewPacketConnectionEx (line 124) | func (r *routeHandlerWrapper) NewPacketConnectionEx(ctx context.Contex...
  function NewRouteContextHandler (line 134) | func NewRouteContextHandler(
  type routeContextHandlerWrapper (line 144) | type routeContextHandlerWrapper struct
    method NewConnectionEx (line 148) | func (r *routeContextHandlerWrapper) NewConnectionEx(ctx context.Conte...
    method NewPacketConnectionEx (line 159) | func (r *routeContextHandlerWrapper) NewPacketConnectionEx(ctx context...

FILE: adapter/upstream_legacy.go
  type LegacyUpstreamHandlerAdapter (line 23) | type LegacyUpstreamHandlerAdapter interface
  function NewLegacyUpstreamHandler (line 32) | func NewLegacyUpstreamHandler(
  type legacyUpstreamHandlerWrapper (line 51) | type legacyUpstreamHandlerWrapper struct
    method NewConnection (line 59) | func (w *legacyUpstreamHandlerWrapper) NewConnection(ctx context.Conte...
    method NewPacketConnection (line 71) | func (w *legacyUpstreamHandlerWrapper) NewPacketConnection(ctx context...
    method NewError (line 83) | func (w *legacyUpstreamHandlerWrapper) NewError(ctx context.Context, e...
  function UpstreamMetadata (line 88) | func UpstreamMetadata(metadata InboundContext) M.Metadata {
  type legacyUpstreamContextHandlerWrapper (line 96) | type legacyUpstreamContextHandlerWrapper struct
    method NewConnection (line 116) | func (w *legacyUpstreamContextHandlerWrapper) NewConnection(ctx contex...
    method NewPacketConnection (line 128) | func (w *legacyUpstreamContextHandlerWrapper) NewPacketConnection(ctx ...
    method NewError (line 140) | func (w *legacyUpstreamContextHandlerWrapper) NewError(ctx context.Con...
  function NewLegacyUpstreamContextHandler (line 103) | func NewLegacyUpstreamContextHandler(
  function NewLegacyRouteHandler (line 145) | func NewLegacyRouteHandler(
  function NewLegacyRouteContextHandler (line 158) | func NewLegacyRouteContextHandler(
  type legacyRouteHandlerWrapper (line 173) | type legacyRouteHandlerWrapper struct
    method NewConnection (line 180) | func (w *legacyRouteHandlerWrapper) NewConnection(ctx context.Context,...
    method NewPacketConnection (line 192) | func (w *legacyRouteHandlerWrapper) NewPacketConnection(ctx context.Co...
    method NewError (line 204) | func (w *legacyRouteHandlerWrapper) NewError(ctx context.Context, err ...
  type legacyRouteContextHandlerWrapper (line 211) | type legacyRouteContextHandlerWrapper struct
    method NewConnection (line 217) | func (w *legacyRouteContextHandlerWrapper) NewConnection(ctx context.C...
    method NewPacketConnection (line 229) | func (w *legacyRouteContextHandlerWrapper) NewPacketConnection(ctx con...
    method NewError (line 241) | func (w *legacyRouteContextHandlerWrapper) NewError(ctx context.Contex...

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 41) | type Box struct
    method PreStart (line 452) | func (s *Box) PreStart() error {
    method Start (line 471) | func (s *Box) Start() error {
    method preStart (line 490) | func (s *Box) preStart() error {
    method start (line 521) | func (s *Box) start() error {
    method Close (line 561) | func (s *Box) Close() error {
    method Network (line 613) | func (s *Box) Network() adapter.NetworkManager {
    method Router (line 617) | func (s *Box) Router() adapter.Router {
    method Inbound (line 621) | func (s *Box) Inbound() adapter.InboundManager {
    method Outbound (line 625) | func (s *Box) Outbound() adapter.OutboundManager {
    method Endpoint (line 629) | func (s *Box) Endpoint() adapter.EndpointManager {
    method LogFactory (line 633) | func (s *Box) LogFactory() log.Factory {
  type Options (line 60) | type Options struct
  function Context (line 66) | func Context(
  function New (line 105) | 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 69) | func fetchChinaFingerprints() (map[string]bool, error) {
  function updateChromeIncludedRootCAs (line 98) | 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_networkquality.go
  function init (line 33) | func init() {
  function runNetworkQuality (line 57) | func runNetworkQuality() error {

FILE: cmd/sing-box/cmd_tools_stun.go
  function init (line 27) | func init() {
  function runSTUN (line 32) | func runSTUN() 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 chromeIncludedPEM (line 5) | func chromeIncludedPEM() string {

FILE: common/certificate/mozilla.go
  function mozillaIncludedPEM (line 5) | func mozillaIncludedPEM() string {

FILE: common/certificate/store.go
  type Store (line 24) | type Store struct
    method Name (line 104) | func (s *Store) Name() string {
    method Start (line 108) | func (s *Store) Start(stage adapter.StartStage) error {
    method Close (line 118) | func (s *Store) Close() error {
    method Pool (line 133) | func (s *Store) Pool() *x509.CertPool {
    method StoreKind (line 139) | func (s *Store) StoreKind() string {
    method ExclusiveAnchors (line 143) | func (s *Store) ExclusiveAnchors() bool {
    method update (line 147) | func (s *Store) update() error {
    method newBasePool (line 216) | func (s *Store) newBasePool() (*x509.CertPool, error) {
  function NewStore (line 37) | func NewStore(ctx context.Context, logger logger.Logger, options option....
  function appendPEMBlock (line 208) | func appendPEMBlock(buffer *bytes.Buffer, block string) {
  function readUniqueDirectoryEntries (line 232) | func readUniqueDirectoryEntries(dir string) ([]fs.DirEntry, error) {
  function isSameDirSymlink (line 246) | func isSameDirSymlink(f fs.DirEntry, dir string) bool {

FILE: common/certificate/store_darwin.go
  type storePlatform (line 30) | type storePlatform struct
  type appleAnchors (line 35) | type appleAnchors struct
    method Retain (line 98) | func (a *appleAnchors) Retain() adapter.AppleAnchors {
    method Release (line 103) | func (a *appleAnchors) Release() {
    method Ref (line 112) | func (a *appleAnchors) Ref() unsafe.Pointer {
  function newAppleAnchors (line 40) | func newAppleAnchors(pemBytes []byte) (*appleAnchors, error) {
  function NewAppleAnchors (line 77) | func NewAppleAnchors(pemBytes []byte) (adapter.AppleAnchors, error) {
  function AcquireAnchors (line 84) | func AcquireAnchors(userAnchors adapter.AppleAnchors, store adapter.Cert...
  method AppleAnchors (line 116) | func (s *Store) AppleAnchors() adapter.AppleAnchors {
  method updatePlatformLocked (line 125) | func (s *Store) updatePlatformLocked(pemBytes []byte) error {
  method closePlatform (line 143) | func (s *Store) closePlatform() error {
  function decodeCertificatePEM (line 153) | func decodeCertificatePEM(pemBytes []byte) [][]byte {

FILE: common/certificate/store_other.go
  type storePlatform (line 6) | type storePlatform struct
  method updatePlatformLocked (line 8) | func (s *Store) updatePlatformLocked(_ []byte) error {
  method closePlatform (line 12) | func (s *Store) closePlatform() error {

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 302) | func FromOptions(rules []option.HeadlessRule) ([]byte, error) {
  function ignoreIPCIDRRegexp (line 400) | func ignoreIPCIDRRegexp(ruleLine string) bool {
  function parseAdGuardHostLine (line 412) | func parseAdGuardHostLine(ruleLine string) (string, error) {
  function parseADGuardIPCIDRLine (line 431) | 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 242) | func (d *DefaultDialer) DialContext(ctx context.Context, network strin...
    method DialParallelInterface (line 269) | func (d *DefaultDialer) DialParallelInterface(ctx context.Context, net...
    method ListenPacket (line 317) | func (d *DefaultDialer) ListenPacket(ctx context.Context, destination ...
    method DialerForICMPDestination (line 333) | func (d *DefaultDialer) DialerForICMPDestination(destination netip.Add...
    method ListenSerialInterfacePacket (line 341) | func (d *DefaultDialer) ListenSerialInterfacePacket(ctx context.Contex...
    method WireGuardControl (line 374) | func (d *DefaultDialer) WireGuardControl() control.Func {
    method trackConn (line 378) | func (d *DefaultDialer) trackConn(conn net.Conn, err error) (net.Conn,...
    method trackPacketConn (line 385) | 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 226) | 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 151) | func (d *DefaultDialer) listenSerialInterfacePacket(ctx context.Context,...
  function selectInterfaces (line 183) | 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 52) | func (d *DetourDialer) Dialer() (N.Dialer, error) {
    method init (line 57) | func (d *DetourDialer) init() {
    method DialContext (line 80) | func (d *DetourDialer) DialContext(ctx context.Context, network string...
    method ListenPacket (line 88) | func (d *DetourDialer) ListenPacket(ctx context.Context, destination M...
    method Upstream (line 96) | func (d *DetourDialer) Upstream() any {
  function NewDetour (line 29) | func NewDetour(outboundManager adapter.OutboundManager, detour string, d...
  function NewDefaultOutboundDetour (line 37) | func NewDefaultOutboundDetour(outboundManager adapter.OutboundManager) N...
  function InitializeDetour (line 44) | func InitializeDetour(dialer N.Dialer) error {

FILE: common/dialer/dialer.go
  type Options (line 19) | type Options struct
  function New (line 32) | func New(ctx context.Context, options option.DialerOptions, remoteIsDoma...
  function NewWithOptions (line 40) | func NewWithOptions(options Options) (N.Dialer, error) {
  type ParallelInterfaceDialer (line 148) | type ParallelInterfaceDialer interface
  type ParallelNetworkDialer (line 154) | type ParallelNetworkDialer interface
  type PacketDialerWithDestination (line 159) | 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 oldReadString (line 22) | func oldReadString(reader varbin.Reader) (string, error) {
  function oldReadItem (line 27) | func oldReadItem(reader varbin.Reader) (Item, error) {
  function TestStringCompat (line 32) | func TestStringCompat(t *testing.T) {
  function TestItemCompat (line 81) | func TestItemCompat(t *testing.T) {
  function TestGeositeWriteReadCompat (line 135) | func TestGeositeWriteReadCompat(t *testing.T) {
  function generateLargeItems (line 220) | 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 51) | func (r *Reader) readMetadata() error {
    method Read (line 97) | func (r *Reader) Read(code string) ([]Item, error) {
    method Upstream (line 125) | 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 readCounter (line 129) | type readCounter struct
    method Read (line 134) | func (r *readCounter) Read(p []byte) (n int, err error) {
  function readString (line 142) | 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/httpclient/apple_transport_darwin.go
  constant applePinnedHashSize (line 40) | applePinnedHashSize = sha256.Size
  function verifyApplePinnedPublicKeySHA256 (line 51) | func verifyApplePinnedPublicKeySHA256(flatHashes []byte, leafCertificate...
  function box_apple_http_verify_public_key_sha256 (line 63) | func box_apple_http_verify_public_key_sha256(knownHashValues *C.uint8_t,...
  type appleSessionConfig (line 73) | type appleSessionConfig struct
    method close (line 200) | func (c *appleSessionConfig) close() {
  type appleTransportShared (line 84) | type appleTransportShared struct
    method retain (line 207) | func (s *appleTransportShared) retain() {
    method release (line 211) | func (s *appleTransportShared) release() error {
    method newSession (line 219) | func (s *appleTransportShared) newSession() (*C.box_apple_http_session...
  type appleTransport (line 92) | type appleTransport struct
    method RoundTrip (line 258) | func (t *appleTransport) RoundTrip(request *http.Request) (*http.Respo...
    method CloseIdleConnections (line 376) | func (t *appleTransport) CloseIdleConnections() {
    method Close (line 400) | func (t *appleTransport) Close() error {
  function newAppleTransport (line 99) | func newAppleTransport(ctx context.Context, logger logger.ContextLogger,...
  function newAppleSessionConfig (line 134) | func newAppleSessionConfig(ctx context.Context, options option.HTTPClien...
  function flattenRequestHeaders (line 414) | func flattenRequestHeaders(request *http.Request) ([]string, []string) {
  function parseAppleHTTPResponse (line 432) | func parseAppleHTTPResponse(request *http.Request, response *C.box_apple...
  function appleCStringError (line 455) | func appleCStringError(cErr *C.char, message string) error {

FILE: common/httpclient/apple_transport_darwin.h
  type box_apple_http_session_t (line 5) | typedef struct box_apple_http_session box_apple_http_session_t;
  type box_apple_http_task_t (line 6) | typedef struct box_apple_http_task box_apple_http_task_t;
  type box_apple_http_session_config_t (line 8) | typedef struct box_apple_http_session_config {
  type box_apple_http_request_t (line 22) | typedef struct box_apple_http_request {
  type box_apple_http_response_t (line 34) | typedef struct box_apple_http_response {

FILE: common/httpclient/apple_transport_darwin_test.go
  constant appleHTTPTestTimeout (line 37) | appleHTTPTestTimeout = 5 * time.Second
  constant appleHTTPRecoveryLoops (line 39) | appleHTTPRecoveryLoops = 5
  type appleHTTPTestDialer (line 41) | type appleHTTPTestDialer struct
    method DialContext (line 843) | func (d *appleHTTPTestDialer) DialContext(ctx context.Context, network...
    method ListenPacket (line 854) | func (d *appleHTTPTestDialer) ListenPacket(ctx context.Context, destin...
  type appleHTTPObservedRequest (line 47) | type appleHTTPObservedRequest struct
  type appleHTTPTestServer (line 55) | type appleHTTPTestServer struct
    method URL (line 779) | func (s *appleHTTPTestServer) URL(path string) string {
  type appleTestAnchors (line 64) | type appleTestAnchors struct
    method Retain (line 69) | func (a *appleTestAnchors) Retain() adapter.AppleAnchors {
    method Release (line 73) | func (a *appleTestAnchors) Release() {
    method Ref (line 77) | func (a *appleTestAnchors) Ref() unsafe.Pointer {
  function TestNewAppleSessionConfig (line 81) | func TestNewAppleSessionConfig(t *testing.T) {
  function TestAppleTransportVerifyPublicKeySHA256 (line 393) | func TestAppleTransportVerifyPublicKeySHA256(t *testing.T) {
  function TestNewAppleTransportClosesSessionConfigOnBridgeFailure (line 421) | func TestNewAppleTransportClosesSessionConfigOnBridgeFailure(t *testing....
  function TestNewAppleTransportClosesSessionConfigOnSessionFailure (line 441) | func TestNewAppleTransportClosesSessionConfigOnSessionFailure(t *testing...
  function TestAppleTransportRoundTripHTTPS (line 461) | func TestAppleTransportRoundTripHTTPS(t *testing.T) {
  function TestAppleTransportPinnedPublicKey (line 545) | func TestAppleTransportPinnedPublicKey(t *testing.T) {
  function TestAppleTransportGuardrails (line 590) | func TestAppleTransportGuardrails(t *testing.T) {
  function TestAppleTransportCancellationRecovery (line 667) | func TestAppleTransportCancellationRecovery(t *testing.T) {
  function TestAppleTransportLifecycle (line 715) | func TestAppleTransportLifecycle(t *testing.T) {
  function startAppleHTTPTestServer (line 749) | func startAppleHTTPTestServer(t *testing.T, handler http.HandlerFunc) *a...
  function newAppleHTTPTestTransport (line 789) | func newAppleHTTPTestTransport(t *testing.T, server *appleHTTPTestServer...
  function newAppleHTTPTestContext (line 810) | func newAppleHTTPTestContext() context.Context {
  function appleTransportAnchorOptions (line 817) | func appleTransportAnchorOptions(certificatePEM string) option.HTTPClien...
  function restoreAppleTransportFactories (line 831) | func restoreAppleTransportFactories(t *testing.T) {
  function newAppleHTTPTestCertificate (line 868) | func newAppleHTTPTestCertificate(t *testing.T, serverName string) (stdtl...
  function certificatePublicKeySHA256 (line 882) | func certificatePublicKeySHA256(t *testing.T, certificateDER []byte) []b...
  function appleHTTPServerTLSOptions (line 897) | func appleHTTPServerTLSOptions(server *appleHTTPTestServer) *option.Outb...
  function newAppleHTTPRequest (line 905) | func newAppleHTTPRequest(t *testing.T, method string, rawURL string, bod...
  function newAppleHTTPRequestWithContext (line 910) | func newAppleHTTPRequestWithContext(t *testing.T, ctx context.Context, m...
  function waitObservedRequest (line 919) | func waitObservedRequest(t *testing.T, requests <-chan appleHTTPObserved...
  function readResponseBody (line 931) | func readResponseBody(t *testing.T, response *http.Response) string {
  function assertAppleHTTPSucceeds (line 941) | func assertAppleHTTPSucceeds(t *testing.T, transport http.RoundTripper, ...

FILE: common/httpclient/apple_transport_stub.go
  function newAppleTransport (line 14) | func newAppleTransport(ctx context.Context, logger logger.ContextLogger,...

FILE: common/httpclient/client.go
  function NewTransport (line 17) | func NewTransport(ctx context.Context, logger logger.ContextLogger, tag ...
  function newTransport (line 87) | func newTransport(rawDialer N.Dialer, baseTLSConfig tls.Config, options ...

FILE: common/httpclient/context.go
  type transportKey (line 5) | type transportKey struct
  function contextWithTransportTag (line 7) | func contextWithTransportTag(ctx context.Context, transportTag string) c...
  function transportTagFromContext (line 11) | func transportTagFromContext(ctx context.Context) (string, bool) {

FILE: common/httpclient/helpers.go
  function dialTLS (line 19) | func dialTLS(ctx context.Context, rawDialer N.Dialer, baseTLSConfig tls....
  function applyHeaders (line 44) | func applyHeaders(request *http.Request, headers http.Header, host strin...
  function requestRequiresHTTP1 (line 53) | func requestRequiresHTTP1(request *http.Request) bool {
  function requestReplayable (line 58) | func requestReplayable(request *http.Request) bool {
  function cloneRequestForRetry (line 62) | func cloneRequestForRetry(request *http.Request) *http.Request {
  function mustGetBody (line 70) | func mustGetBody(request *http.Request) io.ReadCloser {
  function requestAuthority (line 78) | func requestAuthority(request *http.Request) string {
  function buildSTDTLSConfig (line 106) | func buildSTDTLSConfig(baseTLSConfig tls.Config, destination M.Socksaddr...

FILE: common/httpclient/helpers_test.go
  function TestRequestAuthority (line 9) | func TestRequestAuthority(t *testing.T) {

FILE: common/httpclient/http1_transport.go
  type http1Transport (line 13) | type http1Transport struct
    method RoundTrip (line 31) | func (t *http1Transport) RoundTrip(request *http.Request) (*http.Respo...
    method CloseIdleConnections (line 35) | func (t *http1Transport) CloseIdleConnections() {
    method Close (line 39) | func (t *http1Transport) Close() error {
  function newHTTP1Transport (line 17) | func newHTTP1Transport(rawDialer N.Dialer, baseTLSConfig tls.Config) *ht...

FILE: common/httpclient/http2_config.go
  function CloneHTTP2Transport (line 14) | func CloneHTTP2Transport(transport *http2.Transport) *http2.Transport {
  function ConfigureHTTP2Transport (line 22) | func ConfigureHTTP2Transport(options option.HTTP2Options) (*http2.Transp...

FILE: common/httpclient/http2_fallback_transport.go
  type http2FallbackTransport (line 22) | type http2FallbackTransport struct
    method isH2Fallback (line 45) | func (t *http2FallbackTransport) isH2Fallback(authority string) bool {
    method markH2Fallback (line 55) | func (t *http2FallbackTransport) markH2Fallback(authority string) {
    method RoundTrip (line 64) | func (t *http2FallbackTransport) RoundTrip(request *http.Request) (*ht...
    method roundTrip (line 68) | func (t *http2FallbackTransport) roundTrip(request *http.Request, allo...
    method CloseIdleConnections (line 90) | func (t *http2FallbackTransport) CloseIdleConnections() {
    method Close (line 95) | func (t *http2FallbackTransport) Close() error {
  function newHTTP2FallbackTransport (line 29) | func newHTTP2FallbackTransport(rawDialer N.Dialer, baseTLSConfig tls.Con...

FILE: common/httpclient/http2_fallback_transport_test.go
  function TestHTTP2FallbackAuthorityIsolation (line 7) | func TestHTTP2FallbackAuthorityIsolation(t *testing.T) {
  function TestHTTP2FallbackEmptyAuthorityNoOp (line 27) | func TestHTTP2FallbackEmptyAuthorityNoOp(t *testing.T) {

FILE: common/httpclient/http2_transport.go
  type http2Transport (line 17) | type http2Transport struct
    method RoundTrip (line 37) | func (t *http2Transport) RoundTrip(request *http.Request) (*http.Respo...
    method CloseIdleConnections (line 44) | func (t *http2Transport) CloseIdleConnections() {
    method Close (line 49) | func (t *http2Transport) Close() error {
  function newHTTP2Transport (line 22) | func newHTTP2Transport(rawDialer N.Dialer, baseTLSConfig tls.Config, opt...

FILE: common/httpclient/http3_transport.go
  type http3Transport (line 23) | type http3Transport struct
    method RoundTrip (line 125) | func (t *http3Transport) RoundTrip(request *http.Request) (*http.Respo...
    method CloseIdleConnections (line 129) | func (t *http3Transport) CloseIdleConnections() {
    method Close (line 133) | func (t *http3Transport) Close() error {
  type http3BrokenEntry (line 27) | type http3BrokenEntry struct
  type http3FallbackTransport (line 32) | type http3FallbackTransport struct
    method RoundTrip (line 138) | func (t *http3FallbackTransport) RoundTrip(request *http.Request) (*ht...
    method roundTripHTTP3 (line 145) | func (t *http3FallbackTransport) roundTripHTTP3(request *http.Request)...
    method roundTripHTTP3Race (line 171) | func (t *http3FallbackTransport) roundTripHTTP3Race(request *http.Requ...
    method h2FallbackRoundTrip (line 261) | func (t *http3FallbackTransport) h2FallbackRoundTrip(request *http.Req...
    method CloseIdleConnections (line 268) | func (t *http3FallbackTransport) CloseIdleConnections() {
    method Close (line 273) | func (t *http3FallbackTransport) Close() error {
    method h3Broken (line 278) | func (t *http3FallbackTransport) h3Broken(authority string) bool {
    method clearH3Broken (line 295) | func (t *http3FallbackTransport) clearH3Broken(authority string) {
    method markH3Broken (line 304) | func (t *http3FallbackTransport) markH3Broken(authority string) {
  function newHTTP3RoundTripper (line 40) | func newHTTP3RoundTripper(
  function newHTTP3Transport (line 100) | func newHTTP3Transport(
  function newHTTP3FallbackTransport (line 110) | func newHTTP3FallbackTransport(

FILE: common/httpclient/http3_transport_stub.go
  function newHTTP3FallbackTransport (line 14) | func newHTTP3FallbackTransport(
  function newHTTP3Transport (line 24) | func newHTTP3Transport(

FILE: common/httpclient/http3_transport_test.go
  function TestHTTP3BrokenAuthorityIsolation (line 10) | func TestHTTP3BrokenAuthorityIsolation(t *testing.T) {
  function TestHTTP3BrokenBackoffPerAuthority (line 22) | func TestHTTP3BrokenBackoffPerAuthority(t *testing.T) {
  function TestHTTP3BrokenBackoffCap (line 48) | func TestHTTP3BrokenBackoffCap(t *testing.T) {
  function TestHTTP3BrokenClearDeletesEntry (line 58) | func TestHTTP3BrokenClearDeletesEntry(t *testing.T) {
  function TestHTTP3BrokenExpiredEntryGarbageCollected (line 73) | func TestHTTP3BrokenExpiredEntryGarbageCollected(t *testing.T) {
  function TestHTTP3BrokenEmptyAuthorityNoOp (line 88) | func TestHTTP3BrokenEmptyAuthorityNoOp(t *testing.T) {

FILE: common/httpclient/managed_transport.go
  type innerTransport (line 14) | type innerTransport interface
  type ManagedTransport (line 22) | type ManagedTransport struct
    method getEpoch (line 63) | func (t *ManagedTransport) getEpoch() (*transportEpoch, error) {
    method acquireEpoch (line 83) | func (t *ManagedTransport) acquireEpoch() (*transportEpoch, error) {
    method releaseEpoch (line 97) | func (t *ManagedTransport) releaseEpoch(epoch *transportEpoch) {
    method retireEpoch (line 103) | func (t *ManagedTransport) retireEpoch(epoch *transportEpoch) {
    method RoundTrip (line 113) | func (t *ManagedTransport) RoundTrip(request *http.Request) (*http.Res...
    method CloseIdleConnections (line 140) | func (t *ManagedTransport) CloseIdleConnections() {
    method Reset (line 149) | func (t *ManagedTransport) Reset() {
    method close (line 164) | func (t *ManagedTransport) close() error {
  type transportEpoch (line 34) | type transportEpoch struct
    method tryClose (line 47) | func (e *transportEpoch) tryClose() {
  type managedResponseBody (line 41) | type managedResponseBody struct
    method Read (line 53) | func (b *managedResponseBody) Read(p []byte) (int, error) {
    method Close (line 57) | func (b *managedResponseBody) Close() error {
  type sharedRef (line 174) | type sharedRef struct
    method RoundTrip (line 192) | func (r *sharedRef) RoundTrip(request *http.Request) (*http.Response, ...
    method CloseIdleConnections (line 199) | func (r *sharedRef) CloseIdleConnections() {
    method Reset (line 207) | func (r *sharedRef) Reset() {
  type sharedState (line 180) | type sharedState struct
  function newSharedRef (line 184) | func newSharedRef(managed *ManagedTransport, shared *sharedState) *share...

FILE: common/httpclient/manager.go
  type Manager (line 19) | type Manager struct
    method Initialize (line 54) | func (m *Manager) Initialize(defaultTransportFallback func() (*Managed...
    method Name (line 58) | func (m *Manager) Name() string {
    method Start (line 62) | func (m *Manager) Start(stage adapter.StartStage) error {
    method DefaultTransport (line 76) | func (m *Manager) DefaultTransport() adapter.HTTPTransport {
    method ResolveTransport (line 97) | func (m *Manager) ResolveTransport(ctx context.Context, logger logger....
    method trackTransport (line 127) | func (m *Manager) trackTransport(transport *ManagedTransport) {
    method resolveShared (line 133) | func (m *Manager) resolveShared(tag string) (*sharedManagedTransport, ...
    method ResetNetwork (line 156) | func (m *Manager) ResetNetwork() {
    method Close (line 164) | func (m *Manager) Close() error {
  type sharedManagedTransport (line 31) | type sharedManagedTransport struct
  function NewManager (line 36) | func NewManager(ctx context.Context, logger log.ContextLogger, clients [...

FILE: common/interrupt/conn.go
  type Conn (line 20) | type Conn struct
    method Close (line 30) | func (c *Conn) Close() error {
    method ReaderReplaceable (line 37) | func (c *Conn) ReaderReplaceable() bool {
    method WriterReplaceable (line 41) | func (c *Conn) WriterReplaceable() bool {
    method Upstream (line 45) | func (c *Conn) Upstream() any {
  type PacketConn (line 49) | type PacketConn struct
    method Close (line 59) | func (c *PacketConn) Close() error {
    method ReaderReplaceable (line 66) | func (c *PacketConn) ReaderReplaceable() bool {
    method WriterReplaceable (line 70) | func (c *PacketConn) WriterReplaceable() bool {
    method Upstream (line 74) | 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
  function readUint8LengthPrefixed (line 13) | func readUint8LengthPrefixed(s *cryptobyte.String, out *[]byte) bool {
  function readUint16LengthPrefixed (line 19) | func readUint16LengthPrefixed(s *cryptobyte.String, out *[]byte) bool {
  type keyUpdateMsg (line 23) | type keyUpdateMsg struct
    method marshal (line 27) | func (m *keyUpdateMsg) marshal() ([]byte, error) {
    method unmarshal (line 41) | func (m *keyUpdateMsg) unmarshal(data []byte) bool {
  constant typeHelloRequest (line 62) | typeHelloRequest          uint8 = 0
  constant typeClientHello (line 63) | typeClientHello           uint8 = 1
  constant typeServerHello (line 64) | typeServerHello           uint8 = 2
  constant typeNewSessionTicket (line 65) | typeNewSessionTicket      uint8 = 4
  constant typeEndOfEarlyData (line 66) | typeEndOfEarlyData        uint8 = 5
  constant typeEncryptedExtensions (line 67) | typeEncryptedExtensions   uint8 = 8
  constant typeCertificate (line 68) | typeCertificate           uint8 = 11
  constant typeServerKeyExchange (line 69) | typeServerKeyExchange     uint8 = 12
  constant typeCertificateRequest (line 70) | typeCertificateRequest    uint8 = 13
  constant typeServerHelloDone (line 71) | typeServerHelloDone       uint8 = 14
  constant typeCertificateVerify (line 72) | typeCertificateVerify     uint8 = 15
  constant typeClientKeyExchange (line 73) | typeClientKeyExchange     uint8 = 16
  constant typeFinished (line 74) | typeFinished              uint8 = 20
  constant typeCertificateStatus (line 75) | typeCertificateStatus     uint8 = 22
  constant typeKeyUpdate (line 76) | typeKeyUpdate             uint8 = 24
  constant typeCompressedCertificate (line 77) | typeCompressedCertificate uint8 = 25
  constant typeMessageHash (line 78) | typeMessageHash           uint8 = 254
  constant extensionServerName (line 83) | extensionServerName              uint16 = 0
  constant extensionStatusRequest (line 84) | extensionStatusRequest           uint16 = 5
  constant extensionSupportedCurves (line 85) | extensionSupportedCurves         uint16 = 10
  constant extensionSupportedPoints (line 86) | extensionSupportedPoints         uint16 = 11
  constant extensionSignatureAlgorithms (line 87) | extensionSignatureAlgorithms     uint16 = 13
  constant extensionALPN (line 88) | extensionALPN                    uint16 = 16
  constant extensionSCT (line 89) | extensionSCT                     uint16 = 18
  constant extensionPadding (line 90) | extensionPadding                 uint16 = 21
  constant extensionExtendedMasterSecret (line 91) | extensionExtendedMasterSecret    uint16 = 23
  constant extensionCompressCertificate (line 92) | extensionCompressCertificate     uint16 = 27
  constant extensionSessionTicket (line 93) | extensionSessionTicket           uint16 = 35
  constant extensionPreSharedKey (line 94) | extensionPreSharedKey            uint16 = 41
  constant extensionEarlyData (line 95) | extensionEarlyData               uint16 = 42
  constant extensionSupportedVersions (line 96) | extensionSupportedVersions       uint16 = 43
  constant extensionCookie (line 97) | extensionCookie                  uint16 = 44
  constant extensionPSKModes (line 98) | extensionPSKModes                uint16 = 45
  constant extensionCertificateAuthorities (line 99) | extensionCertificateAuthorities  uint16 = 47
  constant extensionSignatureAlgorithmsCert (line 100) | extensionSignatureAlgorithmsCert uint16 = 50
  constant extensionKeyShare (line 101) | extensionKeyShare                uint16 = 51
  constant extensionQUICTransportParameters (line 102) | extensionQUICTransportParameters uint16 = 57
  constant extensionALPS (line 103) | extensionALPS                    uint16 = 17513
  constant extensionRenegotiationInfo (line 104) | extensionRenegotiationInfo       uint16 = 0xff01
  constant extensionECHOuterExtensions (line 105) | extensionECHOuterExtensions      uint16 = 0xfd00
  constant extensionEncryptedClientHello (line 106) | extensionEncryptedClientHello    uint16 = 0xfe0d
  type handshakeMessage (line 109) | type handshakeMessage interface
  type newSessionTicketMsgTLS13 (line 113) | type newSessionTicketMsgTLS13 struct
    method marshal (line 121) | func (m *newSessionTicketMsgTLS13) marshal() ([]byte, error) {
    method unmarshal (line 147) | 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...

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 85) | func (l *Listener) loopTCPIn() {

FILE: common/listener/listener_udp.go
  constant udpOutputBatchSize (line 22) | udpOutputBatchSize = 128
  method ListenUDP (line 24) | func (l *Listener) ListenUDP() (net.PacketConn, error) {
  method DialContext (line 64) | func (l *Listener) DialContext(dialer net.Dialer, ctx context.Context, n...
  method ListenPacket (line 79) | func (l *Listener) ListenPacket(listenConfig net.ListenConfig, ctx conte...
  method UDPAddr (line 94) | func (l *Listener) UDPAddr() M.Socksaddr {
  method PacketWriter (line 98) | func (l *Listener) PacketWriter() N.PacketWriter {
  method loopUDPIn (line 102) | func (l *Listener) loopUDPIn() {
  method loopUDPInBatch (line 168) | func (l *Listener) loopUDPInBatch(handler adapter.PacketBatchHandler, re...
  method loopUDPOut (line 188) | func (l *Listener) loopUDPOut() {
  method releasePacketOutbound (line 231) | func (l *Listener) releasePacketOutbound() {
  type packetWriter (line 243) | type packetWriter
    method WritePacket (line 245) | func (w *packetWriter) WritePacket(buffer *buf.Buffer, destination M.S...
    method WritePacketBatch (line 263) | func (w *packetWriter) WritePacketBatch(buffers []*buf.Buffer, destina...
    method WriteIsThreadUnsafe (line 288) | 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/networkquality/http.go
  function FormatBitrate (line 17) | func FormatBitrate(bps int64) string {
  function NewHTTPClient (line 30) | func NewHTTPClient(dialer N.Dialer) *http.Client {
  function baseTransportFromClient (line 43) | func baseTransportFromClient(client *http.Client) (*http.Transport, erro...
  function newMeasurementClient (line 57) | func newMeasurementClient(
  type MeasurementClientFactory (line 105) | type MeasurementClientFactory
  function defaultMeasurementClientFactory (line 113) | func defaultMeasurementClientFactory(baseClient *http.Client) Measuremen...
  function NewOptionalHTTP3Factory (line 119) | func NewOptionalHTTP3Factory(dialer N.Dialer, useHTTP3 bool) (Measuremen...
  function rewriteDialAddress (line 126) | func rewriteDialAddress(addr string, connectEndpoint string) string {

FILE: common/networkquality/http3.go
  function NewHTTP3MeasurementClientFactory (line 18) | func NewHTTP3MeasurementClientFactory(dialer N.Dialer) (MeasurementClien...

FILE: common/networkquality/http3_stub.go
  function NewHTTP3MeasurementClientFactory (line 10) | func NewHTTP3MeasurementClientFactory(dialer N.Dialer) (MeasurementClien...

FILE: common/networkquality/networkquality.go
  constant DefaultConfigURL (line 25) | DefaultConfigURL = "https://mensura.cdn-apple.com/api/v1/gm/config"
  type Config (line 27) | type Config struct
  type URLs (line 33) | type URLs struct
    method smallDownloadURL (line 42) | func (u *URLs) smallDownloadURL() string {
    method largeDownloadURL (line 49) | func (u *URLs) largeDownloadURL() string {
    method uploadURL (line 56) | func (u *URLs) uploadURL() string {
  type Accuracy (line 63) | type Accuracy
    method String (line 71) | func (a Accuracy) String() string {
  constant AccuracyLow (line 66) | AccuracyLow    Accuracy = 0
  constant AccuracyMedium (line 67) | AccuracyMedium Accuracy = 1
  constant AccuracyHigh (line 68) | AccuracyHigh   Accuracy = 2
  type Result (line 82) | type Result struct
  type Progress (line 94) | type Progress struct
  type Phase (line 108) | type Phase
  constant PhaseIdle (line 111) | PhaseIdle     Phase = 0
  constant PhaseDownload (line 112) | PhaseDownload Phase = 1
  constant PhaseUpload (line 113) | PhaseUpload   Phase = 2
  constant PhaseDone (line 114) | PhaseDone     Phase = 3
  type Options (line 117) | type Options struct
  constant DefaultMaxRuntime (line 127) | DefaultMaxRuntime = 20 * time.Second
  type measurementSettings (line 129) | type measurementSettings struct
  type resolvedConfig (line 159) | type resolvedConfig struct
  type directionPlan (line 166) | type directionPlan struct
  type probeTrace (line 173) | type probeTrace struct
  type probeMeasurement (line 185) | type probeMeasurement struct
  type probeRound (line 195) | type probeRound struct
    method responsivenessLatency (line 203) | func (p probeRound) responsivenessLatency() float64 {
  constant maxConsecutiveErrors (line 220) | maxConsecutiveErrors = 3
  type loadConnection (line 222) | type loadConnection struct
    method run (line 230) | func (c *loadConnection) run(ctx context.Context, onError func(error)) {
  type intervalThroughput (line 266) | type intervalThroughput struct
  type intervalWindow (line 271) | type intervalWindow struct
  type stabilityTracker (line 276) | type stabilityTracker struct
    method add (line 283) | func (s *stabilityTracker) add(value float64) bool {
    method ready (line 298) | func (s *stabilityTracker) ready() bool {
    method accuracy (line 302) | func (s *stabilityTracker) accuracy() Accuracy {
    method stable (line 312) | func (s *stabilityTracker) stable() bool {
  type directionMeasurement (line 323) | type directionMeasurement struct
  type directionRunner (line 330) | type directionRunner struct
    method fail (line 364) | func (r *directionRunner) fail(err error) {
    method onConnectionFailed (line 376) | func (r *directionRunner) onConnectionFailed(err error) {
    method addConnection (line 390) | func (r *directionRunner) addConnection(ctx context.Context) error {
    method connectionCount (line 418) | func (r *directionRunner) connectionCount() int {
    method pickReadyConnection (line 424) | func (r *directionRunner) pickReadyConnection() *loadConnection {
    method startProber (line 439) | func (r *directionRunner) startProber(ctx context.Context) {
    method runProbeRound (line 461) | func (r *directionRunner) runProbeRound(ctx context.Context, selfClien...
    method probeInterval (line 480) | func (r *directionRunner) probeInterval() time.Duration {
    method recordProbeRound (line 498) | func (r *directionRunner) recordProbeRound(round probeRound) {
    method swapIntervalProbeValues (line 508) | func (r *directionRunner) swapIntervalProbeValues() []float64 {
    method setResponsivenessWindow (line 516) | func (r *directionRunner) setResponsivenessWindow(currentInterval int) {
    method recordThroughput (line 523) | func (r *directionRunner) recordThroughput(interval int, bps float64) {
    method setThroughputWindow (line 529) | func (r *directionRunner) setThroughputWindow(currentInterval int) {
    method finalRPM (line 536) | func (r *directionRunner) finalRPM() int32 {
    method finalCapacity (line 554) | func (r *directionRunner) finalCapacity(totalDuration time.Duration) i...
    method wait (line 579) | func (r *directionRunner) wait() {
  function newDirectionRunner (line 355) | func newDirectionRunner(factory MeasurementClientFactory, plan direction...
  function Run (line 583) | func Run(options Options) (*Result, error) {
  function normalizeMaxRuntime (line 680) | func normalizeMaxRuntime(maxRuntime time.Duration) (time.Duration, error) {
  function measureSerial (line 690) | func measureSerial(
  function measureParallel (line 744) | func measureParallel(
  function resolveConfigURL (line 843) | func resolveConfigURL(rawURL string) string {
  function fetchConfig (line 862) | func fetchConfig(ctx context.Context, client *http.Client, configURL str...
  function validateConfig (line 882) | func validateConfig(config *Config) (*resolvedConfig, error) {
  function measureIdleLatency (line 931) | func measureIdleLatency(ctx context.Context, factory MeasurementClientFa...
  function measureDirection (line 958) | func measureDirection(
  function splitRuntimeBudget (line 1076) | func splitRuntimeBudget(total time.Duration, directions int) (time.Durat...
  function collectProbeRound (line 1085) | func collectProbeRound(ctx context.Context, foreignClient *http.Client, ...
  function runProbe (line 1117) | func runProbe(ctx context.Context, client *http.Client, rawURL string, e...
  function runDownloadRequest (line 1213) | func runDownloadRequest(ctx context.Context, client *http.Client, rawURL...
  function runUploadRequest (line 1237) | func runUploadRequest(ctx context.Context, client *http.Client, rawURL s...
  function newRequest (line 1265) | func newRequest(ctx context.Context, method string, rawURL string, body ...
  function closeMeasurementClient (line 1274) | func closeMeasurementClient(client *http.Client) {
  function validateResponse (line 1284) | func validateResponse(resp *http.Response) error {
  function calculateRPM (line 1294) | func calculateRPM(rounds []probeRound) int32 {
  function tlsHandshakeRoundTrips (line 1339) | func tlsHandshakeRoundTrips(version uint16) int {
  function durationMillis (line 1348) | func durationMillis(value time.Duration) float64 {
  function upperTrimmedMean (line 1352) | func upperTrimmedMean(values []float64, trimPercent int) float64 {
  function upperTrimFloat64s (line 1360) | func upperTrimFloat64s(values []float64, trimPercent int) []float64 {
  function meanFloat64s (line 1376) | func meanFloat64s(values []float64) float64 {
  function stdDevFloat64s (line 1387) | func stdDevFloat64s(values []float64) float64 {
  type uploadBody (line 1400) | type uploadBody struct
    method Read (line 1406) | func (u *uploadBody) Read(p []byte) (int, error) {
    method Close (line 1418) | func (u *uploadBody) Close() error {

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 22) | type Config struct
  function FindProcessInfo (line 27) | func FindProcessInfo(searcher Searcher, ctx context.Context, network str...

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

FILE: common/process/searcher_darwin.go
  type darwinSearcher (line 17) | type darwinSearcher struct
    method Close (line 23) | func (d *darwinSearcher) Close() error {
    method FindProcessInfo (line 27) | func (d *darwinSearcher) FindProcessInfo(ctx context.Context, network ...
  function NewSearcher (line 19) | func NewSearcher(_ Config) (Searcher, error) {

FILE: common/process/searcher_darwin_shared.go
  constant darwinSnapshotTTL (line 21) | darwinSnapshotTTL = 200 * time.Millisecond
  constant darwinXinpgenSize (line 23) | darwinXinpgenSize        = 24
  constant darwinXsocketOffset (line 24) | darwinXsocketOffset      = 104
  constant darwinXinpcbForeignPort (line 25) | darwinXinpcbForeignPort  = 16
  constant darwinXinpcbLocalPort (line 26) | darwinXinpcbLocalPort    = 18
  constant darwinXinpcbVFlag (line 27) | darwinXinpcbVFlag        = 44
  constant darwinXinpcbForeignAddr (line 28) | darwinXinpcbForeignAddr  = 48
  constant darwinXinpcbLocalAddr (line 29) | darwinXinpcbLocalAddr    = 64
  constant darwinXinpcbIPv4Addr (line 30) | darwinXinpcbIPv4Addr     = 12
  constant darwinXsocketUID (line 31) | darwinXsocketUID         = 64
  constant darwinXsocketLastPID (line 32) | darwinXsocketLastPID     = 68
  constant darwinTCPExtraStructSize (line 33) | darwinTCPExtraStructSize = 208
  type darwinConnectionEntry (line 36) | type darwinConnectionEntry struct
  type darwinConnectionMatchKind (line 45) | type darwinConnectionMatchKind
  constant darwinConnectionMatchExact (line 48) | darwinConnectionMatchExact darwinConnectionMatchKind = iota
  constant darwinConnectionMatchLocalFallback (line 49) | darwinConnectionMatchLocalFallback
  constant darwinConnectionMatchWildcardFallback (line 50) | darwinConnectionMatchWildcardFallback
  type darwinSnapshot (line 53) | type darwinSnapshot struct
  type darwinConnectionFinder (line 58) | type darwinConnectionFinder struct
    method find (line 79) | func (f *darwinConnectionFinder) find(network string, source netip.Add...
    method loadSnapshot (line 122) | func (f *darwinConnectionFinder) loadSnapshot(network string, forceRef...
  function newDarwinConnectionFinder (line 67) | func newDarwinConnectionFinder(ttl time.Duration) *darwinConnectionFinder {
  function FindDarwinConnectionOwner (line 75) | func FindDarwinConnectionOwner(network string, source netip.AddrPort, de...
  function buildDarwinSnapshot (line 138) | func buildDarwinSnapshot(network string) (darwinSnapshot, error) {
  function darwinSnapshotSettings (line 153) | func darwinSnapshotSettings(network string) (string, int, error) {
  function parseDarwinSnapshot (line 165) | func parseDarwinSnapshot(buf []byte, itemSize int) []darwinConnectionEnt...
  function parseDarwinConnectionEntry (line 178) | func parseDarwinConnectionEntry(inp []byte, so []byte) (darwinConnection...
  function matchDarwinConnectionEntry (line 203) | func matchDarwinConnectionEntry(entries []darwinConnectionEntry, network...
  function normalizeDarwinAddrPort (line 243) | func normalizeDarwinAddrPort(addrPort netip.AddrPort) netip.AddrPort {
  function getExecPathFromPID (line 250) | func getExecPathFromPID(pid uint32) (string, error) {

FILE: common/process/searcher_linux.go
  type linuxSearcher (line 19) | type linuxSearcher struct
    method Close (line 38) | func (s *linuxSearcher) Close() error {
    method FindProcessInfo (line 49) | func (s *linuxSearcher) FindProcessInfo(ctx context.Context, network s...
    method resolveSocketByNetlink (line 66) | func (s *linuxSearcher) resolveSocketByNetlink(network string, source ...
  function NewSearcher (line 25) | func NewSearcher(config Config) (Searcher, error) {

FILE: common/process/searcher_linux_shared.go
  constant sizeOfSocketDiagRequestData (line 26) | sizeOfSocketDiagRequestData = 56
  constant sizeOfSocketDiagRequest (line 27) | sizeOfSocketDiagRequest     = syscall.SizeofNlMsghdr + sizeOfSocketDiagR...
  constant socketDiagResponseMinSize (line 28) | socketDiagResponseMinSize   = 72
  constant socketDiagByFamily (line 29) | socketDiagByFamily          = 20
  constant pathProc (line 30) | pathProc                    = "/proc"
  type socketDiagConn (line 33) | type socketDiagConn struct
    method Close (line 111) | func (c *socketDiagConn) Close() error {
    method query (line 117) | func (c *socketDiagConn) query(source netip.AddrPort, destination neti...
    method ensureOpenLocked (line 147) | func (c *socketDiagConn) ensureOpenLocked() error {
    method closeLocked (line 184) | func (c *socketDiagConn) closeLocked() error {
  type uidProcessPathCache (line 40) | type uidProcessPathCache struct
    method findProcessPath (line 93) | func (c *uidProcessPathCache) findProcessPath(targetInode, uid uint32)...
  type uidProcessPaths (line 44) | type uidProcessPaths struct
  function newSocketDiagConn (line 48) | func newSocketDiagConn(family, protocol uint8) *socketDiagConn {
  function socketDiagConnIndex (line 56) | func socketDiagConnIndex(family, protocol uint8) int {
  function socketDiagSettings (line 67) | func socketDiagSettings(network string, source netip.AddrPort) (family, ...
  function newUIDProcessPathCache (line 87) | func newUIDProcessPathCache(ttl time.Duration) *uidProcessPathCache {
  function querySocketDiagOnce (line 138) | func querySocketDiagOnce(family, protocol uint8, source netip.AddrPort) ...
  function openSocketDiag (line 159) | func openSocketDiag() (int, error) {
  function packSocketDiagRequest (line 193) | func packSocketDiagRequest(family, protocol byte, source netip.AddrPort,...
  function querySocketDiag (line 237) | func querySocketDiag(fd int, request []byte) (inode, uid uint32, err err...
  function unpackSocketDiagMessages (line 254) | func unpackSocketDiagMessages(messages []syscall.NetlinkMessage) (inode,...
  function unpackSocketDiagResponse (line 274) | func unpackSocketDiagResponse(msg *syscall.NetlinkMessage) (inode, uid u...
  function unpackSocketDiagError (line 283) | func unpackSocketDiagError(msg *syscall.NetlinkMessage) error {
  function shouldRetrySocketDiag (line 303) | func shouldRetrySocketDiag(err error) bool {
  function buildProcessPathByUIDCache (line 307) | func buildProcessPathByUIDCache(uid uint32) (map[uint32]string, error) {
  function isIgnorableProcError (line 358) | func isIgnorableProcError(err error) bool {
  function parseSocketInode (line 362) | func parseSocketInode(link []byte) (uint32, bool) {
  function isPid (line 380) | func isPid(s string) bool {

FILE: common/process/searcher_linux_shared_test.go
  function TestQuerySocketDiagUDPExact (line 16) | func TestQuerySocketDiagUDPExact(t *testing.T) {
  function addrPortFromUDPAddr (line 50) | func addrPortFromUDPAddr(t *testing.T, addr net.Addr) netip.AddrPort {

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 Close (line 31) | func (s *windowsSearcher) Close() error {
    method FindProcessInfo (line 35) | 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 47) | func getProcessPath(pid uint32) (string, error) {

FILE: common/proxybridge/bridge.go
  type Bridge (line 22) | type Bridge struct
    method Port (line 62) | func (b *Bridge) Port() uint16 {
    method Username (line 66) | func (b *Bridge) Username() string {
    method Password (line 70) | func (b *Bridge) Password() string {
    method Close (line 74) | func (b *Bridge) Close() error {
    method acceptLoop (line 78) | func (b *Bridge) acceptLoop() {
    method NewConnectionEx (line 99) | func (b *Bridge) NewConnectionEx(ctx context.Context, conn net.Conn, s...
    method NewPacketConnectionEx (line 108) | func (b *Bridge) NewPacketConnectionEx(ctx context.Context, conn N.Pac...
  function New (line 34) | func New(ctx context.Context, logger logger.ContextLogger, tag string, d...
  function randomHex (line 56) | func randomHex(size int) string {

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/schannel/schannel_windows.go
  constant clientCredentialFlags (line 17) | clientCredentialFlags = schCredManualCredValidation | schCredNoDefaultCr...
  function CheckPlatform (line 30) | func CheckPlatform() error {
  type clientCredentialKey (line 34) | type clientCredentialKey struct
  type clientCredential (line 39) | type clientCredential struct
    method acquire (line 66) | func (c *clientCredential) acquire() error {
  function cachedClientCredential (line 49) | func cachedClientCredential(minVersion, maxVersion uint16) (*clientCrede...
  type ClientContext (line 98) | type ClientContext struct
    method Close (line 147) | func (c *ClientContext) Close() {
    method Step (line 171) | func (c *ClientContext) Step(input []byte) (StepResult, error) {
    method StreamSizes (line 224) | func (c *ClientContext) StreamSizes() (header, trailer, maxMessage uin...
    method Encrypt (line 237) | func (c *ClientContext) Encrypt(header, trailer uint32, plaintext []by...
    method Decrypt (line 283) | func (c *ClientContext) Decrypt(input []byte) (DecryptResult, error) {
    method PostHandshake (line 321) | func (c *ClientContext) PostHandshake(input []byte) (StepResult, error) {
    method ApplicationProtocol (line 388) | func (c *ClientContext) ApplicationProtocol() (string, error) {
    method ConnectionInfo (line 407) | func (c *ClientContext) ConnectionInfo() (version, cipherSuite uint16,...
    method RemoteCertificateChain (line 440) | func (c *ClientContext) RemoteCertificateChain() ([][]byte, error) {
    method runInitializeSecurityContext (line 470) | func (c *ClientContext) runInitializeSecurityContext(inputDesc *secBuf...
  function NewClientContext (line 115) | func NewClientContext(minVersion, maxVersion uint16, serverName string, ...
  type StepResult (line 158) | type StepResult struct
  type DecryptResult (line 265) | type DecryptResult struct
  function parseDecryptResult (line 353) | func parseDecryptResult(input []byte, bufs []secBuffer, renegotiate bool...
  function cipherSuiteID (line 424) | func cipherSuiteID(name string) uint16 {
  constant handshakeContextReq (line 458) | handshakeContextReq = iscReqSequenceDetect |
  function consumedFromExtra (line 534) | func consumedFromExtra(extraBuf *secBuffer, inputLen int) (int, error) {
  function disabledProtocolsMask (line 542) | func disabledProtocolsMask(minVersion, maxVersion uint16) uint32 {
  function sspProtocolToTLSVersion (line 575) | func sspProtocolToTLSVersion(sp uint32) uint16 {
  function encodeAlpnBuffer (line 589) | func encodeAlpnBuffer(protocols []string) ([]byte, error) {
  function unsafeSliceCopy (line 615) | func unsafeSliceCopy(ptr *byte, size int) []byte {
  function certContextDER (line 624) | func certContextDER(ctx *windows.CertContext) []byte {
  function buildCertChainDER (line 633) | func buildCertChainDER(leaf *windows.CertContext) ([][]byte, error) {
  function extractCertChainDER (line 645) | func extractCertChainDER(chainCtx *windows.CertChainContext) ([][]byte, ...
  function isSelfSignedCertContext (line 674) | func isSelfSignedCertContext(ctx *windows.CertContext) bool {
  function certNameBlobBytes (line 684) | func certNameBlobBytes(blob windows.CertNameBlob) []byte {
  function sspiError (line 691) | func sspiError(where string, status syscall.Errno) error {
  function formatStatus (line 713) | func formatStatus(status syscall.Errno) string {

FILE: common/schannel/schannel_windows_test.go
  function TestExtractCertChainDERExcludesSelfSignedRoot (line 14) | func TestExtractCertChainDERExcludesSelfSignedRoot(t *testing.T) {
  function TestExtractCertChainDERKeepsLastIntermediateWithoutRoot (line 35) | func TestExtractCertChainDERKeepsLastIntermediateWithoutRoot(t *testing....
  function TestDisabledProtocolsMask (line 52) | func TestDisabledProtocolsMask(t *testing.T) {
  function TestClientCredentialCacheReusesVersionRange (line 86) | func TestClientCredentialCacheReusesVersionRange(t *testing.T) {
  function TestParseDecryptResultKeepsRenegotiateExtraToken (line 117) | func TestParseDecryptResultKeepsRenegotiateExtraToken(t *testing.T) {
  function TestParseDecryptResultKeepsRenegotiateWholeBufferWithoutExtra (line 136) | func TestParseDecryptResultKeepsRenegotiateWholeBufferWithoutExtra(t *te...
  function certChainContextForTest (line 155) | func certChainContextForTest(certs ...*windows.CertContext) *windows.Cer...
  function certContextForTest (line 171) | func certContextForTest(der, issuer, subject []byte) *windows.CertContext {
  function certNameBlobForTest (line 183) | func certNameBlobForTest(value []byte) windows.CertNameBlob {

FILE: common/schannel/syscall_windows.go
  function sspiCompleteAuthToken (line 24) | func sspiCompleteAuthToken(context *secHandle, token *secBufferDesc) (re...

FILE: common/schannel/types_windows.go
  constant unispNameW (line 10) | unispNameW = "Microsoft Unified Security Protocol Provider"
  constant schCredentialsVersion (line 12) | schCredentialsVersion = 5
  constant secPkgCredOutbound (line 14) | secPkgCredOutbound = 2
  constant iscReqSequenceDetect (line 16) | iscReqSequenceDetect       = 0x00000008
  constant iscReqReplayDetect (line 17) | iscReqReplayDetect         = 0x00000004
  constant iscReqConfidentiality (line 18) | iscReqConfidentiality      = 0x00000010
  constant iscReqAllocateMemory (line 19) | iscReqAllocateMemory       = 0x00000100
  constant iscReqStream (line 20) | iscReqStream               = 0x00008000
  constant iscReqUseSuppliedCreds (line 21) | iscReqUseSuppliedCreds     = 0x00000080
  constant iscReqManualCredValidation (line 22) | iscReqManualCredValidation = 0x00080000
  constant iscReqExtendedError (line 23) | iscReqExtendedError        = 0x00004000
  constant secbufferEmpty (line 25) | secbufferEmpty                = 0
  constant secbufferData (line 26) | secbufferData                 = 1
  constant secbufferToken (line 27) | secbufferToken                = 2
  constant secbufferExtra (line 28) | secbufferExtra                = 5
  constant secbufferStreamTrailer (line 29) | secbufferStreamTrailer        = 6
  constant secbufferStreamHeader (line 30) | secbufferStreamHeader         = 7
  constant secbufferApplicationProtocols (line 31) | secbufferApplicationProtocols = 18
  constant secbufferVersion (line 32) | secbufferVersion              = 0
  constant secApplicationProtocolNegotiationExtALPN (line 34) | secApplicationProtocolNegotiationExtALPN = 2
  constant secApplicationProtocolNegotiationStatusSuccess (line 36) | secApplicationProtocolNegotiationStatusSuccess = 1
  constant schCredManualCredValidation (line 38) | schCredManualCredValidation = 0x00000008
  constant schCredNoDefaultCreds (line 39) | schCredNoDefaultCreds       = 0x00000010
  constant schUseStrongCrypto (line 40) | schUseStrongCrypto          = 0x00400000
  constant spProtTLS10Client (line 42) | spProtTLS10Client = 0x00000080
  constant spProtTLS11Client (line 43) | spProtTLS11Client = 0x00000200
  constant spProtTLS12Client (line 44) | spProtTLS12Client = 0x00000800
  constant spProtTLS13Client (line 45) | spProtTLS13Client = 0x00002000
  constant spProtAllTLSClients (line 47) | spProtAllTLSClients = spProtTLS10Client | spProtTLS11Client | spProtTLS1...
  constant secpkgAttrStreamSizes (line 49) | secpkgAttrStreamSizes         = 4
  constant secpkgAttrConnectionInfo (line 50) | secpkgAttrConnectionInfo      = 0x5A
  constant secpkgAttrApplicationProtocol (line 51) | secpkgAttrApplicationProtocol = 0x23
  constant secpkgAttrCipherInfo (line 52) | secpkgAttrCipherInfo          = 0x64
  constant secpkgAttrRemoteCertContext (line 53) | secpkgAttrRemoteCertContext   = 0x53
  constant secEOK (line 57) | secEOK                        = syscall.Errno(windows.SEC_E_OK)
  constant secICompleteNeeded (line 58) | secICompleteNeeded            = syscall.Errno(windows.SEC_I_COMPLETE_NEE...
  constant secICompleteAndContinue (line 59) | secICompleteAndContinue       = syscall.Errno(windows.SEC_I_COMPLETE_AND...
  constant secIContinueNeeded (line 60) | secIContinueNeeded            = syscall.Errno(windows.SEC_I_CONTINUE_NEE...
  constant secIContextExpired (line 61) | secIContextExpired            = syscall.Errno(windows.SEC_I_CONTEXT_EXPI...
  constant secIRenegotiate (line 62) | secIRenegotiate               = syscall.Errno(windows.SEC_I_RENEGOTIATE)
  constant secEIncompleteMessage (line 63) | secEIncompleteMessage         = syscall.Errno(windows.SEC_E_INCOMPLETE_M...
  constant secEIncompleteCreds (line 64) | secEIncompleteCreds           = syscall.Errno(windows.SEC_E_INCOMPLETE_C...
  constant secEBufferTooSmall (line 65) | secEBufferTooSmall            = syscall.Errno(windows.SEC_E_BUFFER_TOO_S...
  constant secEMessageAltered (line 66) | secEMessageAltered            = syscall.Errno(windows.SEC_E_MESSAGE_ALTE...
  constant secEContextExpired (line 67) | secEContextExpired            = syscall.Errno(windows.SEC_E_CONTEXT_EXPI...
  constant secEUnsupportedFunc (line 68) | secEUnsupportedFunc           = syscall.Errno(windows.SEC_E_UNSUPPORTED_...
  constant secEInvalidToken (line 69) | secEInvalidToken              = syscall.Errno(windows.SEC_E_INVALID_TOKEN)
  constant secELogonDenied (line 70) | secELogonDenied               = syscall.Errno(windows.SEC_E_LOGON_DENIED)
  constant secEIllegalMessage (line 71) | secEIllegalMessage            = syscall.Errno(windows.SEC_E_ILLEGAL_MESS...
  constant secEWrongPrincipal (line 72) | secEWrongPrincipal            = syscall.Errno(windows.SEC_E_WRONG_PRINCI...
  constant secECertUnknown (line 73) | secECertUnknown               = syscall.Errno(windows.SEC_E_CERT_UNKNOWN)
  constant secECertExpired (line 74) | secECertExpired               = syscall.Errno(windows.SEC_E_CERT_EXPIRED)
  constant secEAlgorithmMismatch (line 75) | secEAlgorithmMismatch         = syscall.Errno(windows.SEC_E_ALGORITHM_MI...
  constant secEInternalError (line 76) | secEInternalError             = syscall.Errno(windows.SEC_E_INTERNAL_ERROR)
  constant secENoAuthenticatingAuthority (line 77) | secENoAuthenticatingAuthority = syscall.Errno(windows.SEC_E_NO_AUTHENTIC...
  type secHandle (line 80) | type secHandle struct
  type secBuffer (line 85) | type secBuffer struct
  type secBufferDesc (line 91) | type secBufferDesc struct
  type schCredentials (line 97) | type schCredentials struct
  type tlsParameters (line 111) | type tlsParameters struct
  type secPkgContextStreamSizes (line 120) | type secPkgContextStreamSizes struct
  type secPkgContextConnectionInfo (line 128) | type secPkgContextConnectionInfo struct
  type secPkgContextApplicationProtocol (line 138) | type secPkgContextApplicationProtocol struct
  type secPkgContextCipherInfo (line 145) | type secPkgContextCipherInfo struct

FILE: common/schannel/zsyscall_windows.go
  constant errnoERROR_IO_PENDING (line 17) | errnoERROR_IO_PENDING = 997
  function errnoErr (line 27) | func errnoErr(e syscall.Errno) error {
  function sspiAcquireCredentialsHandle (line 53) | func sspiAcquireCredentialsHandle(principal *uint16, pkgname *uint16, cr...
  function sspiDecryptMessage (line 59) | func sspiDecryptMessage(context *secHandle, message *secBufferDesc, sequ...
  function sspiDeleteSecurityContext (line 65) | func sspiDeleteSecurityContext(context *secHandle) (ret syscall.Errno) {
  function sspiEncryptMessage (line 71) | func sspiEncryptMessage(context *secHandle, qop uint32, message *secBuff...
  function sspiFreeContextBuffer (line 77) | func sspiFreeContextBuffer(buffer *byte) (ret syscall.Errno) {
  function sspiFreeCredentialsHandle (line 83) | func sspiFreeCredentialsHandle(credential *secHandle) (ret syscall.Errno) {
  function sspiInitializeSecurityContext (line 89) | func sspiInitializeSecurityContext(credential *secHandle, context *secHa...
  function sspiQueryContextAttributes (line 95) | func sspiQueryContextAttributes(context *secHandle, attribute uint32, bu...

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 21) | type wpaSupplicantMonitor struct
    method ReadWIFIState (line 55) | func (m *wpaSupplicantMonitor) ReadWIFIState() adapter.WIFIState {
    method sendCommand (line 100) | func (m *wpaSupplicantMonitor) sendCommand(conn *net.UnixConn, command...
    method Start (line 120) | func (m *wpaSupplicantMonitor) Start() error {
    method monitorEvents (line 134) | func (m *wpaSupplicantMonitor) monitorEvents(ctx context.Context, last...
    method Close (line 216) | func (m *wpaSupplicantMonitor) Close() error {
  function newWpaSupplicantMonitor (line 29) | func newWpaSupplicantMonitor(callback func(adapter.WIFIState)) (WIFIMoni...

FILE: common/settings/wifi_stub.go
  type stubWIFIMonitor (line 12) | type stubWIFIMonitor struct
    method ReadWIFIState (line 18) | func (m *stubWIFIMonitor) ReadWIFIState() adapter.WIFIState {
    method Start (line 22) | func (m *stubWIFIMonitor) Start() error {
    method Close (line 26) | func (m *stubWIFIMonitor) Close() error {
  function NewWIFIMonitor (line 14) | 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 Seal (line 60) | func (f *xorNonceAEAD) Seal(out, nonce, plaintext, additionalData []by...
    method Open (line 72) | func (f *xorNonceAEAD) Open(out, nonce, ciphertext, additionalData []b...
  function HKDFExpandLabel (line 84) | func HKDFExpandLabel(hash crypto.Hash, secret, context []byte, label str...
  function ReadUvarint (line 101) | 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 11) | x25519Kyber768Draft00 uint16 = 0x11EC
  constant extensionRenegotiationInfo (line 13) | extensionRenegotiationInfo uint16 = 0xFF01
  function isQUICGo (line 19) | 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 ruleItemPackageNameRegex (line 49) | ruleItemPackageNameRegex
  constant ruleItemFinal (line 50) | ruleItemFinal uint8 = 0xFF
  function Read (line 53) | func Read(reader io.Reader, recover bool) (ruleSetCompat option.PlainRul...
  function Write (line 92) | func Write(writer io.Writer, ruleSet option.PlainRuleSet, generateVersio...
  function readRule (line 123) | func readRule(reader varbin.Reader, recover bool) (rule option.HeadlessR...
  function writeRule (line 142) | func writeRule(writer varbin.Writer, rule option.HeadlessRule, generateV...
  function readDefaultRule (line 153) | func readDefaultRule(reader varbin.Reader, recover bool) (rule option.De...
  function writeDefaultRule (line 299) | func writeDefaultRule(writer varbin.Writer, rule option.DefaultHeadlessR...
  function readRuleItemString (line 520) | func readRuleItemString(reader varbin.Reader) ([]string, error) {
  function writeRuleItemString (line 541) | func writeRuleItemString(writer varbin.Writer, itemType uint8, value []s...
  function readRuleItemUint8 (line 563) | func readRuleItemUint8[E ~uint8](reader varbin.Reader) ([]E, error) {
  function writeRuleItemUint8 (line 576) | func writeRuleItemUint8[E ~uint8](writer varbin.Writer, itemType uint8, ...
  function readRuleItemUint16 (line 589) | func readRuleItemUint16(reader varbin.Reader) ([]uint16, error) {
  function writeRuleItemUint16 (line 602) | func writeRuleItemUint16(writer varbin.Writer, itemType uint8, value []u...
  function writeRuleItemCIDR (line 614) | func writeRuleItemCIDR(writer varbin.Writer, itemType uint8, value []str...
  function readLogicalRule (line 640) | func readLogicalRule(reader varbin.Reader, recovery bool) (logicalRule o...
  function writeLogicalRule (line 673) | 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/stun/stun.go
  constant DefaultServer (line 20) | DefaultServer = "stun.voipgate.com:3478"
  constant magicCookie (line 22) | magicCookie = 0x2112A442
  constant headerSize (line 23) | headerSize  = 20
  constant bindingRequest (line 25) | bindingRequest         = 0x0001
  constant bindingSuccessResponse (line 26) | bindingSuccessResponse = 0x0101
  constant bindingErrorResponse (line 27) | bindingErrorResponse   = 0x0111
  constant attrMappedAddress (line 29) | attrMappedAddress    = 0x0001
  constant attrChangeRequest (line 30) | attrChangeRequest    = 0x0003
  constant attrErrorCode (line 31) | attrErrorCode        = 0x0009
  constant attrXORMappedAddress (line 32) | attrXORMappedAddress = 0x0020
  constant attrOtherAddress (line 33) | attrOtherAddress     = 0x802c
  constant familyIPv4 (line 35) | familyIPv4 = 0x01
  constant familyIPv6 (line 36) | familyIPv6 = 0x02
  constant changeIP (line 38) | changeIP   = 0x04
  constant changePort (line 39) | changePort = 0x02
  constant defaultRTO (line 41) | defaultRTO    = 500 * time.Millisecond
  constant minRTO (line 42) | minRTO        = 250 * time.Millisecond
  constant maxRetransmit (line 43) | maxRetransmit = 2
  type Phase (line 46) | type Phase
  constant PhaseBinding (line 49) | PhaseBinding Phase = iota
  constant PhaseNATMapping (line 50) | PhaseNATMapping
  constant PhaseNATFiltering (line 51) | PhaseNATFiltering
  constant PhaseDone (line 52) | PhaseDone
  type NATMapping (line 55) | type NATMapping
    method String (line 65) | func (m NATMapping) String() string {
  constant NATMappingUnknown (line 58) | NATMappingUnknown NATMapping = iota
  constant _ (line 59) | _
  constant NATMappingEndpointIndependent (line 60) | NATMappingEndpointIndependent
  constant NATMappingAddressDependent (line 61) | NATMappingAddressDependent
  constant NATMappingAddressAndPortDependent (line 62) | NATMappingAddressAndPortDependent
  type NATFiltering (line 78) | type NATFiltering
    method String (line 87) | func (f NATFiltering) String() string {
  constant NATFilteringUnknown (line 81) | NATFilteringUnknown NATFiltering = iota
  constant NATFilteringEndpointIndependent (line 82) | NATFilteringEndpointIndependent
  constant NATFilteringAddressDependent (line 83) | NATFilteringAddressDependent
  constant NATFilteringAddressAndPortDependent (line 84) | NATFilteringAddressAndPortDependent
  type TransactionID (line 100) | type TransactionID
  type Options (line 102) | type Options struct
  type Progress (line 109) | type Progress struct
  type Result (line 117) | type Result struct
  type parsedResponse (line 125) | type parsedResponse struct
    method externalAddr (line 131) | func (r *parsedResponse) externalAddr() (netip.AddrPort, bool) {
  type stunAttribute (line 141) | type stunAttribute struct
  function newTransactionID (line 146) | func newTransactionID() TransactionID {
  function buildBindingRequest (line 152) | func buildBindingRequest(txID TransactionID, attrs ...stunAttribute) []b...
  function changeRequestAttr (line 175) | func changeRequestAttr(flags byte) stunAttribute {
  function parseResponse (line 182) | func parseResponse(data []byte, expectedTxID TransactionID) (*parsedResp...
  function parseErrorResponse (line 251) | func parseErrorResponse(data []byte) error {
  function parseXORMappedAddress (line 274) | func parseXORMappedAddress(data []byte, txID TransactionID) (netip.AddrP...
  function parseMappedAddress (line 308) | func parseMappedAddress(data []byte) (netip.AddrPort, error) {
  function roundTrip (line 336) | func roundTrip(conn net.PacketConn, addr net.Addr, txID TransactionID, a...
  function Run (line 390) | func Run(options Options) (*Result, error) {
  function detectNATMapping (line 538) | func detectNATMapping(
  function detectNATFiltering (line 583) | func detectNATFiltering(
  function paddingLen (line 607) | func paddingLen(n int) int {

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 26) | type acmeWrapper struct
    method Start (line 33) | func (w *acmeWrapper) Start() error {
    method Close (line 37) | func (w *acmeWrapper) Close() error {
  function startACME (line 42) | func startACME(ctx context.Context, logger logger.Logger, options option...

FILE: common/tls/acme_logger.go
  type ACMELogWriter (line 12) | type ACMELogWriter struct
    method Write (line 16) | func (w *ACMELogWriter) Write(p []byte) (n int, err error) {
    method Sync (line 33) | func (w *ACMELogWriter) Sync() error {
  function ACMEEncoderConfig (line 37) | func ACMEEncoderConfig() zapcore.EncoderConfig {

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

FILE: common/tls/apple_client.go
  constant appleTLSEngineName (line 14) | appleTLSEngineName = "Apple TLS engine"
  type appleClientConfig (line 16) | type appleClientConfig struct
    method Clone (line 21) | func (c *appleClientConfig) Clone() Config {
    method resolveAnchors (line 28) | func (c *appleClientConfig) resolveAnchors() (adapter.AppleAnchors, er...
  function newAppleClient (line 35) | func newAppleClient(ctx context.Context, logger logger.ContextLogger, se...

FILE: common/tls/apple_client_platform.go
  method ClientHandshake (line 36) | func (c *appleClientConfig) ClientHandshake(ctx context.Context, conn ne...
  constant appleTLSHandshakePollInterval (line 151) | appleTLSHandshakePollInterval = 100 * time.Millisecond
  constant appleTLSWriteChunkSize (line 152) | appleTLSWriteChunkSize        = 32 * 1024
  function waitAppleTLSClientReady (line 155) | func waitAppleTLSClientReady(ctx context.Context, client *C.box_apple_tl...
  type appleTLSConn (line 199) | type appleTLSConn struct
    method Read (line 224) | func (c *appleTLSConn) Read(p []byte) (int, error) {
    method ReadBuffer (line 237) | func (c *appleTLSConn) ReadBuffer(buffer *buf.Buffer) error {
    method readIntoLocked (line 249) | func (c *appleTLSConn) readIntoLocked(p []byte) (int, error) {
    method Write (line 295) | func (c *appleTLSConn) Write(p []byte) (int, error) {
    method WriteBuffer (line 340) | func (c *appleTLSConn) WriteBuffer(buffer *buf.Buffer) error {
    method CreateReadWaiter (line 346) | func (c *appleTLSConn) CreateReadWaiter() (N.ReadWaiter, bool) {
    method Close (line 353) | func (c *appleTLSConn) Close() error {
    method LocalAddr (line 368) | func (c *appleTLSConn) LocalAddr() net.Addr {
    method RemoteAddr (line 372) | func (c *appleTLSConn) RemoteAddr() net.Addr {
    method SetDeadline (line 385) | func (c *appleTLSConn) SetDeadline(t time.Time) error {
    method SetReadDeadline (line 395) | func (c *appleTLSConn) SetReadDeadline(t time.Time) error {
    method SetWriteDeadline (line 403) | func (c *appleTLSConn) SetWriteDeadline(t time.Time) error {
    method prepareReadTimeout (line 411) | func (c *appleTLSConn) prepareReadTimeout() (int, error) {
    method prepareWriteDeadline (line 425) | func (c *appleTLSConn) prepareWriteDeadline() (time.Time, error) {
    method markReadTimedOut (line 439) | func (c *appleTLSConn) markReadTimedOut() {
    method markWriteTimedOut (line 445) | func (c *appleTLSConn) markWriteTimedOut() {
    method isClosed (line 462) | func (c *appleTLSConn) isClosed() bool {
    method acquireClient (line 471) | func (c *appleTLSConn) acquireClient() (*C.box_apple_tls_client_t, err...
    method releaseClient (line 485) | func (c *appleTLSConn) releaseClient() {
    method errorFromPointer (line 489) | func (c *appleTLSConn) errorFromPointer(errorPtr *C.char) error {
    method readWaitResultToBuffer (line 565) | func (c *appleTLSConn) readWaitResultToBuffer(result *C.box_apple_tls_...
    method NetConn (line 621) | func (c *appleTLSConn) NetConn() net.Conn {
    method HandshakeContext (line 625) | func (c *appleTLSConn) HandshakeContext(ctx context.Context) error {
    method ConnectionState (line 629) | func (c *appleTLSConn) ConnectionState() ConnectionState {
  function deadlineTimeoutMs (line 451) | func deadlineTimeoutMs(deadline time.Time) (int, bool) {
  type appleTLSReadWaiter (line 500) | type appleTLSReadWaiter struct
    method InitializeReadWaiter (line 508) | func (w *appleTLSReadWaiter) InitializeReadWaiter(options N.ReadWaitOp...
    method WaitReadBuffer (line 516) | func (w *appleTLSReadWaiter) WaitReadBuffer() (*buf.Buffer, error) {
  function readWaitFreeLen (line 596) | func readWaitFreeLen(options N.ReadWaitOptions) int {
  function box_apple_tls_read_callback (line 607) | func box_apple_tls_read_callback(callbackHandle C.uintptr_t, result *C.b...
  function parseAppleTLSState (line 635) | func parseAppleTLSState(state *C.box_apple_tls_state_t) (tls.ConnectionS...
  function parseAppleCertChain (line 658) | func parseAppleCertChain(chain *C.uint8_t, chainLen C.size_t) ([][]byte,...
  function timeoutFromDuration (line 688) | func timeoutFromDuration(timeout time.Duration) int {
  function cStringOrNil (line 702) | func cStringOrNil(value string) *C.char {
  function cFree (line 709) | func cFree(pointer *C.char) {

FILE: common/tls/apple_client_platform_benchmark_test.go
  constant appleTLSBenchmarkReadPayloadSize (line 21) | appleTLSBenchmarkReadPayloadSize  = 16 * 1024
  constant appleTLSBenchmarkWritePayloadSize (line 22) | appleTLSBenchmarkWritePayloadSize = 48 * 1024
  function BenchmarkAppleClientReadBuffer (line 25) | func BenchmarkAppleClientReadBuffer(b *testing.B) {
  function BenchmarkAppleClientReadWaiter (line 63) | func BenchmarkAppleClientReadWaiter(b *testing.B) {
  function BenchmarkAppleClientWriteBuffer (line 108) | func BenchmarkAppleClientWriteBuffer(b *testing.B) {
  function BenchmarkStdlibClientReadBuffer (line 143) | func BenchmarkStdlibClientReadBuffer(b *testing.B) {
  function BenchmarkStdlibClientWriteBuffer (line 182) | func BenchmarkStdlibClientWriteBuffer(b *testing.B) {
  function newAppleBenchmarkClientConn (line 216) | func newAppleBenchmarkClientConn(b *testing.B, handler func(*stdtls.Conn...
  function newStdlibBenchmarkClientConn (line 240) | func newStdlibBenchmarkClientConn(b *testing.B, handler func(*stdtls.Con...
  function writeBenchmarkPayload (line 269) | func writeBenchmarkPayload(writer io.Writer, payload []byte) error {

FILE: common/tls/apple_client_platform_darwin.h
  type box_apple_tls_client_t (line 6) | typedef struct box_apple_tls_client box_apple_tls_client_t;
  type box_apple_tls_read_result_t (line 7) | typedef struct box_apple_tls_read_result box_apple_tls_read_result_t;
  type box_apple_tls_state_t (line 9) | typedef struct box_apple_tls_state {

FILE: common/tls/apple_client_platform_dispatch_test.go
  function TestAppleTLSDispatchDataCopySegments (line 11) | func TestAppleTLSDispatchDataCopySegments(t *testing.T) {
  function TestAppleTLSDispatchDataCopyRejectsSmallBuffer (line 28) | func TestAppleTLSDispatchDataCopyRejectsSmallBuffer(t *testing.T) {
  function TestAppleTLSDispatchDataCopyEmpty (line 42) | func TestAppleTLSDispatchDataCopyEmpty(t *testing.T) {

FILE: common/tls/apple_client_platform_dispatch_testhelper_darwin.go
  function appleTLSCopyDispatchDataForTest (line 13) | func appleTLSCopyDispatchDataForTest(first, second []byte, buffer []byte...

FILE: common/tls/apple_client_platform_test.go
  constant appleTLSTestTimeout (line 23) | appleTLSTestTimeout = 5 * time.Second
  constant appleTLSSuccessHandshakeLoops (line 26) | appleTLSSuccessHandshakeLoops = 20
  constant appleTLSFailureRecoveryLoops (line 27) | appleTLSFailureRecoveryLoops  = 10
  type appleTLSServerResult (line 30) | type appleTLSServerResult struct
  function TestAppleClientHandshakeAppliesALPNAndVersion (line 40) | func TestAppleClientHandshakeAppliesALPNAndVersion(t *testing.T) {
  function TestAppleClientHandshakeRejectsOpaqueConn (line 87) | func TestAppleClientHandshakeRejectsOpaqueConn(t *testing.T) {
  function TestAppleClientHandshakeRejectsVersionMismatch (line 110) | func TestAppleClientHandshakeRejectsVersionMismatch(t *testing.T) {
  function TestAppleClientHandshakeRejectsServerNameMismatch (line 135) | func TestAppleClientHandshakeRejectsServerNameMismatch(t *testing.T) {
  function TestAppleClientHandshakeRecoversAfterFailure (line 157) | func TestAppleClientHandshakeRecoversAfterFailure(t *testing.T) {
  function TestAppleClientConfigCloneWithInlineCertificate (line 244) | func TestAppleClientConfigCloneWithInlineCertificate(t *testing.T) {
  function TestAppleClientReadBuffer (line 303) | func TestAppleClientReadBuffer(t *testing.T) {
  function TestAppleClientWriteBuffer (line 360) | func TestAppleClientWriteBuffer(t *testing.T) {
  function TestAppleClientCreateReadWaiter (line 410) | func TestAppleClientCreateReadWaiter(t *testing.T) {
  function TestAppleClientReadDeadline (line 475) | func TestAppleClientReadDeadline(t *testing.T) {
  function TestAppleClientSetDeadlineClearsPreExpiredSticky (line 524) | func TestAppleClientSetDeadlineClearsPreExpiredSticky(t *testing.T) {
  function startAppleTLSSilentServer (line 581) | func startAppleTLSSilentServer(t *testing.T, tlsConfig *stdtls.Config) (...
  function startAppleTLSIOTestServer (line 625) | func startAppleTLSIOTestServer(t testing.TB, tlsConfig *stdtls.Config, h...
  function newAppleTestCertificate (line 670) | func newAppleTestCertificate(t testing.TB, serverName string) (stdtls.Ce...
  function startAppleTLSTestServer (line 684) | func startAppleTLSTestServer(t *testing.T, tlsConfig *stdtls.Config) (<-...
  function newAppleTestClientConn (line 734) | func newAppleTestClientConn(t testing.TB, serverAddress string, options ...
  function dialAppleTestClientConn (line 749) | func dialAppleTestClientConn(t testing.TB, serverAddress string, clientC...

FILE: common/tls/apple_client_stub.go
  function newAppleClient (line 13) | func newAppleClient(ctx context.Context, logger logger.ContextLogger, se...

FILE: common/tls/client.go
  function parseTLSSpoofOptions (line 24) | func parseTLSSpoofOptions(serverName string, options option.OutboundTLSO...
  function applyTLSSpoof (line 41) | func applyTLSSpoof(conn net.Conn, spoof string, method tlsspoof.Method) ...
  function NewDialerFromOptions (line 48) | func NewDialerFromOptions(ctx context.Context, logger logger.ContextLogg...
  function NewClient (line 64) | func NewClient(ctx context.Context, logger logger.ContextLogger, serverA...
  type ClientOptions (line 73) | type ClientOptions struct
  function NewClientWithOptions (line 82) | func NewClientWithOptions(options ClientOptions) (Config, error) {
  function ClientHandshake (line 111) | func ClientHandshake(ctx context.Context, conn net.Conn, config Config) ...
  type Dialer (line 125) | type Dialer interface
  type defaultDialer (line 130) | type defaultDialer struct
    method DialContext (line 139) | func (d *defaultDialer) DialContext(ctx context.Context, network strin...
    method ListenPacket (line 146) | func (d *defaultDialer) ListenPacket(ctx context.Context, destination ...
    method DialTLSContext (line 150) | func (d *defaultDialer) DialTLSContext(ctx context.Context, destinatio...
    method dialContext (line 154) | func (d *defaultDialer) dialContext(ctx context.Context, destination M...
    method Upstream (line 174) | func (d *defaultDialer) Upstream() any {
  function NewDialer (line 135) | 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 102) | func (e *RealityClientConfig) ServerName() string {
    method SetServerName (line 106) | func (e *RealityClientConfig) SetServerName(serverName string) {
    method NextProtos (line 110) | func (e *RealityClientConfig) NextProtos() []string {
    method SetNextProtos (line 114) | func (e *RealityClientConfig) SetNextProtos(nextProto []string) {
    method HandshakeTimeout (line 118) | func (e *RealityClientConfig) HandshakeTimeout() time.Duration {
    method SetHandshakeTimeout (line 122) | func (e *RealityClientConfig) SetHandshakeTimeout(timeout time.Duratio...
    method STDConfig (line 126) | func (e *RealityClientConfig) STDConfig() (*STDConfig, error) {
    method Client (line 130) | func (e *RealityClientConfig) Client(conn net.Conn) (Conn, error) {
    method ClientHandshake (line 134) | func (e *RealityClientConfig) ClientHandshake(ctx context.Context, con...
    method Clone (line 268) | func (e *RealityClientConfig) Clone() Config {
  function NewRealityClient (line 54) | func NewRealityClient(ctx context.Context, logger logger.ContextLogger, ...
  function newRealityClient (line 58) | func newRealityClient(ctx context.Context, logger logger.ContextLogger, ...
  function realityClientFallback (line 244) | func realityClientFallback(ctx context.Context, uConn net.Conn, serverNa...
  type realityVerifier (line 277) | type realityVerifier struct
    method VerifyPeerCertificate (line 284) | func (c *realityVerifier) VerifyPeerCertificate(rawCerts [][]byte, ver...
  type realityClientConnWrapper (line 308) | type realityClientConnWrapper struct
    method ConnectionState (line 312) | func (c *realityClientConnWrapper) ConnectionState() tls.ConnectionSta...
    method Upstream (line 331) | func (c *realityClientConnWrapper) Upstream() any {
    method CloseWrite (line 337) | func (c *realityClientConnWrapper) CloseWrite() error {
    method ReaderReplaceable (line 341) | func (c *realityClientConnWrapper) ReaderReplaceable() bool {
    method WriterReplaceable (line 345) | func (c *realityClientConnWrapper) WriterReplaceable() bool {

FILE: common/tls/reality_server.go
  type RealityServerConfig (line 28) | type RealityServerConfig struct
    method ServerName (line 158) | func (c *RealityServerConfig) ServerName() string {
    method SetServerName (line 162) | func (c *RealityServerConfig) SetServerName(serverName string) {
    method NextProtos (line 166) | func (c *RealityServerConfig) NextProtos() []string {
    method SetNextProtos (line 170) | func (c *RealityServerConfig) SetNextProtos(nextProto []string) {
    method HandshakeTimeout (line 174) | func (c *RealityServerConfig) HandshakeTimeout() time.Duration {
    method SetHandshakeTimeout (line 178) | func (c *RealityServerConfig) SetHandshakeTimeout(timeout time.Duratio...
    method STDConfig (line 182) | func (c *RealityServerConfig) STDConfig() (*tls.Config, error) {
    method Client (line 186) | func (c *RealityServerConfig) Client(conn net.Conn) (Conn, error) {
    method Start (line 190) | func (c *RealityServerConfig) Start() error {
    method Close (line 194) | func (c *RealityServerConfig) Close() error {
    method Server (line 198) | func (c *RealityServerConfig) Server(conn net.Conn) (Conn, error) {
    method ServerHandshake (line 202) | func (c *RealityServerConfig) ServerHandshake(ctx context.Context, con...
    method Clone (line 210) | func (c *RealityServerConfig) Clone() Config {
  function NewRealityServer (line 33) | func NewRealityServer(ctx context.Context, logger log.ContextLogger, opt...
  type realityConnWrapper (line 219) | type realityConnWrapper struct
    method ConnectionState (line 223) | func (c *realityConnWrapper) ConnectionState() ConnectionState {
    method Upstream (line 242) | func (c *realityConnWrapper) Upstream() any {
    method CloseWrite (line 248) | func (c *realityConnWrapper) CloseWrite() error {
    method ReaderReplaceable (line 252) | func (c *realityConnWrapper) ReaderReplaceable() bool {
    method WriterReplaceable (line 256) | 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 25) | type STDClientConfig struct
    method ServerName (line 39) | func (c *STDClientConfig) ServerName() string {
    method SetServerName (line 43) | func (c *STDClientConfig) SetServerName(serverName string) {
    method NextProtos (line 57) | func (c *STDClientConfig) NextProtos() []string {
    method SetNextProtos (line 61) | func (c *STDClientConfig) SetNextProtos(nextProto []string) {
    method HandshakeTimeout (line 65) | func (c *STDClientConfig) HandshakeTimeout() time.Duration {
    method SetHandshakeTimeout (line 69) | func (c *STDClientConfig) SetHandshakeTimeout(timeout time.Duration) {
    method STDConfig (line 73) | func (c *STDClientConfig) STDConfig() (*STDConfig, error) {
    method Client (line 77) | func (c *STDClientConfig) Client(conn net.Conn) (Conn, error) {
    method Clone (line 88) | func (c *STDClientConfig) Clone() Config {
    method ECHConfigList (line 106) | func (c *STDClientConfig) ECHConfigList() []byte {
    method SetECHConfigList (line 110) | func (c *STDClientConfig) SetECHConfigList(EncryptedClientHelloConfigL...
  function NewSTDClient (line 114) | func NewSTDClient(ctx context.Context, logger logger.ContextLogger, serv...
  function newSTDClient (line 118) | func newSTDClient(ctx context.Context, logger logger.ContextLogger, serv...
  function verifyConnection (line 269) | func verifyConnection(rootCAs *x509.CertPool, timeFunc func() time.Time,...
  function VerifyPublicKeySHA256 (line 278) | func VerifyPublicKeySHA256(knownHashValues [][]byte, rawCerts [][]byte) ...

FILE: common/tls/std_server.go
  type managedCertificateProvider (line 27) | type managedCertificateProvider interface
  type sharedCertificateProvider (line 32) | type sharedCertificateProvider struct
    method Start (line 38) | func (p *sharedCertificateProvider) Start() error {
    method Close (line 47) | func (p *sharedCertificateProvider) Close() error {
    method GetCertificate (line 51) | func (p *sharedCertificateProvider) GetCertificate(hello *tls.ClientHe...
    method GetACMENextProtos (line 55) | func (p *sharedCertificateProvider) GetACMENextProtos() []string {
  type inlineCertificateProvider (line 59) | type inlineCertificateProvider struct
    method Start (line 63) | func (p *inlineCertificateProvider) Start() error {
    method Close (line 73) | func (p *inlineCertificateProvider) Close() error {
    method GetCertificate (line 77) | func (p *inlineCertificateProvider) GetCertificate(hello *tls.ClientHe...
    method GetACMENextProtos (line 81) | func (p *inlineCertificateProvider) GetACMENextProtos() []string {
  function getACMENextProtos (line 85) | func getACMENextProtos(provider adapter.CertificateProvider) []string {
  type STDServerConfig (line 92) | type STDServerConfig struct
    method ServerName (line 108) | func (c *STDServerConfig) ServerName() string {
    method SetServerName (line 114) | func (c *STDServerConfig) SetServerName(serverName string) {
    method NextProtos (line 122) | func (c *STDServerConfig) NextProtos() []string {
    method SetNextProtos (line 131) | func (c *STDServerConfig) SetNextProtos(nextProto []string) {
    method HandshakeTimeout (line 143) | func (c *STDServerConfig) HandshakeTimeout() time.Duration {
    method SetHandshakeTimeout (line 149) | func (c *STDServerConfig) SetHandshakeTimeout(timeout time.Duration) {
    method hasACMEALPN (line 155) | func (c *STDServerConfig) hasACMEALPN() bool {
    method STDConfig (line 167) | func (c *STDServerConfig) STDConfig() (*STDConfig, error) {
    method Client (line 171) | func (c *STDServerConfig) Client(conn net.Conn) (Conn, error) {
    method Server (line 175) | func (c *STDServerConfig) Server(conn net.Conn) (Conn, error) {
    method Clone (line 179) | func (c *STDServerConfig) Clone() Config {
    method Start (line 186) | func (c *STDServerConfig) Start() error {
    method startWatcher (line 222) | func (c *STDServerConfig) startWatcher() error {
    method certificateUpdated (line 259) | func (c *STDServerConfig) certificateUpdated(path string) error {
    method Close (line 323) | func (c *STDServerConfig) Close() error {
  function NewSTDServer (line 327) | func NewSTDServer(ctx context.Context, logger log.ContextLogger, options...
  function newCertificateProvider (line 529) | func newCertificateProvider(ctx context.Context, logger log.ContextLogge...

FILE: common/tls/system_client.go
  type SystemTLSValidated (line 16) | type SystemTLSValidated struct
  function ValidateSystemTLSOptions (line 24) | func ValidateSystemTLSOptions(ctx context.Context, options option.Outbou...
  function resolveSystemAnchors (line 87) | func resolveSystemAnchors(ctx context.Context, options option.OutboundTL...
  function verifySystemTLSPeer (line 105) | func verifySystemTLSPeer(roots *x509.CertPool, serverName string, timeFu...

FILE: common/tls/system_client_engine.go
  type systemTLSConfig (line 18) | type systemTLSConfig struct
    method ServerName (line 31) | func (c *systemTLSConfig) ServerName() string {
    method SetServerName (line 35) | func (c *systemTLSConfig) SetServerName(serverName string) {
    method NextProtos (line 39) | func (c *systemTLSConfig) NextProtos() []string {
    method SetNextProtos (line 43) | func (c *systemTLSConfig) SetNextProtos(nextProto []string) {
    method HandshakeTimeout (line 47) | func (c *systemTLSConfig) HandshakeTimeout() time.Duration {
    method SetHandshakeTimeout (line 51) | func (c *systemTLSConfig) SetHandshakeTimeout(timeout time.Duration) {
    method STDConfig (line 55) | func (c *systemTLSConfig) STDConfig() (*STDConfig, error) {
    method Client (line 59) | func (c *systemTLSConfig) Client(conn net.Conn) (Conn, error) {
    method clone (line 63) | func (c *systemTLSConfig) clone() systemTLSConfig {
  function newSystemTLSConfig (line 78) | func newSystemTLSConfig(ctx context.Context, serverAddress string, optio...

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 29) | type UTLSClientConfig struct
    method ServerName (line 44) | func (c *UTLSClientConfig) ServerName() string {
    method SetServerName (line 48) | func (c *UTLSClientConfig) SetServerName(serverName string) {
    method NextProtos (line 62) | func (c *UTLSClientConfig) NextProtos() []string {
    method SetNextProtos (line 66) | func (c *UTLSClientConfig) SetNextProtos(nextProto []string) {
    method HandshakeTimeout (line 73) | func (c *UTLSClientConfig) HandshakeTimeout() time.Duration {
    method SetHandshakeTimeout (line 77) | func (c *UTLSClientConfig) SetHandshakeTimeout(timeout time.Duration) {
    method STDConfig (line 81) | func (c *UTLSClientConfig) STDConfig() (*STDConfig, error) {
    method Client (line 85) | func (c *UTLSClientConfig) Client(conn net.Conn) (Conn, error) {
    method SetSessionIDGenerator (line 96) | func (c *UTLSClientConfig) SetSessionIDGenerator(generator func(client...
    method Clone (line 100) | func (c *UTLSClientConfig) Clone() Config {
    method ECHConfigList (line 119) | func (c *UTLSClientConfig) ECHConfigList() []byte {
    method SetECHConfigList (line 123) | func (c *UTLSClientConfig) SetECHConfigList(EncryptedClientHelloConfig...
  type utlsConnWrapper (line 127) | type utlsConnWrapper struct
    method ConnectionState (line 131) | func (c *utlsConnWrapper) ConnectionState() tls.ConnectionState {
    method Upstream (line 150) | func (c *utlsConnWrapper) Upstream() any {
    method ReaderReplaceable (line 154) | func (c *utlsConnWrapper) ReaderReplaceable() bool {
    method WriterReplaceable (line 158) | func (c *utlsConnWrapper) WriterReplaceable() bool {
  type utlsALPNWrapper (line 162) | type utlsALPNWrapper struct
    method HandshakeContext (line 167) | func (c *utlsALPNWrapper) HandshakeContext(ctx context.Context) error {
  function NewUTLSClient (line 187) | func NewUTLSClient(ctx context.Context, logger logger.ContextLogger, ser...
  function newUTLSClient (line 191) | func newUTLSClient(ctx context.Context, logger logger.ContextLogger, ser...
  function init (line 353) | func init() {
  function uTLSClientHelloID (line 371) | func uTLSClientHelloID(name string) (utls.ClientHelloID, error) {

FILE: common/tls/utls_client_test.go
  function newUTLSClientConfigForGateTest (line 21) | func newUTLSClientConfigForGateTest(fragment, recordFragment bool) *UTLS...
  function TestUTLSClient_Client_NoFragment_DoesNotWrap (line 31) | func TestUTLSClient_Client_NoFragment_DoesNotWrap(t *testing.T) {
  function TestUTLSClient_Client_FragmentOnly_Wraps (line 42) | func TestUTLSClient_Client_FragmentOnly_Wraps(t *testing.T) {
  function TestUTLSClient_Client_RecordFragmentOnly_Wraps (line 53) | func TestUTLSClient_Client_RecordFragmentOnly_Wraps(t *testing.T) {
  function TestUTLSClient_Client_BothFragment_Wraps (line 64) | func TestUTLSClient_Client_BothFragment_Wraps(t *testing.T) {

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

FILE: common/tls/windows_client.go
  constant windowsTLSEngineName (line 27) | windowsTLSEngineName        = "Windows TLS engine"
  constant handshakeReadChunkSize (line 28) | handshakeReadChunkSize      = 8192
  constant readScratchSize (line 29) | readScratchSize             = 16 * 1024
  constant readWaitCiphertextChunkSize (line 30) | readWaitCiphertextChunkSize = 4096
  type windowsClientConfig (line 33) | type windowsClientConfig struct
    method Clone (line 38) | func (c *windowsClientConfig) Clone() Config {
    method ClientHandshake (line 67) | func (c *windowsClientConfig) ClientHandshake(ctx context.Context, con...
    method verifyPeerCertificates (line 280) | func (c *windowsClientConfig) verifyPeerCertificates(peerCertificates ...
  function newWindowsClient (line 45) | func newWindowsClient(ctx context.Context, logger logger.ContextLogger, ...
  function driveHandshake (line 129) | func driveHandshake(ctx context.Context, conn net.Conn, client *schannel...
  function driveSteps (line 151) | func driveSteps(
  function installHandshakeCancel (line 200) | func installHandshakeCancel(ctx context.Context, conn net.Conn) func() {
  function handshakeIOError (line 219) | func handshakeIOError(ctx context.Context, err error, message string) er...
  function readTLSRaw (line 227) | func readTLSRaw(conn net.Conn, scratch []byte, requireMore bool) ([]byte...
  function isTimeoutError (line 241) | func isTimeoutError(err error) bool {
  function buildConnectionState (line 249) | func buildConnectionState(serverName string, client *schannel.ClientCont...
  type windowsTLSConn (line 294) | type windowsTLSConn struct
    method Read (line 334) | func (c *windowsTLSConn) Read(p []byte) (int, error) {
    method ReadBuffer (line 346) | func (c *windowsTLSConn) ReadBuffer(buffer *buf.Buffer) error {
    method readIntoLocked (line 361) | func (c *windowsTLSConn) readIntoLocked(p []byte, appendCipher windows...
    method readPlaintextLocked (line 373) | func (c *windowsTLSConn) readPlaintextLocked(appendCipher windowsTLSAp...
    method drivePostHandshake (line 431) | func (c *windowsTLSConn) drivePostHandshake(readRaw windowsTLSReadRawF...
    method writePostHandshakeReplyLocked (line 474) | func (c *windowsTLSConn) writePostHandshakeReplyLocked(data []byte) er...
    method decrypt (line 487) | func (c *windowsTLSConn) decrypt(input []byte) (schannel.DecryptResult...
    method encrypt (line 496) | func (c *windowsTLSConn) encrypt(plaintext []byte) ([]byte, error) {
    method readRaw (line 508) | func (c *windowsTLSConn) readRaw(requireMore bool) ([]byte, error) {
    method appendRaw (line 515) | func (c *windowsTLSConn) appendRaw(requireMore bool) error {
    method Write (line 524) | func (c *windowsTLSConn) Write(p []byte) (int, error) {
    method WriteBuffer (line 568) | func (c *windowsTLSConn) WriteBuffer(buffer *buf.Buffer) error {
    method CreateReadWaiter (line 574) | func (c *windowsTLSConn) CreateReadWaiter() (N.ReadWaiter, bool) {
    method Close (line 585) | func (c *windowsTLSConn) Close() error {
    method LocalAddr (line 603) | func (c *windowsTLSConn) LocalAddr() net.Addr {
    method RemoteAddr (line 607) | func (c *windowsTLSConn) RemoteAddr() net.Addr {
    method SetDeadline (line 611) | func (c *windowsTLSConn) SetDeadline(t time.Time) error {
    method SetReadDeadline (line 623) | func (c *windowsTLSConn) SetReadDeadline(t time.Time) error {
    method SetWriteDeadline (line 634) | func (c *windowsTLSConn) SetWriteDeadline(t time.Time) error {
    method NetConn (line 645) | func (c *windowsTLSConn) NetConn() net.Conn {
    method HandshakeContext (line 649) | func (c *windowsTLSConn) HandshakeContext(ctx context.Context) error {
    method ConnectionState (line 653) | func (c *windowsTLSConn) ConnectionState() ConnectionState {
    method applyReadDeadline (line 657) | func (c *windowsTLSConn) applyReadDeadline() (func(), error) {
    method applyWriteDeadline (line 664) | func (c *windowsTLSConn) applyWriteDeadline() (func(), error) {
    method applyDeadline (line 671) | func (c *windowsTLSConn) applyDeadline(deadline time.Time, set func(ti...
    method beginWrite (line 685) | func (c *windowsTLSConn) beginWrite() error {
    method finishWrite (line 710) | func (c *windowsTLSConn) finishWrite() {
    method beginPostHandshakeWrite (line 719) | func (c *windowsTLSConn) beginPostHandshakeWrite() error {
    method finishPostHandshakeWrite (line 748) | func (c *windowsTLSConn) finishPostHandshakeWrite() {
    method writeCondition (line 758) | func (c *windowsTLSConn) writeCondition() *sync.Cond {
    method isClosed (line 765) | func (c *windowsTLSConn) isClosed() bool {
  type windowsTLSAppendCipherFunc (line 330) | type windowsTLSAppendCipherFunc
  type windowsTLSReadRawFunc (line 331) | type windowsTLSReadRawFunc
  type windowsTLSReadWaiter (line 769) | type windowsTLSReadWaiter struct
    method InitializeReadWaiter (line 777) | func (w *windowsTLSReadWaiter) InitializeReadWaiter(options N.ReadWait...
    method WaitReadBuffer (line 785) | func (w *windowsTLSReadWaiter) WaitReadBuffer() (*buf.Buffer, error) {
    method appendRaw (line 813) | func (w *windowsTLSReadWaiter) appendRaw(requireMore bool) error {
    method readRaw (line 823) | func (w *windowsTLSReadWaiter) readRaw(requireMore bool) ([]byte, erro...
    method readRawBuffer (line 833) | func (w *windowsTLSReadWaiter) readRawBuffer(requireMore bool) (*buf.B...

FILE: common/tls/windows_client_stub.go
  function newWindowsClient (line 13) | func newWindowsClient(ctx context.Context, logger logger.ContextLogger, ...

FILE: common/tls/windows_client_test.go
  constant windowsTLSTestTimeout (line 30) | windowsTLSTestTimeout = 5 * time.Second
  function newTestWindowsTLSConn (line 37) | func newTestWindowsTLSConn(rawConn net.Conn) *windowsTLSConn {
  method writePostHandshakeReply (line 46) | func (c *windowsTLSConn) writePostHandshakeReply(data []byte) error {
  type windowsTLSServerResult (line 56) | type windowsTLSServerResult struct
  type windowsTestDeadlineConn (line 61) | type windowsTestDeadlineConn struct
    method Read (line 87) | func (c *windowsTestDeadlineConn) Read(_ []byte) (int, error) {
    method Write (line 109) | func (c *windowsTestDeadlineConn) Write(_ []byte) (int, error) {
    method Close (line 131) | func (c *windowsTestDeadlineConn) Close() error {
    method LocalAddr (line 135) | func (c *windowsTestDeadlineConn) LocalAddr() net.Addr {
    method RemoteAddr (line 139) | func (c *windowsTestDeadlineConn) RemoteAddr() net.Addr {
    method SetDeadline (line 143) | func (c *windowsTestDeadlineConn) SetDeadline(t time.Time) error {
    method SetReadDeadline (line 153) | func (c *windowsTestDeadlineConn) SetReadDeadline(t time.Time) error {
    method SetWriteDeadline (line 161) | func (c *windowsTestDeadlineConn) SetWriteDeadline(t time.Time) error {
    method recordedWriteDeadlines (line 169) | func (c *windowsTestDeadlineConn) recordedWriteDeadlines() []time.Time {
    method recordedReadDeadlines (line 175) | func (c *windowsTestDeadlineConn) recordedReadDeadlines() []time.Time {
  type windowsTestWriteGateConn (line 73) | type windowsTestWriteGateConn struct
    method Read (line 181) | func (c *windowsTestWriteGateConn) Read(_ []byte) (int, error) {
    method Write (line 185) | func (c *windowsTestWriteGateConn) Write(p []byte) (int, error) {
    method Close (line 191) | func (c *windowsTestWriteGateConn) Close() error {
    method LocalAddr (line 195) | func (c *windowsTestWriteGateConn) LocalAddr() net.Addr {
    method RemoteAddr (line 199) | func (c *windowsTestWriteGateConn) RemoteAddr() net.Addr {
    method SetDeadline (line 203) | func (c *windowsTestWriteGateConn) SetDeadline(time.Time) error {
    method SetReadDeadline (line 207) | func (c *windowsTestWriteGateConn) SetReadDeadline(time.Time) error {
    method SetWriteDeadline (line 211) | func (c *windowsTestWriteGateConn) SetWriteDeadline(time.Time) error {
  type windowsTestIOConn (line 78) | type windowsTestIOConn struct
    method Read (line 215) | func (c *windowsTestIOConn) Read(_ []byte) (int, error) {
    method Write (line 219) | func (c *windowsTestIOConn) Write(p []byte) (int, error) {
    method Close (line 233) | func (c *windowsTestIOConn) Close() error {
    method LocalAddr (line 240) | func (c *windowsTestIOConn) LocalAddr() net.Addr {
    method RemoteAddr (line 244) | func (c *windowsTestIOConn) RemoteAddr() net.Addr {
    method SetDeadline (line 248) | func (c *windowsTestIOConn) SetDeadline(time.Time) error {
    method SetReadDeadline (line 252) | func (c *windowsTestIOConn) SetReadDeadline(time.Time) error {
    method SetWriteDeadline (line 256) | func (c *windowsTestIOConn) SetWriteDeadline(time.Time) error {
    method isClosed (line 260) | func (c *windowsTestIOConn) isClosed() bool {
    method totalWriteCalls (line 266) | func (c *windowsTestIOConn) totalWriteCalls() int {
  type windowsTestAddr (line 272) | type windowsTestAddr
    method Network (line 274) | func (a windowsTestAddr) Network() string {
    method String (line 278) | func (a windowsTestAddr) String() string {
  type windowsOpaqueConn (line 282) | type windowsOpaqueConn struct
  function TestWindowsClientHandshakeTLS12 (line 286) | func TestWindowsClientHandshakeTLS12(t *testing.T) {
  function TestWindowsClientHandshakeWrappedConn (line 335) | func TestWindowsClientHandshakeWrappedConn(t *testing.T) {
  function TestWindowsClientHandshakeTLS13 (line 380) | func TestWindowsClientHandshakeTLS13(t *testing.T) {
  function TestWindowsClientHandshakeALPNNoOverlap (line 419) | func TestWindowsClientHandshakeALPNNoOverlap(t *testing.T) {
  function TestWindowsClientHandshakeMultipleALPN (line 445) | func TestWindowsClientHandshakeMultipleALPN(t *testing.T) {
  function TestWindowsClientHandshakeRejectsVersionMismatch (line 474) | func TestWindowsClientHandshakeRejectsVersionMismatch(t *testing.T) {
  function TestWindowsClientHandshakeRejectsServerNameMismatch (line 500) | func TestWindowsClientHandshakeRejectsServerNameMismatch(t *testing.T) {
  function TestWindowsClientHandshakeRejectsUntrustedCA (line 518) | func TestWindowsClientHandshakeRejectsUntrustedCA(t *testing.T) {
  function TestWindowsClientHandshakeInsecureSkipsValidation (line 535) | func TestWindowsClientHandshakeInsecureSkipsValidation(t *testing.T) {
  function TestWindowsClientHandshakeHonorsPublicKeyPinSuccess (line 558) | func TestWindowsClientHandshakeHonorsPublicKeyPinSuccess(t *testing.T) {
  function TestWindowsClientHandshakeHonorsPublicKeyPinFailure (line 577) | func TestWindowsClientHandshakeHonorsPublicKeyPinFailure(t *testing.T) {
  function TestWindowsClientHandshakeContextCancellation (line 596) | func TestWindowsClientHandshakeContextCancellation(t *testing.T) {
  function TestWindowsClientHandshakeTimeout (line 670) | func TestWindowsClientHandshakeTimeout(t *testing.T) {
  function TestWindowsClientRoundtrip (line 724) | func TestWindowsClientRoundtrip(t *testing.T) {
  function TestWindowsClientRoundtripTLS13 (line 745) | func TestWindowsClientRoundtripTLS13(t *testing.T) {
  function TestWindowsClientReadBuffer (line 767) | func TestWindowsClientReadBuffer(t *testing.T) {
  function TestWindowsClientWriteBuffer (line 796) | func TestWindowsClientWriteBuffer(t *testing.T) {
  function TestWindowsClientCreateReadWaiter (line 828) | func TestWindowsClientCreateReadWaiter(t *testing.T) {
  function TestWindowsClientCreateReadWaiterFallback (line 862) | func TestWindowsClientCreateReadWaiterFallback(t *testing.T) {
  function TestWindowsClientTLS13PostHandshakeConcurrentWrite (line 870) | func TestWindowsClientTLS13PostHandshakeConcurrentWrite(t *testing.T) {
  function TestWindowsClientLargeMessage (line 976) | func TestWindowsClientLargeMessage(t *testing.T) {
  function TestWindowsClientFullDuplexLargePayload (line 1009) | func TestWindowsClientFullDuplexLargePayload(t *testing.T) {
  function TestWindowsClientMultipleRoundtrips (line 1109) | func TestWindowsClientMultipleRoundtrips(t *testing.T) {
  function TestWindowsClientConcurrentReadWrite (line 1133) | func TestWindowsClientConcurrentReadWrite(t *testing.T) {
  function TestWindowsClientServerCloseReturnsEOF (line 1185) | func TestWindowsClientServerCloseReturnsEOF(t *testing.T) {
  function TestWindowsClientCloseUnblocksRead (line 1231) | func TestWindowsClientCloseUnblocksRead(t *testing.T) {
  function TestWindowsClientReadAfterCloseReturnsError (line 1270) | func TestWindowsClientReadAfterCloseReturnsError(t *testing.T) {
  function TestWindowsClientReadAfterCloseDoesNotServeBufferedPlaintext (line 1282) | func TestWindowsClientReadAfterCloseDoesNotServeBufferedPlaintext(t *tes...
  function TestWindowsClientWriteAfterCloseReturnsError (line 1360) | func TestWindowsClientWriteAfterCloseReturnsError(t *testing.T) {
  function TestWindowsClientReadDeadline (line 1371) | func TestWindowsClientReadDeadline(t *testing.T) {
  function TestWindowsClientSetReadDeadlinePreExpired (line 1414) | func TestWindowsClientSetReadDeadlinePreExpired(t *testing.T) {
  function TestWindowsClientSetDeadlinePropagatesToRawConn (line 1466) | func TestWindowsClientSetDeadlinePropagatesToRawConn(t *testing.T) {
  function TestWindowsClientSetReadDeadlineCancelsBlockedRead (line 1493) | func TestWindowsClientSetReadDeadlineCancelsBlockedRead(t *testing.T) {
  function TestWindowsClientSetWriteDeadlineCancelsBlockedWrite (line 1536) | func TestWindowsClientSetWriteDeadlineCancelsBlockedWrite(t *testing.T) {
  function TestWindowsClientPostHandshakeReplyUsesReadDeadline (line 1602) | func TestWindowsClientPostHandshakeReplyUsesReadDeadline(t *testing.T) {
  function TestWindowsClientPostHandshakeReplyPreExpiredReadDeadline (line 1634) | func TestWindowsClientPostHandshakeReplyPreExpiredReadDeadline(t *testin...
  function TestDriveStepsPreservesBufferedHandshakeBytes (line 1659) | func TestDriveStepsPreservesBufferedHandshakeBytes(t *testing.T) {
  function TestWindowsTLSRawReadEOFAtRecordBoundary (line 1703) | func TestWindowsTLSRawReadEOFAtRecordBoundary(t *testing.T) {
  function TestWindowsTLSRawReadEOFWithPendingRecord (line 1711) | func TestWindowsTLSRawReadEOFWithPendingRecord(t *testing.T) {
  function TestWindowsClientPostHandshakeReplyWaitsForWriteAccess (line 1719) | func TestWindowsClientPostHandshakeReplyWaitsForWriteAccess(t *testing.T) {
  function TestWindowsClientPostHandshakeWritePreemptsNewWrite (line 1753) | func TestWindowsClientPostHandshakeWritePreemptsNewWrite(t *testing.T) {
  function TestWindowsClientPostHandshakeReplyErrorClosesConn (line 1817) | func TestWindowsClientPostHandshakeReplyErrorClosesConn(t *testing.T) {
  function TestWindowsClientWriteErrorClosesConn (line 1836) | func TestWindowsClientWriteErrorClosesConn(t *testing.T) {
  function TestWindowsClientConnectionStateFields (line 1892) | func TestWindowsClientConnectionStateFields(t *testing.T) {
  function TestWindowsClientNetConnReturnsUnderlying (line 1940) | func TestWindowsClientNetConnReturnsUnderlying(t *testing.T) {
  function TestNewWindowsClientMissingServerName (line 1951) | func TestNewWindowsClientMissingServerName(t *testing.T) {
  function TestNewWindowsClientInsecureAllowsMissingServerName (line 1965) | func TestNewWindowsClientInsecureAllowsMissingServerName(t *testing.T) {
  function TestWindowsClientConfigSTDConfigReturnsError (line 1980) | func TestWindowsClientConfigSTDConfigReturnsError(t *testing.T) {
  function TestWindowsClientConfigClientReturnsErrInvalid (line 2002) | func TestWindowsClientConfigClientReturnsErrInvalid(t *testing.T) {
  function TestWindowsClientConfigClone (line 2021) | func TestWindowsClientConfigClone(t *testing.T) {
  function TestValidateWindowsTLSOptionsRejections (line 2049) | func TestValidateWindowsTLSOptionsRejections(t *testing.T) {
  function startWindowsTLSSilentServer (line 2126) | func startWindowsTLSSilentServer(t *testing.T, tlsConfig *stdtls.Config)...
  function newWindowsTestCertificate (line 2174) | func newWindowsTestCertificate(t *testing.T, serverName string) (stdtls....
  function generateWindowsTestCertificate (line 2182) | func generateWindowsTestCertificate(serverName
Condensed preview — 1205 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (5,881K 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": 1121,
    "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": "2faf34666c2cc8234f10f2ab6d4c4d6104d34ae2\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": 3137,
    "preview": "#!/usr/bin/env bash\n\nset -e -o pipefail\n\nprepare_apk_root() {\n  # apk mkpkg resolves owner/group names through --root/et"
  },
  {
    "path": ".github/build_openwrt_apk.sh",
    "chars": 3113,
    "preview": "#!/usr/bin/env bash\n\nset -e -o pipefail\n\nprepare_apk_root() {\n  # apk mkpkg resolves owner/group names through --root/et"
  },
  {
    "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/detect_track.sh",
    "chars": 1044,
    "preview": "#!/usr/bin/env bash\nset -euo pipefail\n\nbranches=$(git branch -r --contains HEAD)\nif echo \"$branches\" | grep -q 'origin/s"
  },
  {
    "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.9\"\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.9\"\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": 10724,
    "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": 1816,
    "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": 9774,
    "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": ".github/workflows/test.yml",
    "chars": 1421,
    "preview": "name: Test\n\non:\n  push:\n    branches:\n      - stable\n      - testing\n      - unstable\n    paths-ignore:\n      - '**.md'\n"
  },
  {
    "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": 1135,
    "preview": "version: \"2\"\nrun:\n  go: \"1.24\"\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": 10131,
    "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": 1032,
    "preview": "# sing-box\n\nThe universal proxy platform.\n\n[![Packaging status](https://repology.org/badge/vertical-allrepos/sing-box.sv"
  },
  {
    "path": "adapter/certificate/adapter.go",
    "chars": 354,
    "preview": "package certificate\n\ntype Adapter struct {\n\tproviderType string\n\tproviderTag  string\n}\n\nfunc NewAdapter(providerType str"
  },
  {
    "path": "adapter/certificate/manager.go",
    "chars": 4505,
    "preview": "package certificate\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/sag"
  },
  {
    "path": "adapter/certificate/registry.go",
    "chars": 2290,
    "preview": "package certificate\n\nimport (\n\t\"context\"\n\t\"sync\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.com/sagernet/sing-box"
  },
  {
    "path": "adapter/certificate.go",
    "chars": 369,
    "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/certificate_darwin.go",
    "chars": 315,
    "preview": "//go:build darwin && cgo\n\npackage adapter\n\nimport \"unsafe\"\n\ntype AppleAnchors interface {\n\tRetain() AppleAnchors\n\tReleas"
  },
  {
    "path": "adapter/certificate_provider.go",
    "chars": 966,
    "preview": "package adapter\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\t\"github.com/sagernet/sing-box/o"
  },
  {
    "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": 3797,
    "preview": "package adapter\n\nimport (\n\t\"context\"\n\t\"net/netip\"\n\t\"time\"\n\n\tC \"github.com/sagernet/sing-box/constant\"\n\t\"github.com/sager"
  },
  {
    "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": 4030,
    "preview": "package endpoint\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"sync\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.com/sagernet/sing-"
  },
  {
    "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": 3246,
    "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": 858,
    "preview": "package adapter\n\nimport (\n\t\"context\"\n\t\"net\"\n\n\t\"github.com/sagernet/sing/common/buf\"\n\tM \"github.com/sagernet/sing/common/"
  },
  {
    "path": "adapter/http.go",
    "chars": 879,
    "preview": "package adapter\n\nimport (\n\t\"context\"\n\t\"net/http\"\n\t\"sync\"\n\n\t\"github.com/sagernet/sing-box/option\"\n\t\"github.com/sagernet/s"
  },
  {
    "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": 4018,
    "preview": "package inbound\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"sync\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.com/sagernet/sing-b"
  },
  {
    "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": 4971,
    "preview": "package adapter\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"net/netip\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/common/tlsspoof\"\n\tC \"gi"
  },
  {
    "path": "adapter/inbound_test.go",
    "chars": 884,
    "preview": "package adapter\n\nimport (\n\t\"net\"\n\t\"net/netip\"\n\t\"testing\"\n\n\t\"github.com/miekg/dns\"\n\t\"github.com/stretchr/testify/require\""
  },
  {
    "path": "adapter/lifecycle.go",
    "chars": 2254,
    "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": 460,
    "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": 1825,
    "preview": "package adapter\n\nimport (\n\t\"encoding/hex\"\n\t\"net\"\n\t\"strings\"\n\t\"time\"\n\n\tC \"github.com/sagernet/sing-box/constant\"\n\t\"github"
  },
  {
    "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": 9082,
    "preview": "package outbound\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.c"
  },
  {
    "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": 1876,
    "preview": "package adapter\n\nimport (\n\t\"net/netip\"\n\n\t\"github.com/sagernet/sing-box/option\"\n\t\"github.com/sagernet/sing-tun\"\n\t\"github."
  },
  {
    "path": "adapter/prestart.go",
    "chars": 16,
    "preview": "package adapter\n"
  },
  {
    "path": "adapter/router.go",
    "chars": 2659,
    "preview": "package adapter\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-tun\"\n\tN \"github.com/sagernet/sing/common"
  },
  {
    "path": "adapter/rule.go",
    "chars": 708,
    "preview": "package adapter\n\nimport (\n\tC \"github.com/sagernet/sing-box/constant\"\n\n\t\"github.com/miekg/dns\"\n)\n\ntype HeadlessRule inter"
  },
  {
    "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": 3844,
    "preview": "package service\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"sync\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.com/sagernet/sing-b"
  },
  {
    "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/tailscale.go",
    "chars": 1080,
    "preview": "package adapter\n\nimport \"context\"\n\ntype TailscaleEndpoint interface {\n\tSubscribeTailscaleStatus(ctx context.Context, fn "
  },
  {
    "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": 5048,
    "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": 7364,
    "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": 21758,
    "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\tb"
  },
  {
    "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": 6358,
    "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": 3657,
    "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": 1824,
    "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": 2455,
    "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": 2100,
    "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": 2735,
    "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_networkquality.go",
    "chars": 3992,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/common/networkquality\"\n\t\"github.c"
  },
  {
    "path": "cmd/sing-box/cmd_tools_stun.go",
    "chars": 1914,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/sagernet/sing-box/common/stun\"\n\t\"github.com/sagernet/sing-box/log\"\n\n\t\""
  },
  {
    "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": 4190,
    "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/anchors_darwin.h",
    "chars": 741,
    "preview": "#ifndef BOX_CERTIFICATE_ANCHORS_DARWIN_H\n#define BOX_CERTIFICATE_ANCHORS_DARWIN_H\n\n#include <stddef.h>\n#include <stdint."
  },
  {
    "path": "common/certificate/anchors_darwin.m",
    "chars": 1100,
    "preview": "#import \"anchors_darwin.h\"\n\n#import <Foundation/Foundation.h>\n#import <Security/Security.h>\n\nvoid *box_certificate_ancho"
  },
  {
    "path": "common/certificate/chrome.go",
    "chars": 151510,
    "preview": "// Code generated by 'make update_certificates'. DO NOT EDIT.\n\npackage certificate\n\nfunc chromeIncludedPEM() string {\n\tr"
  },
  {
    "path": "common/certificate/chrome.pem",
    "chars": 161006,
    "preview": "-----BEGIN CERTIFICATE-----\nMIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE\nBhMCSVQxDjAMBgNVBAcMBU1pbGF"
  },
  {
    "path": "common/certificate/mozilla.go",
    "chars": 244603,
    "preview": "// Code generated by 'make update_certificates'. DO NOT EDIT.\n\npackage certificate\n\nfunc mozillaIncludedPEM() string {\n\t"
  },
  {
    "path": "common/certificate/mozilla.pem",
    "chars": 258460,
    "preview": "-----BEGIN CERTIFICATE-----\nMIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE\nBhMCSVQxDjAMBgNVBAcMBU1pbGF"
  },
  {
    "path": "common/certificate/store.go",
    "chars": 6564,
    "preview": "package certificate\n\nimport (\n\t\"bytes\"\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\"g"
  },
  {
    "path": "common/certificate/store_darwin.go",
    "chars": 4095,
    "preview": "//go:build darwin && cgo\n\npackage certificate\n\n/*\n#cgo CFLAGS: -x objective-c -fobjc-arc\n#cgo LDFLAGS: -framework Founda"
  },
  {
    "path": "common/certificate/store_other.go",
    "chars": 287,
    "preview": "//go:build !(darwin && cgo)\n\npackage certificate\n\n//nolint:unused // referenced by Store.platform; populated only in sto"
  },
  {
    "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": 13926,
    "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": 14297,
    "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": 9040,
    "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": 2440,
    "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": 6571,
    "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": 6254,
    "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": 3209,
    "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/httpclient/apple_transport_darwin.go",
    "chars": 14310,
    "preview": "//go:build darwin && cgo\n\npackage httpclient\n\n/*\n#cgo CFLAGS: -x objective-c -fobjc-arc\n#cgo LDFLAGS: -framework Foundat"
  },
  {
    "path": "common/httpclient/apple_transport_darwin.h",
    "chars": 1921,
    "preview": "#include <stdbool.h>\n#include <stddef.h>\n#include <stdint.h>\n\ntypedef struct box_apple_http_session box_apple_http_sessi"
  },
  {
    "path": "common/httpclient/apple_transport_darwin.m",
    "chars": 13734,
    "preview": "#import \"apple_transport_darwin.h\"\n\n#import <CoreFoundation/CFStream.h>\n#import <Foundation/Foundation.h>\n#import <Secur"
  },
  {
    "path": "common/httpclient/apple_transport_darwin_test.go",
    "chars": 28632,
    "preview": "//go:build darwin && cgo\n\npackage httpclient\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/sha256\"\n\tstdtls \"crypto/tls\"\n\t\"crypt"
  },
  {
    "path": "common/httpclient/apple_transport_stub.go",
    "chars": 481,
    "preview": "//go:build !darwin || !cgo\n\npackage httpclient\n\nimport (\n\t\"context\"\n\n\t\"github.com/sagernet/sing-box/option\"\n\tE \"github.c"
  },
  {
    "path": "common/httpclient/client.go",
    "chars": 3940,
    "preview": "package httpclient\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/common/dialer\"\n\t\"github.com/sagernet/sin"
  },
  {
    "path": "common/httpclient/context.go",
    "chars": 363,
    "preview": "package httpclient\n\nimport \"context\"\n\ntype transportKey struct{}\n\nfunc contextWithTransportTag(ctx context.Context, tran"
  },
  {
    "path": "common/httpclient/helpers.go",
    "chars": 3093,
    "preview": "package httpclient\n\nimport (\n\t\"context\"\n\tstdTLS \"crypto/tls\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"strings\"\n\n\t\"github.com/sagernet/"
  },
  {
    "path": "common/httpclient/helpers_test.go",
    "chars": 1643,
    "preview": "package httpclient\n\nimport (\n\t\"net/http\"\n\t\"net/url\"\n\t\"testing\"\n)\n\nfunc TestRequestAuthority(t *testing.T) {\n\ttestCases :"
  },
  {
    "path": "common/httpclient/http1_transport.go",
    "chars": 1110,
    "preview": "package httpclient\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"net/http\"\n\n\t\"github.com/sagernet/sing-box/common/tls\"\n\tM \"github.com/sa"
  },
  {
    "path": "common/httpclient/http2_config.go",
    "chars": 1424,
    "preview": "package httpclient\n\nimport (\n\tstdTLS \"crypto/tls\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/option\"\n\tE \"github"
  },
  {
    "path": "common/httpclient/http2_fallback_transport.go",
    "chars": 2742,
    "preview": "package httpclient\n\nimport (\n\t\"context\"\n\tstdTLS \"crypto/tls\"\n\t\"errors\"\n\t\"net\"\n\t\"net/http\"\n\t\"sync\"\n\n\t\"github.com/sagernet"
  },
  {
    "path": "common/httpclient/http2_fallback_transport_test.go",
    "chars": 1141,
    "preview": "package httpclient\n\nimport (\n\t\"testing\"\n)\n\nfunc TestHTTP2FallbackAuthorityIsolation(t *testing.T) {\n\ttransport := &http2"
  },
  {
    "path": "common/httpclient/http2_transport.go",
    "chars": 1419,
    "preview": "package httpclient\n\nimport (\n\t\"context\"\n\tstdTLS \"crypto/tls\"\n\t\"net\"\n\t\"net/http\"\n\n\t\"github.com/sagernet/sing-box/common/t"
  },
  {
    "path": "common/httpclient/http3_transport.go",
    "chars": 8429,
    "preview": "//go:build with_quic\n\npackage httpclient\n\nimport (\n\t\"context\"\n\tstdTLS \"crypto/tls\"\n\t\"errors\"\n\t\"net/http\"\n\t\"sync\"\n\t\"time\""
  },
  {
    "path": "common/httpclient/http3_transport_stub.go",
    "chars": 708,
    "preview": "//go:build !with_quic\n\npackage httpclient\n\nimport (\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/common/tls\"\n\t\"github.com/sag"
  },
  {
    "path": "common/httpclient/http3_transport_test.go",
    "chars": 3459,
    "preview": "//go:build with_quic\n\npackage httpclient\n\nimport (\n\t\"testing\"\n\t\"time\"\n)\n\nfunc TestHTTP3BrokenAuthorityIsolation(t *testi"
  },
  {
    "path": "common/httpclient/managed_transport.go",
    "chars": 4481,
    "preview": "package httpclient\n\nimport (\n\t\"io\"\n\t\"net/http\"\n\t\"sync\"\n\t\"sync/atomic\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\tE \"githu"
  },
  {
    "path": "common/httpclient/manager.go",
    "chars": 4952,
    "preview": "package httpclient\n\nimport (\n\t\"context\"\n\t\"sync\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.com/sagernet/sing-box/"
  },
  {
    "path": "common/interrupt/conn.go",
    "chars": 1351,
    "preview": "package interrupt\n\nimport (\n\t\"net\"\n\n\t\"github.com/sagernet/sing/common/bufio\"\n\t\"github.com/sagernet/sing/common/x/list\"\n)"
  },
  {
    "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": 10704,
    "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": 5199,
    "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 "
  }
]

// ... and 1005 more files (download for full content)

About this extraction

This page contains the full source code of the reF1nd/sing-box GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1205 files (5.1 MB), approximately 1.4M tokens, and a symbol index with 7773 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!