Showing preview only (3,979K chars total). Download the full file or copy to clipboard to get everything.
Repository: SagerNet/sing-box
Branch: testing
Commit: c5bf6b3e71b6
Files: 1022
Total size: 3.6 MB
Directory structure:
gitextract_d_trzmkv/
├── .fpm_openwrt
├── .fpm_pacman
├── .fpm_systemd
├── .github/
│ ├── CRONET_GO_VERSION
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.yml
│ │ └── bug_report_zh.yml
│ ├── build_alpine_apk.sh
│ ├── build_openwrt_apk.sh
│ ├── deb2ipk.sh
│ ├── renovate.json
│ ├── setup_go_for_macos1013.sh
│ ├── setup_go_for_windows7.sh
│ ├── update_clients.sh
│ ├── update_cronet.sh
│ ├── update_cronet_dev.sh
│ ├── update_dependencies.sh
│ └── workflows/
│ ├── build.yml
│ ├── docker.yml
│ ├── lint.yml
│ ├── linux.yml
│ └── stale.yml
├── .gitignore
├── .gitmodules
├── .golangci.yml
├── Dockerfile
├── Dockerfile.binary
├── LICENSE
├── Makefile
├── README.md
├── adapter/
│ ├── certificate.go
│ ├── connections.go
│ ├── dns.go
│ ├── endpoint/
│ │ ├── adapter.go
│ │ ├── manager.go
│ │ └── registry.go
│ ├── endpoint.go
│ ├── experimental.go
│ ├── fakeip.go
│ ├── fakeip_metadata.go
│ ├── handler.go
│ ├── inbound/
│ │ ├── adapter.go
│ │ ├── manager.go
│ │ └── registry.go
│ ├── inbound.go
│ ├── lifecycle.go
│ ├── lifecycle_legacy.go
│ ├── neighbor.go
│ ├── network.go
│ ├── outbound/
│ │ ├── adapter.go
│ │ ├── manager.go
│ │ └── registry.go
│ ├── outbound.go
│ ├── platform.go
│ ├── prestart.go
│ ├── router.go
│ ├── rule.go
│ ├── service/
│ │ ├── adapter.go
│ │ ├── manager.go
│ │ └── registry.go
│ ├── service.go
│ ├── ssm.go
│ ├── time.go
│ ├── upstream.go
│ ├── upstream_legacy.go
│ └── v2ray.go
├── box.go
├── cmd/
│ ├── internal/
│ │ ├── app_store_connect/
│ │ │ └── main.go
│ │ ├── build/
│ │ │ └── main.go
│ │ ├── build_libbox/
│ │ │ └── main.go
│ │ ├── build_shared/
│ │ │ ├── sdk.go
│ │ │ └── tag.go
│ │ ├── format_docs/
│ │ │ └── main.go
│ │ ├── protogen/
│ │ │ └── main.go
│ │ ├── read_tag/
│ │ │ └── main.go
│ │ ├── tun_bench/
│ │ │ └── main.go
│ │ ├── update_android_version/
│ │ │ └── main.go
│ │ ├── update_apple_version/
│ │ │ └── main.go
│ │ └── update_certificates/
│ │ └── main.go
│ └── sing-box/
│ ├── cmd.go
│ ├── cmd_check.go
│ ├── cmd_format.go
│ ├── cmd_generate.go
│ ├── cmd_generate_ech.go
│ ├── cmd_generate_tls.go
│ ├── cmd_generate_vapid.go
│ ├── cmd_generate_wireguard.go
│ ├── cmd_geoip.go
│ ├── cmd_geoip_export.go
│ ├── cmd_geoip_list.go
│ ├── cmd_geoip_lookup.go
│ ├── cmd_geosite.go
│ ├── cmd_geosite_export.go
│ ├── cmd_geosite_list.go
│ ├── cmd_geosite_lookup.go
│ ├── cmd_geosite_matcher.go
│ ├── cmd_merge.go
│ ├── cmd_rule_set.go
│ ├── cmd_rule_set_compile.go
│ ├── cmd_rule_set_convert.go
│ ├── cmd_rule_set_decompile.go
│ ├── cmd_rule_set_format.go
│ ├── cmd_rule_set_match.go
│ ├── cmd_rule_set_merge.go
│ ├── cmd_rule_set_upgrade.go
│ ├── cmd_run.go
│ ├── cmd_tools.go
│ ├── cmd_tools_connect.go
│ ├── cmd_tools_fetch.go
│ ├── cmd_tools_fetch_http3.go
│ ├── cmd_tools_fetch_http3_stub.go
│ ├── cmd_tools_synctime.go
│ ├── cmd_version.go
│ ├── generate_completions.go
│ └── main.go
├── common/
│ ├── badtls/
│ │ ├── raw_conn.go
│ │ ├── raw_half_conn.go
│ │ ├── read_wait.go
│ │ ├── read_wait_stub.go
│ │ ├── registry.go
│ │ └── registry_utls.go
│ ├── badversion/
│ │ ├── version.go
│ │ ├── version_json.go
│ │ └── version_test.go
│ ├── certificate/
│ │ ├── chrome.go
│ │ ├── mozilla.go
│ │ └── store.go
│ ├── compatible/
│ │ └── map.go
│ ├── convertor/
│ │ └── adguard/
│ │ ├── convertor.go
│ │ └── convertor_test.go
│ ├── dialer/
│ │ ├── default.go
│ │ ├── default_parallel_interface.go
│ │ ├── default_parallel_network.go
│ │ ├── detour.go
│ │ ├── dialer.go
│ │ ├── resolve.go
│ │ ├── router.go
│ │ ├── tfo.go
│ │ └── wireguard.go
│ ├── geoip/
│ │ └── reader.go
│ ├── geosite/
│ │ ├── compat_test.go
│ │ ├── geosite_test.go
│ │ ├── reader.go
│ │ ├── rule.go
│ │ └── writer.go
│ ├── interrupt/
│ │ ├── conn.go
│ │ ├── context.go
│ │ └── group.go
│ ├── ja3/
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── error.go
│ │ ├── ja3.go
│ │ └── parser.go
│ ├── ktls/
│ │ ├── ktls.go
│ │ ├── ktls_alert.go
│ │ ├── ktls_cipher_suites_linux.go
│ │ ├── ktls_close.go
│ │ ├── ktls_const.go
│ │ ├── ktls_handshake_messages.go
│ │ ├── ktls_key_update.go
│ │ ├── ktls_linux.go
│ │ ├── ktls_prf.go
│ │ ├── ktls_read.go
│ │ ├── ktls_read_wait.go
│ │ ├── ktls_stub_nolinkname.go
│ │ ├── ktls_stub_nonlinux.go
│ │ ├── ktls_stub_oldgo.go
│ │ └── ktls_write.go
│ ├── listener/
│ │ ├── listener.go
│ │ ├── listener_tcp.go
│ │ └── listener_udp.go
│ ├── mux/
│ │ ├── client.go
│ │ └── router.go
│ ├── pipelistener/
│ │ └── listener.go
│ ├── process/
│ │ ├── searcher.go
│ │ ├── searcher_android.go
│ │ ├── searcher_darwin.go
│ │ ├── searcher_linux.go
│ │ ├── searcher_linux_shared.go
│ │ ├── searcher_stub.go
│ │ └── searcher_windows.go
│ ├── redir/
│ │ ├── redir_darwin.go
│ │ ├── redir_linux.go
│ │ ├── redir_other.go
│ │ ├── tproxy_linux.go
│ │ └── tproxy_other.go
│ ├── settings/
│ │ ├── proxy_android.go
│ │ ├── proxy_darwin.go
│ │ ├── proxy_linux.go
│ │ ├── proxy_stub.go
│ │ ├── proxy_windows.go
│ │ ├── system_proxy.go
│ │ ├── wifi.go
│ │ ├── wifi_linux.go
│ │ ├── wifi_linux_connman.go
│ │ ├── wifi_linux_iwd.go
│ │ ├── wifi_linux_nm.go
│ │ ├── wifi_linux_wpa.go
│ │ ├── wifi_stub.go
│ │ └── wifi_windows.go
│ ├── sniff/
│ │ ├── bittorrent.go
│ │ ├── bittorrent_test.go
│ │ ├── dns.go
│ │ ├── dns_test.go
│ │ ├── dtls.go
│ │ ├── dtls_test.go
│ │ ├── http.go
│ │ ├── http_test.go
│ │ ├── internal/
│ │ │ └── qtls/
│ │ │ └── qtls.go
│ │ ├── ntp.go
│ │ ├── ntp_test.go
│ │ ├── quic.go
│ │ ├── quic_blacklist.go
│ │ ├── quic_capture_test.go
│ │ ├── quic_test.go
│ │ ├── rdp.go
│ │ ├── rdp_test.go
│ │ ├── sniff.go
│ │ ├── ssh.go
│ │ ├── ssh_test.go
│ │ ├── stun.go
│ │ ├── stun_test.go
│ │ └── tls.go
│ ├── srs/
│ │ ├── binary.go
│ │ ├── compat_test.go
│ │ ├── ip_cidr.go
│ │ └── ip_set.go
│ ├── taskmonitor/
│ │ └── monitor.go
│ ├── tls/
│ │ ├── acme.go
│ │ ├── acme_contstant.go
│ │ ├── acme_stub.go
│ │ ├── client.go
│ │ ├── common.go
│ │ ├── config.go
│ │ ├── ech.go
│ │ ├── ech_shared.go
│ │ ├── ech_tag_stub.go
│ │ ├── ktls.go
│ │ ├── mkcert.go
│ │ ├── reality_client.go
│ │ ├── reality_server.go
│ │ ├── reality_stub.go
│ │ ├── server.go
│ │ ├── std_client.go
│ │ ├── std_server.go
│ │ ├── time_wrapper.go
│ │ ├── utls_client.go
│ │ └── utls_stub.go
│ ├── tlsfragment/
│ │ ├── conn.go
│ │ ├── conn_test.go
│ │ ├── index.go
│ │ ├── index_test.go
│ │ ├── wait_darwin.go
│ │ ├── wait_linux.go
│ │ ├── wait_stub.go
│ │ └── wait_windows.go
│ ├── uot/
│ │ └── router.go
│ └── urltest/
│ └── urltest.go
├── constant/
│ ├── certificate.go
│ ├── cgo.go
│ ├── cgo_disabled.go
│ ├── dhcp.go
│ ├── dns.go
│ ├── err.go
│ ├── goos/
│ │ ├── gengoos.go
│ │ ├── goos.go
│ │ ├── zgoos_aix.go
│ │ ├── zgoos_android.go
│ │ ├── zgoos_darwin.go
│ │ ├── zgoos_dragonfly.go
│ │ ├── zgoos_freebsd.go
│ │ ├── zgoos_hurd.go
│ │ ├── zgoos_illumos.go
│ │ ├── zgoos_ios.go
│ │ ├── zgoos_js.go
│ │ ├── zgoos_linux.go
│ │ ├── zgoos_netbsd.go
│ │ ├── zgoos_openbsd.go
│ │ ├── zgoos_plan9.go
│ │ ├── zgoos_solaris.go
│ │ ├── zgoos_windows.go
│ │ └── zgoos_zos.go
│ ├── hysteria2.go
│ ├── network.go
│ ├── os.go
│ ├── path.go
│ ├── path_unix.go
│ ├── protocol.go
│ ├── proxy.go
│ ├── quic.go
│ ├── quic_stub.go
│ ├── rule.go
│ ├── speed.go
│ ├── time.go
│ ├── timeout.go
│ ├── v2ray.go
│ └── version.go
├── daemon/
│ ├── deprecated.go
│ ├── instance.go
│ ├── platform.go
│ ├── started_service.go
│ ├── started_service.pb.go
│ ├── started_service.proto
│ └── started_service_grpc.pb.go
├── debug.go
├── debug_http.go
├── debug_stub.go
├── debug_unix.go
├── dns/
│ ├── client.go
│ ├── client_log.go
│ ├── client_truncate.go
│ ├── extension_edns0_subnet.go
│ ├── rcode.go
│ ├── router.go
│ ├── transport/
│ │ ├── base.go
│ │ ├── connector.go
│ │ ├── connector_test.go
│ │ ├── dhcp/
│ │ │ ├── dhcp.go
│ │ │ └── dhcp_shared.go
│ │ ├── fakeip/
│ │ │ ├── fakeip.go
│ │ │ ├── memory.go
│ │ │ └── store.go
│ │ ├── hosts/
│ │ │ ├── hosts.go
│ │ │ ├── hosts_file.go
│ │ │ ├── hosts_test.go
│ │ │ ├── hosts_unix.go
│ │ │ ├── hosts_windows.go
│ │ │ └── testdata/
│ │ │ └── hosts
│ │ ├── https.go
│ │ ├── https_transport.go
│ │ ├── local/
│ │ │ ├── local.go
│ │ │ ├── local_darwin.go
│ │ │ ├── local_darwin_dhcp.go
│ │ │ ├── local_darwin_nodhcp.go
│ │ │ ├── local_resolved.go
│ │ │ ├── local_resolved_linux.go
│ │ │ ├── local_resolved_stub.go
│ │ │ ├── local_shared.go
│ │ │ ├── resolv.go
│ │ │ ├── resolv_default.go
│ │ │ ├── resolv_test.go
│ │ │ ├── resolv_unix.go
│ │ │ └── resolv_windows.go
│ │ ├── quic/
│ │ │ ├── http3.go
│ │ │ └── quic.go
│ │ ├── tcp.go
│ │ ├── tls.go
│ │ └── udp.go
│ ├── transport_adapter.go
│ ├── transport_dialer.go
│ ├── transport_manager.go
│ └── transport_registry.go
├── docs/
│ ├── CNAME
│ ├── changelog.md
│ ├── clients/
│ │ ├── android/
│ │ │ ├── features.md
│ │ │ └── index.md
│ │ ├── apple/
│ │ │ ├── features.md
│ │ │ └── index.md
│ │ ├── general.md
│ │ ├── index.md
│ │ ├── index.zh.md
│ │ └── privacy.md
│ ├── configuration/
│ │ ├── certificate/
│ │ │ ├── index.md
│ │ │ └── index.zh.md
│ │ ├── dns/
│ │ │ ├── fakeip.md
│ │ │ ├── fakeip.zh.md
│ │ │ ├── index.md
│ │ │ ├── index.zh.md
│ │ │ ├── rule.md
│ │ │ ├── rule.zh.md
│ │ │ ├── rule_action.md
│ │ │ ├── rule_action.zh.md
│ │ │ └── server/
│ │ │ ├── dhcp.md
│ │ │ ├── dhcp.zh.md
│ │ │ ├── fakeip.md
│ │ │ ├── fakeip.zh.md
│ │ │ ├── hosts.md
│ │ │ ├── hosts.zh.md
│ │ │ ├── http3.md
│ │ │ ├── http3.zh.md
│ │ │ ├── https.md
│ │ │ ├── https.zh.md
│ │ │ ├── index.md
│ │ │ ├── index.zh.md
│ │ │ ├── legacy.md
│ │ │ ├── legacy.zh.md
│ │ │ ├── local.md
│ │ │ ├── local.zh.md
│ │ │ ├── quic.md
│ │ │ ├── quic.zh.md
│ │ │ ├── resolved.md
│ │ │ ├── resolved.zh.md
│ │ │ ├── tailscale.md
│ │ │ ├── tailscale.zh.md
│ │ │ ├── tcp.md
│ │ │ ├── tcp.zh.md
│ │ │ ├── tls.md
│ │ │ ├── tls.zh.md
│ │ │ ├── udp.md
│ │ │ └── udp.zh.md
│ │ ├── endpoint/
│ │ │ ├── index.md
│ │ │ ├── index.zh.md
│ │ │ ├── tailscale.md
│ │ │ ├── tailscale.zh.md
│ │ │ ├── wireguard.md
│ │ │ └── wireguard.zh.md
│ │ ├── experimental/
│ │ │ ├── cache-file.md
│ │ │ ├── cache-file.zh.md
│ │ │ ├── clash-api.md
│ │ │ ├── clash-api.zh.md
│ │ │ ├── index.md
│ │ │ ├── index.zh.md
│ │ │ ├── v2ray-api.md
│ │ │ └── v2ray-api.zh.md
│ │ ├── inbound/
│ │ │ ├── anytls.md
│ │ │ ├── anytls.zh.md
│ │ │ ├── direct.md
│ │ │ ├── direct.zh.md
│ │ │ ├── http.md
│ │ │ ├── http.zh.md
│ │ │ ├── hysteria.md
│ │ │ ├── hysteria.zh.md
│ │ │ ├── hysteria2.md
│ │ │ ├── hysteria2.zh.md
│ │ │ ├── index.md
│ │ │ ├── index.zh.md
│ │ │ ├── mixed.md
│ │ │ ├── mixed.zh.md
│ │ │ ├── naive.md
│ │ │ ├── naive.zh.md
│ │ │ ├── redirect.md
│ │ │ ├── redirect.zh.md
│ │ │ ├── shadowsocks.md
│ │ │ ├── shadowsocks.zh.md
│ │ │ ├── shadowtls.md
│ │ │ ├── shadowtls.zh.md
│ │ │ ├── socks.md
│ │ │ ├── socks.zh.md
│ │ │ ├── tproxy.md
│ │ │ ├── tproxy.zh.md
│ │ │ ├── trojan.md
│ │ │ ├── trojan.zh.md
│ │ │ ├── tuic.md
│ │ │ ├── tuic.zh.md
│ │ │ ├── tun.md
│ │ │ ├── tun.zh.md
│ │ │ ├── vless.md
│ │ │ ├── vless.zh.md
│ │ │ ├── vmess.md
│ │ │ └── vmess.zh.md
│ │ ├── index.md
│ │ ├── index.zh.md
│ │ ├── log/
│ │ │ ├── index.md
│ │ │ └── index.zh.md
│ │ ├── ntp/
│ │ │ ├── index.md
│ │ │ └── index.zh.md
│ │ ├── outbound/
│ │ │ ├── anytls.md
│ │ │ ├── anytls.zh.md
│ │ │ ├── block.md
│ │ │ ├── block.zh.md
│ │ │ ├── direct.md
│ │ │ ├── direct.zh.md
│ │ │ ├── dns.md
│ │ │ ├── dns.zh.md
│ │ │ ├── http.md
│ │ │ ├── http.zh.md
│ │ │ ├── hysteria.md
│ │ │ ├── hysteria.zh.md
│ │ │ ├── hysteria2.md
│ │ │ ├── hysteria2.zh.md
│ │ │ ├── index.md
│ │ │ ├── index.zh.md
│ │ │ ├── naive.md
│ │ │ ├── naive.zh.md
│ │ │ ├── selector.md
│ │ │ ├── selector.zh.md
│ │ │ ├── shadowsocks.md
│ │ │ ├── shadowsocks.zh.md
│ │ │ ├── shadowtls.md
│ │ │ ├── shadowtls.zh.md
│ │ │ ├── socks.md
│ │ │ ├── socks.zh.md
│ │ │ ├── ssh.md
│ │ │ ├── ssh.zh.md
│ │ │ ├── tor.md
│ │ │ ├── tor.zh.md
│ │ │ ├── trojan.md
│ │ │ ├── trojan.zh.md
│ │ │ ├── tuic.md
│ │ │ ├── tuic.zh.md
│ │ │ ├── urltest.md
│ │ │ ├── urltest.zh.md
│ │ │ ├── vless.md
│ │ │ ├── vless.zh.md
│ │ │ ├── vmess.md
│ │ │ ├── vmess.zh.md
│ │ │ ├── wireguard.md
│ │ │ └── wireguard.zh.md
│ │ ├── route/
│ │ │ ├── geoip.md
│ │ │ ├── geoip.zh.md
│ │ │ ├── geosite.md
│ │ │ ├── geosite.zh.md
│ │ │ ├── index.md
│ │ │ ├── index.zh.md
│ │ │ ├── rule.md
│ │ │ ├── rule.zh.md
│ │ │ ├── rule_action.md
│ │ │ ├── rule_action.zh.md
│ │ │ ├── sniff.md
│ │ │ └── sniff.zh.md
│ │ ├── rule-set/
│ │ │ ├── adguard.md
│ │ │ ├── adguard.zh.md
│ │ │ ├── headless-rule.md
│ │ │ ├── headless-rule.zh.md
│ │ │ ├── index.md
│ │ │ ├── index.zh.md
│ │ │ ├── source-format.md
│ │ │ └── source-format.zh.md
│ │ ├── service/
│ │ │ ├── ccm.md
│ │ │ ├── ccm.zh.md
│ │ │ ├── derp.md
│ │ │ ├── derp.zh.md
│ │ │ ├── index.md
│ │ │ ├── index.zh.md
│ │ │ ├── ocm.md
│ │ │ ├── ocm.zh.md
│ │ │ ├── resolved.md
│ │ │ ├── resolved.zh.md
│ │ │ ├── ssm-api.md
│ │ │ └── ssm-api.zh.md
│ │ └── shared/
│ │ ├── dial.md
│ │ ├── dial.zh.md
│ │ ├── dns01_challenge.md
│ │ ├── dns01_challenge.zh.md
│ │ ├── listen.md
│ │ ├── listen.zh.md
│ │ ├── multiplex.md
│ │ ├── multiplex.zh.md
│ │ ├── neighbor.md
│ │ ├── neighbor.zh.md
│ │ ├── pre-match.md
│ │ ├── pre-match.zh.md
│ │ ├── tcp-brutal.md
│ │ ├── tcp-brutal.zh.md
│ │ ├── tls.md
│ │ ├── tls.zh.md
│ │ ├── udp-over-tcp.md
│ │ ├── udp-over-tcp.zh.md
│ │ ├── v2ray-transport.md
│ │ ├── v2ray-transport.zh.md
│ │ ├── wifi-state.md
│ │ └── wifi-state.zh.md
│ ├── deprecated.md
│ ├── deprecated.zh.md
│ ├── index.md
│ ├── index.zh.md
│ ├── installation/
│ │ ├── build-from-source.md
│ │ ├── build-from-source.zh.md
│ │ ├── docker.md
│ │ ├── docker.zh.md
│ │ ├── package-manager.md
│ │ ├── package-manager.zh.md
│ │ └── tools/
│ │ ├── arch-install.sh
│ │ ├── deb-install.sh
│ │ ├── install.sh
│ │ ├── rpm-install.sh
│ │ └── sing-box.repo
│ ├── manual/
│ │ ├── misc/
│ │ │ └── tunnelvision.md
│ │ ├── proxy/
│ │ │ ├── client.md
│ │ │ └── server.md
│ │ └── proxy-protocol/
│ │ ├── hysteria2.md
│ │ ├── shadowsocks.md
│ │ └── trojan.md
│ ├── migration.md
│ ├── migration.zh.md
│ ├── sponsors.md
│ ├── support.md
│ └── support.zh.md
├── experimental/
│ ├── cachefile/
│ │ ├── cache.go
│ │ ├── fakeip.go
│ │ └── rdrc.go
│ ├── clashapi/
│ │ ├── api_meta.go
│ │ ├── api_meta_group.go
│ │ ├── api_meta_upgrade.go
│ │ ├── cache.go
│ │ ├── common.go
│ │ ├── configs.go
│ │ ├── connections.go
│ │ ├── ctxkeys.go
│ │ ├── dns.go
│ │ ├── errors.go
│ │ ├── profile.go
│ │ ├── provider.go
│ │ ├── proxies.go
│ │ ├── ruleprovider.go
│ │ ├── rules.go
│ │ ├── script.go
│ │ ├── server.go
│ │ ├── server_fs.go
│ │ ├── server_resources.go
│ │ └── trafficontrol/
│ │ ├── manager.go
│ │ └── tracker.go
│ ├── clashapi.go
│ ├── deprecated/
│ │ ├── constants.go
│ │ ├── manager.go
│ │ └── stderr.go
│ ├── libbox/
│ │ ├── build_info.go
│ │ ├── command.go
│ │ ├── command_client.go
│ │ ├── command_server.go
│ │ ├── command_types.go
│ │ ├── config.go
│ │ ├── deprecated.go
│ │ ├── dns.go
│ │ ├── fdroid.go
│ │ ├── fdroid_mirrors.go
│ │ ├── ffi.json
│ │ ├── http.go
│ │ ├── internal/
│ │ │ └── procfs/
│ │ │ └── procfs.go
│ │ ├── iterator.go
│ │ ├── link_flags_stub.go
│ │ ├── link_flags_unix.go
│ │ ├── log.go
│ │ ├── memory.go
│ │ ├── monitor.go
│ │ ├── neighbor.go
│ │ ├── neighbor_darwin.go
│ │ ├── neighbor_linux.go
│ │ ├── neighbor_stub.go
│ │ ├── panic.go
│ │ ├── pidfd_android.go
│ │ ├── platform.go
│ │ ├── pprof.go
│ │ ├── profile_import.go
│ │ ├── remote_profile.go
│ │ ├── semver.go
│ │ ├── semver_test.go
│ │ ├── service.go
│ │ ├── service_other.go
│ │ ├── service_windows.go
│ │ ├── setup.go
│ │ ├── tun.go
│ │ ├── tun_darwin.go
│ │ ├── tun_name_darwin.go
│ │ ├── tun_name_linux.go
│ │ └── tun_name_other.go
│ ├── locale/
│ │ ├── locale.go
│ │ └── locale_zh_CN.go
│ ├── v2rayapi/
│ │ ├── server.go
│ │ ├── stats.go
│ │ ├── stats.pb.go
│ │ ├── stats.proto
│ │ └── stats_grpc.pb.go
│ └── v2rayapi.go
├── go.mod
├── go.sum
├── include/
│ ├── ccm.go
│ ├── ccm_stub.go
│ ├── ccm_stub_darwin.go
│ ├── clashapi.go
│ ├── clashapi_stub.go
│ ├── dhcp.go
│ ├── dhcp_stub.go
│ ├── naive_outbound.go
│ ├── naive_outbound_stub.go
│ ├── ocm.go
│ ├── ocm_stub.go
│ ├── oom_killer.go
│ ├── quic.go
│ ├── quic_stub.go
│ ├── registry.go
│ ├── tailscale.go
│ ├── tailscale_stub.go
│ ├── tz_android.go
│ ├── tz_ios.go
│ ├── v2rayapi.go
│ ├── v2rayapi_stub.go
│ ├── wireguard.go
│ └── wireguard_stub.go
├── log/
│ ├── export.go
│ ├── factory.go
│ ├── format.go
│ ├── id.go
│ ├── level.go
│ ├── log.go
│ ├── nop.go
│ ├── observable.go
│ ├── override.go
│ └── platform.go
├── mkdocs.yml
├── option/
│ ├── anytls.go
│ ├── ccm.go
│ ├── certificate.go
│ ├── debug.go
│ ├── direct.go
│ ├── dns.go
│ ├── dns_record.go
│ ├── endpoint.go
│ ├── experimental.go
│ ├── group.go
│ ├── hysteria.go
│ ├── hysteria2.go
│ ├── inbound.go
│ ├── multiplex.go
│ ├── naive.go
│ ├── ntp.go
│ ├── ocm.go
│ ├── oom_killer.go
│ ├── options.go
│ ├── outbound.go
│ ├── platform.go
│ ├── redir.go
│ ├── resolved.go
│ ├── route.go
│ ├── rule.go
│ ├── rule_action.go
│ ├── rule_dns.go
│ ├── rule_set.go
│ ├── service.go
│ ├── shadowsocks.go
│ ├── shadowsocksr.go
│ ├── shadowtls.go
│ ├── simple.go
│ ├── ssh.go
│ ├── ssmapi.go
│ ├── tailscale.go
│ ├── tls.go
│ ├── tls_acme.go
│ ├── tor.go
│ ├── trojan.go
│ ├── tuic.go
│ ├── tun.go
│ ├── tun_platform.go
│ ├── types.go
│ ├── udp_over_tcp.go
│ ├── v2ray.go
│ ├── v2ray_transport.go
│ ├── vless.go
│ ├── vmess.go
│ └── wireguard.go
├── protocol/
│ ├── anytls/
│ │ ├── inbound.go
│ │ └── outbound.go
│ ├── block/
│ │ └── outbound.go
│ ├── direct/
│ │ ├── inbound.go
│ │ ├── loopback_detect.go
│ │ └── outbound.go
│ ├── dns/
│ │ ├── handle.go
│ │ └── outbound.go
│ ├── group/
│ │ ├── selector.go
│ │ └── urltest.go
│ ├── http/
│ │ ├── inbound.go
│ │ └── outbound.go
│ ├── hysteria/
│ │ ├── inbound.go
│ │ └── outbound.go
│ ├── hysteria2/
│ │ ├── inbound.go
│ │ └── outbound.go
│ ├── mixed/
│ │ └── inbound.go
│ ├── naive/
│ │ ├── inbound.go
│ │ ├── inbound_conn.go
│ │ ├── outbound.go
│ │ └── quic/
│ │ └── inbound_init.go
│ ├── redirect/
│ │ ├── redirect.go
│ │ └── tproxy.go
│ ├── shadowsocks/
│ │ ├── inbound.go
│ │ ├── inbound_multi.go
│ │ ├── inbound_relay.go
│ │ └── outbound.go
│ ├── shadowtls/
│ │ ├── inbound.go
│ │ └── outbound.go
│ ├── socks/
│ │ ├── inbound.go
│ │ └── outbound.go
│ ├── ssh/
│ │ └── outbound.go
│ ├── tailscale/
│ │ ├── dns_transport.go
│ │ ├── endpoint.go
│ │ ├── tun_device_unix.go
│ │ └── tun_device_windows.go
│ ├── tor/
│ │ ├── outbound.go
│ │ └── proxy.go
│ ├── trojan/
│ │ ├── inbound.go
│ │ └── outbound.go
│ ├── tuic/
│ │ ├── inbound.go
│ │ └── outbound.go
│ ├── tun/
│ │ ├── hook.go
│ │ └── inbound.go
│ ├── vless/
│ │ ├── inbound.go
│ │ └── outbound.go
│ ├── vmess/
│ │ ├── inbound.go
│ │ └── outbound.go
│ └── wireguard/
│ └── endpoint.go
├── release/
│ ├── DEFAULT_BUILD_TAGS
│ ├── DEFAULT_BUILD_TAGS_OTHERS
│ ├── DEFAULT_BUILD_TAGS_WINDOWS
│ ├── LDFLAGS
│ ├── completions/
│ │ ├── sing-box.bash
│ │ ├── sing-box.fish
│ │ └── sing-box.zsh
│ ├── config/
│ │ ├── config.json
│ │ ├── openwrt.conf
│ │ ├── openwrt.init
│ │ ├── openwrt.keep
│ │ ├── openwrt.prerm
│ │ ├── sing-box-split-dns.xml
│ │ ├── sing-box.confd
│ │ ├── sing-box.initd
│ │ ├── sing-box.postinst
│ │ ├── sing-box.rules
│ │ ├── sing-box.service
│ │ ├── sing-box.sysusers
│ │ └── sing-box@.service
│ └── local/
│ ├── common.sh
│ ├── debug.sh
│ ├── enable.sh
│ ├── install.sh
│ ├── install_go.sh
│ ├── reinstall.sh
│ ├── sing-box.service
│ ├── uninstall.sh
│ └── update.sh
├── route/
│ ├── conn.go
│ ├── dns.go
│ ├── neighbor_resolver_darwin.go
│ ├── neighbor_resolver_lease.go
│ ├── neighbor_resolver_linux.go
│ ├── neighbor_resolver_parse.go
│ ├── neighbor_resolver_platform.go
│ ├── neighbor_resolver_stub.go
│ ├── neighbor_table_darwin.go
│ ├── neighbor_table_linux.go
│ ├── network.go
│ ├── platform_searcher.go
│ ├── route.go
│ ├── router.go
│ ├── rule/
│ │ ├── rule_abstract.go
│ │ ├── rule_abstract_test.go
│ │ ├── rule_action.go
│ │ ├── rule_default.go
│ │ ├── rule_default_interface_address.go
│ │ ├── rule_dns.go
│ │ ├── rule_headless.go
│ │ ├── rule_interface_address.go
│ │ ├── rule_item_adguard.go
│ │ ├── rule_item_auth_user.go
│ │ ├── rule_item_cidr.go
│ │ ├── rule_item_clash_mode.go
│ │ ├── rule_item_client.go
│ │ ├── rule_item_domain.go
│ │ ├── rule_item_domain_keyword.go
│ │ ├── rule_item_domain_regex.go
│ │ ├── rule_item_inbound.go
│ │ ├── rule_item_ip_accept_any.go
│ │ ├── rule_item_ip_is_private.go
│ │ ├── rule_item_ipversion.go
│ │ ├── rule_item_network.go
│ │ ├── rule_item_network_is_constrained.go
│ │ ├── rule_item_network_is_expensive.go
│ │ ├── rule_item_network_type.go
│ │ ├── rule_item_outbound.go
│ │ ├── rule_item_package_name.go
│ │ ├── rule_item_port.go
│ │ ├── rule_item_port_range.go
│ │ ├── rule_item_preferred_by.go
│ │ ├── rule_item_process_name.go
│ │ ├── rule_item_process_path.go
│ │ ├── rule_item_process_path_regex.go
│ │ ├── rule_item_protocol.go
│ │ ├── rule_item_query_type.go
│ │ ├── rule_item_rule_set.go
│ │ ├── rule_item_source_hostname.go
│ │ ├── rule_item_source_mac_address.go
│ │ ├── rule_item_user.go
│ │ ├── rule_item_user_id.go
│ │ ├── rule_item_wifi_bssid.go
│ │ ├── rule_item_wifi_ssid.go
│ │ ├── rule_network_interface_address.go
│ │ ├── rule_set.go
│ │ ├── rule_set_local.go
│ │ └── rule_set_remote.go
│ └── rule_conds.go
├── service/
│ ├── ccm/
│ │ ├── credential.go
│ │ ├── credential_darwin.go
│ │ ├── credential_other.go
│ │ ├── service.go
│ │ ├── service_usage.go
│ │ └── service_user.go
│ ├── derp/
│ │ └── service.go
│ ├── ocm/
│ │ ├── credential.go
│ │ ├── credential_darwin.go
│ │ ├── credential_other.go
│ │ ├── service.go
│ │ ├── service_usage.go
│ │ ├── service_user.go
│ │ └── service_websocket.go
│ ├── oomkiller/
│ │ ├── config.go
│ │ ├── service.go
│ │ ├── service_stub.go
│ │ └── service_timer.go
│ ├── resolved/
│ │ ├── resolve1.go
│ │ ├── service.go
│ │ ├── stub.go
│ │ └── transport.go
│ └── ssmapi/
│ ├── api.go
│ ├── cache.go
│ ├── server.go
│ ├── traffic.go
│ └── user.go
├── test/
│ ├── box_test.go
│ ├── brutal_test.go
│ ├── clash_darwin_test.go
│ ├── clash_other_test.go
│ ├── clash_test.go
│ ├── config/
│ │ ├── hysteria-client.json
│ │ ├── hysteria-server.json
│ │ ├── hysteria2-client.yml
│ │ ├── hysteria2-server.yml
│ │ ├── naive-nginx.conf
│ │ ├── naive-quic.json
│ │ ├── naive.json
│ │ ├── nginx.conf
│ │ ├── shadowsocksr.json
│ │ ├── trojan.json
│ │ ├── tuic-client.json
│ │ ├── tuic-server.json
│ │ ├── vless-server.json
│ │ ├── vless-tls-client.json
│ │ ├── vless-tls-server.json
│ │ ├── vmess-client.json
│ │ ├── vmess-grpc-client.json
│ │ ├── vmess-grpc-server.json
│ │ ├── vmess-mux-client.json
│ │ ├── vmess-server.json
│ │ ├── vmess-ws-client.json
│ │ ├── vmess-ws-server.json
│ │ └── wireguard.conf
│ ├── direct_test.go
│ ├── docker_test.go
│ ├── domain_inbound_test.go
│ ├── ech_test.go
│ ├── go.mod
│ ├── go.sum
│ ├── http_test.go
│ ├── hysteria2_test.go
│ ├── hysteria_test.go
│ ├── inbound_detour_test.go
│ ├── ktls_test.go
│ ├── mkcert.go
│ ├── mux_cool_test.go
│ ├── mux_test.go
│ ├── naive_self_test.go
│ ├── naive_test.go
│ ├── reality_test.go
│ ├── shadowsocks_legacy_test.go
│ ├── shadowsocks_test.go
│ ├── shadowtls_test.go
│ ├── socks_test.go
│ ├── ss_plugin_test.go
│ ├── tfo_test.go
│ ├── tls_test.go
│ ├── trojan_test.go
│ ├── tuic_test.go
│ ├── v2ray_api_test.go
│ ├── v2ray_grpc_test.go
│ ├── v2ray_httpupgrade_test.go
│ ├── v2ray_transport_test.go
│ ├── v2ray_ws_test.go
│ ├── vmess_test.go
│ └── wrapper_test.go
└── transport/
├── simple-obfs/
│ ├── README.md
│ ├── http.go
│ └── tls.go
├── sip003/
│ ├── args.go
│ ├── obfs.go
│ ├── plugin.go
│ └── v2ray.go
├── trojan/
│ ├── mux.go
│ ├── protocol.go
│ ├── protocol_wait.go
│ ├── service.go
│ └── service_wait.go
├── v2ray/
│ ├── grpc.go
│ ├── grpc_lite.go
│ ├── quic.go
│ └── transport.go
├── v2raygrpc/
│ ├── client.go
│ ├── conn.go
│ ├── credentials/
│ │ ├── credentials.go
│ │ ├── spiffe.go
│ │ ├── syscallconn.go
│ │ └── util.go
│ ├── custom_name.go
│ ├── server.go
│ ├── stream.pb.go
│ ├── stream.proto
│ ├── stream_grpc.pb.go
│ └── tls_credentials.go
├── v2raygrpclite/
│ ├── client.go
│ ├── conn.go
│ └── server.go
├── v2rayhttp/
│ ├── client.go
│ ├── conn.go
│ ├── force_close.go
│ ├── pool.go
│ └── server.go
├── v2rayhttpupgrade/
│ ├── client.go
│ └── server.go
├── v2rayquic/
│ ├── client.go
│ ├── init.go
│ ├── server.go
│ └── stream.go
├── v2raywebsocket/
│ ├── client.go
│ ├── conn.go
│ ├── server.go
│ └── writer.go
└── wireguard/
├── client_bind.go
├── device.go
├── device_nat.go
├── device_stack.go
├── device_stack_gonet.go
├── device_stack_stub.go
├── device_system.go
├── device_system_stack.go
├── endpoint.go
└── endpoint_options.go
================================================
FILE CONTENTS
================================================
================================================
FILE: .fpm_openwrt
================================================
-s dir
--name sing-box
--category net
--license GPL-3.0-or-later
--description "The universal proxy platform."
--url "https://sing-box.sagernet.org/"
--maintainer "nekohasekai <contact-git@sekai.icu>"
--no-deb-generate-changes
--config-files /etc/config/sing-box
--config-files /etc/sing-box/config.json
--depends ca-bundle
--depends kmod-inet-diag
--depends kmod-tun
--depends firewall4
--depends kmod-nft-queue
--before-remove release/config/openwrt.prerm
release/config/config.json=/etc/sing-box/config.json
release/config/openwrt.conf=/etc/config/sing-box
release/config/openwrt.init=/etc/init.d/sing-box
release/config/openwrt.keep=/lib/upgrade/keep.d/sing-box
release/completions/sing-box.bash=/usr/share/bash-completion/completions/sing-box.bash
release/completions/sing-box.fish=/usr/share/fish/vendor_completions.d/sing-box.fish
release/completions/sing-box.zsh=/usr/share/zsh/site-functions/_sing-box
LICENSE=/usr/share/licenses/sing-box/LICENSE
================================================
FILE: .fpm_pacman
================================================
-s dir
--name sing-box
--category net
--license GPL-3.0-or-later
--description "The universal proxy platform."
--url "https://sing-box.sagernet.org/"
--maintainer "nekohasekai <contact-git@sekai.icu>"
--config-files etc/sing-box/config.json
--after-install release/config/sing-box.postinst
release/config/config.json=/etc/sing-box/config.json
release/config/sing-box.service=/usr/lib/systemd/system/sing-box.service
release/config/sing-box@.service=/usr/lib/systemd/system/sing-box@.service
release/config/sing-box.sysusers=/usr/lib/sysusers.d/sing-box.conf
release/config/sing-box.rules=usr/share/polkit-1/rules.d/sing-box.rules
release/config/sing-box-split-dns.xml=/usr/share/dbus-1/system.d/sing-box-split-dns.conf
release/completions/sing-box.bash=/usr/share/bash-completion/completions/sing-box.bash
release/completions/sing-box.fish=/usr/share/fish/vendor_completions.d/sing-box.fish
release/completions/sing-box.zsh=/usr/share/zsh/site-functions/_sing-box
LICENSE=/usr/share/licenses/sing-box/LICENSE
================================================
FILE: .fpm_systemd
================================================
-s dir
--name sing-box
--category net
--license GPL-3.0-or-later
--description "The universal proxy platform."
--url "https://sing-box.sagernet.org/"
--maintainer "nekohasekai <contact-git@sekai.icu>"
--deb-field "Bug: https://github.com/SagerNet/sing-box/issues"
--no-deb-generate-changes
--config-files /etc/sing-box/config.json
--after-install release/config/sing-box.postinst
release/config/config.json=/etc/sing-box/config.json
release/config/sing-box.service=/usr/lib/systemd/system/sing-box.service
release/config/sing-box@.service=/usr/lib/systemd/system/sing-box@.service
release/config/sing-box.sysusers=/usr/lib/sysusers.d/sing-box.conf
release/config/sing-box.rules=usr/share/polkit-1/rules.d/sing-box.rules
release/config/sing-box-split-dns.xml=/usr/share/dbus-1/system.d/sing-box-split-dns.conf
release/completions/sing-box.bash=/usr/share/bash-completion/completions/sing-box.bash
release/completions/sing-box.fish=/usr/share/fish/vendor_completions.d/sing-box.fish
release/completions/sing-box.zsh=/usr/share/zsh/site-functions/_sing-box
LICENSE=/usr/share/licenses/sing-box/LICENSE
================================================
FILE: .github/CRONET_GO_VERSION
================================================
ea7cd33752aed62603775af3df946c1b83f4b0b3
================================================
FILE: .github/FUNDING.yml
================================================
github: nekohasekai
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.yml
================================================
name: Bug report
description: "Report sing-box bug"
body:
- type: dropdown
attributes:
label: Operating system
description: Operating system type
options:
- iOS
- macOS
- Apple tvOS
- Android
- Windows
- Linux
- Others
validations:
required: true
- type: input
attributes:
label: System version
description: Please provide the operating system version
validations:
required: true
- type: dropdown
attributes:
label: Installation type
description: Please provide the sing-box installation type
options:
- Original sing-box Command Line
- sing-box for iOS Graphical Client
- sing-box for macOS Graphical Client
- sing-box for Apple tvOS Graphical Client
- sing-box for Android Graphical Client
- Third-party graphical clients that advertise themselves as using sing-box (Windows)
- Third-party graphical clients that advertise themselves as using sing-box (Android)
- Others
validations:
required: true
- type: input
attributes:
description: Graphical client version
label: If you are using a graphical client, please provide the version of the client.
- type: textarea
attributes:
label: Version
description: If you are using the original command line program, please provide the output of the `sing-box version` command.
render: shell
- type: textarea
attributes:
label: Description
description: Please provide a detailed description of the error.
validations:
required: true
- type: textarea
attributes:
label: Reproduction
description: Please provide the steps to reproduce the error, including the configuration files and procedures that can locally (not dependent on the remote server) reproduce the error using the original command line program of sing-box.
validations:
required: true
- type: textarea
attributes:
label: Logs
description: |-
In addition, if you encounter a crash with the graphical client, please also provide crash logs.
For Apple platform clients, please check `Settings - View Service Log` for crash logs.
For the Android client, please check the `/sdcard/Android/data/io.nekohasekai.sfa/files/stderr.log` file for crash logs.
render: shell
- type: checkboxes
id: supporter
attributes:
label: Supporter
options:
- label: I am a [sponsor](https://github.com/sponsors/nekohasekai/)
- type: checkboxes
attributes:
label: Integrity requirements
description: |-
Please check all of the following options to prove that you have read and understood the requirements, otherwise this issue will be closed.
Sing-box is not a project aimed to please users who can't make any meaningful contributions and gain unethical influence. If you deceive here to deliberately waste the time of the developers, you will be permanently blocked.
options:
- label: I confirm that I have read the documentation, understand the meaning of all the configuration items I wrote, and did not pile up seemingly useful options or default values.
required: true
- label: I confirm that I have provided the server and client configuration files and process that can be reproduced locally, instead of a complicated client configuration file that has been stripped of sensitive data.
required: true
- label: I confirm that I have provided the simplest configuration that can be used to reproduce the error I reported, instead of depending on remote servers, TUN, graphical interface clients, or other closed-source software.
required: true
- label: I confirm that I have provided the complete configuration files and logs, rather than just providing parts I think are useful out of confidence in my own intelligence.
required: true
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report_zh.yml
================================================
name: 错误反馈
description: "提交 sing-box 漏洞"
body:
- type: dropdown
attributes:
label: 操作系统
description: 请提供操作系统类型
options:
- iOS
- macOS
- Apple tvOS
- Android
- Windows
- Linux
- 其他
validations:
required: true
- type: input
attributes:
label: 系统版本
description: 请提供操作系统版本
validations:
required: true
- type: dropdown
attributes:
label: 安装类型
description: 请提供该 sing-box 安装类型
options:
- sing-box 原始命令行程序
- sing-box for iOS 图形客户端程序
- sing-box for macOS 图形客户端程序
- sing-box for Apple tvOS 图形客户端程序
- sing-box for Android 图形客户端程序
- 宣传使用 sing-box 的第三方图形客户端程序 (Windows)
- 宣传使用 sing-box 的第三方图形客户端程序 (Android)
- 其他
validations:
required: true
- type: input
attributes:
description: 图形客户端版本
label: 如果您使用图形客户端程序,请提供该程序版本。
- type: textarea
attributes:
label: 版本
description: 如果您使用原始命令行程序,请提供 `sing-box version` 命令的输出。
render: shell
- type: textarea
attributes:
label: 描述
description: 请提供错误的详细描述。
validations:
required: true
- type: textarea
attributes:
label: 重现方式
description: 请提供重现错误的步骤,必须包括可以在本地(不依赖与远程服务器)使用 sing-box 原始命令行程序重现错误的配置文件与流程。
validations:
required: true
- type: textarea
attributes:
label: 日志
description: |-
此外,如果您遭遇图形界面应用程序崩溃,请附加提供崩溃日志。
对于 Apple 平台图形客户端程序,请检查 `Settings - View Service Log` 以导出崩溃日志。
对于 Android 图形客户端程序,请检查 `/sdcard/Android/data/io.nekohasekai.sfa/files/stderr.log` 文件以导出崩溃日志。
render: shell
- type: checkboxes
id: supporter
attributes:
label: 支持我们
options:
- label: 我已经 [赞助](https://github.com/sponsors/nekohasekai/)
- type: checkboxes
attributes:
label: 完整性要求
description: |-
请勾选以下所有选项以证明您已经阅读并理解了以下要求,否则该 issue 将被关闭。
sing-box 不是讨好无法作出任何意义上的贡献的最终用户并获取非道德影响力的项目,如果您在此处欺骗以故意浪费开发者的时间,您将被永久封锁。
options:
- label: 我保证阅读了文档,了解所有我编写的配置文件项的含义,而不是大量堆砌看似有用的选项或默认值。
required: true
- label: 我保证提供了可以在本地重现该问题的服务器、客户端配置文件与流程,而不是一个脱敏的复杂客户端配置文件。
required: true
- label: 我保证提供了可用于重现我报告的错误的最简配置,而不是依赖远程服务器、TUN、图形界面客户端或者其他闭源软件。
required: true
- label: 我保证提供了完整的配置文件与日志,而不是出于对自身智力的自信而仅提供了部分认为有用的部分。
required: true
================================================
FILE: .github/build_alpine_apk.sh
================================================
#!/usr/bin/env bash
set -e -o pipefail
ARCHITECTURE="$1"
VERSION="$2"
BINARY_PATH="$3"
OUTPUT_PATH="$4"
if [ -z "$ARCHITECTURE" ] || [ -z "$VERSION" ] || [ -z "$BINARY_PATH" ] || [ -z "$OUTPUT_PATH" ]; then
echo "Usage: $0 <architecture> <version> <binary_path> <output_path>"
exit 1
fi
PROJECT=$(cd "$(dirname "$0")/.."; pwd)
# Convert version to APK format:
# 1.13.0-beta.8 -> 1.13.0_beta8-r0
# 1.13.0-rc.3 -> 1.13.0_rc3-r0
# 1.13.0 -> 1.13.0-r0
APK_VERSION=$(echo "$VERSION" | sed -E 's/-([a-z]+)\.([0-9]+)/_\1\2/')
APK_VERSION="${APK_VERSION}-r0"
ROOT_DIR=$(mktemp -d)
trap 'rm -rf "$ROOT_DIR"' EXIT
# Binary
install -Dm755 "$BINARY_PATH" "$ROOT_DIR/usr/bin/sing-box"
# Config files
install -Dm644 "$PROJECT/release/config/config.json" "$ROOT_DIR/etc/sing-box/config.json"
install -Dm755 "$PROJECT/release/config/sing-box.initd" "$ROOT_DIR/etc/init.d/sing-box"
install -Dm644 "$PROJECT/release/config/sing-box.confd" "$ROOT_DIR/etc/conf.d/sing-box"
# Service files
install -Dm644 "$PROJECT/release/config/sing-box.service" "$ROOT_DIR/usr/lib/systemd/system/sing-box.service"
install -Dm644 "$PROJECT/release/config/sing-box@.service" "$ROOT_DIR/usr/lib/systemd/system/sing-box@.service"
# Completions
install -Dm644 "$PROJECT/release/completions/sing-box.bash" "$ROOT_DIR/usr/share/bash-completion/completions/sing-box.bash"
install -Dm644 "$PROJECT/release/completions/sing-box.fish" "$ROOT_DIR/usr/share/fish/vendor_completions.d/sing-box.fish"
install -Dm644 "$PROJECT/release/completions/sing-box.zsh" "$ROOT_DIR/usr/share/zsh/site-functions/_sing-box"
# License
install -Dm644 "$PROJECT/LICENSE" "$ROOT_DIR/usr/share/licenses/sing-box/LICENSE"
# APK metadata
PACKAGES_DIR="$ROOT_DIR/lib/apk/packages"
mkdir -p "$PACKAGES_DIR"
# .conffiles
cat > "$PACKAGES_DIR/.conffiles" <<'EOF'
/etc/conf.d/sing-box
/etc/init.d/sing-box
/etc/sing-box/config.json
EOF
# .conffiles_static (sha256 checksums)
while IFS= read -r conffile; do
sha256=$(sha256sum "$ROOT_DIR$conffile" | cut -d' ' -f1)
echo "$conffile $sha256"
done < "$PACKAGES_DIR/.conffiles" > "$PACKAGES_DIR/.conffiles_static"
# .list (all files, excluding lib/apk/packages/ metadata)
(cd "$ROOT_DIR" && find . -type f -o -type l) \
| sed 's|^\./|/|' \
| grep -v '^/lib/apk/packages/' \
| sort > "$PACKAGES_DIR/.list"
# Build APK
apk mkpkg \
--info "name:sing-box" \
--info "version:${APK_VERSION}" \
--info "description:The universal proxy platform." \
--info "arch:${ARCHITECTURE}" \
--info "license:GPL-3.0-or-later with name use or association addition" \
--info "origin:sing-box" \
--info "url:https://sing-box.sagernet.org/" \
--info "maintainer:nekohasekai <contact-git@sekai.icu>" \
--files "$ROOT_DIR" \
--output "$OUTPUT_PATH"
================================================
FILE: .github/build_openwrt_apk.sh
================================================
#!/usr/bin/env bash
set -e -o pipefail
ARCHITECTURE="$1"
VERSION="$2"
BINARY_PATH="$3"
OUTPUT_PATH="$4"
if [ -z "$ARCHITECTURE" ] || [ -z "$VERSION" ] || [ -z "$BINARY_PATH" ] || [ -z "$OUTPUT_PATH" ]; then
echo "Usage: $0 <architecture> <version> <binary_path> <output_path>"
exit 1
fi
PROJECT=$(cd "$(dirname "$0")/.."; pwd)
# Convert version to APK format:
# 1.13.0-beta.8 -> 1.13.0_beta8-r0
# 1.13.0-rc.3 -> 1.13.0_rc3-r0
# 1.13.0 -> 1.13.0-r0
APK_VERSION=$(echo "$VERSION" | sed -E 's/-([a-z]+)\.([0-9]+)/_\1\2/')
APK_VERSION="${APK_VERSION}-r0"
ROOT_DIR=$(mktemp -d)
trap 'rm -rf "$ROOT_DIR"' EXIT
# Binary
install -Dm755 "$BINARY_PATH" "$ROOT_DIR/usr/bin/sing-box"
# Config files
install -Dm644 "$PROJECT/release/config/config.json" "$ROOT_DIR/etc/sing-box/config.json"
install -Dm644 "$PROJECT/release/config/openwrt.conf" "$ROOT_DIR/etc/config/sing-box"
install -Dm755 "$PROJECT/release/config/openwrt.init" "$ROOT_DIR/etc/init.d/sing-box"
install -Dm644 "$PROJECT/release/config/openwrt.keep" "$ROOT_DIR/lib/upgrade/keep.d/sing-box"
# Completions
install -Dm644 "$PROJECT/release/completions/sing-box.bash" "$ROOT_DIR/usr/share/bash-completion/completions/sing-box.bash"
install -Dm644 "$PROJECT/release/completions/sing-box.fish" "$ROOT_DIR/usr/share/fish/vendor_completions.d/sing-box.fish"
install -Dm644 "$PROJECT/release/completions/sing-box.zsh" "$ROOT_DIR/usr/share/zsh/site-functions/_sing-box"
# License
install -Dm644 "$PROJECT/LICENSE" "$ROOT_DIR/usr/share/licenses/sing-box/LICENSE"
# APK metadata
PACKAGES_DIR="$ROOT_DIR/lib/apk/packages"
mkdir -p "$PACKAGES_DIR"
# .conffiles
cat > "$PACKAGES_DIR/.conffiles" <<'EOF'
/etc/config/sing-box
/etc/sing-box/config.json
EOF
# .conffiles_static (sha256 checksums)
while IFS= read -r conffile; do
sha256=$(sha256sum "$ROOT_DIR$conffile" | cut -d' ' -f1)
echo "$conffile $sha256"
done < "$PACKAGES_DIR/.conffiles" > "$PACKAGES_DIR/.conffiles_static"
# .list (all files, excluding lib/apk/packages/ metadata)
(cd "$ROOT_DIR" && find . -type f -o -type l) \
| sed 's|^\./|/|' \
| grep -v '^/lib/apk/packages/' \
| sort > "$PACKAGES_DIR/.list"
# Build APK
apk mkpkg \
--info "name:sing-box" \
--info "version:${APK_VERSION}" \
--info "description:The universal proxy platform." \
--info "arch:${ARCHITECTURE}" \
--info "license:GPL-3.0-or-later" \
--info "origin:sing-box" \
--info "url:https://sing-box.sagernet.org/" \
--info "maintainer:nekohasekai <contact-git@sekai.icu>" \
--info "depends:ca-bundle kmod-inet-diag kmod-tun firewall4 kmod-nft-queue" \
--info "provider-priority:100" \
--script "pre-deinstall:${PROJECT}/release/config/openwrt.prerm" \
--files "$ROOT_DIR" \
--output "$OUTPUT_PATH"
================================================
FILE: .github/deb2ipk.sh
================================================
#!/usr/bin/env bash
# mod from https://gist.github.com/pldubouilh/c5703052986bfdd404005951dee54683
set -e -o pipefail
PROJECT=$(dirname "$0")/../..
TMP_PATH=`mktemp -d`
cp $2 $TMP_PATH
pushd $TMP_PATH
DEB_NAME=`ls *.deb`
ar x $DEB_NAME
mkdir control
pushd control
tar xf ../control.tar.gz
rm md5sums
sed "s/Architecture:\\ \w*/Architecture:\\ $1/g" ./control -i
cat control
tar czf ../control.tar.gz ./*
popd
DEB_NAME=${DEB_NAME%.deb}
tar czf $DEB_NAME.ipk control.tar.gz data.tar.gz debian-binary
popd
cp $TMP_PATH/$DEB_NAME.ipk $3
rm -r $TMP_PATH
================================================
FILE: .github/renovate.json
================================================
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"commitMessagePrefix": "[dependencies]",
"extends": [
"config:base",
":disableRateLimiting"
],
"baseBranches": [
"unstable"
],
"golang": {
"enabled": false
},
"packageRules": [
{
"matchManagers": [
"github-actions"
],
"groupName": "github-actions"
},
{
"matchManagers": [
"dockerfile"
],
"groupName": "Dockerfile"
}
]
}
================================================
FILE: .github/setup_go_for_macos1013.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
VERSION="1.25.8"
PATCH_COMMITS=(
"afe69d3cec1c6dcf0f1797b20546795730850070"
"1ed289b0cf87dc5aae9c6fe1aa5f200a83412938"
)
CURL_ARGS=(
-fL
--silent
--show-error
)
if [[ -n "${GITHUB_TOKEN:-}" ]]; then
CURL_ARGS+=(-H "Authorization: Bearer ${GITHUB_TOKEN}")
fi
mkdir -p "$HOME/go"
cd "$HOME/go"
wget "https://dl.google.com/go/go${VERSION}.darwin-arm64.tar.gz"
tar -xzf "go${VERSION}.darwin-arm64.tar.gz"
#cp -a go go_bootstrap
mv go go_osx
cd go_osx
# these patch URLs only work on golang1.25.x
# that means after golang1.26 release it must be changed
# see: https://github.com/SagerNet/go/commits/release-branch.go1.25/
# revert:
# 33d3f603c1: "cmd/link/internal/ld: use 12.0.0 OS/SDK versions for macOS linking"
# 937368f84e: "crypto/x509: change how we retrieve chains on darwin"
for patch_commit in "${PATCH_COMMITS[@]}"; do
curl "${CURL_ARGS[@]}" "https://github.com/SagerNet/go/commit/${patch_commit}.diff" | patch --verbose -p 1
done
# Rebuild is not needed: we build with CGO_ENABLED=1, so Apple's external
# linker handles LC_BUILD_VERSION via MACOSX_DEPLOYMENT_TARGET, and the
# stdlib (crypto/x509) is compiled from patched src automatically.
#cd src
#GOROOT_BOOTSTRAP="$HOME/go/go_bootstrap" ./make.bash
#cd ../..
#rm -rf go_bootstrap "go${VERSION}.darwin-arm64.tar.gz"
================================================
FILE: .github/setup_go_for_windows7.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
VERSION="1.25.8"
PATCH_COMMITS=(
"466f6c7a29bc098b0d4c987b803c779222894a11"
"1bdabae205052afe1dadb2ad6f1ba612cdbc532a"
"a90777dcf692dd2168577853ba743b4338721b06"
"f6bddda4e8ff58a957462a1a09562924d5f3d05c"
"bed309eff415bcb3c77dd4bc3277b682b89a388d"
"34b899c2fb39b092db4fa67c4417e41dc046be4b"
)
CURL_ARGS=(
-fL
--silent
--show-error
)
if [[ -n "${GITHUB_TOKEN:-}" ]]; then
CURL_ARGS+=(-H "Authorization: Bearer ${GITHUB_TOKEN}")
fi
mkdir -p "$HOME/go"
cd "$HOME/go"
wget "https://dl.google.com/go/go${VERSION}.linux-amd64.tar.gz"
tar -xzf "go${VERSION}.linux-amd64.tar.gz"
mv go go_win7
cd go_win7
# modify from https://github.com/restic/restic/issues/4636#issuecomment-1896455557
# these patch URLs only work on golang1.25.x
# that means after golang1.26 release it must be changed
# see: https://github.com/MetaCubeX/go/commits/release-branch.go1.25/
# revert:
# 693def151adff1af707d82d28f55dba81ceb08e1: "crypto/rand,runtime: switch RtlGenRandom for ProcessPrng"
# 7c1157f9544922e96945196b47b95664b1e39108: "net: remove sysSocket fallback for Windows 7"
# 48042aa09c2f878c4faa576948b07fe625c4707a: "syscall: remove Windows 7 console handle workaround"
# a17d959debdb04cd550016a3501dd09d50cd62e7: "runtime: always use LoadLibraryEx to load system libraries"
# fixes:
# bed309eff415bcb3c77dd4bc3277b682b89a388d: "Fix os.RemoveAll not working on Windows7"
# 34b899c2fb39b092db4fa67c4417e41dc046be4b: "Revert \"os: remove 5ms sleep on Windows in (*Process).Wait\""
for patch_commit in "${PATCH_COMMITS[@]}"; do
curl "${CURL_ARGS[@]}" "https://github.com/MetaCubeX/go/commit/${patch_commit}.diff" | patch --verbose -p 1
done
================================================
FILE: .github/update_clients.sh
================================================
#!/usr/bin/env bash
PROJECTS=$(dirname "$0")/../..
function updateClient() {
pushd clients/$1
git fetch
git reset FETCH_HEAD --hard
popd
git add clients/$1
}
updateClient "apple"
updateClient "android"
================================================
FILE: .github/update_cronet.sh
================================================
#!/usr/bin/env bash
set -e -o pipefail
SCRIPT_DIR=$(dirname "$0")
PROJECTS=$SCRIPT_DIR/../..
git -C $PROJECTS/cronet-go fetch origin main
git -C $PROJECTS/cronet-go fetch origin go
go get -x github.com/sagernet/cronet-go/all@$(git -C $PROJECTS/cronet-go rev-parse origin/go)
go get -x github.com/sagernet/cronet-go@$(git -C $PROJECTS/cronet-go rev-parse origin/go)
go mod tidy
git -C $PROJECTS/cronet-go rev-parse origin/go > "$SCRIPT_DIR/CRONET_GO_VERSION"
================================================
FILE: .github/update_cronet_dev.sh
================================================
#!/usr/bin/env bash
set -e -o pipefail
SCRIPT_DIR=$(dirname "$0")
PROJECTS=$SCRIPT_DIR/../..
git -C $PROJECTS/cronet-go fetch origin dev
git -C $PROJECTS/cronet-go fetch origin go_dev
go get -x github.com/sagernet/cronet-go/all@$(git -C $PROJECTS/cronet-go rev-parse origin/go_dev)
go get -x github.com/sagernet/cronet-go@$(git -C $PROJECTS/cronet-go rev-parse origin/go_dev)
go mod tidy
git -C $PROJECTS/cronet-go rev-parse origin/dev > "$SCRIPT_DIR/CRONET_GO_VERSION"
================================================
FILE: .github/update_dependencies.sh
================================================
#!/usr/bin/env bash
PROJECTS=$(dirname "$0")/../..
go get -x github.com/sagernet/$1@$(git -C $PROJECTS/$1 rev-parse HEAD)
go mod tidy
================================================
FILE: .github/workflows/build.yml
================================================
name: Build
on:
workflow_dispatch:
inputs:
version:
description: "Version name"
required: true
type: string
build:
description: "Build type"
required: true
type: choice
default: "All"
options:
- All
- Binary
- Android
- Apple
- app-store
- iOS
- macOS
- tvOS
- macOS-standalone
- publish-android
push:
branches:
- stable
- testing
- unstable
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}-${{ inputs.build }}
cancel-in-progress: true
jobs:
calculate_version:
name: Calculate version
runs-on: ubuntu-latest
outputs:
version: ${{ steps.outputs.outputs.version }}
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
with:
fetch-depth: 0
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ~1.25.8
- name: Check input version
if: github.event_name == 'workflow_dispatch'
run: |-
echo "version=${{ inputs.version }}"
echo "version=${{ inputs.version }}" >> "$GITHUB_ENV"
- name: Calculate version
if: github.event_name != 'workflow_dispatch'
run: |-
go run -v ./cmd/internal/read_tag --ci --nightly
- name: Set outputs
id: outputs
run: |-
echo "version=$version" >> "$GITHUB_OUTPUT"
build:
name: Build binary
if: github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Binary'
runs-on: ubuntu-latest
needs:
- calculate_version
strategy:
matrix:
include:
- { os: linux, arch: amd64, variant: purego, naive: true }
- { os: linux, arch: amd64, variant: glibc, naive: true }
- { os: linux, arch: amd64, variant: musl, naive: true, debian: amd64, rpm: x86_64, pacman: x86_64, alpine: x86_64, openwrt: "x86_64" }
- { os: linux, arch: arm64, variant: purego, naive: true }
- { os: linux, arch: arm64, variant: glibc, naive: true }
- { os: linux, arch: arm64, variant: musl, naive: true, debian: arm64, rpm: aarch64, pacman: aarch64, alpine: aarch64, openwrt: "aarch64_cortex-a53 aarch64_cortex-a72 aarch64_cortex-a76 aarch64_generic" }
- { os: linux, arch: "386", go386: sse2 }
- { os: linux, arch: "386", variant: glibc, naive: true, go386: sse2 }
- { os: linux, arch: "386", variant: musl, naive: true, go386: sse2, debian: i386, rpm: i386, alpine: x86, openwrt: "i386_pentium4" }
- { os: linux, arch: arm, goarm: "7" }
- { os: linux, arch: arm, variant: glibc, naive: true, goarm: "7" }
- { os: linux, arch: arm, variant: musl, naive: true, goarm: "7", debian: armhf, rpm: armv7hl, pacman: armv7hl, alpine: armv7, openwrt: "arm_cortex-a5_vfpv4 arm_cortex-a7_neon-vfpv4 arm_cortex-a7_vfpv4 arm_cortex-a8_vfpv3 arm_cortex-a9_neon arm_cortex-a9_vfpv3-d16 arm_cortex-a15_neon-vfpv4" }
- { os: linux, arch: mipsle, gomips: hardfloat, naive: true, variant: glibc }
- { os: linux, arch: mipsle, gomips: softfloat, naive: true, variant: musl, debian: mipsel, rpm: mipsel, openwrt: "mipsel_24kc mipsel_74kc mipsel_mips32" }
- { os: linux, arch: mips64le, gomips: hardfloat, naive: true, variant: glibc, debian: mips64el, rpm: mips64el }
- { os: linux, arch: riscv64, naive: true, variant: glibc }
- { os: linux, arch: riscv64, naive: true, variant: musl, debian: riscv64, rpm: riscv64, alpine: riscv64, openwrt: "riscv64_generic" }
- { os: linux, arch: loong64, naive: true, variant: glibc }
- { os: linux, arch: loong64, naive: true, variant: musl, debian: loongarch64, rpm: loongarch64, alpine: loongarch64, openwrt: "loongarch64_generic" }
- { os: linux, arch: "386", go386: softfloat, openwrt: "i386_pentium-mmx" }
- { os: linux, arch: arm, goarm: "5", openwrt: "arm_arm926ej-s arm_cortex-a7 arm_cortex-a9 arm_fa526 arm_xscale" }
- { os: linux, arch: arm, goarm: "6", debian: armel, rpm: armv6hl, openwrt: "arm_arm1176jzf-s_vfp" }
- { os: linux, arch: mips, gomips: softfloat, openwrt: "mips_24kc mips_4kec mips_mips32" }
- { os: linux, arch: mipsle, gomips: hardfloat, openwrt: "mipsel_24kc_24kf" }
- { os: linux, arch: mipsle, gomips: softfloat }
- { os: linux, arch: mips64, gomips: softfloat, openwrt: "mips64_mips64r2 mips64_octeonplus" }
- { os: linux, arch: mips64le, gomips: hardfloat }
- { os: linux, arch: mips64le, gomips: softfloat, openwrt: "mips64el_mips64r2" }
- { os: linux, arch: s390x, debian: s390x, rpm: s390x }
- { os: linux, arch: ppc64le, debian: ppc64el, rpm: ppc64le }
- { os: linux, arch: riscv64 }
- { os: linux, arch: loong64 }
- { os: windows, arch: amd64, legacy_win7: true, legacy_name: "windows-7" }
- { os: windows, arch: "386", legacy_win7: true, legacy_name: "windows-7" }
- { os: android, arch: arm64, ndk: "aarch64-linux-android23" }
- { os: android, arch: arm, ndk: "armv7a-linux-androideabi23" }
- { os: android, arch: amd64, ndk: "x86_64-linux-android23" }
- { os: android, arch: "386", ndk: "i686-linux-android23" }
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
with:
fetch-depth: 0
- name: Setup Go
if: ${{ ! matrix.legacy_win7 }}
uses: actions/setup-go@v5
with:
go-version: ~1.25.8
- name: Cache Go for Windows 7
if: matrix.legacy_win7
id: cache-go-for-windows7
uses: actions/cache@v4
with:
path: |
~/go/go_win7
key: go_win7_1258
- name: Setup Go for Windows 7
if: matrix.legacy_win7 && steps.cache-go-for-windows7.outputs.cache-hit != 'true'
env:
GITHUB_TOKEN: ${{ github.token }}
run: |-
.github/setup_go_for_windows7.sh
- name: Setup Go for Windows 7
if: matrix.legacy_win7
run: |-
echo "PATH=$HOME/go/go_win7/bin:$PATH" >> $GITHUB_ENV
echo "GOROOT=$HOME/go/go_win7" >> $GITHUB_ENV
- name: Setup Android NDK
if: matrix.os == 'android'
uses: nttld/setup-ndk@v1
with:
ndk-version: r28
local-cache: true
- name: Clone cronet-go
if: matrix.naive
run: |
set -xeuo pipefail
CRONET_GO_VERSION=$(cat .github/CRONET_GO_VERSION)
git init ~/cronet-go
git -C ~/cronet-go remote add origin https://github.com/sagernet/cronet-go.git
git -C ~/cronet-go fetch --depth=1 origin "$CRONET_GO_VERSION"
git -C ~/cronet-go checkout FETCH_HEAD
git -C ~/cronet-go submodule update --init --recursive --depth=1
- name: Regenerate Debian keyring
if: matrix.naive
run: |
set -xeuo pipefail
rm -f ~/cronet-go/naiveproxy/src/build/linux/sysroot_scripts/keyring.gpg
cd ~/cronet-go
GPG_TTY=/dev/null ./naiveproxy/src/build/linux/sysroot_scripts/generate_keyring.sh
- name: Cache Chromium toolchain
if: matrix.naive
id: cache-chromium-toolchain
uses: actions/cache@v4
with:
path: |
~/cronet-go/naiveproxy/src/third_party/llvm-build/
~/cronet-go/naiveproxy/src/gn/out/
~/cronet-go/naiveproxy/src/chrome/build/pgo_profiles/
~/cronet-go/naiveproxy/src/out/sysroot-build/
key: chromium-toolchain-${{ matrix.arch }}-${{ matrix.variant }}-${{ hashFiles('.github/CRONET_GO_VERSION') }}
- name: Download Chromium toolchain
if: matrix.naive
run: |
set -xeuo pipefail
cd ~/cronet-go
if [[ "${{ matrix.variant }}" == "musl" ]]; then
go run ./cmd/build-naive --target=linux/${{ matrix.arch }} --libc=musl download-toolchain
else
go run ./cmd/build-naive --target=linux/${{ matrix.arch }} download-toolchain
fi
- name: Set Chromium toolchain environment
if: matrix.naive
run: |
set -xeuo pipefail
cd ~/cronet-go
if [[ "${{ matrix.variant }}" == "musl" ]]; then
go run ./cmd/build-naive --target=linux/${{ matrix.arch }} --libc=musl env >> $GITHUB_ENV
else
go run ./cmd/build-naive --target=linux/${{ matrix.arch }} env >> $GITHUB_ENV
fi
- name: Set tag
run: |-
git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
git tag v${{ needs.calculate_version.outputs.version }} -f
- name: Set build tags
run: |
set -xeuo pipefail
if [[ "${{ matrix.naive }}" == "true" ]]; then
TAGS=$(cat release/DEFAULT_BUILD_TAGS)
else
TAGS=$(cat release/DEFAULT_BUILD_TAGS_OTHERS)
fi
if [[ "${{ matrix.variant }}" == "purego" ]]; then
TAGS="${TAGS},with_purego"
elif [[ "${{ matrix.variant }}" == "musl" ]]; then
TAGS="${TAGS},with_musl"
fi
echo "BUILD_TAGS=${TAGS}" >> "${GITHUB_ENV}"
- name: Set shared ldflags
run: |
echo "LDFLAGS_SHARED=$(cat release/LDFLAGS)" >> "${GITHUB_ENV}"
- name: Build (purego)
if: matrix.variant == 'purego'
run: |
set -xeuo pipefail
mkdir -p dist
go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \
-ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }}' ${LDFLAGS_SHARED} -s -w -buildid=" \
./cmd/sing-box
env:
CGO_ENABLED: "0"
GOOS: ${{ matrix.os }}
GOARCH: ${{ matrix.arch }}
GO386: ${{ matrix.go386 }}
GOARM: ${{ matrix.goarm }}
GOMIPS: ${{ matrix.gomips }}
GOMIPS64: ${{ matrix.gomips }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Extract libcronet.so
if: matrix.variant == 'purego' && matrix.naive
run: |
cd ~/cronet-go
CGO_ENABLED=0 go run -v ./cmd/build-naive extract-lib --target ${{ matrix.os }}/${{ matrix.arch }} -o $GITHUB_WORKSPACE/dist
- name: Build (glibc)
if: matrix.variant == 'glibc'
run: |
set -xeuo pipefail
mkdir -p dist
go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \
-ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }}' ${LDFLAGS_SHARED} -s -w -buildid=" \
./cmd/sing-box
env:
CGO_ENABLED: "1"
GOOS: linux
GOARCH: ${{ matrix.arch }}
GO386: ${{ matrix.go386 }}
GOARM: ${{ matrix.goarm }}
GOMIPS: ${{ matrix.gomips }}
GOMIPS64: ${{ matrix.gomips }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build (musl)
if: matrix.variant == 'musl'
run: |
set -xeuo pipefail
mkdir -p dist
go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \
-ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }}' ${LDFLAGS_SHARED} -s -w -buildid=" \
./cmd/sing-box
env:
CGO_ENABLED: "1"
GOOS: linux
GOARCH: ${{ matrix.arch }}
GO386: ${{ matrix.go386 }}
GOARM: ${{ matrix.goarm }}
GOMIPS: ${{ matrix.gomips }}
GOMIPS64: ${{ matrix.gomips }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build (non-variant)
if: matrix.os != 'android' && matrix.variant == ''
run: |
set -xeuo pipefail
mkdir -p dist
go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \
-ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }}' ${LDFLAGS_SHARED} -s -w -buildid=" \
./cmd/sing-box
env:
CGO_ENABLED: "0"
GOOS: ${{ matrix.os }}
GOARCH: ${{ matrix.arch }}
GO386: ${{ matrix.go386 }}
GOARM: ${{ matrix.goarm }}
GOMIPS: ${{ matrix.gomips }}
GOMIPS64: ${{ matrix.gomips }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build Android
if: matrix.os == 'android'
run: |
set -xeuo pipefail
go install -v ./cmd/internal/build
export CC='${{ matrix.ndk }}-clang'
export CXX="${CC}++"
mkdir -p dist
GOOS=$BUILD_GOOS GOARCH=$BUILD_GOARCH build go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \
-ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }}' ${LDFLAGS_SHARED} -s -w -buildid=" \
./cmd/sing-box
env:
CGO_ENABLED: "1"
BUILD_GOOS: ${{ matrix.os }}
BUILD_GOARCH: ${{ matrix.arch }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Set name
run: |-
DIR_NAME="sing-box-${{ needs.calculate_version.outputs.version }}-${{ matrix.os }}-${{ matrix.arch }}"
if [[ -n "${{ matrix.goarm }}" ]]; then
DIR_NAME="${DIR_NAME}v${{ matrix.goarm }}"
elif [[ -n "${{ matrix.go386 }}" && "${{ matrix.go386 }}" != 'sse2' ]]; then
DIR_NAME="${DIR_NAME}-${{ matrix.go386 }}"
elif [[ -n "${{ matrix.gomips }}" && "${{ matrix.gomips }}" != 'hardfloat' ]]; then
DIR_NAME="${DIR_NAME}-${{ matrix.gomips }}"
elif [[ -n "${{ matrix.legacy_name }}" ]]; then
DIR_NAME="${DIR_NAME}-legacy-${{ matrix.legacy_name }}"
fi
if [[ "${{ matrix.variant }}" == "glibc" ]]; then
DIR_NAME="${DIR_NAME}-glibc"
elif [[ "${{ matrix.variant }}" == "musl" ]]; then
DIR_NAME="${DIR_NAME}-musl"
fi
echo "DIR_NAME=${DIR_NAME}" >> "${GITHUB_ENV}"
PKG_VERSION="${{ needs.calculate_version.outputs.version }}"
PKG_VERSION="${PKG_VERSION//-/\~}"
echo "PKG_VERSION=${PKG_VERSION}" >> "${GITHUB_ENV}"
- name: Package DEB
if: matrix.debian != ''
run: |
set -xeuo pipefail
sudo gem install fpm
sudo apt-get update
sudo apt-get install -y debsigs
cp .fpm_systemd .fpm
fpm -t deb \
-v "$PKG_VERSION" \
-p "dist/sing-box_${{ needs.calculate_version.outputs.version }}_${{ matrix.os }}_${{ matrix.debian }}.deb" \
--architecture ${{ matrix.debian }} \
dist/sing-box=/usr/bin/sing-box
curl -Lo '/tmp/debsigs.diff' 'https://gitlab.com/debsigs/debsigs/-/commit/160138f5de1ec110376d3c807b60a37388bc7c90.diff'
sudo patch /usr/bin/debsigs < '/tmp/debsigs.diff'
rm -rf $HOME/.gnupg
gpg --pinentry-mode loopback --passphrase "${{ secrets.GPG_PASSPHRASE }}" --import <<EOF
${{ secrets.GPG_KEY }}
EOF
debsigs --sign=origin -k ${{ secrets.GPG_KEY_ID }} --gpgopts '--pinentry-mode loopback --passphrase "${{ secrets.GPG_PASSPHRASE }}"' dist/*.deb
- name: Package RPM
if: matrix.rpm != ''
run: |-
set -xeuo pipefail
sudo gem install fpm
cp .fpm_systemd .fpm
fpm -t rpm \
-v "$PKG_VERSION" \
-p "dist/sing-box_${{ needs.calculate_version.outputs.version }}_${{ matrix.os }}_${{ matrix.rpm }}.rpm" \
--architecture ${{ matrix.rpm }} \
dist/sing-box=/usr/bin/sing-box
cat > $HOME/.rpmmacros <<EOF
%_gpg_name ${{ secrets.GPG_KEY_ID }}
%_gpg_sign_cmd_extra_args --pinentry-mode loopback --passphrase ${{ secrets.GPG_PASSPHRASE }}
EOF
gpg --pinentry-mode loopback --passphrase "${{ secrets.GPG_PASSPHRASE }}" --import <<EOF
${{ secrets.GPG_KEY }}
EOF
rpmsign --addsign dist/*.rpm
- name: Package Pacman
if: matrix.pacman != ''
run: |-
set -xeuo pipefail
sudo gem install fpm
sudo apt-get update
sudo apt-get install -y libarchive-tools
cp .fpm_pacman .fpm
fpm -t pacman \
-v "$PKG_VERSION" \
-p "dist/sing-box_${{ needs.calculate_version.outputs.version }}_${{ matrix.os }}_${{ matrix.pacman }}.pkg.tar.zst" \
--architecture ${{ matrix.pacman }} \
dist/sing-box=/usr/bin/sing-box
- name: Package OpenWrt
if: matrix.openwrt != ''
run: |-
set -xeuo pipefail
sudo gem install fpm
cp .fpm_openwrt .fpm
fpm -t deb \
-v "$PKG_VERSION" \
-p "dist/openwrt.deb" \
--architecture all \
dist/sing-box=/usr/bin/sing-box
for architecture in ${{ matrix.openwrt }}; do
.github/deb2ipk.sh "$architecture" "dist/openwrt.deb" "dist/sing-box_${{ needs.calculate_version.outputs.version }}_openwrt_${architecture}.ipk"
done
rm "dist/openwrt.deb"
- name: Install apk-tools
if: matrix.openwrt != '' || matrix.alpine != ''
run: |-
docker run --rm -v /usr/local/bin:/mnt alpine:edge sh -c "apk add --no-cache apk-tools-static && cp /sbin/apk.static /mnt/apk && chmod +x /mnt/apk"
- name: Package OpenWrt APK
if: matrix.openwrt != ''
run: |-
set -xeuo pipefail
for architecture in ${{ matrix.openwrt }}; do
.github/build_openwrt_apk.sh \
"$architecture" \
"${{ needs.calculate_version.outputs.version }}" \
"dist/sing-box" \
"dist/sing-box_${{ needs.calculate_version.outputs.version }}_openwrt_${architecture}.apk"
done
- name: Package Alpine APK
if: matrix.alpine != ''
run: |-
set -xeuo pipefail
.github/build_alpine_apk.sh \
"${{ matrix.alpine }}" \
"${{ needs.calculate_version.outputs.version }}" \
"dist/sing-box" \
"dist/sing-box_${{ needs.calculate_version.outputs.version }}_linux_${{ matrix.alpine }}.apk"
- name: Archive
run: |
set -xeuo pipefail
cd dist
mkdir -p "${DIR_NAME}"
cp ../LICENSE "${DIR_NAME}"
if [ '${{ matrix.os }}' = 'windows' ]; then
cp sing-box "${DIR_NAME}/sing-box.exe"
zip -r "${DIR_NAME}.zip" "${DIR_NAME}"
else
cp sing-box "${DIR_NAME}"
if [ -f libcronet.so ]; then
cp libcronet.so "${DIR_NAME}"
fi
tar -czvf "${DIR_NAME}.tar.gz" "${DIR_NAME}"
fi
rm -r "${DIR_NAME}"
- name: Cleanup
run: rm -f dist/sing-box dist/libcronet.so
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: binary-${{ matrix.os }}_${{ matrix.arch }}${{ matrix.goarm && format('v{0}', matrix.goarm) }}${{ matrix.go386 && format('_{0}', matrix.go386) }}${{ matrix.gomips && format('_{0}', matrix.gomips) }}${{ matrix.legacy_name && format('-legacy-{0}', matrix.legacy_name) }}${{ matrix.variant && format('-{0}', matrix.variant) }}
path: "dist"
build_darwin:
name: Build Darwin binaries
if: github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Binary'
runs-on: macos-latest
needs:
- calculate_version
strategy:
matrix:
include:
- { arch: amd64 }
- { arch: arm64 }
- { arch: amd64, legacy_osx: true, legacy_name: "macos-10.13" }
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
with:
fetch-depth: 0
- name: Setup Go
if: ${{ ! matrix.legacy_osx }}
uses: actions/setup-go@v5
with:
go-version: ^1.25.3
- name: Cache Go for macOS 10.13
if: matrix.legacy_osx
id: cache-go-for-macos1013
uses: actions/cache@v4
with:
path: |
~/go/go_osx
key: go_osx_1258
- name: Setup Go for macOS 10.13
if: matrix.legacy_osx && steps.cache-go-for-macos1013.outputs.cache-hit != 'true'
env:
GITHUB_TOKEN: ${{ github.token }}
run: |-
.github/setup_go_for_macos1013.sh
- name: Setup Go for macOS 10.13
if: matrix.legacy_osx
run: |-
echo "PATH=$HOME/go/go_osx/bin:$PATH" >> $GITHUB_ENV
echo "GOROOT=$HOME/go/go_osx" >> $GITHUB_ENV
- name: Set tag
run: |-
git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
git tag v${{ needs.calculate_version.outputs.version }} -f
- name: Set build tags
run: |
set -xeuo pipefail
if [[ "${{ matrix.legacy_osx }}" != "true" ]]; then
TAGS=$(cat release/DEFAULT_BUILD_TAGS)
else
TAGS=$(cat release/DEFAULT_BUILD_TAGS_OTHERS)
fi
echo "BUILD_TAGS=${TAGS}" >> "${GITHUB_ENV}"
- name: Set shared ldflags
run: |
echo "LDFLAGS_SHARED=$(cat release/LDFLAGS)" >> "${GITHUB_ENV}"
- name: Build
run: |
set -xeuo pipefail
mkdir -p dist
go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \
-ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }}' ${LDFLAGS_SHARED} -s -w -buildid=" \
./cmd/sing-box
env:
CGO_ENABLED: "1"
GOOS: darwin
GOARCH: ${{ matrix.arch }}
MACOSX_DEPLOYMENT_TARGET: ${{ matrix.legacy_osx && '10.13' || '' }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Set name
run: |-
DIR_NAME="sing-box-${{ needs.calculate_version.outputs.version }}-darwin-${{ matrix.arch }}"
if [[ -n "${{ matrix.legacy_name }}" ]]; then
DIR_NAME="${DIR_NAME}-legacy-${{ matrix.legacy_name }}"
fi
echo "DIR_NAME=${DIR_NAME}" >> "${GITHUB_ENV}"
- name: Archive
run: |
set -xeuo pipefail
cd dist
mkdir -p "${DIR_NAME}"
cp ../LICENSE "${DIR_NAME}"
cp sing-box "${DIR_NAME}"
tar -czvf "${DIR_NAME}.tar.gz" "${DIR_NAME}"
rm -r "${DIR_NAME}"
- name: Cleanup
run: rm dist/sing-box
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: binary-darwin_${{ matrix.arch }}${{ matrix.legacy_name && format('-legacy-{0}', matrix.legacy_name) }}
path: "dist"
build_windows:
name: Build Windows binaries
if: github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Binary'
runs-on: windows-latest
needs:
- calculate_version
strategy:
matrix:
include:
- { arch: amd64, naive: true }
- { arch: "386" }
- { arch: arm64, naive: true }
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
with:
fetch-depth: 0
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ^1.25.4
- name: Set tag
run: |-
git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$env:GITHUB_ENV"
git tag v${{ needs.calculate_version.outputs.version }} -f
- name: Build
if: matrix.naive
run: |
$TAGS = Get-Content release/DEFAULT_BUILD_TAGS_WINDOWS
$LDFLAGS_SHARED = Get-Content release/LDFLAGS
mkdir -p dist
go build -v -trimpath -o dist/sing-box.exe -tags "$TAGS" `
-ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }}' $LDFLAGS_SHARED -s -w -buildid=" `
./cmd/sing-box
env:
CGO_ENABLED: "0"
GOOS: windows
GOARCH: ${{ matrix.arch }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build
if: ${{ !matrix.naive }}
run: |
$TAGS = Get-Content release/DEFAULT_BUILD_TAGS_OTHERS
$LDFLAGS_SHARED = Get-Content release/LDFLAGS
mkdir -p dist
go build -v -trimpath -o dist/sing-box.exe -tags "$TAGS" `
-ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }}' $LDFLAGS_SHARED -s -w -buildid=" `
./cmd/sing-box
env:
CGO_ENABLED: "0"
GOOS: windows
GOARCH: ${{ matrix.arch }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Extract libcronet.dll
if: matrix.naive
run: |
$CRONET_GO_VERSION = Get-Content .github/CRONET_GO_VERSION
$env:CGO_ENABLED = "0"
go run -v "github.com/sagernet/cronet-go/cmd/build-naive@$CRONET_GO_VERSION" extract-lib --target windows/${{ matrix.arch }} -o dist
- name: Archive
if: matrix.naive
run: |
$DIR_NAME = "sing-box-${{ needs.calculate_version.outputs.version }}-windows-${{ matrix.arch }}"
mkdir "dist/$DIR_NAME"
Copy-Item LICENSE "dist/$DIR_NAME"
Copy-Item "dist/sing-box.exe" "dist/$DIR_NAME"
Copy-Item "dist/libcronet.dll" "dist/$DIR_NAME"
Compress-Archive -Path "dist/$DIR_NAME" -DestinationPath "dist/$DIR_NAME.zip"
Remove-Item -Recurse "dist/$DIR_NAME"
- name: Archive
if: ${{ !matrix.naive }}
run: |
$DIR_NAME = "sing-box-${{ needs.calculate_version.outputs.version }}-windows-${{ matrix.arch }}"
mkdir "dist/$DIR_NAME"
Copy-Item LICENSE "dist/$DIR_NAME"
Copy-Item "dist/sing-box.exe" "dist/$DIR_NAME"
Compress-Archive -Path "dist/$DIR_NAME" -DestinationPath "dist/$DIR_NAME.zip"
Remove-Item -Recurse "dist/$DIR_NAME"
- name: Cleanup
if: matrix.naive
run: Remove-Item dist/sing-box.exe, dist/libcronet.dll
- name: Cleanup
if: ${{ !matrix.naive }}
run: Remove-Item dist/sing-box.exe
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: binary-windows_${{ matrix.arch }}
path: "dist"
build_android:
name: Build Android
if: (github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Android') && github.ref != 'refs/heads/oldstable'
runs-on: ubuntu-latest
needs:
- calculate_version
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
with:
fetch-depth: 0
submodules: 'recursive'
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ~1.25.8
- name: Setup Android NDK
id: setup-ndk
uses: nttld/setup-ndk@v1
with:
ndk-version: r28
- name: Setup OpenJDK
run: |-
sudo apt update && sudo apt install -y openjdk-17-jdk-headless
/usr/lib/jvm/java-17-openjdk-amd64/bin/java --version
- name: Set tag
run: |-
git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
git tag v${{ needs.calculate_version.outputs.version }} -f
- name: Build library
run: |-
make lib_install
export PATH="$PATH:$(go env GOPATH)/bin"
make lib_android
env:
JAVA_HOME: /usr/lib/jvm/java-17-openjdk-amd64
ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
- name: Checkout main branch
if: github.ref == 'refs/heads/stable' && github.event_name != 'workflow_dispatch'
run: |-
cd clients/android
git checkout main
- name: Checkout dev branch
if: github.ref == 'refs/heads/testing'
run: |-
cd clients/android
git checkout dev
- name: Gradle cache
uses: actions/cache@v4
with:
path: ~/.gradle
key: gradle-${{ hashFiles('**/*.gradle') }}
- name: Update version
if: github.event_name == 'workflow_dispatch'
run: |-
go run -v ./cmd/internal/update_android_version --ci
- name: Update nightly version
if: github.event_name != 'workflow_dispatch'
run: |-
go run -v ./cmd/internal/update_android_version --ci --nightly
- name: Build
run: |-
mkdir clients/android/app/libs
cp *.aar clients/android/app/libs
cd clients/android
./gradlew :app:assembleOtherRelease :app:assembleOtherLegacyRelease
env:
JAVA_HOME: /usr/lib/jvm/java-17-openjdk-amd64
ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
LOCAL_PROPERTIES: ${{ secrets.LOCAL_PROPERTIES }}
- name: Prepare upload
run: |-
mkdir -p dist
#cp clients/android/app/build/outputs/apk/play/release/*.apk dist
cp clients/android/app/build/outputs/apk/other/release/*.apk dist
cp clients/android/app/build/outputs/apk/otherLegacy/release/*.apk dist
VERSION_CODE=$(grep VERSION_CODE clients/android/version.properties | cut -d= -f2)
VERSION_NAME=$(grep VERSION_NAME clients/android/version.properties | cut -d= -f2)
cat > dist/SFA-version-metadata.json << EOF
{
"version_code": ${VERSION_CODE},
"version_name": "${VERSION_NAME}"
}
EOF
cat dist/SFA-version-metadata.json
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: binary-android-apks
path: 'dist'
publish_android:
name: Publish Android
if: github.event_name == 'workflow_dispatch' && inputs.build == 'publish-android' && github.ref != 'refs/heads/oldstable'
runs-on: ubuntu-latest
needs:
- calculate_version
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
with:
fetch-depth: 0
submodules: 'recursive'
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ~1.25.8
- name: Setup Android NDK
id: setup-ndk
uses: nttld/setup-ndk@v1
with:
ndk-version: r28
- name: Setup OpenJDK
run: |-
sudo apt update && sudo apt install -y openjdk-17-jdk-headless
/usr/lib/jvm/java-17-openjdk-amd64/bin/java --version
- name: Set tag
run: |-
git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
git tag v${{ needs.calculate_version.outputs.version }} -f
- name: Build library
run: |-
make lib_install
export PATH="$PATH:$(go env GOPATH)/bin"
make lib_android
env:
JAVA_HOME: /usr/lib/jvm/java-17-openjdk-amd64
ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
- name: Checkout main branch
if: github.ref == 'refs/heads/stable' && github.event_name != 'workflow_dispatch'
run: |-
cd clients/android
git checkout main
- name: Checkout dev branch
if: github.ref == 'refs/heads/testing'
run: |-
cd clients/android
git checkout dev
- name: Gradle cache
uses: actions/cache@v4
with:
path: ~/.gradle
key: gradle-${{ hashFiles('**/*.gradle') }}
- name: Build
run: |-
go run -v ./cmd/internal/update_android_version --ci
mkdir clients/android/app/libs
cp *.aar clients/android/app/libs
cd clients/android
echo -n "$SERVICE_ACCOUNT_CREDENTIALS" | base64 --decode > service-account-credentials.json
./gradlew :app:publishPlayReleaseBundle
env:
JAVA_HOME: /usr/lib/jvm/java-17-openjdk-amd64
ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
LOCAL_PROPERTIES: ${{ secrets.LOCAL_PROPERTIES }}
SERVICE_ACCOUNT_CREDENTIALS: ${{ secrets.SERVICE_ACCOUNT_CREDENTIALS }}
build_apple:
name: Build Apple clients
runs-on: macos-26
if: false # github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Apple' || inputs.build == 'app-store' || inputs.build == 'iOS' || inputs.build == 'macOS' || inputs.build == 'tvOS' || inputs.build == 'macOS-standalone'
needs:
- calculate_version
strategy:
matrix:
include:
- name: iOS
if: ${{ github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Apple' || inputs.build == 'app-store'|| inputs.build == 'iOS' }}
platform: ios
scheme: SFI
destination: 'generic/platform=iOS'
archive: build/SFI.xcarchive
upload: SFI/Upload.plist
- name: macOS
if: ${{ github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Apple' || inputs.build == 'app-store'|| inputs.build == 'macOS' }}
platform: macos
scheme: SFM
destination: 'generic/platform=macOS'
archive: build/SFM.xcarchive
upload: SFI/Upload.plist
- name: tvOS
if: ${{ github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Apple' || inputs.build == 'app-store'|| inputs.build == 'tvOS' }}
platform: tvos
scheme: SFT
destination: 'generic/platform=tvOS'
archive: build/SFT.xcarchive
upload: SFI/Upload.plist
- name: macOS-standalone
if: ${{ github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Apple' || inputs.build == 'macOS-standalone' }}
platform: macos
scheme: SFM.System
destination: 'generic/platform=macOS'
archive: build/SFM.System.xcarchive
export: SFM.System/Export.plist
export_path: build/SFM.System
steps:
- name: Checkout
if: matrix.if
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
with:
fetch-depth: 0
submodules: 'recursive'
- name: Setup Go
if: matrix.if
uses: actions/setup-go@v5
with:
go-version: ~1.25.8
- name: Set tag
if: matrix.if
run: |-
git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
git tag v${{ needs.calculate_version.outputs.version }} -f
echo "VERSION=${{ needs.calculate_version.outputs.version }}" >> "$GITHUB_ENV"
- name: Checkout main branch
if: matrix.if && github.ref == 'refs/heads/stable' && github.event_name != 'workflow_dispatch'
run: |-
cd clients/apple
git checkout main
- name: Checkout dev branch
if: matrix.if && github.ref == 'refs/heads/testing'
run: |-
cd clients/apple
git checkout dev
- name: Setup certificates
if: matrix.if
run: |-
CERTIFICATE_PATH=$RUNNER_TEMP/Certificates.p12
KEYCHAIN_PATH=$RUNNER_TEMP/certificates.keychain-db
echo -n "$CERTIFICATES_P12" | base64 --decode -o $CERTIFICATE_PATH
security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
security import $CERTIFICATE_PATH -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
security list-keychain -d user -s $KEYCHAIN_PATH
PROFILES_ZIP_PATH=$RUNNER_TEMP/Profiles.zip
echo -n "$PROVISIONING_PROFILES" | base64 --decode -o $PROFILES_ZIP_PATH
PROFILES_PATH="$HOME/Library/MobileDevice/Provisioning Profiles"
mkdir -p "$PROFILES_PATH"
unzip $PROFILES_ZIP_PATH -d "$PROFILES_PATH"
ASC_KEY_PATH=$RUNNER_TEMP/Key.p12
echo -n "$ASC_KEY" | base64 --decode -o $ASC_KEY_PATH
xcrun notarytool store-credentials "notarytool-password" \
--key $ASC_KEY_PATH \
--key-id $ASC_KEY_ID \
--issuer $ASC_KEY_ISSUER_ID
echo "ASC_KEY_PATH=$ASC_KEY_PATH" >> "$GITHUB_ENV"
echo "ASC_KEY_ID=$ASC_KEY_ID" >> "$GITHUB_ENV"
echo "ASC_KEY_ISSUER_ID=$ASC_KEY_ISSUER_ID" >> "$GITHUB_ENV"
env:
CERTIFICATES_P12: ${{ secrets.CERTIFICATES_P12 }}
P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
KEYCHAIN_PASSWORD: ${{ secrets.P12_PASSWORD }}
PROVISIONING_PROFILES: ${{ secrets.PROVISIONING_PROFILES }}
ASC_KEY: ${{ secrets.ASC_KEY }}
ASC_KEY_ID: ${{ secrets.ASC_KEY_ID }}
ASC_KEY_ISSUER_ID: ${{ secrets.ASC_KEY_ISSUER_ID }}
- name: Build library
if: matrix.if
run: |-
make lib_install
export PATH="$PATH:$(go env GOPATH)/bin"
go run ./cmd/internal/build_libbox -target apple -platform ${{ matrix.platform }}
mv Libbox.xcframework clients/apple
- name: Update macOS version
if: matrix.if && matrix.name == 'macOS' && github.event_name == 'workflow_dispatch'
run: |-
MACOS_PROJECT_VERSION=$(go run -v ./cmd/internal/app_store_connect next_macos_project_version)
echo "MACOS_PROJECT_VERSION=$MACOS_PROJECT_VERSION"
echo "MACOS_PROJECT_VERSION=$MACOS_PROJECT_VERSION" >> "$GITHUB_ENV"
- name: Update version
if: matrix.if && matrix.name != 'iOS'
run: |-
go run -v ./cmd/internal/update_apple_version --ci
- name: Build
if: matrix.if
run: |-
cd clients/apple
xcodebuild archive \
-scheme "${{ matrix.scheme }}" \
-configuration Release \
-destination "${{ matrix.destination }}" \
-archivePath "${{ matrix.archive }}" \
-allowProvisioningUpdates \
-authenticationKeyPath $ASC_KEY_PATH \
-authenticationKeyID $ASC_KEY_ID \
-authenticationKeyIssuerID $ASC_KEY_ISSUER_ID
- name: Upload to App Store Connect
if: matrix.if && matrix.name != 'macOS-standalone' && github.event_name == 'workflow_dispatch'
run: |-
go run -v ./cmd/internal/app_store_connect cancel_app_store ${{ matrix.platform }}
cd clients/apple
xcodebuild -exportArchive \
-archivePath "${{ matrix.archive }}" \
-exportOptionsPlist ${{ matrix.upload }} \
-allowProvisioningUpdates \
-authenticationKeyPath $ASC_KEY_PATH \
-authenticationKeyID $ASC_KEY_ID \
-authenticationKeyIssuerID $ASC_KEY_ISSUER_ID
- name: Publish to TestFlight
if: matrix.if && matrix.name != 'macOS-standalone' && github.event_name == 'workflow_dispatch' && github.ref =='refs/heads/testing'
run: |-
go run -v ./cmd/internal/app_store_connect publish_testflight ${{ matrix.platform }}
- name: Build image
if: matrix.if && matrix.name == 'macOS-standalone' && github.event_name == 'workflow_dispatch'
run: |-
pushd clients/apple
xcodebuild -exportArchive \
-archivePath "${{ matrix.archive }}" \
-exportOptionsPlist ${{ matrix.export }} \
-exportPath "${{ matrix.export_path }}"
brew install create-dmg
create-dmg \
--volname "sing-box" \
--volicon "${{ matrix.export_path }}/SFM.app/Contents/Resources/AppIcon.icns" \
--icon "SFM.app" 0 0 \
--hide-extension "SFM.app" \
--app-drop-link 0 0 \
--skip-jenkins \
SFM.dmg "${{ matrix.export_path }}/SFM.app"
xcrun notarytool submit "SFM.dmg" --wait --keychain-profile "notarytool-password"
cd "${{ matrix.archive }}"
zip -r SFM.dSYMs.zip dSYMs
popd
mkdir -p dist
cp clients/apple/SFM.dmg "dist/SFM-${VERSION}-universal.dmg"
cp "clients/apple/${{ matrix.archive }}/SFM.dSYMs.zip" "dist/SFM-${VERSION}-universal.dSYMs.zip"
- name: Upload image
if: matrix.if && matrix.name == 'macOS-standalone' && github.event_name == 'workflow_dispatch'
uses: actions/upload-artifact@v4
with:
name: binary-macos-dmg
path: 'dist'
upload:
name: Upload builds
if: "!failure() && github.event_name == 'workflow_dispatch' && (inputs.build == 'All' || inputs.build == 'Binary' || inputs.build == 'Android' || inputs.build == 'Apple' || inputs.build == 'macOS-standalone')"
runs-on: ubuntu-latest
needs:
- calculate_version
- build
- build_darwin
- build_windows
- build_android
- build_apple
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
with:
fetch-depth: 0
- name: Cache ghr
uses: actions/cache@v4
id: cache-ghr
with:
path: |
~/go/bin/ghr
key: ghr
- name: Setup ghr
if: steps.cache-ghr.outputs.cache-hit != 'true'
run: |-
cd $HOME
git clone https://github.com/nekohasekai/ghr ghr
cd ghr
go install -v .
- name: Set tag
run: |-
git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
git tag v${{ needs.calculate_version.outputs.version }} -f
echo "VERSION=${{ needs.calculate_version.outputs.version }}" >> "$GITHUB_ENV"
- name: Download builds
uses: actions/download-artifact@v5
with:
path: dist
merge-multiple: true
- name: Upload builds
if: ${{ env.PUBLISHED == 'false' }}
run: |-
export PATH="$PATH:$HOME/go/bin"
ghr --replace --draft --prerelease -p 5 "v${VERSION}" dist
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Replace builds
if: ${{ env.PUBLISHED != 'false' }}
run: |-
export PATH="$PATH:$HOME/go/bin"
ghr --replace -p 5 "v${VERSION}" dist
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
================================================
FILE: .github/workflows/docker.yml
================================================
name: Publish Docker Images
on:
#push:
# branches:
# - stable
# - testing
release:
types:
- published
workflow_dispatch:
inputs:
tag:
description: "The tag version you want to build"
env:
REGISTRY_IMAGE: ghcr.io/sagernet/sing-box
jobs:
build_binary:
name: Build binary
if: github.event_name != 'release' || github.event.release.target_commitish != 'oldstable'
runs-on: ubuntu-latest
strategy:
fail-fast: true
matrix:
include:
# Naive-enabled builds (musl)
- { arch: amd64, naive: true, docker_platform: "linux/amd64" }
- { arch: arm64, naive: true, docker_platform: "linux/arm64" }
- { arch: "386", naive: true, docker_platform: "linux/386" }
- { arch: arm, goarm: "7", naive: true, docker_platform: "linux/arm/v7" }
- { arch: mipsle, gomips: softfloat, naive: true, docker_platform: "linux/mipsle" }
- { arch: riscv64, naive: true, docker_platform: "linux/riscv64" }
- { arch: loong64, naive: true, docker_platform: "linux/loong64" }
# Non-naive builds
- { arch: arm, goarm: "6", docker_platform: "linux/arm/v6" }
- { arch: ppc64le, docker_platform: "linux/ppc64le" }
- { arch: s390x, docker_platform: "linux/s390x" }
steps:
- name: Get commit to build
id: ref
run: |-
if [[ -z "${{ github.event.inputs.tag }}" ]]; then
ref="${{ github.ref_name }}"
else
ref="${{ github.event.inputs.tag }}"
fi
echo "ref=$ref"
echo "ref=$ref" >> $GITHUB_OUTPUT
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
with:
ref: ${{ steps.ref.outputs.ref }}
fetch-depth: 0
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ~1.25.8
- name: Clone cronet-go
if: matrix.naive
run: |
set -xeuo pipefail
CRONET_GO_VERSION=$(cat .github/CRONET_GO_VERSION)
git init ~/cronet-go
git -C ~/cronet-go remote add origin https://github.com/sagernet/cronet-go.git
git -C ~/cronet-go fetch --depth=1 origin "$CRONET_GO_VERSION"
git -C ~/cronet-go checkout FETCH_HEAD
git -C ~/cronet-go submodule update --init --recursive --depth=1
- name: Regenerate Debian keyring
if: matrix.naive
run: |
set -xeuo pipefail
rm -f ~/cronet-go/naiveproxy/src/build/linux/sysroot_scripts/keyring.gpg
cd ~/cronet-go
GPG_TTY=/dev/null ./naiveproxy/src/build/linux/sysroot_scripts/generate_keyring.sh
- name: Cache Chromium toolchain
if: matrix.naive
id: cache-chromium-toolchain
uses: actions/cache@v4
with:
path: |
~/cronet-go/naiveproxy/src/third_party/llvm-build/
~/cronet-go/naiveproxy/src/gn/out/
~/cronet-go/naiveproxy/src/chrome/build/pgo_profiles/
~/cronet-go/naiveproxy/src/out/sysroot-build/
key: chromium-toolchain-${{ matrix.arch }}-musl-${{ hashFiles('.github/CRONET_GO_VERSION') }}
- name: Download Chromium toolchain
if: matrix.naive
run: |
set -xeuo pipefail
cd ~/cronet-go
go run ./cmd/build-naive --target=linux/${{ matrix.arch }} --libc=musl download-toolchain
- name: Set version
run: |
set -xeuo pipefail
VERSION=$(go run ./cmd/internal/read_tag)
echo "VERSION=${VERSION}" >> "${GITHUB_ENV}"
- name: Set Chromium toolchain environment
if: matrix.naive
run: |
set -xeuo pipefail
cd ~/cronet-go
go run ./cmd/build-naive --target=linux/${{ matrix.arch }} --libc=musl env >> $GITHUB_ENV
- name: Set build tags
run: |
set -xeuo pipefail
if [[ "${{ matrix.naive }}" == "true" ]]; then
TAGS="$(cat release/DEFAULT_BUILD_TAGS),with_musl"
else
TAGS=$(cat release/DEFAULT_BUILD_TAGS_OTHERS)
fi
echo "BUILD_TAGS=${TAGS}" >> "${GITHUB_ENV}"
- name: Set shared ldflags
run: |
echo "LDFLAGS_SHARED=$(cat release/LDFLAGS)" >> "${GITHUB_ENV}"
- name: Build (naive)
if: matrix.naive
run: |
set -xeuo pipefail
go build -v -trimpath -o sing-box -tags "${BUILD_TAGS}" \
-ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${VERSION}' ${LDFLAGS_SHARED} -s -w -buildid=" \
./cmd/sing-box
env:
CGO_ENABLED: "1"
GOOS: linux
GOARCH: ${{ matrix.arch }}
GOARM: ${{ matrix.goarm }}
GOMIPS: ${{ matrix.gomips }}
- name: Build (non-naive)
if: ${{ ! matrix.naive }}
run: |
set -xeuo pipefail
go build -v -trimpath -o sing-box -tags "${BUILD_TAGS}" \
-ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${VERSION}' ${LDFLAGS_SHARED} -s -w -buildid=" \
./cmd/sing-box
env:
CGO_ENABLED: "0"
GOOS: linux
GOARCH: ${{ matrix.arch }}
GOARM: ${{ matrix.goarm }}
- name: Prepare artifact
run: |
platform=${{ matrix.docker_platform }}
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
# Rename binary to include arch info for Dockerfile.binary
BINARY_NAME="sing-box-${{ matrix.arch }}"
if [[ -n "${{ matrix.goarm }}" ]]; then
BINARY_NAME="${BINARY_NAME}v${{ matrix.goarm }}"
fi
mv sing-box "${BINARY_NAME}"
echo "BINARY_NAME=${BINARY_NAME}" >> $GITHUB_ENV
- name: Upload binary
uses: actions/upload-artifact@v4
with:
name: binary-${{ env.PLATFORM_PAIR }}
path: ${{ env.BINARY_NAME }}
if-no-files-found: error
retention-days: 1
build_docker:
name: Build Docker image
runs-on: ubuntu-latest
needs:
- build_binary
strategy:
fail-fast: true
matrix:
include:
- { platform: "linux/amd64" }
- { platform: "linux/arm/v6" }
- { platform: "linux/arm/v7" }
- { platform: "linux/arm64" }
- { platform: "linux/386" }
# mipsle: no base Docker image available for this platform
- { platform: "linux/ppc64le" }
- { platform: "linux/riscv64" }
- { platform: "linux/s390x" }
- { platform: "linux/loong64", base_image: "ghcr.io/loong64/alpine:edge" }
steps:
- name: Get commit to build
id: ref
run: |-
if [[ -z "${{ github.event.inputs.tag }}" ]]; then
ref="${{ github.ref_name }}"
else
ref="${{ github.event.inputs.tag }}"
fi
echo "ref=$ref"
echo "ref=$ref" >> $GITHUB_OUTPUT
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
with:
ref: ${{ steps.ref.outputs.ref }}
fetch-depth: 0
- name: Prepare
run: |
platform=${{ matrix.platform }}
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
- name: Download binary
uses: actions/download-artifact@v5
with:
name: binary-${{ env.PLATFORM_PAIR }}
path: .
- name: Prepare binary
run: |
# Find and make the binary executable
chmod +x sing-box-*
ls -la sing-box-*
- name: Setup QEMU
uses: docker/setup-qemu-action@v3
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY_IMAGE }}
- name: Build and push by digest
id: build
uses: docker/build-push-action@v6
with:
platforms: ${{ matrix.platform }}
context: .
file: Dockerfile.binary
build-args: |
BASE_IMAGE=${{ matrix.base_image || 'alpine' }}
labels: ${{ steps.meta.outputs.labels }}
outputs: type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true
- name: Export digest
run: |
mkdir -p /tmp/digests
digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"
- name: Upload digest
uses: actions/upload-artifact@v4
with:
name: digests-${{ env.PLATFORM_PAIR }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1
merge:
if: github.event_name != 'push'
runs-on: ubuntu-latest
needs:
- build_docker
steps:
- name: Get commit to build
id: ref
run: |-
if [[ -z "${{ github.event.inputs.tag }}" ]]; then
ref="${{ github.ref_name }}"
else
ref="${{ github.event.inputs.tag }}"
fi
echo "ref=$ref"
echo "ref=$ref" >> $GITHUB_OUTPUT
if [[ $ref == *"-"* ]]; then
latest=latest-beta
else
latest=latest
fi
echo "latest=$latest"
echo "latest=$latest" >> $GITHUB_OUTPUT
- name: Download digests
uses: actions/download-artifact@v5
with:
path: /tmp/digests
pattern: digests-*
merge-multiple: true
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Create manifest list and push
if: github.event_name != 'push'
working-directory: /tmp/digests
run: |
docker buildx imagetools create \
-t "${{ env.REGISTRY_IMAGE }}:${{ steps.ref.outputs.latest }}" \
-t "${{ env.REGISTRY_IMAGE }}:${{ steps.ref.outputs.ref }}" \
$(printf '${{ env.REGISTRY_IMAGE }}@sha256:%s ' *)
- name: Inspect image
if: github.event_name != 'push'
run: |
docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ steps.ref.outputs.latest }}
docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ steps.ref.outputs.ref }}
================================================
FILE: .github/workflows/lint.yml
================================================
name: Lint
on:
push:
branches:
- oldstable
- stable
- testing
- unstable
paths-ignore:
- '**.md'
- '.github/**'
- '!.github/workflows/lint.yml'
pull_request:
branches:
- oldstable
- stable
- testing
- unstable
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
with:
fetch-depth: 0
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ^1.25
- name: golangci-lint
uses: golangci/golangci-lint-action@v8
with:
version: latest
args: --timeout=30m
install-mode: binary
verify: false
================================================
FILE: .github/workflows/linux.yml
================================================
name: Build Linux Packages
on:
#push:
# branches:
# - stable
# - testing
workflow_dispatch:
inputs:
version:
description: "Version name"
required: true
type: string
forceBeta:
description: "Force beta"
required: false
type: boolean
default: false
release:
types:
- published
jobs:
calculate_version:
name: Calculate version
if: github.event_name != 'release' || github.event.release.target_commitish != 'oldstable'
runs-on: ubuntu-latest
outputs:
version: ${{ steps.outputs.outputs.version }}
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
with:
fetch-depth: 0
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ~1.25.8
- name: Check input version
if: github.event_name == 'workflow_dispatch'
run: |-
echo "version=${{ inputs.version }}"
echo "version=${{ inputs.version }}" >> "$GITHUB_ENV"
- name: Calculate version
if: github.event_name != 'workflow_dispatch'
run: |-
go run -v ./cmd/internal/read_tag --ci --nightly
- name: Set outputs
id: outputs
run: |-
echo "version=$version" >> "$GITHUB_OUTPUT"
build:
name: Build binary
runs-on: ubuntu-latest
needs:
- calculate_version
strategy:
matrix:
include:
# Naive-enabled builds (musl)
- { os: linux, arch: amd64, naive: true, debian: amd64, rpm: x86_64, pacman: x86_64 }
- { os: linux, arch: arm64, naive: true, debian: arm64, rpm: aarch64, pacman: aarch64 }
- { os: linux, arch: "386", naive: true, debian: i386, rpm: i386 }
- { os: linux, arch: arm, goarm: "7", naive: true, debian: armhf, rpm: armv7hl, pacman: armv7hl }
- { os: linux, arch: mipsle, gomips: softfloat, naive: true, debian: mipsel, rpm: mipsel }
- { os: linux, arch: riscv64, naive: true, debian: riscv64, rpm: riscv64 }
- { os: linux, arch: loong64, naive: true, debian: loongarch64, rpm: loongarch64 }
# Non-naive builds (unsupported architectures)
- { os: linux, arch: arm, goarm: "6", debian: armel, rpm: armv6hl }
- { os: linux, arch: mips64le, debian: mips64el, rpm: mips64el }
- { os: linux, arch: s390x, debian: s390x, rpm: s390x }
- { os: linux, arch: ppc64le, debian: ppc64el, rpm: ppc64le }
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
with:
fetch-depth: 0
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ~1.25.8
- name: Clone cronet-go
if: matrix.naive
run: |
set -xeuo pipefail
CRONET_GO_VERSION=$(cat .github/CRONET_GO_VERSION)
git init ~/cronet-go
git -C ~/cronet-go remote add origin https://github.com/sagernet/cronet-go.git
git -C ~/cronet-go fetch --depth=1 origin "$CRONET_GO_VERSION"
git -C ~/cronet-go checkout FETCH_HEAD
git -C ~/cronet-go submodule update --init --recursive --depth=1
- name: Regenerate Debian keyring
if: matrix.naive
run: |
set -xeuo pipefail
rm -f ~/cronet-go/naiveproxy/src/build/linux/sysroot_scripts/keyring.gpg
cd ~/cronet-go
GPG_TTY=/dev/null ./naiveproxy/src/build/linux/sysroot_scripts/generate_keyring.sh
- name: Cache Chromium toolchain
if: matrix.naive
id: cache-chromium-toolchain
uses: actions/cache@v4
with:
path: |
~/cronet-go/naiveproxy/src/third_party/llvm-build/
~/cronet-go/naiveproxy/src/gn/out/
~/cronet-go/naiveproxy/src/chrome/build/pgo_profiles/
~/cronet-go/naiveproxy/src/out/sysroot-build/
key: chromium-toolchain-${{ matrix.arch }}-musl-${{ hashFiles('.github/CRONET_GO_VERSION') }}
- name: Download Chromium toolchain
if: matrix.naive
run: |
set -xeuo pipefail
cd ~/cronet-go
go run ./cmd/build-naive --target=linux/${{ matrix.arch }} --libc=musl download-toolchain
- name: Set Chromium toolchain environment
if: matrix.naive
run: |
set -xeuo pipefail
cd ~/cronet-go
go run ./cmd/build-naive --target=linux/${{ matrix.arch }} --libc=musl env >> $GITHUB_ENV
- name: Set tag
run: |-
git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
git tag v${{ needs.calculate_version.outputs.version }} -f
- name: Set build tags
run: |
set -xeuo pipefail
if [[ "${{ matrix.naive }}" == "true" ]]; then
TAGS="$(cat release/DEFAULT_BUILD_TAGS),with_musl"
else
TAGS=$(cat release/DEFAULT_BUILD_TAGS_OTHERS)
fi
echo "BUILD_TAGS=${TAGS}" >> "${GITHUB_ENV}"
- name: Set shared ldflags
run: |
echo "LDFLAGS_SHARED=$(cat release/LDFLAGS)" >> "${GITHUB_ENV}"
- name: Build (naive)
if: matrix.naive
run: |
set -xeuo pipefail
mkdir -p dist
go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \
-ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }}' ${LDFLAGS_SHARED} -s -w -buildid=" \
./cmd/sing-box
env:
CGO_ENABLED: "1"
GOOS: linux
GOARCH: ${{ matrix.arch }}
GOARM: ${{ matrix.goarm }}
GOMIPS: ${{ matrix.gomips }}
GOMIPS64: ${{ matrix.gomips }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build (non-naive)
if: ${{ ! matrix.naive }}
run: |
set -xeuo pipefail
mkdir -p dist
go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \
-ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }}' ${LDFLAGS_SHARED} -s -w -buildid=" \
./cmd/sing-box
env:
CGO_ENABLED: "0"
GOOS: ${{ matrix.os }}
GOARCH: ${{ matrix.arch }}
GOARM: ${{ matrix.goarm }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Set mtime
run: |-
TZ=UTC touch -t '197001010000' dist/sing-box
- name: Set name
if: (! contains(needs.calculate_version.outputs.version, '-')) && !inputs.forceBeta
run: |-
echo "NAME=sing-box" >> "$GITHUB_ENV"
- name: Set beta name
if: contains(needs.calculate_version.outputs.version, '-') || inputs.forceBeta
run: |-
echo "NAME=sing-box-beta" >> "$GITHUB_ENV"
- name: Set version
run: |-
PKG_VERSION="${{ needs.calculate_version.outputs.version }}"
PKG_VERSION="${PKG_VERSION//-/\~}"
echo "PKG_VERSION=${PKG_VERSION}" >> "${GITHUB_ENV}"
- name: Package DEB
if: matrix.debian != ''
run: |
set -xeuo pipefail
sudo gem install fpm
sudo apt-get install -y debsigs
cp .fpm_systemd .fpm
fpm -t deb \
--name "${NAME}" \
-v "$PKG_VERSION" \
-p "dist/${NAME}_${{ needs.calculate_version.outputs.version }}_linux_${{ matrix.debian }}.deb" \
--architecture ${{ matrix.debian }} \
dist/sing-box=/usr/bin/sing-box
curl -Lo '/tmp/debsigs.diff' 'https://gitlab.com/debsigs/debsigs/-/commit/160138f5de1ec110376d3c807b60a37388bc7c90.diff'
sudo patch /usr/bin/debsigs < '/tmp/debsigs.diff'
rm -rf $HOME/.gnupg
gpg --pinentry-mode loopback --passphrase "${{ secrets.GPG_PASSPHRASE }}" --import <<EOF
${{ secrets.GPG_KEY }}
EOF
debsigs --sign=origin -k ${{ secrets.GPG_KEY_ID }} --gpgopts '--pinentry-mode loopback --passphrase "${{ secrets.GPG_PASSPHRASE }}"' dist/*.deb
- name: Package RPM
if: matrix.rpm != ''
run: |-
set -xeuo pipefail
sudo gem install fpm
cp .fpm_systemd .fpm
fpm -t rpm \
--name "${NAME}" \
-v "$PKG_VERSION" \
-p "dist/${NAME}_${{ needs.calculate_version.outputs.version }}_linux_${{ matrix.rpm }}.rpm" \
--architecture ${{ matrix.rpm }} \
dist/sing-box=/usr/bin/sing-box
cat > $HOME/.rpmmacros <<EOF
%_gpg_name ${{ secrets.GPG_KEY_ID }}
%_gpg_sign_cmd_extra_args --pinentry-mode loopback --passphrase ${{ secrets.GPG_PASSPHRASE }}
EOF
gpg --pinentry-mode loopback --passphrase "${{ secrets.GPG_PASSPHRASE }}" --import <<EOF
${{ secrets.GPG_KEY }}
EOF
rpmsign --addsign dist/*.rpm
- name: Cleanup
run: rm dist/sing-box
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: binary-${{ matrix.os }}_${{ matrix.arch }}${{ matrix.goarm && format('v{0}', matrix.goarm) }}${{ matrix.legacy_go && '-legacy' || '' }}
path: "dist"
upload:
name: Upload builds
runs-on: ubuntu-latest
needs:
- calculate_version
- build
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
with:
fetch-depth: 0
- name: Set tag
run: |-
git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
git tag v${{ needs.calculate_version.outputs.version }} -f
echo "VERSION=${{ needs.calculate_version.outputs.version }}" >> "$GITHUB_ENV"
- name: Download builds
uses: actions/download-artifact@v5
with:
path: dist
merge-multiple: true
- name: Publish packages
if: github.event_name != 'push'
run: |-
ls dist | xargs -I {} curl -F "package=@dist/{}" https://${{ secrets.FURY_TOKEN }}@push.fury.io/sagernet/
================================================
FILE: .github/workflows/stale.yml
================================================
name: Mark stale issues and pull requests
on:
schedule:
- cron: "30 1 * * *"
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v9
with:
stale-issue-message: 'This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 5 days'
days-before-stale: 60
days-before-close: 5
exempt-issue-labels: 'bug,enhancement'
================================================
FILE: .gitignore
================================================
/.idea/
/vendor/
/*.json
/*.srs
/*.db
/site/
/bin/
/dist/
/sing-box
/sing-box.exe
/build/
/*.jar
/*.aar
/*.xcframework/
/experimental/libbox/*.aar
/experimental/libbox/*.xcframework/
/experimental/libbox/*.nupkg
.DS_Store
/config.d/
/venv/
CLAUDE.md
AGENTS.md
/.claude/
================================================
FILE: .gitmodules
================================================
[submodule "clients/apple"]
path = clients/apple
url = https://github.com/SagerNet/sing-box-for-apple.git
[submodule "clients/android"]
path = clients/android
url = https://github.com/SagerNet/sing-box-for-android.git
================================================
FILE: .golangci.yml
================================================
version: "2"
run:
go: "1.25"
build-tags:
- with_gvisor
- with_quic
- with_dhcp
- with_wireguard
- with_utls
- with_acme
- with_clash_api
- with_tailscale
- with_ccm
- with_ocm
- badlinkname
- tfogo_checklinkname0
linters:
default: none
enable:
- govet
- ineffassign
- paralleltest
- staticcheck
settings:
staticcheck:
checks:
- all
- -S1000
- -S1008
- -S1017
- -ST1003
- -QF1001
- -QF1003
- -QF1008
exclusions:
generated: lax
presets:
- comments
- common-false-positives
- legacy
- std-error-handling
paths:
- transport/simple-obfs
- third_party$
- builtin$
- examples$
formatters:
enable:
- gci
- gofumpt
settings:
gci:
sections:
- standard
- prefix(github.com/sagernet/)
- default
custom-order: true
exclusions:
generated: lax
paths:
- transport/simple-obfs
- third_party$
- builtin$
- examples$
================================================
FILE: Dockerfile
================================================
FROM --platform=$BUILDPLATFORM golang:1.25-alpine AS builder
LABEL maintainer="nekohasekai <contact-git@sekai.icu>"
COPY . /go/src/github.com/sagernet/sing-box
WORKDIR /go/src/github.com/sagernet/sing-box
ARG TARGETOS TARGETARCH
ARG GOPROXY=""
ENV GOPROXY ${GOPROXY}
ENV CGO_ENABLED=0
ENV GOOS=$TARGETOS
ENV GOARCH=$TARGETARCH
RUN set -ex \
&& apk add git build-base \
&& export COMMIT=$(git rev-parse --short HEAD) \
&& export VERSION=$(go run ./cmd/internal/read_tag) \
&& export TAGS=$(cat release/DEFAULT_BUILD_TAGS_OTHERS) \
&& export LDFLAGS_SHARED=$(cat release/LDFLAGS) \
&& go build -v -trimpath -tags "$TAGS" \
-o /go/bin/sing-box \
-ldflags "-X \"github.com/sagernet/sing-box/constant.Version=$VERSION\" $LDFLAGS_SHARED -s -w -buildid=" \
./cmd/sing-box
FROM --platform=$TARGETPLATFORM alpine AS dist
LABEL maintainer="nekohasekai <contact-git@sekai.icu>"
RUN set -ex \
&& apk add --no-cache --upgrade bash tzdata ca-certificates nftables
COPY --from=builder /go/bin/sing-box /usr/local/bin/sing-box
ENTRYPOINT ["sing-box"]
================================================
FILE: Dockerfile.binary
================================================
ARG BASE_IMAGE=alpine
FROM ${BASE_IMAGE}
ARG TARGETARCH
ARG TARGETVARIANT
LABEL maintainer="nekohasekai <contact-git@sekai.icu>"
RUN set -ex \
&& if command -v apk > /dev/null; then \
apk add --no-cache --upgrade bash tzdata ca-certificates nftables; \
else \
apt-get update && apt-get install -y --no-install-recommends bash tzdata ca-certificates nftables \
&& rm -rf /var/lib/apt/lists/*; \
fi
COPY sing-box-${TARGETARCH}${TARGETVARIANT} /usr/local/bin/sing-box
ENTRYPOINT ["sing-box"]
================================================
FILE: LICENSE
================================================
Copyright (C) 2022 by nekohasekai <contact-sagernet@sekai.icu>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
In addition, no derivative work may use the name or imply association
with this application without prior consent.
================================================
FILE: Makefile
================================================
NAME = sing-box
COMMIT = $(shell git rev-parse --short HEAD)
TAGS ?= $(shell cat release/DEFAULT_BUILD_TAGS_OTHERS)
GOHOSTOS = $(shell go env GOHOSTOS)
GOHOSTARCH = $(shell go env GOHOSTARCH)
VERSION=$(shell CGO_ENABLED=0 GOOS=$(GOHOSTOS) GOARCH=$(GOHOSTARCH) go run github.com/sagernet/sing-box/cmd/internal/read_tag@latest)
LDFLAGS_SHARED = $(shell cat release/LDFLAGS)
PARAMS = -v -trimpath -ldflags "-X 'github.com/sagernet/sing-box/constant.Version=$(VERSION)' $(LDFLAGS_SHARED) -s -w -buildid="
MAIN_PARAMS = $(PARAMS) -tags "$(TAGS)"
MAIN = ./cmd/sing-box
PREFIX ?= $(shell go env GOPATH)
SING_FFI ?= sing-ffi
LIBBOX_FFI_CONFIG ?= ./experimental/libbox/ffi.json
.PHONY: test release docs build
build:
export GOTOOLCHAIN=local && \
go build $(MAIN_PARAMS) $(MAIN)
race:
export GOTOOLCHAIN=local && \
go build -race $(MAIN_PARAMS) $(MAIN)
ci_build:
export GOTOOLCHAIN=local && \
go build $(PARAMS) $(MAIN) && \
go build $(MAIN_PARAMS) $(MAIN)
generate_completions:
go run -v --tags "$(TAGS),generate,generate_completions" $(MAIN)
install:
go build -o $(PREFIX)/bin/$(NAME) $(MAIN_PARAMS) $(MAIN)
fmt:
@gofumpt -l -w .
@gofmt -s -w .
@gci write --custom-order -s standard -s "prefix(github.com/sagernet/)" -s "default" .
fmt_docs:
go run ./cmd/internal/format_docs
fmt_install:
go install -v mvdan.cc/gofumpt@latest
go install -v github.com/daixiang0/gci@latest
lint:
GOOS=linux golangci-lint run ./...
GOOS=android golangci-lint run ./...
GOOS=windows golangci-lint run ./...
GOOS=darwin golangci-lint run ./...
GOOS=freebsd golangci-lint run ./...
lint_install:
go install -v github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest
proto:
@go run ./cmd/internal/protogen
@gofumpt -l -w .
@gofumpt -l -w .
proto_install:
go install -v google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install -v google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
update_certificates:
go run ./cmd/internal/update_certificates
release:
go run ./cmd/internal/build goreleaser release --clean --skip publish
mkdir dist/release
mv dist/*.tar.gz \
dist/*.zip \
dist/*.deb \
dist/*.rpm \
dist/*_amd64.pkg.tar.zst \
dist/*_arm64.pkg.tar.zst \
dist/release
ghr --replace --draft --prerelease -p 5 "v${VERSION}" dist/release
rm -r dist/release
release_repo:
go run ./cmd/internal/build goreleaser release -f .goreleaser.fury.yaml --clean
release_install:
go install -v github.com/tcnksm/ghr@latest
update_android_version:
go run ./cmd/internal/update_android_version
build_android:
cd ../sing-box-for-android && ./gradlew :app:clean :app:assembleOtherRelease :app:assembleOtherLegacyRelease && ./gradlew --stop
upload_android:
mkdir -p dist/release_android
cp ../sing-box-for-android/app/build/outputs/apk/other/release/*.apk dist/release_android
cp ../sing-box-for-android/app/build/outputs/apk/otherLegacy/release/*.apk dist/release_android
ghr --replace --draft --prerelease -p 5 "v${VERSION}" dist/release_android
rm -rf dist/release_android
release_android: lib_android update_android_version build_android upload_android
publish_android:
cd ../sing-box-for-android && ./gradlew :app:publishPlayReleaseBundle && ./gradlew --stop
# TODO: find why and remove `-destination 'generic/platform=iOS'`
# TODO: remove xcode clean when fix control widget fixed
build_ios:
cd ../sing-box-for-apple && \
rm -rf build/SFI.xcarchive && \
xcodebuild clean -scheme SFI && \
xcodebuild archive -scheme SFI -configuration Release -destination 'generic/platform=iOS' -archivePath build/SFI.xcarchive -allowProvisioningUpdates | xcbeautify | grep -A 10 -e "Archive Succeeded" -e "ARCHIVE FAILED" -e "❌"
upload_ios_app_store:
cd ../sing-box-for-apple && \
xcodebuild -exportArchive -archivePath build/SFI.xcarchive -exportOptionsPlist SFI/Upload.plist -allowProvisioningUpdates
export_ios_ipa:
cd ../sing-box-for-apple && \
xcodebuild -exportArchive -archivePath build/SFI.xcarchive -exportOptionsPlist SFI/Export.plist -allowProvisioningUpdates -exportPath build/SFI && \
cp build/SFI/sing-box.ipa dist/SFI.ipa
upload_ios_ipa:
cd dist && \
cp SFI.ipa "SFI-${VERSION}.ipa" && \
ghr --replace --draft --prerelease "v${VERSION}" "SFI-${VERSION}.ipa"
release_ios: build_ios upload_ios_app_store
build_macos:
cd ../sing-box-for-apple && \
rm -rf build/SFM.xcarchive && \
xcodebuild archive -scheme SFM -configuration Release -archivePath build/SFM.xcarchive -allowProvisioningUpdates | xcbeautify | grep -A 10 -e "Archive Succeeded" -e "ARCHIVE FAILED" -e "❌"
upload_macos_app_store:
cd ../sing-box-for-apple && \
xcodebuild -exportArchive -archivePath build/SFM.xcarchive -exportOptionsPlist SFI/Upload.plist -allowProvisioningUpdates
release_macos: build_macos upload_macos_app_store
build_macos_standalone:
$(MAKE) -C ../sing-box-for-apple archive_macos_standalone
build_macos_dmg:
$(MAKE) -C ../sing-box-for-apple build_macos_dmg
build_macos_pkg:
$(MAKE) -C ../sing-box-for-apple build_macos_pkg
notarize_macos_dmg:
$(MAKE) -C ../sing-box-for-apple notarize_macos_dmg
notarize_macos_pkg:
$(MAKE) -C ../sing-box-for-apple notarize_macos_pkg
upload_macos_dmg:
mkdir -p dist/SFM
cp ../sing-box-for-apple/build/SFM-Apple.dmg "dist/SFM/SFM-${VERSION}-Apple.dmg"
cp ../sing-box-for-apple/build/SFM-Intel.dmg "dist/SFM/SFM-${VERSION}-Intel.dmg"
cp ../sing-box-for-apple/build/SFM-Universal.dmg "dist/SFM/SFM-${VERSION}-Universal.dmg"
ghr --replace --draft --prerelease "v${VERSION}" "dist/SFM/SFM-${VERSION}-Apple.dmg"
ghr --replace --draft --prerelease "v${VERSION}" "dist/SFM/SFM-${VERSION}-Intel.dmg"
ghr --replace --draft --prerelease "v${VERSION}" "dist/SFM/SFM-${VERSION}-Universal.dmg"
upload_macos_pkg:
mkdir -p dist/SFM
cp ../sing-box-for-apple/build/SFM-Apple.pkg "dist/SFM/SFM-${VERSION}-Apple.pkg"
cp ../sing-box-for-apple/build/SFM-Intel.pkg "dist/SFM/SFM-${VERSION}-Intel.pkg"
cp ../sing-box-for-apple/build/SFM-Universal.pkg "dist/SFM/SFM-${VERSION}-Universal.pkg"
ghr --replace --draft --prerelease "v${VERSION}" "dist/SFM/SFM-${VERSION}-Apple.pkg"
ghr --replace --draft --prerelease "v${VERSION}" "dist/SFM/SFM-${VERSION}-Intel.pkg"
ghr --replace --draft --prerelease "v${VERSION}" "dist/SFM/SFM-${VERSION}-Universal.pkg"
upload_macos_dsyms:
mkdir -p dist/SFM
cd ../sing-box-for-apple/build/SFM.System-universal.xcarchive && zip -r SFM.dSYMs.zip dSYMs
cp ../sing-box-for-apple/build/SFM.System-universal.xcarchive/SFM.dSYMs.zip "dist/SFM/SFM-${VERSION}.dSYMs.zip"
ghr --replace --draft --prerelease "v${VERSION}" "dist/SFM/SFM-${VERSION}.dSYMs.zip"
release_macos_standalone: build_macos_pkg notarize_macos_pkg upload_macos_pkg upload_macos_dsyms
build_tvos:
cd ../sing-box-for-apple && \
rm -rf build/SFT.xcarchive && \
xcodebuild archive -scheme SFT -configuration Release -archivePath build/SFT.xcarchive -allowProvisioningUpdates | xcbeautify | grep -A 10 -e "Archive Succeeded" -e "ARCHIVE FAILED" -e "❌"
upload_tvos_app_store:
cd ../sing-box-for-apple && \
xcodebuild -exportArchive -archivePath "build/SFT.xcarchive" -exportOptionsPlist SFI/Upload.plist -allowProvisioningUpdates
export_tvos_ipa:
cd ../sing-box-for-apple && \
xcodebuild -exportArchive -archivePath "build/SFT.xcarchive" -exportOptionsPlist SFI/Export.plist -allowProvisioningUpdates -exportPath build/SFT && \
cp build/SFT/sing-box.ipa dist/SFT.ipa
upload_tvos_ipa:
cd dist && \
cp SFT.ipa "SFT-${VERSION}.ipa" && \
ghr --replace --draft --prerelease "v${VERSION}" "SFT-${VERSION}.ipa"
release_tvos: build_tvos upload_tvos_app_store
update_apple_version:
go run ./cmd/internal/update_apple_version
update_macos_version:
MACOS_PROJECT_VERSION=$(shell go run -v ./cmd/internal/app_store_connect next_macos_project_version) go run ./cmd/internal/update_apple_version
release_apple: lib_apple update_apple_version release_ios release_macos release_tvos release_macos_standalone
release_apple_beta: update_apple_version release_ios release_macos release_tvos
publish_testflight:
go run -v ./cmd/internal/app_store_connect publish_testflight $(filter-out $@,$(MAKECMDGOALS))
prepare_app_store:
go run -v ./cmd/internal/app_store_connect prepare_app_store
publish_app_store:
go run -v ./cmd/internal/app_store_connect publish_app_store
test:
@go test -v ./... && \
cd test && \
go mod tidy && \
go test -v -tags "$(TAGS_TEST)" .
test_stdio:
@go test -v ./... && \
cd test && \
go mod tidy && \
go test -v -tags "$(TAGS_TEST),force_stdio" .
lib_android:
go run ./cmd/internal/build_libbox -target android
lib_apple:
go run ./cmd/internal/build_libbox -target apple
lib_windows:
$(SING_FFI) generate --config $(LIBBOX_FFI_CONFIG) --platform-type csharp
lib_android_new:
$(SING_FFI) generate --config $(LIBBOX_FFI_CONFIG) --platform-type android
lib_apple_new:
$(SING_FFI) generate --config $(LIBBOX_FFI_CONFIG) --platform-type apple
lib_install:
go install -v github.com/sagernet/gomobile/cmd/gomobile@v0.1.12
go install -v github.com/sagernet/gomobile/cmd/gobind@v0.1.12
docs:
venv/bin/mkdocs serve
publish_docs:
venv/bin/mkdocs gh-deploy -m "Update" --force --ignore-version --no-history
docs_install:
python3 -m venv venv
source ./venv/bin/activate && pip install --force-reinstall mkdocs-material=="9.7.2" mkdocs-static-i18n=="1.2.*"
clean:
rm -rf bin dist sing-box
rm -f $(shell go env GOPATH)/sing-box
update:
git fetch
git reset FETCH_HEAD --hard
git clean -fdx
%:
@:
================================================
FILE: README.md
================================================
> Sponsored by [Warp](https://go.warp.dev/sing-box), built for coding with multiple AI agents
<a href="https://go.warp.dev/sing-box">
<img alt="Warp sponsorship" width="400" src="https://github.com/warpdotdev/brand-assets/raw/refs/heads/main/Github/Sponsor/Warp-Github-LG-02.png">
</a>
---
# sing-box
The universal proxy platform.
[](https://repology.org/project/sing-box/versions)
## Documentation
https://sing-box.sagernet.org
## License
```
Copyright (C) 2022 by nekohasekai <contact-sagernet@sekai.icu>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
In addition, no derivative work may use the name or imply association
with this application without prior consent.
```
================================================
FILE: adapter/certificate.go
================================================
package adapter
import (
"context"
"crypto/x509"
"github.com/sagernet/sing/service"
)
type CertificateStore interface {
LifecycleService
Pool() *x509.CertPool
}
func RootPoolFromContext(ctx context.Context) *x509.CertPool {
store := service.FromContext[CertificateStore](ctx)
if store == nil {
return nil
}
return store.Pool()
}
================================================
FILE: adapter/connections.go
================================================
package adapter
import (
"context"
"net"
N "github.com/sagernet/sing/common/network"
)
type ConnectionManager interface {
Lifecycle
Count() int
CloseAll()
TrackConn(conn net.Conn) net.Conn
TrackPacketConn(conn net.PacketConn) net.PacketConn
NewConnection(ctx context.Context, this N.Dialer, conn net.Conn, metadata InboundContext, onClose N.CloseHandlerFunc)
NewPacketConnection(ctx context.Context, this N.Dialer, conn N.PacketConn, metadata InboundContext, onClose N.CloseHandlerFunc)
}
================================================
FILE: adapter/dns.go
================================================
package adapter
import (
"context"
"net/netip"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/logger"
"github.com/sagernet/sing/service"
"github.com/miekg/dns"
)
type DNSRouter interface {
Lifecycle
Exchange(ctx context.Context, message *dns.Msg, options DNSQueryOptions) (*dns.Msg, error)
Lookup(ctx context.Context, domain string, options DNSQueryOptions) ([]netip.Addr, error)
ClearCache()
LookupReverseMapping(ip netip.Addr) (string, bool)
ResetNetwork()
}
type DNSClient interface {
Start()
Exchange(ctx context.Context, transport DNSTransport, message *dns.Msg, options DNSQueryOptions, responseChecker func(responseAddrs []netip.Addr) bool) (*dns.Msg, error)
Lookup(ctx context.Context, transport DNSTransport, domain string, options DNSQueryOptions, responseChecker func(responseAddrs []netip.Addr) bool) ([]netip.Addr, error)
ClearCache()
}
type DNSQueryOptions struct {
Transport DNSTransport
Strategy C.DomainStrategy
LookupStrategy C.DomainStrategy
DisableCache bool
RewriteTTL *uint32
ClientSubnet netip.Prefix
}
func DNSQueryOptionsFrom(ctx context.Context, options *option.DomainResolveOptions) (*DNSQueryOptions, error) {
if options == nil {
return &DNSQueryOptions{}, nil
}
transportManager := service.FromContext[DNSTransportManager](ctx)
transport, loaded := transportManager.Transport(options.Server)
if !loaded {
return nil, E.New("domain resolver not found: " + options.Server)
}
return &DNSQueryOptions{
Transport: transport,
Strategy: C.DomainStrategy(options.Strategy),
DisableCache: options.DisableCache,
RewriteTTL: options.RewriteTTL,
ClientSubnet: options.ClientSubnet.Build(netip.Prefix{}),
}, nil
}
type RDRCStore interface {
LoadRDRC(transportName string, qName string, qType uint16) (rejected bool)
SaveRDRC(transportName string, qName string, qType uint16) error
SaveRDRCAsync(transportName string, qName string, qType uint16, logger logger.Logger)
}
type DNSTransport interface {
Lifecycle
Type() string
Tag() string
Dependencies() []string
Reset()
Exchange(ctx context.Context, message *dns.Msg) (*dns.Msg, error)
}
type LegacyDNSTransport interface {
LegacyStrategy() C.DomainStrategy
LegacyClientSubnet() netip.Prefix
}
type DNSTransportRegistry interface {
option.DNSTransportOptionsRegistry
CreateDNSTransport(ctx context.Context, logger log.ContextLogger, tag string, transportType string, options any) (DNSTransport, error)
}
type DNSTransportManager interface {
Lifecycle
Transports() []DNSTransport
Transport(tag string) (DNSTransport, bool)
Default() DNSTransport
FakeIP() FakeIPTransport
Remove(tag string) error
Create(ctx context.Context, logger log.ContextLogger, tag string, outboundType string, options any) error
}
================================================
FILE: adapter/endpoint/adapter.go
================================================
package endpoint
import "github.com/sagernet/sing-box/option"
type Adapter struct {
endpointType string
endpointTag string
network []string
dependencies []string
}
func NewAdapter(endpointType string, endpointTag string, network []string, dependencies []string) Adapter {
return Adapter{
endpointType: endpointType,
endpointTag: endpointTag,
network: network,
dependencies: dependencies,
}
}
func NewAdapterWithDialerOptions(endpointType string, endpointTag string, network []string, dialOptions option.DialerOptions) Adapter {
var dependencies []string
if dialOptions.Detour != "" {
dependencies = []string{dialOptions.Detour}
}
return NewAdapter(endpointType, endpointTag, network, dependencies)
}
func (a *Adapter) Type() string {
return a.endpointType
}
func (a *Adapter) Tag() string {
return a.endpointTag
}
func (a *Adapter) Network() []string {
return a.network
}
func (a *Adapter) Dependencies() []string {
return a.dependencies
}
================================================
FILE: adapter/endpoint/manager.go
================================================
package endpoint
import (
"context"
"os"
"sync"
"time"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/taskmonitor"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
F "github.com/sagernet/sing/common/format"
)
var _ adapter.EndpointManager = (*Manager)(nil)
type Manager struct {
logger log.ContextLogger
registry adapter.EndpointRegistry
access sync.Mutex
started bool
stage adapter.StartStage
endpoints []adapter.Endpoint
endpointByTag map[string]adapter.Endpoint
}
func NewManager(logger log.ContextLogger, registry adapter.EndpointRegistry) *Manager {
return &Manager{
logger: logger,
registry: registry,
endpointByTag: make(map[string]adapter.Endpoint),
}
}
func (m *Manager) Start(stage adapter.StartStage) error {
m.access.Lock()
defer m.access.Unlock()
if m.started && m.stage >= stage {
panic("already started")
}
m.started = true
m.stage = stage
if stage == adapter.StartStateStart {
// started with outbound manager
return nil
}
for _, endpoint := range m.endpoints {
name := "endpoint/" + endpoint.Type() + "[" + endpoint.Tag() + "]"
m.logger.Trace(stage, " ", name)
startTime := time.Now()
err := adapter.LegacyStart(endpoint, stage)
if err != nil {
return E.Cause(err, stage, " ", name)
}
m.logger.Trace(stage, " ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
}
return nil
}
func (m *Manager) Close() error {
m.access.Lock()
defer m.access.Unlock()
if !m.started {
return nil
}
m.started = false
endpoints := m.endpoints
m.endpoints = nil
monitor := taskmonitor.New(m.logger, C.StopTimeout)
var err error
for _, endpoint := range endpoints {
name := "endpoint/" + endpoint.Type() + "[" + endpoint.Tag() + "]"
m.logger.Trace("close ", name)
startTime := time.Now()
monitor.Start("close ", name)
err = E.Append(err, endpoint.Close(), func(err error) error {
return E.Cause(err, "close ", name)
})
monitor.Finish()
m.logger.Trace("close ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
}
return nil
}
func (m *Manager) Endpoints() []adapter.Endpoint {
m.access.Lock()
defer m.access.Unlock()
return m.endpoints
}
func (m *Manager) Get(tag string) (adapter.Endpoint, bool) {
m.access.Lock()
defer m.access.Unlock()
endpoint, found := m.endpointByTag[tag]
return endpoint, found
}
func (m *Manager) Remove(tag string) error {
m.access.Lock()
endpoint, found := m.endpointByTag[tag]
if !found {
m.access.Unlock()
return os.ErrInvalid
}
delete(m.endpointByTag, tag)
index := common.Index(m.endpoints, func(it adapter.Endpoint) bool {
return it == endpoint
})
if index == -1 {
panic("invalid endpoint index")
}
m.endpoints = append(m.endpoints[:index], m.endpoints[index+1:]...)
started := m.started
m.access.Unlock()
if started {
return endpoint.Close()
}
return nil
}
func (m *Manager) Create(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, outboundType string, options any) error {
endpoint, err := m.registry.Create(ctx, router, logger, tag, outboundType, options)
if err != nil {
return err
}
m.access.Lock()
defer m.access.Unlock()
if m.started {
name := "endpoint/" + endpoint.Type() + "[" + endpoint.Tag() + "]"
for _, stage := range adapter.ListStartStages {
m.logger.Trace(stage, " ", name)
startTime := time.Now()
err = adapter.LegacyStart(endpoint, stage)
if err != nil {
return E.Cause(err, stage, " ", name)
}
m.logger.Trace(stage, " ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
}
}
if existsEndpoint, loaded := m.endpointByTag[tag]; loaded {
if m.started {
err = existsEndpoint.Close()
if err != nil {
return E.Cause(err, "close endpoint/", existsEndpoint.Type(), "[", existsEndpoint.Tag(), "]")
}
}
existsIndex := common.Index(m.endpoints, func(it adapter.Endpoint) bool {
return it == existsEndpoint
})
if existsIndex == -1 {
panic("invalid endpoint index")
}
m.endpoints = append(m.endpoints[:existsIndex], m.endpoints[existsIndex+1:]...)
}
m.endpoints = append(m.endpoints, endpoint)
m.endpointByTag[tag] = endpoint
return nil
}
================================================
FILE: adapter/endpoint/registry.go
================================================
package endpoint
import (
"context"
"sync"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
)
type ConstructorFunc[T any] func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options T) (adapter.Endpoint, error)
func Register[Options any](registry *Registry, outboundType string, constructor ConstructorFunc[Options]) {
registry.register(outboundType, func() any {
return new(Options)
}, func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, rawOptions any) (adapter.Endpoint, error) {
var options *Options
if rawOptions != nil {
options = rawOptions.(*Options)
}
return constructor(ctx, router, logger, tag, common.PtrValueOrDefault(options))
})
}
var _ adapter.EndpointRegistry = (*Registry)(nil)
type (
optionsConstructorFunc func() any
constructorFunc func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options any) (adapter.Endpoint, error)
)
type Registry struct {
access sync.Mutex
optionsType map[string]optionsConstructorFunc
constructor map[string]constructorFunc
}
func NewRegistry() *Registry {
return &Registry{
optionsType: make(map[string]optionsConstructorFunc),
constructor: make(map[string]constructorFunc),
}
}
func (m *Registry) CreateOptions(outboundType string) (any, bool) {
m.access.Lock()
defer m.access.Unlock()
optionsConstructor, loaded := m.optionsType[outboundType]
if !loaded {
return nil, false
}
return optionsConstructor(), true
}
func (m *Registry) Create(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, outboundType string, options any) (adapter.Endpoint, error) {
m.access.Lock()
defer m.access.Unlock()
constructor, loaded := m.constructor[outboundType]
if !loaded {
return nil, E.New("outbound type not found: " + outboundType)
}
return constructor(ctx, router, logger, tag, options)
}
func (m *Registry) register(outboundType string, optionsConstructor optionsConstructorFunc, constructor constructorFunc) {
m.access.Lock()
defer m.access.Unlock()
m.optionsType[outboundType] = optionsConstructor
m.constructor[outboundType] = constructor
}
================================================
FILE: adapter/endpoint.go
================================================
package adapter
import (
"context"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
)
type Endpoint interface {
Lifecycle
Type() string
Tag() string
Outbound
}
type EndpointRegistry interface {
option.EndpointOptionsRegistry
Create(ctx context.Context, router Router, logger log.ContextLogger, tag string, endpointType string, options any) (Endpoint, error)
}
type EndpointManager interface {
Lifecycle
Endpoints() []Endpoint
Get(tag string) (Endpoint, bool)
Remove(tag string) error
Create(ctx context.Context, router Router, logger log.ContextLogger, tag string, endpointType string, options any) error
}
================================================
FILE: adapter/experimental.go
================================================
package adapter
import (
"bytes"
"context"
"encoding/binary"
"io"
"time"
"github.com/sagernet/sing/common/observable"
"github.com/sagernet/sing/common/varbin"
)
type ClashServer interface {
LifecycleService
ConnectionTracker
Mode() string
ModeList() []string
SetModeUpdateHook(hook *observable.Subscriber[struct{}])
HistoryStorage() URLTestHistoryStorage
}
type URLTestHistory struct {
Time time.Time `json:"time"`
Delay uint16 `json:"delay"`
}
type URLTestHistoryStorage interface {
SetHook(hook *observable.Subscriber[struct{}])
LoadURLTestHistory(tag string) *URLTestHistory
DeleteURLTestHistory(tag string)
StoreURLTestHistory(tag string, history *URLTestHistory)
Close() error
}
type V2RayServer interface {
LifecycleService
StatsService() ConnectionTracker
}
type CacheFile interface {
LifecycleService
StoreFakeIP() bool
FakeIPStorage
StoreRDRC() bool
RDRCStore
LoadMode() string
StoreMode(mode string) error
LoadSelected(group string) string
StoreSelected(group string, selected string) error
LoadGroupExpand(group string) (isExpand bool, loaded bool)
StoreGroupExpand(group string, expand bool) error
LoadRuleSet(tag string) *SavedBinary
SaveRuleSet(tag string, set *SavedBinary) error
}
type SavedBinary struct {
Content []byte
LastUpdated time.Time
LastEtag string
}
func (s *SavedBinary) MarshalBinary() ([]byte, error) {
var buffer bytes.Buffer
err := binary.Write(&buffer, binary.BigEndian, uint8(1))
if err != nil {
return nil, err
}
_, err = varbin.WriteUvarint(&buffer, uint64(len(s.Content)))
if err != nil {
return nil, err
}
_, err = buffer.Write(s.Content)
if err != nil {
return nil, err
}
err = binary.Write(&buffer, binary.BigEndian, s.LastUpdated.Unix())
if err != nil {
return nil, err
}
_, err = varbin.WriteUvarint(&buffer, uint64(len(s.LastEtag)))
if err != nil {
return nil, err
}
_, err = buffer.WriteString(s.LastEtag)
if err != nil {
return nil, err
}
return buffer.Bytes(), nil
}
func (s *SavedBinary) UnmarshalBinary(data []byte) error {
reader := bytes.NewReader(data)
var version uint8
err := binary.Read(reader, binary.BigEndian, &version)
if err != nil {
return err
}
contentLength, err := binary.ReadUvarint(reader)
if err != nil {
return err
}
s.Content = make([]byte, contentLength)
_, err = io.ReadFull(reader, s.Content)
if err != nil {
return err
}
var lastUpdated int64
err = binary.Read(reader, binary.BigEndian, &lastUpdated)
if err != nil {
return err
}
s.LastUpdated = time.Unix(lastUpdated, 0)
etagLength, err := binary.ReadUvarint(reader)
if err != nil {
return err
}
etagBytes := make([]byte, etagLength)
_, err = io.ReadFull(reader, etagBytes)
if err != nil {
return err
}
s.LastEtag = string(etagBytes)
return nil
}
type OutboundGroup interface {
Outbound
Now() string
All() []string
}
type URLTestGroup interface {
OutboundGroup
URLTest(ctx context.Context) (map[string]uint16, error)
}
func OutboundTag(detour Outbound) string {
if group, isGroup := detour.(OutboundGroup); isGroup {
return group.Now()
}
return detour.Tag()
}
================================================
FILE: adapter/fakeip.go
================================================
package adapter
import (
"net/netip"
"github.com/sagernet/sing/common/logger"
)
type FakeIPStore interface {
SimpleLifecycle
Contains(address netip.Addr) bool
Create(domain string, isIPv6 bool) (netip.Addr, error)
Lookup(address netip.Addr) (string, bool)
Reset() error
}
type FakeIPStorage interface {
FakeIPMetadata() *FakeIPMetadata
FakeIPSaveMetadata(metadata *FakeIPMetadata) error
FakeIPSaveMetadataAsync(metadata *FakeIPMetadata)
FakeIPStore(address netip.Addr, domain string) error
FakeIPStoreAsync(address netip.Addr, domain string, logger logger.Logger)
FakeIPLoad(address netip.Addr) (string, bool)
FakeIPLoadDomain(domain string, isIPv6 bool) (netip.Addr, bool)
FakeIPReset() error
}
type FakeIPTransport interface {
DNSTransport
Store() FakeIPStore
}
================================================
FILE: adapter/fakeip_metadata.go
================================================
package adapter
import (
"bytes"
"encoding"
"encoding/binary"
"io"
"net/netip"
"github.com/sagernet/sing/common"
)
type FakeIPMetadata struct {
Inet4Range netip.Prefix
Inet6Range netip.Prefix
Inet4Current netip.Addr
Inet6Current netip.Addr
}
func (m *FakeIPMetadata) MarshalBinary() (data []byte, err error) {
var buffer bytes.Buffer
for _, marshaler := range []encoding.BinaryMarshaler{m.Inet4Range, m.Inet6Range, m.Inet4Current, m.Inet6Current} {
data, err = marshaler.MarshalBinary()
if err != nil {
return
}
common.Must(binary.Write(&buffer, binary.BigEndian, uint16(len(data))))
buffer.Write(data)
}
data = buffer.Bytes()
return
}
func (m *FakeIPMetadata) UnmarshalBinary(data []byte) error {
reader := bytes.NewReader(data)
for _, unmarshaler := range []encoding.BinaryUnmarshaler{&m.Inet4Range, &m.Inet6Range, &m.Inet4Current, &m.Inet6Current} {
var length uint16
common.Must(binary.Read(reader, binary.BigEndian, &length))
element := make([]byte, length)
_, err := io.ReadFull(reader, element)
if err != nil {
return err
}
err = unmarshaler.UnmarshalBinary(element)
if err != nil {
return err
}
}
return nil
}
================================================
FILE: adapter/handler.go
================================================
package adapter
import (
"context"
"net"
"github.com/sagernet/sing/common/buf"
E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
)
// Deprecated
type ConnectionHandler interface {
NewConnection(ctx context.Context, conn net.Conn, metadata InboundContext) error
}
type ConnectionHandlerEx interface {
NewConnectionEx(ctx context.Context, conn net.Conn, metadata InboundContext, onClose N.CloseHandlerFunc)
}
// Deprecated: use PacketHandlerEx instead
type PacketHandler interface {
NewPacket(ctx context.Context, conn N.PacketConn, buffer *buf.Buffer, metadata InboundContext) error
}
type PacketHandlerEx interface {
NewPacketEx(buffer *buf.Buffer, source M.Socksaddr)
}
// Deprecated: use OOBPacketHandlerEx instead
type OOBPacketHandler interface {
NewPacket(ctx context.Context, conn N.PacketConn, buffer *buf.Buffer, oob []byte, metadata InboundContext) error
}
type OOBPacketHandlerEx interface {
NewPacketEx(buffer *buf.Buffer, oob []byte, source M.Socksaddr)
}
// Deprecated
type PacketConnectionHandler interface {
NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata InboundContext) error
}
type PacketConnectionHandlerEx interface {
NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, metadata InboundContext, onClose N.CloseHandlerFunc)
}
// Deprecated: use TCPConnectionHandlerEx instead
//
//nolint:staticcheck
type UpstreamHandlerAdapter interface {
N.TCPConnectionHandler
N.UDPConnectionHandler
E.Handler
}
type UpstreamHandlerAdapterEx interface {
N.TCPConnectionHandlerEx
N.UDPConnectionHandlerEx
}
================================================
FILE: adapter/inbound/adapter.go
================================================
package inbound
type Adapter struct {
inboundType string
inboundTag string
}
func NewAdapter(inboundType string, inboundTag string) Adapter {
return Adapter{
inboundType: inboundType,
inboundTag: inboundTag,
}
}
func (a *Adapter) Type() string {
return a.inboundType
}
func (a *Adapter) Tag() string {
return a.inboundTag
}
================================================
FILE: adapter/inbound/manager.go
================================================
package inbound
import (
"context"
"os"
"sync"
"time"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/taskmonitor"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
F "github.com/sagernet/sing/common/format"
)
var _ adapter.InboundManager = (*Manager)(nil)
type Manager struct {
logger log.ContextLogger
registry adapter.InboundRegistry
endpoint adapter.EndpointManager
access sync.Mutex
started bool
stage adapter.StartStage
inbounds []adapter.Inbound
inboundByTag map[string]adapter.Inbound
}
func NewManager(logger log.ContextLogger, registry adapter.InboundRegistry, endpoint adapter.EndpointManager) *Manager {
return &Manager{
logger: logger,
registry: registry,
endpoint: endpoint,
inboundByTag: make(map[string]adapter.Inbound),
}
}
func (m *Manager) Start(stage adapter.StartStage) error {
m.access.Lock()
if m.started && m.stage >= stage {
panic("already started")
}
m.started = true
m.stage = stage
inbounds := m.inbounds
m.access.Unlock()
for _, inbound := range inbounds {
name := "inbound/" + inbound.Type() + "[" + inbound.Tag() + "]"
m.logger.Trace(stage, " ", name)
startTime := time.Now()
err := adapter.LegacyStart(inbound, stage)
if err != nil {
return E.Cause(err, stage, " ", name)
}
m.logger.Trace(stage, " ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
}
return nil
}
func (m *Manager) Close() error {
m.access.Lock()
defer m.access.Unlock()
if !m.started {
return nil
}
m.started = false
inbounds := m.inbounds
m.inbounds = nil
monitor := taskmonitor.New(m.logger, C.StopTimeout)
var err error
for _, inbound := range inbounds {
name := "inbound/" + inbound.Type() + "[" + inbound.Tag() + "]"
m.logger.Trace("close ", name)
startTime := time.Now()
monitor.Start("close ", name)
err = E.Append(err, inbound.Close(), func(err error) error {
return E.Cause(err, "close ", name)
})
monitor.Finish()
m.logger.Trace("close ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
}
return nil
}
func (m *Manager) Inbounds() []adapter.Inbound {
m.access.Lock()
defer m.access.Unlock()
return m.inbounds
}
func (m *Manager) Get(tag string) (adapter.Inbound, bool) {
m.access.Lock()
inbound, found := m.inboundByTag[tag]
m.access.Unlock()
if found {
return inbound, true
}
return m.endpoint.Get(tag)
}
func (m *Manager) Remove(tag string) error {
m.access.Lock()
inbound, found := m.inboundByTag[tag]
if !found {
m.access.Unlock()
return os.ErrInvalid
}
delete(m.inboundByTag, tag)
index := common.Index(m.inbounds, func(it adapter.Inbound) bool {
return it == inbound
})
if index == -1 {
panic("invalid inbound index")
}
m.inbounds = append(m.inbounds[:index], m.inbounds[index+1:]...)
started := m.started
m.access.Unlock()
if started {
return inbound.Close()
}
return nil
}
func (m *Manager) Create(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, outboundType string, options any) error {
inbound, err := m.registry.Create(ctx, router, logger, tag, outboundType, options)
if err != nil {
return err
}
m.access.Lock()
defer m.access.Unlock()
if m.started {
name := "inbound/" + inbound.Type() + "[" + inbound.Tag() + "]"
for _, stage := range adapter.ListStartStages {
m.logger.Trace(stage, " ", name)
startTime := time.Now()
err = adapter.LegacyStart(inbound, stage)
if err != nil {
return E.Cause(err, stage, " ", name)
}
m.logger.Trace(stage, " ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
}
}
if existsInbound, loaded := m.inboundByTag[tag]; loaded {
if m.started {
err = existsInbound.Close()
if err != nil {
return E.Cause(err, "close inbound/", existsInbound.Type(), "[", existsInbound.Tag(), "]")
}
}
existsIndex := common.Index(m.inbounds, func(it adapter.Inbound) bool {
return it == existsInbound
})
if existsIndex == -1 {
panic("invalid inbound index")
}
m.inbounds = append(m.inbounds[:existsIndex], m.inbounds[existsIndex+1:]...)
}
m.inbounds = append(m.inbounds, inbound)
m.inboundByTag[tag] = inbound
return nil
}
================================================
FILE: adapter/inbound/registry.go
================================================
package inbound
import (
"context"
"sync"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
)
type ConstructorFunc[T any] func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options T) (adapter.Inbound, error)
func Register[Options any](registry *Registry, outboundType string, constructor ConstructorFunc[Options]) {
registry.register(outboundType, func() any {
return new(Options)
}, func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, rawOptions any) (adapter.Inbound, error) {
var options *Options
if rawOptions != nil {
options = rawOptions.(*Options)
}
return constructor(ctx, router, logger, tag, common.PtrValueOrDefault(options))
})
}
var _ adapter.InboundRegistry = (*Registry)(nil)
type (
optionsConstructorFunc func() any
constructorFunc func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options any) (adapter.Inbound, error)
)
type Registry struct {
access sync.Mutex
optionsType map[string]optionsConstructorFunc
constructor map[string]constructorFunc
}
func NewRegistry() *Registry {
return &Registry{
optionsType: make(map[string]optionsConstructorFunc),
constructor: make(map[string]constructorFunc),
}
}
func (m *Registry) CreateOptions(outboundType string) (any, bool) {
m.access.Lock()
defer m.access.Unlock()
optionsConstructor, loaded := m.optionsType[outboundType]
if !loaded {
return nil, false
}
return optionsConstructor(), true
}
func (m *Registry) Create(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, outboundType string, options any) (adapter.Inbound, error) {
m.access.Lock()
defer m.access.Unlock()
constructor, loaded := m.constructor[outboundType]
if !loaded {
return nil, E.New("outbound type not found: " + outboundType)
}
return constructor(ctx, router, logger, tag, options)
}
func (m *Registry) register(outboundType string, optionsConstructor optionsConstructorFunc, constructor constructorFunc) {
m.access.Lock()
defer m.access.Unlock()
m.optionsType[outboundType] = optionsConstructor
m.constructor[outboundType] = constructor
}
================================================
FILE: adapter/inbound.go
================================================
package adapter
import (
"context"
"net"
"net/netip"
"time"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
M "github.com/sagernet/sing/common/metadata"
)
type Inbound interface {
Lifecycle
Type() string
Tag() string
}
type TCPInjectableInbound interface {
Inbound
ConnectionHandlerEx
}
type UDPInjectableInbound interface {
Inbound
PacketConnectionHandlerEx
}
type InboundRegistry interface {
option.InboundOptionsRegistry
Create(ctx context.Context, router Router, logger log.ContextLogger, tag string, inboundType string, options any) (Inbound, error)
}
type InboundManager interface {
Lifecycle
Inbounds() []Inbound
Get(tag string) (Inbound, bool)
Remove(tag string) error
Create(ctx context.Context, router Router, logger log.ContextLogger, tag string, inboundType string, options any) error
}
type InboundContext struct {
Inbound string
InboundType string
IPVersion uint8
Network string
Source M.Socksaddr
Destination M.Socksaddr
User string
Outbound string
// sniffer
Protocol string
Domain string
Client string
SniffContext any
SnifferNames []string
SniffError error
// cache
// Deprecated: implement in rule action
InboundDetour string
LastInbound string
OriginDestination M.Socksaddr
RouteOriginalDestination M.Socksaddr
UDPDisableDomainUnmapping bool
UDPConnect bool
UDPTimeout time.Duration
TLSFragment bool
TLSFragmentFallbackDelay time.Duration
TLSRecordFragment bool
NetworkStrategy *C.NetworkStrategy
NetworkType []C.InterfaceType
FallbackNetworkType []C.InterfaceType
FallbackDelay time.Duration
DestinationAddresses []netip.Addr
SourceGeoIPCode string
GeoIPCode string
ProcessInfo *ConnectionOwner
SourceMACAddress net.HardwareAddr
SourceHostname string
QueryType uint16
FakeIP bool
// rule cache
IPCIDRMatchSource bool
IPCIDRAcceptEmpty bool
SourceAddressMatch bool
SourcePortMatch bool
DestinationAddressMatch bool
DestinationPortMatch bool
DidMatch bool
IgnoreDestinationIPCIDRMatch bool
}
func (c *InboundContext) ResetRuleCache() {
c.IPCIDRMatchSource = false
c.IPCIDRAcceptEmpty = false
c.SourceAddressMatch = false
c.SourcePortMatch = false
c.DestinationAddressMatch = false
c.DestinationPortMatch = false
c.DidMatch = false
}
type inboundContextKey struct{}
func WithContext(ctx context.Context, inboundContext *InboundContext) context.Context {
return context.WithValue(ctx, (*inboundContextKey)(nil), inboundContext)
}
func ContextFrom(ctx context.Context) *InboundContext {
metadata := ctx.Value((*inboundContextKey)(nil))
if metadata == nil {
return nil
}
return metadata.(*InboundContext)
}
func ExtendContext(ctx context.Context) (context.Context, *InboundContext) {
var newMetadata InboundContext
if metadata := ContextFrom(ctx); metadata != nil {
newMetadata = *metadata
}
return WithContext(ctx, &newMetadata), &newMetadata
}
func OverrideContext(ctx context.Context) context.Context {
if metadata := ContextFrom(ctx); metadata != nil {
newMetadata := *metadata
return WithContext(ctx, &newMetadata)
}
return ctx
}
================================================
FILE: adapter/lifecycle.go
================================================
package adapter
import (
"reflect"
"strings"
"time"
"github.com/sagernet/sing-box/log"
E "github.com/sagernet/sing/common/exceptions"
F "github.com/sagernet/sing/common/format"
)
type SimpleLifecycle interface {
Start() error
Close() error
}
type StartStage uint8
const (
StartStateInitialize StartStage = iota
StartStateStart
StartStatePostStart
StartStateStarted
)
var ListStartStages = []StartStage{
StartStateInitialize,
StartStateStart,
StartStatePostStart,
StartStateStarted,
}
func (s StartStage) String() string {
switch s {
case StartStateInitialize:
return "initialize"
case StartStateStart:
return "start"
case StartStatePostStart:
return "post-start"
case StartStateStarted:
return "finish-start"
default:
panic("unknown stage")
}
}
type Lifecycle interface {
Start(stage StartStage) error
Close() error
}
type LifecycleService interface {
Name() string
Lifecycle
}
func getServiceName(service any) string {
if named, ok := service.(interface {
Type() string
Tag() string
}); ok {
tag := named.Tag()
if tag != "" {
return named.Type() + "[" + tag + "]"
}
return named.Type()
}
t := reflect.TypeOf(service)
if t.Kind() == reflect.Ptr {
t = t.Elem()
}
return strings.ToLower(t.Name())
}
func Start(logger log.ContextLogger, stage StartStage, services ...Lifecycle) error {
for _, service := range services {
name := getServiceName(service)
logger.Trace(stage, " ", name)
startTime := time.Now()
err := service.Start(stage)
if err != nil {
return err
}
logger.Trace(stage, " ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
}
return nil
}
func StartNamed(logger log.ContextLogger, stage StartStage, services []LifecycleService) error {
for _, service := range services {
logger.Trace(stage, " ", service.Name())
startTime := time.Now()
err := service.Start(stage)
if err != nil {
return E.Cause(err, stage.String(), " ", service.Name())
}
logger.Trace(stage, " ", service.Name(), " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
}
return nil
}
================================================
FILE: adapter/lifecycle_legacy.go
================================================
package adapter
func LegacyStart(starter any, stage StartStage) error {
if lifecycle, isLifecycle := starter.(Lifecycle); isLifecycle {
return lifecycle.Start(stage)
}
switch stage {
case StartStateInitialize:
if preStarter, isPreStarter := starter.(interface {
PreStart() error
}); isPreStarter {
return preStarter.PreStart()
}
case StartStateStart:
if starter, isStarter := starter.(interface {
Start() error
}); isStarter {
return starter.Start()
}
case StartStateStarted:
if postStarter, isPostStarter := starter.(interface {
PostStart() error
}); isPostStarter {
return postStarter.PostStart()
}
}
return nil
}
type lifecycleServiceWrapper struct {
SimpleLifecycle
name string
}
func NewLifecycleService(service SimpleLifecycle, name string) LifecycleService {
return &lifecycleServiceWrapper{
SimpleLifecycle: service,
name: name,
}
}
func (l *lifecycleServiceWrapper) Name() string {
return l.name
}
func (l *lifecycleServiceWrapper) Start(stage StartStage) error {
return LegacyStart(l.SimpleLifecycle, stage)
}
func (l *lifecycleServiceWrapper) Close() error {
return l.SimpleLifecycle.Close()
}
================================================
FILE: adapter/neighbor.go
================================================
package adapter
import (
"net"
"net/netip"
)
type NeighborEntry struct {
Address netip.Addr
MACAddress net.HardwareAddr
Hostname string
}
type NeighborResolver interface {
LookupMAC(address netip.Addr) (net.HardwareAddr, bool)
LookupHostname(address netip.Addr) (string, bool)
Start() error
Close() error
}
type NeighborUpdateListener interface {
UpdateNeighborTable(entries []NeighborEntry)
}
================================================
FILE: adapter/network.go
================================================
package adapter
import (
"time"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-tun"
"github.com/sagernet/sing/common/control"
)
type NetworkManager interface {
Lifecycle
Initialize(ruleSets []RuleSet)
InterfaceFinder() control.InterfaceFinder
UpdateInterfaces() error
DefaultNetworkInterface() *NetworkInterface
NetworkInterfaces() []NetworkInterface
AutoDetectInterface() bool
AutoDetectInterfaceFunc() control.Func
ProtectFunc() control.Func
DefaultOptions() NetworkOptions
RegisterAutoRedirectOutputMark(mark uint32) error
AutoRedirectOutputMark() uint32
AutoRedirectOutputMarkFunc() control.Func
NetworkMonitor() tun.NetworkUpdateMonitor
InterfaceMonitor() tun.DefaultInterfaceMonitor
PackageManager() tun.PackageManager
NeedWIFIState() bool
WIFIState() WIFIState
UpdateWIFIState()
ResetNetwork()
}
type NetworkOptions struct {
BindInterface string
RoutingMark uint32
DomainResolver string
DomainResolveOptions DNSQueryOptions
NetworkStrategy *C.NetworkStrategy
NetworkType []C.InterfaceType
FallbackNetworkType []C.InterfaceType
FallbackDelay time.Duration
}
type InterfaceUpdateListener interface {
InterfaceUpdated()
}
type WIFIState struct {
SSID string
BSSID string
}
type NetworkInterface struct {
control.Interface
Type C.InterfaceType
DNSServers []string
Expensive bool
Constrained bool
}
================================================
FILE: adapter/outbound/adapter.go
================================================
package outbound
import (
"github.com/sagernet/sing-box/option"
)
type Adapter struct {
outboundType string
outboundTag string
network []string
dependencies []string
}
func NewAdapter(outboundType string, outboundTag string, network []string, dependencies []string) Adapter {
return Adapter{
outboundType: outboundType,
outboundTag: outboundTag,
network: network,
dependencies: dependencies,
}
}
func NewAdapterWithDialerOptions(outboundType string, outboundTag string, network []string, dialOptions option.DialerOptions) Adapter {
var dependencies []string
if dialOptions.Detour != "" {
dependencies = []string{dialOptions.Detour}
}
return NewAdapter(outboundType, outboundTag, network, dependencies)
}
func (a *Adapter) Type() string {
return a.outboundType
}
func (a *Adapter) Tag() string {
return a.outboundTag
}
func (a *Adapter) Network() []string {
return a.network
}
func (a *Adapter) Dependencies() []string {
return a.dependencies
}
================================================
FILE: adapter/outbound/manager.go
================================================
package outbound
import (
"context"
"io"
"os"
"strings"
"sync"
"time"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/taskmonitor"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
F "github.com/sagernet/sing/common/format"
"github.com/sagernet/sing/common/logger"
)
var _ adapter.OutboundManager = (*Manager)(nil)
type Manager struct {
logger log.ContextLogger
registry adapter.OutboundRegistry
endpoint adapter.EndpointManager
defaultTag string
access sync.RWMutex
started bool
stage adapter.StartStage
outbounds []adapter.Outbound
outboundByTag map[string]adapter.Outbound
dependByTag map[string][]string
defaultOutbound adapter.Outbound
defaultOutboundFallback func() (adapter.Outbound, error)
}
func NewManager(logger logger.ContextLogger, registry adapter.OutboundRegistry, endpoint adapter.EndpointManager, defaultTag string) *Manager {
return &Manager{
logger: logger,
registry: registry,
endpoint: endpoint,
defaultTag: defaultTag,
outboundByTag: make(map[string]adapter.Outbound),
dependByTag: make(map[string][]string),
}
}
func (m *Manager) Initialize(defaultOutboundFallback func() (adapter.Outbound, error)) {
m.defaultOutboundFallback = defaultOutboundFallback
}
func (m *Manager) Start(stage adapter.StartStage) error {
m.access.Lock()
if m.started && m.stage >= stage {
panic("already started")
}
m.started = true
m.stage = stage
if stage == adapter.StartStateStart {
if m.defaultTag != "" && m.defaultOutbound == nil {
defaultEndpoint, loaded := m.endpoint.Get(m.defaultTag)
if !loaded {
m.access.Unlock()
return E.New("default outbound not found: ", m.defaultTag)
}
m.defaultOutbound = defaultEndpoint
}
if m.defaultOutbound == nil {
directOutbound, err := m.defaultOutboundFallback()
if err != nil {
m.access.Unlock()
return E.Cause(err, "create direct outbound for fallback")
}
m.outbounds = append(m.outbounds, directOutbound)
m.outboundByTag[directOutbound.Tag()] = directOutbound
m.defaultOutbound = directOutbound
}
outbounds := m.outbounds
m.access.Unlock()
return m.startOutbounds(append(outbounds, common.Map(m.endpoint.Endpoints(), func(it adapter.Endpoint) adapter.Outbound { return it })...))
} else {
outbounds := m.outbounds
m.access.Unlock()
for _, outbound := range outbounds {
name := "outbound/" + outbound.Type() + "[" + outbound.Tag() + "]"
m.logger.Trace(stage, " ", name)
startTime := time.Now()
err := adapter.LegacyStart(outbound, stage)
if err != nil {
return E.Cause(err, stage, " ", name)
}
m.logger.Trace(stage, " ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
}
}
return nil
}
func (m *Manager) startOutbounds(outbounds []adapter.Outbound) error {
monitor := taskmonitor.New(m.logger, C.StartTimeout)
started := make(map[string]bool)
for {
canContinue := false
startOne:
for _, outboundToStart := range outbounds {
outboundTag := outboundToStart.Tag()
if started[outboundTag] {
continue
}
dependencies := outboundToStart.Dependencies()
for _, dependency := range dependencies {
if !started[dependency] {
continue startOne
}
}
started[outboundTag] = true
canContinue = true
name := "outbound/" + outboundToStart.Type() + "[" + outboundTag + "]"
if starter, isStarter := outboundToStart.(adapter.Lifecycle); isStarter {
m.logger.Trace("start ", name)
startTime := time.Now()
monitor.Start("start ", name)
err := starter.Start(adapter.StartStateStart)
monitor.Finish()
if err != nil {
return E.Cause(err, "start ", name)
}
m.logger.Trace("start ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
} else if starter, isStarter := outboundToStart.(interface {
Start() error
}); isStarter {
m.logger.Trace("start ", name)
startTime := time.Now()
monitor.Start("start ", name)
err := starter.Start()
monitor.Finish()
if err != nil {
return E.Cause(err, "start ", name)
}
m.logger.Trace("start ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
}
}
if len(started) == len(outbounds) {
break
}
if canContinue {
continue
}
currentOutbound := common.Find(outbounds, func(it adapter.Outbound) bool {
return !started[it.Tag()]
})
var lintOutbound func(oTree []string, oCurrent adapter.Outbound) error
lintOutbound = func(oTree []string, oCurrent adapter.Outbound) error {
problemOutboundTag := common.Find(oCurrent.Dependencies(), func(it string) bool {
return !started[it]
})
if common.Contains(oTree, problemOutboundTag) {
return E.New("circular outbound dependency: ", strings.Join(oTree, " -> "), " -> ", problemOutboundTag)
}
m.access.Lock()
problemOutbound := m.outboundByTag[problemOutboundTag]
m.access.Unlock()
if problemOutbound == nil {
return E.New("dependency[", problemOutboundTag, "] not found for outbound[", oCurrent.Tag(), "]")
}
return lintOutbound(append(oTree, problemOutboundTag), problemOutbound)
}
return lintOutbound([]string{currentOutbound.Tag()}, currentOutbound)
}
return nil
}
func (m *Manager) Close() error {
monitor := taskmonitor.New(m.logger, C.StopTimeout)
m.access.Lock()
if !m.started {
m.access.Unlock()
return nil
}
m.started = false
outbounds := m.outbounds
m.outbounds = nil
m.access.Unlock()
var err error
for _, outbound := range outbounds {
if closer, isCloser := outbound.(io.Closer); isCloser {
name := "outbound/" + outbound.Type() + "[" + outbound.Tag() + "]"
m.logger.Trace("close ", name)
startTime := time.Now()
monitor.Start("close ", name)
err = E.Append(err, closer.Close(), func(err error) error {
return E.Cause(err, "close ", name)
})
monitor.Finish()
m.logger.Trace("close ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
}
}
return nil
}
func (m *Manager) Outbounds() []adapter.Outbound {
m.access.RLock()
defer m.access.RUnlock()
return m.outbounds
}
func (m *Manager) Outbound(tag string) (adapter.Outbound, bool) {
m.access.RLock()
outbound, found := m.outboundByTag[tag]
m.access.RUnlock()
if found {
return outbound, true
}
return m.endpoint.Get(tag)
}
func (m *Manager) Default() adapter.Outbound {
m.access.RLock()
defer m.access.RUnlock()
return m.defaultOutbound
}
func (m *Manager) Remove(tag string) error {
m.access.Lock()
defer m.access.Unlock()
outbound, found := m.outboundByTag[tag]
if !found {
return os.ErrInvalid
}
delete(m.outboundByTag, tag)
index := common.Index(m.outbounds, func(it adapter.Outbound) bool {
return it == outbound
})
if index == -1 {
panic("invalid inbound index")
}
m.outbounds = append(m.outbounds[:index], m.outbounds[index+1:]...)
started := m.started
if m.defaultOutbound == outbound {
if len(m.outbounds) > 0 {
m.defaultOutbound = m.outbounds[0]
m.logger.Info("updated default outbound to ", m.defaultOutbound.Tag())
} else {
m.defaultOutbound = nil
}
}
dependBy := m.dependByTag[tag]
if len(dependBy) > 0 {
return E.New("outbound[", tag, "] is depended by ", strings.Join(dependBy, ", "))
}
dependencies := outbound.Dependencies()
for _, dependency := range dependencies {
if len(m.dependByTag[dependency]) == 1 {
delete(m.dependByTag, dependency)
} else {
m.dependByTag[dependency] = common.Filter(m.dependByTag[dependency], func(it string) bool {
return it != tag
})
}
}
if started {
return common.Close(outbound)
}
return nil
}
func (m *Manager) Create(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, inboundType string, options any) error {
if tag == "" {
return os.ErrInvalid
}
outbound, err := m.registry.CreateOutbound(ctx, router, logger, tag, inboundType, options)
if err != nil {
return err
}
if m.started {
name := "outbound/" + outbound.Type() + "[" + outbound.Tag() + "]"
for _, stage := range adapter.ListStartStages {
m.logger.Trace(stage, " ", name)
startTime := time.Now()
err = adapter.LegacyStart(outbound, stage)
if err != nil {
return E.Cause(err, stage, " ", name)
}
m.logger.Trace(stage, " ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
}
}
m.access.Lock()
defer m.access.Unlock()
if existsOutbound, loaded := m.outboundByTag[tag]; loaded {
if m.started {
err = common.Close(existsOutbound)
if err != nil {
return E.Cause(err, "close outbound/", existsOutbound.Type(), "[", existsOutbound.Tag(), "]")
}
}
existsIndex := common.Index(m.outbounds, func(it adapter.Outbound) bool {
return it == existsOutbound
})
if existsIndex == -1 {
panic("invalid inbound index")
}
m.outbounds = append(m.outbounds[:existsIndex], m.outbounds[existsIndex+1:]...)
}
m.outbounds = append(m.outbounds, outbound)
m.outboundByTag[tag] = outbound
dependencies := outbound.Dependencies()
for _, dependency := range dependencies {
m.dependByTag[dependency] = append(m.dependByTag[dependency], tag)
}
if tag == m.defaultTag || (m.defaultTag == "" && m.defaultOutbound == nil) {
m.defaultOutbound = outbound
if m.started {
m.logger.Info("updated default outbound to ", outbound.Tag())
}
}
return nil
}
================================================
FILE: adapter/outbound/registry.go
================================================
package outbound
import (
"context"
"sync"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
)
type ConstructorFunc[T any] func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options T) (adapter.Outbound, error)
func Register[Options any](registry *Registry, outboundType string, constructor ConstructorFunc[Options]) {
registry.register(outboundType, func() any {
return new(Options)
}, func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, rawOptions any) (adapter.Outbound, error) {
var options *Options
if rawOptions != nil {
options = rawOptions.(*Options)
}
return constructor(ctx, router, logger, tag, common.PtrValueOrDefault(options))
})
}
var _ adapter.OutboundRegistry = (*Registry)(nil)
type (
optionsConstructorFunc func() any
constructorFunc func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options any) (adapter.Outbound, error)
)
type Registry struct {
access sync.Mutex
optionsType map[string]optionsConstructorFunc
constructors map[string]constructorFunc
}
func NewRegistry() *Registry {
return &Registry{
optionsType: make(map[string]optionsConstructorFunc),
constructors: make(map[string]constructorFunc),
}
}
func (r *Registry) CreateOptions(outboundType string) (any, bool) {
r.access.Lock()
defer r.access.Unlock()
optionsConstructor, loaded := r.optionsType[outboundType]
if !loaded {
return nil, false
}
return optionsConstructor(), true
}
func (r *Registry) CreateOutbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, outboundType string, options any) (adapter.Outbound, error) {
r.access.Lock()
defer r.access.Unlock()
constructor, loaded := r.constructors[outboundType]
if !loaded {
return nil, E.New("outbound type not found: " + outboundType)
}
return constructor(ctx, router, logger, tag, options)
}
func (r *Registry) register(outboundType string, optionsConstructor optionsConstructorFunc, constructor constructorFunc) {
r.access.Lock()
defer r.access.Unlock()
r.optionsType[outboundType] = optionsConstructor
r.constructors[outboundType] = constructor
}
================================================
FILE: adapter/outbound.go
================================================
package adapter
import (
"context"
"net/netip"
"time"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-tun"
N "github.com/sagernet/sing/common/network"
)
// Note: for proxy protocols, outbound creates early connections by default.
type Outbound interface {
Type() string
Tag() string
Network() []string
Dependencies() []string
N.Dialer
}
type OutboundWithPreferredRoutes interface {
Outbound
PreferredDomain(domain string) bool
PreferredAddress(address netip.Addr) bool
}
type DirectRouteOutbound interface {
Outbound
NewDirectRouteConnection(metadata InboundContext, routeContext tun.DirectRouteContext, timeout time.Duration) (tun.DirectRouteDestination, error)
}
type OutboundRegistry interface {
option.OutboundOptionsRegistry
CreateOutbound(ctx context.Context, router Router, logger log.ContextLogger, tag string, outboundType string, options any) (Outbound, error)
}
type OutboundManager interface {
Lifecycle
Outbounds() []Outbound
Outbound(tag string) (Outbound, bool)
Default() Outbound
Remove(tag string) error
Create(ctx context.Context, router Router, logger log.ContextLogger, tag string, outboundType string, options any) error
}
================================================
FILE: adapter/platform.go
================================================
package adapter
import (
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-tun"
"github.com/sagernet/sing/common/logger"
)
type PlatformInterface interface {
Initialize(networkManager NetworkManager) error
UsePlatformAutoDetectInterfaceControl() bool
AutoDetectInterfaceControl(fd int) error
UsePlatformInterface() bool
OpenInterface(options *tun.Options, platformOptions option.TunPlatformOptions) (tun.Tun, error)
UsePlatformDefaultInterfaceMonitor() bool
CreateDefaultInterfaceMonitor(logger logger.Logger) tun.DefaultInterfaceMonitor
UsePlatformNetworkInterfaces() bool
NetworkInterfaces() ([]NetworkInterface, error)
UnderNetworkExtension() bool
NetworkExtensionIncludeAllNetworks() bool
ClearDNSCache()
RequestPermissionForWIFIState() error
ReadWIFIState() WIFIState
SystemCertificates() []string
UsePlatformConnectionOwnerFinder() bool
FindConnectionOwner(request *FindConnectionOwnerRequest) (*ConnectionOwner, error)
UsePlatformWIFIMonitor() bool
UsePlatformNotification() bool
SendNotification(notification *Notification) error
UsePlatformNeighborResolver() bool
StartNeighborMonitor(listener NeighborUpdateListener) error
CloseNeighborMonitor(listener NeighborUpdateListener) error
}
type FindConnectionOwnerRequest struct {
IpProtocol int32
SourceAddress string
SourcePort int32
DestinationAddress string
DestinationPort int32
}
type ConnectionOwner struct {
ProcessID uint32
UserId int32
UserName string
ProcessPath string
AndroidPackageName string
}
type Notification struct {
Identifier string
TypeName string
TypeID int32
Title string
Subtitle string
Body string
OpenURL string
}
type SystemProxyStatus struct {
Available bool
Enabled bool
}
================================================
FILE: adapter/prestart.go
================================================
package adapter
================================================
FILE: adapter/router.go
================================================
package adapter
import (
"context"
"crypto/tls"
"net"
"net/http"
"sync"
"time"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-tun"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
"github.com/sagernet/sing/common/ntp"
"github.com/sagernet/sing/common/x/list"
"go4.org/netipx"
)
type Router interface {
Lifecycle
ConnectionRouter
PreMatch(metadata InboundContext, context tun.DirectRouteContext, timeout time.Duration, supportBypass bool) (tun.DirectRouteDestination, error)
ConnectionRouterEx
RuleSet(tag string) (RuleSet, bool)
Rules() []Rule
NeedFindProcess() bool
NeedFindNeighbor() bool
NeighborResolver() NeighborResolver
AppendTracker(tracker ConnectionTracker)
ResetNetwork()
}
type ConnectionTracker interface {
RoutedConnection(ctx context.Context, conn net.Conn, metadata InboundContext, matchedRule Rule, matchOutbound Outbound) net.Conn
RoutedPacketConnection(ctx context.Context, conn N.PacketConn, metadata InboundContext, matchedRule Rule, matchOutbound Outbound) N.PacketConn
}
// Deprecated: Use ConnectionRouterEx instead.
type ConnectionRouter interface {
RouteConnection(ctx context.Context, conn net.Conn, metadata InboundContext) error
RoutePacketConnection(ctx context.Context, conn N.PacketConn, metadata InboundContext) error
}
type ConnectionRouterEx interface {
ConnectionRouter
RouteConnectionEx(ctx context.Context, conn net.Conn, metadata InboundContext, onClose N.CloseHandlerFunc)
RoutePacketConnectionEx(ctx context.Context, conn N.PacketConn, metadata InboundContext, onClose N.CloseHandlerFunc)
}
type RuleSet interface {
Name() string
StartContext(ctx context.Context, startContext *HTTPStartContext) error
PostStart() error
Metadata() RuleSetMetadata
ExtractIPSet() []*netipx.IPSet
IncRef()
DecRef()
Cleanup()
RegisterCallback(callback RuleSetUpdateCallback) *list.Element[RuleSetUpdateCallback]
UnregisterCallback(element *list.Element[RuleSetUpdateCallback])
Close() error
HeadlessRule
}
type RuleSetUpdateCallback func(it RuleSet)
type RuleSetMetadata struct {
ContainsProcessRule bool
ContainsWIFIRule bool
ContainsIPCIDRRule bool
}
type HTTPStartContext struct {
ctx context.Context
access sync.Mutex
httpClientCache map[string]*http.Client
}
func NewHTTPStartContext(ctx context.Context) *HTTPStartContext {
return &HTTPStartContext{
ctx: ctx,
httpClientCache: make(map[string]*http.Client),
}
}
func (c *HTTPStartContext) HTTPClient(detour string, dialer N.Dialer) *http.Client {
c.access.Lock()
defer c.access.Unlock()
if httpClient, loaded := c.httpClientCache[detour]; loaded {
return httpClient
}
httpClient := &http.Client{
Transport: &http.Transport{
ForceAttemptHTTP2: true,
TLSHandshakeTimeout: C.TCPTimeout,
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
return dialer.DialContext(ctx, network, M.ParseSocksaddr(addr))
},
TLSClientConfig: &tls.Config{
Time: ntp.TimeFuncFromContext(c.ctx),
RootCAs: RootPoolFromContext(c.ctx),
},
},
}
c.httpClientCache[detour] = httpClient
return httpClient
}
func (c *HTTPStartContext) Close() {
c.access.Lock()
defer c.access.Unlock()
for _, client := range c.httpClientCache {
client.CloseIdleConnections()
}
}
================================================
FILE: adapter/rule.go
================================================
package adapter
import (
C "github.com/sagernet/sing-box/constant"
)
type HeadlessRule interface {
Match(metadata *InboundContext) bool
String() string
}
type Rule interface {
HeadlessRule
SimpleLifecycle
Type() string
Action() RuleAction
}
type DNSRule interface {
Rule
WithAddressLimit() bool
MatchAddressLimit(metadata *InboundContext) bool
}
type RuleAction interface {
Type() string
String() string
}
func IsFinalAction(action RuleAction) bool {
switch action.Type() {
case C.RuleActionTypeSniff, C.RuleActionTypeResolve:
return false
default:
return true
}
}
================================================
FILE: adapter/service/adapter.go
================================================
package service
type Adapter struct {
serviceType string
serviceTag string
}
func NewAdapter(serviceType string, serviceTag string) Adapter {
return Adapter{
serviceType: serviceType,
serviceTag: serviceTag,
}
}
func (a *Adapter) Type() string {
return a.serviceType
}
func (a *Adapter) Tag() string {
return a.serviceTag
}
================================================
FILE: adapter/service/manager.go
================================================
package service
import (
"context"
"os"
"sync"
"time"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/taskmonitor"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
F "github.com/sagernet/sing/common/format"
)
var _ adapter.ServiceManager = (*Manager)(nil)
type Manager struct {
logger log.ContextLogger
registry adapter.ServiceRegistry
access sync.Mutex
started bool
stage adapter.StartStage
services []adapter.Service
serviceByTag map[string]adapter.Service
}
func NewManager(logger log.ContextLogger, registry adapter.ServiceRegistry) *Manager {
return &Manager{
logger: logger,
registry: registry,
serviceByTag: make(map[string]adapter.Service),
}
}
func (m *Manager) Start(stage adapter.StartStage) error {
m.access.Lock()
if m.started && m.stage >= stage {
panic("already started")
}
m.started = true
m.stage = stage
services := m.services
m.access.Unlock()
for _, service := range services {
name := "service/" + service.Type() + "[" + service.Tag() + "]"
m.logger.Trace(stage, " ", name)
startTime := time.Now()
err := adapter.LegacyStart(service, stage)
if err != nil {
return E.Cause(err, stage, " ", name)
}
m.logger.Trace(stage, " ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
}
return nil
}
func (m *Manager) Close() error {
m.access.Lock()
defer m.access.Unlock()
if !m.started {
return nil
}
m.started = false
services := m.services
m.services = nil
monitor := taskmonitor.New(m.logger, C.StopTimeout)
var err error
for _, service := range services {
name := "service/" + service.Type() + "[" + service.Tag() + "]"
m.logger.Trace("close ", name)
startTime := time.Now()
monitor.Start("close ", name)
err = E.Append(err, service.Close(), func(err error) error {
return E.Cause(err, "close ", name)
})
monitor.Finish()
m.logger.Trace("close ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
}
return nil
}
func (m *Manager) Services() []adapter.Service {
m.access.Lock()
defer m.access.Unlock()
return m.services
}
func (m *Manager) Get(tag string) (adapter.Service, bool) {
m.access.Lock()
service, found := m.serviceByTag[tag]
m.access.Unlock()
return service, found
}
func (m *Manager) Remove(tag string) error {
m.access.Lock()
service, found := m.serviceByTag[tag]
if !found {
m.access.Unlock()
return os.ErrInvalid
}
delete(m.serviceByTag, tag)
index := common.Index(m.services, func(it adapter.Service) bool {
return it == service
})
if index == -1 {
panic("invalid service index")
}
m.services = append(m.services[:index], m.services[index+1:]...)
started := m.started
m.access.Unlock()
if started {
return service.Close()
}
return nil
}
func (m *Manager) Create(ctx context.Context, logger log.ContextLogger, tag string, serviceType string, options any) error {
service, err := m.registry.Create(ctx, logger, tag, serviceType, options)
if err != nil {
return err
}
m.access.Lock()
defer m.access.Unlock()
if m.started {
name := "service/" + service.Type() + "[" + service.Tag() + "]"
for _, stage := range adapter.ListStartStages {
m.logger.Trace(stage, " ", name)
startTime := time.Now()
err = adapter.LegacyStart(service, stage)
if err != nil {
return E.Cause(err, stage, " ", name)
}
m.logger.Trace(stage, " ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
}
}
if existsService, loaded := m.serviceByTag[tag]; loaded {
if m.started {
err = existsService.Close()
if err != nil {
return E.Cause(err, "close service/", existsService.Type(), "[", existsService.Tag(), "]")
}
}
existsIndex := common.Index(m.services, func(it adapter.Service) bool {
return it == existsService
})
if existsIndex == -1 {
panic("invalid service index")
}
m.services = append(m.services[:existsIndex], m.services[existsIndex+1:]...)
}
m.services = append(m.services, service)
m.serviceByTag[tag] = service
return nil
}
================================================
FILE: adapter/service/registry.go
================================================
package service
import (
"context"
"sync"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
)
type ConstructorFunc[T any] func(ctx context.Context, logger log.ContextLogger, tag string, options T) (adapter.Service, error)
func Register[Options any](registry *Registry, outboundType string, constructor ConstructorFunc[Options]) {
registry.register(outboundType, func() any {
return new(Options)
}, func(ctx context.Context, logger log.ContextLogger, tag string, rawOptions any) (adapter.Service, error) {
var options *Options
if rawOptions != nil {
options = rawOptions.(*Options)
}
return constructor(ctx, logger, tag, common.PtrValueOrDefault(options))
})
}
var _ adapter.ServiceRegistry = (*Registry)(nil)
type (
optionsConstructorFunc func() any
constructorFunc func(ctx context.Context, logger log.ContextLogger, tag string, options any) (adapter.Service, error)
)
type Registry struct {
access sync.Mutex
optionsType map[string]optionsConstructorFunc
constructor map[string]constructorFunc
}
func NewRegistry() *Registry {
return &Registry{
optionsType: make(map[string]optionsConstructorFunc),
constructor: make(map[string]constructorFunc),
}
}
func (m *Registry) CreateOptions(outboundType string) (any, bool) {
m.access.Lock()
defer m.access.Unlock()
optionsConstructor, loaded := m.optionsType[outboundType]
if !loaded {
return nil, false
}
return optionsConstructor(), true
}
func (m *Registry) Create(ctx context.Context, logger log.ContextLogger, tag string, outboundType string, options any) (adapter.Service, error) {
m.access.Lock()
defer m.access.Unlock()
constructor, loaded := m.constructor[outboundType]
if !loaded {
return nil, E.New("outbound type not found: " + outboundType)
}
return constructor(ctx, logger, tag, options)
}
func (m *Registry) register(outboundType string, optionsConstructor optionsConstructorFunc, constructor constructorFunc) {
m.access.Lock()
defer m.access.Unlock()
m.optionsType[outboundType] = optionsConstructor
m.constructor[outboundType] = constructor
}
================================================
FILE: adapter/service.go
================================================
package adapter
import (
"context"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
)
type Service interface {
Lifecycle
Type() string
Tag() string
}
type ServiceRegistry interface {
option.ServiceOptionsRegistry
Create(ctx context.Context, logger log.ContextLogger, tag string, serviceType string, options any) (Service, error)
}
type ServiceManager interface {
Lifecycle
Services() []Service
Get(tag string) (Service, bool)
Remove(tag string) error
Create(ctx context.Context, logger log.ContextLogger, tag string, serviceType string, options any) error
}
================================================
FILE: adapter/ssm.go
================================================
package adapter
import (
"net"
N "github.com/sagernet/sing/common/network"
)
type ManagedSSMServer interface {
Inbound
SetTracker(tracker SSMTracker)
UpdateUsers(users []string, uPSKs []string) error
}
type SSMTracker interface {
TrackConnection(conn net.Conn, metadata InboundContext) net.Conn
TrackPacketConnection(conn N.PacketConn, metadata InboundContext) N.PacketConn
}
================================================
FILE: adapter/time.go
================================================
package adapter
import "time"
type TimeService interface {
SimpleLifecycle
TimeFunc() func() time.Time
}
================================================
FILE: adapter/upstream.go
================================================
package adapter
import (
"context"
"net"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
)
type (
ConnectionHandlerFuncEx = func(ctx context.Context, conn net.Conn, metadata InboundContext, onClose N.CloseHandlerFunc)
PacketConnectionHandlerFuncEx = func(ctx context.Context, conn N.PacketConn, metadata InboundContext, onClose N.CloseHandlerFunc)
)
func NewUpstreamHandlerEx(
metadata InboundContext,
connectionHandler ConnectionHandlerFuncEx,
packetHandler PacketConnectionHandlerFuncEx,
) UpstreamHandlerAdapterEx {
return &myUpstreamHandlerWrapperEx{
metadata: metadata,
connectionHandler: connectionHandler,
packetHandler: packetHandler,
}
}
var _ UpstreamHandlerAdapterEx = (*myUpstreamHandlerWrapperEx)(nil)
type myUpstreamHandlerWrapperEx struct {
metadata InboundContext
connectionHandler ConnectionHandlerFuncEx
packetHandler PacketConnectionHandlerFuncEx
}
func (w *myUpstreamHandlerWrapperEx) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
myMetadata := w.metadata
if source.IsValid() {
myMetadata.Source = source
}
if destination.IsValid() {
myMetadata.Destination = destination
}
w.connectionHandler(ctx, conn, myMetadata, onClose)
}
func (w *myUpstreamHandlerWrapperEx) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
myMetadata := w.metadata
if source.IsValid() {
myMetadata.Source = source
}
if destination.IsValid() {
myMetadata.Destination = destination
}
w.packetHandler(ctx, conn, myMetadata, onClose)
}
var _ UpstreamHandlerAdapterEx = (*myUpstreamContextHandlerWrapperEx)(nil)
type myUpstreamContextHandlerWrapperEx struct {
connectionHandler ConnectionHandlerFuncEx
packetHandler PacketConnectionHandlerFuncEx
}
func NewUpstreamContextHandlerEx(
connectionHandler ConnectionHandlerFuncEx,
packetHandler PacketConnectionHandlerFuncEx,
) UpstreamHandlerAdapterEx {
return &myUpstreamContextHandlerWrapperEx{
connectionHandler: connectionHandler,
packetHandler: packetHandler,
}
}
func (w *myUpstreamContextHandlerWrapperEx) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
_, myMetadata := ExtendContext(ctx)
if source.IsValid() {
myMetadata.Source = source
}
if destination.IsValid() {
myMetadata.Destination = destination
}
w.connectionHandler(ctx, conn, *myMetadata, onClose)
}
func (w *myUpstreamContextHandlerWrapperEx) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
_, myMetadata := ExtendContext(ctx)
if source.IsValid() {
myMetadata.Source = source
}
if destination.IsValid() {
myMetadata.Destination = destination
}
w.packetHandler(ctx, conn, *myMetadata, onClose)
}
func NewRouteHandlerEx(
metadata InboundContext,
router ConnectionRouterEx,
) UpstreamHandlerAdapterEx {
return &routeHandlerWrapperEx{
metadata: metadata,
router: router,
}
}
var _ UpstreamHandlerAdapterEx = (*routeHandlerWrapperEx)(nil)
type routeHandlerWrapperEx struct {
metadata InboundContext
router ConnectionRouterEx
}
func (r *routeHandlerWrapperEx) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
if source.IsValid() {
r.metadata.Source = source
}
if destination.IsValid() {
r.metadata.Destination = destination
}
r.router.RouteConnectionEx(ctx, conn, r.metadata, onClose)
}
func (r *routeHandlerWrapperEx) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
if source.IsValid() {
r.metadata.Source = source
}
if destination.IsValid() {
r.metadata.Destination = destination
}
r.router.RoutePacketConnectionEx(ctx, conn, r.metadata, onClose)
}
func NewRouteContextHandlerEx(
router ConnectionRouterEx,
) UpstreamHandlerAdapterEx {
return &routeContextHandlerWrapperEx{
router: router,
}
}
var _ UpstreamHandlerAdapterEx = (*routeContextHandlerWrapperEx)(nil)
type routeContextHandlerWrapperEx struct {
router ConnectionRouterEx
}
func (r *routeContextHandlerWrapperEx) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
_, metadata := ExtendContext(ctx)
if source.IsValid() {
metadata.Source = source
}
if destination.IsValid() {
metadata.Destination = destination
}
r.router.RouteConnectionEx(ctx, conn, *metadata, onClose)
}
func (r *routeContextHandlerWrapperEx) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
_, metadata := ExtendContext(ctx)
if source.IsValid() {
metadata.Source = source
}
if destination.IsValid() {
metadata.Destination = destination
}
r.router.RoutePacketConnectionEx(ctx, conn, *metadata, onClose)
}
================================================
FILE: adapter/upstream_legacy.go
================================================
package adapter
import (
"context"
"net"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/logger"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
)
type (
// Deprecated
ConnectionHandlerFunc = func(ctx context.Context, conn net.Conn, metadata InboundContext) error
// Deprecated
PacketConnectionHandlerFunc = func(ctx context.Context, conn N.PacketConn, metadata InboundContext) error
)
// Deprecated
//
//nolint:staticcheck
func NewUpstreamHandler(
metadata InboundContext,
connectionHandler ConnectionHandlerFunc,
packetHandler PacketConnectionHandlerFunc,
errorHandler E.Handler,
) UpstreamHandlerAdapter {
return &myUpstreamHandlerWrapper{
metadata: metadata,
connectionHandler: connectionHandler,
packetHandler: packetHandler,
errorHandler: errorHandler,
}
}
var _ UpstreamHandlerAdapter = (*myUpstreamHandlerWrapper)(nil)
// Deprecated: use myUpstreamHandlerWrapperEx instead.
//
//nolint:staticcheck
type myUpstreamHandlerWrapper struct {
metadata InboundContext
connectionHandler ConnectionHandlerFunc
packetHandler PacketConnectionHandlerFunc
errorHandler E.Handler
}
// Deprecated: use myUpstreamHandlerWrapperEx instead.
func (w *myUpstreamHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
myMetadata := w.metadata
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.connectionHandler(ctx, conn, myMetadata)
}
// Deprecated: use myUpstreamHandlerWrapperEx instead.
func (w *myUpstreamHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
myMetadata := w.metadata
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.packetHandler(ctx, conn, myMetadata)
}
// Deprecated: use myUpstreamHandlerWrapperEx instead.
func (w *myUpstreamHandlerWrapper) NewError(ctx context.Context, err error) {
w.errorHandler.NewError(ctx, err)
}
// Deprecated: removed
func UpstreamMetadata(metadata InboundContext) M.Metadata {
return M.Metadata{
Source: metadata.Source.Unwrap(),
Destination: metadata.Destination.Unwrap(),
}
}
// Deprecated: Use NewUpstreamContextHandlerEx instead.
type myUpstreamContextHandlerWrapper struct {
connectionHandler ConnectionHandlerFunc
packetHandler PacketConnectionHandlerFunc
errorHandler E.Handler
}
// Deprecated: Use NewUpstreamContextHandlerEx instead.
func NewUpstreamContextHandler(
connectionHandler ConnectionHandlerFunc,
packetHandler PacketConnectionHandlerFunc,
errorHandler E.Handler,
) UpstreamHandlerAdapter {
return &myUpstreamContextHandlerWrapper{
connectionHandler: connectionHandler,
packetHandler: packetHandler,
errorHandler: errorHandler,
}
}
// Deprecated: Use NewUpstreamContextHandlerEx instead.
func (w *myUpstreamContextHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
myMetadata := ContextFrom(ctx)
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.connectionHandler(ctx, conn, *myMetadata)
}
// Deprecated: Use NewUpstreamContextHandlerEx instead.
func (w *myUpstreamContextHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
myMetadata := ContextFrom(ctx)
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.packetHandler(ctx, conn, *myMetadata)
}
// Deprecated: Use NewUpstreamContextHandlerEx instead.
func (w *myUpstreamContextHandlerWrapper) NewError(ctx context.Context, err error) {
w.errorHandler.NewError(ctx, err)
}
// Deprecated: Use ConnectionRouterEx instead.
func NewRouteHandler(
metadata InboundContext,
router ConnectionRouter,
logger logger.ContextLogger,
) UpstreamHandlerAdapter {
return &routeHandlerWrapper{
metadata: metadata,
router: router,
logger: logger,
}
}
// Deprecated: Use ConnectionRouterEx instead.
func NewRouteContextHandler(
router ConnectionRouter,
logger logger.ContextLogger,
) UpstreamHandlerAdapter {
return &routeContextHandlerWrapper{
router: router,
logger: logger,
}
}
var _ UpstreamHandlerAdapter = (*routeHandlerWrapper)(nil)
// Deprecated: Use ConnectionRouterEx instead.
//
//nolint:staticcheck
type routeHandlerWrapper struct {
metadata InboundContext
router ConnectionRouter
logger logger.ContextLogger
}
// Deprecated: Use ConnectionRouterEx instead.
func (w *routeHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
myMetadata := w.metadata
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.router.RouteConnection(ctx, conn, myMetadata)
}
// Deprecated: Use ConnectionRouterEx instead.
func (w *routeHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
myMetadata := w.metadata
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.router.RoutePacketConnection(ctx, conn, myMetadata)
}
// Deprecated: Use ConnectionRouterEx instead.
func (w *routeHandlerWrapper) NewError(ctx context.Context, err error) {
w.logger.ErrorContext(ctx, err)
}
var _ UpstreamHandlerAdapter = (*routeContextHandlerWrapper)(nil)
// Deprecated: Use ConnectionRouterEx instead.
type routeContextHandlerWrapper struct {
router ConnectionRouter
logger logger.ContextLogger
}
// Deprecated: Use ConnectionRouterEx instead.
func (w *routeContextHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
myMetadata := ContextFrom(ctx)
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.router.RouteConnection(ctx, conn, *myMetadata)
}
// Deprecated: Use ConnectionRouterEx instead.
func (w *routeContextHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
myMetadata := ContextFrom(ctx)
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.router.RoutePacketConnection(ctx, conn, *myMetadata)
}
// Deprecated: Use ConnectionRouterEx instead.
func (w *routeContextHandlerWrapper) NewError(ctx context.Context, err error) {
w.logger.ErrorContext(ctx, err)
}
================================================
FILE: adapter/v2ray.go
================================================
package adapter
import (
"context"
"net"
N "github.com/sagernet/sing/common/network"
)
type V2RayServerTransport interface {
Network() []string
Serve(listener net.Listener) error
ServePacket(listener net.PacketConn) error
Close() error
}
type V2RayServerTransportHandler interface {
N.TCPConnectionHandlerEx
}
type V2RayClientTransport interface {
DialContext(ctx context.Context) (net.Conn, error)
Close() error
}
================================================
FILE: box.go
================================================
package box
import (
"context"
"fmt"
"io"
"os"
"runtime/debug"
"time"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/adapter/endpoint"
"github.com/sagernet/sing-box/adapter/inbound"
"github.com/sagernet/sing-box/adapter/outbound"
boxService "github.com/sagernet/sing-box/adapter/service"
"github.com/sagernet/sing-box/common/certificate"
"github.com/sagernet/sing-box/common/dialer"
"github.com/sagernet/sing-box/common/taskmonitor"
"github.com/sagernet/sing-box/common/tls"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/dns"
"github.com/sagernet/sing-box/dns/transport/local"
"github.com/sagernet/sing-box/experimental"
"github.com/sagernet/sing-box/experimental/cachefile"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-box/protocol/direct"
"github.com/sagernet/sing-box/route"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
F "github.com/sagernet/sing/common/format"
"github.com/sagernet/sing/common/ntp"
"github.com/sagernet/sing/service"
"github.com/sagernet/sing/service/pause"
)
var _ adapter.SimpleLifecycle = (*Box)(nil)
type Box struct {
createdAt time.Time
logFactory log.Factory
logger log.ContextLogger
network *route.NetworkManager
endpoint *endpoint.Manager
inbound *inbound.Manager
outbound *outbound.Manager
service *boxService.Manager
dnsTransport *dns.TransportManager
dnsRouter *dns.Router
connection *route.ConnectionManager
router *route.Router
internalService []adapter.LifecycleService
done chan struct{}
}
type Options struct {
option.Options
Context context.Context
PlatformLogWriter log.PlatformWriter
}
func Context(
ctx context.Context,
inboundRegistry adapter.InboundRegistry,
outboundRegistry adapter.OutboundRegistry,
endpointRegistry adapter.EndpointRegistry,
dnsTransportRegistry adapter.DNSTransportRegistry,
serviceRegistry adapter.ServiceRegistry,
) context.Context {
if service.FromContext[option.InboundOptionsRegistry](ctx) == nil ||
service.FromContext[adapter.InboundRegistry](ctx) == nil {
ctx = service.ContextWith[option.InboundOptionsRegistry](ctx, inboundRegistry)
ctx = service.ContextWith[adapter.InboundRegistry](ctx, inboundRegistry)
}
if service.FromContext[option.OutboundOptionsRegistry](ctx) == nil ||
service.FromContext[adapter.OutboundRegistry](ctx) == nil {
ctx = service.ContextWith[option.OutboundOptionsRegistry](ctx, outboundRegistry)
ctx = service.ContextWith[adapter.OutboundRegistry](ctx, outboundRegistry)
}
if service.FromContext[option.EndpointOptionsRegistry](ctx) == nil ||
service.FromContext[adapter.EndpointRegistry](ctx) == nil {
ctx = service.ContextWith[option.EndpointOptionsRegistry](ctx, endpointRegistry)
ctx = service.ContextWith[adapter.EndpointRegistry](ctx, endpointRegistry)
}
if service.FromContext[adapter.DNSTransportRegistry](ctx) == nil {
ctx = service.ContextWith[option.DNSTransportOptionsRegistry](ctx, dnsTransportRegistry)
ctx = service.ContextWith[adapter.DNSTransportRegistry](ctx, dnsTransportRegistry)
}
if service.FromContext[adapter.ServiceRegistry](ctx) == nil {
ctx = service.ContextWith[option.ServiceOptionsRegistry](ctx, serviceRegistry)
ctx = service.ContextWith[adapter.ServiceRegistry](ctx, serviceRegistry)
}
return ctx
}
func New(options Options) (*Box, error) {
createdAt := time.Now()
ctx := options.Context
if ctx == nil {
ctx = context.Background()
}
ctx = service.ContextWithDefaultRegistry(ctx)
endpointRegistry := service.FromContext[adapter.EndpointRegistry](ctx)
inboundRegistry := service.FromContext[adapter.InboundRegistry](ctx)
outboundRegistry := service.FromContext[adapter.OutboundRegistry](ctx)
dnsTransportRegistry := service.FromContext[adapter.DNSTransportRegistry](ctx)
serviceRegistry := service.FromContext[adapter.ServiceRegistry](ctx)
if endpointRegistry == nil {
return nil, E.New("missing endpoint registry in context")
}
if inboundRegistry == nil {
return nil, E.New("missing inbound registry in context")
}
if outboundRegistry == nil {
return nil, E.New("missing outbound registry in context")
}
if dnsTransportRegistry == nil {
return nil, E.New("missing DNS transport registry in context")
}
if serviceRegistry == nil {
return nil, E.New("missing service registry in context")
}
ctx = pause.WithDefaultManager(ctx)
experimentalOptions := common.PtrValueOrDefault(options.Experimental)
err := applyDebugOptions(common.PtrValueOrDefault(experimentalOptions.Debug))
if err != nil {
return nil, err
}
var needCacheFile bool
var needClashAPI bool
var needV2RayAPI bool
if experimentalOptions.CacheFile != nil && experimentalOptions.CacheFile.Enabled || options.PlatformLogWriter != nil {
needCacheFile = true
}
if experimentalOptions.ClashAPI != nil || options.PlatformLogWriter != nil {
needClashAPI = true
}
if experimentalOptions.V2RayAPI != nil && experimentalOptions.V2RayAPI.Listen != "" {
needV2RayAPI = true
}
platformInterface := service.FromContext[adapter.PlatformInterface](ctx)
var defaultLogWriter io.Writer
if platformInterface != nil {
defaultLogWriter = io.Discard
}
logFactory, err := log.New(log.Options{
Context: ctx,
Options: common.PtrValueOrDefault(options.Log),
Observable: needClashAPI,
DefaultWriter: defaultLogWriter,
BaseTime: createdAt,
PlatformWriter: options.PlatformLogWriter,
})
if err != nil {
return nil, E.Cause(err, "create log factory")
}
var internalServices []adapter.LifecycleService
certificateOptions := common.PtrValueOrDefault(options.Certificate)
if C.IsAndroid || certificateOptions.Store != "" && certificateOptions.Store != C.CertificateStoreSystem ||
len(certificateOptions.Certificate) > 0 ||
len(certificateOptions.CertificatePath) > 0 ||
len(certificateOptions.CertificateDirectoryPath) > 0 {
certificateStore, err := certificate.NewStore(ctx, logFactory.NewLogger("certificate"), certificateOptions)
if err != nil {
return nil, err
}
service.MustRegister[adapter.CertificateStore](ctx, certificateStore)
internalServices = append(internalServices, certificateStore)
}
routeOptions := common.PtrValueOrDefault(options.Route)
dnsOptions := common.PtrValueOrDefault(options.DNS)
endpointManager := endpoint.NewManager(logFactory.NewLogger("endpoint"), endpointRegistry)
inboundManager := inbound.NewManager(logFactory.NewLogger("inbound"), inboundRegistry, endpointManager)
outboundManager := outbound.NewManager(logFactory.NewLogger("outbound"), outboundRegistry, endpointManager, routeOptions.Final)
dnsTransportManager := dns.NewTransportManager(logFactory.NewLogger("dns/transport"), dnsTransportRegistry, outboundManager, dnsOptions.Final)
serviceManager := boxService.NewManager(logFactory.NewLogger("service"), serviceRegistry)
service.MustRegister[adapter.EndpointManager](ctx, endpointManager)
service.MustRegister[adapter.InboundManager](ctx, inboundManager)
service.MustRegister[adapter.OutboundManager](ctx, outboundManager)
service.MustRegister[adapter.DNSTransportManager](ctx, dnsTransportManager)
service.MustRegister[adapter.ServiceManager](ctx, serviceManager)
dnsRouter := dns.NewRouter(ctx, logFactory, dnsOptions)
service.MustRegister[adapter.DNSRouter](ctx, dnsRouter)
networkManager, err := route.NewNetworkManager(ctx, logFactory.NewLogger("network"), routeOptions, dnsOptions)
if err != nil {
return nil, E.Cause(err, "initialize network manager")
}
service.MustRegister[adapter.NetworkManager](ctx, networkManager)
connectionManager := route.NewConnectionManager(logFactory.NewLogger("connection"))
service.MustRegister[adapter.ConnectionManager](ctx, connectionManager)
router := route.NewRouter(ctx, logFactory, routeOptions, dnsOptions)
service.MustRegister[adapter.Router](ctx, router)
err = router.Initialize(routeOptions.Rules, routeOptions.RuleSet)
if err != nil {
return nil, E.Cause(err, "initialize router")
}
ntpOptions := common.PtrValueOrDefault(options.NTP)
var timeService *tls.TimeServiceWrapper
if ntpOptions.Enabled {
timeService = new(tls.TimeServiceWrapper)
service.MustRegister[ntp.TimeService](ctx, timeService)
}
for i, transportOptions := range dnsOptions.Servers {
var tag string
if transportOptions.Tag != "" {
tag = transportOptions.Tag
} else {
tag = F.ToString(i)
}
err = dnsTransportManager.Create(
ctx,
logFactory.NewLogger(F.ToString("dns/", transportOptions.Type, "[", tag, "]")),
tag,
transportOptions.Type,
transportOptions.Options,
)
if err != nil {
return nil, E.Cause(err, "initialize DNS server[", i, "]")
}
}
err = dnsRouter.Initialize(dnsOptions.Rules)
if err != nil {
return nil, E.Cause(err, "initialize dns router")
}
for i, endpointOptions := range options.Endpoints {
var tag string
if endpointOptions.Tag != "" {
tag = endpointOptions.Tag
} else {
tag = F.ToString(i)
}
endpointCtx := ctx
if tag != "" {
// TODO: remove this
endpointCtx = adapter.WithContext(endpointCtx, &adapter.InboundContext{
Outbound: tag,
})
}
err = endpointManager.Create(
endpointCtx,
router,
logFactory.NewLogger(F.ToString("endpoint/", endpointOptions.Type, "[", tag, "]")),
tag,
endpointOptions.Type,
endpointOptions.Options,
)
if err != nil {
return nil, E.Cause(err, "initialize endpoint[", i, "]")
}
}
for i, inboundOptions := range options.Inbounds {
var tag string
if inboundOptions.Tag != "" {
tag = inboundOptions.Tag
} else {
tag = F.ToString(i)
}
err = inboundManager.Create(
ctx,
router,
logFactory.NewLogger(F.ToString("inbound/", inboundOptions.Type, "[", tag, "]")),
tag,
inboundOptions.Type,
inboundOptions.Options,
)
if err != nil {
return nil, E.Cause(err, "initialize inbound[", i, "]")
}
}
for i, outboundOptions := range options.Outbounds {
var tag string
if outboundOptions.Tag != "" {
tag = outboundOptions.Tag
} else {
tag = F.ToString(i)
}
outboundCtx := ctx
if tag != "" {
// TODO: remove this
outboundCtx = adapter.WithContext(outboundCtx, &adapter.InboundContext{
Outbound: tag,
})
}
err = outboundManager.Create(
outboundCtx,
router,
logFactory.NewLogger(F.ToString("outbound/", outboundOptions.Type, "[", tag, "]")),
tag,
outboundOptions.Type,
outboundOptions.Options,
)
if err != nil {
return nil, E.Cause(err, "initialize outbound[", i, "]")
}
}
for i, serviceOptions := range options.Services {
var tag string
if serviceOptions.Tag != "" {
tag = serviceOptions.Tag
} else {
tag = F.ToString(i)
}
err = serviceManager.Create(
ctx,
logFactory.NewLogger(F.ToString("service/", serviceOptions.Type, "[", tag, "]")),
tag,
serviceOptions.Type,
serviceOptions.Options,
)
if err != nil {
return nil, E.Cause(err, "initialize service[", i, "]")
}
}
outboundManager.Initialize(func() (adapter.Outbound, error) {
return direct.NewOutbound(
ctx,
router,
logFactory.NewLogger("outbound/direct"),
"direct",
option.DirectOutboundOptions{},
)
})
dnsTransportManager.Initialize(func() (adapter.DNSTransport, error) {
return local.NewTransport(
ctx,
logFactory.NewLogger("dns/local"),
"local",
option.LocalDNSServerOptions{},
)
})
if platformInterface != nil {
err = platformInterface.Initialize(networkManager)
if err != nil {
return nil, E.Cause(err, "initialize platform interface")
}
}
if needCacheFile {
cacheFile := cachefile.New(ctx, common.PtrValueOrDefault(experimentalOptions.CacheFile))
service.MustRegister[adapter.CacheFile](ctx, cacheFile)
internalServices = append(internalServices, cacheFile)
}
if needClashAPI {
clashAPIOptions := common.PtrValueOrDefault(experimentalOptions.ClashAPI)
clashAPIOptions.ModeList = experimental.CalculateClashModeList(options.Options)
clashServer, err := experimental.NewClashServer(ctx, logFactory.(log.ObservableFactory), clashAPIOptions)
if err != nil {
return nil, E.Cause(err, "create clash-server")
}
router.AppendTracker(clashServer)
service.MustRegister[adapter.ClashServer](ctx, clashServer)
internalServices = append(internalServices, clashServer)
}
if needV2RayAPI {
v2rayServer, err := experimental.NewV2RayServer(logFactory.NewLogger("v2ray-api"), common.PtrValueOrDefault(experimentalOptions.V2RayAPI))
if err != nil {
return nil, E.Cause(err, "create v2ray-server")
}
if v2rayServer.StatsService() != nil {
router.AppendTracker(v2rayServer.StatsService())
internalServices = append(internalServices, v2rayServer)
service.MustRegister[adapter.V2RayServer](ctx, v2rayServer)
}
}
if ntpOptions.Enabled {
ntpDialer, err := dialer.New(ctx, ntpOptions.DialerOptions, ntpOptions.ServerIsDomain())
if err != nil {
return nil, E.Cause(err, "create NTP service")
}
ntpService := ntp.NewService(ntp.Options{
Context: ctx,
Dialer: ntpDialer,
Logger: logFactory.NewLogger("ntp"),
Server: ntpOptions.ServerOptions.Build(),
Interval: time.Duration(ntpOptions.Interval),
WriteToSystem: ntpOptions.WriteToSystem,
})
timeService.TimeService = ntpService
internalServices = append(internalServices, adapter.NewLifecycleService(ntpService, "ntp service"))
}
return &Box{
network: networkManager,
endpoint: endpointManager,
inbound: inboundManager,
outbound: outboundManager,
dnsTransport: dnsTransportManager,
service: serviceManager,
dnsRouter: dnsRouter,
connection: connectionManager,
router: router,
createdAt: createdAt,
logFactory: logFactory,
logger: logFactory.Logger(),
internalService: internalServices,
done: make(chan struct{}),
}, nil
}
func (s *Box) PreStart() error {
err := s.preStart()
if err != nil {
// TODO: remove catch error
defer func() {
v := recover()
if v != nil {
println(err.Error())
debug.PrintStack()
panic("panic on early close: " + fmt.Sprint(v))
}
}()
s.Close()
return err
}
s.logger.Info("sing-box pre-started (", F.Seconds(time.Since(s.createdAt).Seconds()), "s)")
return nil
}
func (s *Box) Start() error {
err := s.start()
if err != nil {
// TODO: remove catch error
defer func() {
v := recover()
if v != nil {
println(err.Error())
debug.PrintStack()
println("panic on early start: " + fmt.Sprint(v))
}
}()
s.Close()
return err
}
s.logger.Info("sing-box started (", F.Seconds(time.Since(s.createdAt).Seconds()), "s)")
return nil
}
func (s *Box) preStart() error {
monitor := taskmonitor.New(s.logger, C.StartTimeout)
monitor.Start("start logger")
err := s.logFactory.Start()
monitor.Finish()
if err != nil {
return E.Cause(err, "start logger")
}
err = adapter.StartNamed(s.logger, adapter.StartStateInitialize, s.internalService) // cache-file clash-api v2ray-api
if err != nil {
return err
}
err = adapter.Start(s.logger, adapter.StartStateInitialize, s.network, s.dnsTransport, s.dnsRouter, s.connection, s.router, s.outbound, s.inbound, s.endpoint, s.service)
if err != nil {
return err
}
err = adapter.Start(s.logger, adapter.StartStateStart, s.outbound, s.dnsTransport, s.dnsRouter, s.network, s.connection, s.router)
if err != nil {
return err
}
return nil
}
func (s *Box) start() error {
err := s.preStart()
if err != nil {
return err
}
err = adapter.StartNamed(s.logger, adapter.StartStateStart, s.internalService)
if err != nil {
retur
gitextract_d_trzmkv/
├── .fpm_openwrt
├── .fpm_pacman
├── .fpm_systemd
├── .github/
│ ├── CRONET_GO_VERSION
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.yml
│ │ └── bug_report_zh.yml
│ ├── build_alpine_apk.sh
│ ├── build_openwrt_apk.sh
│ ├── deb2ipk.sh
│ ├── renovate.json
│ ├── setup_go_for_macos1013.sh
│ ├── setup_go_for_windows7.sh
│ ├── update_clients.sh
│ ├── update_cronet.sh
│ ├── update_cronet_dev.sh
│ ├── update_dependencies.sh
│ └── workflows/
│ ├── build.yml
│ ├── docker.yml
│ ├── lint.yml
│ ├── linux.yml
│ └── stale.yml
├── .gitignore
├── .gitmodules
├── .golangci.yml
├── Dockerfile
├── Dockerfile.binary
├── LICENSE
├── Makefile
├── README.md
├── adapter/
│ ├── certificate.go
│ ├── connections.go
│ ├── dns.go
│ ├── endpoint/
│ │ ├── adapter.go
│ │ ├── manager.go
│ │ └── registry.go
│ ├── endpoint.go
│ ├── experimental.go
│ ├── fakeip.go
│ ├── fakeip_metadata.go
│ ├── handler.go
│ ├── inbound/
│ │ ├── adapter.go
│ │ ├── manager.go
│ │ └── registry.go
│ ├── inbound.go
│ ├── lifecycle.go
│ ├── lifecycle_legacy.go
│ ├── neighbor.go
│ ├── network.go
│ ├── outbound/
│ │ ├── adapter.go
│ │ ├── manager.go
│ │ └── registry.go
│ ├── outbound.go
│ ├── platform.go
│ ├── prestart.go
│ ├── router.go
│ ├── rule.go
│ ├── service/
│ │ ├── adapter.go
│ │ ├── manager.go
│ │ └── registry.go
│ ├── service.go
│ ├── ssm.go
│ ├── time.go
│ ├── upstream.go
│ ├── upstream_legacy.go
│ └── v2ray.go
├── box.go
├── cmd/
│ ├── internal/
│ │ ├── app_store_connect/
│ │ │ └── main.go
│ │ ├── build/
│ │ │ └── main.go
│ │ ├── build_libbox/
│ │ │ └── main.go
│ │ ├── build_shared/
│ │ │ ├── sdk.go
│ │ │ └── tag.go
│ │ ├── format_docs/
│ │ │ └── main.go
│ │ ├── protogen/
│ │ │ └── main.go
│ │ ├── read_tag/
│ │ │ └── main.go
│ │ ├── tun_bench/
│ │ │ └── main.go
│ │ ├── update_android_version/
│ │ │ └── main.go
│ │ ├── update_apple_version/
│ │ │ └── main.go
│ │ └── update_certificates/
│ │ └── main.go
│ └── sing-box/
│ ├── cmd.go
│ ├── cmd_check.go
│ ├── cmd_format.go
│ ├── cmd_generate.go
│ ├── cmd_generate_ech.go
│ ├── cmd_generate_tls.go
│ ├── cmd_generate_vapid.go
│ ├── cmd_generate_wireguard.go
│ ├── cmd_geoip.go
│ ├── cmd_geoip_export.go
│ ├── cmd_geoip_list.go
│ ├── cmd_geoip_lookup.go
│ ├── cmd_geosite.go
│ ├── cmd_geosite_export.go
│ ├── cmd_geosite_list.go
│ ├── cmd_geosite_lookup.go
│ ├── cmd_geosite_matcher.go
│ ├── cmd_merge.go
│ ├── cmd_rule_set.go
│ ├── cmd_rule_set_compile.go
│ ├── cmd_rule_set_convert.go
│ ├── cmd_rule_set_decompile.go
│ ├── cmd_rule_set_format.go
│ ├── cmd_rule_set_match.go
│ ├── cmd_rule_set_merge.go
│ ├── cmd_rule_set_upgrade.go
│ ├── cmd_run.go
│ ├── cmd_tools.go
│ ├── cmd_tools_connect.go
│ ├── cmd_tools_fetch.go
│ ├── cmd_tools_fetch_http3.go
│ ├── cmd_tools_fetch_http3_stub.go
│ ├── cmd_tools_synctime.go
│ ├── cmd_version.go
│ ├── generate_completions.go
│ └── main.go
├── common/
│ ├── badtls/
│ │ ├── raw_conn.go
│ │ ├── raw_half_conn.go
│ │ ├── read_wait.go
│ │ ├── read_wait_stub.go
│ │ ├── registry.go
│ │ └── registry_utls.go
│ ├── badversion/
│ │ ├── version.go
│ │ ├── version_json.go
│ │ └── version_test.go
│ ├── certificate/
│ │ ├── chrome.go
│ │ ├── mozilla.go
│ │ └── store.go
│ ├── compatible/
│ │ └── map.go
│ ├── convertor/
│ │ └── adguard/
│ │ ├── convertor.go
│ │ └── convertor_test.go
│ ├── dialer/
│ │ ├── default.go
│ │ ├── default_parallel_interface.go
│ │ ├── default_parallel_network.go
│ │ ├── detour.go
│ │ ├── dialer.go
│ │ ├── resolve.go
│ │ ├── router.go
│ │ ├── tfo.go
│ │ └── wireguard.go
│ ├── geoip/
│ │ └── reader.go
│ ├── geosite/
│ │ ├── compat_test.go
│ │ ├── geosite_test.go
│ │ ├── reader.go
│ │ ├── rule.go
│ │ └── writer.go
│ ├── interrupt/
│ │ ├── conn.go
│ │ ├── context.go
│ │ └── group.go
│ ├── ja3/
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── error.go
│ │ ├── ja3.go
│ │ └── parser.go
│ ├── ktls/
│ │ ├── ktls.go
│ │ ├── ktls_alert.go
│ │ ├── ktls_cipher_suites_linux.go
│ │ ├── ktls_close.go
│ │ ├── ktls_const.go
│ │ ├── ktls_handshake_messages.go
│ │ ├── ktls_key_update.go
│ │ ├── ktls_linux.go
│ │ ├── ktls_prf.go
│ │ ├── ktls_read.go
│ │ ├── ktls_read_wait.go
│ │ ├── ktls_stub_nolinkname.go
│ │ ├── ktls_stub_nonlinux.go
│ │ ├── ktls_stub_oldgo.go
│ │ └── ktls_write.go
│ ├── listener/
│ │ ├── listener.go
│ │ ├── listener_tcp.go
│ │ └── listener_udp.go
│ ├── mux/
│ │ ├── client.go
│ │ └── router.go
│ ├── pipelistener/
│ │ └── listener.go
│ ├── process/
│ │ ├── searcher.go
│ │ ├── searcher_android.go
│ │ ├── searcher_darwin.go
│ │ ├── searcher_linux.go
│ │ ├── searcher_linux_shared.go
│ │ ├── searcher_stub.go
│ │ └── searcher_windows.go
│ ├── redir/
│ │ ├── redir_darwin.go
│ │ ├── redir_linux.go
│ │ ├── redir_other.go
│ │ ├── tproxy_linux.go
│ │ └── tproxy_other.go
│ ├── settings/
│ │ ├── proxy_android.go
│ │ ├── proxy_darwin.go
│ │ ├── proxy_linux.go
│ │ ├── proxy_stub.go
│ │ ├── proxy_windows.go
│ │ ├── system_proxy.go
│ │ ├── wifi.go
│ │ ├── wifi_linux.go
│ │ ├── wifi_linux_connman.go
│ │ ├── wifi_linux_iwd.go
│ │ ├── wifi_linux_nm.go
│ │ ├── wifi_linux_wpa.go
│ │ ├── wifi_stub.go
│ │ └── wifi_windows.go
│ ├── sniff/
│ │ ├── bittorrent.go
│ │ ├── bittorrent_test.go
│ │ ├── dns.go
│ │ ├── dns_test.go
│ │ ├── dtls.go
│ │ ├── dtls_test.go
│ │ ├── http.go
│ │ ├── http_test.go
│ │ ├── internal/
│ │ │ └── qtls/
│ │ │ └── qtls.go
│ │ ├── ntp.go
│ │ ├── ntp_test.go
│ │ ├── quic.go
│ │ ├── quic_blacklist.go
│ │ ├── quic_capture_test.go
│ │ ├── quic_test.go
│ │ ├── rdp.go
│ │ ├── rdp_test.go
│ │ ├── sniff.go
│ │ ├── ssh.go
│ │ ├── ssh_test.go
│ │ ├── stun.go
│ │ ├── stun_test.go
│ │ └── tls.go
│ ├── srs/
│ │ ├── binary.go
│ │ ├── compat_test.go
│ │ ├── ip_cidr.go
│ │ └── ip_set.go
│ ├── taskmonitor/
│ │ └── monitor.go
│ ├── tls/
│ │ ├── acme.go
│ │ ├── acme_contstant.go
│ │ ├── acme_stub.go
│ │ ├── client.go
│ │ ├── common.go
│ │ ├── config.go
│ │ ├── ech.go
│ │ ├── ech_shared.go
│ │ ├── ech_tag_stub.go
│ │ ├── ktls.go
│ │ ├── mkcert.go
│ │ ├── reality_client.go
│ │ ├── reality_server.go
│ │ ├── reality_stub.go
│ │ ├── server.go
│ │ ├── std_client.go
│ │ ├── std_server.go
│ │ ├── time_wrapper.go
│ │ ├── utls_client.go
│ │ └── utls_stub.go
│ ├── tlsfragment/
│ │ ├── conn.go
│ │ ├── conn_test.go
│ │ ├── index.go
│ │ ├── index_test.go
│ │ ├── wait_darwin.go
│ │ ├── wait_linux.go
│ │ ├── wait_stub.go
│ │ └── wait_windows.go
│ ├── uot/
│ │ └── router.go
│ └── urltest/
│ └── urltest.go
├── constant/
│ ├── certificate.go
│ ├── cgo.go
│ ├── cgo_disabled.go
│ ├── dhcp.go
│ ├── dns.go
│ ├── err.go
│ ├── goos/
│ │ ├── gengoos.go
│ │ ├── goos.go
│ │ ├── zgoos_aix.go
│ │ ├── zgoos_android.go
│ │ ├── zgoos_darwin.go
│ │ ├── zgoos_dragonfly.go
│ │ ├── zgoos_freebsd.go
│ │ ├── zgoos_hurd.go
│ │ ├── zgoos_illumos.go
│ │ ├── zgoos_ios.go
│ │ ├── zgoos_js.go
│ │ ├── zgoos_linux.go
│ │ ├── zgoos_netbsd.go
│ │ ├── zgoos_openbsd.go
│ │ ├── zgoos_plan9.go
│ │ ├── zgoos_solaris.go
│ │ ├── zgoos_windows.go
│ │ └── zgoos_zos.go
│ ├── hysteria2.go
│ ├── network.go
│ ├── os.go
│ ├── path.go
│ ├── path_unix.go
│ ├── protocol.go
│ ├── proxy.go
│ ├── quic.go
│ ├── quic_stub.go
│ ├── rule.go
│ ├── speed.go
│ ├── time.go
│ ├── timeout.go
│ ├── v2ray.go
│ └── version.go
├── daemon/
│ ├── deprecated.go
│ ├── instance.go
│ ├── platform.go
│ ├── started_service.go
│ ├── started_service.pb.go
│ ├── started_service.proto
│ └── started_service_grpc.pb.go
├── debug.go
├── debug_http.go
├── debug_stub.go
├── debug_unix.go
├── dns/
│ ├── client.go
│ ├── client_log.go
│ ├── client_truncate.go
│ ├── extension_edns0_subnet.go
│ ├── rcode.go
│ ├── router.go
│ ├── transport/
│ │ ├── base.go
│ │ ├── connector.go
│ │ ├── connector_test.go
│ │ ├── dhcp/
│ │ │ ├── dhcp.go
│ │ │ └── dhcp_shared.go
│ │ ├── fakeip/
│ │ │ ├── fakeip.go
│ │ │ ├── memory.go
│ │ │ └── store.go
│ │ ├── hosts/
│ │ │ ├── hosts.go
│ │ │ ├── hosts_file.go
│ │ │ ├── hosts_test.go
│ │ │ ├── hosts_unix.go
│ │ │ ├── hosts_windows.go
│ │ │ └── testdata/
│ │ │ └── hosts
│ │ ├── https.go
│ │ ├── https_transport.go
│ │ ├── local/
│ │ │ ├── local.go
│ │ │ ├── local_darwin.go
│ │ │ ├── local_darwin_dhcp.go
│ │ │ ├── local_darwin_nodhcp.go
│ │ │ ├── local_resolved.go
│ │ │ ├── local_resolved_linux.go
│ │ │ ├── local_resolved_stub.go
│ │ │ ├── local_shared.go
│ │ │ ├── resolv.go
│ │ │ ├── resolv_default.go
│ │ │ ├── resolv_test.go
│ │ │ ├── resolv_unix.go
│ │ │ └── resolv_windows.go
│ │ ├── quic/
│ │ │ ├── http3.go
│ │ │ └── quic.go
│ │ ├── tcp.go
│ │ ├── tls.go
│ │ └── udp.go
│ ├── transport_adapter.go
│ ├── transport_dialer.go
│ ├── transport_manager.go
│ └── transport_registry.go
├── docs/
│ ├── CNAME
│ ├── changelog.md
│ ├── clients/
│ │ ├── android/
│ │ │ ├── features.md
│ │ │ └── index.md
│ │ ├── apple/
│ │ │ ├── features.md
│ │ │ └── index.md
│ │ ├── general.md
│ │ ├── index.md
│ │ ├── index.zh.md
│ │ └── privacy.md
│ ├── configuration/
│ │ ├── certificate/
│ │ │ ├── index.md
│ │ │ └── index.zh.md
│ │ ├── dns/
│ │ │ ├── fakeip.md
│ │ │ ├── fakeip.zh.md
│ │ │ ├── index.md
│ │ │ ├── index.zh.md
│ │ │ ├── rule.md
│ │ │ ├── rule.zh.md
│ │ │ ├── rule_action.md
│ │ │ ├── rule_action.zh.md
│ │ │ └── server/
│ │ │ ├── dhcp.md
│ │ │ ├── dhcp.zh.md
│ │ │ ├── fakeip.md
│ │ │ ├── fakeip.zh.md
│ │ │ ├── hosts.md
│ │ │ ├── hosts.zh.md
│ │ │ ├── http3.md
│ │ │ ├── http3.zh.md
│ │ │ ├── https.md
│ │ │ ├── https.zh.md
│ │ │ ├── index.md
│ │ │ ├── index.zh.md
│ │ │ ├── legacy.md
│ │ │ ├── legacy.zh.md
│ │ │ ├── local.md
│ │ │ ├── local.zh.md
│ │ │ ├── quic.md
│ │ │ ├── quic.zh.md
│ │ │ ├── resolved.md
│ │ │ ├── resolved.zh.md
│ │ │ ├── tailscale.md
│ │ │ ├── tailscale.zh.md
│ │ │ ├── tcp.md
│ │ │ ├── tcp.zh.md
│ │ │ ├── tls.md
│ │ │ ├── tls.zh.md
│ │ │ ├── udp.md
│ │ │ └── udp.zh.md
│ │ ├── endpoint/
│ │ │ ├── index.md
│ │ │ ├── index.zh.md
│ │ │ ├── tailscale.md
│ │ │ ├── tailscale.zh.md
│ │ │ ├── wireguard.md
│ │ │ └── wireguard.zh.md
│ │ ├── experimental/
│ │ │ ├── cache-file.md
│ │ │ ├── cache-file.zh.md
│ │ │ ├── clash-api.md
│ │ │ ├── clash-api.zh.md
│ │ │ ├── index.md
│ │ │ ├── index.zh.md
│ │ │ ├── v2ray-api.md
│ │ │ └── v2ray-api.zh.md
│ │ ├── inbound/
│ │ │ ├── anytls.md
│ │ │ ├── anytls.zh.md
│ │ │ ├── direct.md
│ │ │ ├── direct.zh.md
│ │ │ ├── http.md
│ │ │ ├── http.zh.md
│ │ │ ├── hysteria.md
│ │ │ ├── hysteria.zh.md
│ │ │ ├── hysteria2.md
│ │ │ ├── hysteria2.zh.md
│ │ │ ├── index.md
│ │ │ ├── index.zh.md
│ │ │ ├── mixed.md
│ │ │ ├── mixed.zh.md
│ │ │ ├── naive.md
│ │ │ ├── naive.zh.md
│ │ │ ├── redirect.md
│ │ │ ├── redirect.zh.md
│ │ │ ├── shadowsocks.md
│ │ │ ├── shadowsocks.zh.md
│ │ │ ├── shadowtls.md
│ │ │ ├── shadowtls.zh.md
│ │ │ ├── socks.md
│ │ │ ├── socks.zh.md
│ │ │ ├── tproxy.md
│ │ │ ├── tproxy.zh.md
│ │ │ ├── trojan.md
│ │ │ ├── trojan.zh.md
│ │ │ ├── tuic.md
│ │ │ ├── tuic.zh.md
│ │ │ ├── tun.md
│ │ │ ├── tun.zh.md
│ │ │ ├── vless.md
│ │ │ ├── vless.zh.md
│ │ │ ├── vmess.md
│ │ │ └── vmess.zh.md
│ │ ├── index.md
│ │ ├── index.zh.md
│ │ ├── log/
│ │ │ ├── index.md
│ │ │ └── index.zh.md
│ │ ├── ntp/
│ │ │ ├── index.md
│ │ │ └── index.zh.md
│ │ ├── outbound/
│ │ │ ├── anytls.md
│ │ │ ├── anytls.zh.md
│ │ │ ├── block.md
│ │ │ ├── block.zh.md
│ │ │ ├── direct.md
│ │ │ ├── direct.zh.md
│ │ │ ├── dns.md
│ │ │ ├── dns.zh.md
│ │ │ ├── http.md
│ │ │ ├── http.zh.md
│ │ │ ├── hysteria.md
│ │ │ ├── hysteria.zh.md
│ │ │ ├── hysteria2.md
│ │ │ ├── hysteria2.zh.md
│ │ │ ├── index.md
│ │ │ ├── index.zh.md
│ │ │ ├── naive.md
│ │ │ ├── naive.zh.md
│ │ │ ├── selector.md
│ │ │ ├── selector.zh.md
│ │ │ ├── shadowsocks.md
│ │ │ ├── shadowsocks.zh.md
│ │ │ ├── shadowtls.md
│ │ │ ├── shadowtls.zh.md
│ │ │ ├── socks.md
│ │ │ ├── socks.zh.md
│ │ │ ├── ssh.md
│ │ │ ├── ssh.zh.md
│ │ │ ├── tor.md
│ │ │ ├── tor.zh.md
│ │ │ ├── trojan.md
│ │ │ ├── trojan.zh.md
│ │ │ ├── tuic.md
│ │ │ ├── tuic.zh.md
│ │ │ ├── urltest.md
│ │ │ ├── urltest.zh.md
│ │ │ ├── vless.md
│ │ │ ├── vless.zh.md
│ │ │ ├── vmess.md
│ │ │ ├── vmess.zh.md
│ │ │ ├── wireguard.md
│ │ │ └── wireguard.zh.md
│ │ ├── route/
│ │ │ ├── geoip.md
│ │ │ ├── geoip.zh.md
│ │ │ ├── geosite.md
│ │ │ ├── geosite.zh.md
│ │ │ ├── index.md
│ │ │ ├── index.zh.md
│ │ │ ├── rule.md
│ │ │ ├── rule.zh.md
│ │ │ ├── rule_action.md
│ │ │ ├── rule_action.zh.md
│ │ │ ├── sniff.md
│ │ │ └── sniff.zh.md
│ │ ├── rule-set/
│ │ │ ├── adguard.md
│ │ │ ├── adguard.zh.md
│ │ │ ├── headless-rule.md
│ │ │ ├── headless-rule.zh.md
│ │ │ ├── index.md
│ │ │ ├── index.zh.md
│ │ │ ├── source-format.md
│ │ │ └── source-format.zh.md
│ │ ├── service/
│ │ │ ├── ccm.md
│ │ │ ├── ccm.zh.md
│ │ │ ├── derp.md
│ │ │ ├── derp.zh.md
│ │ │ ├── index.md
│ │ │ ├── index.zh.md
│ │ │ ├── ocm.md
│ │ │ ├── ocm.zh.md
│ │ │ ├── resolved.md
│ │ │ ├── resolved.zh.md
│ │ │ ├── ssm-api.md
│ │ │ └── ssm-api.zh.md
│ │ └── shared/
│ │ ├── dial.md
│ │ ├── dial.zh.md
│ │ ├── dns01_challenge.md
│ │ ├── dns01_challenge.zh.md
│ │ ├── listen.md
│ │ ├── listen.zh.md
│ │ ├── multiplex.md
│ │ ├── multiplex.zh.md
│ │ ├── neighbor.md
│ │ ├── neighbor.zh.md
│ │ ├── pre-match.md
│ │ ├── pre-match.zh.md
│ │ ├── tcp-brutal.md
│ │ ├── tcp-brutal.zh.md
│ │ ├── tls.md
│ │ ├── tls.zh.md
│ │ ├── udp-over-tcp.md
│ │ ├── udp-over-tcp.zh.md
│ │ ├── v2ray-transport.md
│ │ ├── v2ray-transport.zh.md
│ │ ├── wifi-state.md
│ │ └── wifi-state.zh.md
│ ├── deprecated.md
│ ├── deprecated.zh.md
│ ├── index.md
│ ├── index.zh.md
│ ├── installation/
│ │ ├── build-from-source.md
│ │ ├── build-from-source.zh.md
│ │ ├── docker.md
│ │ ├── docker.zh.md
│ │ ├── package-manager.md
│ │ ├── package-manager.zh.md
│ │ └── tools/
│ │ ├── arch-install.sh
│ │ ├── deb-install.sh
│ │ ├── install.sh
│ │ ├── rpm-install.sh
│ │ └── sing-box.repo
│ ├── manual/
│ │ ├── misc/
│ │ │ └── tunnelvision.md
│ │ ├── proxy/
│ │ │ ├── client.md
│ │ │ └── server.md
│ │ └── proxy-protocol/
│ │ ├── hysteria2.md
│ │ ├── shadowsocks.md
│ │ └── trojan.md
│ ├── migration.md
│ ├── migration.zh.md
│ ├── sponsors.md
│ ├── support.md
│ └── support.zh.md
├── experimental/
│ ├── cachefile/
│ │ ├── cache.go
│ │ ├── fakeip.go
│ │ └── rdrc.go
│ ├── clashapi/
│ │ ├── api_meta.go
│ │ ├── api_meta_group.go
│ │ ├── api_meta_upgrade.go
│ │ ├── cache.go
│ │ ├── common.go
│ │ ├── configs.go
│ │ ├── connections.go
│ │ ├── ctxkeys.go
│ │ ├── dns.go
│ │ ├── errors.go
│ │ ├── profile.go
│ │ ├── provider.go
│ │ ├── proxies.go
│ │ ├── ruleprovider.go
│ │ ├── rules.go
│ │ ├── script.go
│ │ ├── server.go
│ │ ├── server_fs.go
│ │ ├── server_resources.go
│ │ └── trafficontrol/
│ │ ├── manager.go
│ │ └── tracker.go
│ ├── clashapi.go
│ ├── deprecated/
│ │ ├── constants.go
│ │ ├── manager.go
│ │ └── stderr.go
│ ├── libbox/
│ │ ├── build_info.go
│ │ ├── command.go
│ │ ├── command_client.go
│ │ ├── command_server.go
│ │ ├── command_types.go
│ │ ├── config.go
│ │ ├── deprecated.go
│ │ ├── dns.go
│ │ ├── fdroid.go
│ │ ├── fdroid_mirrors.go
│ │ ├── ffi.json
│ │ ├── http.go
│ │ ├── internal/
│ │ │ └── procfs/
│ │ │ └── procfs.go
│ │ ├── iterator.go
│ │ ├── link_flags_stub.go
│ │ ├── link_flags_unix.go
│ │ ├── log.go
│ │ ├── memory.go
│ │ ├── monitor.go
│ │ ├── neighbor.go
│ │ ├── neighbor_darwin.go
│ │ ├── neighbor_linux.go
│ │ ├── neighbor_stub.go
│ │ ├── panic.go
│ │ ├── pidfd_android.go
│ │ ├── platform.go
│ │ ├── pprof.go
│ │ ├── profile_import.go
│ │ ├── remote_profile.go
│ │ ├── semver.go
│ │ ├── semver_test.go
│ │ ├── service.go
│ │ ├── service_other.go
│ │ ├── service_windows.go
│ │ ├── setup.go
│ │ ├── tun.go
│ │ ├── tun_darwin.go
│ │ ├── tun_name_darwin.go
│ │ ├── tun_name_linux.go
│ │ └── tun_name_other.go
│ ├── locale/
│ │ ├── locale.go
│ │ └── locale_zh_CN.go
│ ├── v2rayapi/
│ │ ├── server.go
│ │ ├── stats.go
│ │ ├── stats.pb.go
│ │ ├── stats.proto
│ │ └── stats_grpc.pb.go
│ └── v2rayapi.go
├── go.mod
├── go.sum
├── include/
│ ├── ccm.go
│ ├── ccm_stub.go
│ ├── ccm_stub_darwin.go
│ ├── clashapi.go
│ ├── clashapi_stub.go
│ ├── dhcp.go
│ ├── dhcp_stub.go
│ ├── naive_outbound.go
│ ├── naive_outbound_stub.go
│ ├── ocm.go
│ ├── ocm_stub.go
│ ├── oom_killer.go
│ ├── quic.go
│ ├── quic_stub.go
│ ├── registry.go
│ ├── tailscale.go
│ ├── tailscale_stub.go
│ ├── tz_android.go
│ ├── tz_ios.go
│ ├── v2rayapi.go
│ ├── v2rayapi_stub.go
│ ├── wireguard.go
│ └── wireguard_stub.go
├── log/
│ ├── export.go
│ ├── factory.go
│ ├── format.go
│ ├── id.go
│ ├── level.go
│ ├── log.go
│ ├── nop.go
│ ├── observable.go
│ ├── override.go
│ └── platform.go
├── mkdocs.yml
├── option/
│ ├── anytls.go
│ ├── ccm.go
│ ├── certificate.go
│ ├── debug.go
│ ├── direct.go
│ ├── dns.go
│ ├── dns_record.go
│ ├── endpoint.go
│ ├── experimental.go
│ ├── group.go
│ ├── hysteria.go
│ ├── hysteria2.go
│ ├── inbound.go
│ ├── multiplex.go
│ ├── naive.go
│ ├── ntp.go
│ ├── ocm.go
│ ├── oom_killer.go
│ ├── options.go
│ ├── outbound.go
│ ├── platform.go
│ ├── redir.go
│ ├── resolved.go
│ ├── route.go
│ ├── rule.go
│ ├── rule_action.go
│ ├── rule_dns.go
│ ├── rule_set.go
│ ├── service.go
│ ├── shadowsocks.go
│ ├── shadowsocksr.go
│ ├── shadowtls.go
│ ├── simple.go
│ ├── ssh.go
│ ├── ssmapi.go
│ ├── tailscale.go
│ ├── tls.go
│ ├── tls_acme.go
│ ├── tor.go
│ ├── trojan.go
│ ├── tuic.go
│ ├── tun.go
│ ├── tun_platform.go
│ ├── types.go
│ ├── udp_over_tcp.go
│ ├── v2ray.go
│ ├── v2ray_transport.go
│ ├── vless.go
│ ├── vmess.go
│ └── wireguard.go
├── protocol/
│ ├── anytls/
│ │ ├── inbound.go
│ │ └── outbound.go
│ ├── block/
│ │ └── outbound.go
│ ├── direct/
│ │ ├── inbound.go
│ │ ├── loopback_detect.go
│ │ └── outbound.go
│ ├── dns/
│ │ ├── handle.go
│ │ └── outbound.go
│ ├── group/
│ │ ├── selector.go
│ │ └── urltest.go
│ ├── http/
│ │ ├── inbound.go
│ │ └── outbound.go
│ ├── hysteria/
│ │ ├── inbound.go
│ │ └── outbound.go
│ ├── hysteria2/
│ │ ├── inbound.go
│ │ └── outbound.go
│ ├── mixed/
│ │ └── inbound.go
│ ├── naive/
│ │ ├── inbound.go
│ │ ├── inbound_conn.go
│ │ ├── outbound.go
│ │ └── quic/
│ │ └── inbound_init.go
│ ├── redirect/
│ │ ├── redirect.go
│ │ └── tproxy.go
│ ├── shadowsocks/
│ │ ├── inbound.go
│ │ ├── inbound_multi.go
│ │ ├── inbound_relay.go
│ │ └── outbound.go
│ ├── shadowtls/
│ │ ├── inbound.go
│ │ └── outbound.go
│ ├── socks/
│ │ ├── inbound.go
│ │ └── outbound.go
│ ├── ssh/
│ │ └── outbound.go
│ ├── tailscale/
│ │ ├── dns_transport.go
│ │ ├── endpoint.go
│ │ ├── tun_device_unix.go
│ │ └── tun_device_windows.go
│ ├── tor/
│ │ ├── outbound.go
│ │ └── proxy.go
│ ├── trojan/
│ │ ├── inbound.go
│ │ └── outbound.go
│ ├── tuic/
│ │ ├── inbound.go
│ │ └── outbound.go
│ ├── tun/
│ │ ├── hook.go
│ │ └── inbound.go
│ ├── vless/
│ │ ├── inbound.go
│ │ └── outbound.go
│ ├── vmess/
│ │ ├── inbound.go
│ │ └── outbound.go
│ └── wireguard/
│ └── endpoint.go
├── release/
│ ├── DEFAULT_BUILD_TAGS
│ ├── DEFAULT_BUILD_TAGS_OTHERS
│ ├── DEFAULT_BUILD_TAGS_WINDOWS
│ ├── LDFLAGS
│ ├── completions/
│ │ ├── sing-box.bash
│ │ ├── sing-box.fish
│ │ └── sing-box.zsh
│ ├── config/
│ │ ├── config.json
│ │ ├── openwrt.conf
│ │ ├── openwrt.init
│ │ ├── openwrt.keep
│ │ ├── openwrt.prerm
│ │ ├── sing-box-split-dns.xml
│ │ ├── sing-box.confd
│ │ ├── sing-box.initd
│ │ ├── sing-box.postinst
│ │ ├── sing-box.rules
│ │ ├── sing-box.service
│ │ ├── sing-box.sysusers
│ │ └── sing-box@.service
│ └── local/
│ ├── common.sh
│ ├── debug.sh
│ ├── enable.sh
│ ├── install.sh
│ ├── install_go.sh
│ ├── reinstall.sh
│ ├── sing-box.service
│ ├── uninstall.sh
│ └── update.sh
├── route/
│ ├── conn.go
│ ├── dns.go
│ ├── neighbor_resolver_darwin.go
│ ├── neighbor_resolver_lease.go
│ ├── neighbor_resolver_linux.go
│ ├── neighbor_resolver_parse.go
│ ├── neighbor_resolver_platform.go
│ ├── neighbor_resolver_stub.go
│ ├── neighbor_table_darwin.go
│ ├── neighbor_table_linux.go
│ ├── network.go
│ ├── platform_searcher.go
│ ├── route.go
│ ├── router.go
│ ├── rule/
│ │ ├── rule_abstract.go
│ │ ├── rule_abstract_test.go
│ │ ├── rule_action.go
│ │ ├── rule_default.go
│ │ ├── rule_default_interface_address.go
│ │ ├── rule_dns.go
│ │ ├── rule_headless.go
│ │ ├── rule_interface_address.go
│ │ ├── rule_item_adguard.go
│ │ ├── rule_item_auth_user.go
│ │ ├── rule_item_cidr.go
│ │ ├── rule_item_clash_mode.go
│ │ ├── rule_item_client.go
│ │ ├── rule_item_domain.go
│ │ ├── rule_item_domain_keyword.go
│ │ ├── rule_item_domain_regex.go
│ │ ├── rule_item_inbound.go
│ │ ├── rule_item_ip_accept_any.go
│ │ ├── rule_item_ip_is_private.go
│ │ ├── rule_item_ipversion.go
│ │ ├── rule_item_network.go
│ │ ├── rule_item_network_is_constrained.go
│ │ ├── rule_item_network_is_expensive.go
│ │ ├── rule_item_network_type.go
│ │ ├── rule_item_outbound.go
│ │ ├── rule_item_package_name.go
│ │ ├── rule_item_port.go
│ │ ├── rule_item_port_range.go
│ │ ├── rule_item_preferred_by.go
│ │ ├── rule_item_process_name.go
│ │ ├── rule_item_process_path.go
│ │ ├── rule_item_process_path_regex.go
│ │ ├── rule_item_protocol.go
│ │ ├── rule_item_query_type.go
│ │ ├── rule_item_rule_set.go
│ │ ├── rule_item_source_hostname.go
│ │ ├── rule_item_source_mac_address.go
│ │ ├── rule_item_user.go
│ │ ├── rule_item_user_id.go
│ │ ├── rule_item_wifi_bssid.go
│ │ ├── rule_item_wifi_ssid.go
│ │ ├── rule_network_interface_address.go
│ │ ├── rule_set.go
│ │ ├── rule_set_local.go
│ │ └── rule_set_remote.go
│ └── rule_conds.go
├── service/
│ ├── ccm/
│ │ ├── credential.go
│ │ ├── credential_darwin.go
│ │ ├── credential_other.go
│ │ ├── service.go
│ │ ├── service_usage.go
│ │ └── service_user.go
│ ├── derp/
│ │ └── service.go
│ ├── ocm/
│ │ ├── credential.go
│ │ ├── credential_darwin.go
│ │ ├── credential_other.go
│ │ ├── service.go
│ │ ├── service_usage.go
│ │ ├── service_user.go
│ │ └── service_websocket.go
│ ├── oomkiller/
│ │ ├── config.go
│ │ ├── service.go
│ │ ├── service_stub.go
│ │ └── service_timer.go
│ ├── resolved/
│ │ ├── resolve1.go
│ │ ├── service.go
│ │ ├── stub.go
│ │ └── transport.go
│ └── ssmapi/
│ ├── api.go
│ ├── cache.go
│ ├── server.go
│ ├── traffic.go
│ └── user.go
├── test/
│ ├── box_test.go
│ ├── brutal_test.go
│ ├── clash_darwin_test.go
│ ├── clash_other_test.go
│ ├── clash_test.go
│ ├── config/
│ │ ├── hysteria-client.json
│ │ ├── hysteria-server.json
│ │ ├── hysteria2-client.yml
│ │ ├── hysteria2-server.yml
│ │ ├── naive-nginx.conf
│ │ ├── naive-quic.json
│ │ ├── naive.json
│ │ ├── nginx.conf
│ │ ├── shadowsocksr.json
│ │ ├── trojan.json
│ │ ├── tuic-client.json
│ │ ├── tuic-server.json
│ │ ├── vless-server.json
│ │ ├── vless-tls-client.json
│ │ ├── vless-tls-server.json
│ │ ├── vmess-client.json
│ │ ├── vmess-grpc-client.json
│ │ ├── vmess-grpc-server.json
│ │ ├── vmess-mux-client.json
│ │ ├── vmess-server.json
│ │ ├── vmess-ws-client.json
│ │ ├── vmess-ws-server.json
│ │ └── wireguard.conf
│ ├── direct_test.go
│ ├── docker_test.go
│ ├── domain_inbound_test.go
│ ├── ech_test.go
│ ├── go.mod
│ ├── go.sum
│ ├── http_test.go
│ ├── hysteria2_test.go
│ ├── hysteria_test.go
│ ├── inbound_detour_test.go
│ ├── ktls_test.go
│ ├── mkcert.go
│ ├── mux_cool_test.go
│ ├── mux_test.go
│ ├── naive_self_test.go
│ ├── naive_test.go
│ ├── reality_test.go
│ ├── shadowsocks_legacy_test.go
│ ├── shadowsocks_test.go
│ ├── shadowtls_test.go
│ ├── socks_test.go
│ ├── ss_plugin_test.go
│ ├── tfo_test.go
│ ├── tls_test.go
│ ├── trojan_test.go
│ ├── tuic_test.go
│ ├── v2ray_api_test.go
│ ├── v2ray_grpc_test.go
│ ├── v2ray_httpupgrade_test.go
│ ├── v2ray_transport_test.go
│ ├── v2ray_ws_test.go
│ ├── vmess_test.go
│ └── wrapper_test.go
└── transport/
├── simple-obfs/
│ ├── README.md
│ ├── http.go
│ └── tls.go
├── sip003/
│ ├── args.go
│ ├── obfs.go
│ ├── plugin.go
│ └── v2ray.go
├── trojan/
│ ├── mux.go
│ ├── protocol.go
│ ├── protocol_wait.go
│ ├── service.go
│ └── service_wait.go
├── v2ray/
│ ├── grpc.go
│ ├── grpc_lite.go
│ ├── quic.go
│ └── transport.go
├── v2raygrpc/
│ ├── client.go
│ ├── conn.go
│ ├── credentials/
│ │ ├── credentials.go
│ │ ├── spiffe.go
│ │ ├── syscallconn.go
│ │ └── util.go
│ ├── custom_name.go
│ ├── server.go
│ ├── stream.pb.go
│ ├── stream.proto
│ ├── stream_grpc.pb.go
│ └── tls_credentials.go
├── v2raygrpclite/
│ ├── client.go
│ ├── conn.go
│ └── server.go
├── v2rayhttp/
│ ├── client.go
│ ├── conn.go
│ ├── force_close.go
│ ├── pool.go
│ └── server.go
├── v2rayhttpupgrade/
│ ├── client.go
│ └── server.go
├── v2rayquic/
│ ├── client.go
│ ├── init.go
│ ├── server.go
│ └── stream.go
├── v2raywebsocket/
│ ├── client.go
│ ├── conn.go
│ ├── server.go
│ └── writer.go
└── wireguard/
├── client_bind.go
├── device.go
├── device_nat.go
├── device_stack.go
├── device_stack_gonet.go
├── device_stack_stub.go
├── device_system.go
├── device_system_stack.go
├── endpoint.go
└── endpoint_options.go
Showing preview only (507K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (5675 symbols across 689 files)
FILE: adapter/certificate.go
type CertificateStore (line 10) | type CertificateStore interface
function RootPoolFromContext (line 15) | func RootPoolFromContext(ctx context.Context) *x509.CertPool {
FILE: adapter/connections.go
type ConnectionManager (line 10) | type ConnectionManager interface
FILE: adapter/dns.go
type DNSRouter (line 17) | type DNSRouter interface
type DNSClient (line 26) | type DNSClient interface
type DNSQueryOptions (line 33) | type DNSQueryOptions struct
function DNSQueryOptionsFrom (line 42) | func DNSQueryOptionsFrom(ctx context.Context, options *option.DomainReso...
type RDRCStore (line 60) | type RDRCStore interface
type DNSTransport (line 66) | type DNSTransport interface
type LegacyDNSTransport (line 75) | type LegacyDNSTransport interface
type DNSTransportRegistry (line 80) | type DNSTransportRegistry interface
type DNSTransportManager (line 85) | type DNSTransportManager interface
FILE: adapter/endpoint.go
type Endpoint (line 10) | type Endpoint interface
type EndpointRegistry (line 17) | type EndpointRegistry interface
type EndpointManager (line 22) | type EndpointManager interface
FILE: adapter/endpoint/adapter.go
type Adapter (line 5) | type Adapter struct
method Type (line 29) | func (a *Adapter) Type() string {
method Tag (line 33) | func (a *Adapter) Tag() string {
method Network (line 37) | func (a *Adapter) Network() []string {
method Dependencies (line 41) | func (a *Adapter) Dependencies() []string {
function NewAdapter (line 12) | func NewAdapter(endpointType string, endpointTag string, network []strin...
function NewAdapterWithDialerOptions (line 21) | func NewAdapterWithDialerOptions(endpointType string, endpointTag string...
FILE: adapter/endpoint/manager.go
type Manager (line 20) | type Manager struct
method Start (line 38) | func (m *Manager) Start(stage adapter.StartStage) error {
method Close (line 63) | func (m *Manager) Close() error {
method Endpoints (line 88) | func (m *Manager) Endpoints() []adapter.Endpoint {
method Get (line 94) | func (m *Manager) Get(tag string) (adapter.Endpoint, bool) {
method Remove (line 101) | func (m *Manager) Remove(tag string) error {
method Create (line 124) | func (m *Manager) Create(ctx context.Context, router adapter.Router, l...
function NewManager (line 30) | func NewManager(logger log.ContextLogger, registry adapter.EndpointRegis...
FILE: adapter/endpoint/registry.go
type ConstructorFunc (line 13) | type ConstructorFunc
function Register (line 15) | func Register[Options any](registry *Registry, outboundType string, cons...
type optionsConstructorFunc (line 30) | type optionsConstructorFunc
type constructorFunc (line 31) | type constructorFunc
type Registry (line 34) | type Registry struct
method CreateOptions (line 47) | func (m *Registry) CreateOptions(outboundType string) (any, bool) {
method Create (line 57) | func (m *Registry) Create(ctx context.Context, router adapter.Router, ...
method register (line 67) | func (m *Registry) register(outboundType string, optionsConstructor op...
function NewRegistry (line 40) | func NewRegistry() *Registry {
FILE: adapter/experimental.go
type ClashServer (line 14) | type ClashServer interface
type URLTestHistory (line 23) | type URLTestHistory struct
type URLTestHistoryStorage (line 28) | type URLTestHistoryStorage interface
type V2RayServer (line 36) | type V2RayServer interface
type CacheFile (line 41) | type CacheFile interface
type SavedBinary (line 60) | type SavedBinary struct
method MarshalBinary (line 66) | func (s *SavedBinary) MarshalBinary() ([]byte, error) {
method UnmarshalBinary (line 95) | func (s *SavedBinary) UnmarshalBinary(data []byte) error {
type OutboundGroup (line 130) | type OutboundGroup interface
type URLTestGroup (line 136) | type URLTestGroup interface
function OutboundTag (line 141) | func OutboundTag(detour Outbound) string {
FILE: adapter/fakeip.go
type FakeIPStore (line 9) | type FakeIPStore interface
type FakeIPStorage (line 17) | type FakeIPStorage interface
type FakeIPTransport (line 28) | type FakeIPTransport interface
FILE: adapter/fakeip_metadata.go
type FakeIPMetadata (line 13) | type FakeIPMetadata struct
method MarshalBinary (line 20) | func (m *FakeIPMetadata) MarshalBinary() (data []byte, err error) {
method UnmarshalBinary (line 34) | func (m *FakeIPMetadata) UnmarshalBinary(data []byte) error {
FILE: adapter/handler.go
type ConnectionHandler (line 14) | type ConnectionHandler interface
type ConnectionHandlerEx (line 18) | type ConnectionHandlerEx interface
type PacketHandler (line 23) | type PacketHandler interface
type PacketHandlerEx (line 27) | type PacketHandlerEx interface
type OOBPacketHandler (line 32) | type OOBPacketHandler interface
type OOBPacketHandlerEx (line 36) | type OOBPacketHandlerEx interface
type PacketConnectionHandler (line 41) | type PacketConnectionHandler interface
type PacketConnectionHandlerEx (line 45) | type PacketConnectionHandlerEx interface
type UpstreamHandlerAdapter (line 52) | type UpstreamHandlerAdapter interface
type UpstreamHandlerAdapterEx (line 58) | type UpstreamHandlerAdapterEx interface
FILE: adapter/inbound.go
type Inbound (line 15) | type Inbound interface
type TCPInjectableInbound (line 21) | type TCPInjectableInbound interface
type UDPInjectableInbound (line 26) | type UDPInjectableInbound interface
type InboundRegistry (line 31) | type InboundRegistry interface
type InboundManager (line 36) | type InboundManager interface
type InboundContext (line 44) | type InboundContext struct
method ResetRuleCache (line 104) | func (c *InboundContext) ResetRuleCache() {
type inboundContextKey (line 114) | type inboundContextKey struct
function WithContext (line 116) | func WithContext(ctx context.Context, inboundContext *InboundContext) co...
function ContextFrom (line 120) | func ContextFrom(ctx context.Context) *InboundContext {
function ExtendContext (line 128) | func ExtendContext(ctx context.Context) (context.Context, *InboundContex...
function OverrideContext (line 136) | func OverrideContext(ctx context.Context) context.Context {
FILE: adapter/inbound/adapter.go
type Adapter (line 3) | type Adapter struct
method Type (line 15) | func (a *Adapter) Type() string {
method Tag (line 19) | func (a *Adapter) Tag() string {
function NewAdapter (line 8) | func NewAdapter(inboundType string, inboundTag string) Adapter {
FILE: adapter/inbound/manager.go
type Manager (line 20) | type Manager struct
method Start (line 40) | func (m *Manager) Start(stage adapter.StartStage) error {
method Close (line 62) | func (m *Manager) Close() error {
method Inbounds (line 87) | func (m *Manager) Inbounds() []adapter.Inbound {
method Get (line 93) | func (m *Manager) Get(tag string) (adapter.Inbound, bool) {
method Remove (line 103) | func (m *Manager) Remove(tag string) error {
method Create (line 126) | func (m *Manager) Create(ctx context.Context, router adapter.Router, l...
function NewManager (line 31) | func NewManager(logger log.ContextLogger, registry adapter.InboundRegist...
FILE: adapter/inbound/registry.go
type ConstructorFunc (line 13) | type ConstructorFunc
function Register (line 15) | func Register[Options any](registry *Registry, outboundType string, cons...
type optionsConstructorFunc (line 30) | type optionsConstructorFunc
type constructorFunc (line 31) | type constructorFunc
type Registry (line 34) | type Registry struct
method CreateOptions (line 47) | func (m *Registry) CreateOptions(outboundType string) (any, bool) {
method Create (line 57) | func (m *Registry) Create(ctx context.Context, router adapter.Router, ...
method register (line 67) | func (m *Registry) register(outboundType string, optionsConstructor op...
function NewRegistry (line 40) | func NewRegistry() *Registry {
FILE: adapter/lifecycle.go
type SimpleLifecycle (line 13) | type SimpleLifecycle interface
type StartStage (line 18) | type StartStage
method String (line 34) | func (s StartStage) String() string {
constant StartStateInitialize (line 21) | StartStateInitialize StartStage = iota
constant StartStateStart (line 22) | StartStateStart
constant StartStatePostStart (line 23) | StartStatePostStart
constant StartStateStarted (line 24) | StartStateStarted
type Lifecycle (line 49) | type Lifecycle interface
type LifecycleService (line 54) | type LifecycleService interface
function getServiceName (line 59) | func getServiceName(service any) string {
function Start (line 77) | func Start(logger log.ContextLogger, stage StartStage, services ...Lifec...
function StartNamed (line 91) | func StartNamed(logger log.ContextLogger, stage StartStage, services []L...
FILE: adapter/lifecycle_legacy.go
function LegacyStart (line 3) | func LegacyStart(starter any, stage StartStage) error {
type lifecycleServiceWrapper (line 30) | type lifecycleServiceWrapper struct
method Name (line 42) | func (l *lifecycleServiceWrapper) Name() string {
method Start (line 46) | func (l *lifecycleServiceWrapper) Start(stage StartStage) error {
method Close (line 50) | func (l *lifecycleServiceWrapper) Close() error {
function NewLifecycleService (line 35) | func NewLifecycleService(service SimpleLifecycle, name string) Lifecycle...
FILE: adapter/neighbor.go
type NeighborEntry (line 8) | type NeighborEntry struct
type NeighborResolver (line 14) | type NeighborResolver interface
type NeighborUpdateListener (line 21) | type NeighborUpdateListener interface
FILE: adapter/network.go
type NetworkManager (line 11) | type NetworkManager interface
type NetworkOptions (line 34) | type NetworkOptions struct
type InterfaceUpdateListener (line 45) | type InterfaceUpdateListener interface
type WIFIState (line 49) | type WIFIState struct
type NetworkInterface (line 54) | type NetworkInterface struct
FILE: adapter/outbound.go
type Outbound (line 16) | type Outbound interface
type OutboundWithPreferredRoutes (line 24) | type OutboundWithPreferredRoutes interface
type DirectRouteOutbound (line 30) | type DirectRouteOutbound interface
type OutboundRegistry (line 35) | type OutboundRegistry interface
type OutboundManager (line 40) | type OutboundManager interface
FILE: adapter/outbound/adapter.go
type Adapter (line 7) | type Adapter struct
method Type (line 31) | func (a *Adapter) Type() string {
method Tag (line 35) | func (a *Adapter) Tag() string {
method Network (line 39) | func (a *Adapter) Network() []string {
method Dependencies (line 43) | func (a *Adapter) Dependencies() []string {
function NewAdapter (line 14) | func NewAdapter(outboundType string, outboundTag string, network []strin...
function NewAdapterWithDialerOptions (line 23) | func NewAdapterWithDialerOptions(outboundType string, outboundTag string...
FILE: adapter/outbound/manager.go
type Manager (line 23) | type Manager struct
method Initialize (line 49) | func (m *Manager) Initialize(defaultOutboundFallback func() (adapter.O...
method Start (line 53) | func (m *Manager) Start(stage adapter.StartStage) error {
method startOutbounds (line 99) | func (m *Manager) startOutbounds(outbounds []adapter.Outbound) error {
method Close (line 173) | func (m *Manager) Close() error {
method Outbounds (line 201) | func (m *Manager) Outbounds() []adapter.Outbound {
method Outbound (line 207) | func (m *Manager) Outbound(tag string) (adapter.Outbound, bool) {
method Default (line 217) | func (m *Manager) Default() adapter.Outbound {
method Remove (line 223) | func (m *Manager) Remove(tag string) error {
method Create (line 267) | func (m *Manager) Create(ctx context.Context, router adapter.Router, l...
function NewManager (line 38) | func NewManager(logger logger.ContextLogger, registry adapter.OutboundRe...
FILE: adapter/outbound/registry.go
type ConstructorFunc (line 13) | type ConstructorFunc
function Register (line 15) | func Register[Options any](registry *Registry, outboundType string, cons...
type optionsConstructorFunc (line 30) | type optionsConstructorFunc
type constructorFunc (line 31) | type constructorFunc
type Registry (line 34) | type Registry struct
method CreateOptions (line 47) | func (r *Registry) CreateOptions(outboundType string) (any, bool) {
method CreateOutbound (line 57) | func (r *Registry) CreateOutbound(ctx context.Context, router adapter....
method register (line 67) | func (r *Registry) register(outboundType string, optionsConstructor op...
function NewRegistry (line 40) | func NewRegistry() *Registry {
FILE: adapter/platform.go
type PlatformInterface (line 9) | type PlatformInterface interface
type FindConnectionOwnerRequest (line 45) | type FindConnectionOwnerRequest struct
type ConnectionOwner (line 53) | type ConnectionOwner struct
type Notification (line 61) | type Notification struct
type SystemProxyStatus (line 71) | type SystemProxyStatus struct
FILE: adapter/router.go
type Router (line 21) | type Router interface
type ConnectionTracker (line 35) | type ConnectionTracker interface
type ConnectionRouter (line 41) | type ConnectionRouter interface
type ConnectionRouterEx (line 46) | type ConnectionRouterEx interface
type RuleSet (line 52) | type RuleSet interface
type RuleSetUpdateCallback (line 67) | type RuleSetUpdateCallback
type RuleSetMetadata (line 69) | type RuleSetMetadata struct
type HTTPStartContext (line 74) | type HTTPStartContext struct
method HTTPClient (line 87) | func (c *HTTPStartContext) HTTPClient(detour string, dialer N.Dialer) ...
method Close (line 110) | func (c *HTTPStartContext) Close() {
function NewHTTPStartContext (line 80) | func NewHTTPStartContext(ctx context.Context) *HTTPStartContext {
FILE: adapter/rule.go
type HeadlessRule (line 7) | type HeadlessRule interface
type Rule (line 12) | type Rule interface
type DNSRule (line 19) | type DNSRule interface
type RuleAction (line 25) | type RuleAction interface
function IsFinalAction (line 30) | func IsFinalAction(action RuleAction) bool {
FILE: adapter/service.go
type Service (line 10) | type Service interface
type ServiceRegistry (line 16) | type ServiceRegistry interface
type ServiceManager (line 21) | type ServiceManager interface
FILE: adapter/service/adapter.go
type Adapter (line 3) | type Adapter struct
method Type (line 15) | func (a *Adapter) Type() string {
method Tag (line 19) | func (a *Adapter) Tag() string {
function NewAdapter (line 8) | func NewAdapter(serviceType string, serviceTag string) Adapter {
FILE: adapter/service/manager.go
type Manager (line 20) | type Manager struct
method Start (line 38) | func (m *Manager) Start(stage adapter.StartStage) error {
method Close (line 60) | func (m *Manager) Close() error {
method Services (line 85) | func (m *Manager) Services() []adapter.Service {
method Get (line 91) | func (m *Manager) Get(tag string) (adapter.Service, bool) {
method Remove (line 98) | func (m *Manager) Remove(tag string) error {
method Create (line 121) | func (m *Manager) Create(ctx context.Context, logger log.ContextLogger...
function NewManager (line 30) | func NewManager(logger log.ContextLogger, registry adapter.ServiceRegist...
FILE: adapter/service/registry.go
type ConstructorFunc (line 13) | type ConstructorFunc
function Register (line 15) | func Register[Options any](registry *Registry, outboundType string, cons...
type optionsConstructorFunc (line 30) | type optionsConstructorFunc
type constructorFunc (line 31) | type constructorFunc
type Registry (line 34) | type Registry struct
method CreateOptions (line 47) | func (m *Registry) CreateOptions(outboundType string) (any, bool) {
method Create (line 57) | func (m *Registry) Create(ctx context.Context, logger log.ContextLogge...
method register (line 67) | func (m *Registry) register(outboundType string, optionsConstructor op...
function NewRegistry (line 40) | func NewRegistry() *Registry {
FILE: adapter/ssm.go
type ManagedSSMServer (line 9) | type ManagedSSMServer interface
type SSMTracker (line 15) | type SSMTracker interface
FILE: adapter/time.go
type TimeService (line 5) | type TimeService interface
FILE: adapter/upstream.go
function NewUpstreamHandlerEx (line 16) | func NewUpstreamHandlerEx(
type myUpstreamHandlerWrapperEx (line 30) | type myUpstreamHandlerWrapperEx struct
method NewConnectionEx (line 36) | func (w *myUpstreamHandlerWrapperEx) NewConnectionEx(ctx context.Conte...
method NewPacketConnectionEx (line 47) | func (w *myUpstreamHandlerWrapperEx) NewPacketConnectionEx(ctx context...
type myUpstreamContextHandlerWrapperEx (line 60) | type myUpstreamContextHandlerWrapperEx struct
method NewConnectionEx (line 75) | func (w *myUpstreamContextHandlerWrapperEx) NewConnectionEx(ctx contex...
method NewPacketConnectionEx (line 86) | func (w *myUpstreamContextHandlerWrapperEx) NewPacketConnectionEx(ctx ...
function NewUpstreamContextHandlerEx (line 65) | func NewUpstreamContextHandlerEx(
function NewRouteHandlerEx (line 97) | func NewRouteHandlerEx(
type routeHandlerWrapperEx (line 109) | type routeHandlerWrapperEx struct
method NewConnectionEx (line 114) | func (r *routeHandlerWrapperEx) NewConnectionEx(ctx context.Context, c...
method NewPacketConnectionEx (line 124) | func (r *routeHandlerWrapperEx) NewPacketConnectionEx(ctx context.Cont...
function NewRouteContextHandlerEx (line 134) | func NewRouteContextHandlerEx(
type routeContextHandlerWrapperEx (line 144) | type routeContextHandlerWrapperEx struct
method NewConnectionEx (line 148) | func (r *routeContextHandlerWrapperEx) NewConnectionEx(ctx context.Con...
method NewPacketConnectionEx (line 159) | func (r *routeContextHandlerWrapperEx) NewPacketConnectionEx(ctx conte...
FILE: adapter/upstream_legacy.go
function NewUpstreamHandler (line 23) | func NewUpstreamHandler(
type myUpstreamHandlerWrapper (line 42) | type myUpstreamHandlerWrapper struct
method NewConnection (line 50) | func (w *myUpstreamHandlerWrapper) NewConnection(ctx context.Context, ...
method NewPacketConnection (line 62) | func (w *myUpstreamHandlerWrapper) NewPacketConnection(ctx context.Con...
method NewError (line 74) | func (w *myUpstreamHandlerWrapper) NewError(ctx context.Context, err e...
function UpstreamMetadata (line 79) | func UpstreamMetadata(metadata InboundContext) M.Metadata {
type myUpstreamContextHandlerWrapper (line 87) | type myUpstreamContextHandlerWrapper struct
method NewConnection (line 107) | func (w *myUpstreamContextHandlerWrapper) NewConnection(ctx context.Co...
method NewPacketConnection (line 119) | func (w *myUpstreamContextHandlerWrapper) NewPacketConnection(ctx cont...
method NewError (line 131) | func (w *myUpstreamContextHandlerWrapper) NewError(ctx context.Context...
function NewUpstreamContextHandler (line 94) | func NewUpstreamContextHandler(
function NewRouteHandler (line 136) | func NewRouteHandler(
function NewRouteContextHandler (line 149) | func NewRouteContextHandler(
type routeHandlerWrapper (line 164) | type routeHandlerWrapper struct
method NewConnection (line 171) | func (w *routeHandlerWrapper) NewConnection(ctx context.Context, conn ...
method NewPacketConnection (line 183) | func (w *routeHandlerWrapper) NewPacketConnection(ctx context.Context,...
method NewError (line 195) | func (w *routeHandlerWrapper) NewError(ctx context.Context, err error) {
type routeContextHandlerWrapper (line 202) | type routeContextHandlerWrapper struct
method NewConnection (line 208) | func (w *routeContextHandlerWrapper) NewConnection(ctx context.Context...
method NewPacketConnection (line 220) | func (w *routeContextHandlerWrapper) NewPacketConnection(ctx context.C...
method NewError (line 232) | func (w *routeContextHandlerWrapper) NewError(ctx context.Context, err...
FILE: adapter/v2ray.go
type V2RayServerTransport (line 10) | type V2RayServerTransport interface
type V2RayServerTransportHandler (line 17) | type V2RayServerTransportHandler interface
type V2RayClientTransport (line 21) | type V2RayClientTransport interface
FILE: box.go
type Box (line 39) | type Box struct
method PreStart (line 403) | func (s *Box) PreStart() error {
method Start (line 422) | func (s *Box) Start() error {
method preStart (line 441) | func (s *Box) preStart() error {
method start (line 464) | func (s *Box) start() error {
method Close (line 496) | func (s *Box) Close() error {
method Network (line 542) | func (s *Box) Network() adapter.NetworkManager {
method Router (line 546) | func (s *Box) Router() adapter.Router {
method Inbound (line 550) | func (s *Box) Inbound() adapter.InboundManager {
method Outbound (line 554) | func (s *Box) Outbound() adapter.OutboundManager {
method LogFactory (line 558) | func (s *Box) LogFactory() log.Factory {
type Options (line 56) | type Options struct
function Context (line 62) | func Context(
function New (line 96) | func New(options Options) (*Box, error) {
FILE: cmd/internal/app_store_connect/main.go
function main (line 19) | func main() {
constant appID (line 53) | appID = "6673731168"
constant groupID (line 54) | groupID = "5c5f3b78-b7a0-40c0-bcad-e6ef87bbefda"
function createClient (line 57) | func createClient(expireDuration time.Duration) *asc.Client {
function fetchMacOSVersion (line 69) | func fetchMacOSVersion(ctx context.Context) error {
function publishTestflight (line 102) | func publishTestflight(ctx context.Context) error {
function cancelAppStore (line 213) | func cancelAppStore(ctx context.Context, platform string) error {
function prepareAppStore (line 262) | func prepareAppStore(ctx context.Context) error {
function publishAppStore (line 402) | func publishAppStore(ctx context.Context) error {
function isRetryable (line 442) | func isRetryable(response *asc.Response) bool {
FILE: cmd/internal/build/main.go
function main (line 12) | func main() {
FILE: cmd/internal/build_libbox/main.go
function init (line 26) | func init() {
function main (line 33) | func main() {
function init (line 56) | func init() {
type AndroidBuildConfig (line 74) | type AndroidBuildConfig struct
function filterTags (line 80) | func filterTags(tags []string, exclude ...string) []string {
function checkJavaVersion (line 94) | func checkJavaVersion() {
function getAndroidBindTarget (line 112) | func getAndroidBindTarget() string {
function buildAndroidVariant (line 121) | func buildAndroidVariant(config AndroidBuildConfig, bindTarget string) {
function buildAndroid (line 160) | func buildAndroid() {
function buildApple (line 191) | func buildApple() {
FILE: cmd/internal/build_shared/sdk.go
function FindSDK (line 22) | func FindSDK() {
function findNDK (line 50) | func findNDK() bool {
function FindMobile (line 94) | func FindMobile() {
FILE: cmd/internal/build_shared/tag.go
function ReadTag (line 9) | func ReadTag() (string, error) {
function ReadTagVersionRev (line 23) | func ReadTagVersionRev() (badversion.Version, error) {
function ReadTagVersion (line 28) | func ReadTagVersion() (badversion.Version, error) {
FILE: cmd/internal/format_docs/main.go
function main (line 12) | func main() {
function processFile (line 30) | func processFile(path string) error {
FILE: cmd/internal/protogen/main.go
function envFile (line 18) | func envFile() (string, error) {
function GetRuntimeEnv (line 37) | func GetRuntimeEnv(key string) (string, error) {
function GetGOBIN (line 63) | func GetGOBIN() string {
function main (line 82) | func main() {
function NormalizeGeneratedProtoFile (line 184) | func NormalizeGeneratedProtoFile(path string) error {
FILE: cmd/internal/read_tag/main.go
function init (line 17) | func init() {
function main (line 22) | func main() {
function setGitHubEnv (line 55) | func setGitHubEnv(name string, value string) error {
FILE: cmd/internal/tun_bench/main.go
function main (line 26) | func main() {
function main0 (line 33) | func main0() error {
function runTests (line 47) | func runTests() ([]TestResult, error) {
type TestResult (line 93) | type TestResult struct
function testOnce (line 103) | func testOnce(boxPath string, stackName string, mtu int, multiThread boo...
type stderrWriter (line 280) | type stderrWriter struct
method Write (line 282) | func (w *stderrWriter) Write(p []byte) (n int, err error) {
FILE: cmd/internal/update_android_version/main.go
function init (line 21) | func init() {
function main (line 26) | func main() {
FILE: cmd/internal/update_apple_version/main.go
function init (line 19) | func init() {
function main (line 23) | func main() {
function findAndReplace (line 60) | func findAndReplace(objectsMap map[string]any, projectContent string, bu...
function findAndReplaceProjectVersion (line 84) | func findAndReplaceProjectVersion(objectsMap map[string]any, projectCont...
function findObjectKey (line 108) | func findObjectKey(objectsMap map[string]any, bundleIDList []string) []s...
function findObjectKeyByDirectory (line 126) | func findObjectKeyByDirectory(objectsMap map[string]any, directoryList [...
FILE: cmd/internal/update_certificates/main.go
function main (line 15) | func main() {
function updateMozillaIncludedRootCAs (line 26) | func updateMozillaIncludedRootCAs() error {
function fetchChinaFingerprints (line 77) | func fetchChinaFingerprints() (map[string]bool, error) {
function updateChromeIncludedRootCAs (line 106) | func updateChromeIncludedRootCAs() error {
FILE: cmd/sing-box/cmd.go
function init (line 32) | func init() {
function preRun (line 39) | func preRun(cmd *cobra.Command, args []string) {
FILE: cmd/sing-box/cmd_check.go
function init (line 24) | func init() {
function check (line 28) | func check() error {
FILE: cmd/sing-box/cmd_format.go
function init (line 30) | func init() {
function format (line 35) | func format() error {
FILE: cmd/sing-box/cmd_generate.go
function init (line 21) | func init() {
function init (line 45) | func init() {
function generateRandom (line 50) | func generateRandom(args []string) error {
function generateUUID (line 85) | func generateUUID() error {
FILE: cmd/sing-box/cmd_generate_ech.go
function init (line 24) | func init() {
function generateECHKeyPair (line 28) | func generateECHKeyPair(serverName string) error {
FILE: cmd/sing-box/cmd_generate_tls.go
function init (line 27) | func init() {
function generateTLSKeyPair (line 32) | func generateTLSKeyPair(serverName string) error {
FILE: cmd/sing-box/cmd_generate_vapid.go
function init (line 27) | func init() {
function generateVAPIDKeyPair (line 31) | func generateVAPIDKeyPair() error {
FILE: cmd/sing-box/cmd_generate_wireguard.go
function init (line 13) | func init() {
function generateWireGuardKey (line 30) | func generateWireGuardKey() error {
function generateRealityKey (line 52) | func generateRealityKey() error {
FILE: cmd/sing-box/cmd_geoip.go
function init (line 27) | func init() {
function geoipPreRun (line 32) | func geoipPreRun() error {
FILE: cmd/sing-box/cmd_geoip_export.go
constant flagGeoipExportDefaultOutput (line 21) | flagGeoipExportDefaultOutput = "geoip-<country>.srs"
function init (line 35) | func init() {
function geoipExport (line 40) | func geoipExport(countryCode string) error {
FILE: cmd/sing-box/cmd_geoip_list.go
function init (line 22) | func init() {
function listGeoip (line 26) | func listGeoip() error {
FILE: cmd/sing-box/cmd_geoip_lookup.go
function init (line 26) | func init() {
function geoipLookup (line 30) | func geoipLookup(address string) error {
FILE: cmd/sing-box/cmd_geosite.go
function init (line 28) | func init() {
function geositePreRun (line 33) | func geositePreRun() error {
FILE: cmd/sing-box/cmd_geosite_export.go
constant commandGeositeExportDefaultOutput (line 18) | commandGeositeExportDefaultOutput = "geosite-<category>.json"
function init (line 32) | func init() {
function geositeExport (line 37) | func geositeExport(category string) error {
FILE: cmd/sing-box/cmd_geosite_list.go
function init (line 24) | func init() {
function geositeList (line 28) | func geositeList() error {
FILE: cmd/sing-box/cmd_geosite_lookup.go
function init (line 36) | func init() {
function geositeLookup (line 40) | func geositeLookup(source string, target string) error {
FILE: cmd/sing-box/cmd_geosite_matcher.go
type searchGeositeMatcher (line 10) | type searchGeositeMatcher struct
method Match (line 32) | func (r *searchGeositeMatcher) Match(domain string) string {
function newSearchGeositeMatcher (line 17) | func newSearchGeositeMatcher(items []geosite.Item) (*searchGeositeMatche...
FILE: cmd/sing-box/cmd_merge.go
function init (line 32) | func init() {
function merge (line 36) | func merge(outputPath string) error {
function mergePathResources (line 70) | func mergePathResources(options *option.Options) error {
function mergeTLSInboundOptions (line 88) | func mergeTLSInboundOptions(options *option.InboundTLSOptions) *option.I...
function mergeTLSOutboundOptions (line 112) | func mergeTLSOutboundOptions(options *option.OutboundTLSOptions) *option...
function mergeSSHOutboundOptions (line 131) | func mergeSSHOutboundOptions(options *option.SSHOutboundOptions) {
function trimStringArray (line 139) | func trimStringArray(array []string) []string {
FILE: cmd/sing-box/cmd_rule_set.go
function init (line 12) | func init() {
FILE: cmd/sing-box/cmd_rule_set_compile.go
constant flagRuleSetCompileDefaultOutput (line 20) | flagRuleSetCompileDefaultOutput = "<file_name>.srs"
function init (line 34) | func init() {
function compileRuleSet (line 39) | func compileRuleSet(sourcePath string) error {
function downgradeRuleSetVersion (line 84) | func downgradeRuleSetVersion(version uint8, options option.PlainRuleSet)...
FILE: cmd/sing-box/cmd_rule_set_convert.go
function init (line 35) | func init() {
function convertRuleSet (line 41) | func convertRuleSet(sourcePath string) error {
FILE: cmd/sing-box/cmd_rule_set_decompile.go
constant flagRuleSetDecompileDefaultOutput (line 20) | flagRuleSetDecompileDefaultOutput = "<file_name>.json"
function init (line 34) | func init() {
function decompileRuleSet (line 39) | func decompileRuleSet(sourcePath string) error {
function hasRule (line 87) | func hasRule(rules []option.HeadlessRule, cond func(rule option.DefaultH...
FILE: cmd/sing-box/cmd_rule_set_format.go
function init (line 31) | func init() {
function formatRuleSet (line 36) | func formatRuleSet(sourcePath string) error {
FILE: cmd/sing-box/cmd_rule_set_match.go
function init (line 38) | func init() {
function ruleSetMatch (line 43) | func ruleSetMatch(sourcePath string, domain string) error {
FILE: cmd/sing-box/cmd_rule_set_merge.go
function init (line 38) | func init() {
type RuleSetEntry (line 44) | type RuleSetEntry struct
function readRuleSetAt (line 50) | func readRuleSetAt(path string) (*RuleSetEntry, error) {
function readRuleSet (line 74) | func readRuleSet() ([]*RuleSetEntry, error) {
function readRuleSetAndMerge (line 105) | func readRuleSetAndMerge() (option.PlainRuleSetCompat, error) {
function mergeRuleSet (line 134) | func mergeRuleSet(outputPath string) error {
FILE: cmd/sing-box/cmd_rule_set_upgrade.go
function init (line 32) | func init() {
function upgradeRuleSet (line 37) | func upgradeRuleSet(sourcePath string) error {
FILE: cmd/sing-box/cmd_run.go
function init (line 37) | func init() {
type OptionsEntry (line 41) | type OptionsEntry struct
function readConfigAt (line 47) | func readConfigAt(path string) (*OptionsEntry, error) {
function readConfig (line 71) | func readConfig() ([]*OptionsEntry, error) {
function readConfigAndMerge (line 102) | func readConfigAndMerge() (option.Options, error) {
function create (line 125) | func create() (*box.Box, context.CancelFunc, error) {
function run (line 169) | func run() error {
function closeMonitor (line 204) | func closeMonitor(ctx context.Context) {
FILE: cmd/sing-box/cmd_tools.go
function init (line 21) | func init() {
function createPreStartedClient (line 26) | func createPreStartedClient() (*box.Box, error) {
function createDialer (line 44) | func createDialer(instance *box.Box, outboundTag string) (N.Dialer, erro...
FILE: cmd/sing-box/cmd_tools_connect.go
function init (line 32) | func init() {
function connect (line 37) | func connect(address string) error {
FILE: cmd/sing-box/cmd_tools_fetch.go
function init (line 33) | func init() {
function fetch (line 42) | func fetch(args []string) error {
function fetchHTTP (line 99) | func fetchHTTP(httpClient *http.Client, parsedURL *url.URL) error {
FILE: cmd/sing-box/cmd_tools_fetch_http3.go
function initializeHTTP3Client (line 18) | func initializeHTTP3Client(instance *box.Box) error {
FILE: cmd/sing-box/cmd_tools_fetch_http3_stub.go
function initializeHTTP3Client (line 12) | func initializeHTTP3Client(instance *box.Box) error {
function fetchHTTP3 (line 16) | func fetchHTTP3(parsedURL *url.URL) error {
FILE: cmd/sing-box/cmd_tools_synctime.go
function init (line 34) | func init() {
function syncTime (line 41) | func syncTime() error {
FILE: cmd/sing-box/cmd_version.go
function init (line 22) | func init() {
function printVersion (line 27) | func printVersion(cmd *cobra.Command, args []string) {
FILE: cmd/sing-box/generate_completions.go
function main (line 7) | func main() {
function generateCompletions (line 14) | func generateCompletions() error {
FILE: cmd/sing-box/main.go
function main (line 7) | func main() {
FILE: common/badtls/raw_conn.go
type RawConn (line 16) | type RawConn struct
method ReadRecord (line 166) | func (c *RawConn) ReadRecord() error {
method HandlePostHandshakeMessage (line 170) | func (c *RawConn) HandlePostHandshakeMessage() error {
method WriteRecordLocked (line 174) | func (c *RawConn) WriteRecordLocked(typ uint16, data []byte) (int, err...
function NewRawConn (line 42) | func NewRawConn(rawTLSConn tls.Conn) (*RawConn, error) {
FILE: common/badtls/raw_half_conn.go
type RawHalfConn (line 14) | type RawHalfConn struct
method Decrypt (line 107) | func (hc *RawHalfConn) Decrypt(record []byte) ([]byte, uint8, error) {
method SetErrorLocked (line 111) | func (hc *RawHalfConn) SetErrorLocked(err error) error {
method SetTrafficSecret (line 115) | func (hc *RawHalfConn) SetTrafficSecret(suite unsafe.Pointer, level in...
method ExplicitNonceLen (line 119) | func (hc *RawHalfConn) ExplicitNonceLen() int {
function NewRawHalfConn (line 30) | func NewRawHalfConn(rawHalfConn reflect.Value, methods *Methods) (*RawHa...
FILE: common/badtls/read_wait.go
type ReadWaitConn (line 13) | type ReadWaitConn struct
method InitializeReadWaiter (line 33) | func (c *ReadWaitConn) InitializeReadWaiter(options N.ReadWaitOptions)...
method WaitReadBuffer (line 38) | func (c *ReadWaitConn) WaitReadBuffer() (buffer *buf.Buffer, err error) {
method Upstream (line 76) | func (c *ReadWaitConn) Upstream() any {
method ReaderReplaceable (line 80) | func (c *ReadWaitConn) ReaderReplaceable() bool {
function NewReadWaitConn (line 19) | func NewReadWaitConn(conn tls.Conn) (tls.Conn, error) {
FILE: common/badtls/read_wait_stub.go
function NewReadWaitConn (line 11) | func NewReadWaitConn(conn tls.Conn) (tls.Conn, error) {
FILE: common/badtls/registry.go
type Methods (line 11) | type Methods struct
function init (line 24) | func init() {
function stdTLSReadRecord (line 44) | func stdTLSReadRecord(c unsafe.Pointer) error
function stdTLSHandlePostHandshakeMessage (line 47) | func stdTLSHandlePostHandshakeMessage(c unsafe.Pointer) error
function stdWriteRecordLocked (line 50) | func stdWriteRecordLocked(c unsafe.Pointer, typ uint16, data []byte) (in...
function stdSetErrorLocked (line 53) | func stdSetErrorLocked(hc unsafe.Pointer, err error) error
function stdDecrypt (line 56) | func stdDecrypt(hc unsafe.Pointer, record []byte) ([]byte, uint8, error)
function stdSetTrafficSecret (line 59) | func stdSetTrafficSecret(hc unsafe.Pointer, suite unsafe.Pointer, level ...
function stdExplicitNonceLen (line 62) | func stdExplicitNonceLen(hc unsafe.Pointer) int
FILE: common/badtls/registry_utls.go
function init (line 14) | func init() {
function utlsReadRecord (line 38) | func utlsReadRecord(c unsafe.Pointer) error
function utlsHandlePostHandshakeMessage (line 41) | func utlsHandlePostHandshakeMessage(c unsafe.Pointer) error
function utlsWriteRecordLocked (line 44) | func utlsWriteRecordLocked(hc unsafe.Pointer, typ uint16, data []byte) (...
function utlsSetErrorLocked (line 47) | func utlsSetErrorLocked(hc unsafe.Pointer, err error) error
function utlsDecrypt (line 50) | func utlsDecrypt(hc unsafe.Pointer, record []byte) ([]byte, uint8, error)
function utlsSetTrafficSecret (line 53) | func utlsSetTrafficSecret(hc unsafe.Pointer, suite unsafe.Pointer, level...
function utlsExplicitNonceLen (line 56) | func utlsExplicitNonceLen(hc unsafe.Pointer) int
FILE: common/badversion/version.go
type Version (line 12) | type Version struct
method LessThan (line 21) | func (v Version) LessThan(anotherVersion Version) bool {
method LessThanOrEqual (line 25) | func (v Version) LessThanOrEqual(anotherVersion Version) bool {
method GreaterThanOrEqual (line 29) | func (v Version) GreaterThanOrEqual(anotherVersion Version) bool {
method GreaterThan (line 33) | func (v Version) GreaterThan(anotherVersion Version) bool {
method VersionString (line 84) | func (v Version) VersionString() string {
method String (line 88) | func (v Version) String() string {
method BadString (line 96) | func (v Version) BadString() string {
function parsePreReleaseIdentifier (line 73) | func parsePreReleaseIdentifier(identifier string) int {
function IsValid (line 110) | func IsValid(versionName string) bool {
function Parse (line 114) | func Parse(versionName string) (version Version) {
FILE: common/badversion/version_json.go
method MarshalJSON (line 5) | func (v Version) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 9) | func (v *Version) UnmarshalJSON(data []byte) error {
FILE: common/badversion/version_test.go
function TestCompareVersion (line 9) | func TestCompareVersion(t *testing.T) {
FILE: common/certificate/chrome.go
function init (line 9) | func init() {
FILE: common/certificate/mozilla.go
function init (line 9) | func init() {
FILE: common/certificate/store.go
type Store (line 23) | type Store struct
method Name (line 99) | func (s *Store) Name() string {
method Start (line 103) | func (s *Store) Start(stage adapter.StartStage) error {
method Close (line 113) | func (s *Store) Close() error {
method Pool (line 120) | func (s *Store) Pool() *x509.CertPool {
method update (line 126) | func (s *Store) update() error {
function NewStore (line 33) | func NewStore(ctx context.Context, logger logger.Logger, options option....
function readUniqueDirectoryEntries (line 172) | func readUniqueDirectoryEntries(dir string) ([]fs.DirEntry, error) {
function isSameDirSymlink (line 186) | func isSameDirSymlink(f fs.DirEntry, dir string) bool {
FILE: common/compatible/map.go
type Map (line 6) | type Map struct
method Len (line 10) | func (m *Map[K, V]) Len() int {
method Load (line 19) | func (m *Map[K, V]) Load(key K) (V, bool) {
method Store (line 28) | func (m *Map[K, V]) Store(key K, value V) {
method Delete (line 32) | func (m *Map[K, V]) Delete(key K) {
method Range (line 36) | func (m *Map[K, V]) Range(f func(key K, value V) bool) {
method LoadOrStore (line 42) | func (m *Map[K, V]) LoadOrStore(key K, value V) (V, bool) {
method LoadAndDelete (line 47) | func (m *Map[K, V]) LoadAndDelete(key K) (V, bool) {
function New (line 56) | func New[K comparable, V any]() *Map[K, V] {
FILE: common/convertor/adguard/convertor.go
type agdguardRuleLine (line 20) | type agdguardRuleLine struct
function ToOptions (line 31) | func ToOptions(reader io.Reader, logger logger.Logger) ([]option.Headles...
function FromOptions (line 306) | func FromOptions(rules []option.HeadlessRule) ([]byte, error) {
function ignoreIPCIDRRegexp (line 404) | func ignoreIPCIDRRegexp(ruleLine string) bool {
function parseAdGuardHostLine (line 416) | func parseAdGuardHostLine(ruleLine string) (string, error) {
function parseADGuardIPCIDRLine (line 435) | func parseADGuardIPCIDRLine(ruleLine string) (netip.Prefix, error) {
FILE: common/convertor/adguard/convertor_test.go
function TestConverter (line 15) | func TestConverter(t *testing.T) {
function TestHosts (line 84) | func TestHosts(t *testing.T) {
function TestSimpleHosts (line 115) | func TestSimpleHosts(t *testing.T) {
FILE: common/dialer/default.go
type DefaultDialer (line 30) | type DefaultDialer struct
method DialContext (line 239) | func (d *DefaultDialer) DialContext(ctx context.Context, network strin...
method DialParallelInterface (line 266) | func (d *DefaultDialer) DialParallelInterface(ctx context.Context, net...
method ListenPacket (line 314) | func (d *DefaultDialer) ListenPacket(ctx context.Context, destination ...
method DialerForICMPDestination (line 330) | func (d *DefaultDialer) DialerForICMPDestination(destination netip.Add...
method ListenSerialInterfacePacket (line 338) | func (d *DefaultDialer) ListenSerialInterfacePacket(ctx context.Contex...
method WireGuardControl (line 371) | func (d *DefaultDialer) WireGuardControl() control.Func {
method trackConn (line 375) | func (d *DefaultDialer) trackConn(conn net.Conn, err error) (net.Conn,...
method trackPacketConn (line 382) | func (d *DefaultDialer) trackPacketConn(conn net.PacketConn, err error...
function NewDefault (line 49) | func NewDefault(ctx context.Context, options option.DialerOptions) (*Def...
function setMarkWrapper (line 223) | func setMarkWrapper(networkManager adapter.NetworkManager, mark uint32, ...
FILE: common/dialer/default_parallel_interface.go
method dialParallelInterface (line 16) | func (d *DefaultDialer) dialParallelInterface(ctx context.Context, diale...
method dialParallelInterfaceFastFallback (line 90) | func (d *DefaultDialer) dialParallelInterfaceFastFallback(ctx context.Co...
method listenSerialInterfacePacket (line 153) | func (d *DefaultDialer) listenSerialInterfacePacket(ctx context.Context,...
function selectInterfaces (line 185) | func selectInterfaces(networkManager adapter.NetworkManager, strategy C....
FILE: common/dialer/default_parallel_network.go
function DialSerialNetwork (line 16) | func DialSerialNetwork(ctx context.Context, dialer N.Dialer, network str...
function DialParallelNetwork (line 47) | func DialParallelNetwork(ctx context.Context, dialer ParallelInterfaceDi...
function ListenSerialNetworkPacket (line 132) | func ListenSerialNetworkPacket(ctx context.Context, dialer N.Dialer, des...
FILE: common/dialer/detour.go
type DirectDialer (line 15) | type DirectDialer interface
type DetourDialer (line 19) | type DetourDialer struct
method Dialer (line 44) | func (d *DetourDialer) Dialer() (N.Dialer, error) {
method init (line 49) | func (d *DetourDialer) init() {
method DialContext (line 66) | func (d *DetourDialer) DialContext(ctx context.Context, network string...
method ListenPacket (line 74) | func (d *DetourDialer) ListenPacket(ctx context.Context, destination M...
method Upstream (line 82) | func (d *DetourDialer) Upstream() any {
function NewDetour (line 28) | func NewDetour(outboundManager adapter.OutboundManager, detour string, l...
function InitializeDetour (line 36) | func InitializeDetour(dialer N.Dialer) error {
FILE: common/dialer/dialer.go
type Options (line 19) | type Options struct
function New (line 31) | func New(ctx context.Context, options option.DialerOptions, remoteIsDoma...
function NewWithOptions (line 39) | func NewWithOptions(options Options) (N.Dialer, error) {
type ParallelInterfaceDialer (line 138) | type ParallelInterfaceDialer interface
type ParallelNetworkDialer (line 144) | type ParallelNetworkDialer interface
type PacketDialerWithDestination (line 149) | type PacketDialerWithDestination interface
FILE: common/dialer/resolve.go
type ResolveDialer (line 24) | type ResolveDialer interface
type ParallelInterfaceResolveDialer (line 29) | type ParallelInterfaceResolveDialer interface
type resolveDialer (line 34) | type resolveDialer struct
method initialize (line 77) | func (d *resolveDialer) initialize() error {
method initServer (line 82) | func (d *resolveDialer) initServer() {
method DialContext (line 94) | func (d *resolveDialer) DialContext(ctx context.Context, network strin...
method ListenPacket (line 114) | func (d *resolveDialer) ListenPacket(ctx context.Context, destination ...
method QueryOptions (line 134) | func (d *resolveDialer) QueryOptions() adapter.DNSQueryOptions {
method Upstream (line 138) | func (d *resolveDialer) Upstream() any {
function NewResolveDialer (line 46) | func NewResolveDialer(ctx context.Context, dialer N.Dialer, parallel boo...
type resolveParallelNetworkDialer (line 72) | type resolveParallelNetworkDialer struct
method DialParallelInterface (line 142) | func (d *resolveParallelNetworkDialer) DialParallelInterface(ctx conte...
method ListenSerialInterfacePacket (line 165) | func (d *resolveParallelNetworkDialer) ListenSerialInterfacePacket(ctx...
method QueryOptions (line 188) | func (d *resolveParallelNetworkDialer) QueryOptions() adapter.DNSQuery...
method Upstream (line 192) | func (d *resolveParallelNetworkDialer) Upstream() any {
FILE: common/dialer/router.go
type DefaultOutboundDialer (line 13) | type DefaultOutboundDialer struct
method DialContext (line 23) | func (d *DefaultOutboundDialer) DialContext(ctx context.Context, netwo...
method ListenPacket (line 27) | func (d *DefaultOutboundDialer) ListenPacket(ctx context.Context, dest...
method Upstream (line 31) | func (d *DefaultOutboundDialer) Upstream() any {
function NewDefaultOutbound (line 17) | func NewDefaultOutbound(ctx context.Context) N.Dialer {
FILE: common/dialer/tfo.go
type slowOpenConn (line 20) | type slowOpenConn struct
method Read (line 52) | func (c *slowOpenConn) Read(b []byte) (n int, err error) {
method Write (line 68) | func (c *slowOpenConn) Write(b []byte) (n int, err error) {
method Close (line 96) | func (c *slowOpenConn) Close() error {
method LocalAddr (line 107) | func (c *slowOpenConn) LocalAddr() net.Addr {
method RemoteAddr (line 115) | func (c *slowOpenConn) RemoteAddr() net.Addr {
method SetDeadline (line 123) | func (c *slowOpenConn) SetDeadline(t time.Time) error {
method SetReadDeadline (line 131) | func (c *slowOpenConn) SetReadDeadline(t time.Time) error {
method SetWriteDeadline (line 139) | func (c *slowOpenConn) SetWriteDeadline(t time.Time) error {
method Upstream (line 147) | func (c *slowOpenConn) Upstream() any {
method ReaderReplaceable (line 151) | func (c *slowOpenConn) ReaderReplaceable() bool {
method WriterReplaceable (line 155) | func (c *slowOpenConn) WriterReplaceable() bool {
method LazyHeadroom (line 159) | func (c *slowOpenConn) LazyHeadroom() bool {
method NeedHandshake (line 163) | func (c *slowOpenConn) NeedHandshake() bool {
method WriteTo (line 167) | func (c *slowOpenConn) WriteTo(w io.Writer) (n int64, err error) {
function DialSlowContext (line 33) | func DialSlowContext(dialer *tfo.Dialer, ctx context.Context, network st...
FILE: common/dialer/wireguard.go
type WireGuardListener (line 7) | type WireGuardListener interface
FILE: common/geoip/reader.go
type Reader (line 11) | type Reader struct
method Lookup (line 27) | func (r *Reader) Lookup(addr netip.Addr) string {
method Close (line 36) | func (r *Reader) Close() error {
function Open (line 15) | func Open(path string) (*Reader, []string, error) {
FILE: common/geosite/compat_test.go
function oldWriteString (line 17) | func oldWriteString(writer varbin.Writer, value string) error {
function oldWriteItem (line 22) | func oldWriteItem(writer varbin.Writer, item Item) error {
function oldReadString (line 27) | func oldReadString(reader varbin.Reader) (string, error) {
function oldReadItem (line 32) | func oldReadItem(reader varbin.Reader) (Item, error) {
function TestStringCompat (line 37) | func TestStringCompat(t *testing.T) {
function TestItemCompat (line 86) | func TestItemCompat(t *testing.T) {
function TestGeositeWriteReadCompat (line 140) | func TestGeositeWriteReadCompat(t *testing.T) {
function generateLargeItems (line 225) | func generateLargeItems(count int) map[string][]Item {
FILE: common/geosite/geosite_test.go
function TestGeosite (line 12) | func TestGeosite(t *testing.T) {
FILE: common/geosite/reader.go
type Reader (line 14) | type Reader struct
method readMetadata (line 57) | func (r *Reader) readMetadata() error {
method Read (line 103) | func (r *Reader) Read(code string) ([]Item, error) {
method Upstream (line 128) | func (r *Reader) Upstream() any {
function Open (line 23) | func Open(path string) (*Reader, []string, error) {
function NewReader (line 36) | func NewReader(readSeeker io.ReadSeeker) (*Reader, []string, error) {
type geositeMetadata (line 51) | type geositeMetadata struct
type readCounter (line 132) | type readCounter struct
method Read (line 137) | func (r *readCounter) Read(p []byte) (n int, err error) {
function readString (line 145) | func readString(reader io.ByteReader) (string, error) {
FILE: common/geosite/rule.go
constant RuleTypeDomain (line 8) | RuleTypeDomain ItemType = iota
constant RuleTypeDomainSuffix (line 9) | RuleTypeDomainSuffix
constant RuleTypeDomainKeyword (line 10) | RuleTypeDomainKeyword
constant RuleTypeDomainRegex (line 11) | RuleTypeDomainRegex
type Item (line 14) | type Item struct
function Compile (line 19) | func Compile(code []Item) option.DefaultRule {
function Merge (line 64) | func Merge(rules []option.DefaultRule) option.DefaultRule {
FILE: common/geosite/writer.go
function Write (line 10) | func Write(writer varbin.Writer, domains map[string][]Item) error {
function writeString (line 66) | func writeString(writer varbin.Writer, value string) error {
FILE: common/interrupt/conn.go
type Conn (line 19) | type Conn struct
method Close (line 29) | func (c *Conn) Close() error {
method ReaderReplaceable (line 36) | func (c *Conn) ReaderReplaceable() bool {
method WriterReplaceable (line 40) | func (c *Conn) WriterReplaceable() bool {
method Upstream (line 44) | func (c *Conn) Upstream() any {
type PacketConn (line 48) | type PacketConn struct
method Close (line 58) | func (c *PacketConn) Close() error {
method ReaderReplaceable (line 65) | func (c *PacketConn) ReaderReplaceable() bool {
method WriterReplaceable (line 69) | func (c *PacketConn) WriterReplaceable() bool {
method Upstream (line 73) | func (c *PacketConn) Upstream() any {
FILE: common/interrupt/context.go
type contextKeyIsExternalConnection (line 5) | type contextKeyIsExternalConnection struct
function ContextWithIsExternalConnection (line 7) | func ContextWithIsExternalConnection(ctx context.Context) context.Context {
function IsExternalConnectionFromContext (line 11) | func IsExternalConnectionFromContext(ctx context.Context) bool {
FILE: common/interrupt/group.go
type Group (line 11) | type Group struct
method NewConn (line 25) | func (g *Group) NewConn(conn net.Conn, isExternal bool) net.Conn {
method NewPacketConn (line 32) | func (g *Group) NewPacketConn(conn net.PacketConn, isExternal bool) ne...
method Interrupt (line 39) | func (g *Group) Interrupt(interruptExternalConnections bool) {
type groupConnItem (line 16) | type groupConnItem struct
function NewGroup (line 21) | func NewGroup() *Group {
FILE: common/ja3/error.go
constant LengthErr (line 13) | LengthErr string = "length check %v failed"
constant ContentTypeErr (line 14) | ContentTypeErr string = "content type not matching"
constant VersionErr (line 15) | VersionErr string = "version check %v failed"
constant HandshakeTypeErr (line 16) | HandshakeTypeErr string = "handshake type not matching"
constant SNITypeErr (line 17) | SNITypeErr string = "SNI type not supported"
type ParseError (line 21) | type ParseError struct
method Error (line 26) | func (e *ParseError) Error() string {
FILE: common/ja3/ja3.go
type ClientHello (line 16) | type ClientHello struct
method Equals (line 29) | func (j *ClientHello) Equals(another *ClientHello, ignoreExtensionsSeq...
method sortedExtensions (line 54) | func (j *ClientHello) sortedExtensions() []uint16 {
method String (line 67) | func (j *ClientHello) String() string {
method Hash (line 74) | func (j *ClientHello) Hash() string {
function Compute (line 61) | func Compute(payload []byte) (*ClientHello, error) {
FILE: common/ja3/parser.go
constant recordLayerHeaderLen (line 16) | recordLayerHeaderLen int = 5
constant handshakeHeaderLen (line 17) | handshakeHeaderLen int = 6
constant randomDataLen (line 18) | randomDataLen int = 32
constant sessionIDHeaderLen (line 19) | sessionIDHeaderLen int = 1
constant cipherSuiteHeaderLen (line 20) | cipherSuiteHeaderLen int = 2
constant compressMethodHeaderLen (line 21) | compressMethodHeaderLen int = 1
constant extensionsHeaderLen (line 22) | extensionsHeaderLen int = 2
constant extensionHeaderLen (line 23) | extensionHeaderLen int = 4
constant sniExtensionHeaderLen (line 24) | sniExtensionHeaderLen int = 5
constant ecExtensionHeaderLen (line 25) | ecExtensionHeaderLen int = 2
constant ecpfExtensionHeaderLen (line 26) | ecpfExtensionHeaderLen int = 1
constant versionExtensionHeaderLen (line 27) | versionExtensionHeaderLen int = 1
constant signatureAlgorithmsExtensionHeaderLen (line 28) | signatureAlgorithmsExtensionHeaderLen int = 2
constant contentType (line 29) | contentType uint8 = 22
constant handshakeType (line 30) | handshakeType uint8 = 1
constant sniExtensionType (line 31) | sniExtensionType uint16 = 0
constant sniNameDNSHostnameType (line 32) | sniNameDNSHostnameType uint8 = 0
constant ecExtensionType (line 33) | ecExtensionType uint16 = 10
constant ecpfExtensionType (line 34) | ecpfExtensionType uint16 = 11
constant versionExtensionType (line 35) | versionExtensionType uint16 = 43
constant signatureAlgorithmsExtensionType (line 36) | signatureAlgorithmsExtensionType uint16 = 13
constant tlsVersionBitmask (line 40) | tlsVersionBitmask uint16 = 0xFFFC
constant tls13 (line 41) | tls13 uint16 = 0x0304
constant GreaseBitmask (line 45) | GreaseBitmask uint16 = 0x0F0F
constant dashByte (line 48) | dashByte = byte(45)
constant commaByte (line 49) | commaByte = byte(44)
method parseSegment (line 53) | func (j *ClientHello) parseSegment(segment []byte) error {
method parseHandshake (line 85) | func (j *ClientHello) parseHandshake(hs []byte) error {
method parseExtensions (line 155) | func (j *ClientHello) parseExtensions(exs []byte) error {
method marshalJA3 (line 291) | func (j *ClientHello) marshalJA3() {
FILE: common/ktls/ktls.go
type Conn (line 24) | type Conn struct
method Upstream (line 89) | func (c *Conn) Upstream() any {
method SyscallConnForRead (line 93) | func (c *Conn) SyscallConnForRead() syscall.RawConn {
method HandleSyscallReadError (line 105) | func (c *Conn) HandleSyscallReadError(inputErr error) ([]byte, error) {
method SyscallConnForWrite (line 127) | func (c *Conn) SyscallConnForWrite() syscall.RawConn {
function NewConn (line 38) | func NewConn(ctx context.Context, logger logger.ContextLogger, conn aTLS...
FILE: common/ktls/ktls_alert.go
constant alertLevelWarning (line 16) | alertLevelWarning = 1
constant alertLevelError (line 17) | alertLevelError = 2
constant alertCloseNotify (line 21) | alertCloseNotify = 0
constant alertUnexpectedMessage (line 22) | alertUnexpectedMessage = 10
constant alertBadRecordMAC (line 23) | alertBadRecordMAC = 20
constant alertDecryptionFailed (line 24) | alertDecryptionFailed = 21
constant alertRecordOverflow (line 25) | alertRecordOverflow = 22
constant alertDecompressionFailure (line 26) | alertDecompressionFailure = 30
constant alertHandshakeFailure (line 27) | alertHandshakeFailure = 40
constant alertBadCertificate (line 28) | alertBadCertificate = 42
constant alertUnsupportedCertificate (line 29) | alertUnsupportedCertificate = 43
constant alertCertificateRevoked (line 30) | alertCertificateRevoked = 44
constant alertCertificateExpired (line 31) | alertCertificateExpired = 45
constant alertCertificateUnknown (line 32) | alertCertificateUnknown = 46
constant alertIllegalParameter (line 33) | alertIllegalParameter = 47
constant alertUnknownCA (line 34) | alertUnknownCA = 48
constant alertAccessDenied (line 35) | alertAccessDenied = 49
constant alertDecodeError (line 36) | alertDecodeError = 50
constant alertDecryptError (line 37) | alertDecryptError = 51
constant alertExportRestriction (line 38) | alertExportRestriction = 60
constant alertProtocolVersion (line 39) | alertProtocolVersion = 70
constant alertInsufficientSecurity (line 40) | alertInsufficientSecurity = 71
constant alertInternalError (line 41) | alertInternalError = 80
constant alertInappropriateFallback (line 42) | alertInappropriateFallback = 86
constant alertUserCanceled (line 43) | alertUserCanceled = 90
constant alertNoRenegotiation (line 44) | alertNoRenegotiation = 100
constant alertMissingExtension (line 45) | alertMissingExtension = 109
constant alertUnsupportedExtension (line 46) | alertUnsupportedExtension = 110
constant alertCertificateUnobtainable (line 47) | alertCertificateUnobtainable = 111
constant alertUnrecognizedName (line 48) | alertUnrecognizedName = 112
constant alertBadCertificateStatusResponse (line 49) | alertBadCertificateStatusResponse = 113
constant alertBadCertificateHashValue (line 50) | alertBadCertificateHashValue = 114
constant alertUnknownPSKIdentity (line 51) | alertUnknownPSKIdentity = 115
constant alertCertificateRequired (line 52) | alertCertificateRequired = 116
constant alertNoApplicationProtocol (line 53) | alertNoApplicationProtocol = 120
constant alertECHRequired (line 54) | alertECHRequired = 121
method sendAlertLocked (line 57) | func (c *Conn) sendAlertLocked(err uint8) error {
method sendAlert (line 76) | func (c *Conn) sendAlert(err uint8) error {
FILE: common/ktls/ktls_cipher_suites_linux.go
type kernelCryptoCipherType (line 16) | type kernelCryptoCipherType
constant TLS_CIPHER_AES_GCM_128 (line 19) | TLS_CIPHER_AES_GCM_128 kernelCryptoCipherType = 51
constant TLS_CIPHER_AES_GCM_128_IV_SIZE (line 20) | TLS_CIPHER_AES_GCM_128_IV_SIZE kernelCryptoCipherType = 8
constant TLS_CIPHER_AES_GCM_128_KEY_SIZE (line 21) | TLS_CIPHER_AES_GCM_128_KEY_SIZE kernelCryptoCipherType = 16
constant TLS_CIPHER_AES_GCM_128_SALT_SIZE (line 22) | TLS_CIPHER_AES_GCM_128_SALT_SIZE kernelCryptoCipherType = 4
constant TLS_CIPHER_AES_GCM_128_TAG_SIZE (line 23) | TLS_CIPHER_AES_GCM_128_TAG_SIZE kernelCryptoCipherType = 16
constant TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE (line 24) | TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE kernelCryptoCipherType = 8
constant TLS_CIPHER_AES_GCM_256 (line 26) | TLS_CIPHER_AES_GCM_256 kernelCryptoCipherType = 52
constant TLS_CIPHER_AES_GCM_256_IV_SIZE (line 27) | TLS_CIPHER_AES_GCM_256_IV_SIZE kernelCryptoCipherType = 8
constant TLS_CIPHER_AES_GCM_256_KEY_SIZE (line 28) | TLS_CIPHER_AES_GCM_256_KEY_SIZE kernelCryptoCipherType = 32
constant TLS_CIPHER_AES_GCM_256_SALT_SIZE (line 29) | TLS_CIPHER_AES_GCM_256_SALT_SIZE kernelCryptoCipherType = 4
constant TLS_CIPHER_AES_GCM_256_TAG_SIZE (line 30) | TLS_CIPHER_AES_GCM_256_TAG_SIZE kernelCryptoCipherType = 16
constant TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE (line 31) | TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE kernelCryptoCipherType = 8
constant TLS_CIPHER_AES_CCM_128 (line 33) | TLS_CIPHER_AES_CCM_128 kernelCryptoCipherType = 53
constant TLS_CIPHER_AES_CCM_128_IV_SIZE (line 34) | TLS_CIPHER_AES_CCM_128_IV_SIZE kernelCryptoCipherType = 8
constant TLS_CIPHER_AES_CCM_128_KEY_SIZE (line 35) | TLS_CIPHER_AES_CCM_128_KEY_SIZE kernelCryptoCipherType = 16
constant TLS_CIPHER_AES_CCM_128_SALT_SIZE (line 36) | TLS_CIPHER_AES_CCM_128_SALT_SIZE kernelCryptoCipherType = 4
constant TLS_CIPHER_AES_CCM_128_TAG_SIZE (line 37) | TLS_CIPHER_AES_CCM_128_TAG_SIZE kernelCryptoCipherType = 16
constant TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE (line 38) | TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE kernelCryptoCipherType = 8
constant TLS_CIPHER_CHACHA20_POLY1305 (line 40) | TLS_CIPHER_CHACHA20_POLY1305 kernelCryptoCipherType = 54
constant TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE (line 41) | TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE kernelCryptoCipherType = 12
constant TLS_CIPHER_CHACHA20_POLY1305_KEY_SIZE (line 42) | TLS_CIPHER_CHACHA20_POLY1305_KEY_SIZE kernelCryptoCipherType = 32
constant TLS_CIPHER_CHACHA20_POLY1305_SALT_SIZE (line 43) | TLS_CIPHER_CHACHA20_POLY1305_SALT_SIZE kernelCryptoCipherType = 0
constant TLS_CIPHER_CHACHA20_POLY1305_TAG_SIZE (line 44) | TLS_CIPHER_CHACHA20_POLY1305_TAG_SIZE kernelCryptoCipherType = 16
constant TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE (line 45) | TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE kernelCryptoCipherType = 8
constant TLS_CIPHER_ARIA_GCM_128 (line 61) | TLS_CIPHER_ARIA_GCM_128 kernelCryptoCipherType = 57
constant TLS_CIPHER_ARIA_GCM_128_IV_SIZE (line 62) | TLS_CIPHER_ARIA_GCM_128_IV_SIZE kernelCryptoCipherType = 8
constant TLS_CIPHER_ARIA_GCM_128_KEY_SIZE (line 63) | TLS_CIPHER_ARIA_GCM_128_KEY_SIZE kernelCryptoCipherType = 16
constant TLS_CIPHER_ARIA_GCM_128_SALT_SIZE (line 64) | TLS_CIPHER_ARIA_GCM_128_SALT_SIZE kernelCryptoCipherType = 4
constant TLS_CIPHER_ARIA_GCM_128_TAG_SIZE (line 65) | TLS_CIPHER_ARIA_GCM_128_TAG_SIZE kernelCryptoCipherType = 16
constant TLS_CIPHER_ARIA_GCM_128_REC_SEQ_SIZE (line 66) | TLS_CIPHER_ARIA_GCM_128_REC_SEQ_SIZE kernelCryptoCipherType = 8
constant TLS_CIPHER_ARIA_GCM_256 (line 68) | TLS_CIPHER_ARIA_GCM_256 kernelCryptoCipherType = 58
constant TLS_CIPHER_ARIA_GCM_256_IV_SIZE (line 69) | TLS_CIPHER_ARIA_GCM_256_IV_SIZE kernelCryptoCipherType = 8
constant TLS_CIPHER_ARIA_GCM_256_KEY_SIZE (line 70) | TLS_CIPHER_ARIA_GCM_256_KEY_SIZE kernelCryptoCipherType = 32
constant TLS_CIPHER_ARIA_GCM_256_SALT_SIZE (line 71) | TLS_CIPHER_ARIA_GCM_256_SALT_SIZE kernelCryptoCipherType = 4
constant TLS_CIPHER_ARIA_GCM_256_TAG_SIZE (line 72) | TLS_CIPHER_ARIA_GCM_256_TAG_SIZE kernelCryptoCipherType = 16
constant TLS_CIPHER_ARIA_GCM_256_REC_SEQ_SIZE (line 73) | TLS_CIPHER_ARIA_GCM_256_REC_SEQ_SIZE kernelCryptoCipherType = 8
type kernelCrypto (line 76) | type kernelCrypto interface
type kernelCryptoInfo (line 80) | type kernelCryptoInfo struct
type kernelCryptoAES128GCM (line 87) | type kernelCryptoAES128GCM struct
method String (line 95) | func (crypto *kernelCryptoAES128GCM) String() string {
type kernelCryptoAES256GCM (line 102) | type kernelCryptoAES256GCM struct
method String (line 110) | func (crypto *kernelCryptoAES256GCM) String() string {
type kernelCryptoAES128CCM (line 117) | type kernelCryptoAES128CCM struct
method String (line 125) | func (crypto *kernelCryptoAES128CCM) String() string {
type kernelCryptoChacha20Poly1035 (line 132) | type kernelCryptoChacha20Poly1035 struct
method String (line 140) | func (crypto *kernelCryptoChacha20Poly1035) String() string {
type kernelCryptoARIA128GCM (line 177) | type kernelCryptoARIA128GCM struct
method String (line 185) | func (crypto *kernelCryptoARIA128GCM) String() string {
type kernelCryptoARIA256GCM (line 192) | type kernelCryptoARIA256GCM struct
method String (line 200) | func (crypto *kernelCryptoARIA256GCM) String() string {
function kernelCipher (line 205) | func kernelCipher(kernel *Support, hc *badtls.RawHalfConn, cipherSuite u...
FILE: common/ktls/ktls_close.go
method Close (line 15) | func (c *Conn) Close() error {
method closeNotify (line 54) | func (c *Conn) closeNotify() error {
FILE: common/ktls/ktls_const.go
constant maxPlaintext (line 10) | maxPlaintext = 16384
constant maxCiphertext (line 11) | maxCiphertext = 16384 + 2048
constant maxCiphertextTLS13 (line 12) | maxCiphertextTLS13 = 16384 + 256
constant recordHeaderLen (line 13) | recordHeaderLen = 5
constant maxHandshake (line 14) | maxHandshake = 65536
constant maxHandshakeCertificateMsg (line 15) | maxHandshakeCertificateMsg = 262144
constant maxUselessRecords (line 16) | maxUselessRecords = 16
constant recordTypeChangeCipherSpec (line 20) | recordTypeChangeCipherSpec = 20
constant recordTypeAlert (line 21) | recordTypeAlert = 21
constant recordTypeHandshake (line 22) | recordTypeHandshake = 22
constant recordTypeApplicationData (line 23) | recordTypeApplicationData = 23
FILE: common/ktls/ktls_handshake_messages.go
type marshalingFunction (line 17) | type marshalingFunction
method Marshal (line 19) | func (f marshalingFunction) Marshal(b *cryptobyte.Builder) error {
function addBytesWithLength (line 25) | func addBytesWithLength(b *cryptobyte.Builder, v []byte, n int) {
function addUint64 (line 36) | func addUint64(b *cryptobyte.Builder, v uint64) {
function readUint64 (line 43) | func readUint64(s *cryptobyte.String, out *uint64) bool {
function readUint8LengthPrefixed (line 54) | func readUint8LengthPrefixed(s *cryptobyte.String, out *[]byte) bool {
function readUint16LengthPrefixed (line 60) | func readUint16LengthPrefixed(s *cryptobyte.String, out *[]byte) bool {
function readUint24LengthPrefixed (line 66) | func readUint24LengthPrefixed(s *cryptobyte.String, out *[]byte) bool {
type keyUpdateMsg (line 70) | type keyUpdateMsg struct
method marshal (line 74) | func (m *keyUpdateMsg) marshal() ([]byte, error) {
method unmarshal (line 88) | func (m *keyUpdateMsg) unmarshal(data []byte) bool {
constant typeHelloRequest (line 109) | typeHelloRequest uint8 = 0
constant typeClientHello (line 110) | typeClientHello uint8 = 1
constant typeServerHello (line 111) | typeServerHello uint8 = 2
constant typeNewSessionTicket (line 112) | typeNewSessionTicket uint8 = 4
constant typeEndOfEarlyData (line 113) | typeEndOfEarlyData uint8 = 5
constant typeEncryptedExtensions (line 114) | typeEncryptedExtensions uint8 = 8
constant typeCertificate (line 115) | typeCertificate uint8 = 11
constant typeServerKeyExchange (line 116) | typeServerKeyExchange uint8 = 12
constant typeCertificateRequest (line 117) | typeCertificateRequest uint8 = 13
constant typeServerHelloDone (line 118) | typeServerHelloDone uint8 = 14
constant typeCertificateVerify (line 119) | typeCertificateVerify uint8 = 15
constant typeClientKeyExchange (line 120) | typeClientKeyExchange uint8 = 16
constant typeFinished (line 121) | typeFinished uint8 = 20
constant typeCertificateStatus (line 122) | typeCertificateStatus uint8 = 22
constant typeKeyUpdate (line 123) | typeKeyUpdate uint8 = 24
constant typeCompressedCertificate (line 124) | typeCompressedCertificate uint8 = 25
constant typeMessageHash (line 125) | typeMessageHash uint8 = 254
constant compressionNone (line 130) | compressionNone uint8 = 0
constant extensionServerName (line 135) | extensionServerName uint16 = 0
constant extensionStatusRequest (line 136) | extensionStatusRequest uint16 = 5
constant extensionSupportedCurves (line 137) | extensionSupportedCurves uint16 = 10
constant extensionSupportedPoints (line 138) | extensionSupportedPoints uint16 = 11
constant extensionSignatureAlgorithms (line 139) | extensionSignatureAlgorithms uint16 = 13
constant extensionALPN (line 140) | extensionALPN uint16 = 16
constant extensionSCT (line 141) | extensionSCT uint16 = 18
constant extensionPadding (line 142) | extensionPadding uint16 = 21
constant extensionExtendedMasterSecret (line 143) | extensionExtendedMasterSecret uint16 = 23
constant extensionCompressCertificate (line 144) | extensionCompressCertificate uint16 = 27
constant extensionSessionTicket (line 145) | extensionSessionTicket uint16 = 35
constant extensionPreSharedKey (line 146) | extensionPreSharedKey uint16 = 41
constant extensionEarlyData (line 147) | extensionEarlyData uint16 = 42
constant extensionSupportedVersions (line 148) | extensionSupportedVersions uint16 = 43
constant extensionCookie (line 149) | extensionCookie uint16 = 44
constant extensionPSKModes (line 150) | extensionPSKModes uint16 = 45
constant extensionCertificateAuthorities (line 151) | extensionCertificateAuthorities uint16 = 47
constant extensionSignatureAlgorithmsCert (line 152) | extensionSignatureAlgorithmsCert uint16 = 50
constant extensionKeyShare (line 153) | extensionKeyShare uint16 = 51
constant extensionQUICTransportParameters (line 154) | extensionQUICTransportParameters uint16 = 57
constant extensionALPS (line 155) | extensionALPS uint16 = 17513
constant extensionRenegotiationInfo (line 156) | extensionRenegotiationInfo uint16 = 0xff01
constant extensionECHOuterExtensions (line 157) | extensionECHOuterExtensions uint16 = 0xfd00
constant extensionEncryptedClientHello (line 158) | extensionEncryptedClientHello uint16 = 0xfe0d
type handshakeMessage (line 161) | type handshakeMessage interface
type newSessionTicketMsgTLS13 (line 165) | type newSessionTicketMsgTLS13 struct
method marshal (line 173) | func (m *newSessionTicketMsgTLS13) marshal() ([]byte, error) {
method unmarshal (line 199) | func (m *newSessionTicketMsgTLS13) unmarshal(data []byte) bool {
FILE: common/ktls/ktls_key_update.go
method handlePostHandshakeMessage (line 19) | func (c *Conn) handlePostHandshakeMessage() error {
method handleKeyUpdate (line 49) | func (c *Conn) handleKeyUpdate(keyUpdate *keyUpdateMsg) error {
method readHandshakeBytes (line 103) | func (c *Conn) readHandshakeBytes(n int) error {
method readHandshake (line 115) | func (c *Conn) readHandshake(transcript io.Writer) (any, error) {
method unmarshalHandshakeMessage (line 144) | func (c *Conn) unmarshalHandshakeMessage(data []byte, transcript io.Writ...
FILE: common/ktls/ktls_linux.go
constant TLS_TX (line 26) | TLS_TX = 1
constant TLS_RX (line 27) | TLS_RX = 2
constant TLS_TX_ZEROCOPY_RO (line 28) | TLS_TX_ZEROCOPY_RO = 3
constant TLS_RX_EXPECT_NO_PAD (line 29) | TLS_RX_EXPECT_NO_PAD = 4
constant TLS_SET_RECORD_TYPE (line 31) | TLS_SET_RECORD_TYPE = 1
constant TLS_GET_RECORD_TYPE (line 32) | TLS_GET_RECORD_TYPE = 2
type Support (line 35) | type Support struct
function Load (line 114) | func Load() error {
method setupKernel (line 125) | func (c *Conn) setupKernel(txOffload, rxOffload bool) error {
method resetupTX (line 193) | func (c *Conn) resetupTX() (func() error, error) {
method resetupRX (line 215) | func (c *Conn) resetupRX() error {
method readKernelRecord (line 235) | func (c *Conn) readKernelRecord() (uint8, []byte, error) {
method writeKernelRecord (line 290) | func (c *Conn) writeKernelRecord(typ uint16, data []byte) (int, error) {
function recvmsg (line 326) | func recvmsg(fd int, msg *unix.Msghdr, flags int) (n int, err error)
function sendmsg (line 329) | func sendmsg(fd int, msg *unix.Msghdr, flags int) (n int, err error)
FILE: common/ktls/ktls_prf.go
function cipherSuiteByID (line 12) | func cipherSuiteByID(id uint16) unsafe.Pointer
function keysFromMasterSecret (line 15) | func keysFromMasterSecret(version uint16, suite unsafe.Pointer, masterSe...
function cipherSuiteTLS13ByID (line 18) | func cipherSuiteTLS13ByID(id uint16) unsafe.Pointer
function nextTrafficSecret (line 21) | func nextTrafficSecret(cs unsafe.Pointer, trafficSecret []byte) []byte
function trafficKey (line 24) | func trafficKey(cs unsafe.Pointer, trafficSecret []byte) (key, iv []byte)
FILE: common/ktls/ktls_read.go
method Read (line 18) | func (c *Conn) Read(b []byte) (int, error) {
method readRecord (line 62) | func (c *Conn) readRecord() error {
method readRawRecord (line 170) | func (c *Conn) readRawRecord() (typ uint8, data []byte, err error) {
method retryReadRecord (line 241) | func (c *Conn) retryReadRecord( /*expectChangeCipherSpec bool*/ ) error {
type atLeastReader (line 253) | type atLeastReader struct
method Read (line 258) | func (r *atLeastReader) Read(p []byte) (int, error) {
method readFromUntil (line 275) | func (c *Conn) readFromUntil(r io.Reader, n int) error {
method newRecordHeaderError (line 288) | func (c *Conn) newRecordHeaderError(conn net.Conn, msg string) (err tls....
FILE: common/ktls/ktls_read_wait.go
method InitializeReadWaiter (line 14) | func (c *Conn) InitializeReadWaiter(options N.ReadWaitOptions) (needCopy...
method WaitReadBuffer (line 19) | func (c *Conn) WaitReadBuffer() (buffer *buf.Buffer, err error) {
FILE: common/ktls/ktls_stub_nolinkname.go
function NewConn (line 13) | func NewConn(ctx context.Context, logger logger.ContextLogger, conn aTLS...
FILE: common/ktls/ktls_stub_nonlinux.go
function NewConn (line 13) | func NewConn(ctx context.Context, logger logger.ContextLogger, conn aTLS...
FILE: common/ktls/ktls_stub_oldgo.go
function NewConn (line 13) | func NewConn(ctx context.Context, logger logger.ContextLogger, conn aTLS...
FILE: common/ktls/ktls_write.go
method Write (line 16) | func (c *Conn) Write(b []byte) (int, error) {
method writeRecordLocked (line 76) | func (c *Conn) writeRecordLocked(typ uint16, data []byte) (n int, err er...
constant tcpMSSEstimate (line 101) | tcpMSSEstimate = 1208
constant recordSizeBoostThreshold (line 106) | recordSizeBoostThreshold = 128 * 1024
method maxPayloadSizeForWrite (line 109) | func (c *Conn) maxPayloadSizeForWrite(typ uint16) int {
FILE: common/listener/listener.go
type Listener (line 23) | type Listener struct
method Start (line 80) | func (l *Listener) Start() error {
method Close (line 122) | func (l *Listener) Close() error {
method TCPListener (line 134) | func (l *Listener) TCPListener() net.Listener {
method UDPConn (line 138) | func (l *Listener) UDPConn() *net.UDPConn {
method ListenOptions (line 142) | func (l *Listener) ListenOptions() option.ListenOptions {
type Options (line 46) | type Options struct
function New (line 61) | func New(
function ListenNetworkNamespace (line 146) | func ListenNetworkNamespace[T any](nameOrPath string, block func() (T, e...
FILE: common/listener/listener_tcp.go
method ListenTCP (line 23) | func (l *Listener) ListenTCP() (net.Listener, error) {
method loopTCPIn (line 82) | func (l *Listener) loopTCPIn() {
FILE: common/listener/listener_udp.go
method ListenUDP (line 21) | func (l *Listener) ListenUDP() (net.PacketConn, error) {
method DialContext (line 61) | func (l *Listener) DialContext(dialer net.Dialer, ctx context.Context, n...
method ListenPacket (line 76) | func (l *Listener) ListenPacket(listenConfig net.ListenConfig, ctx conte...
method UDPAddr (line 91) | func (l *Listener) UDPAddr() M.Socksaddr {
method PacketWriter (line 95) | func (l *Listener) PacketWriter() N.PacketWriter {
method loopUDPIn (line 99) | func (l *Listener) loopUDPIn() {
method loopUDPOut (line 156) | func (l *Listener) loopUDPOut() {
type packetWriter (line 186) | type packetWriter
method WritePacket (line 188) | func (w *packetWriter) WritePacket(buffer *buf.Buffer, destination M.S...
method WriteIsThreadUnsafe (line 206) | func (w *packetWriter) WriteIsThreadUnsafe() {
FILE: common/mux/client.go
function NewClientWithOptions (line 19) | func NewClientWithOptions(dialer N.Dialer, logger logger.Logger, options...
type clientDialer (line 49) | type clientDialer struct
method DialContext (line 53) | func (d *clientDialer) DialContext(ctx context.Context, network string...
method ListenPacket (line 57) | func (d *clientDialer) ListenPacket(ctx context.Context, destination M...
FILE: common/mux/router.go
type Router (line 17) | type Router struct
method RouteConnection (line 56) | func (r *Router) RouteConnection(ctx context.Context, conn net.Conn, m...
method RoutePacketConnection (line 66) | func (r *Router) RoutePacketConnection(ctx context.Context, conn N.Pac...
method RouteConnectionEx (line 70) | func (r *Router) RouteConnectionEx(ctx context.Context, conn net.Conn,...
method RoutePacketConnectionEx (line 78) | func (r *Router) RoutePacketConnectionEx(ctx context.Context, conn N.P...
function NewRouterWithOptions (line 22) | func NewRouterWithOptions(router adapter.ConnectionRouterEx, logger logg...
FILE: common/pipelistener/listener.go
type Listener (line 10) | type Listener struct
method Serve (line 22) | func (l *Listener) Serve(conn net.Conn) {
method Accept (line 26) | func (l *Listener) Accept() (net.Conn, error) {
method Close (line 35) | func (l *Listener) Close() error {
method Addr (line 45) | func (l *Listener) Addr() net.Addr {
function New (line 15) | func New(channelSize int) *Listener {
type addr (line 49) | type addr struct
method Network (line 51) | func (a addr) Network() string {
method String (line 55) | func (a addr) String() string {
FILE: common/process/searcher.go
type Searcher (line 15) | type Searcher interface
type Config (line 21) | type Config struct
function FindProcessInfo (line 26) | func FindProcessInfo(searcher Searcher, ctx context.Context, network str...
FILE: common/process/searcher_android.go
type androidSearcher (line 13) | type androidSearcher struct
method FindProcessInfo (line 21) | func (s *androidSearcher) FindProcessInfo(ctx context.Context, network...
function NewSearcher (line 17) | func NewSearcher(config Config) (Searcher, error) {
FILE: common/process/searcher_darwin.go
type darwinSearcher (line 21) | type darwinSearcher struct
method FindProcessInfo (line 27) | func (d *darwinSearcher) FindProcessInfo(ctx context.Context, network ...
function NewSearcher (line 23) | func NewSearcher(_ Config) (Searcher, error) {
function findProcessName (line 51) | func findProcessName(network string, ip netip.Addr, port int) (string, e...
function getExecPathFromPID (line 129) | func getExecPathFromPID(pid uint32) (string, error) {
function readNativeUint32 (line 151) | func readNativeUint32(b []byte) uint32 {
FILE: common/process/searcher_linux.go
type linuxSearcher (line 15) | type linuxSearcher struct
method FindProcessInfo (line 23) | func (s *linuxSearcher) FindProcessInfo(ctx context.Context, network s...
function NewSearcher (line 19) | func NewSearcher(config Config) (Searcher, error) {
FILE: common/process/searcher_linux_shared.go
constant sizeOfSocketDiagRequest (line 34) | sizeOfSocketDiagRequest = syscall.SizeofNlMsghdr + 8 + 48
constant socketDiagByFamily (line 35) | socketDiagByFamily = 20
constant pathProc (line 36) | pathProc = "/proc"
function resolveSocketByNetlink (line 39) | func resolveSocketByNetlink(network string, source netip.AddrPort, desti...
function packSocketDiagRequest (line 110) | func packSocketDiagRequest(family, protocol byte, source netip.AddrPort)...
function unpackSocketDiagResponse (line 140) | func unpackSocketDiagResponse(msg *syscall.NetlinkMessage) (inode, uid u...
function resolveProcessNameByProcSearch (line 153) | func resolveProcessNameByProcSearch(inode, uid uint32) (string, error) {
function isPid (line 198) | func isPid(s string) bool {
FILE: common/process/searcher_stub.go
function NewSearcher (line 9) | func NewSearcher(_ Config) (Searcher, error) {
FILE: common/process/searcher_windows.go
type windowsSearcher (line 17) | type windowsSearcher struct
method FindProcessInfo (line 31) | func (s *windowsSearcher) FindProcessInfo(ctx context.Context, network...
function NewSearcher (line 19) | func NewSearcher(_ Config) (Searcher, error) {
function initWin32API (line 27) | func initWin32API() error {
function getProcessPath (line 43) | func getProcessPath(pid uint32) (string, error) {
FILE: common/redir/redir_darwin.go
constant PF_OUT (line 13) | PF_OUT = 0x2
constant DIOCNATLOOK (line 14) | DIOCNATLOOK = 0xc0544417
function GetOriginalDestination (line 17) | func GetOriginalDestination(conn net.Conn) (destination netip.AddrPort, ...
FILE: common/redir/redir_linux.go
function GetOriginalDestination (line 15) | func GetOriginalDestination(conn net.Conn) (destination netip.AddrPort, ...
FILE: common/redir/redir_other.go
function GetOriginalDestination (line 11) | func GetOriginalDestination(conn net.Conn) (destination netip.AddrPort, ...
FILE: common/redir/tproxy_linux.go
function TProxy (line 15) | func TProxy(fd uintptr, isIPv6 bool, isUDP bool) error {
function TProxyWriteBack (line 34) | func TProxyWriteBack() control.Func {
function GetOriginalDestinationFromOOB (line 46) | func GetOriginalDestinationFromOOB(oob []byte) (netip.AddrPort, error) {
FILE: common/redir/tproxy_other.go
function TProxy (line 12) | func TProxy(fd uintptr, isIPv6 bool, isUDP bool) error {
function TProxyWriteBack (line 16) | func TProxyWriteBack() control.Func {
function GetOriginalDestinationFromOOB (line 20) | func GetOriginalDestinationFromOOB(oob []byte) (netip.AddrPort, error) {
FILE: common/settings/proxy_android.go
type AndroidSystemProxy (line 15) | type AndroidSystemProxy struct
method IsEnabled (line 45) | func (p *AndroidSystemProxy) IsEnabled() bool {
method Enable (line 49) | func (p *AndroidSystemProxy) Enable() error {
method Disable (line 58) | func (p *AndroidSystemProxy) Disable() error {
method runAndroidShell (line 67) | func (p *AndroidSystemProxy) runAndroidShell(name string, args ...stri...
function NewSystemProxy (line 23) | func NewSystemProxy(ctx context.Context, serverAddr M.Socksaddr, support...
FILE: common/settings/proxy_darwin.go
type DarwinSystemProxy (line 18) | type DarwinSystemProxy struct
method IsEnabled (line 41) | func (p *DarwinSystemProxy) IsEnabled() bool {
method Enable (line 45) | func (p *DarwinSystemProxy) Enable() error {
method Disable (line 49) | func (p *DarwinSystemProxy) Disable() error {
method routeUpdate (line 69) | func (p *DarwinSystemProxy) routeUpdate(defaultInterface *control.Inte...
method update0 (line 76) | func (p *DarwinSystemProxy) update0() error {
function NewSystemProxy (line 27) | func NewSystemProxy(ctx context.Context, serverAddr M.Socksaddr, support...
function getInterfaceDisplayName (line 107) | func getInterfaceDisplayName(name string) (string, error) {
FILE: common/settings/proxy_linux.go
type LinuxSystemProxy (line 18) | type LinuxSystemProxy struct
method IsEnabled (line 56) | func (p *LinuxSystemProxy) IsEnabled() bool {
method Enable (line 60) | func (p *LinuxSystemProxy) Enable() error {
method Disable (line 109) | func (p *LinuxSystemProxy) Disable() error {
method runAsUser (line 130) | func (p *LinuxSystemProxy) runAsUser(name string, args ...string) error {
method setGnomeProxy (line 140) | func (p *LinuxSystemProxy) setGnomeProxy(proxyTypes ...string) error {
method setKDEProxy (line 154) | func (p *LinuxSystemProxy) setKDEProxy(proxyTypes ...string) error {
function NewSystemProxy (line 27) | func NewSystemProxy(ctx context.Context, serverAddr M.Socksaddr, support...
FILE: common/settings/proxy_stub.go
function NewSystemProxy (line 12) | func NewSystemProxy(ctx context.Context, serverAddr M.Socksaddr, support...
FILE: common/settings/proxy_windows.go
type WindowsSystemProxy (line 10) | type WindowsSystemProxy struct
method IsEnabled (line 23) | func (p *WindowsSystemProxy) IsEnabled() bool {
method Enable (line 27) | func (p *WindowsSystemProxy) Enable() error {
method Disable (line 36) | func (p *WindowsSystemProxy) Disable() error {
function NewSystemProxy (line 16) | func NewSystemProxy(ctx context.Context, serverAddr M.Socksaddr, support...
FILE: common/settings/system_proxy.go
type SystemProxy (line 3) | type SystemProxy interface
FILE: common/settings/wifi.go
type WIFIMonitor (line 5) | type WIFIMonitor interface
FILE: common/settings/wifi_linux.go
type LinuxWIFIMonitor (line 8) | type LinuxWIFIMonitor struct
method ReadWIFIState (line 30) | func (m *LinuxWIFIMonitor) ReadWIFIState() adapter.WIFIState {
method Start (line 34) | func (m *LinuxWIFIMonitor) Start() error {
method Close (line 41) | func (m *LinuxWIFIMonitor) Close() error {
function NewWIFIMonitor (line 12) | func NewWIFIMonitor(callback func(adapter.WIFIState)) (WIFIMonitor, erro...
FILE: common/settings/wifi_linux_connman.go
type connmanMonitor (line 15) | type connmanMonitor struct
method ReadWIFIState (line 38) | func (m *connmanMonitor) ReadWIFIState() adapter.WIFIState {
method Start (line 105) | func (m *connmanMonitor) Start() error {
method monitorSignals (line 130) | func (m *connmanMonitor) monitorSignals(ctx context.Context, signalCha...
method Close (line 152) | func (m *connmanMonitor) Close() error {
function newConnManMonitor (line 22) | func newConnManMonitor(callback func(adapter.WIFIState)) (WIFIMonitor, e...
FILE: common/settings/wifi_linux_iwd.go
type iwdMonitor (line 15) | type iwdMonitor struct
method ReadWIFIState (line 38) | func (m *iwdMonitor) ReadWIFIState() adapter.WIFIState {
method Start (line 129) | func (m *iwdMonitor) Start() error {
method monitorSignals (line 154) | func (m *iwdMonitor) monitorSignals(ctx context.Context, signalChan ch...
method Close (line 174) | func (m *iwdMonitor) Close() error {
function newIWDMonitor (line 22) | func newIWDMonitor(callback func(adapter.WIFIState)) (WIFIMonitor, error) {
FILE: common/settings/wifi_linux_nm.go
type networkManagerMonitor (line 15) | type networkManagerMonitor struct
method ReadWIFIState (line 39) | func (m *networkManagerMonitor) ReadWIFIState() adapter.WIFIState {
method Start (line 104) | func (m *networkManagerMonitor) Start() error {
method monitorSignals (line 129) | func (m *networkManagerMonitor) monitorSignals(ctx context.Context, si...
method Close (line 149) | func (m *networkManagerMonitor) Close() error {
function newNetworkManagerMonitor (line 22) | func newNetworkManagerMonitor(callback func(adapter.WIFIState)) (WIFIMon...
FILE: common/settings/wifi_linux_wpa.go
type wpaSupplicantMonitor (line 20) | type wpaSupplicantMonitor struct
method ReadWIFIState (line 54) | func (m *wpaSupplicantMonitor) ReadWIFIState() adapter.WIFIState {
method sendCommand (line 99) | func (m *wpaSupplicantMonitor) sendCommand(conn *net.UnixConn, command...
method Start (line 119) | func (m *wpaSupplicantMonitor) Start() error {
method monitorEvents (line 133) | func (m *wpaSupplicantMonitor) monitorEvents(ctx context.Context, last...
method Close (line 215) | func (m *wpaSupplicantMonitor) Close() error {
function newWpaSupplicantMonitor (line 28) | func newWpaSupplicantMonitor(callback func(adapter.WIFIState)) (WIFIMoni...
FILE: common/settings/wifi_stub.go
type stubWIFIMonitor (line 11) | type stubWIFIMonitor struct
method ReadWIFIState (line 17) | func (m *stubWIFIMonitor) ReadWIFIState() adapter.WIFIState {
method Start (line 21) | func (m *stubWIFIMonitor) Start() error {
method Close (line 25) | func (m *stubWIFIMonitor) Close() error {
function NewWIFIMonitor (line 13) | func NewWIFIMonitor(callback func(adapter.WIFIState)) (WIFIMonitor, erro...
FILE: common/settings/wifi_windows.go
type windowsWIFIMonitor (line 18) | type windowsWIFIMonitor struct
method ReadWIFIState (line 48) | func (m *windowsWIFIMonitor) ReadWIFIState() adapter.WIFIState {
method Start (line 87) | func (m *windowsWIFIMonitor) Start() error {
method checkAndNotify (line 125) | func (m *windowsWIFIMonitor) checkAndNotify() {
method Close (line 138) | func (m *windowsWIFIMonitor) Close() error {
function NewWIFIMonitor (line 26) | func NewWIFIMonitor(callback func(adapter.WIFIState)) (WIFIMonitor, erro...
function formatBSSID (line 82) | func formatBSSID(mac winwlanapi.Dot11MacAddress) string {
FILE: common/sniff/bittorrent.go
constant trackerConnectFlag (line 16) | trackerConnectFlag = 0
constant trackerProtocolID (line 17) | trackerProtocolID = 0x41727101980
constant trackerConnectMinSize (line 18) | trackerConnectMinSize = 16
function BitTorrent (line 23) | func BitTorrent(_ context.Context, metadata *adapter.InboundContext, rea...
function UTP (line 56) | func UTP(_ context.Context, metadata *adapter.InboundContext, packet []b...
function UDPTracker (line 95) | func UDPTracker(_ context.Context, metadata *adapter.InboundContext, pac...
FILE: common/sniff/bittorrent_test.go
function TestSniffBittorrent (line 16) | func TestSniffBittorrent(t *testing.T) {
function TestSniffIncompleteBittorrent (line 35) | func TestSniffIncompleteBittorrent(t *testing.T) {
function TestSniffNotBittorrent (line 45) | func TestSniffNotBittorrent(t *testing.T) {
function TestSniffUTP (line 56) | func TestSniffUTP(t *testing.T) {
function TestSniffUDPTracker (line 76) | func TestSniffUDPTracker(t *testing.T) {
function TestSniffNotUTP (line 96) | func TestSniffNotUTP(t *testing.T) {
FILE: common/sniff/dns.go
function StreamDomainNameQuery (line 17) | func StreamDomainNameQuery(readCtx context.Context, metadata *adapter.In...
function DomainNameQuery (line 49) | func DomainNameQuery(ctx context.Context, metadata *adapter.InboundConte...
FILE: common/sniff/dns_test.go
function TestSniffDNS (line 16) | func TestSniffDNS(t *testing.T) {
function TestSniffStreamDNS (line 26) | func TestSniffStreamDNS(t *testing.T) {
function TestSniffIncompleteStreamDNS (line 36) | func TestSniffIncompleteStreamDNS(t *testing.T) {
function TestSniffNotStreamDNS (line 45) | func TestSniffNotStreamDNS(t *testing.T) {
FILE: common/sniff/dtls.go
function DTLSRecord (line 11) | func DTLSRecord(ctx context.Context, metadata *adapter.InboundContext, p...
FILE: common/sniff/dtls_test.go
function TestSniffDTLSClientHello (line 15) | func TestSniffDTLSClientHello(t *testing.T) {
function TestSniffDTLSClientApplicationData (line 25) | func TestSniffDTLSClientApplicationData(t *testing.T) {
FILE: common/sniff/http.go
function HTTPHost (line 16) | func HTTPHost(_ context.Context, metadata *adapter.InboundContext, reade...
FILE: common/sniff/http_test.go
function TestSniffHTTP1 (line 14) | func TestSniffHTTP1(t *testing.T) {
function TestSniffHTTP1WithPort (line 23) | func TestSniffHTTP1WithPort(t *testing.T) {
FILE: common/sniff/internal/qtls/qtls.go
constant VersionDraft29 (line 14) | VersionDraft29 = 0xff00001d
constant Version1 (line 15) | Version1 = 0x1
constant Version2 (line 16) | Version2 = 0x6b3343cf
constant HKDFLabelKeyV1 (line 26) | HKDFLabelKeyV1 = "quic key"
constant HKDFLabelKeyV2 (line 27) | HKDFLabelKeyV2 = "quicv2 key"
constant HKDFLabelIVV1 (line 28) | HKDFLabelIVV1 = "quic iv"
constant HKDFLabelIVV2 (line 29) | HKDFLabelIVV2 = "quicv2 iv"
constant HKDFLabelHeaderProtectionV1 (line 30) | HKDFLabelHeaderProtectionV1 = "quic hp"
constant HKDFLabelHeaderProtectionV2 (line 31) | HKDFLabelHeaderProtectionV2 = "quicv2 hp"
function AEADAESGCMTLS13 (line 34) | func AEADAESGCMTLS13(key, nonceMask []byte) cipher.AEAD {
type xorNonceAEAD (line 52) | type xorNonceAEAD struct
method NonceSize (line 57) | func (f *xorNonceAEAD) NonceSize() int { return 8 }
method Overhead (line 58) | func (f *xorNonceAEAD) Overhead() int { return f.aead.Overhead...
method explicitNonceLen (line 59) | func (f *xorNonceAEAD) explicitNonceLen() int { return 0 }
method Seal (line 61) | func (f *xorNonceAEAD) Seal(out, nonce, plaintext, additionalData []by...
method Open (line 73) | func (f *xorNonceAEAD) Open(out, nonce, ciphertext, additionalData []b...
function HKDFExpandLabel (line 85) | func HKDFExpandLabel(hash crypto.Hash, secret, context []byte, label str...
function ReadUvarint (line 102) | func ReadUvarint(r io.ByteReader) (uint64, error) {
FILE: common/sniff/ntp.go
function NTP (line 12) | func NTP(ctx context.Context, metadata *adapter.InboundContext, packet [...
FILE: common/sniff/ntp_test.go
function TestSniffNTP (line 16) | func TestSniffNTP(t *testing.T) {
function TestSniffNTPFailed (line 26) | func TestSniffNTPFailed(t *testing.T) {
FILE: common/sniff/quic.go
function QUICClientHello (line 23) | func QUICClientHello(ctx context.Context, metadata *adapter.InboundConte...
function isZero (line 350) | func isZero(slices []uint8) bool {
function count (line 359) | func count(slices []uint8, value uint8) int {
type qCryptoFragment (line 369) | type qCryptoFragment struct
FILE: common/sniff/quic_blacklist.go
constant x25519Kyber768Draft00 (line 9) | x25519Kyber768Draft00 uint16 = 0x11EC
constant extensionRenegotiationInfo (line 11) | extensionRenegotiationInfo uint16 = 0xFF01
function isQUICGo (line 17) | func isQUICGo(fingerprint *ja3.ClientHello) bool {
FILE: common/sniff/quic_capture_test.go
function TestSniffQUICQuicGoFingerprint (line 19) | func TestSniffQUICQuicGoFingerprint(t *testing.T) {
function TestSniffQUICInitialFromQuicGo (line 88) | func TestSniffQUICInitialFromQuicGo(t *testing.T) {
FILE: common/sniff/quic_test.go
function TestSniffQUICChromeNew (line 15) | func TestSniffQUICChromeNew(t *testing.T) {
function TestSniffQUICChromium (line 35) | func TestSniffQUICChromium(t *testing.T) {
function TestSniffUQUICChrome115 (line 51) | func TestSniffUQUICChrome115(t *testing.T) {
function TestSniffQUICFirefox (line 63) | func TestSniffQUICFirefox(t *testing.T) {
function TestSniffQUICSafari (line 75) | func TestSniffQUICSafari(t *testing.T) {
function FuzzSniffQUIC (line 87) | func FuzzSniffQUIC(f *testing.F) {
FILE: common/sniff/rdp.go
function RDP (line 15) | func RDP(_ context.Context, metadata *adapter.InboundContext, reader io....
FILE: common/sniff/rdp_test.go
function TestSniffRDP (line 16) | func TestSniffRDP(t *testing.T) {
FILE: common/sniff/sniff.go
function Skip (line 25) | func Skip(metadata *adapter.InboundContext) bool {
function PeekStream (line 41) | func PeekStream(ctx context.Context, metadata *adapter.InboundContext, c...
function PeekPacket (line 78) | func PeekPacket(ctx context.Context, metadata *adapter.InboundContext, p...
FILE: common/sniff/ssh.go
function SSH (line 14) | func SSH(_ context.Context, metadata *adapter.InboundContext, reader io....
FILE: common/sniff/ssh_test.go
function TestSniffSSH (line 16) | func TestSniffSSH(t *testing.T) {
function TestSniffIncompleteSSH (line 28) | func TestSniffIncompleteSSH(t *testing.T) {
function TestSniffNotSSH (line 38) | func TestSniffNotSSH(t *testing.T) {
FILE: common/sniff/stun.go
function STUNMessage (line 12) | func STUNMessage(_ context.Context, metadata *adapter.InboundContext, pa...
FILE: common/sniff/stun_test.go
function TestSniffSTUN (line 15) | func TestSniffSTUN(t *testing.T) {
function FuzzSniffSTUN (line 25) | func FuzzSniffSTUN(f *testing.F) {
FILE: common/sniff/tls.go
function TLSClientHello (line 15) | func TLSClientHello(ctx context.Context, metadata *adapter.InboundContex...
FILE: common/srs/binary.go
constant ruleItemQueryType (line 26) | ruleItemQueryType uint8 = iota
constant ruleItemNetwork (line 27) | ruleItemNetwork
constant ruleItemDomain (line 28) | ruleItemDomain
constant ruleItemDomainKeyword (line 29) | ruleItemDomainKeyword
constant ruleItemDomainRegex (line 30) | ruleItemDomainRegex
constant ruleItemSourceIPCIDR (line 31) | ruleItemSourceIPCIDR
constant ruleItemIPCIDR (line 32) | ruleItemIPCIDR
constant ruleItemSourcePort (line 33) | ruleItemSourcePort
constant ruleItemSourcePortRange (line 34) | ruleItemSourcePortRange
constant ruleItemPort (line 35) | ruleItemPort
constant ruleItemPortRange (line 36) | ruleItemPortRange
constant ruleItemProcessName (line 37) | ruleItemProcessName
constant ruleItemProcessPath (line 38) | ruleItemProcessPath
constant ruleItemPackageName (line 39) | ruleItemPackageName
constant ruleItemWIFISSID (line 40) | ruleItemWIFISSID
constant ruleItemWIFIBSSID (line 41) | ruleItemWIFIBSSID
constant ruleItemAdGuardDomain (line 42) | ruleItemAdGuardDomain
constant ruleItemProcessPathRegex (line 43) | ruleItemProcessPathRegex
constant ruleItemNetworkType (line 44) | ruleItemNetworkType
constant ruleItemNetworkIsExpensive (line 45) | ruleItemNetworkIsExpensive
constant ruleItemNetworkIsConstrained (line 46) | ruleItemNetworkIsConstrained
constant ruleItemNetworkInterfaceAddress (line 47) | ruleItemNetworkInterfaceAddress
constant ruleItemDefaultInterfaceAddress (line 48) | ruleItemDefaultInterfaceAddress
constant ruleItemFinal (line 49) | ruleItemFinal uint8 = 0xFF
function Read (line 52) | func Read(reader io.Reader, recover bool) (ruleSetCompat option.PlainRul...
function Write (line 91) | func Write(writer io.Writer, ruleSet option.PlainRuleSet, generateVersio...
function readRule (line 122) | func readRule(reader varbin.Reader, recover bool) (rule option.HeadlessR...
function writeRule (line 141) | func writeRule(writer varbin.Writer, rule option.HeadlessRule, generateV...
function readDefaultRule (line 152) | func readDefaultRule(reader varbin.Reader, recover bool) (rule option.De...
function writeDefaultRule (line 296) | func writeDefaultRule(writer varbin.Writer, rule option.DefaultHeadlessR...
function readRuleItemString (line 508) | func readRuleItemString(reader varbin.Reader) ([]string, error) {
function writeRuleItemString (line 529) | func writeRuleItemString(writer varbin.Writer, itemType uint8, value []s...
function readRuleItemUint8 (line 551) | func readRuleItemUint8[E ~uint8](reader varbin.Reader) ([]E, error) {
function writeRuleItemUint8 (line 564) | func writeRuleItemUint8[E ~uint8](writer varbin.Writer, itemType uint8, ...
function readRuleItemUint16 (line 577) | func readRuleItemUint16(reader varbin.Reader) ([]uint16, error) {
function writeRuleItemUint16 (line 590) | func writeRuleItemUint16(writer varbin.Writer, itemType uint8, value []u...
function writeRuleItemCIDR (line 602) | func writeRuleItemCIDR(writer varbin.Writer, itemType uint8, value []str...
function readLogicalRule (line 628) | func readLogicalRule(reader varbin.Reader, recovery bool) (logicalRule o...
function writeLogicalRule (line 661) | func writeLogicalRule(writer varbin.Writer, logicalRule option.LogicalHe...
FILE: common/srs/compat_test.go
function oldWriteStringSlice (line 21) | func oldWriteStringSlice(writer varbin.Writer, value []string) error {
function oldReadStringSlice (line 26) | func oldReadStringSlice(reader varbin.Reader) ([]string, error) {
function oldWriteUint8Slice (line 31) | func oldWriteUint8Slice[E ~uint8](writer varbin.Writer, value []E) error {
function oldReadUint8Slice (line 36) | func oldReadUint8Slice[E ~uint8](reader varbin.Reader) ([]E, error) {
function oldWriteUint16Slice (line 41) | func oldWriteUint16Slice(writer varbin.Writer, value []uint16) error {
function oldReadUint16Slice (line 46) | func oldReadUint16Slice(reader varbin.Reader) ([]uint16, error) {
function oldWritePrefix (line 51) | func oldWritePrefix(writer varbin.Writer, prefix netip.Prefix) error {
type oldIPRangeData (line 60) | type oldIPRangeData struct
function oldReadIPSet (line 78) | func oldReadIPSet(reader varbin.Reader) (*netipx.IPSet, error) {
function newWriteStringSlice (line 109) | func newWriteStringSlice(writer varbin.Writer, value []string) error {
function newWriteUint8Slice (line 127) | func newWriteUint8Slice[E ~uint8](writer varbin.Writer, value []E) error {
function newWriteUint16Slice (line 136) | func newWriteUint16Slice(writer varbin.Writer, value []uint16) error {
function newWritePrefix (line 144) | func newWritePrefix(writer varbin.Writer, prefix netip.Prefix) error {
function TestStringSliceCompat (line 159) | func TestStringSliceCompat(t *testing.T) {
function TestUint8SliceCompat (line 212) | func TestUint8SliceCompat(t *testing.T) {
function TestUint16SliceCompat (line 261) | func TestUint16SliceCompat(t *testing.T) {
function TestPrefixCompat (line 310) | func TestPrefixCompat(t *testing.T) {
function TestIPSetCompat (line 361) | func TestIPSetCompat(t *testing.T) {
function generateStrings (line 409) | func generateStrings(count int) []string {
function generateUint8Slice (line 417) | func generateUint8Slice(count int) []uint8 {
function generateUint16Slice (line 425) | func generateUint16Slice(count int) []uint16 {
function buildIPSet (line 433) | func buildIPSet(cidrs ...string) *netipx.IPSet {
function buildLargeIPSet (line 451) | func buildLargeIPSet(count int) *netipx.IPSet {
function requireStringSliceEqual (line 461) | func requireStringSliceEqual(t *testing.T, expected, actual []string) {
function requireUint8SliceEqual (line 469) | func requireUint8SliceEqual(t *testing.T, expected, actual []uint8) {
function requireUint16SliceEqual (line 477) | func requireUint16SliceEqual(t *testing.T, expected, actual []uint16) {
function requireIPSetEqual (line 485) | func requireIPSetEqual(t *testing.T, expected, actual *netipx.IPSet) {
FILE: common/srs/ip_cidr.go
function readPrefix (line 12) | func readPrefix(reader varbin.Reader) (netip.Prefix, error) {
function writePrefix (line 29) | func writePrefix(writer varbin.Writer, prefix netip.Prefix) error {
FILE: common/srs/ip_set.go
type myIPSet (line 16) | type myIPSet struct
type myIPRange (line 20) | type myIPRange struct
function readIPSet (line 25) | func readIPSet(reader varbin.Reader) (*netipx.IPSet, error) {
function writeIPSet (line 67) | func writeIPSet(writer varbin.Writer, set *netipx.IPSet) error {
FILE: common/taskmonitor/monitor.go
type Monitor (line 10) | type Monitor struct
method Start (line 23) | func (m *Monitor) Start(taskName ...any) {
method Finish (line 29) | func (m *Monitor) Finish() {
function New (line 16) | func New(logger logger.Logger, timeout time.Duration) *Monitor {
FILE: common/tls/acme.go
type acmeWrapper (line 25) | type acmeWrapper struct
method Start (line 32) | func (w *acmeWrapper) Start() error {
method Close (line 36) | func (w *acmeWrapper) Close() error {
type acmeLogWriter (line 41) | type acmeLogWriter struct
method Write (line 45) | func (w *acmeLogWriter) Write(p []byte) (n int, err error) {
method Sync (line 62) | func (w *acmeLogWriter) Sync() error {
function encoderConfig (line 66) | func encoderConfig() zapcore.EncoderConfig {
function startACME (line 72) | func startACME(ctx context.Context, logger logger.Logger, options option...
FILE: common/tls/acme_contstant.go
constant ACMETLS1Protocol (line 3) | ACMETLS1Protocol = "acme-tls/1"
FILE: common/tls/acme_stub.go
function startACME (line 15) | func startACME(ctx context.Context, logger logger.Logger, options option...
FILE: common/tls/client.go
function NewDialerFromOptions (line 19) | func NewDialerFromOptions(ctx context.Context, logger logger.ContextLogg...
function NewClient (line 35) | func NewClient(ctx context.Context, logger logger.ContextLogger, serverA...
type ClientOptions (line 44) | type ClientOptions struct
function NewClientWithOptions (line 52) | func NewClientWithOptions(options ClientOptions) (Config, error) {
function ClientHandshake (line 72) | func ClientHandshake(ctx context.Context, conn net.Conn, config Config) ...
type Dialer (line 88) | type Dialer interface
type defaultDialer (line 93) | type defaultDialer struct
method DialContext (line 102) | func (d *defaultDialer) DialContext(ctx context.Context, network strin...
method ListenPacket (line 109) | func (d *defaultDialer) ListenPacket(ctx context.Context, destination ...
method DialTLSContext (line 113) | func (d *defaultDialer) DialTLSContext(ctx context.Context, destinatio...
method dialContext (line 117) | func (d *defaultDialer) dialContext(ctx context.Context, destination M...
method Upstream (line 137) | func (d *defaultDialer) Upstream() any {
function NewDialer (line 98) | func NewDialer(dialer N.Dialer, config Config) Dialer {
FILE: common/tls/common.go
constant VersionTLS10 (line 4) | VersionTLS10 = 0x0301
constant VersionTLS11 (line 5) | VersionTLS11 = 0x0302
constant VersionTLS12 (line 6) | VersionTLS12 = 0x0303
constant VersionTLS13 (line 7) | VersionTLS13 = 0x0304
constant VersionSSL30 (line 11) | VersionSSL30 = 0x0300
FILE: common/tls/config.go
function ParseTLSVersion (line 24) | func ParseTLSVersion(version string) (uint16, error) {
FILE: common/tls/ech.go
function parseECHClientConfig (line 27) | func parseECHClientConfig(ctx context.Context, clientConfig ECHCapableCo...
function parseECHServerConfig (line 58) | func parseECHServerConfig(ctx context.Context, options option.InboundTLS...
method setECHServerConfig (line 84) | func (c *STDServerConfig) setECHServerConfig(echKey []byte) error {
function parseECHKeys (line 97) | func parseECHKeys(echKey []byte) ([]tls.EncryptedClientHelloKey, error) {
type ECHClientConfig (line 109) | type ECHClientConfig struct
method ClientHandshake (line 118) | func (s *ECHClientConfig) ClientHandshake(ctx context.Context, conn ne...
method fetchAndHandshake (line 130) | func (s *ECHClientConfig) fetchAndHandshake(ctx context.Context, conn ...
method Clone (line 182) | func (s *ECHClientConfig) Clone() Config {
function UnmarshalECHKeys (line 191) | func UnmarshalECHKeys(raw []byte) ([]tls.EncryptedClientHelloKey, error) {
FILE: common/tls/ech_shared.go
type ECHCapableConfig (line 11) | type ECHCapableConfig interface
function ECHKeygenDefault (line 17) | func ECHKeygenDefault(publicName string) (configPem string, keyPem strin...
function marshalECHConfig (line 50) | func marshalECHConfig(id uint8, pubKey []byte, publicName string, maxNam...
FILE: common/tls/ktls.go
type KTLSClientConfig (line 13) | type KTLSClientConfig struct
method ClientHandshake (line 19) | func (w *KTLSClientConfig) ClientHandshake(ctx context.Context, conn n...
method Clone (line 32) | func (w *KTLSClientConfig) Clone() Config {
type KTlSServerConfig (line 41) | type KTlSServerConfig struct
method ServerHandshake (line 47) | func (w *KTlSServerConfig) ServerHandshake(ctx context.Context, conn n...
method Clone (line 60) | func (w *KTlSServerConfig) Clone() Config {
FILE: common/tls/mkcert.go
function GenerateKeyPair (line 14) | func GenerateKeyPair(parent *x509.Certificate, parentKey any, timeFunc f...
function GenerateCertificate (line 29) | func GenerateCertificate(parent *x509.Certificate, parentKey any, timeFu...
FILE: common/tls/reality_client.go
type RealityClientConfig (line 47) | type RealityClientConfig struct
method ServerName (line 95) | func (e *RealityClientConfig) ServerName() string {
method SetServerName (line 99) | func (e *RealityClientConfig) SetServerName(serverName string) {
method NextProtos (line 103) | func (e *RealityClientConfig) NextProtos() []string {
method SetNextProtos (line 107) | func (e *RealityClientConfig) SetNextProtos(nextProto []string) {
method STDConfig (line 111) | func (e *RealityClientConfig) STDConfig() (*STDConfig, error) {
method Client (line 115) | func (e *RealityClientConfig) Client(conn net.Conn) (Conn, error) {
method ClientHandshake (line 119) | func (e *RealityClientConfig) ClientHandshake(ctx context.Context, con...
method Clone (line 253) | func (e *RealityClientConfig) Clone() Config {
function NewRealityClient (line 54) | func NewRealityClient(ctx context.Context, logger logger.ContextLogger, ...
function realityClientFallback (line 229) | func realityClientFallback(ctx context.Context, uConn net.Conn, serverNa...
type realityVerifier (line 262) | type realityVerifier struct
method VerifyPeerCertificate (line 269) | func (c *realityVerifier) VerifyPeerCertificate(rawCerts [][]byte, ver...
type realityClientConnWrapper (line 293) | type realityClientConnWrapper struct
method ConnectionState (line 297) | func (c *realityClientConnWrapper) ConnectionState() tls.ConnectionSta...
method Upstream (line 316) | func (c *realityClientConnWrapper) Upstream() any {
method CloseWrite (line 322) | func (c *realityClientConnWrapper) CloseWrite() error {
method ReaderReplaceable (line 326) | func (c *realityClientConnWrapper) ReaderReplaceable() bool {
method WriterReplaceable (line 330) | func (c *realityClientConnWrapper) WriterReplaceable() bool {
FILE: common/tls/reality_server.go
type RealityServerConfig (line 28) | type RealityServerConfig struct
method ServerName (line 144) | func (c *RealityServerConfig) ServerName() string {
method SetServerName (line 148) | func (c *RealityServerConfig) SetServerName(serverName string) {
method NextProtos (line 152) | func (c *RealityServerConfig) NextProtos() []string {
method SetNextProtos (line 156) | func (c *RealityServerConfig) SetNextProtos(nextProto []string) {
method STDConfig (line 160) | func (c *RealityServerConfig) STDConfig() (*tls.Config, error) {
method Client (line 164) | func (c *RealityServerConfig) Client(conn net.Conn) (Conn, error) {
method Start (line 168) | func (c *RealityServerConfig) Start() error {
method Close (line 172) | func (c *RealityServerConfig) Close() error {
method Server (line 176) | func (c *RealityServerConfig) Server(conn net.Conn) (Conn, error) {
method ServerHandshake (line 180) | func (c *RealityServerConfig) ServerHandshake(ctx context.Context, con...
method Clone (line 188) | func (c *RealityServerConfig) Clone() Config {
function NewRealityServer (line 32) | func NewRealityServer(ctx context.Context, logger log.ContextLogger, opt...
type realityConnWrapper (line 196) | type realityConnWrapper struct
method ConnectionState (line 200) | func (c *realityConnWrapper) ConnectionState() ConnectionState {
method Upstream (line 219) | func (c *realityConnWrapper) Upstream() any {
method CloseWrite (line 225) | func (c *realityConnWrapper) CloseWrite() error {
method ReaderReplaceable (line 229) | func (c *realityConnWrapper) ReaderReplaceable() bool {
method WriterReplaceable (line 233) | func (c *realityConnWrapper) WriterReplaceable() bool {
FILE: common/tls/server.go
type ServerOptions (line 15) | type ServerOptions struct
function NewServer (line 22) | func NewServer(ctx context.Context, logger log.ContextLogger, options op...
function NewServerWithOptions (line 30) | func NewServerWithOptions(options ServerOptions) (ServerConfig, error) {
function ServerHandshake (line 48) | func ServerHandshake(ctx context.Context, conn net.Conn, config ServerCo...
FILE: common/tls/std_client.go
type STDClientConfig (line 24) | type STDClientConfig struct
method ServerName (line 32) | func (c *STDClientConfig) ServerName() string {
method SetServerName (line 36) | func (c *STDClientConfig) SetServerName(serverName string) {
method NextProtos (line 40) | func (c *STDClientConfig) NextProtos() []string {
method SetNextProtos (line 44) | func (c *STDClientConfig) SetNextProtos(nextProto []string) {
method STDConfig (line 48) | func (c *STDClientConfig) STDConfig() (*STDConfig, error) {
method Client (line 52) | func (c *STDClientConfig) Client(conn net.Conn) (Conn, error) {
method Clone (line 59) | func (c *STDClientConfig) Clone() Config {
method ECHConfigList (line 69) | func (c *STDClientConfig) ECHConfigList() []byte {
method SetECHConfigList (line 73) | func (c *STDClientConfig) SetECHConfigList(EncryptedClientHelloConfigL...
function NewSTDClient (line 77) | func NewSTDClient(ctx context.Context, logger logger.ContextLogger, serv...
function verifyPublicKeySHA256 (line 223) | func verifyPublicKeySHA256(knownHashValues [][]byte, rawCerts [][]byte, ...
FILE: common/tls/std_server.go
type STDServerConfig (line 25) | type STDServerConfig struct
method ServerName (line 39) | func (c *STDServerConfig) ServerName() string {
method SetServerName (line 45) | func (c *STDServerConfig) SetServerName(serverName string) {
method NextProtos (line 53) | func (c *STDServerConfig) NextProtos() []string {
method SetNextProtos (line 63) | func (c *STDServerConfig) SetNextProtos(nextProto []string) {
method STDConfig (line 75) | func (c *STDServerConfig) STDConfig() (*STDConfig, error) {
method Client (line 79) | func (c *STDServerConfig) Client(conn net.Conn) (Conn, error) {
method Server (line 83) | func (c *STDServerConfig) Server(conn net.Conn) (Conn, error) {
method Clone (line 87) | func (c *STDServerConfig) Clone() Config {
method Start (line 93) | func (c *STDServerConfig) Start() error {
method startWatcher (line 105) | func (c *STDServerConfig) startWatcher() error {
method certificateUpdated (line 142) | func (c *STDServerConfig) certificateUpdated(path string) error {
method Close (line 205) | func (c *STDServerConfig) Close() error {
function NewSTDServer (line 215) | func NewSTDServer(ctx context.Context, logger log.ContextLogger, options...
FILE: common/tls/time_wrapper.go
type TimeServiceWrapper (line 9) | type TimeServiceWrapper struct
method TimeFunc (line 13) | func (w *TimeServiceWrapper) TimeFunc() func() time.Time {
method Upstream (line 23) | func (w *TimeServiceWrapper) Upstream() any {
FILE: common/tls/utls_client.go
type UTLSClientConfig (line 28) | type UTLSClientConfig struct
method ServerName (line 37) | func (c *UTLSClientConfig) ServerName() string {
method SetServerName (line 41) | func (c *UTLSClientConfig) SetServerName(serverName string) {
method NextProtos (line 45) | func (c *UTLSClientConfig) NextProtos() []string {
method SetNextProtos (line 49) | func (c *UTLSClientConfig) SetNextProtos(nextProto []string) {
method STDConfig (line 56) | func (c *UTLSClientConfig) STDConfig() (*STDConfig, error) {
method Client (line 60) | func (c *UTLSClientConfig) Client(conn net.Conn) (Conn, error) {
method SetSessionIDGenerator (line 67) | func (c *UTLSClientConfig) SetSessionIDGenerator(generator func(client...
method Clone (line 71) | func (c *UTLSClientConfig) Clone() Config {
method ECHConfigList (line 77) | func (c *UTLSClientConfig) ECHConfigList() []byte {
method SetECHConfigList (line 81) | func (c *UTLSClientConfig) SetECHConfigList(EncryptedClientHelloConfig...
type utlsConnWrapper (line 85) | type utlsConnWrapper struct
method ConnectionState (line 89) | func (c *utlsConnWrapper) ConnectionState() tls.ConnectionState {
method Upstream (line 108) | func (c *utlsConnWrapper) Upstream() any {
method ReaderReplaceable (line 112) | func (c *utlsConnWrapper) ReaderReplaceable() bool {
method WriterReplaceable (line 116) | func (c *utlsConnWrapper) WriterReplaceable() bool {
type utlsALPNWrapper (line 120) | type utlsALPNWrapper struct
method HandshakeContext (line 125) | func (c *utlsALPNWrapper) HandshakeContext(ctx context.Context) error {
function NewUTLSClient (line 145) | func NewUTLSClient(ctx context.Context, logger logger.ContextLogger, ser...
function init (line 287) | func init() {
function uTLSClientHelloID (line 305) | func uTLSClientHelloID(name string) (utls.ClientHelloID, error) {
FILE: common/tls/utls_stub.go
function NewUTLSClient (line 14) | func NewUTLSClient(ctx context.Context, logger logger.ContextLogger, ser...
function NewRealityClient (line 18) | func NewRealityClient(ctx context.Context, logger logger.ContextLogger, ...
function NewRealityServer (line 22) | func NewRealityServer(ctx context.Context, logger log.Logger, options op...
FILE: common/tlsfragment/conn.go
type Conn (line 18) | type Conn struct
method Write (line 43) | func (c *Conn) Write(b []byte) (n int, err error) {
method ReaderReplaceable (line 136) | func (c *Conn) ReaderReplaceable() bool {
method WriterReplaceable (line 140) | func (c *Conn) WriterReplaceable() bool {
method Upstream (line 144) | func (c *Conn) Upstream() any {
function NewConn (line 28) | func NewConn(conn net.Conn, ctx context.Context, splitPacket bool, split...
FILE: common/tlsfragment/conn_test.go
function TestTLSFragment (line 14) | func TestTLSFragment(t *testing.T) {
function TestTLSRecordFragment (line 24) | func TestTLSRecordFragment(t *testing.T) {
function TestTLS2Fragment (line 34) | func TestTLS2Fragment(t *testing.T) {
FILE: common/tlsfragment/index.go
constant recordLayerHeaderLen (line 8) | recordLayerHeaderLen int = 5
constant handshakeHeaderLen (line 9) | handshakeHeaderLen int = 6
constant randomDataLen (line 10) | randomDataLen int = 32
constant sessionIDHeaderLen (line 11) | sessionIDHeaderLen int = 1
constant cipherSuiteHeaderLen (line 12) | cipherSuiteHeaderLen int = 2
constant compressMethodHeaderLen (line 13) | compressMethodHeaderLen int = 1
constant extensionsHeaderLen (line 14) | extensionsHeaderLen int = 2
constant extensionHeaderLen (line 15) | extensionHeaderLen int = 4
constant sniExtensionHeaderLen (line 16) | sniExtensionHeaderLen int = 5
constant contentType (line 17) | contentType uint8 = 22
constant handshakeType (line 18) | handshakeType uint8 = 1
constant sniExtensionType (line 19) | sniExtensionType uint16 = 0
constant sniNameDNSHostnameType (line 20) | sniNameDNSHostnameType uint8 = 0
constant tlsVersionBitmask (line 21) | tlsVersionBitmask uint16 = 0xFFFC
constant tls13 (line 22) | tls13 uint16 = 0x0304
type MyServerName (line 25) | type MyServerName struct
function IndexTLSServerName (line 31) | func IndexTLSServerName(payload []byte) *MyServerName {
function indexTLSServerNameFromHandshake (line 47) | func indexTLSServerNameFromHandshake(handshake []byte) *MyServerName {
function indexTLSServerNameFromExtensions (line 88) | func indexTLSServerNameFromExtensions(exs []byte) *MyServerName {
FILE: common/tlsfragment/index_test.go
function TestIndexTLSServerName (line 12) | func TestIndexTLSServerName(t *testing.T) {
FILE: common/tlsfragment/wait_darwin.go
function writeAndWaitAck (line 66) | func writeAndWaitAck(ctx context.Context, conn *net.TCPConn, payload []b...
FILE: common/tlsfragment/wait_linux.go
function writeAndWaitAck (line 13) | func writeAndWaitAck(ctx context.Context, conn *net.TCPConn, payload []b...
FILE: common/tlsfragment/wait_stub.go
function writeAndWaitAck (line 11) | func writeAndWaitAck(ctx context.Context, conn *net.TCPConn, payload []b...
FILE: common/tlsfragment/wait_windows.go
function writeAndWaitAck (line 14) | func writeAndWaitAck(ctx context.Context, conn *net.TCPConn, payload []b...
FILE: common/uot/router.go
type Router (line 18) | type Router struct
method RouteConnection (line 27) | func (r *Router) RouteConnection(ctx context.Context, conn net.Conn, m...
method RoutePacketConnection (line 51) | func (r *Router) RoutePacketConnection(ctx context.Context, conn N.Pac...
method RouteConnectionEx (line 55) | func (r *Router) RouteConnectionEx(ctx context.Context, conn net.Conn,...
method RoutePacketConnectionEx (line 84) | func (r *Router) RoutePacketConnectionEx(ctx context.Context, conn N.P...
function NewRouter (line 23) | func NewRouter(router adapter.ConnectionRouterEx, logger logger.ContextL...
FILE: common/urltest/urltest.go
type HistoryStorage (line 22) | type HistoryStorage struct
method SetHook (line 34) | func (s *HistoryStorage) SetHook(hook *observable.Subscriber[struct{}]) {
method LoadURLTestHistory (line 38) | func (s *HistoryStorage) LoadURLTestHistory(tag string) *adapter.URLTe...
method DeleteURLTestHistory (line 47) | func (s *HistoryStorage) DeleteURLTestHistory(tag string) {
method StoreURLTestHistory (line 54) | func (s *HistoryStorage) StoreURLTestHistory(tag string, history *adap...
method notifyUpdated (line 61) | func (s *HistoryStorage) notifyUpdated() {
method Close (line 68) | func (s *HistoryStorage) Close() error {
function NewHistoryStorage (line 28) | func NewHistoryStorage() *HistoryStorage {
function URLTest (line 75) | func URLTest(ctx context.Context, link string, detour N.Dialer) (t uint1...
FILE: constant/certificate.go
constant CertificateStoreSystem (line 4) | CertificateStoreSystem = "system"
constant CertificateStoreMozilla (line 5) | CertificateStoreMozilla = "mozilla"
constant CertificateStoreChrome (line 6) | CertificateStoreChrome = "chrome"
constant CertificateStoreNone (line 7) | CertificateStoreNone = "none"
FILE: constant/cgo.go
constant CGO_ENABLED (line 5) | CGO_ENABLED = true
FILE: constant/cgo_disabled.go
constant CGO_ENABLED (line 5) | CGO_ENABLED = false
FILE: constant/dhcp.go
constant DHCPTTL (line 6) | DHCPTTL = time.Hour
constant DHCPTimeout (line 7) | DHCPTimeout = 5 * time.Second
FILE: constant/dns.go
constant DefaultDNSTTL (line 4) | DefaultDNSTTL = 600
constant DomainStrategyAsIS (line 10) | DomainStrategyAsIS DomainStrategy = iota
constant DomainStrategyPreferIPv4 (line 11) | DomainStrategyPreferIPv4
constant DomainStrategyPreferIPv6 (line 12) | DomainStrategyPreferIPv6
constant DomainStrategyIPv4Only (line 13) | DomainStrategyIPv4Only
constant DomainStrategyIPv6Only (line 14) | DomainStrategyIPv6Only
constant DNSTypeLegacy (line 18) | DNSTypeLegacy = "legacy"
constant DNSTypeLegacyRcode (line 19) | DNSTypeLegacyRcode = "legacy_rcode"
constant DNSTypeUDP (line 20) | DNSTypeUDP = "udp"
constant DNSTypeTCP (line 21) | DNSTypeTCP = "tcp"
constant DNSTypeTLS (line 22) | DNSTypeTLS = "tls"
constant DNSTypeHTTPS (line 23) | DNSTypeHTTPS = "https"
constant DNSTypeQUIC (line 24) | DNSTypeQUIC = "quic"
constant DNSTypeHTTP3 (line 25) | DNSTypeHTTP3 = "h3"
constant DNSTypeLocal (line 26) | DNSTypeLocal = "local"
constant DNSTypeHosts (line 27) | DNSTypeHosts = "hosts"
constant DNSTypeFakeIP (line 28) | DNSTypeFakeIP = "fakeip"
constant DNSTypeDHCP (line 29) | DNSTypeDHCP = "dhcp"
constant DNSTypeTailscale (line 30) | DNSTypeTailscale = "tailscale"
constant DNSProviderAliDNS (line 34) | DNSProviderAliDNS = "alidns"
constant DNSProviderCloudflare (line 35) | DNSProviderCloudflare = "cloudflare"
constant DNSProviderACMEDNS (line 36) | DNSProviderACMEDNS = "acmedns"
FILE: constant/goos/gengoos.go
function main (line 20) | func main() {
FILE: constant/goos/zgoos_aix.go
constant GOOS (line 7) | GOOS = `aix`
constant IsAix (line 9) | IsAix = 1
constant IsAndroid (line 10) | IsAndroid = 0
constant IsDarwin (line 11) | IsDarwin = 0
constant IsDragonfly (line 12) | IsDragonfly = 0
constant IsFreebsd (line 13) | IsFreebsd = 0
constant IsHurd (line 14) | IsHurd = 0
constant IsIllumos (line 15) | IsIllumos = 0
constant IsIos (line 16) | IsIos = 0
constant IsJs (line 17) | IsJs = 0
constant IsLinux (line 18) | IsLinux = 0
constant IsNacl (line 19) | IsNacl = 0
constant IsNetbsd (line 20) | IsNetbsd = 0
constant IsOpenbsd (line 21) | IsOpenbsd = 0
constant IsPlan9 (line 22) | IsPlan9 = 0
constant IsSolaris (line 23) | IsSolaris = 0
constant IsWindows (line 24) | IsWindows = 0
constant IsZos (line 25) | IsZos = 0
FILE: constant/goos/zgoos_android.go
constant GOOS (line 7) | GOOS = `android`
constant IsAix (line 9) | IsAix = 0
constant IsAndroid (line 10) | IsAndroid = 1
constant IsDarwin (line 11) | IsDarwin = 0
constant IsDragonfly (line 12) | IsDragonfly = 0
constant IsFreebsd (line 13) | IsFreebsd = 0
constant IsHurd (line 14) | IsHurd = 0
constant IsIllumos (line 15) | IsIllumos = 0
constant IsIos (line 16) | IsIos = 0
constant IsJs (line 17) | IsJs = 0
constant IsLinux (line 18) | IsLinux = 0
constant IsNacl (line 19) | IsNacl = 0
constant IsNetbsd (line 20) | IsNetbsd = 0
constant IsOpenbsd (line 21) | IsOpenbsd = 0
constant IsPlan9 (line 22) | IsPlan9 = 0
constant IsSolaris (line 23) | IsSolaris = 0
constant IsWindows (line 24) | IsWindows = 0
constant IsZos (line 25) | IsZos = 0
FILE: constant/goos/zgoos_darwin.go
constant GOOS (line 7) | GOOS = `darwin`
constant IsAix (line 9) | IsAix = 0
constant IsAndroid (line 10) | IsAndroid = 0
constant IsDarwin (line 11) | IsDarwin = 1
constant IsDragonfly (line 12) | IsDragonfly = 0
constant IsFreebsd (line 13) | IsFreebsd = 0
constant IsHurd (line 14) | IsHurd = 0
constant IsIllumos (line 15) | IsIllumos = 0
constant IsIos (line 16) | IsIos = 0
constant IsJs (line 17) | IsJs = 0
constant IsLinux (line 18) | IsLinux = 0
constant IsNacl (line 19) | IsNacl = 0
constant IsNetbsd (line 20) | IsNetbsd = 0
constant IsOpenbsd (line 21) | IsOpenbsd = 0
constant IsPlan9 (line 22) | IsPlan9 = 0
constant IsSolaris (line 23) | IsSolaris = 0
constant IsWindows (line 24) | IsWindows = 0
constant IsZos (line 25) | IsZos = 0
FILE: constant/goos/zgoos_dragonfly.go
constant GOOS (line 7) | GOOS = `dragonfly`
constant IsAix (line 9) | IsAix = 0
constant IsAndroid (line 10) | IsAndroid = 0
constant IsDarwin (line 11) | IsDarwin = 0
constant IsDragonfly (line 12) | IsDragonfly = 1
constant IsFreebsd (line 13) | IsFreebsd = 0
constant IsHurd (line 14) | IsHurd = 0
constant IsIllumos (line 15) | IsIllumos = 0
constant IsIos (line 16) | IsIos = 0
constant IsJs (line 17) | IsJs = 0
constant IsLinux (line 18) | IsLinux = 0
constant IsNacl (line 19) | IsNacl = 0
constant IsNetbsd (line 20) | IsNetbsd = 0
constant IsOpenbsd (line 21) | IsOpenbsd = 0
constant IsPlan9 (line 22) | IsPlan9 = 0
constant IsSolaris (line 23) | IsSolaris = 0
constant IsWindows (line 24) | IsWindows = 0
constant IsZos (line 25) | IsZos = 0
FILE: constant/goos/zgoos_freebsd.go
constant GOOS (line 7) | GOOS = `freebsd`
constant IsAix (line 9) | IsAix = 0
constant IsAndroid (line 10) | IsAndroid = 0
constant IsDarwin (line 11) | IsDarwin = 0
constant IsDragonfly (line 12) | IsDragonfly = 0
constant IsFreebsd (line 13) | IsFreebsd = 1
constant IsHurd (line 14) | IsHurd = 0
constant IsIllumos (line 15) | IsIllumos = 0
constant IsIos (line 16) | IsIos = 0
constant IsJs (line 17) | IsJs = 0
constant IsLinux (line 18) | IsLinux = 0
constant IsNacl (line 19) | IsNacl = 0
constant IsNetbsd (line 20) | IsNetbsd = 0
constant IsOpenbsd (line 21) | IsOpenbsd = 0
constant IsPlan9 (line 22) | IsPlan9 = 0
constant IsSolaris (line 23) | IsSolaris = 0
constant IsWindows (line 24) | IsWindows = 0
constant IsZos (line 25) | IsZos = 0
FILE: constant/goos/zgoos_hurd.go
constant GOOS (line 7) | GOOS = `hurd`
constant IsAix (line 9) | IsAix = 0
constant IsAndroid (line 10) | IsAndroid = 0
constant IsDarwin (line 11) | IsDarwin = 0
constant IsDragonfly (line 12) | IsDragonfly = 0
constant IsFreebsd (line 13) | IsFreebsd = 0
constant IsHurd (line 14) | IsHurd = 1
constant IsIllumos (line 15) | IsIllumos = 0
constant IsIos (line 16) | IsIos = 0
constant IsJs (line 17) | IsJs = 0
constant IsLinux (line 18) | IsLinux = 0
constant IsNacl (line 19) | IsNacl = 0
constant IsNetbsd (line 20) | IsNetbsd = 0
constant IsOpenbsd (line 21) | IsOpenbsd = 0
constant IsPlan9 (line 22) | IsPlan9 = 0
constant IsSolaris (line 23) | IsSolaris = 0
constant IsWindows (line 24) | IsWindows = 0
constant IsZos (line 25) | IsZos = 0
FILE: constant/goos/zgoos_illumos.go
constant GOOS (line 7) | GOOS = `illumos`
constant IsAix (line 9) | IsAix = 0
constant IsAndroid (line 10) | IsAndroid = 0
constant IsDarwin (line 11) | IsDarwin = 0
constant IsDragonfly (line 12) | IsDragonfly = 0
constant IsFreebsd (line 13) | IsFreebsd = 0
constant IsHurd (line 14) | IsHurd = 0
constant IsIllumos (line 15) | IsIllumos = 1
constant IsIos (line 16) | IsIos = 0
constant IsJs (line 17) | IsJs = 0
constant IsLinux (line 18) | IsLinux = 0
constant IsNacl (line 19) | IsNacl = 0
constant IsNetbsd (line 20) | IsNetbsd = 0
constant IsOpenbsd (line 21) | IsOpenbsd = 0
constant IsPlan9 (line 22) | IsPlan9 = 0
constant IsSolaris (line 23) | IsSolaris = 0
constant IsWindows (line 24) | IsWindows = 0
constant IsZos (line 25) | IsZos = 0
FILE: constant/goos/zgoos_ios.go
constant GOOS (line 7) | GOOS = `ios`
constant IsAix (line 9) | IsAix = 0
constant IsAndroid (line 10) | IsAndroid = 0
constant IsDarwin (line 11) | IsDarwin = 0
constant IsDragonfly (line 12) | IsDragonfly = 0
constant IsFreebsd (line 13) | IsFreebsd = 0
constant IsHurd (line 14) | IsHurd = 0
constant IsIllumos (line 15) | IsIllumos = 0
constant IsIos (line 16) | IsIos = 1
constant IsJs (line 17) | IsJs = 0
constant IsLinux (line 18) | IsLinux = 0
constant IsNacl (line 19) | IsNacl = 0
constant IsNetbsd (line 20) | IsNetbsd = 0
constant IsOpenbsd (line 21) | IsOpenbsd = 0
constant IsPlan9 (line 22) | IsPlan9 = 0
constant IsSolaris (line 23) | IsSolaris = 0
constant IsWindows (line 24) | IsWindows = 0
constant IsZos (line 25) | IsZos = 0
FILE: constant/goos/zgoos_js.go
constant GOOS (line 7) | GOOS = `js`
constant IsAix (line 9) | IsAix = 0
constant IsAndroid (line 10) | IsAndroid = 0
constant IsDarwin (line 11) | IsDarwin = 0
constant IsDragonfly (line 12) | IsDragonfly = 0
constant IsFreebsd (line 13) | IsFreebsd = 0
constant IsHurd (line 14) | IsHurd = 0
constant IsIllumos (line 15) | IsIllumos = 0
constant IsIos (line 16) | IsIos = 0
constant IsJs (line 17) | IsJs = 1
constant IsLinux (line 18) | IsLinux = 0
constant IsNacl (line 19) | IsNacl = 0
constant IsNetbsd (line 20) | IsNetbsd = 0
constant IsOpenbsd (line 21) | IsOpenbsd = 0
constant IsPlan9 (line 22) | IsPlan9 = 0
constant IsSolaris (line 23) | IsSolaris = 0
constant IsWindows (line 24) | IsWindows = 0
constant IsZos (line 25) | IsZos = 0
FILE: constant/goos/zgoos_linux.go
constant GOOS (line 7) | GOOS = `linux`
constant IsAix (line 9) | IsAix = 0
constant IsAndroid (line 10) | IsAndroid = 0
constant IsDarwin (line 11) | IsDarwin = 0
constant IsDragonfly (line 12) | IsDragonfly = 0
constant IsFreebsd (line 13) | IsFreebsd = 0
constant IsHurd (line 14) | IsHurd = 0
constant IsIllumos (line 15) | IsIllumos = 0
constant IsIos (line 16) | IsIos = 0
constant IsJs (line 17) | IsJs = 0
constant IsLinux (line 18) | IsLinux = 1
constant IsNacl (line 19) | IsNacl = 0
constant IsNetbsd (line 20) | IsNetbsd = 0
constant IsOpenbsd (line 21) | IsOpenbsd = 0
constant IsPlan9 (line 22) | IsPlan9 = 0
constant IsSolaris (line 23) | IsSolaris = 0
constant IsWindows (line 24) | IsWindows = 0
constant IsZos (line 25) | IsZos = 0
FILE: constant/goos/zgoos_netbsd.go
constant GOOS (line 7) | GOOS = `netbsd`
constant IsAix (line 9) | IsAix = 0
constant IsAndroid (line 10) | IsAndroid = 0
constant IsDarwin (line 11) | IsDarwin = 0
constant IsDragonfly (line 12) | IsDragonfly = 0
constant IsFreebsd (line 13) | IsFreebsd = 0
constant IsHurd (line 14) | IsHurd = 0
constant IsIllumos (line 15) | IsIllumos = 0
constant IsIos (line 16) | IsIos = 0
constant IsJs (line 17) | IsJs = 0
constant IsLinux (line 18) | IsLinux = 0
constant IsNacl (line 19) | IsNacl = 0
constant IsNetbsd (line 20) | IsNetbsd = 1
constant IsOpenbsd (line 21) | IsOpenbsd = 0
constant IsPlan9 (line 22) | IsPlan9 = 0
constant IsSolaris (line 23) | IsSolaris = 0
constant IsWindows (line 24) | IsWindows = 0
constant IsZos (line 25) | IsZos = 0
FILE: constant/goos/zgoos_openbsd.go
constant GOOS (line 7) | GOOS = `openbsd`
constant IsAix (line 9) | IsAix = 0
constant IsAndroid (line 10) | IsAndroid = 0
constant IsDarwin (line 11) | IsDarwin = 0
constant IsDragonfly (line 12) | IsDragonfly = 0
constant IsFreebsd (line 13) | IsFreebsd = 0
constant IsHurd (line 14) | IsHurd = 0
constant IsIllumos (line 15) | IsIllumos = 0
constant IsIos (line 16) | IsIos = 0
constant IsJs (line 17) | IsJs = 0
constant IsLinux (line 18) | IsLinux = 0
constant IsNacl (line 19) | IsNacl = 0
constant IsNetbsd (line 20) | IsNetbsd = 0
constant IsOpenbsd (line 21) | IsOpenbsd = 1
constant IsPlan9 (line 22) | IsPlan9 = 0
constant IsSolaris (line 23) | IsSolaris = 0
constant IsWindows (line 24) | IsWindows = 0
constant IsZos (line 25) | IsZos = 0
FILE: constant/goos/zgoos_plan9.go
constant GOOS (line 7) | GOOS = `plan9`
constant IsAix (line 9) | IsAix = 0
constant IsAndroid (line 10) | IsAndroid = 0
constant IsDarwin (line 11) | IsDarwin = 0
constant IsDragonfly (line 12) | IsDragonfly = 0
constant IsFreebsd (line 13) | IsFreebsd = 0
constant IsHurd (line 14) | IsHurd = 0
constant IsIllumos (line 15) | IsIllumos = 0
constant IsIos (line 16) | IsIos = 0
constant IsJs (line 17) | IsJs = 0
constant IsLinux (line 18) | IsLinux = 0
constant IsNacl (line 19) | IsNacl = 0
constant IsNetbsd (line 20) | IsNetbsd = 0
constant IsOpenbsd (line 21) | IsOpenbsd = 0
constant IsPlan9 (line 22) | IsPlan9 = 1
constant IsSolaris (line 23) | IsSolaris = 0
constant IsWindows (line 24) | IsWindows = 0
constant IsZos (line 25) | IsZos = 0
FILE: constant/goos/zgoos_solaris.go
constant GOOS (line 7) | GOOS = `solaris`
constant IsAix (line 9) | IsAix = 0
constant IsAndroid (line 10) | IsAndroid = 0
constant IsDarwin (line 11) | IsDarwin = 0
constant IsDragonfly (line 12) | IsDragonfly = 0
constant IsFreebsd (line 13) | IsFreebsd = 0
constant IsHurd (line 14) | IsHurd = 0
constant IsIllumos (line 15) | IsIllumos = 0
constant IsIos (line 16) | IsIos = 0
constant IsJs (line 17) | IsJs = 0
constant IsLinux (line 18) | IsLinux = 0
constant IsNacl (line 19) | IsNacl = 0
constant IsNetbsd (line 20) | IsNetbsd = 0
constant IsOpenbsd (line 21) | IsOpenbsd = 0
constant IsPlan9 (line 22) | IsPlan9 = 0
constant IsSolaris (line 23) | IsSolaris = 1
constant IsWindows (line 24) | IsWindows = 0
constant IsZos (line 25) | IsZos = 0
FILE: constant/goos/zgoos_windows.go
constant GOOS (line 7) | GOOS = `windows`
constant IsAix (line 9) | IsAix = 0
constant IsAndroid (line 10) | IsAndroid = 0
constant IsDarwin (line 11) | IsDarwin = 0
constant IsDragonfly (line 12) | IsDragonfly = 0
constant IsFreebsd (line 13) | IsFreebsd = 0
constant IsHurd (line 14) | IsHurd = 0
constant IsIllumos (line 15) | IsIllumos = 0
constant IsIos (line 16) | IsIos = 0
constant IsJs (line 17) | IsJs = 0
constant IsLinux (line 18) | IsLinux = 0
constant IsNacl (line 19) | IsNacl = 0
constant IsNetbsd (line 20) | IsNetbsd = 0
constant IsOpenbsd (line 21) | IsOpenbsd = 0
constant IsPlan9 (line 22) | IsPlan9 = 0
constant IsSolaris (line 23) | IsSolaris = 0
constant IsWindows (line 24) | IsWindows = 1
constant IsZos (line 25) | IsZos = 0
FILE: constant/goos/zgoos_zos.go
constant GOOS (line 7) | GOOS = `zos`
constant IsAix (line 9) | IsAix = 0
constant IsAndroid (line 10) | IsAndroid = 0
constant IsDarwin (line 11) | IsDarwin = 0
constant IsDragonfly (line 12) | IsDragonfly = 0
constant IsFreebsd (line 13) | IsFreebsd = 0
constant IsHurd (line 14) | IsHurd = 0
constant IsIllumos (line 15) | IsIllumos = 0
constant IsIos (line 16) | IsIos = 0
constant IsJs (line 17) | IsJs = 0
constant IsLinux (line 18) | IsLinux = 0
constant IsNacl (line 19) | IsNacl = 0
constant IsNetbsd (line 20) | IsNetbsd = 0
constant IsOpenbsd (line 21) | IsOpenbsd = 0
constant IsPlan9 (line 22) | IsPlan9 = 0
constant IsSolaris (line 23) | IsSolaris = 0
constant IsWindows (line 24) | IsWindows = 0
constant IsZos (line 25) | IsZos = 1
FILE: constant/hysteria2.go
constant Hysterai2MasqueradeTypeFile (line 4) | Hysterai2MasqueradeTypeFile = "file"
constant Hysterai2MasqueradeTypeProxy (line 5) | Hysterai2MasqueradeTypeProxy = "proxy"
constant Hysterai2MasqueradeTypeString (line 6) | Hysterai2MasqueradeTypeString = "string"
FILE: constant/network.go
type InterfaceType (line 8) | type InterfaceType
method String (line 27) | func (t InterfaceType) String() string {
constant InterfaceTypeWIFI (line 11) | InterfaceTypeWIFI InterfaceType = iota
constant InterfaceTypeCellular (line 12) | InterfaceTypeCellular
constant InterfaceTypeEthernet (line 13) | InterfaceTypeEthernet
constant InterfaceTypeOther (line 14) | InterfaceTypeOther
type NetworkStrategy (line 35) | type NetworkStrategy
method String (line 52) | func (s NetworkStrategy) String() string {
constant NetworkStrategyDefault (line 38) | NetworkStrategyDefault NetworkStrategy = iota
constant NetworkStrategyFallback (line 39) | NetworkStrategyFallback
constant NetworkStrategyHybrid (line 40) | NetworkStrategyHybrid
FILE: constant/os.go
constant IsAndroid (line 7) | IsAndroid = goos.IsAndroid == 1
constant IsDarwin (line 9) | IsDarwin = goos.IsDarwin == 1 || goos.IsIos == 1
constant IsDragonfly (line 11) | IsDragonfly = goos.IsDragonfly == 1
constant IsFreebsd (line 13) | IsFreebsd = goos.IsFreebsd == 1
constant IsHurd (line 15) | IsHurd = goos.IsHurd == 1
constant IsIllumos (line 17) | IsIllumos = goos.IsIllumos == 1
constant IsIos (line 19) | IsIos = goos.IsIos == 1
constant IsJs (line 21) | IsJs = goos.IsJs == 1
constant IsLinux (line 23) | IsLinux = goos.IsLinux == 1 || goos.IsAndroid == 1
constant IsNacl (line 25) | IsNacl = goos.IsNacl == 1
constant IsNetbsd (line 27) | IsNetbsd = goos.IsNetbsd == 1
constant IsOpenbsd (line 29) | IsOpenbsd = goos.IsOpenbsd == 1
constant IsPlan9 (line 31) | IsPlan9 = goos.IsPlan9 == 1
constant IsSolaris (line 33) | IsSolaris = goos.IsSolaris == 1
constant IsWindows (line 35) | IsWindows = goos.IsWindows == 1
constant IsZos (line 37) | IsZos = goos.IsZos == 1
FILE: constant/path.go
constant dirName (line 10) | dirName = "sing-box"
function FindPath (line 14) | func FindPath(name string) (string, bool) {
function init (line 30) | func init() {
FILE: constant/path_unix.go
function init (line 9) | func init() {
FILE: constant/protocol.go
constant ProtocolTLS (line 4) | ProtocolTLS = "tls"
constant ProtocolHTTP (line 5) | ProtocolHTTP = "http"
constant ProtocolQUIC (line 6) | ProtocolQUIC = "quic"
constant ProtocolDNS (line 7) | ProtocolDNS = "dns"
constant ProtocolSTUN (line 8) | ProtocolSTUN = "stun"
constant ProtocolBitTorrent (line 9) | ProtocolBitTorrent = "bittorrent"
constant ProtocolDTLS (line 10) | ProtocolDTLS = "dtls"
constant ProtocolSSH (line 11) | ProtocolSSH = "ssh"
constant ProtocolRDP (line 12) | ProtocolRDP = "rdp"
constant ProtocolNTP (line 13) | ProtocolNTP = "ntp"
constant ClientChromium (line 17) | ClientChromium = "chromium"
constant ClientSafari (line 18) | ClientSafari = "safari"
constant ClientFirefox (line 19) | ClientFirefox = "firefox"
constant ClientQUICGo (line 20) | ClientQUICGo = "quic-go"
constant ClientUnknown (line 21) | ClientUnknown = "unknown"
FILE: constant/proxy.go
constant TypeTun (line 4) | TypeTun = "tun"
constant TypeRedirect (line 5) | TypeRedirect = "redirect"
constant TypeTProxy (line 6) | TypeTProxy = "tproxy"
constant TypeDirect (line 7) | TypeDirect = "direct"
constant TypeBlock (line 8) | TypeBlock = "block"
constant TypeDNS (line 9) | TypeDNS = "dns"
constant TypeSOCKS (line 10) | TypeSOCKS = "socks"
constant TypeHTTP (line 11) | TypeHTTP = "http"
constant TypeMixed (line 12) | TypeMixed = "mixed"
constant TypeShadowsocks (line 13) | TypeShadowsocks = "shadowsocks"
constant TypeVMess (line 14) | TypeVMess = "vmess"
constant TypeTrojan (line 15) | TypeTrojan = "trojan"
constant TypeNaive (line 16) | TypeNaive = "naive"
constant TypeWireGuard (line 17) | TypeWireGuard = "wireguard"
constant TypeHysteria (line 18) | TypeHysteria = "hysteria"
constant TypeTor (line 19) | TypeTor = "tor"
constant TypeSSH (line 20) | TypeSSH = "ssh"
constant TypeShadowTLS (line 21) | TypeShadowTLS = "shadowtls"
constant TypeAnyTLS (line 22) | TypeAnyTLS = "anytls"
constant TypeShadowsocksR (line 23) | TypeShadowsocksR = "shadowsocksr"
constant TypeVLESS (line 24) | TypeVLESS = "vless"
constant TypeTUIC (line 25) | TypeTUIC = "tuic"
constant TypeHysteria2 (line 26) | TypeHysteria2 = "hysteria2"
constant TypeTailscale (line 27) | TypeTailscale = "tailscale"
constant TypeDERP (line 28) | TypeDERP = "derp"
constant TypeResolved (line 29) | TypeResolved = "resolved"
constant TypeSSMAPI (line 30) | TypeSSMAPI = "ssm-api"
constant TypeCCM (line 31) | TypeCCM = "ccm"
constant TypeOCM (line 32) | TypeOCM = "ocm"
constant TypeOOMKiller (line 33) | TypeOOMKiller = "oom-killer"
constant TypeSelector (line 37) | TypeSelector = "selector"
constant TypeURLTest (line 38) | TypeURLTest = "urltest"
function ProxyDisplayName (line 41) | func ProxyDisplayName(proxyType string) string {
FILE: constant/quic.go
constant WithQUIC (line 5) | WithQUIC = true
FILE: constant/quic_stub.go
constant WithQUIC (line 5) | WithQUIC = false
FILE: constant/rule.go
constant RuleTypeDefault (line 4) | RuleTypeDefault = "default"
constant RuleTypeLogical (line 5) | RuleTypeLogical = "logical"
constant LogicalTypeAnd (line 9) | LogicalTypeAnd = "and"
constant LogicalTypeOr (line 10) | LogicalTypeOr = "or"
constant RuleSetTypeInline (line 14) | RuleSetTypeInline = "inline"
constant RuleSetTypeLocal (line 15) | RuleSetTypeLocal = "local"
constant RuleSetTypeRemote (line 16) | RuleSetTypeRemote = "remote"
constant RuleSetFormatSource (line 17) | RuleSetFormatSource = "source"
constant RuleSetFormatBinary (line 18) | RuleSetFormatBinary = "binary"
constant RuleSetVersion1 (line 22) | RuleSetVersion1 = 1 + iota
constant RuleSetVersion2 (line 23) | RuleSetVersion2
constant RuleSetVersion3 (line 24) | RuleSetVersion3
constant RuleSetVersion4 (line 25) | RuleSetVersion4
constant RuleSetVersionCurrent (line 26) | RuleSetVersionCurrent = RuleSetVersion4
constant RuleActionTypeRoute (line 30) | RuleActionTypeRoute = "route"
constant RuleActionTypeRouteOptions (line 31) | RuleActionTypeRouteOptions = "route-options"
constant RuleActionTypeDirect (line 32) | RuleActionTypeDirect = "direct"
constant RuleActionTypeBypass (line 33) | RuleActionTypeBypass = "bypass"
constant RuleActionTypeReject (line 34) | RuleActionTypeReject = "reject"
constant RuleActionTypeHijackDNS (line 35) | RuleActionTypeHijackDNS = "hijack-dns"
constant RuleActionTypeSniff (line 36) | RuleActionTypeSniff = "sniff"
constant RuleActionTypeResolve (line 37) | RuleActionTypeResolve = "resolve"
constant RuleActionTypePredefined (line 38) | RuleActionTypePredefined = "predefined"
constant RuleActionRejectMethodDefault (line 42) | RuleActionRejectMethodDefault = "default"
constant RuleActionRejectMethodDrop (line 43) | RuleActionRejectMethodDrop = "drop"
constant RuleActionRejectMethodReply (line 44) | RuleActionRejectMethodReply = "reply"
FILE: constant/speed.go
constant MbpsToBps (line 3) | MbpsToBps = 125000
FILE: constant/time.go
constant TimeLayout (line 3) | TimeLayout = "2006-01-02 15:04:05 -0700"
FILE: constant/timeout.go
constant TCPKeepAliveInitial (line 6) | TCPKeepAliveInitial = 5 * time.Minute
constant TCPKeepAliveInterval (line 7) | TCPKeepAliveInterval = 75 * time.Second
constant TCPConnectTimeout (line 8) | TCPConnectTimeout = 5 * time.Second
constant TCPTimeout (line 9) | TCPTimeout = 15 * time.Second
constant ReadPayloadTimeout (line 10) | ReadPayloadTimeout = 300 * time.Millisecond
constant DNSTimeout (line 11) | DNSTimeout = 10 * time.Second
constant UDPTimeout (line 12) | UDPTimeout = 5 * time.Minute
constant DefaultURLTestInterval (line 13) | DefaultURLTestInterval = 3 * time.Minute
constant DefaultURLTestIdleTimeout (line 14) | DefaultURLTestIdleTimeout = 30 * time.Minute
constant StartTimeout (line 15) | StartTimeout = 10 * time.Second
constant StopTimeout (line 16) | StopTimeout = 5 * time.Second
constant FatalStopTimeout (line 17) | FatalStopTimeout = 10 * time.Second
constant FakeIPMetadataSaveInterval (line 18) | FakeIPMetadataSaveInterval = 10 * time.Second
constant TLSFragmentFallbackDelay (line 19) | TLSFragmentFallbackDelay = 500 * time.Millisecond
FILE: constant/v2ray.go
constant V2RayTransportTypeHTTP (line 4) | V2RayTransportTypeHTTP = "http"
constant V2RayTransportTypeWebsocket (line 5) | V2RayTransportTypeWebsocket = "ws"
constant V2RayTransportTypeQUIC (line 6) | V2RayTransportTypeQUIC = "quic"
constant V2RayTransportTypeGRPC (line 7) | V2RayTransportTypeGRPC = "grpc"
constant V2RayTransportTypeHTTPUpgrade (line 8) | V2RayTransportTypeHTTPUpgrade = "httpupgrade"
FILE: daemon/deprecated.go
type deprecatedManager (line 12) | type deprecatedManager struct
method ReportDeprecated (line 17) | func (m *deprecatedManager) ReportDeprecated(feature deprecated.Note) {
method Get (line 23) | func (m *deprecatedManager) Get() []deprecated.Note {
FILE: daemon/instance.go
type Instance (line 22) | type Instance struct
method Start (line 124) | func (i *Instance) Start() error {
method Close (line 128) | func (i *Instance) Close() error {
method Box (line 134) | func (i *Instance) Box() *box.Box {
method PauseManager (line 138) | func (i *Instance) PauseManager() pause.Manager {
method CheckConfig (line 33) | func (s *StartedService) CheckConfig(configContent string) error {
method FormatConfig (line 50) | func (s *StartedService) FormatConfig(configContent string) (string, err...
type OverrideOptions (line 65) | type OverrideOptions struct
method newInstance (line 71) | func (s *StartedService) newInstance(profileContent string, overrideOpti...
function parseConfig (line 142) | func parseConfig(ctx context.Context, configContent string) (option.Opti...
FILE: daemon/platform.go
type PlatformHandler (line 3) | type PlatformHandler interface
FILE: daemon/started_service.go
type StartedService (line 32) | type StartedService struct
method resetLogs (line 107) | func (s *StartedService) resetLogs() {
method updateStatus (line 114) | func (s *StartedService) updateStatus(newStatus ServiceStatus_Type) {
method updateStatusError (line 120) | func (s *StartedService) updateStatusError(err error) error {
method waitForStarted (line 128) | func (s *StartedService) waitForStarted(ctx context.Context) error {
method StartOrReloadService (line 168) | func (s *StartedService) StartOrReloadService(profileContent string, o...
method Close (line 212) | func (s *StartedService) Close() {
method CloseService (line 220) | func (s *StartedService) CloseService() error {
method SetError (line 243) | func (s *StartedService) SetError(err error) {
method StopService (line 249) | func (s *StartedService) StopService(ctx context.Context, empty *empty...
method ReloadService (line 257) | func (s *StartedService) ReloadService(ctx context.Context, empty *emp...
method SubscribeServiceStatus (line 265) | func (s *StartedService) SubscribeServiceStatus(empty *emptypb.Empty, ...
method SubscribeLog (line 292) | func (s *StartedService) SubscribeLog(empty *emptypb.Empty, server grp...
method GetDefaultLogLevel (line 360) | func (s *StartedService) GetDefaultLogLevel(ctx context.Context, empty...
method ClearLogs (line 373) | func (s *StartedService) ClearLogs(ctx context.Context, empty *emptypb...
method SubscribeStatus (line 378) | func (s *StartedService) SubscribeStatus(request *SubscribeStatusReque...
method readStatus (line 410) | func (s *StartedService) readStatus() *Status {
method SubscribeGroups (line 431) | func (s *StartedService) SubscribeGroups(empty *emptypb.Empty, server ...
method readGroups (line 465) | func (s *StartedService) readGroups() *Groups {
method GetClashModeStatus (line 511) | func (s *StartedService) GetClashModeStatus(ctx context.Context, empty...
method SubscribeClashMode (line 528) | func (s *StartedService) SubscribeClashMode(empty *emptypb.Empty, serv...
method SetClashMode (line 562) | func (s *StartedService) SetClashMode(ctx context.Context, request *Cl...
method URLTest (line 574) | func (s *StartedService) URLTest(ctx context.Context, request *URLTest...
method SelectOutbound (line 631) | func (s *StartedService) SelectOutbound(ctx context.Context, request *...
method SetGroupExpand (line 656) | func (s *StartedService) SetGroupExpand(ctx context.Context, request *...
method GetSystemProxyStatus (line 675) | func (s *StartedService) GetSystemProxyStatus(ctx context.Context, emp...
method SetSystemProxyEnabled (line 679) | func (s *StartedService) SetSystemProxyEnabled(ctx context.Context, re...
method SubscribeConnections (line 687) | func (s *StartedService) SubscribeConnections(request *SubscribeConnec...
method buildInitialConnectionState (line 776) | func (s *StartedService) buildInitialConnectionState(manager *traffico...
method applyConnectionEvent (line 804) | func (s *StartedService) applyConnectionEvent(event trafficontrol.Conn...
method buildTrafficUpdates (line 844) | func (s *StartedService) buildTrafficUpdates(manager *trafficontrol.Ma...
method CloseConnection (line 982) | func (s *StartedService) CloseConnection(ctx context.Context, request ...
method CloseAllConnections (line 999) | func (s *StartedService) CloseAllConnections(ctx context.Context, empt...
method GetDeprecatedWarnings (line 1009) | func (s *StartedService) GetDeprecatedWarnings(ctx context.Context, em...
method GetStartedAt (line 1029) | func (s *StartedService) GetStartedAt(ctx context.Context, empty *empt...
method mustEmbedUnimplementedStartedServiceServer (line 1035) | func (s *StartedService) mustEmbedUnimplementedStartedServiceServer() {
method WriteMessage (line 1038) | func (s *StartedService) WriteMessage(level log.Level, message string) {
method Instance (line 1052) | func (s *StartedService) Instance() *Instance {
type ServiceOptions (line 64) | type ServiceOptions struct
function NewStartedService (line 78) | func NewStartedService(options ServiceOptions) *StartedService {
type connectionSnapshot (line 770) | type connectionSnapshot struct
function buildConnectionProto (line 942) | func buildConnectionProto(metadata *trafficontrol.TrackerMetadata) *Conn...
FILE: daemon/started_service.pb.go
constant _ (line 15) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
constant _ (line 17) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
type LogLevel (line 20) | type LogLevel
method Enum (line 54) | func (x LogLevel) Enum() *LogLevel {
method String (line 60) | func (x LogLevel) String() string {
method Descriptor (line 64) | func (LogLevel) Descriptor() protoreflect.EnumDescriptor {
method Type (line 68) | func (LogLevel) Type() protoreflect.EnumType {
method Number (line 72) | func (x LogLevel) Number() protoreflect.EnumNumber {
method EnumDescriptor (line 77) | func (LogLevel) EnumDescriptor() ([]byte, []int) {
constant LogLevel_PANIC (line 23) | LogLevel_PANIC LogLevel = 0
constant LogLevel_FATAL (line 24) | LogLevel_FATAL LogLevel = 1
constant LogLevel_ERROR (line 25) | LogLevel_ERROR LogLevel = 2
constant LogLevel_WARN (line 26) | LogLevel_WARN LogLevel = 3
constant LogLevel_INFO (line 27) | LogLevel_INFO LogLevel = 4
constant LogLevel_DEBUG (line 28) | LogLevel_DEBUG LogLevel = 5
constant LogLevel_TRACE (line 29) | LogLevel_TRACE LogLevel = 6
type ConnectionEventType (line 81) | type ConnectionEventType
method Enum (line 103) | func (x ConnectionEventType) Enum() *ConnectionEventType {
method String (line 109) | func (x ConnectionEventType) String() string {
method Descriptor (line 113) | func (ConnectionEventType) Descriptor() protoreflect.EnumDescriptor {
method Type (line 117) | func (ConnectionEventType) Type() protoreflect.EnumType {
method Number (line 121) | func (x ConnectionEventType) Number() protoreflect.EnumNumber {
method EnumDescriptor (line 126) | func (ConnectionEventType) EnumDescriptor() ([]byte, []int) {
constant ConnectionEventType_CONNECTION_EVENT_NEW (line 84) | ConnectionEventType_CONNECTION_EVENT_NEW ConnectionEventType = 0
constant ConnectionEventType_CONNECTION_EVENT_UPDATE (line 85) | ConnectionEventType_CONNECTION_EVENT_UPDATE ConnectionEventType = 1
constant ConnectionEventType_CONNECTION_EVENT_CLOSED (line 86) | ConnectionEventType_CONNECTION_EVENT_CLOSED ConnectionEventType = 2
type ServiceStatus_Type (line 130) | type ServiceStatus_Type
method Enum (line 158) | func (x ServiceStatus_Type) Enum() *ServiceStatus_Type {
method String (line 164) | func (x ServiceStatus_Type) String() string {
method Descriptor (line 168) | func (ServiceStatus_Type) Descriptor() protoreflect.EnumDescriptor {
method Type (line 172) | func (ServiceStatus_Type) Type() protoreflect.EnumType {
method Number (line 176) | func (x ServiceStatus_Type) Number() protoreflect.EnumNumber {
method EnumDescriptor (line 181) | func (ServiceStatus_Type) EnumDescriptor() ([]byte, []int) {
constant ServiceStatus_IDLE (line 133) | ServiceStatus_IDLE ServiceStatus_Type = 0
constant ServiceStatus_STARTING (line 134) | ServiceStatus_STARTING ServiceStatus_Type = 1
constant ServiceStatus_STARTED (line 135) | ServiceStatus_STARTED ServiceStatus_Type = 2
constant ServiceStatus_STOPPING (line 136) | ServiceStatus_STOPPING ServiceStatus_Type = 3
constant ServiceStatus_FATAL (line 137) | ServiceStatus_FATAL ServiceStatus_Type = 4
type ServiceStatus (line 185) | type ServiceStatus struct
method Reset (line 193) | func (x *ServiceStatus) Reset() {
method String (line 200) | func (x *ServiceStatus) String() string {
method ProtoMessage (line 204) | func (*ServiceStatus) ProtoMessage() {}
method ProtoReflect (line 206) | func (x *ServiceStatus) ProtoReflect() protoreflect.Message {
method Descriptor (line 219) | func (*ServiceStatus) Descriptor() ([]byte, []int) {
method GetStatus (line 223) | func (x *ServiceStatus) GetStatus() ServiceStatus_Type {
method GetErrorMessage (line 230) | func (x *ServiceStatus) GetErrorMessage() string {
type ReloadServiceRequest (line 237) | type ReloadServiceRequest struct
method Reset (line 244) | func (x *ReloadServiceRequest) Reset() {
method String (line 251) | func (x *ReloadServiceRequest) String() string {
method ProtoMessage (line 255) | func (*ReloadServiceRequest) ProtoMessage() {}
method ProtoReflect (line 257) | func (x *ReloadServiceRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 270) | func (*ReloadServiceRequest) Descriptor() ([]byte, []int) {
method GetNewProfileContent (line 274) | func (x *ReloadServiceRequest) GetNewProfileContent() string {
type SubscribeStatusRequest (line 281) | type SubscribeStatusRequest struct
method Reset (line 288) | func (x *SubscribeStatusRequest) Reset() {
method String (line 295) | func (x *SubscribeStatusRequest) String() string {
method ProtoMessage (line 299) | func (*SubscribeStatusRequest) ProtoMessage() {}
method ProtoReflect (line 301) | func (x *SubscribeStatusRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 314) | func (*SubscribeStatusRequest) Descriptor() ([]byte, []int) {
method GetInterval (line 318) | func (x *SubscribeStatusRequest) GetInterval() int64 {
type Log (line 325) | type Log struct
method Reset (line 333) | func (x *Log) Reset() {
method String (line 340) | func (x *Log) String() string {
method ProtoMessage (line 344) | func (*Log) ProtoMessage() {}
method ProtoReflect (line 346) | func (x *Log) ProtoReflect() protoreflect.Message {
method Descriptor (line 359) | func (*Log) Descriptor() ([]byte, []int) {
method GetMessages (line 363) | func (x *Log) GetMessages() []*Log_Message {
method GetReset_ (line 370) | func (x *Log) GetReset_() bool {
type DefaultLogLevel (line 377) | type DefaultLogLevel struct
method Reset (line 384) | func (x *DefaultLogLevel) Reset() {
method String (line 391) | func (x *DefaultLogLevel) String() string {
method ProtoMessage (line 395) | func (*DefaultLogLevel) ProtoMessage() {}
method ProtoReflect (line 397) | func (x *DefaultLogLevel) ProtoReflect() protoreflect.Message {
method Descriptor (line 410) | func (*DefaultLogLevel) Descriptor() ([]byte, []int) {
method GetLevel (line 414) | func (x *DefaultLogLevel) GetLevel() LogLevel {
type Status (line 421) | type Status struct
method Reset (line 436) | func (x *Status) Reset() {
method String (line 443) | func (x *Status) String() string {
method ProtoMessage (line 447) | func (*Status) ProtoMessage() {}
method ProtoReflect (line 449) | func (x *Status) ProtoReflect() protoreflect.Message {
method Descriptor (line 462) | func (*Status) Descriptor() ([]byte, []int) {
method GetMemory (line 466) | func (x *Status) GetMemory() uint64 {
method GetGoroutines (line 473) | func (x *Status) GetGoroutines() int32 {
method GetConnectionsIn (line 480) | func (x *Status) GetConnectionsIn() int32 {
method GetConnectionsOut (line 487) | func (x *Status) GetConnectionsOut() int32 {
method GetTrafficAvailable (line 494) | func (x *Status) GetTrafficAvailable() bool {
method GetUplink (line 501) | func (x *Status) GetUplink() int64 {
method GetDownlink (line 508) | func (x *Status) GetDownlink() int64 {
method GetUplinkTotal (line 515) | func (x *Status) GetUplinkTotal() int64 {
method GetDownlinkTotal (line 522) | func (x *Status) GetDownlinkTotal() int64 {
type Groups (line 529) | type Groups struct
method Reset (line 536) | func (x *Groups) Reset() {
method String (line 543) | func (x *Groups) String() string {
method ProtoMessage (line 547) | func (*Groups) ProtoMessage() {}
method ProtoReflect (line 549) | func (x *Groups) ProtoReflect() protoreflect.Message {
method Descriptor (line 562) | func (*Groups) Descriptor() ([]byte, []int) {
method GetGroup (line 566) | func (x *Groups) GetGroup() []*Group {
type Group (line 573) | type Group struct
method Reset (line 585) | func (x *Group) Reset() {
method String (line 592) | func (x *Group) String() string {
method ProtoMessage (line 596) | func (*Group) ProtoMessage() {}
method ProtoReflect (line 598) | func (x *Group) ProtoReflect() protoreflect.Message {
method Descriptor (line 611) | func (*Group) Descriptor() ([]byte, []int) {
method GetTag (line 615) | func (x *Group) GetTag() string {
method GetType (line 622) | func (x *Group) GetType() string {
method GetSelectable (line 629) | func (x *Group) GetSelectable() bool {
method GetSelected (line 636) | func (x *Group) GetSelected() string {
method GetIsExpand (line 643) | func (x *Group) GetIsExpand() bool {
method GetItems (line 650) | func (x *Group) GetItems() []*GroupItem {
type GroupItem (line 657) | type GroupItem struct
method Reset (line 667) | func (x *GroupItem) Reset() {
method String (line 674) | func (x *GroupItem) String() string {
method ProtoMessage (line 678) | func (*GroupItem) ProtoMessage() {}
method ProtoReflect (line 680) | func (x *GroupItem) ProtoReflect() protoreflect.Message {
method Descriptor (line 693) | func (*GroupItem) Descriptor() ([]byte, []int) {
method GetTag (line 697) | func (x *GroupItem) GetTag() string {
method GetType (line 704) | func (x *GroupItem) GetType() string {
method GetUrlTestTime (line 711) | func (x *GroupItem) GetUrlTestTime() int64 {
method GetUrlTestDelay (line 718) | func (x *GroupItem) GetUrlTestDelay() int32 {
type URLTestRequest (line 725) | type URLTestRequest struct
method Reset (line 732) | func (x *URLTestRequest) Reset() {
method String (line 739) | func (x *URLTestRequest) String() string {
method ProtoMessage (line 743) | func (*URLTestRequest) ProtoMessage() {}
method ProtoReflect (line 745) | func (x *URLTestRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 758) | func (*URLTestRequest) Descriptor() ([]byte, []int) {
method GetOutboundTag (line 762) | func (x *URLTestRequest) GetOutboundTag() string {
type SelectOutboundRequest (line 769) | type SelectOutboundRequest struct
method Reset (line 777) | func (x *SelectOutboundRequest) Reset() {
method String (line 784) | func (x *SelectOutboundRequest) String() string {
method ProtoMessage (line 788) | func (*SelectOutboundRequest) ProtoMessage() {}
method ProtoReflect (line 790) | func (x *SelectOutboundRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 803) | func (*SelectOutboundRequest) Descriptor() ([]byte, []int) {
method GetGroupTag (line 807) | func (x *SelectOutboundRequest) GetGroupTag() string {
method GetOutboundTag (line 814) | func (x *SelectOutboundRequest) GetOutboundTag() string {
type SetGroupExpandRequest (line 821) | type SetGroupExpandRequest struct
method Reset (line 829) | func (x *SetGroupExpandRequest) Reset() {
method String (line 836) | func (x *SetGroupExpandRequest) String() string {
method ProtoMessage (line 840) | func (*SetGroupExpandRequest) ProtoMessage() {}
method ProtoReflect (line 842) | func (x *SetGroupExpandRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 855) | func (*SetGroupExpandRequest) Descriptor() ([]byte, []int) {
method GetGroupTag (line 859) | func (x *SetGroupExpandRequest) GetGroupTag() string {
method GetIsExpand (line 866) | func (x *SetGroupExpandRequest) GetIsExpand() bool {
type ClashMode (line 873) | type ClashMode struct
method Reset (line 880) | func (x *ClashMode) Reset() {
method String (line 887) | func (x *ClashMode) String() string {
method ProtoMessage (line 891) | func (*ClashMode) ProtoMessage() {}
method ProtoReflect (line 893) | func (x *ClashMode) ProtoReflect() protoreflect.Message {
method Descriptor (line 906) | func (*ClashMode) Descriptor() ([]byte, []int) {
method GetMode (line 910) | func (x *ClashMode) GetMode() string {
type ClashModeStatus (line 917) | type ClashModeStatus struct
method Reset (line 925) | func (x *ClashModeStatus) Reset() {
method String (line 932) | func (x *ClashModeStatus) String() string {
method ProtoMessage (line 936) | func (*ClashModeStatus) ProtoMessage() {}
method ProtoReflect (line 938) | func (x *ClashModeStatus) ProtoReflect() protoreflect.Message {
method Descriptor (line 951) | func (*ClashModeStatus) Descriptor() ([]byte, []int) {
method GetModeList (line 955) | func (x *ClashModeStatus) GetModeList() []string {
method GetCurrentMode (line 962) | func (x *ClashModeStatus) GetCurrentMode() string {
type SystemProxyStatus (line 969) | type SystemProxyStatus struct
method Reset (line 977) | func (x *SystemProxyStatus) Reset() {
method String (line 984) | func (x *SystemProxyStatus) String() string {
method ProtoMessage (line 988) | func (*SystemProxyStatus) ProtoMessage() {}
method ProtoReflect (line 990) | func (x *SystemProxyStatus) ProtoReflect() protoreflect.Message {
method Descriptor (line 1003) | func (*SystemProxyStatus) Descriptor() ([]byte, []int) {
method GetAvailable (line 1007) | func (x *SystemProxyStatus) GetAvailable() bool {
method GetEnabled (line 1014) | func (x *SystemProxyStatus) GetEnabled() bool {
type SetSystemProxyEnabledRequest (line 1021) | type SetSystemProxyEnabledRequest struct
method Reset (line 1028) | func (x *SetSystemProxyEnabledRequest) Reset() {
method String (line 1035) | func (x *SetSystemProxyEnabledRequest) String() string {
method ProtoMessage (line 1039) | func (*SetSystemProxyEnabledRequest) ProtoMessage() {}
method ProtoReflect (line 1041) | func (x *SetSystemProxyEnabledRequest) ProtoReflect() protoreflect.Mes...
method Descriptor (line 1054) | func (*SetSystemProxyEnabledRequest) Descriptor() ([]byte, []int) {
method GetEnabled (line 1058) | func (x *SetSystemProxyEnabledRequest) GetEnabled() bool {
type SubscribeConnectionsRequest (line 1065) | type SubscribeConnectionsRequest struct
method Reset (line 1072) | func (x *SubscribeConnectionsRequest) Reset() {
method String (line 1079) | func (x *SubscribeConnectionsRequest) String() string {
method ProtoMessage (line 1083) | func (*SubscribeConnectionsRequest) ProtoMessage() {}
method ProtoReflect (line 1085) | func (x *SubscribeConnectionsRequest) ProtoReflect() protoreflect.Mess...
method Descriptor (line 1098) | func (*SubscribeConnectionsRequest) Descriptor() ([]byte, []int) {
method GetInterval (line 1102) | func (x *SubscribeConnectionsRequest) GetInterval() int64 {
type ConnectionEvent (line 1109) | type ConnectionEvent struct
method Reset (line 1121) | func (x *ConnectionEvent) Reset() {
method String (line 1128) | func (x *ConnectionEvent) String() string {
method ProtoMessage (line 1132) | func (*ConnectionEvent) ProtoMessage() {}
method ProtoReflect (line 1134) | func (x *ConnectionEvent) ProtoReflect() protoreflect.Message {
method Descriptor (line 1147) | func (*ConnectionEvent) Descriptor() ([]byte, []int) {
method GetType (line 1151) | func (x *ConnectionEvent) GetType() ConnectionEventType {
method GetId (line 1158) | func (x *ConnectionEvent) GetId() string {
method GetConnection (line 1165) | func (x *ConnectionEvent) GetConnection() *Connection {
method GetUplinkDelta (line 1172) | func (x *ConnectionEvent) GetUplinkDelta() int64 {
method GetDownlinkDelta (line 1179) | func (x *ConnectionEvent) GetDownlinkDelta() int64 {
method GetClosedAt (line 1186) | func (x *ConnectionEvent) GetClosedAt() int64 {
type ConnectionEvents (line 1193) | type ConnectionEvents struct
method Reset (line 1201) | func (x *ConnectionEvents) Reset() {
method String (line 1208) | func (x *ConnectionEvents) String() string {
method ProtoMessage (line 1212) | func (*ConnectionEvents) ProtoMessage() {}
method ProtoReflect (line 1214) | func (x *ConnectionEvents) ProtoReflect() protoreflect.Message {
method Descriptor (line 1227) | func (*ConnectionEvents) Descriptor() ([]byte, []int) {
method GetEvents (line 1231) | func (x *ConnectionEvents) GetEvents() []*ConnectionEvent {
method GetReset_ (line 1238) | func (x *ConnectionEvents) GetReset_() bool {
type Connection (line 1245) | type Connection struct
method Reset (line 1273) | func (x *Connection) Reset() {
method String (line 1280) | func (x *Connection) String() string {
method ProtoMessage (line 1284) | func (*Connection) ProtoMessage() {}
method ProtoReflect (line 1286) | func (x *Connection) ProtoReflect() protoreflect.Message {
method Descriptor (line 1299) | func (*Connection) Descriptor() ([]byte, []int) {
method GetId (line 1303) | func (x *Connection) GetId() string {
method GetInbound (line 1310) | func (x *Connection) GetInbound() string {
method GetInboundType (line 1317) | func (x *Connection) GetInboundType() string {
method GetIpVersion (line 1324) | func (x *Connection) GetIpVersion() int32 {
method GetNetwork (line 1331) | func (x *Connection) GetNetwork() string {
method GetSource (line 1338) | func (x *Connection) GetSource() string {
method GetDestination (line 1345) | func (x *Connection) GetDestination() string {
method GetDomain (line 1352) | func (x *Connection) GetDomain() string {
method GetProtocol (line 1359) | func (x *Connection) GetProtocol() string {
method GetUser (line 1366) | func (x *Connection) GetUser() string {
method GetFromOutbound (line 1373) | func (x *Connection) GetFromOutbound() string {
method GetCreatedAt (line 1380) | func (x *Connection) GetCreatedAt() int64 {
method GetClosedAt (line 1387) | func (x *Connection) GetClosedAt() int64 {
method GetUplink (line 1394) | func (x *Connection) GetUplink() int64 {
method GetDownlink (line 1401) | func (x *Connection) GetDownlink() int64 {
method GetUplinkTotal (line 1408) | func (x *Connection) GetUplinkTotal() int64 {
method GetDownlinkTotal (line 1415) | func (x *Connection) GetDownlinkTotal() int64 {
method GetRule (line 1422) | func (x *Connection) GetRule() string {
method GetOutbound (line 1429) | func (x *Connection) GetOutbound() string {
method GetOutboundType (line 1436) | func (x *Connection) GetOutboundType() string {
method GetChainList (line 1443) | func (x *Connection) GetChainList() []string {
method GetProcessInfo (line 1450) | func (x *Connection) GetProcessInfo() *ProcessInfo {
type ProcessInfo (line 1457) | type ProcessInfo struct
method Reset (line 1468) | func (x *ProcessInfo) Reset() {
method String (line 1475) | func (x *ProcessInfo) String() string {
method ProtoMessage (line 1479) | func (*ProcessInfo) ProtoMessage() {}
method ProtoReflect (line 1481) | func (x *ProcessInfo) ProtoReflect() protoreflect.Message {
method Descriptor (line 1494) | func (*ProcessInfo) Descriptor() ([]byte, []int) {
method GetProcessId (line 1498) | func (x *ProcessInfo) GetProcessId() uint32 {
method GetUserId (line 1505) | func (x *ProcessInfo) GetUserId() int32 {
method GetUserName (line 1512) | func (x *ProcessInfo) GetUserName() string {
method GetProcessPath (line 1519) | func (x *ProcessInfo) GetProcessPath() string {
method GetPackageName (line 1526) | func (x *ProcessInfo) GetPackageName() string {
type CloseConnectionRequest (line 1533) | type CloseConnectionRequest struct
method Reset (line 1540) | func (x *CloseConnectionRequest) Reset() {
method String (line 1547) | func (x *CloseConnectionRequest) String() string {
method ProtoMessage (line 1551) | func (*CloseConnectionRequest) ProtoMessage() {}
method ProtoReflect (line 1553) | func (x *CloseConnectionRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 1566) | func (*CloseConnectionRequest) Descriptor() ([]byte, []int) {
method GetId (line 1570) | func (x *CloseConnectionRequest) GetId() string {
type DeprecatedWarnings (line 1577) | type DeprecatedWarnings struct
method Reset (line 1584) | func (x *DeprecatedWarnings) Reset() {
method String (line 1591) | func (x *DeprecatedWarnings) String() string {
method ProtoMessage (line 1595) | func (*DeprecatedWarnings) ProtoMessage() {}
method ProtoReflect (line 1597) | func (x *DeprecatedWarnings) ProtoReflect() protoreflect.Message {
method Descriptor (line 1610) | func (*DeprecatedWarnings) Descriptor() ([]byte, []int) {
method GetWarnings (line 1614) | func (x *DeprecatedWarnings) GetWarnings() []*DeprecatedWarning {
type DeprecatedWarning (line 1621) | type DeprecatedWarning struct
method Reset (line 1630) | func (x *DeprecatedWarning) Reset() {
method String (line 1637) | func (x *DeprecatedWarning) String() string {
method ProtoMessage (line 1641) | func (*DeprecatedWarning) ProtoMessage() {}
method ProtoReflect (line 1643) | func (x *DeprecatedWarning) ProtoReflect() protoreflect.Message {
method Descriptor (line 1656) | func (*DeprecatedWarning) Descriptor() ([]byte, []int) {
method GetMessage (line 1660) | func (x *DeprecatedWarning) GetMessage() string {
method GetImpending (line 1667) | func (x *DeprecatedWarning) GetImpending() bool {
method GetMigrationLink (line 1674) | func (x *DeprecatedWarning) GetMigrationLink() string {
type StartedAt (line 1681) | type StartedAt struct
method Reset (line 1688) | func (x *StartedAt) Reset() {
method String (line 1695) | func (x *StartedAt) String() string {
method ProtoMessage (line 1699) | func (*StartedAt) ProtoMessage() {}
method ProtoReflect (line 1701) | func (x *StartedAt) ProtoReflect() protoreflect.Message {
method Descriptor (line 1714) | func (*StartedAt) Descriptor() ([]byte, []int) {
method GetStartedAt (line 1718) | func (x *StartedAt) GetStartedAt() int64 {
type Log_Message (line 1725) | type Log_Message struct
method Reset (line 1733) | func (x *Log_Message) Reset() {
method String (line 1740) | func (x *Log_Message) String() string {
method ProtoMessage (line 1744) | func (*Log_Message) ProtoMessage() {}
method ProtoReflect (line 1746) | func (x *Log_Message) ProtoReflect() protoreflect.Message {
method Descriptor (line 1759) | func (*Log_Message) Descriptor() ([]byte, []int) {
method GetLevel (line 1763) | func (x *Log_Message) GetLevel() LogLevel {
method GetMessage (line 1770) | func (x *Log_Message) GetMessage() string {
constant file_daemon_started_service_proto_rawDesc (line 1779) | file_daemon_started_service_proto_rawDesc = "" +
function file_daemon_started_service_proto_rawDescGZIP (line 1944) | func file_daemon_started_service_proto_rawDescGZIP() []byte {
function init (line 2049) | func init() { file_daemon_started_service_proto_init() }
function file_daemon_started_service_proto_init (line 2050) | func file_daemon_started_service_proto_init() {
FILE: daemon/started_service_grpc.pb.go
constant _ (line 15) | _ = grpc.SupportPackageIsVersion9
constant StartedService_StopService_FullMethodName (line 18) | StartedService_StopService_FullMethodName = "/daemon.StartedS...
constant StartedService_ReloadService_FullMethodName (line 19) | StartedService_ReloadService_FullMethodName = "/daemon.StartedS...
constant StartedService_SubscribeServiceStatus_FullMethodName (line 20) | StartedService_SubscribeServiceStatus_FullMethodName = "/daemon.StartedS...
constant StartedService_SubscribeLog_FullMethodName (line 21) | StartedService_SubscribeLog_FullMethodName = "/daemon.StartedS...
constant StartedService_GetDefaultLogLevel_FullMethodName (line 22) | StartedService_GetDefaultLogLevel_FullMethodName = "/daemon.StartedS...
constant StartedService_ClearLogs_FullMethodName (line 23) | StartedService_ClearLogs_FullMethodName = "/daemon.StartedS...
constant StartedService_SubscribeStatus_FullMethodName (line 24) | StartedService_SubscribeStatus_FullMethodName = "/daemon.StartedS...
constant StartedService_SubscribeGroups_FullMethodName (line 25) | StartedService_SubscribeGroups_FullMethodName = "/daemon.StartedS...
constant StartedService_GetClashModeStatus_FullMethodName (line 26) | StartedService_GetClashModeStatus_FullMethodName = "/daemon.StartedS...
constant StartedService_SubscribeClashMode_FullMethodName (line 27) | StartedService_SubscribeClashMode_FullMethodName = "/daemon.StartedS...
constant StartedService_SetClashMode_FullMethodName (line 28) | StartedService_SetClashMode_FullMethodName = "/daemon.StartedS...
constant StartedService_URLTest_FullMethodName (line 29) | StartedService_URLTest_FullMethodName = "/daemon.StartedS...
constant StartedService_SelectOutbound_FullMethodName (line 30) | StartedService_SelectOutbound_FullMethodName = "/daemon.StartedS...
constant StartedService_SetGroupExpand_FullMethodName (line 31) | StartedService_SetGroupExpand_FullMethodName = "/daemon.StartedS...
constant StartedService_GetSystemProxyStatus_FullMethodName (line 32) | StartedService_GetSystemProxyStatus_FullMethodName = "/daemon.StartedS...
constant StartedService_SetSystemProxyEnabled_FullMethodName (line 33) | StartedService_SetSystemProxyEnabled_FullMethodName = "/daemon.StartedS...
constant StartedService_SubscribeConnections_FullMethodName (line 34) | StartedService_SubscribeConnections_FullMethodName = "/daemon.StartedS...
constant StartedService_CloseConnection_FullMethodName (line 35) | StartedService_CloseConnection_FullMethodName = "/daemon.StartedS...
constant StartedService_CloseAllConnections_FullMethodName (line 36) | StartedService_CloseAllConnections_FullMethodName = "/daemon.StartedS...
constant StartedService_GetDeprecatedWarnings_FullMethodName (line 37) | StartedService_GetDeprecatedWarnings_FullMethodName = "/daemon.StartedS...
constant StartedService_GetStartedAt_FullMethodName (line 38) | StartedService_GetStartedAt_FullMethodName = "/daemon.StartedS...
type StartedServiceClient (line 44) | type StartedServiceClient interface
type startedServiceClient (line 68) | type startedServiceClient struct
method StopService (line 76) | func (c *startedServiceClient) StopService(ctx context.Context, in *em...
method ReloadService (line 86) | func (c *startedServiceClient) ReloadService(ctx context.Context, in *...
method SubscribeServiceStatus (line 96) | func (c *startedServiceClient) SubscribeServiceStatus(ctx context.Cont...
method SubscribeLog (line 115) | func (c *startedServiceClient) SubscribeLog(ctx context.Context, in *e...
method GetDefaultLogLevel (line 134) | func (c *startedServiceClient) GetDefaultLogLevel(ctx context.Context,...
method ClearLogs (line 144) | func (c *startedServiceClient) ClearLogs(ctx context.Context, in *empt...
method SubscribeStatus (line 154) | func (c *startedServiceClient) SubscribeStatus(ctx context.Context, in...
method SubscribeGroups (line 173) | func (c *startedServiceClient) SubscribeGroups(ctx context.Context, in...
method GetClashModeStatus (line 192) | func (c *startedServiceClient) GetClashModeStatus(ctx context.Context,...
method SubscribeClashMode (line 202) | func (c *startedServiceClient) SubscribeClashMode(ctx context.Context,...
method SetClashMode (line 221) | func (c *startedServiceClient) SetClashMode(ctx context.Context, in *C...
method URLTest (line 231) | func (c *startedServiceClient) URLTest(ctx context.Context, in *URLTes...
method SelectOutbound (line 241) | func (c *startedServiceClient) SelectOutbound(ctx context.Context, in ...
method SetGroupExpand (line 251) | func (c *startedServiceClient) SetGroupExpand(ctx context.Context, in ...
method GetSystemProxyStatus (line 261) | func (c *startedServiceClient) GetSystemProxyStatus(ctx context.Contex...
method SetSystemProxyEnabled (line 271) | func (c *startedServiceClient) SetSystemProxyEnabled(ctx context.Conte...
method SubscribeConnections (line 281) | func (c *startedServiceClient) SubscribeConnections(ctx context.Contex...
method CloseConnection (line 300) | func (c *startedServiceClient) CloseConnection(ctx context.Context, in...
method CloseAllConnections (line 310) | func (c *startedServiceClient) CloseAllConnections(ctx context.Context...
method GetDeprecatedWarnings (line 320) | func (c *startedServiceClient) GetDeprecatedWarnings(ctx context.Conte...
method GetStartedAt (line 330) | func (c *startedServiceClient) GetStartedAt(ctx context.Context, in *e...
function NewStartedServiceClient (line 72) | func NewStartedServiceClient(cc grpc.ClientConnInterface) StartedService...
type StartedServiceServer (line 343) | type StartedServiceServer interface
type UnimplementedStartedServiceServer (line 373) | type UnimplementedStartedServiceServer struct
method StopService (line 375) | func (UnimplementedStartedServiceServer) StopService(context.Context, ...
method ReloadService (line 379) | func (UnimplementedStartedServiceServer) ReloadService(context.Context...
method SubscribeServiceStatus (line 383) | func (UnimplementedStartedServiceServer) SubscribeServiceStatus(*empty...
method SubscribeLog (line 387) | func (UnimplementedStartedServiceServer) SubscribeLog(*emptypb.Empty, ...
method GetDefaultLogLevel (line 391) | func (UnimplementedStartedServiceServer) GetDefaultLogLevel(context.Co...
method ClearLogs (line 395) | func (UnimplementedStartedServiceServer) ClearLogs(context.Context, *e...
method SubscribeStatus (line 399) | func (UnimplementedStartedServiceServer) SubscribeStatus(*SubscribeSta...
method SubscribeGroups (line 403) | func (UnimplementedStartedServiceServer) SubscribeGroups(*emptypb.Empt...
method GetClashModeStatus (line 407) | func (UnimplementedStartedServiceServer) GetClashModeStatus(context.Co...
method SubscribeClashMode (line 411) | func (UnimplementedStartedServiceServer) SubscribeClashMode(*emptypb.E...
method SetClashMode (line 415) | func (UnimplementedStartedServiceServer) SetClashMode(context.Context,...
method URLTest (line 419) | func (UnimplementedStartedServiceServer) URLTest(context.Context, *URL...
method SelectOutbound (line 423) | func (UnimplementedStartedServiceServer) SelectOutbound(context.Contex...
method SetGroupExpand (line 427) | func (UnimplementedStartedServiceServer) SetGroupExpand(context.Contex...
method GetSystemProxyStatus (line 431) | func (UnimplementedStartedServiceServer) GetSystemProxyStatus(context....
method SetSystemProxyEnabled (line 435) | func (UnimplementedStartedServiceServer) SetSystemProxyEnabled(context...
method SubscribeConnections (line 439) | func (UnimplementedStartedServiceServer) SubscribeConnections(*Subscri...
method CloseConnection (line 443) | func (UnimplementedStartedServiceServer) CloseConnection(context.Conte...
method CloseAllConnections (line 447) | func (UnimplementedStartedServiceServer) CloseAllConnections(context.C...
method GetDeprecatedWarnings (line 451) | func (UnimplementedStartedServiceServer) GetDeprecatedWarnings(context...
method GetStartedAt (line 455) | func (UnimplementedStartedServiceServer) GetStartedAt(context.Context,...
method mustEmbedUnimplementedStartedServiceServer (line 458) | func (UnimplementedStartedServiceServer) mustEmbedUnimplementedStarted...
method testEmbeddedByValue (line 459) | func (UnimplementedStartedServiceServer) testEmbeddedByValue() ...
type UnsafeStartedServiceServer (line 464) | type UnsafeStartedServiceServer interface
function RegisterStartedServiceServer (line 468) | func RegisterStartedServiceServer(s grpc.ServiceRegistrar, srv StartedSe...
function _StartedService_StopService_Handler (line 479) | func _StartedService_StopService_Handler(srv interface{}, ctx context.Co...
function _StartedService_ReloadService_Handler (line 497) | func _StartedService_ReloadService_Handler(srv interface{}, ctx context....
function _StartedService_SubscribeServiceStatus_Handler (line 515) | func _StartedService_SubscribeServiceStatus_Handler(srv interface{}, str...
function _StartedService_SubscribeLog_Handler (line 526) | func _StartedService_SubscribeLog_Handler(srv interface{}, stream grpc.S...
function _StartedService_GetDefaultLogLevel_Handler (line 537) | func _StartedService_GetDefaultLogLevel_Handler(srv interface{}, ctx con...
function _StartedService_ClearLogs_Handler (line 555) | func _StartedService_ClearLogs_Handler(srv interface{}, ctx context.Cont...
function _StartedService_SubscribeStatus_Handler (line 573) | func _StartedService_SubscribeStatus_Handler(srv interface{}, stream grp...
function _StartedService_SubscribeGroups_Handler (line 584) | func _StartedService_SubscribeGroups_Handler(srv interface{}, stream grp...
function _StartedService_GetClashModeStatus_Handler (line 595) | func _StartedService_GetClashModeStatus_Handler(srv interface{}, ctx con...
function _StartedService_SubscribeClashMode_Handler (line 613) | func _StartedService_SubscribeClashMode_Handler(srv interface{}, stream ...
function _StartedService_SetClashMode_Handler (line 624) | func _StartedService_SetClashMode_Handler(srv interface{}, ctx context.C...
function _StartedService_URLTest_Handler (line 642) | func _StartedService_URLTest_Handler(srv interface{}, ctx context.Contex...
function _StartedService_SelectOutbound_Handler (line 660) | func _StartedService_SelectOutbound_Handler(srv interface{}, ctx context...
function _StartedService_SetGroupExpand_Handler (line 678) | func _StartedService_SetGroupExpand_Handler(srv interface{}, ctx context...
function _StartedService_GetSystemProxyStatus_Handler (line 696) | func _StartedService_GetSystemProxyStatus_Handler(srv interface{}, ctx c...
function _StartedService_SetSystemProxyEnabled_Handler (line 714) | func _StartedService_SetSystemProxyEnabled_Handler(srv interface{}, ctx ...
function _StartedService_SubscribeConnections_Handler (line 732) | func _StartedService_SubscribeConnections_Handler(srv interface{}, strea...
function _StartedService_CloseConnection_Handler (line 743) | func _StartedService_CloseConnection_Handler(srv interface{}, ctx contex...
function _StartedService_CloseAllConnections_Handler (line 761) | func _StartedService_CloseAllConnections_Handler(srv interface{}, ctx co...
function _StartedService_GetDeprecatedWarnings_Handler (line 779) | func _StartedService_GetDeprecatedWarnings_Handler(srv interface{}, ctx ...
function _StartedService_GetStartedAt_Handler (line 797) | func _StartedService_GetStartedAt_Handler(srv interface{}, ctx context.C...
FILE: debug.go
function applyDebugOptions (line 10) | func applyDebugOptions(options option.DebugOptions) error {
FILE: debug_http.go
function applyDebugListenOption (line 22) | func applyDebugListenOption(options option.DebugOptions) {
FILE: debug_stub.go
function rusageMaxRSS (line 5) | func rusageMaxRSS() float64 {
FILE: debug_unix.go
function rusageMaxRSS (line 10) | func rusageMaxRSS() float64 {
FILE: dns/client.go
type Client (line 34) | type Client struct
method Start (line 92) | func (c *Client) Start() {
method Exchange (line 112) | func (c *Client) Exchange(ctx context.Context, transport adapter.DNSTr...
method Lookup (line 318) | func (c *Client) Lookup(ctx context.Context, transport adapter.DNSTran...
method ClearCache (line 362) | func (c *Client) ClearCache() {
method storeCache (line 378) | func (c *Client) storeCache(transport adapter.DNSTransport, question d...
method lookupToExchange (line 403) | func (c *Client) lookupToExchange(ctx context.Context, transport adapt...
method questionCache (line 432) | func (c *Client) questionCache(question dns.Question, transport adapte...
method loadResponse (line 443) | func (c *Client) loadResponse(question dns.Question, transport adapter...
type ClientOptions (line 49) | type ClientOptions struct
function NewClient (line 60) | func NewClient(options ClientOptions) *Client {
type transportCacheKey (line 87) | type transportCacheKey struct
function extractNegativeTTL (line 98) | func extractNegativeTTL(response *dns.Msg) (uint32, bool) {
function sortAddresses (line 370) | func sortAddresses(response4 []netip.Addr, response6 []netip.Addr, strat...
function MessageToAddresses (line 517) | func MessageToAddresses(response *dns.Msg) []netip.Addr {
function wrapError (line 539) | func wrapError(err error) error {
type transportKey (line 551) | type transportKey struct
function contextWithTransportTag (line 553) | func contextWithTransportTag(ctx context.Context, transportTag string) c...
function transportTagFromContext (line 557) | func transportTagFromContext(ctx context.Context) (string, bool) {
function FixedResponseStatus (line 562) | func FixedResponseStatus(message *dns.Msg, rcode int) *dns.Msg {
function FixedResponse (line 576) | func FixedResponse(id uint16, question dns.Question, addresses []netip.A...
function FixedResponseCNAME (line 614) | func FixedResponseCNAME(id uint16, question dns.Question, record string,...
function FixedResponseTXT (line 640) | func FixedResponseTXT(id uint16, question dns.Question, records []string...
function FixedResponseMX (line 666) | func FixedResponseMX(id uint16, question dns.Question, records []*net.MX...
FILE: dns/client_log.go
function logCachedResponse (line 12) | func logCachedResponse(logger logger.ContextLogger, ctx context.Context,...
function logExchangedResponse (line 25) | func logExchangedResponse(logger logger.ContextLogger, ctx context.Conte...
function logRejectedResponse (line 38) | func logRejectedResponse(logger logger.ContextLogger, ctx context.Contex...
function FqdnToDomain (line 49) | func FqdnToDomain(fqdn string) string {
function FormatQuestion (line 56) | func FormatQuestion(string string) string {
FILE: dns/client_truncate.go
function TruncateDNSMessage (line 9) | func TruncateDNSMessage(request *dns.Msg, response *dns.Msg, headroom in...
FILE: dns/extension_edns0_subnet.go
function SetClientSubnet (line 9) | func SetClientSubnet(message *dns.Msg, clientSubnet netip.Prefix) *dns.M...
function setClientSubnet (line 13) | func setClientSubnet(message *dns.Msg, clientSubnet netip.Prefix, clone ...
FILE: dns/rcode.go
constant RcodeSuccess (line 8) | RcodeSuccess RcodeError = mDNS.RcodeSuccess
constant RcodeFormatError (line 9) | RcodeFormatError RcodeError = mDNS.RcodeFormatError
constant RcodeNameError (line 10) | RcodeNameError RcodeError = mDNS.RcodeNameError
constant RcodeRefused (line 11) | RcodeRefused RcodeError = mDNS.RcodeRefused
type RcodeError (line 14) | type RcodeError
method Error (line 16) | func (e RcodeError) Error() string {
FILE: dns/router.go
type Router (line 31) | type Router struct
method Initialize (line 76) | func (r *Router) Initialize(rules []option.DNSRule) error {
method Start (line 87) | func (r *Router) Start(stage adapter.StartStage) error {
method Close (line 107) | func (r *Router) Close() error {
method matchDNS (line 120) | func (r *Router) matchDNS(ctx context.Context, allowFakeIP bool, ruleI...
method Exchange (line 210) | func (r *Router) Exchange(ctx context.Context, message *mDNS.Msg, opti...
method Lookup (line 327) | func (r *Router) Lookup(ctx context.Context, domain string, options ad...
method ClearCache (line 440) | func (r *Router) ClearCache() {
method LookupReverseMapping (line 447) | func (r *Router) LookupReverseMapping(ip netip.Addr) (string, bool) {
method ResetNetwork (line 455) | func (r *Router) ResetNetwork() {
function NewRouter (line 43) | func NewRouter(ctx context.Context, logFactory log.Factory, options opti...
function isAddressQuery (line 419) | func isAddressQuery(message *mDNS.Msg) bool {
function addressLimitResponseCheck (line 428) | func addressLimitResponseCheck(rule adapter.DNSRule, metadata *adapter.I...
FILE: dns/transport/base.go
type TransportState (line 14) | type TransportState
constant StateNew (line 17) | StateNew TransportState = iota
constant StateStarted (line 18) | StateStarted
constant StateClosing (line 19) | StateClosing
constant StateClosed (line 20) | StateClosed
type BaseTransport (line 28) | type BaseTransport struct
method State (line 51) | func (t *BaseTransport) State() TransportState {
method SetStarted (line 57) | func (t *BaseTransport) SetStarted() error {
method BeginQuery (line 71) | func (t *BaseTransport) BeginQuery() bool {
method EndQuery (line 81) | func (t *BaseTransport) EndQuery() {
method CloseContext (line 93) | func (t *BaseTransport) CloseContext() context.Context {
method Shutdown (line 97) | func (t *BaseTransport) Shutdown(ctx context.Context) error {
method Close (line 141) | func (t *BaseTransport) Close() error {
function NewBaseTransport (line 40) | func NewBaseTransport(adapter dns.TransportAdapter, logger logger.Contex...
FILE: dns/transport/connector.go
type ConnectorCallbacks (line 12) | type ConnectorCallbacks struct
type Connector (line 18) | type Connector struct
function NewConnector (line 32) | func NewConnector[T any](closeCtx context.Context, dial func(context.Con...
function NewSingleflightConnector (line 40) | func NewSingleflightConnector(closeCtx context.Context, dial func(contex...
type contextKeyConnecting (line 54) | type contextKeyConnecting struct
type connectorDialResult (line 58) | type connectorDialResult struct
method Get (line 64) | func (c *Connector[T]) Get(ctx context.Context) (T, error) {
function isRecursiveConnectorDial (line 143) | func isRecursiveConnectorDial[T any](ctx context.Context, connector *Con...
method completeDial (line 148) | func (c *Connector[T]) completeDial(ctx context.Context, connecting chan...
method dialWithCancellation (line 180) | func (c *Connector[T]) dialWithCancellation(ctx context.Context) (T, con...
type valueContext (line 221) | type valueContext struct
method Value (line 226) | func (v valueContext) Value(key any) any {
method Deadline (line 230) | func (v valueContext) Deadline() (time.Time, bool) {
method Close (line 234) | func (c *Connector[T]) Close() error {
method Reset (line 255) | func (c *Connector[T]) Reset() {
type Connection (line 269) | type Connection struct
method Done (line 284) | func (c *Connection) Done() <-chan struct{} {
method IsClosed (line 288) | func (c *Connection) IsClosed() bool {
method CloseError (line 297) | func (c *Connection) CloseError() error {
method Close (line 309) | func (c *Connection) Close() error {
method CloseWithError (line 313) | func (c *Connection) CloseWithError(err error) error {
function WrapConnection (line 277) | func WrapConnection(conn net.Conn) *Connection {
FILE: dns/transport/connector_test.go
type testConnectorConnection (line 12) | type testConnectorConnection struct
function TestConnectorRecursiveGetFailsFast (line 14) | func TestConnectorRecursiveGetFailsFast(t *testing.T) {
function TestConnectorRecursiveGetAcrossConnectorsAllowed (line 50) | func TestConnectorRecursiveGetAcrossConnectorsAllowed(t *testing.T) {
function TestConnectorDialContextPreservesValueAndDeadline (line 92) | func TestConnectorDialContextPreservesValueAndDeadline(t *testing.T) {
function TestConnectorDialSkipsCanceledRequest (line 126) | func TestConnectorDialSkipsCanceledRequest(t *testing.T) {
function TestConnectorCanceledRequestDoesNotCacheConnection (line 149) | func TestConnectorCanceledRequestDoesNotCacheConnection(t *testing.T) {
function TestConnectorCanceledRequestReturnsBeforeIgnoredDialCompletes (line 200) | func TestConnectorCanceledRequestReturnsBeforeIgnoredDialCompletes(t *te...
function TestConnectorWaiterDoesNotStartNewDialBeforeCanceledDialCompletes (line 259) | func TestConnectorWaiterDoesNotStartNewDialBeforeCanceledDialCompletes(t...
function TestConnectorDialContextNotCanceledByRequestContextAfterDial (line 342) | func TestConnectorDialContextNotCanceledByRequestContextAfterDial(t *tes...
function TestConnectorDialContextCanceledOnClose (line 374) | func TestConnectorDialContextCanceledOnClose(t *testing.T) {
FILE: dns/transport/dhcp/dhcp.go
function RegisterTransport (line 36) | func RegisterTransport(registry *dns.TransportRegistry) {
type Transport (line 42) | type Transport struct
method Start (line 88) | func (t *Transport) Start(stage adapter.StartStage) error {
method Close (line 104) | func (t *Transport) Close() error {
method Reset (line 111) | func (t *Transport) Reset() {
method Exchange (line 118) | func (t *Transport) Exchange(ctx context.Context, message *mDNS.Msg) (...
method Exchange0 (line 129) | func (t *Transport) Exchange0(ctx context.Context, message *mDNS.Msg, ...
method Fetch (line 139) | func (t *Transport) Fetch() []M.Socksaddr {
method fetch (line 144) | func (t *Transport) fetch() ([]M.Socksaddr, error) {
method fetchInterface (line 168) | func (t *Transport) fetchInterface() (*control.Interface, error) {
method updateServers (line 183) | func (t *Transport) updateServers() error {
method interfaceUpdated (line 206) | func (t *Transport) interfaceUpdated(defaultInterface *control.Interfa...
method fetchServers0 (line 213) | func (t *Transport) fetchServers0(ctx context.Context, iface *control....
method fetchServersResponse (line 261) | func (t *Transport) fetchServersResponse(iface *control.Interface, pac...
method recreateServers (line 295) | func (t *Transport) recreateServers(iface *control.Interface, dhcpPack...
function NewTransport (line 59) | func NewTransport(ctx context.Context, logger log.ContextLogger, tag str...
function NewRawTransport (line 76) | func NewRawTransport(transportAdapter dns.TransportAdapter, ctx context....
FILE: dns/transport/dhcp/dhcp_shared.go
method exchangeSingleRequest (line 20) | func (t *Transport) exchangeSingleRequest(ctx context.Context, servers [...
method exchangeParallel (line 33) | func (t *Transport) exchangeParallel(ctx context.Context, servers []M.So...
method tryOneName (line 79) | func (t *Transport) tryOneName(ctx context.Context, servers []M.Socksadd...
method exchangeOne (line 98) | func (
Condensed preview — 1022 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (4,171K chars).
[
{
"path": ".fpm_openwrt",
"chars": 963,
"preview": "-s dir\n--name sing-box\n--category net\n--license GPL-3.0-or-later\n--description \"The universal proxy platform.\"\n--url \"ht"
},
{
"path": ".fpm_pacman",
"chars": 1013,
"preview": "-s dir\n--name sing-box\n--category net\n--license GPL-3.0-or-later\n--description \"The universal proxy platform.\"\n--url \"ht"
},
{
"path": ".fpm_systemd",
"chars": 1103,
"preview": "-s dir\n--name sing-box\n--category net\n--license GPL-3.0-or-later\n--description \"The universal proxy platform.\"\n--url \"ht"
},
{
"path": ".github/CRONET_GO_VERSION",
"chars": 41,
"preview": "ea7cd33752aed62603775af3df946c1b83f4b0b3\n"
},
{
"path": ".github/FUNDING.yml",
"chars": 19,
"preview": "github: nekohasekai"
},
{
"path": ".github/ISSUE_TEMPLATE/bug_report.yml",
"chars": 4024,
"preview": "name: Bug report\ndescription: \"Report sing-box bug\"\nbody:\n - type: dropdown\n attributes:\n label: Operating syst"
},
{
"path": ".github/ISSUE_TEMPLATE/bug_report_zh.yml",
"chars": 2413,
"preview": "name: 错误反馈\ndescription: \"提交 sing-box 漏洞\"\nbody:\n - type: dropdown\n attributes:\n label: 操作系统\n description: 请"
},
{
"path": ".github/build_alpine_apk.sh",
"chars": 2762,
"preview": "#!/usr/bin/env bash\n\nset -e -o pipefail\n\nARCHITECTURE=\"$1\"\nVERSION=\"$2\"\nBINARY_PATH=\"$3\"\nOUTPUT_PATH=\"$4\"\n\nif [ -z \"$ARC"
},
{
"path": ".github/build_openwrt_apk.sh",
"chars": 2738,
"preview": "#!/usr/bin/env bash\n\nset -e -o pipefail\n\nARCHITECTURE=\"$1\"\nVERSION=\"$2\"\nBINARY_PATH=\"$3\"\nOUTPUT_PATH=\"$4\"\n\nif [ -z \"$ARC"
},
{
"path": ".github/deb2ipk.sh",
"chars": 555,
"preview": "#!/usr/bin/env bash\n# mod from https://gist.github.com/pldubouilh/c5703052986bfdd404005951dee54683\n\nset -e -o pipefail\n\n"
},
{
"path": ".github/renovate.json",
"chars": 489,
"preview": "{\n \"$schema\": \"https://docs.renovatebot.com/renovate-schema.json\",\n \"commitMessagePrefix\": \"[dependencies]\",\n \"extend"
},
{
"path": ".github/setup_go_for_macos1013.sh",
"chars": 1338,
"preview": "#!/usr/bin/env bash\n\nset -euo pipefail\n\nVERSION=\"1.25.8\"\nPATCH_COMMITS=(\n \"afe69d3cec1c6dcf0f1797b20546795730850070\"\n "
},
{
"path": ".github/setup_go_for_windows7.sh",
"chars": 1687,
"preview": "#!/usr/bin/env bash\n\nset -euo pipefail\n\nVERSION=\"1.25.8\"\nPATCH_COMMITS=(\n \"466f6c7a29bc098b0d4c987b803c779222894a11\"\n "
},
{
"path": ".github/update_clients.sh",
"chars": 215,
"preview": "#!/usr/bin/env bash\n\nPROJECTS=$(dirname \"$0\")/../..\n\nfunction updateClient() {\n pushd clients/$1\n git fetch\n git rese"
},
{
"path": ".github/update_cronet.sh",
"chars": 461,
"preview": "#!/usr/bin/env bash\n\nset -e -o pipefail\n\nSCRIPT_DIR=$(dirname \"$0\")\nPROJECTS=$SCRIPT_DIR/../..\n\ngit -C $PROJECTS/cronet-"
},
{
"path": ".github/update_cronet_dev.sh",
"chars": 473,
"preview": "#!/usr/bin/env bash\n\nset -e -o pipefail\n\nSCRIPT_DIR=$(dirname \"$0\")\nPROJECTS=$SCRIPT_DIR/../..\n\ngit -C $PROJECTS/cronet-"
},
{
"path": ".github/update_dependencies.sh",
"chars": 135,
"preview": "#!/usr/bin/env bash\n\nPROJECTS=$(dirname \"$0\")/../..\ngo get -x github.com/sagernet/$1@$(git -C $PROJECTS/$1 rev-parse HEA"
},
{
"path": ".github/workflows/build.yml",
"chars": 43490,
"preview": "name: Build\n\non:\n workflow_dispatch:\n inputs:\n version:\n description: \"Version name\"\n required: t"
},
{
"path": ".github/workflows/docker.yml",
"chars": 10793,
"preview": "name: Publish Docker Images\n\non:\n #push:\n # branches:\n # - stable\n # - testing\n release:\n types:\n - "
},
{
"path": ".github/workflows/lint.yml",
"chars": 801,
"preview": "name: Lint\n\non:\n push:\n branches:\n - oldstable\n - stable\n - testing\n - unstable\n paths-ignore"
},
{
"path": ".github/workflows/linux.yml",
"chars": 10283,
"preview": "name: Build Linux Packages\n\non:\n #push:\n # branches:\n # - stable\n # - testing\n workflow_dispatch:\n inputs"
},
{
"path": ".github/workflows/stale.yml",
"chars": 462,
"preview": "name: Mark stale issues and pull requests\n\non:\n schedule:\n - cron: \"30 1 * * *\"\n\njobs:\n stale:\n runs-on: ubuntu-"
},
{
"path": ".gitignore",
"chars": 270,
"preview": "/.idea/\n/vendor/\n/*.json\n/*.srs\n/*.db\n/site/\n/bin/\n/dist/\n/sing-box\n/sing-box.exe\n/build/\n/*.jar\n/*.aar\n/*.xcframework/\n"
},
{
"path": ".gitmodules",
"chars": 222,
"preview": "[submodule \"clients/apple\"]\n\tpath = clients/apple\n\turl = https://github.com/SagerNet/sing-box-for-apple.git\n[submodule \""
},
{
"path": ".golangci.yml",
"chars": 1094,
"preview": "version: \"2\"\nrun:\n go: \"1.25\"\n build-tags:\n - with_gvisor\n - with_quic\n - with_dhcp\n - with_wireguard\n "
},
{
"path": "Dockerfile",
"chars": 1087,
"preview": "FROM --platform=$BUILDPLATFORM golang:1.25-alpine AS builder\nLABEL maintainer=\"nekohasekai <contact-git@sekai.icu>\"\nCOPY"
},
{
"path": "Dockerfile.binary",
"chars": 525,
"preview": "ARG BASE_IMAGE=alpine\nFROM ${BASE_IMAGE}\nARG TARGETARCH\nARG TARGETVARIANT\nLABEL maintainer=\"nekohasekai <contact-git@sek"
},
{
"path": "LICENSE",
"chars": 791,
"preview": "Copyright (C) 2022 by nekohasekai <contact-sagernet@sekai.icu>\n\nThis program is free software: you can redistribute it a"
},
{
"path": "Makefile",
"chars": 9430,
"preview": "NAME = sing-box\nCOMMIT = $(shell git rev-parse --short HEAD)\nTAGS ?= $(shell cat release/DEFAULT_BUILD_TAGS_OTHERS)\n\nGOH"
},
{
"path": "README.md",
"chars": 1325,
"preview": "> Sponsored by [Warp](https://go.warp.dev/sing-box), built for coding with multiple AI agents\n\n<a href=\"https://go.warp."
},
{
"path": "adapter/certificate.go",
"chars": 344,
"preview": "package adapter\n\nimport (\n\t\"context\"\n\t\"crypto/x509\"\n\n\t\"github.com/sagernet/sing/service\"\n)\n\ntype CertificateStore interf"
},
{
"path": "adapter/connections.go",
"chars": 502,
"preview": "package adapter\n\nimport (\n\t\"context\"\n\t\"net\"\n\n\tN \"github.com/sagernet/sing/common/network\"\n)\n\ntype ConnectionManager inte"
},
{
"path": "adapter/dns.go",
"chars": 2922,
"preview": "package adapter\n\nimport (\n\t\"context\"\n\t\"net/netip\"\n\n\tC \"github.com/sagernet/sing-box/constant\"\n\t\"github.com/sagernet/sing"
},
{
"path": "adapter/endpoint/adapter.go",
"chars": 984,
"preview": "package endpoint\n\nimport \"github.com/sagernet/sing-box/option\"\n\ntype Adapter struct {\n\tendpointType string\n\tendpointTag "
},
{
"path": "adapter/endpoint/manager.go",
"chars": 4369,
"preview": "package endpoint\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.com/sagern"
},
{
"path": "adapter/endpoint/registry.go",
"chars": 2300,
"preview": "package endpoint\n\nimport (\n\t\"context\"\n\t\"sync\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.com/sagernet/sing-box/lo"
},
{
"path": "adapter/endpoint.go",
"chars": 650,
"preview": "package adapter\n\nimport (\n\t\"context\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\t\"github.com/sagernet/sing-box/option\"\n)\n\ntype"
},
{
"path": "adapter/experimental.go",
"chars": 3129,
"preview": "package adapter\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/binary\"\n\t\"io\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing/common/observ"
},
{
"path": "adapter/fakeip.go",
"chars": 786,
"preview": "package adapter\n\nimport (\n\t\"net/netip\"\n\n\t\"github.com/sagernet/sing/common/logger\"\n)\n\ntype FakeIPStore interface {\n\tSimpl"
},
{
"path": "adapter/fakeip_metadata.go",
"chars": 1183,
"preview": "package adapter\n\nimport (\n\t\"bytes\"\n\t\"encoding\"\n\t\"encoding/binary\"\n\t\"io\"\n\t\"net/netip\"\n\n\t\"github.com/sagernet/sing/common\""
},
{
"path": "adapter/handler.go",
"chars": 1659,
"preview": "package adapter\n\nimport (\n\t\"context\"\n\t\"net\"\n\n\t\"github.com/sagernet/sing/common/buf\"\n\tE \"github.com/sagernet/sing/common/"
},
{
"path": "adapter/inbound/adapter.go",
"chars": 340,
"preview": "package inbound\n\ntype Adapter struct {\n\tinboundType string\n\tinboundTag string\n}\n\nfunc NewAdapter(inboundType string, in"
},
{
"path": "adapter/inbound/manager.go",
"chars": 4357,
"preview": "package inbound\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.com/sagerne"
},
{
"path": "adapter/inbound/registry.go",
"chars": 2294,
"preview": "package inbound\n\nimport (\n\t\"context\"\n\t\"sync\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.com/sagernet/sing-box/log"
},
{
"path": "adapter/inbound.go",
"chars": 3402,
"preview": "package adapter\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"net/netip\"\n\t\"time\"\n\n\tC \"github.com/sagernet/sing-box/constant\"\n\t\"github.co"
},
{
"path": "adapter/lifecycle.go",
"chars": 2107,
"preview": "package adapter\n\nimport (\n\t\"reflect\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\tE \"github.com/sagernet/sin"
},
{
"path": "adapter/lifecycle_legacy.go",
"chars": 1179,
"preview": "package adapter\n\nfunc LegacyStart(starter any, stage StartStage) error {\n\tif lifecycle, isLifecycle := starter.(Lifecycl"
},
{
"path": "adapter/neighbor.go",
"chars": 413,
"preview": "package adapter\n\nimport (\n\t\"net\"\n\t\"net/netip\"\n)\n\ntype NeighborEntry struct {\n\tAddress netip.Addr\n\tMACAddress net.Hard"
},
{
"path": "adapter/network.go",
"chars": 1424,
"preview": "package adapter\n\nimport (\n\t\"time\"\n\n\tC \"github.com/sagernet/sing-box/constant\"\n\t\"github.com/sagernet/sing-tun\"\n\t\"github.c"
},
{
"path": "adapter/outbound/adapter.go",
"chars": 989,
"preview": "package outbound\n\nimport (\n\t\"github.com/sagernet/sing-box/option\"\n)\n\ntype Adapter struct {\n\toutboundType string\n\toutboun"
},
{
"path": "adapter/outbound/manager.go",
"chars": 9615,
"preview": "package outbound\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\""
},
{
"path": "adapter/outbound/registry.go",
"chars": 2315,
"preview": "package outbound\n\nimport (\n\t\"context\"\n\t\"sync\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.com/sagernet/sing-box/lo"
},
{
"path": "adapter/outbound.go",
"chars": 1228,
"preview": "package adapter\n\nimport (\n\t\"context\"\n\t\"net/netip\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\t\"github.com/sagernet/sin"
},
{
"path": "adapter/platform.go",
"chars": 1819,
"preview": "package adapter\n\nimport (\n\t\"github.com/sagernet/sing-box/option\"\n\t\"github.com/sagernet/sing-tun\"\n\t\"github.com/sagernet/s"
},
{
"path": "adapter/prestart.go",
"chars": 16,
"preview": "package adapter\n"
},
{
"path": "adapter/router.go",
"chars": 3356,
"preview": "package adapter\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"net\"\n\t\"net/http\"\n\t\"sync\"\n\t\"time\"\n\n\tC \"github.com/sagernet/sing-box/"
},
{
"path": "adapter/rule.go",
"chars": 591,
"preview": "package adapter\n\nimport (\n\tC \"github.com/sagernet/sing-box/constant\"\n)\n\ntype HeadlessRule interface {\n\tMatch(metadata *I"
},
{
"path": "adapter/service/adapter.go",
"chars": 340,
"preview": "package service\n\ntype Adapter struct {\n\tserviceType string\n\tserviceTag string\n}\n\nfunc NewAdapter(serviceType string, se"
},
{
"path": "adapter/service/manager.go",
"chars": 4183,
"preview": "package service\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.com/sagerne"
},
{
"path": "adapter/service/registry.go",
"chars": 2186,
"preview": "package service\n\nimport (\n\t\"context\"\n\t\"sync\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.com/sagernet/sing-box/log"
},
{
"path": "adapter/service.go",
"chars": 600,
"preview": "package adapter\n\nimport (\n\t\"context\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\t\"github.com/sagernet/sing-box/option\"\n)\n\ntype"
},
{
"path": "adapter/ssm.go",
"chars": 387,
"preview": "package adapter\n\nimport (\n\t\"net\"\n\n\tN \"github.com/sagernet/sing/common/network\"\n)\n\ntype ManagedSSMServer interface {\n\tInb"
},
{
"path": "adapter/time.go",
"chars": 109,
"preview": "package adapter\n\nimport \"time\"\n\ntype TimeService interface {\n\tSimpleLifecycle\n\tTimeFunc() func() time.Time\n}\n"
},
{
"path": "adapter/upstream.go",
"chars": 5132,
"preview": "package adapter\n\nimport (\n\t\"context\"\n\t\"net\"\n\n\tM \"github.com/sagernet/sing/common/metadata\"\n\tN \"github.com/sagernet/sing/"
},
{
"path": "adapter/upstream_legacy.go",
"chars": 7018,
"preview": "package adapter\n\nimport (\n\t\"context\"\n\t\"net\"\n\n\tE \"github.com/sagernet/sing/common/exceptions\"\n\t\"github.com/sagernet/sing/"
},
{
"path": "adapter/v2ray.go",
"chars": 430,
"preview": "package adapter\n\nimport (\n\t\"context\"\n\t\"net\"\n\n\tN \"github.com/sagernet/sing/common/network\"\n)\n\ntype V2RayServerTransport i"
},
{
"path": "box.go",
"chars": 18306,
"preview": "package box\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"runtime/debug\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\""
},
{
"path": "cmd/internal/app_store_connect/main.go",
"chars": 13764,
"preview": "package main\n\nimport (\n\t\"context\"\n\t\"net/http\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/sagernet/asc-go/asc\"\n\t\"g"
},
{
"path": "cmd/internal/build/main.go",
"chars": 439,
"preview": "package main\n\nimport (\n\t\"go/build\"\n\t\"os\"\n\t\"os/exec\"\n\n\t\"github.com/sagernet/sing-box/cmd/internal/build_shared\"\n\t\"github."
},
{
"path": "cmd/internal/build_libbox/main.go",
"chars": 6289,
"preview": "package main\n\nimport (\n\t\"flag\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"strconv\"\n\t\"strings\"\n\n\t_ \"github.com/sagernet/gomobile"
},
{
"path": "cmd/internal/build_shared/sdk.go",
"chars": 2774,
"preview": "package build_shared\n\nimport (\n\t\"go/build\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com"
},
{
"path": "cmd/internal/build_shared/tag.go",
"chars": 1260,
"preview": "package build_shared\n\nimport (\n\t\"github.com/sagernet/sing-box/common/badversion\"\n\t\"github.com/sagernet/sing/common\"\n\t\"gi"
},
{
"path": "cmd/internal/format_docs/main.go",
"chars": 2667,
"preview": "package main\n\nimport (\n\t\"bytes\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/sagernet/sing-box/log\"\n)\n\nfunc main() {\n"
},
{
"path": "cmd/internal/protogen/main.go",
"chars": 4966,
"preview": "package main\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"go/build\"\n\t\"io\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"strings"
},
{
"path": "cmd/internal/read_tag/main.go",
"chars": 1375,
"preview": "package main\n\nimport (\n\t\"flag\"\n\t\"os\"\n\n\t\"github.com/sagernet/sing-box/cmd/internal/build_shared\"\n\t\"github.com/sagernet/si"
},
{
"path": "cmd/internal/tun_bench/main.go",
"chars": 6881,
"preview": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/netip\"\n\t\"os\"\n\t\"os/exec\"\n\t\"strings\"\n\t\"syscall\"\n\t\"time\"\n\n\tC \"github.c"
},
{
"path": "cmd/internal/update_android_version/main.go",
"chars": 2158,
"preview": "package main\n\nimport (\n\t\"flag\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/sagernet/sing-box/c"
},
{
"path": "cmd/internal/update_apple_version/main.go",
"chars": 5178,
"preview": "package main\n\nimport (\n\t\"flag\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"strings\"\n\n\t\"github.com/sagernet/sing-box/cmd/internal/"
},
{
"path": "cmd/internal/update_certificates/main.go",
"chars": 4055,
"preview": "package main\n\nimport (\n\t\"encoding/csv\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\n\t\"golang"
},
{
"path": "cmd/sing-box/cmd.go",
"chars": 2202,
"preview": "package main\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"os/user\"\n\t\"strconv\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/experimental/depre"
},
{
"path": "cmd/sing-box/cmd_check.go",
"chars": 684,
"preview": "package main\n\nimport (\n\t\"context\"\n\n\t\"github.com/sagernet/sing-box\"\n\t\"github.com/sagernet/sing-box/log\"\n\n\t\"github.com/spf"
},
{
"path": "cmd/sing-box/cmd_format.go",
"chars": 1733,
"preview": "package main\n\nimport (\n\t\"bytes\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\tE \"github.com/sagernet/sing"
},
{
"path": "cmd/sing-box/cmd_generate.go",
"chars": 1820,
"preview": "package main\n\nimport (\n\t\"crypto/rand\"\n\t\"encoding/base64\"\n\t\"encoding/hex\"\n\t\"os\"\n\t\"strconv\"\n\n\t\"github.com/sagernet/sing-bo"
},
{
"path": "cmd/sing-box/cmd_generate_ech.go",
"chars": 722,
"preview": "package main\n\nimport (\n\t\"os\"\n\n\t\"github.com/sagernet/sing-box/common/tls\"\n\t\"github.com/sagernet/sing-box/log\"\n\n\t\"github.c"
},
{
"path": "cmd/sing-box/cmd_generate_tls.go",
"chars": 1005,
"preview": "package main\n\nimport (\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/common/tls\"\n\t\"github.com/sagernet/sing-box/log\"\n\n\t\""
},
{
"path": "cmd/sing-box/cmd_generate_vapid.go",
"chars": 860,
"preview": "//go:build go1.20\n\npackage main\n\nimport (\n\t\"crypto/ecdh\"\n\t\"crypto/rand\"\n\t\"encoding/base64\"\n\t\"os\"\n\n\t\"github.com/sagernet/"
},
{
"path": "cmd/sing-box/cmd_generate_wireguard.go",
"chars": 1469,
"preview": "package main\n\nimport (\n\t\"encoding/base64\"\n\t\"os\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\n\t\"github.com/spf13/cobra\"\n\t\"golang"
},
{
"path": "cmd/sing-box/cmd_geoip.go",
"chars": 940,
"preview": "package main\n\nimport (\n\t\"github.com/sagernet/sing-box/log\"\n\tE \"github.com/sagernet/sing/common/exceptions\"\n\n\t\"github.com"
},
{
"path": "cmd/sing-box/cmd_geoip_export.go",
"chars": 2478,
"preview": "package main\n\nimport (\n\t\"io\"\n\t\"net\"\n\t\"os\"\n\t\"strings\"\n\n\tC \"github.com/sagernet/sing-box/constant\"\n\t\"github.com/sagernet/s"
},
{
"path": "cmd/sing-box/cmd_geoip_list.go",
"chars": 497,
"preview": "package main\n\nimport (\n\t\"os\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\n\t\"github.com/spf13/cobra\"\n)\n\nvar commandGeoipList = &"
},
{
"path": "cmd/sing-box/cmd_geoip_lookup.go",
"chars": 960,
"preview": "package main\n\nimport (\n\t\"net/netip\"\n\t\"os\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\tE \"github.com/sagernet/sing/common/excep"
},
{
"path": "cmd/sing-box/cmd_geosite.go",
"chars": 902,
"preview": "package main\n\nimport (\n\t\"github.com/sagernet/sing-box/common/geosite\"\n\t\"github.com/sagernet/sing-box/log\"\n\tE \"github.com"
},
{
"path": "cmd/sing-box/cmd_geosite_export.go",
"chars": 2128,
"preview": "package main\n\nimport (\n\t\"io\"\n\t\"os\"\n\n\t\"github.com/sagernet/sing-box/common/geosite\"\n\tC \"github.com/sagernet/sing-box/cons"
},
{
"path": "cmd/sing-box/cmd_geosite_list.go",
"chars": 1016,
"preview": "package main\n\nimport (\n\t\"os\"\n\t\"sort\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\tF \"github.com/sagernet/sing/common/format\"\n\n\t"
},
{
"path": "cmd/sing-box/cmd_geosite_lookup.go",
"chars": 2084,
"preview": "package main\n\nimport (\n\t\"os\"\n\t\"sort\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\tE \"github.com/sagernet/sing/common/exceptions"
},
{
"path": "cmd/sing-box/cmd_geosite_matcher.go",
"chars": 1220,
"preview": "package main\n\nimport (\n\t\"regexp\"\n\t\"strings\"\n\n\t\"github.com/sagernet/sing-box/common/geosite\"\n)\n\ntype searchGeositeMatcher"
},
{
"path": "cmd/sing-box/cmd_merge.go",
"chars": 3876,
"preview": "package main\n\nimport (\n\t\"bytes\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\tC \"github.com/sagernet/sing-box/constant\"\n\t\"github.c"
},
{
"path": "cmd/sing-box/cmd_rule_set.go",
"chars": 196,
"preview": "package main\n\nimport (\n\t\"github.com/spf13/cobra\"\n)\n\nvar commandRuleSet = &cobra.Command{\n\tUse: \"rule-set\",\n\tShort: \"Ma"
},
{
"path": "cmd/sing-box/cmd_rule_set_compile.go",
"chars": 2538,
"preview": "package main\n\nimport (\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/sagernet/sing-box/common/srs\"\n\tC \"github.com/sagernet/sing-b"
},
{
"path": "cmd/sing-box/cmd_rule_set_convert.go",
"chars": 2140,
"preview": "package main\n\nimport (\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/sagernet/sing-box/common/convertor/adguard\"\n\t\"github.com/sag"
},
{
"path": "cmd/sing-box/cmd_rule_set_decompile.go",
"chars": 2354,
"preview": "package main\n\nimport (\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/sagernet/sing-box/common/srs\"\n\tC \"github.com/sagernet/sing-b"
},
{
"path": "cmd/sing-box/cmd_rule_set_format.go",
"chars": 1853,
"preview": "package main\n\nimport (\n\t\"bytes\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\t\"github.com/sagernet/"
},
{
"path": "cmd/sing-box/cmd_rule_set_match.go",
"chars": 2674,
"preview": "package main\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"githu"
},
{
"path": "cmd/sing-box/cmd_rule_set_merge.go",
"chars": 4185,
"preview": "package main\n\nimport (\n\t\"bytes\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"sort\"\n\t\"strings\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\t\"g"
},
{
"path": "cmd/sing-box/cmd_rule_set_upgrade.go",
"chars": 2190,
"preview": "package main\n\nimport (\n\t\"bytes\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\n\tC \"github.com/sagernet/sing-box/constant\"\n\t\"github.com/sa"
},
{
"path": "cmd/sing-box/cmd_run.go",
"chars": 4783,
"preview": "package main\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"os\"\n\t\"os/signal\"\n\t\"path/filepath\"\n\truntimeDebug \"runtime/debug\"\n\t\"sort\"\n\t\"stri"
},
{
"path": "cmd/sing-box/cmd_tools.go",
"chars": 1357,
"preview": "package main\n\nimport (\n\t\"errors\"\n\t\"os\"\n\n\t\"github.com/sagernet/sing-box\"\n\tE \"github.com/sagernet/sing/common/exceptions\"\n"
},
{
"path": "cmd/sing-box/cmd_tools_connect.go",
"chars": 1791,
"preview": "package main\n\nimport (\n\t\"context\"\n\t\"os\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\t\"github.com/sagernet/sing/common\"\n\t\"github"
},
{
"path": "cmd/sing-box/cmd_tools_fetch.go",
"chars": 2375,
"preview": "package main\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"os\"\n\n\tC \"github.com/sagernet/sing-box/"
},
{
"path": "cmd/sing-box/cmd_tools_fetch_http3.go",
"chars": 935,
"preview": "//go:build with_quic\n\npackage main\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"net/http\"\n\n\t\"github.com/sagernet/quic-go\"\n\t\"gith"
},
{
"path": "cmd/sing-box/cmd_tools_fetch_http3_stub.go",
"chars": 250,
"preview": "//go:build !with_quic\n\npackage main\n\nimport (\n\t\"net/url\"\n\t\"os\"\n\n\tbox \"github.com/sagernet/sing-box\"\n)\n\nfunc initializeHT"
},
{
"path": "cmd/sing-box/cmd_tools_synctime.go",
"chars": 1718,
"preview": "package main\n\nimport (\n\t\"context\"\n\t\"os\"\n\n\tC \"github.com/sagernet/sing-box/constant\"\n\t\"github.com/sagernet/sing-box/log\"\n"
},
{
"path": "cmd/sing-box/cmd_version.go",
"chars": 1252,
"preview": "package main\n\nimport (\n\t\"os\"\n\t\"runtime\"\n\t\"runtime/debug\"\n\n\tC \"github.com/sagernet/sing-box/constant\"\n\n\t\"github.com/spf13"
},
{
"path": "cmd/sing-box/generate_completions.go",
"chars": 573,
"preview": "//go:build generate && generate_completions\n\npackage main\n\nimport \"github.com/sagernet/sing-box/log\"\n\nfunc main() {\n\terr"
},
{
"path": "cmd/sing-box/main.go",
"chars": 162,
"preview": "//go:build !generate\n\npackage main\n\nimport \"github.com/sagernet/sing-box/log\"\n\nfunc main() {\n\tif err := mainCommand.Exec"
},
{
"path": "common/badtls/raw_conn.go",
"chars": 5218,
"preview": "//go:build go1.25 && badlinkname\n\npackage badtls\n\nimport (\n\t\"bytes\"\n\t\"os\"\n\t\"reflect\"\n\t\"sync/atomic\"\n\t\"unsafe\"\n\n\tE \"githu"
},
{
"path": "common/badtls/raw_half_conn.go",
"chars": 4200,
"preview": "//go:build go1.25 && badlinkname\n\npackage badtls\n\nimport (\n\t\"hash\"\n\t\"reflect\"\n\t\"sync\"\n\t\"unsafe\"\n\n\tE \"github.com/sagernet"
},
{
"path": "common/badtls/read_wait.go",
"chars": 1768,
"preview": "//go:build go1.25 && badlinkname\n\npackage badtls\n\nimport (\n\t\"github.com/sagernet/sing/common/buf\"\n\tN \"github.com/sagerne"
},
{
"path": "common/badtls/read_wait_stub.go",
"chars": 195,
"preview": "//go:build !go1.25 || !badlinkname\n\npackage badtls\n\nimport (\n\t\"os\"\n\n\t\"github.com/sagernet/sing/common/tls\"\n)\n\nfunc NewRe"
},
{
"path": "common/badtls/registry.go",
"chars": 2219,
"preview": "//go:build go1.25 && badlinkname\n\npackage badtls\n\nimport (\n\t\"crypto/tls\"\n\t\"net\"\n\t\"unsafe\"\n)\n\ntype Methods struct {\n\tread"
},
{
"path": "common/badtls/registry_utls.go",
"chars": 1989,
"preview": "//go:build go1.25 && badlinkname\n\npackage badtls\n\nimport (\n\t\"net\"\n\t\"unsafe\"\n\n\tN \"github.com/sagernet/sing/common/network"
},
{
"path": "common/badversion/version.go",
"chars": 4215,
"preview": "package badversion\n\nimport (\n\t\"strconv\"\n\t\"strings\"\n\n\tF \"github.com/sagernet/sing/common/format\"\n\n\t\"golang.org/x/mod/semv"
},
{
"path": "common/badversion/version_json.go",
"chars": 332,
"preview": "package badversion\n\nimport \"github.com/sagernet/sing/common/json\"\n\nfunc (v Version) MarshalJSON() ([]byte, error) {\n\tret"
},
{
"path": "common/badversion/version_test.go",
"chars": 596,
"preview": "package badversion\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestCompareVersion(t *testing.T)"
},
{
"path": "common/certificate/chrome.go",
"chars": 170799,
"preview": "// Code generated by 'make update_certificates'. DO NOT EDIT.\n\npackage certificate\n\nimport \"crypto/x509\"\n\nvar chromeIncl"
},
{
"path": "common/certificate/mozilla.go",
"chars": 271452,
"preview": "// Code generated by 'make update_certificates'. DO NOT EDIT.\n\npackage certificate\n\nimport \"crypto/x509\"\n\nvar mozillaInc"
},
{
"path": "common/certificate/store.go",
"chars": 4782,
"preview": "package certificate\n\nimport (\n\t\"context\"\n\t\"crypto/x509\"\n\t\"io/fs\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com"
},
{
"path": "common/compatible/map.go",
"chars": 982,
"preview": "package compatible\n\nimport \"sync\"\n\n// Map is a generics sync.Map\ntype Map[K comparable, V any] struct {\n\tm sync.Map\n}\n\nf"
},
{
"path": "common/convertor/adguard/convertor.go",
"chars": 14015,
"preview": "package adguard\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"io\"\n\t\"net/netip\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\n\tC \"github.com/sagernet/sing"
},
{
"path": "common/convertor/adguard/convertor_test.go",
"chars": 3234,
"preview": "package adguard\n\nimport (\n\t\"context\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.com/sagerne"
},
{
"path": "common/dialer/default.go",
"chars": 14224,
"preview": "package dialer\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"net\"\n\t\"net/netip\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/ada"
},
{
"path": "common/dialer/default_parallel_interface.go",
"chars": 8815,
"preview": "package dialer\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\tC \"github.com/sagernet/sing"
},
{
"path": "common/dialer/default_parallel_network.go",
"chars": 5487,
"preview": "package dialer\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"net/netip\"\n\t\"time\"\n\n\tC \"github.com/sagernet/sing-box/constant\"\n\t\"github.com"
},
{
"path": "common/dialer/detour.go",
"chars": 1996,
"preview": "package dialer\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"sync\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.com/sagernet/sing/c"
},
{
"path": "common/dialer/dialer.go",
"chars": 5961,
"preview": "package dialer\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"net/netip\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\tC \"github.com/"
},
{
"path": "common/dialer/resolve.go",
"chars": 6091,
"preview": "package dialer\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\tC \"github.com/sager"
},
{
"path": "common/dialer/router.go",
"chars": 901,
"preview": "package dialer\n\nimport (\n\t\"context\"\n\t\"net\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\tM \"github.com/sagernet/sing/common/"
},
{
"path": "common/dialer/tfo.go",
"chars": 3613,
"preview": "package dialer\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"net\"\n\t\"os\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing/common"
},
{
"path": "common/dialer/wireguard.go",
"chars": 141,
"preview": "package dialer\n\nimport (\n\t\"github.com/sagernet/sing/common/control\"\n)\n\ntype WireGuardListener interface {\n\tWireGuardCont"
},
{
"path": "common/geoip/reader.go",
"chars": 789,
"preview": "package geoip\n\nimport (\n\t\"net/netip\"\n\n\tE \"github.com/sagernet/sing/common/exceptions\"\n\n\t\"github.com/oschwald/maxminddb-g"
},
{
"path": "common/geosite/compat_test.go",
"chars": 6397,
"preview": "package geosite\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/sagernet/sing/common/"
},
{
"path": "common/geosite/geosite_test.go",
"chars": 699,
"preview": "package geosite_test\n\nimport (\n\t\"bytes\"\n\t\"testing\"\n\n\t\"github.com/sagernet/sing-box/common/geosite\"\n\n\t\"github.com/stretch"
},
{
"path": "common/geosite/reader.go",
"chars": 3244,
"preview": "package geosite\n\nimport (\n\t\"bufio\"\n\t\"encoding/binary\"\n\t\"io\"\n\t\"os\"\n\t\"sync\"\n\t\"sync/atomic\"\n\n\tE \"github.com/sagernet/sing/c"
},
{
"path": "common/geosite/rule.go",
"chars": 2763,
"preview": "package geosite\n\nimport \"github.com/sagernet/sing-box/option\"\n\ntype ItemType = uint8\n\nconst (\n\tRuleTypeDomain ItemType ="
},
{
"path": "common/geosite/writer.go",
"chars": 1358,
"preview": "package geosite\n\nimport (\n\t\"bytes\"\n\t\"sort\"\n\n\t\"github.com/sagernet/sing/common/varbin\"\n)\n\nfunc Write(writer varbin.Writer"
},
{
"path": "common/interrupt/conn.go",
"chars": 1289,
"preview": "package interrupt\n\nimport (\n\t\"net\"\n\n\t\"github.com/sagernet/sing/common/x/list\"\n)\n\n/*type GroupedConn interface {\n\tMarkAsI"
},
{
"path": "common/interrupt/context.go",
"chars": 359,
"preview": "package interrupt\n\nimport \"context\"\n\ntype contextKeyIsExternalConnection struct{}\n\nfunc ContextWithIsExternalConnection("
},
{
"path": "common/interrupt/group.go",
"chars": 1232,
"preview": "package interrupt\n\nimport (\n\t\"io\"\n\t\"net\"\n\t\"sync\"\n\n\t\"github.com/sagernet/sing/common/x/list\"\n)\n\ntype Group struct {\n\tacce"
},
{
"path": "common/ja3/LICENSE",
"chars": 1515,
"preview": "BSD 3-Clause License\n\nCopyright (c) 2018, Open Systems AG\nAll rights reserved.\n\nRedistribution and use in source and bin"
},
{
"path": "common/ja3/README.md",
"chars": 47,
"preview": "# JA3\n\nmod from: https://github.com/open-ch/ja3"
},
{
"path": "common/ja3/error.go",
"chars": 809,
"preview": "// Copyright (c) 2018, Open Systems AG. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style li"
},
{
"path": "common/ja3/ja3.go",
"chars": 1938,
"preview": "// Copyright (c) 2018, Open Systems AG. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style li"
},
{
"path": "common/ja3/parser.go",
"chars": 10722,
"preview": "// Copyright (c) 2018, Open Systems AG. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style li"
},
{
"path": "common/ktls/ktls.go",
"chars": 3091,
"preview": "//go:build linux && go1.25 && badlinkname\n\npackage ktls\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/tls\"\n\t\"errors\"\n\t\"io\"\n\t\"ne"
},
{
"path": "common/ktls/ktls_alert.go",
"chars": 2389,
"preview": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
},
{
"path": "common/ktls/ktls_cipher_suites_linux.go",
"chars": 10804,
"preview": "// Copyright 2010 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
},
{
"path": "common/ktls/ktls_close.go",
"chars": 1682,
"preview": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
},
{
"path": "common/ktls/ktls_const.go",
"chars": 965,
"preview": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
},
{
"path": "common/ktls/ktls_handshake_messages.go",
"chars": 6728,
"preview": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
},
{
"path": "common/ktls/ktls_key_update.go",
"chars": 5162,
"preview": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
},
{
"path": "common/ktls/ktls_linux.go",
"chars": 8784,
"preview": "//go:build linux && go1.25 && badlinkname\n\npackage ktls\n\nimport (\n\t\"crypto/tls\"\n\t\"errors\"\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n\t\"sync\""
},
{
"path": "common/ktls/ktls_prf.go",
"chars": 1108,
"preview": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
},
{
"path": "common/ktls/ktls_read.go",
"chars": 9946,
"preview": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
},
{
"path": "common/ktls/ktls_read_wait.go",
"chars": 1014,
"preview": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
},
{
"path": "common/ktls/ktls_stub_nolinkname.go",
"chars": 469,
"preview": "//go:build linux && go1.25 && !badlinkname\n\npackage ktls\n\nimport (\n\t\"context\"\n\n\tE \"github.com/sagernet/sing/common/excep"
},
{
"path": "common/ktls/ktls_stub_nonlinux.go",
"chars": 374,
"preview": "//go:build !linux\n\npackage ktls\n\nimport (\n\t\"context\"\n\n\tE \"github.com/sagernet/sing/common/exceptions\"\n\t\"github.com/sager"
},
{
"path": "common/ktls/ktls_stub_oldgo.go",
"chars": 413,
"preview": "//go:build linux && !go1.25\n\npackage ktls\n\nimport (\n\t\"context\"\n\n\tE \"github.com/sagernet/sing/common/exceptions\"\n\t\"github"
},
{
"path": "common/ktls/ktls_write.go",
"chars": 4195,
"preview": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
},
{
"path": "common/listener/listener.go",
"chars": 4817,
"preview": "package listener\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"net/netip\"\n\t\"runtime\"\n\t\"strings\"\n\t\"sync/atomic\"\n\n\t\"github.com/sagernet/si"
},
{
"path": "common/listener/listener_tcp.go",
"chars": 3683,
"preview": "package listener\n\nimport (\n\t\"net\"\n\t\"net/netip\"\n\t\"strings\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\""
},
{
"path": "common/listener/listener_udp.go",
"chars": 6372,
"preview": "package listener\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"net/netip\"\n\t\"os\"\n\t\"strings\"\n\t\"syscall\"\n\n\t\"github.com/sagernet/sing-box/ad"
},
{
"path": "common/mux/client.go",
"chars": 1832,
"preview": "package mux\n\nimport (\n\t\"context\"\n\t\"net\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\tC \"github.com/sagernet/sing-box/consta"
},
{
"path": "common/mux/router.go",
"chars": 2805,
"preview": "package mux\n\nimport (\n\t\"context\"\n\t\"net\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\tC \"github.com/sagernet/sing-box/consta"
},
{
"path": "common/pipelistener/listener.go",
"chars": 806,
"preview": "package pipelistener\n\nimport (\n\t\"io\"\n\t\"net\"\n)\n\nvar _ net.Listener = (*Listener)(nil)\n\ntype Listener struct {\n\tpipe chan "
},
{
"path": "common/process/searcher.go",
"chars": 1009,
"preview": "package process\n\nimport (\n\t\"context\"\n\t\"net/netip\"\n\t\"os/user\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.com/sager"
},
{
"path": "common/process/searcher_android.go",
"chars": 1083,
"preview": "package process\n\nimport (\n\t\"context\"\n\t\"net/netip\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.com/sagernet/sing-tu"
},
{
"path": "common/process/searcher_darwin.go",
"chars": 3624,
"preview": "package process\n\nimport (\n\t\"context\"\n\t\"encoding/binary\"\n\t\"net/netip\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\t\"syscall\"\n\t\"unsafe\"\n\n\t"
},
{
"path": "common/process/searcher_linux.go",
"chars": 870,
"preview": "//go:build linux && !android\n\npackage process\n\nimport (\n\t\"context\"\n\t\"net/netip\"\n\n\t\"github.com/sagernet/sing-box/adapter\""
},
{
"path": "common/process/searcher_linux_shared.go",
"chars": 4605,
"preview": "//go:build linux\n\npackage process\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/netip\"\n\t\"os\"\n\t\"path\"\n\t\"strin"
},
{
"path": "common/process/searcher_stub.go",
"chars": 153,
"preview": "//go:build !linux && !windows && !darwin\n\npackage process\n\nimport (\n\t\"os\"\n)\n\nfunc NewSearcher(_ Config) (Searcher, error"
},
{
"path": "common/process/searcher_windows.go",
"chars": 1554,
"preview": "package process\n\nimport (\n\t\"context\"\n\t\"net/netip\"\n\t\"syscall\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\tE \"github.com/sag"
},
{
"path": "common/redir/redir_darwin.go",
"chars": 1642,
"preview": "package redir\n\nimport (\n\t\"net\"\n\t\"net/netip\"\n\t\"syscall\"\n\t\"unsafe\"\n\n\tM \"github.com/sagernet/sing/common/metadata\"\n)\n\nconst"
},
{
"path": "common/redir/redir_linux.go",
"chars": 1146,
"preview": "package redir\n\nimport (\n\t\"encoding/binary\"\n\t\"net\"\n\t\"net/netip\"\n\t\"os\"\n\t\"syscall\"\n\n\t\"github.com/sagernet/sing/common\"\n\t\"gi"
},
{
"path": "common/redir/redir_other.go",
"chars": 210,
"preview": "//go:build !linux && !darwin\n\npackage redir\n\nimport (\n\t\"net\"\n\t\"net/netip\"\n\t\"os\"\n)\n\nfunc GetOriginalDestination(conn net."
},
{
"path": "common/redir/tproxy_linux.go",
"chars": 1953,
"preview": "package redir\n\nimport (\n\t\"encoding/binary\"\n\t\"net/netip\"\n\t\"syscall\"\n\n\t\"github.com/sagernet/sing/common/control\"\n\tE \"githu"
},
{
"path": "common/redir/tproxy_other.go",
"chars": 359,
"preview": "//go:build !linux\n\npackage redir\n\nimport (\n\t\"net/netip\"\n\t\"os\"\n\n\t\"github.com/sagernet/sing/common/control\"\n)\n\nfunc TProxy"
},
{
"path": "common/settings/proxy_android.go",
"chars": 1746,
"preview": "package settings\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"strings\"\n\n\tC \"github.com/sagernet/sing-box/constant\"\n\tE \"github.com/sagern"
},
{
"path": "common/settings/proxy_darwin.go",
"chars": 3582,
"preview": "package settings\n\nimport (\n\t\"context\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.com/sagern"
},
{
"path": "common/settings/proxy_linux.go",
"chars": 4558,
"preview": "//go:build linux && !android\n\npackage settings\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"os/exec\"\n\t\"strings\"\n\n\t\"github.com/sagernet/s"
},
{
"path": "common/settings/proxy_stub.go",
"chars": 272,
"preview": "//go:build !(windows || linux || darwin)\n\npackage settings\n\nimport (\n\t\"context\"\n\t\"os\"\n\n\tM \"github.com/sagernet/sing/comm"
},
{
"path": "common/settings/proxy_windows.go",
"chars": 847,
"preview": "package settings\n\nimport (\n\t\"context\"\n\n\tM \"github.com/sagernet/sing/common/metadata\"\n\t\"github.com/sagernet/sing/common/w"
},
{
"path": "common/settings/system_proxy.go",
"chars": 100,
"preview": "package settings\n\ntype SystemProxy interface {\n\tIsEnabled() bool\n\tEnable() error\n\tDisable() error\n}\n"
},
{
"path": "common/settings/wifi.go",
"chars": 161,
"preview": "package settings\n\nimport \"github.com/sagernet/sing-box/adapter\"\n\ntype WIFIMonitor interface {\n\tReadWIFIState() adapter.W"
},
{
"path": "common/settings/wifi_linux.go",
"chars": 1013,
"preview": "package settings\n\nimport (\n\t\"github.com/sagernet/sing-box/adapter\"\n\tE \"github.com/sagernet/sing/common/exceptions\"\n)\n\nty"
},
{
"path": "common/settings/wifi_linux_connman.go",
"chars": 3745,
"preview": "//go:build linux\n\npackage settings\n\nimport (\n\t\"context\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\n\t\"g"
},
{
"path": "common/settings/wifi_linux_iwd.go",
"chars": 4355,
"preview": "//go:build linux\n\npackage settings\n\nimport (\n\t\"context\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\n\t\"g"
},
{
"path": "common/settings/wifi_linux_nm.go",
"chars": 4618,
"preview": "//go:build linux\n\npackage settings\n\nimport (\n\t\"context\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\n\t\"g"
},
{
"path": "common/settings/wifi_linux_wpa.go",
"chars": 5515,
"preview": "package settings\n\nimport (\n\t\"bufio\"\n\t\"context\"\n\t\"fmt\"\n\t\"net\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\""
},
{
"path": "common/settings/wifi_stub.go",
"chars": 452,
"preview": "//go:build !linux && !windows\n\npackage settings\n\nimport (\n\t\"os\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n)\n\ntype stubWIF"
},
{
"path": "common/settings/wifi_windows.go",
"chars": 3083,
"preview": "//go:build windows\n\npackage settings\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"strings\"\n\t\"sync\"\n\t\"syscall\"\n\n\t\"github.com/sagernet/si"
}
]
// ... and 822 more files (download for full content)
About this extraction
This page contains the full source code of the SagerNet/sing-box GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1022 files (3.6 MB), approximately 999.9k tokens, and a symbol index with 5675 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.