Showing preview only (5,622K chars total). Download the full file or copy to clipboard to get everything.
Repository: reF1nd/sing-box
Branch: testing
Commit: 6b07a229185d
Files: 1205
Total size: 5.1 MB
Directory structure:
gitextract_yza4ly9v/
├── .fpm_openwrt
├── .fpm_pacman
├── .fpm_systemd
├── .github/
│ ├── CRONET_GO_VERSION
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.yml
│ │ └── bug_report_zh.yml
│ ├── build_alpine_apk.sh
│ ├── build_openwrt_apk.sh
│ ├── deb2ipk.sh
│ ├── detect_track.sh
│ ├── renovate.json
│ ├── setup_go_for_macos1013.sh
│ ├── setup_go_for_windows7.sh
│ ├── update_clients.sh
│ ├── update_cronet.sh
│ ├── update_cronet_dev.sh
│ ├── update_dependencies.sh
│ └── workflows/
│ ├── build.yml
│ ├── docker.yml
│ ├── lint.yml
│ ├── linux.yml
│ ├── stale.yml
│ └── test.yml
├── .gitignore
├── .gitmodules
├── .golangci.yml
├── Dockerfile
├── Dockerfile.binary
├── LICENSE
├── Makefile
├── README.md
├── adapter/
│ ├── certificate/
│ │ ├── adapter.go
│ │ ├── manager.go
│ │ └── registry.go
│ ├── certificate.go
│ ├── certificate_darwin.go
│ ├── certificate_provider.go
│ ├── connections.go
│ ├── dns.go
│ ├── endpoint/
│ │ ├── adapter.go
│ │ ├── manager.go
│ │ └── registry.go
│ ├── endpoint.go
│ ├── experimental.go
│ ├── fakeip.go
│ ├── fakeip_metadata.go
│ ├── handler.go
│ ├── http.go
│ ├── inbound/
│ │ ├── adapter.go
│ │ ├── manager.go
│ │ └── registry.go
│ ├── inbound.go
│ ├── inbound_test.go
│ ├── lifecycle.go
│ ├── lifecycle_legacy.go
│ ├── neighbor.go
│ ├── network.go
│ ├── outbound/
│ │ ├── adapter.go
│ │ ├── manager.go
│ │ └── registry.go
│ ├── outbound.go
│ ├── platform.go
│ ├── prestart.go
│ ├── router.go
│ ├── rule.go
│ ├── service/
│ │ ├── adapter.go
│ │ ├── manager.go
│ │ └── registry.go
│ ├── service.go
│ ├── ssm.go
│ ├── tailscale.go
│ ├── time.go
│ ├── upstream.go
│ ├── upstream_legacy.go
│ └── v2ray.go
├── box.go
├── cmd/
│ ├── internal/
│ │ ├── app_store_connect/
│ │ │ └── main.go
│ │ ├── build/
│ │ │ └── main.go
│ │ ├── build_libbox/
│ │ │ └── main.go
│ │ ├── build_shared/
│ │ │ ├── sdk.go
│ │ │ └── tag.go
│ │ ├── format_docs/
│ │ │ └── main.go
│ │ ├── protogen/
│ │ │ └── main.go
│ │ ├── read_tag/
│ │ │ └── main.go
│ │ ├── tun_bench/
│ │ │ └── main.go
│ │ ├── update_android_version/
│ │ │ └── main.go
│ │ ├── update_apple_version/
│ │ │ └── main.go
│ │ └── update_certificates/
│ │ └── main.go
│ └── sing-box/
│ ├── cmd.go
│ ├── cmd_check.go
│ ├── cmd_format.go
│ ├── cmd_generate.go
│ ├── cmd_generate_ech.go
│ ├── cmd_generate_tls.go
│ ├── cmd_generate_vapid.go
│ ├── cmd_generate_wireguard.go
│ ├── cmd_geoip.go
│ ├── cmd_geoip_export.go
│ ├── cmd_geoip_list.go
│ ├── cmd_geoip_lookup.go
│ ├── cmd_geosite.go
│ ├── cmd_geosite_export.go
│ ├── cmd_geosite_list.go
│ ├── cmd_geosite_lookup.go
│ ├── cmd_geosite_matcher.go
│ ├── cmd_merge.go
│ ├── cmd_rule_set.go
│ ├── cmd_rule_set_compile.go
│ ├── cmd_rule_set_convert.go
│ ├── cmd_rule_set_decompile.go
│ ├── cmd_rule_set_format.go
│ ├── cmd_rule_set_match.go
│ ├── cmd_rule_set_merge.go
│ ├── cmd_rule_set_upgrade.go
│ ├── cmd_run.go
│ ├── cmd_tools.go
│ ├── cmd_tools_connect.go
│ ├── cmd_tools_fetch.go
│ ├── cmd_tools_fetch_http3.go
│ ├── cmd_tools_fetch_http3_stub.go
│ ├── cmd_tools_networkquality.go
│ ├── cmd_tools_stun.go
│ ├── cmd_tools_synctime.go
│ ├── cmd_version.go
│ ├── generate_completions.go
│ └── main.go
├── common/
│ ├── badtls/
│ │ ├── raw_conn.go
│ │ ├── raw_half_conn.go
│ │ ├── read_wait.go
│ │ ├── read_wait_stub.go
│ │ ├── registry.go
│ │ └── registry_utls.go
│ ├── badversion/
│ │ ├── version.go
│ │ ├── version_json.go
│ │ └── version_test.go
│ ├── certificate/
│ │ ├── anchors_darwin.h
│ │ ├── anchors_darwin.m
│ │ ├── chrome.go
│ │ ├── chrome.pem
│ │ ├── mozilla.go
│ │ ├── mozilla.pem
│ │ ├── store.go
│ │ ├── store_darwin.go
│ │ └── store_other.go
│ ├── compatible/
│ │ └── map.go
│ ├── convertor/
│ │ └── adguard/
│ │ ├── convertor.go
│ │ └── convertor_test.go
│ ├── dialer/
│ │ ├── default.go
│ │ ├── default_parallel_interface.go
│ │ ├── default_parallel_network.go
│ │ ├── detour.go
│ │ ├── dialer.go
│ │ ├── resolve.go
│ │ ├── router.go
│ │ ├── tfo.go
│ │ └── wireguard.go
│ ├── geoip/
│ │ └── reader.go
│ ├── geosite/
│ │ ├── compat_test.go
│ │ ├── geosite_test.go
│ │ ├── reader.go
│ │ ├── rule.go
│ │ └── writer.go
│ ├── httpclient/
│ │ ├── apple_transport_darwin.go
│ │ ├── apple_transport_darwin.h
│ │ ├── apple_transport_darwin.m
│ │ ├── apple_transport_darwin_test.go
│ │ ├── apple_transport_stub.go
│ │ ├── client.go
│ │ ├── context.go
│ │ ├── helpers.go
│ │ ├── helpers_test.go
│ │ ├── http1_transport.go
│ │ ├── http2_config.go
│ │ ├── http2_fallback_transport.go
│ │ ├── http2_fallback_transport_test.go
│ │ ├── http2_transport.go
│ │ ├── http3_transport.go
│ │ ├── http3_transport_stub.go
│ │ ├── http3_transport_test.go
│ │ ├── managed_transport.go
│ │ └── manager.go
│ ├── interrupt/
│ │ ├── conn.go
│ │ ├── context.go
│ │ └── group.go
│ ├── ja3/
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── error.go
│ │ ├── ja3.go
│ │ └── parser.go
│ ├── ktls/
│ │ ├── ktls.go
│ │ ├── ktls_alert.go
│ │ ├── ktls_cipher_suites_linux.go
│ │ ├── ktls_close.go
│ │ ├── ktls_const.go
│ │ ├── ktls_handshake_messages.go
│ │ ├── ktls_key_update.go
│ │ ├── ktls_linux.go
│ │ ├── ktls_prf.go
│ │ ├── ktls_read.go
│ │ ├── ktls_read_wait.go
│ │ ├── ktls_stub_nolinkname.go
│ │ ├── ktls_stub_nonlinux.go
│ │ ├── ktls_stub_oldgo.go
│ │ └── ktls_write.go
│ ├── listener/
│ │ ├── listener.go
│ │ ├── listener_tcp.go
│ │ └── listener_udp.go
│ ├── mux/
│ │ ├── client.go
│ │ └── router.go
│ ├── networkquality/
│ │ ├── http.go
│ │ ├── http3.go
│ │ ├── http3_stub.go
│ │ └── networkquality.go
│ ├── pipelistener/
│ │ └── listener.go
│ ├── process/
│ │ ├── searcher.go
│ │ ├── searcher_android.go
│ │ ├── searcher_darwin.go
│ │ ├── searcher_darwin_shared.go
│ │ ├── searcher_linux.go
│ │ ├── searcher_linux_shared.go
│ │ ├── searcher_linux_shared_test.go
│ │ ├── searcher_stub.go
│ │ └── searcher_windows.go
│ ├── proxybridge/
│ │ └── bridge.go
│ ├── redir/
│ │ ├── redir_darwin.go
│ │ ├── redir_linux.go
│ │ ├── redir_other.go
│ │ ├── tproxy_linux.go
│ │ └── tproxy_other.go
│ ├── schannel/
│ │ ├── doc.go
│ │ ├── schannel_windows.go
│ │ ├── schannel_windows_test.go
│ │ ├── syscall_windows.go
│ │ ├── types_windows.go
│ │ └── zsyscall_windows.go
│ ├── settings/
│ │ ├── proxy_android.go
│ │ ├── proxy_darwin.go
│ │ ├── proxy_linux.go
│ │ ├── proxy_stub.go
│ │ ├── proxy_windows.go
│ │ ├── system_proxy.go
│ │ ├── wifi.go
│ │ ├── wifi_linux.go
│ │ ├── wifi_linux_connman.go
│ │ ├── wifi_linux_iwd.go
│ │ ├── wifi_linux_nm.go
│ │ ├── wifi_linux_wpa.go
│ │ ├── wifi_stub.go
│ │ └── wifi_windows.go
│ ├── sniff/
│ │ ├── bittorrent.go
│ │ ├── bittorrent_test.go
│ │ ├── dns.go
│ │ ├── dns_test.go
│ │ ├── dtls.go
│ │ ├── dtls_test.go
│ │ ├── http.go
│ │ ├── http_test.go
│ │ ├── internal/
│ │ │ └── qtls/
│ │ │ └── qtls.go
│ │ ├── ntp.go
│ │ ├── ntp_test.go
│ │ ├── quic.go
│ │ ├── quic_blacklist.go
│ │ ├── quic_capture_test.go
│ │ ├── quic_test.go
│ │ ├── rdp.go
│ │ ├── rdp_test.go
│ │ ├── sniff.go
│ │ ├── ssh.go
│ │ ├── ssh_test.go
│ │ ├── stun.go
│ │ ├── stun_test.go
│ │ └── tls.go
│ ├── srs/
│ │ ├── binary.go
│ │ ├── compat_test.go
│ │ ├── ip_cidr.go
│ │ └── ip_set.go
│ ├── stun/
│ │ └── stun.go
│ ├── taskmonitor/
│ │ └── monitor.go
│ ├── tls/
│ │ ├── acme.go
│ │ ├── acme_logger.go
│ │ ├── acme_stub.go
│ │ ├── apple_client.go
│ │ ├── apple_client_platform.go
│ │ ├── apple_client_platform_benchmark_test.go
│ │ ├── apple_client_platform_darwin.h
│ │ ├── apple_client_platform_darwin.m
│ │ ├── apple_client_platform_dispatch_test.go
│ │ ├── apple_client_platform_dispatch_testhelper_darwin.go
│ │ ├── apple_client_platform_test.go
│ │ ├── apple_client_stub.go
│ │ ├── client.go
│ │ ├── common.go
│ │ ├── config.go
│ │ ├── ech.go
│ │ ├── ech_shared.go
│ │ ├── ech_tag_stub.go
│ │ ├── ktls.go
│ │ ├── mkcert.go
│ │ ├── reality_client.go
│ │ ├── reality_server.go
│ │ ├── reality_stub.go
│ │ ├── server.go
│ │ ├── std_client.go
│ │ ├── std_server.go
│ │ ├── system_client.go
│ │ ├── system_client_engine.go
│ │ ├── time_wrapper.go
│ │ ├── utls_client.go
│ │ ├── utls_client_test.go
│ │ ├── utls_stub.go
│ │ ├── windows_client.go
│ │ ├── windows_client_stub.go
│ │ └── windows_client_test.go
│ ├── tlsfragment/
│ │ ├── conn.go
│ │ ├── conn_test.go
│ │ ├── index.go
│ │ ├── index_test.go
│ │ ├── wait_darwin.go
│ │ ├── wait_linux.go
│ │ ├── wait_stub.go
│ │ └── wait_windows.go
│ ├── tlsspoof/
│ │ ├── README.md
│ │ ├── client_hello.go
│ │ ├── endpoints.go
│ │ ├── integration_darwin_test.go
│ │ ├── integration_linux_test.go
│ │ ├── integration_test.go
│ │ ├── integration_tls_test.go
│ │ ├── integration_unix_test.go
│ │ ├── integration_windows_test.go
│ │ ├── packet.go
│ │ ├── packet_darwin.go
│ │ ├── raw_darwin.go
│ │ ├── raw_linux.go
│ │ ├── raw_stub.go
│ │ ├── raw_unix.go
│ │ ├── raw_windows.go
│ │ ├── spoof.go
│ │ └── testdata_test.go
│ ├── uot/
│ │ └── router.go
│ ├── urltest/
│ │ └── urltest.go
│ └── windivert/
│ ├── address_test.go
│ ├── assets/
│ │ ├── LICENSE.txt
│ │ ├── WinDivert32.sys
│ │ └── WinDivert64.sys
│ ├── assets_386.go
│ ├── assets_amd64.go
│ ├── assets_unsupported.go
│ ├── driver_windows.go
│ ├── filter.go
│ ├── filter_test.go
│ ├── handle_windows.go
│ ├── handle_windows_test.go
│ ├── integration_windows_test.go
│ └── windivert.go
├── constant/
│ ├── certificate.go
│ ├── cgo.go
│ ├── cgo_disabled.go
│ ├── dhcp.go
│ ├── dns.go
│ ├── err.go
│ ├── goos/
│ │ ├── gengoos.go
│ │ ├── goos.go
│ │ ├── zgoos_aix.go
│ │ ├── zgoos_android.go
│ │ ├── zgoos_darwin.go
│ │ ├── zgoos_dragonfly.go
│ │ ├── zgoos_freebsd.go
│ │ ├── zgoos_hurd.go
│ │ ├── zgoos_illumos.go
│ │ ├── zgoos_ios.go
│ │ ├── zgoos_js.go
│ │ ├── zgoos_linux.go
│ │ ├── zgoos_netbsd.go
│ │ ├── zgoos_openbsd.go
│ │ ├── zgoos_plan9.go
│ │ ├── zgoos_solaris.go
│ │ ├── zgoos_windows.go
│ │ └── zgoos_zos.go
│ ├── hysteria2.go
│ ├── network.go
│ ├── os.go
│ ├── path.go
│ ├── path_unix.go
│ ├── protocol.go
│ ├── proxy.go
│ ├── quic.go
│ ├── quic_stub.go
│ ├── rule.go
│ ├── speed.go
│ ├── time.go
│ ├── timeout.go
│ ├── tls.go
│ ├── v2ray.go
│ └── version.go
├── daemon/
│ ├── deprecated.go
│ ├── instance.go
│ ├── platform.go
│ ├── started_service.go
│ ├── started_service.pb.go
│ ├── started_service.proto
│ └── started_service_grpc.pb.go
├── debug.go
├── debug_http.go
├── debug_stub.go
├── debug_unix.go
├── dns/
│ ├── client.go
│ ├── client_log.go
│ ├── client_truncate.go
│ ├── extension_edns0_subnet.go
│ ├── rcode.go
│ ├── repro_test.go
│ ├── router.go
│ ├── router_test.go
│ ├── transport/
│ │ ├── conn_pool.go
│ │ ├── dhcp/
│ │ │ ├── dhcp.go
│ │ │ └── dhcp_shared.go
│ │ ├── fakeip/
│ │ │ ├── fakeip.go
│ │ │ ├── memory.go
│ │ │ └── store.go
│ │ ├── hosts/
│ │ │ ├── hosts.go
│ │ │ ├── hosts_file.go
│ │ │ ├── hosts_test.go
│ │ │ ├── hosts_unix.go
│ │ │ ├── hosts_windows.go
│ │ │ └── testdata/
│ │ │ └── hosts
│ │ ├── https.go
│ │ ├── https_transport.go
│ │ ├── local/
│ │ │ ├── local.go
│ │ │ ├── local_darwin_cgo.go
│ │ │ ├── local_darwin_stun.go
│ │ │ ├── local_dhcp.go
│ │ │ ├── local_neighbor.go
│ │ │ ├── local_nodhcp.go
│ │ │ ├── local_other.go
│ │ │ ├── local_resolved.go
│ │ │ ├── local_resolved_linux.go
│ │ │ ├── local_resolved_stub.go
│ │ │ ├── local_shared.go
│ │ │ ├── resolv.go
│ │ │ ├── resolv_default.go
│ │ │ ├── resolv_test.go
│ │ │ ├── resolv_unix.go
│ │ │ └── resolv_windows.go
│ │ ├── mdns/
│ │ │ └── mdns.go
│ │ ├── quic/
│ │ │ ├── http3.go
│ │ │ └── quic.go
│ │ ├── tcp.go
│ │ ├── tls.go
│ │ └── udp.go
│ ├── transport_adapter.go
│ ├── transport_dialer.go
│ ├── transport_manager.go
│ └── transport_registry.go
├── docs/
│ ├── CNAME
│ ├── changelog.md
│ ├── clients/
│ │ ├── android/
│ │ │ ├── features.md
│ │ │ └── index.md
│ │ ├── apple/
│ │ │ ├── features.md
│ │ │ └── index.md
│ │ ├── general.md
│ │ ├── index.md
│ │ ├── index.zh.md
│ │ └── privacy.md
│ ├── configuration/
│ │ ├── certificate/
│ │ │ ├── index.md
│ │ │ └── index.zh.md
│ │ ├── dns/
│ │ │ ├── fakeip.md
│ │ │ ├── fakeip.zh.md
│ │ │ ├── index.md
│ │ │ ├── index.zh.md
│ │ │ ├── rule.md
│ │ │ ├── rule.zh.md
│ │ │ ├── rule_action.md
│ │ │ ├── rule_action.zh.md
│ │ │ └── server/
│ │ │ ├── dhcp.md
│ │ │ ├── dhcp.zh.md
│ │ │ ├── fakeip.md
│ │ │ ├── fakeip.zh.md
│ │ │ ├── hosts.md
│ │ │ ├── hosts.zh.md
│ │ │ ├── http3.md
│ │ │ ├── http3.zh.md
│ │ │ ├── https.md
│ │ │ ├── https.zh.md
│ │ │ ├── index.md
│ │ │ ├── index.zh.md
│ │ │ ├── legacy.md
│ │ │ ├── legacy.zh.md
│ │ │ ├── local.md
│ │ │ ├── local.zh.md
│ │ │ ├── mdns.md
│ │ │ ├── mdns.zh.md
│ │ │ ├── quic.md
│ │ │ ├── quic.zh.md
│ │ │ ├── resolved.md
│ │ │ ├── resolved.zh.md
│ │ │ ├── tailscale.md
│ │ │ ├── tailscale.zh.md
│ │ │ ├── tcp.md
│ │ │ ├── tcp.zh.md
│ │ │ ├── tls.md
│ │ │ ├── tls.zh.md
│ │ │ ├── udp.md
│ │ │ └── udp.zh.md
│ │ ├── endpoint/
│ │ │ ├── index.md
│ │ │ ├── index.zh.md
│ │ │ ├── tailscale.md
│ │ │ ├── tailscale.zh.md
│ │ │ ├── wireguard.md
│ │ │ └── wireguard.zh.md
│ │ ├── experimental/
│ │ │ ├── cache-file.md
│ │ │ ├── cache-file.zh.md
│ │ │ ├── clash-api.md
│ │ │ ├── clash-api.zh.md
│ │ │ ├── index.md
│ │ │ ├── index.zh.md
│ │ │ ├── v2ray-api.md
│ │ │ └── v2ray-api.zh.md
│ │ ├── inbound/
│ │ │ ├── anytls.md
│ │ │ ├── anytls.zh.md
│ │ │ ├── cloudflared.md
│ │ │ ├── cloudflared.zh.md
│ │ │ ├── direct.md
│ │ │ ├── direct.zh.md
│ │ │ ├── http.md
│ │ │ ├── http.zh.md
│ │ │ ├── hysteria.md
│ │ │ ├── hysteria.zh.md
│ │ │ ├── hysteria2.md
│ │ │ ├── hysteria2.zh.md
│ │ │ ├── index.md
│ │ │ ├── index.zh.md
│ │ │ ├── mixed.md
│ │ │ ├── mixed.zh.md
│ │ │ ├── naive.md
│ │ │ ├── naive.zh.md
│ │ │ ├── redirect.md
│ │ │ ├── redirect.zh.md
│ │ │ ├── shadowsocks.md
│ │ │ ├── shadowsocks.zh.md
│ │ │ ├── shadowtls.md
│ │ │ ├── shadowtls.zh.md
│ │ │ ├── socks.md
│ │ │ ├── socks.zh.md
│ │ │ ├── tproxy.md
│ │ │ ├── tproxy.zh.md
│ │ │ ├── trojan.md
│ │ │ ├── trojan.zh.md
│ │ │ ├── tuic.md
│ │ │ ├── tuic.zh.md
│ │ │ ├── tun.md
│ │ │ ├── tun.zh.md
│ │ │ ├── vless.md
│ │ │ ├── vless.zh.md
│ │ │ ├── vmess.md
│ │ │ └── vmess.zh.md
│ │ ├── index.md
│ │ ├── index.zh.md
│ │ ├── log/
│ │ │ ├── index.md
│ │ │ └── index.zh.md
│ │ ├── ntp/
│ │ │ ├── index.md
│ │ │ └── index.zh.md
│ │ ├── outbound/
│ │ │ ├── anytls.md
│ │ │ ├── anytls.zh.md
│ │ │ ├── block.md
│ │ │ ├── block.zh.md
│ │ │ ├── direct.md
│ │ │ ├── direct.zh.md
│ │ │ ├── dns.md
│ │ │ ├── dns.zh.md
│ │ │ ├── http.md
│ │ │ ├── http.zh.md
│ │ │ ├── hysteria.md
│ │ │ ├── hysteria.zh.md
│ │ │ ├── hysteria2.md
│ │ │ ├── hysteria2.zh.md
│ │ │ ├── index.md
│ │ │ ├── index.zh.md
│ │ │ ├── naive.md
│ │ │ ├── naive.zh.md
│ │ │ ├── selector.md
│ │ │ ├── selector.zh.md
│ │ │ ├── shadowsocks.md
│ │ │ ├── shadowsocks.zh.md
│ │ │ ├── shadowtls.md
│ │ │ ├── shadowtls.zh.md
│ │ │ ├── socks.md
│ │ │ ├── socks.zh.md
│ │ │ ├── ssh.md
│ │ │ ├── ssh.zh.md
│ │ │ ├── tor.md
│ │ │ ├── tor.zh.md
│ │ │ ├── trojan.md
│ │ │ ├── trojan.zh.md
│ │ │ ├── tuic.md
│ │ │ ├── tuic.zh.md
│ │ │ ├── urltest.md
│ │ │ ├── urltest.zh.md
│ │ │ ├── vless.md
│ │ │ ├── vless.zh.md
│ │ │ ├── vmess.md
│ │ │ ├── vmess.zh.md
│ │ │ ├── wireguard.md
│ │ │ └── wireguard.zh.md
│ │ ├── route/
│ │ │ ├── geoip.md
│ │ │ ├── geoip.zh.md
│ │ │ ├── geosite.md
│ │ │ ├── geosite.zh.md
│ │ │ ├── index.md
│ │ │ ├── index.zh.md
│ │ │ ├── rule.md
│ │ │ ├── rule.zh.md
│ │ │ ├── rule_action.md
│ │ │ ├── rule_action.zh.md
│ │ │ ├── sniff.md
│ │ │ └── sniff.zh.md
│ │ ├── rule-set/
│ │ │ ├── adguard.md
│ │ │ ├── adguard.zh.md
│ │ │ ├── headless-rule.md
│ │ │ ├── headless-rule.zh.md
│ │ │ ├── index.md
│ │ │ ├── index.zh.md
│ │ │ ├── source-format.md
│ │ │ └── source-format.zh.md
│ │ ├── service/
│ │ │ ├── ccm.md
│ │ │ ├── ccm.zh.md
│ │ │ ├── derp.md
│ │ │ ├── derp.zh.md
│ │ │ ├── hysteria-realm.md
│ │ │ ├── hysteria-realm.zh.md
│ │ │ ├── index.md
│ │ │ ├── index.zh.md
│ │ │ ├── ocm.md
│ │ │ ├── ocm.zh.md
│ │ │ ├── resolved.md
│ │ │ ├── resolved.zh.md
│ │ │ ├── ssm-api.md
│ │ │ └── ssm-api.zh.md
│ │ └── shared/
│ │ ├── certificate-provider/
│ │ │ ├── acme.md
│ │ │ ├── acme.zh.md
│ │ │ ├── cloudflare-origin-ca.md
│ │ │ ├── cloudflare-origin-ca.zh.md
│ │ │ ├── index.md
│ │ │ ├── index.zh.md
│ │ │ ├── tailscale.md
│ │ │ └── tailscale.zh.md
│ │ ├── dial.md
│ │ ├── dial.zh.md
│ │ ├── dns01_challenge.md
│ │ ├── dns01_challenge.zh.md
│ │ ├── http-client.md
│ │ ├── http-client.zh.md
│ │ ├── http2.md
│ │ ├── http2.zh.md
│ │ ├── listen.md
│ │ ├── listen.zh.md
│ │ ├── multiplex.md
│ │ ├── multiplex.zh.md
│ │ ├── neighbor.md
│ │ ├── neighbor.zh.md
│ │ ├── pre-match.md
│ │ ├── pre-match.zh.md
│ │ ├── quic.md
│ │ ├── quic.zh.md
│ │ ├── tcp-brutal.md
│ │ ├── tcp-brutal.zh.md
│ │ ├── tls.md
│ │ ├── tls.zh.md
│ │ ├── udp-over-tcp.md
│ │ ├── udp-over-tcp.zh.md
│ │ ├── v2ray-transport.md
│ │ ├── v2ray-transport.zh.md
│ │ ├── wifi-state.md
│ │ └── wifi-state.zh.md
│ ├── deprecated.md
│ ├── deprecated.zh.md
│ ├── index.md
│ ├── index.zh.md
│ ├── installation/
│ │ ├── build-from-source.md
│ │ ├── build-from-source.zh.md
│ │ ├── docker.md
│ │ ├── docker.zh.md
│ │ ├── package-manager.md
│ │ ├── package-manager.zh.md
│ │ └── tools/
│ │ ├── arch-install.sh
│ │ ├── deb-install.sh
│ │ ├── install.sh
│ │ ├── rpm-install.sh
│ │ └── sing-box.repo
│ ├── manual/
│ │ ├── misc/
│ │ │ └── tunnelvision.md
│ │ ├── proxy/
│ │ │ ├── client.md
│ │ │ └── server.md
│ │ └── proxy-protocol/
│ │ ├── hysteria2.md
│ │ ├── shadowsocks.md
│ │ └── trojan.md
│ ├── migration.md
│ ├── migration.zh.md
│ ├── sponsors.md
│ ├── support.md
│ └── support.zh.md
├── experimental/
│ ├── cachefile/
│ │ ├── cache.go
│ │ ├── dns_cache.go
│ │ ├── fakeip.go
│ │ └── rdrc.go
│ ├── clashapi/
│ │ ├── api_meta.go
│ │ ├── api_meta_group.go
│ │ ├── api_meta_upgrade.go
│ │ ├── cache.go
│ │ ├── common.go
│ │ ├── configs.go
│ │ ├── connections.go
│ │ ├── ctxkeys.go
│ │ ├── dns.go
│ │ ├── errors.go
│ │ ├── profile.go
│ │ ├── provider.go
│ │ ├── proxies.go
│ │ ├── ruleprovider.go
│ │ ├── rules.go
│ │ ├── script.go
│ │ ├── server.go
│ │ ├── server_fs.go
│ │ ├── server_resources.go
│ │ └── trafficontrol/
│ │ ├── manager.go
│ │ └── tracker.go
│ ├── clashapi.go
│ ├── deprecated/
│ │ ├── constants.go
│ │ ├── manager.go
│ │ └── stderr.go
│ ├── libbox/
│ │ ├── build_info.go
│ │ ├── command.go
│ │ ├── command_client.go
│ │ ├── command_server.go
│ │ ├── command_types.go
│ │ ├── command_types_nq.go
│ │ ├── command_types_stun.go
│ │ ├── command_types_tailscale.go
│ │ ├── command_types_tailscale_ping.go
│ │ ├── config.go
│ │ ├── connection_owner_darwin.go
│ │ ├── debug.go
│ │ ├── deprecated.go
│ │ ├── dns.go
│ │ ├── fdroid.go
│ │ ├── fdroid_mirrors.go
│ │ ├── ffi.json
│ │ ├── http.go
│ │ ├── internal/
│ │ │ ├── oomprofile/
│ │ │ │ ├── builder.go
│ │ │ │ ├── defs_darwin_amd64.go
│ │ │ │ ├── defs_darwin_arm64.go
│ │ │ │ ├── linkname.go
│ │ │ │ ├── mapping_darwin.go
│ │ │ │ ├── mapping_linux.go
│ │ │ │ ├── mapping_windows.go
│ │ │ │ ├── oomprofile.go
│ │ │ │ └── protobuf.go
│ │ │ └── procfs/
│ │ │ └── procfs.go
│ │ ├── iterator.go
│ │ ├── link_flags_stub.go
│ │ ├── link_flags_unix.go
│ │ ├── log.go
│ │ ├── monitor.go
│ │ ├── neighbor.go
│ │ ├── neighbor_darwin.go
│ │ ├── neighbor_linux.go
│ │ ├── neighbor_stub.go
│ │ ├── neighbor_unix.go
│ │ ├── networkquality.go
│ │ ├── oom_report.go
│ │ ├── panic.go
│ │ ├── pidfd_android.go
│ │ ├── platform.go
│ │ ├── pprof.go
│ │ ├── profile_import.go
│ │ ├── remote_profile.go
│ │ ├── report.go
│ │ ├── semver.go
│ │ ├── semver_test.go
│ │ ├── service.go
│ │ ├── service_other.go
│ │ ├── service_windows.go
│ │ ├── setup.go
│ │ ├── signal_handler_darwin.go
│ │ ├── signal_handler_stub.go
│ │ ├── stun.go
│ │ ├── tun.go
│ │ ├── tun_darwin.go
│ │ ├── tun_name_darwin.go
│ │ ├── tun_name_linux.go
│ │ └── tun_name_other.go
│ ├── locale/
│ │ ├── locale.go
│ │ └── locale_zh_CN.go
│ ├── v2rayapi/
│ │ ├── server.go
│ │ ├── stats.go
│ │ ├── stats.pb.go
│ │ ├── stats.proto
│ │ └── stats_grpc.pb.go
│ └── v2rayapi.go
├── go.mod
├── go.sum
├── include/
│ ├── acme.go
│ ├── acme_stub.go
│ ├── ccm.go
│ ├── ccm_stub.go
│ ├── ccm_stub_darwin.go
│ ├── clashapi.go
│ ├── clashapi_stub.go
│ ├── cloudflared.go
│ ├── cloudflared_stub.go
│ ├── dhcp.go
│ ├── dhcp_stub.go
│ ├── naive_outbound.go
│ ├── naive_outbound_stub.go
│ ├── ocm.go
│ ├── ocm_stub.go
│ ├── oom_killer.go
│ ├── quic.go
│ ├── quic_stub.go
│ ├── registry.go
│ ├── tailscale.go
│ ├── tailscale_stub.go
│ ├── tz_android.go
│ ├── tz_ios.go
│ ├── v2rayapi.go
│ ├── v2rayapi_stub.go
│ ├── wireguard.go
│ └── wireguard_stub.go
├── log/
│ ├── export.go
│ ├── factory.go
│ ├── format.go
│ ├── id.go
│ ├── level.go
│ ├── log.go
│ ├── nop.go
│ ├── observable.go
│ ├── override.go
│ └── platform.go
├── mkdocs.yml
├── option/
│ ├── acme.go
│ ├── anytls.go
│ ├── ccm.go
│ ├── certificate.go
│ ├── certificate_provider.go
│ ├── cloudflared.go
│ ├── debug.go
│ ├── direct.go
│ ├── dns.go
│ ├── dns_record.go
│ ├── dns_record_test.go
│ ├── dns_test.go
│ ├── endpoint.go
│ ├── experimental.go
│ ├── group.go
│ ├── http.go
│ ├── hysteria.go
│ ├── hysteria2.go
│ ├── inbound.go
│ ├── multiplex.go
│ ├── naive.go
│ ├── ntp.go
│ ├── ocm.go
│ ├── oom_killer.go
│ ├── options.go
│ ├── origin_ca.go
│ ├── outbound.go
│ ├── platform.go
│ ├── redir.go
│ ├── resolved.go
│ ├── route.go
│ ├── rule.go
│ ├── rule_action.go
│ ├── rule_action_test.go
│ ├── rule_dns.go
│ ├── rule_nested.go
│ ├── rule_nested_test.go
│ ├── rule_set.go
│ ├── service.go
│ ├── shadowsocks.go
│ ├── shadowsocksr.go
│ ├── shadowtls.go
│ ├── simple.go
│ ├── ssh.go
│ ├── ssmapi.go
│ ├── tailscale.go
│ ├── tls.go
│ ├── tls_acme.go
│ ├── tor.go
│ ├── trojan.go
│ ├── tuic.go
│ ├── tun.go
│ ├── tun_platform.go
│ ├── types.go
│ ├── udp_over_tcp.go
│ ├── v2ray.go
│ ├── v2ray_transport.go
│ ├── vless.go
│ ├── vmess.go
│ └── wireguard.go
├── protocol/
│ ├── anytls/
│ │ ├── inbound.go
│ │ └── outbound.go
│ ├── block/
│ │ └── outbound.go
│ ├── cloudflare/
│ │ └── inbound.go
│ ├── direct/
│ │ ├── inbound.go
│ │ └── outbound.go
│ ├── dns/
│ │ ├── handle.go
│ │ └── outbound.go
│ ├── group/
│ │ ├── selector.go
│ │ └── urltest.go
│ ├── http/
│ │ ├── inbound.go
│ │ └── outbound.go
│ ├── hysteria/
│ │ ├── inbound.go
│ │ ├── outbound.go
│ │ └── quic.go
│ ├── hysteria2/
│ │ ├── inbound.go
│ │ ├── outbound.go
│ │ ├── realm.go
│ │ └── realm_server.go
│ ├── mixed/
│ │ └── inbound.go
│ ├── naive/
│ │ ├── inbound.go
│ │ ├── inbound_conn.go
│ │ ├── outbound.go
│ │ └── quic/
│ │ └── inbound_init.go
│ ├── redirect/
│ │ ├── redirect.go
│ │ └── tproxy.go
│ ├── shadowsocks/
│ │ ├── inbound.go
│ │ ├── inbound_multi.go
│ │ ├── inbound_relay.go
│ │ └── outbound.go
│ ├── shadowtls/
│ │ ├── inbound.go
│ │ └── outbound.go
│ ├── socks/
│ │ ├── inbound.go
│ │ └── outbound.go
│ ├── ssh/
│ │ └── outbound.go
│ ├── tailscale/
│ │ ├── certificate_provider.go
│ │ ├── dns_transport.go
│ │ ├── endpoint.go
│ │ ├── hostinfo_tvos.go
│ │ ├── ping.go
│ │ ├── status.go
│ │ ├── tun_device_unix.go
│ │ └── tun_device_windows.go
│ ├── tor/
│ │ └── outbound.go
│ ├── trojan/
│ │ ├── inbound.go
│ │ └── outbound.go
│ ├── tuic/
│ │ ├── inbound.go
│ │ └── outbound.go
│ ├── tun/
│ │ └── inbound.go
│ ├── vless/
│ │ ├── inbound.go
│ │ └── outbound.go
│ ├── vmess/
│ │ ├── inbound.go
│ │ └── outbound.go
│ └── wireguard/
│ └── endpoint.go
├── release/
│ ├── DEFAULT_BUILD_TAGS
│ ├── DEFAULT_BUILD_TAGS_OTHERS
│ ├── DEFAULT_BUILD_TAGS_WINDOWS
│ ├── LDFLAGS
│ ├── completions/
│ │ ├── sing-box.bash
│ │ ├── sing-box.fish
│ │ └── sing-box.zsh
│ ├── config/
│ │ ├── config.json
│ │ ├── openwrt.conf
│ │ ├── openwrt.init
│ │ ├── openwrt.keep
│ │ ├── openwrt.prerm
│ │ ├── sing-box-split-dns.xml
│ │ ├── sing-box.confd
│ │ ├── sing-box.initd
│ │ ├── sing-box.postinst
│ │ ├── sing-box.rules
│ │ ├── sing-box.service
│ │ ├── sing-box.sysusers
│ │ └── sing-box@.service
│ └── local/
│ ├── common.sh
│ ├── debug.sh
│ ├── enable.sh
│ ├── install.sh
│ ├── install_go.sh
│ ├── reinstall.sh
│ ├── sing-box.service
│ ├── uninstall.sh
│ └── update.sh
├── route/
│ ├── conn.go
│ ├── dns.go
│ ├── neighbor_resolver_darwin.go
│ ├── neighbor_resolver_hostname.go
│ ├── neighbor_resolver_lease.go
│ ├── neighbor_resolver_linux.go
│ ├── neighbor_resolver_parse.go
│ ├── neighbor_resolver_platform.go
│ ├── neighbor_resolver_stub.go
│ ├── neighbor_table_darwin.go
│ ├── neighbor_table_linux.go
│ ├── network.go
│ ├── platform_searcher.go
│ ├── process_cache.go
│ ├── route.go
│ ├── router.go
│ ├── rule/
│ │ ├── match_state.go
│ │ ├── rule_abstract.go
│ │ ├── rule_abstract_test.go
│ │ ├── rule_action.go
│ │ ├── rule_default.go
│ │ ├── rule_default_interface_address.go
│ │ ├── rule_dns.go
│ │ ├── rule_headless.go
│ │ ├── rule_interface_address.go
│ │ ├── rule_item_adguard.go
│ │ ├── rule_item_auth_user.go
│ │ ├── rule_item_cidr.go
│ │ ├── rule_item_clash_mode.go
│ │ ├── rule_item_client.go
│ │ ├── rule_item_domain.go
│ │ ├── rule_item_domain_keyword.go
│ │ ├── rule_item_domain_regex.go
│ │ ├── rule_item_inbound.go
│ │ ├── rule_item_ip_accept_any.go
│ │ ├── rule_item_ip_is_private.go
│ │ ├── rule_item_ipversion.go
│ │ ├── rule_item_network.go
│ │ ├── rule_item_network_is_constrained.go
│ │ ├── rule_item_network_is_expensive.go
│ │ ├── rule_item_network_type.go
│ │ ├── rule_item_outbound.go
│ │ ├── rule_item_package_name.go
│ │ ├── rule_item_package_name_regex.go
│ │ ├── rule_item_port.go
│ │ ├── rule_item_port_range.go
│ │ ├── rule_item_preferred_by.go
│ │ ├── rule_item_preferred_by_dns.go
│ │ ├── rule_item_process_name.go
│ │ ├── rule_item_process_path.go
│ │ ├── rule_item_process_path_regex.go
│ │ ├── rule_item_protocol.go
│ │ ├── rule_item_query_type.go
│ │ ├── rule_item_response_rcode.go
│ │ ├── rule_item_response_record.go
│ │ ├── rule_item_rule_set.go
│ │ ├── rule_item_rule_set_test.go
│ │ ├── rule_item_source_hostname.go
│ │ ├── rule_item_source_mac_address.go
│ │ ├── rule_item_user.go
│ │ ├── rule_item_user_id.go
│ │ ├── rule_item_wifi_bssid.go
│ │ ├── rule_item_wifi_ssid.go
│ │ ├── rule_nested_action.go
│ │ ├── rule_nested_action_test.go
│ │ ├── rule_network_interface_address.go
│ │ ├── rule_set.go
│ │ ├── rule_set_local.go
│ │ ├── rule_set_remote.go
│ │ ├── rule_set_semantics_test.go
│ │ └── rule_set_update_validation_test.go
│ └── rule_conds.go
├── service/
│ ├── acme/
│ │ ├── service.go
│ │ └── stub.go
│ ├── ccm/
│ │ ├── credential.go
│ │ ├── credential_darwin.go
│ │ ├── credential_other.go
│ │ ├── service.go
│ │ ├── service_usage.go
│ │ └── service_user.go
│ ├── derp/
│ │ └── service.go
│ ├── ocm/
│ │ ├── credential.go
│ │ ├── credential_darwin.go
│ │ ├── credential_other.go
│ │ ├── service.go
│ │ ├── service_usage.go
│ │ ├── service_user.go
│ │ └── service_websocket.go
│ ├── oomkiller/
│ │ ├── badcleanup.go
│ │ ├── badcleanup_stub.go
│ │ ├── policy.go
│ │ ├── service.go
│ │ ├── service_darwin.go
│ │ ├── service_stub.go
│ │ ├── timer.go
│ │ └── timer_darwin.go
│ ├── origin_ca/
│ │ └── service.go
│ ├── resolved/
│ │ ├── resolve1.go
│ │ ├── service.go
│ │ ├── stub.go
│ │ └── transport.go
│ └── ssmapi/
│ ├── api.go
│ ├── cache.go
│ ├── server.go
│ ├── traffic.go
│ └── user.go
├── test/
│ ├── box_test.go
│ ├── brutal_test.go
│ ├── clash_darwin_test.go
│ ├── clash_other_test.go
│ ├── clash_test.go
│ ├── config/
│ │ ├── hysteria-client.json
│ │ ├── hysteria-server.json
│ │ ├── hysteria2-client.yml
│ │ ├── hysteria2-server.yml
│ │ ├── naive-nginx.conf
│ │ ├── naive-quic.json
│ │ ├── naive.json
│ │ ├── nginx.conf
│ │ ├── shadowsocksr.json
│ │ ├── trojan.json
│ │ ├── tuic-client.json
│ │ ├── tuic-server.json
│ │ ├── vless-server.json
│ │ ├── vless-tls-client.json
│ │ ├── vless-tls-server.json
│ │ ├── vmess-client.json
│ │ ├── vmess-grpc-client.json
│ │ ├── vmess-grpc-server.json
│ │ ├── vmess-mux-client.json
│ │ ├── vmess-server.json
│ │ ├── vmess-ws-client.json
│ │ ├── vmess-ws-server.json
│ │ └── wireguard.conf
│ ├── direct_test.go
│ ├── docker_test.go
│ ├── domain_inbound_test.go
│ ├── ech_test.go
│ ├── go.mod
│ ├── go.sum
│ ├── http_test.go
│ ├── hysteria2_test.go
│ ├── hysteria_test.go
│ ├── inbound_detour_test.go
│ ├── ktls_test.go
│ ├── mkcert.go
│ ├── mux_cool_test.go
│ ├── mux_test.go
│ ├── naive_self_test.go
│ ├── naive_test.go
│ ├── reality_test.go
│ ├── shadowsocks_legacy_test.go
│ ├── shadowsocks_test.go
│ ├── shadowtls_test.go
│ ├── socks_test.go
│ ├── ss_plugin_test.go
│ ├── tfo_test.go
│ ├── tls_test.go
│ ├── trojan_test.go
│ ├── tuic_test.go
│ ├── v2ray_api_test.go
│ ├── v2ray_grpc_test.go
│ ├── v2ray_httpupgrade_test.go
│ ├── v2ray_transport_test.go
│ ├── v2ray_ws_test.go
│ ├── vmess_test.go
│ └── wrapper_test.go
└── transport/
├── simple-obfs/
│ ├── README.md
│ ├── http.go
│ └── tls.go
├── sip003/
│ ├── args.go
│ ├── obfs.go
│ ├── plugin.go
│ └── v2ray.go
├── trojan/
│ ├── mux.go
│ ├── protocol.go
│ ├── protocol_wait.go
│ ├── service.go
│ └── service_wait.go
├── v2ray/
│ ├── grpc.go
│ ├── grpc_lite.go
│ ├── quic.go
│ └── transport.go
├── v2raygrpc/
│ ├── client.go
│ ├── conn.go
│ ├── credentials/
│ │ ├── credentials.go
│ │ ├── spiffe.go
│ │ ├── syscallconn.go
│ │ └── util.go
│ ├── custom_name.go
│ ├── server.go
│ ├── stream.pb.go
│ ├── stream.proto
│ ├── stream_grpc.pb.go
│ └── tls_credentials.go
├── v2raygrpclite/
│ ├── client.go
│ ├── conn.go
│ └── server.go
├── v2rayhttp/
│ ├── client.go
│ ├── conn.go
│ ├── force_close.go
│ ├── pool.go
│ └── server.go
├── v2rayhttpupgrade/
│ ├── client.go
│ └── server.go
├── v2rayquic/
│ ├── client.go
│ ├── init.go
│ ├── server.go
│ └── stream.go
├── v2raywebsocket/
│ ├── client.go
│ ├── conn.go
│ ├── server.go
│ └── writer.go
└── wireguard/
├── client_bind.go
├── device.go
├── device_nat.go
├── device_stack.go
├── device_stack_gonet.go
├── device_stack_stub.go
├── device_system.go
├── device_system_stack.go
├── endpoint.go
└── endpoint_options.go
================================================
FILE CONTENTS
================================================
================================================
FILE: .fpm_openwrt
================================================
-s dir
--name sing-box
--category net
--license GPL-3.0-or-later
--description "The universal proxy platform."
--url "https://sing-box.sagernet.org/"
--maintainer "nekohasekai <contact-git@sekai.icu>"
--no-deb-generate-changes
--config-files /etc/config/sing-box
--config-files /etc/sing-box/config.json
--depends ca-bundle
--depends kmod-inet-diag
--depends kmod-tun
--depends firewall4
--depends kmod-nft-queue
--before-remove release/config/openwrt.prerm
release/config/config.json=/etc/sing-box/config.json
release/config/openwrt.conf=/etc/config/sing-box
release/config/openwrt.init=/etc/init.d/sing-box
release/config/openwrt.keep=/lib/upgrade/keep.d/sing-box
release/completions/sing-box.bash=/usr/share/bash-completion/completions/sing-box.bash
release/completions/sing-box.fish=/usr/share/fish/vendor_completions.d/sing-box.fish
release/completions/sing-box.zsh=/usr/share/zsh/site-functions/_sing-box
LICENSE=/usr/share/licenses/sing-box/LICENSE
================================================
FILE: .fpm_pacman
================================================
-s dir
--name sing-box
--category net
--license GPL-3.0-or-later
--description "The universal proxy platform."
--url "https://sing-box.sagernet.org/"
--maintainer "nekohasekai <contact-git@sekai.icu>"
--config-files etc/sing-box/config.json
--after-install release/config/sing-box.postinst
release/config/config.json=/etc/sing-box/config.json
release/config/sing-box.service=/usr/lib/systemd/system/sing-box.service
release/config/sing-box@.service=/usr/lib/systemd/system/sing-box@.service
release/config/sing-box.sysusers=/usr/lib/sysusers.d/sing-box.conf
release/config/sing-box.rules=usr/share/polkit-1/rules.d/sing-box.rules
release/config/sing-box-split-dns.xml=/usr/share/dbus-1/system.d/sing-box-split-dns.conf
release/completions/sing-box.bash=/usr/share/bash-completion/completions/sing-box.bash
release/completions/sing-box.fish=/usr/share/fish/vendor_completions.d/sing-box.fish
release/completions/sing-box.zsh=/usr/share/zsh/site-functions/_sing-box
LICENSE=/usr/share/licenses/sing-box/LICENSE
================================================
FILE: .fpm_systemd
================================================
-s dir
--name sing-box
--category net
--license GPL-3.0-or-later
--description "The universal proxy platform."
--url "https://sing-box.sagernet.org/"
--vendor SagerNet
--maintainer "nekohasekai <contact-git@sekai.icu>"
--deb-field "Bug: https://github.com/SagerNet/sing-box/issues"
--no-deb-generate-changes
--config-files /etc/sing-box/config.json
--after-install release/config/sing-box.postinst
release/config/config.json=/etc/sing-box/config.json
release/config/sing-box.service=/usr/lib/systemd/system/sing-box.service
release/config/sing-box@.service=/usr/lib/systemd/system/sing-box@.service
release/config/sing-box.sysusers=/usr/lib/sysusers.d/sing-box.conf
release/config/sing-box.rules=usr/share/polkit-1/rules.d/sing-box.rules
release/config/sing-box-split-dns.xml=/usr/share/dbus-1/system.d/sing-box-split-dns.conf
release/completions/sing-box.bash=/usr/share/bash-completion/completions/sing-box.bash
release/completions/sing-box.fish=/usr/share/fish/vendor_completions.d/sing-box.fish
release/completions/sing-box.zsh=/usr/share/zsh/site-functions/_sing-box
LICENSE=/usr/share/licenses/sing-box/LICENSE
================================================
FILE: .github/CRONET_GO_VERSION
================================================
2faf34666c2cc8234f10f2ab6d4c4d6104d34ae2
================================================
FILE: .github/FUNDING.yml
================================================
github: nekohasekai
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.yml
================================================
name: Bug report
description: "Report sing-box bug"
body:
- type: dropdown
attributes:
label: Operating system
description: Operating system type
options:
- iOS
- macOS
- Apple tvOS
- Android
- Windows
- Linux
- Others
validations:
required: true
- type: input
attributes:
label: System version
description: Please provide the operating system version
validations:
required: true
- type: dropdown
attributes:
label: Installation type
description: Please provide the sing-box installation type
options:
- Original sing-box Command Line
- sing-box for iOS Graphical Client
- sing-box for macOS Graphical Client
- sing-box for Apple tvOS Graphical Client
- sing-box for Android Graphical Client
- Third-party graphical clients that advertise themselves as using sing-box (Windows)
- Third-party graphical clients that advertise themselves as using sing-box (Android)
- Others
validations:
required: true
- type: input
attributes:
description: Graphical client version
label: If you are using a graphical client, please provide the version of the client.
- type: textarea
attributes:
label: Version
description: If you are using the original command line program, please provide the output of the `sing-box version` command.
render: shell
- type: textarea
attributes:
label: Description
description: Please provide a detailed description of the error.
validations:
required: true
- type: textarea
attributes:
label: Reproduction
description: Please provide the steps to reproduce the error, including the configuration files and procedures that can locally (not dependent on the remote server) reproduce the error using the original command line program of sing-box.
validations:
required: true
- type: textarea
attributes:
label: Logs
description: |-
In addition, if you encounter a crash with the graphical client, please also provide crash logs.
For Apple platform clients, please check `Settings - View Service Log` for crash logs.
For the Android client, please check the `/sdcard/Android/data/io.nekohasekai.sfa/files/stderr.log` file for crash logs.
render: shell
- type: checkboxes
id: supporter
attributes:
label: Supporter
options:
- label: I am a [sponsor](https://github.com/sponsors/nekohasekai/)
- type: checkboxes
attributes:
label: Integrity requirements
description: |-
Please check all of the following options to prove that you have read and understood the requirements, otherwise this issue will be closed.
Sing-box is not a project aimed to please users who can't make any meaningful contributions and gain unethical influence. If you deceive here to deliberately waste the time of the developers, you will be permanently blocked.
options:
- label: I confirm that I have read the documentation, understand the meaning of all the configuration items I wrote, and did not pile up seemingly useful options or default values.
required: true
- label: I confirm that I have provided the server and client configuration files and process that can be reproduced locally, instead of a complicated client configuration file that has been stripped of sensitive data.
required: true
- label: I confirm that I have provided the simplest configuration that can be used to reproduce the error I reported, instead of depending on remote servers, TUN, graphical interface clients, or other closed-source software.
required: true
- label: I confirm that I have provided the complete configuration files and logs, rather than just providing parts I think are useful out of confidence in my own intelligence.
required: true
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report_zh.yml
================================================
name: 错误反馈
description: "提交 sing-box 漏洞"
body:
- type: dropdown
attributes:
label: 操作系统
description: 请提供操作系统类型
options:
- iOS
- macOS
- Apple tvOS
- Android
- Windows
- Linux
- 其他
validations:
required: true
- type: input
attributes:
label: 系统版本
description: 请提供操作系统版本
validations:
required: true
- type: dropdown
attributes:
label: 安装类型
description: 请提供该 sing-box 安装类型
options:
- sing-box 原始命令行程序
- sing-box for iOS 图形客户端程序
- sing-box for macOS 图形客户端程序
- sing-box for Apple tvOS 图形客户端程序
- sing-box for Android 图形客户端程序
- 宣传使用 sing-box 的第三方图形客户端程序 (Windows)
- 宣传使用 sing-box 的第三方图形客户端程序 (Android)
- 其他
validations:
required: true
- type: input
attributes:
description: 图形客户端版本
label: 如果您使用图形客户端程序,请提供该程序版本。
- type: textarea
attributes:
label: 版本
description: 如果您使用原始命令行程序,请提供 `sing-box version` 命令的输出。
render: shell
- type: textarea
attributes:
label: 描述
description: 请提供错误的详细描述。
validations:
required: true
- type: textarea
attributes:
label: 重现方式
description: 请提供重现错误的步骤,必须包括可以在本地(不依赖与远程服务器)使用 sing-box 原始命令行程序重现错误的配置文件与流程。
validations:
required: true
- type: textarea
attributes:
label: 日志
description: |-
此外,如果您遭遇图形界面应用程序崩溃,请附加提供崩溃日志。
对于 Apple 平台图形客户端程序,请检查 `Settings - View Service Log` 以导出崩溃日志。
对于 Android 图形客户端程序,请检查 `/sdcard/Android/data/io.nekohasekai.sfa/files/stderr.log` 文件以导出崩溃日志。
render: shell
- type: checkboxes
id: supporter
attributes:
label: 支持我们
options:
- label: 我已经 [赞助](https://github.com/sponsors/nekohasekai/)
- type: checkboxes
attributes:
label: 完整性要求
description: |-
请勾选以下所有选项以证明您已经阅读并理解了以下要求,否则该 issue 将被关闭。
sing-box 不是讨好无法作出任何意义上的贡献的最终用户并获取非道德影响力的项目,如果您在此处欺骗以故意浪费开发者的时间,您将被永久封锁。
options:
- label: 我保证阅读了文档,了解所有我编写的配置文件项的含义,而不是大量堆砌看似有用的选项或默认值。
required: true
- label: 我保证提供了可以在本地重现该问题的服务器、客户端配置文件与流程,而不是一个脱敏的复杂客户端配置文件。
required: true
- label: 我保证提供了可用于重现我报告的错误的最简配置,而不是依赖远程服务器、TUN、图形界面客户端或者其他闭源软件。
required: true
- label: 我保证提供了完整的配置文件与日志,而不是出于对自身智力的自信而仅提供了部分认为有用的部分。
required: true
================================================
FILE: .github/build_alpine_apk.sh
================================================
#!/usr/bin/env bash
set -e -o pipefail
prepare_apk_root() {
# apk mkpkg resolves owner/group names through --root/etc/{passwd,group}.
APK_ROOT_DIR=$(mktemp -d)
mkdir -p "$APK_ROOT_DIR/etc"
cat > "$APK_ROOT_DIR/etc/passwd" <<EOF
root:x:$(id -u):$(id -g):root:/root:/sbin/nologin
EOF
cat > "$APK_ROOT_DIR/etc/group" <<EOF
root:x:$(id -g):root
EOF
}
ARCHITECTURE="$1"
VERSION="$2"
BINARY_PATH="$3"
OUTPUT_PATH="$4"
if [ -z "$ARCHITECTURE" ] || [ -z "$VERSION" ] || [ -z "$BINARY_PATH" ] || [ -z "$OUTPUT_PATH" ]; then
echo "Usage: $0 <architecture> <version> <binary_path> <output_path>"
exit 1
fi
PROJECT=$(cd "$(dirname "$0")/.."; pwd)
# Convert version to APK format:
# 1.13.0-beta.8 -> 1.13.0_beta8-r0
# 1.13.0-rc.3 -> 1.13.0_rc3-r0
# 1.13.0 -> 1.13.0-r0
APK_VERSION=$(echo "$VERSION" | sed -E 's/-([a-z]+)\.([0-9]+)/_\1\2/')
APK_VERSION="${APK_VERSION}-r0"
ROOT_DIR=$(mktemp -d)
prepare_apk_root
trap 'rm -rf "$ROOT_DIR" "$APK_ROOT_DIR"' EXIT
# Binary
install -Dm755 "$BINARY_PATH" "$ROOT_DIR/usr/bin/sing-box"
# Config files
install -Dm644 "$PROJECT/release/config/config.json" "$ROOT_DIR/etc/sing-box/config.json"
install -Dm755 "$PROJECT/release/config/sing-box.initd" "$ROOT_DIR/etc/init.d/sing-box"
install -Dm644 "$PROJECT/release/config/sing-box.confd" "$ROOT_DIR/etc/conf.d/sing-box"
# Service files
install -Dm644 "$PROJECT/release/config/sing-box.service" "$ROOT_DIR/usr/lib/systemd/system/sing-box.service"
install -Dm644 "$PROJECT/release/config/sing-box@.service" "$ROOT_DIR/usr/lib/systemd/system/sing-box@.service"
# Completions
install -Dm644 "$PROJECT/release/completions/sing-box.bash" "$ROOT_DIR/usr/share/bash-completion/completions/sing-box.bash"
install -Dm644 "$PROJECT/release/completions/sing-box.fish" "$ROOT_DIR/usr/share/fish/vendor_completions.d/sing-box.fish"
install -Dm644 "$PROJECT/release/completions/sing-box.zsh" "$ROOT_DIR/usr/share/zsh/site-functions/_sing-box"
# License
install -Dm644 "$PROJECT/LICENSE" "$ROOT_DIR/usr/share/licenses/sing-box/LICENSE"
# APK metadata
PACKAGES_DIR="$ROOT_DIR/lib/apk/packages"
mkdir -p "$PACKAGES_DIR"
# .conffiles
cat > "$PACKAGES_DIR/.conffiles" <<'EOF'
/etc/conf.d/sing-box
/etc/init.d/sing-box
/etc/sing-box/config.json
EOF
# .conffiles_static (sha256 checksums)
while IFS= read -r conffile; do
sha256=$(sha256sum "$ROOT_DIR$conffile" | cut -d' ' -f1)
echo "$conffile $sha256"
done < "$PACKAGES_DIR/.conffiles" > "$PACKAGES_DIR/.conffiles_static"
# .list (all files, excluding lib/apk/packages/ metadata)
(cd "$ROOT_DIR" && find . -type f -o -type l) \
| sed 's|^\./|/|' \
| grep -v '^/lib/apk/packages/' \
| sort > "$PACKAGES_DIR/.list"
# Build APK
apk --root "$APK_ROOT_DIR" mkpkg \
--info "name:sing-box" \
--info "version:${APK_VERSION}" \
--info "description:The universal proxy platform." \
--info "arch:${ARCHITECTURE}" \
--info "license:GPL-3.0-or-later with name use or association addition" \
--info "origin:sing-box" \
--info "url:https://sing-box.sagernet.org/" \
--info "maintainer:nekohasekai <contact-git@sekai.icu>" \
--files "$ROOT_DIR" \
--output "$OUTPUT_PATH"
================================================
FILE: .github/build_openwrt_apk.sh
================================================
#!/usr/bin/env bash
set -e -o pipefail
prepare_apk_root() {
# apk mkpkg resolves owner/group names through --root/etc/{passwd,group}.
APK_ROOT_DIR=$(mktemp -d)
mkdir -p "$APK_ROOT_DIR/etc"
cat > "$APK_ROOT_DIR/etc/passwd" <<EOF
root:x:$(id -u):$(id -g):root:/root:/sbin/nologin
EOF
cat > "$APK_ROOT_DIR/etc/group" <<EOF
root:x:$(id -g):root
EOF
}
ARCHITECTURE="$1"
VERSION="$2"
BINARY_PATH="$3"
OUTPUT_PATH="$4"
if [ -z "$ARCHITECTURE" ] || [ -z "$VERSION" ] || [ -z "$BINARY_PATH" ] || [ -z "$OUTPUT_PATH" ]; then
echo "Usage: $0 <architecture> <version> <binary_path> <output_path>"
exit 1
fi
PROJECT=$(cd "$(dirname "$0")/.."; pwd)
# Convert version to APK format:
# 1.13.0-beta.8 -> 1.13.0_beta8-r0
# 1.13.0-rc.3 -> 1.13.0_rc3-r0
# 1.13.0 -> 1.13.0-r0
APK_VERSION=$(echo "$VERSION" | sed -E 's/-([a-z]+)\.([0-9]+)/_\1\2/')
APK_VERSION="${APK_VERSION}-r0"
ROOT_DIR=$(mktemp -d)
prepare_apk_root
trap 'rm -rf "$ROOT_DIR" "$APK_ROOT_DIR"' EXIT
# Binary
install -Dm755 "$BINARY_PATH" "$ROOT_DIR/usr/bin/sing-box"
# Config files
install -Dm644 "$PROJECT/release/config/config.json" "$ROOT_DIR/etc/sing-box/config.json"
install -Dm644 "$PROJECT/release/config/openwrt.conf" "$ROOT_DIR/etc/config/sing-box"
install -Dm755 "$PROJECT/release/config/openwrt.init" "$ROOT_DIR/etc/init.d/sing-box"
install -Dm644 "$PROJECT/release/config/openwrt.keep" "$ROOT_DIR/lib/upgrade/keep.d/sing-box"
# Completions
install -Dm644 "$PROJECT/release/completions/sing-box.bash" "$ROOT_DIR/usr/share/bash-completion/completions/sing-box.bash"
install -Dm644 "$PROJECT/release/completions/sing-box.fish" "$ROOT_DIR/usr/share/fish/vendor_completions.d/sing-box.fish"
install -Dm644 "$PROJECT/release/completions/sing-box.zsh" "$ROOT_DIR/usr/share/zsh/site-functions/_sing-box"
# License
install -Dm644 "$PROJECT/LICENSE" "$ROOT_DIR/usr/share/licenses/sing-box/LICENSE"
# APK metadata
PACKAGES_DIR="$ROOT_DIR/lib/apk/packages"
mkdir -p "$PACKAGES_DIR"
# .conffiles
cat > "$PACKAGES_DIR/.conffiles" <<'EOF'
/etc/config/sing-box
/etc/sing-box/config.json
EOF
# .conffiles_static (sha256 checksums)
while IFS= read -r conffile; do
sha256=$(sha256sum "$ROOT_DIR$conffile" | cut -d' ' -f1)
echo "$conffile $sha256"
done < "$PACKAGES_DIR/.conffiles" > "$PACKAGES_DIR/.conffiles_static"
# .list (all files, excluding lib/apk/packages/ metadata)
(cd "$ROOT_DIR" && find . -type f -o -type l) \
| sed 's|^\./|/|' \
| grep -v '^/lib/apk/packages/' \
| sort > "$PACKAGES_DIR/.list"
# Build APK
apk --root "$APK_ROOT_DIR" mkpkg \
--info "name:sing-box" \
--info "version:${APK_VERSION}" \
--info "description:The universal proxy platform." \
--info "arch:${ARCHITECTURE}" \
--info "license:GPL-3.0-or-later" \
--info "origin:sing-box" \
--info "url:https://sing-box.sagernet.org/" \
--info "maintainer:nekohasekai <contact-git@sekai.icu>" \
--info "depends:ca-bundle kmod-inet-diag kmod-tun firewall4 kmod-nft-queue" \
--info "provider-priority:100" \
--script "pre-deinstall:${PROJECT}/release/config/openwrt.prerm" \
--files "$ROOT_DIR" \
--output "$OUTPUT_PATH"
================================================
FILE: .github/deb2ipk.sh
================================================
#!/usr/bin/env bash
# mod from https://gist.github.com/pldubouilh/c5703052986bfdd404005951dee54683
set -e -o pipefail
PROJECT=$(dirname "$0")/../..
TMP_PATH=`mktemp -d`
cp $2 $TMP_PATH
pushd $TMP_PATH
DEB_NAME=`ls *.deb`
ar x $DEB_NAME
mkdir control
pushd control
tar xf ../control.tar.gz
rm md5sums
sed "s/Architecture:\\ \w*/Architecture:\\ $1/g" ./control -i
cat control
tar czf ../control.tar.gz ./*
popd
DEB_NAME=${DEB_NAME%.deb}
tar czf $DEB_NAME.ipk control.tar.gz data.tar.gz debian-binary
popd
cp $TMP_PATH/$DEB_NAME.ipk $3
rm -r $TMP_PATH
================================================
FILE: .github/detect_track.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
branches=$(git branch -r --contains HEAD)
if echo "$branches" | grep -q 'origin/stable'; then
track=stable
elif echo "$branches" | grep -q 'origin/testing'; then
track=testing
elif echo "$branches" | grep -q 'origin/oldstable'; then
track=oldstable
else
echo "ERROR: HEAD is not on any known release branch (stable/testing/oldstable)" >&2
exit 1
fi
if [[ "$track" == "stable" ]]; then
tag=$(git describe --tags --exact-match HEAD 2>/dev/null || true)
if [[ -n "$tag" && "$tag" == *"-"* ]]; then
track=beta
fi
fi
case "$track" in
stable) name=sing-box; docker_tag=latest ;;
beta) name=sing-box-beta; docker_tag=latest-beta ;;
testing) name=sing-box-testing; docker_tag=latest-testing ;;
oldstable) name=sing-box-oldstable; docker_tag=latest-oldstable ;;
esac
echo "track=${track} name=${name} docker_tag=${docker_tag}" >&2
echo "TRACK=${track}" >> "$GITHUB_ENV"
echo "NAME=${name}" >> "$GITHUB_ENV"
echo "DOCKER_TAG=${docker_tag}" >> "$GITHUB_ENV"
================================================
FILE: .github/renovate.json
================================================
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"commitMessagePrefix": "[dependencies]",
"extends": [
"config:base",
":disableRateLimiting"
],
"baseBranches": [
"unstable"
],
"golang": {
"enabled": false
},
"packageRules": [
{
"matchManagers": [
"github-actions"
],
"groupName": "github-actions"
},
{
"matchManagers": [
"dockerfile"
],
"groupName": "Dockerfile"
}
]
}
================================================
FILE: .github/setup_go_for_macos1013.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
VERSION="1.25.9"
PATCH_COMMITS=(
"afe69d3cec1c6dcf0f1797b20546795730850070"
"1ed289b0cf87dc5aae9c6fe1aa5f200a83412938"
)
CURL_ARGS=(
-fL
--silent
--show-error
)
if [[ -n "${GITHUB_TOKEN:-}" ]]; then
CURL_ARGS+=(-H "Authorization: Bearer ${GITHUB_TOKEN}")
fi
mkdir -p "$HOME/go"
cd "$HOME/go"
wget "https://dl.google.com/go/go${VERSION}.darwin-arm64.tar.gz"
tar -xzf "go${VERSION}.darwin-arm64.tar.gz"
#cp -a go go_bootstrap
mv go go_osx
cd go_osx
# these patch URLs only work on golang1.25.x
# that means after golang1.26 release it must be changed
# see: https://github.com/SagerNet/go/commits/release-branch.go1.25/
# revert:
# 33d3f603c1: "cmd/link/internal/ld: use 12.0.0 OS/SDK versions for macOS linking"
# 937368f84e: "crypto/x509: change how we retrieve chains on darwin"
for patch_commit in "${PATCH_COMMITS[@]}"; do
curl "${CURL_ARGS[@]}" "https://github.com/SagerNet/go/commit/${patch_commit}.diff" | patch --verbose -p 1
done
# Rebuild is not needed: we build with CGO_ENABLED=1, so Apple's external
# linker handles LC_BUILD_VERSION via MACOSX_DEPLOYMENT_TARGET, and the
# stdlib (crypto/x509) is compiled from patched src automatically.
#cd src
#GOROOT_BOOTSTRAP="$HOME/go/go_bootstrap" ./make.bash
#cd ../..
#rm -rf go_bootstrap "go${VERSION}.darwin-arm64.tar.gz"
================================================
FILE: .github/setup_go_for_windows7.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
VERSION="1.25.9"
PATCH_COMMITS=(
"466f6c7a29bc098b0d4c987b803c779222894a11"
"1bdabae205052afe1dadb2ad6f1ba612cdbc532a"
"a90777dcf692dd2168577853ba743b4338721b06"
"f6bddda4e8ff58a957462a1a09562924d5f3d05c"
"bed309eff415bcb3c77dd4bc3277b682b89a388d"
"34b899c2fb39b092db4fa67c4417e41dc046be4b"
)
CURL_ARGS=(
-fL
--silent
--show-error
)
if [[ -n "${GITHUB_TOKEN:-}" ]]; then
CURL_ARGS+=(-H "Authorization: Bearer ${GITHUB_TOKEN}")
fi
mkdir -p "$HOME/go"
cd "$HOME/go"
wget "https://dl.google.com/go/go${VERSION}.linux-amd64.tar.gz"
tar -xzf "go${VERSION}.linux-amd64.tar.gz"
mv go go_win7
cd go_win7
# modify from https://github.com/restic/restic/issues/4636#issuecomment-1896455557
# these patch URLs only work on golang1.25.x
# that means after golang1.26 release it must be changed
# see: https://github.com/MetaCubeX/go/commits/release-branch.go1.25/
# revert:
# 693def151adff1af707d82d28f55dba81ceb08e1: "crypto/rand,runtime: switch RtlGenRandom for ProcessPrng"
# 7c1157f9544922e96945196b47b95664b1e39108: "net: remove sysSocket fallback for Windows 7"
# 48042aa09c2f878c4faa576948b07fe625c4707a: "syscall: remove Windows 7 console handle workaround"
# a17d959debdb04cd550016a3501dd09d50cd62e7: "runtime: always use LoadLibraryEx to load system libraries"
# fixes:
# bed309eff415bcb3c77dd4bc3277b682b89a388d: "Fix os.RemoveAll not working on Windows7"
# 34b899c2fb39b092db4fa67c4417e41dc046be4b: "Revert \"os: remove 5ms sleep on Windows in (*Process).Wait\""
for patch_commit in "${PATCH_COMMITS[@]}"; do
curl "${CURL_ARGS[@]}" "https://github.com/MetaCubeX/go/commit/${patch_commit}.diff" | patch --verbose -p 1
done
================================================
FILE: .github/update_clients.sh
================================================
#!/usr/bin/env bash
PROJECTS=$(dirname "$0")/../..
function updateClient() {
pushd clients/$1
git fetch
git reset FETCH_HEAD --hard
popd
git add clients/$1
}
updateClient "apple"
updateClient "android"
================================================
FILE: .github/update_cronet.sh
================================================
#!/usr/bin/env bash
set -e -o pipefail
SCRIPT_DIR=$(dirname "$0")
PROJECTS=$SCRIPT_DIR/../..
git -C $PROJECTS/cronet-go fetch origin main
git -C $PROJECTS/cronet-go fetch origin go
go get -x github.com/sagernet/cronet-go/all@$(git -C $PROJECTS/cronet-go rev-parse origin/go)
go get -x github.com/sagernet/cronet-go@$(git -C $PROJECTS/cronet-go rev-parse origin/go)
go mod tidy
git -C $PROJECTS/cronet-go rev-parse origin/go > "$SCRIPT_DIR/CRONET_GO_VERSION"
================================================
FILE: .github/update_cronet_dev.sh
================================================
#!/usr/bin/env bash
set -e -o pipefail
SCRIPT_DIR=$(dirname "$0")
PROJECTS=$SCRIPT_DIR/../..
git -C $PROJECTS/cronet-go fetch origin dev
git -C $PROJECTS/cronet-go fetch origin go_dev
go get -x github.com/sagernet/cronet-go/all@$(git -C $PROJECTS/cronet-go rev-parse origin/go_dev)
go get -x github.com/sagernet/cronet-go@$(git -C $PROJECTS/cronet-go rev-parse origin/go_dev)
go mod tidy
git -C $PROJECTS/cronet-go rev-parse origin/dev > "$SCRIPT_DIR/CRONET_GO_VERSION"
================================================
FILE: .github/update_dependencies.sh
================================================
#!/usr/bin/env bash
PROJECTS=$(dirname "$0")/../..
go get -x github.com/sagernet/$1@$(git -C $PROJECTS/$1 rev-parse HEAD)
go mod tidy
================================================
FILE: .github/workflows/build.yml
================================================
name: Build
on:
workflow_dispatch:
inputs:
version:
description: "Version name"
required: true
type: string
build:
description: "Build type"
required: true
type: choice
default: "All"
options:
- All
- Binary
- Android
- Apple
- app-store
- iOS
- macOS
- tvOS
- macOS-standalone
- publish-android
push:
branches:
- stable
- testing
- unstable
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}-${{ inputs.build }}
cancel-in-progress: true
jobs:
calculate_version:
name: Calculate version
runs-on: ubuntu-latest
outputs:
version: ${{ steps.outputs.outputs.version }}
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
with:
fetch-depth: 0
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ~1.25.9
- name: Check input version
if: github.event_name == 'workflow_dispatch'
run: |-
echo "version=${{ inputs.version }}"
echo "version=${{ inputs.version }}" >> "$GITHUB_ENV"
- name: Calculate version
if: github.event_name != 'workflow_dispatch'
run: |-
go run -v ./cmd/internal/read_tag --ci --nightly
- name: Set outputs
id: outputs
run: |-
echo "version=$version" >> "$GITHUB_OUTPUT"
build:
name: Build binary
if: github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Binary'
runs-on: ubuntu-latest
needs:
- calculate_version
strategy:
matrix:
include:
- { os: linux, arch: amd64, variant: purego, naive: true }
- { os: linux, arch: amd64, variant: glibc, naive: true }
- { os: linux, arch: amd64, variant: musl, naive: true, debian: amd64, rpm: x86_64, pacman: x86_64, alpine: x86_64, openwrt: "x86_64" }
- { os: linux, arch: arm64, variant: purego, naive: true }
- { os: linux, arch: arm64, variant: glibc, naive: true }
- { os: linux, arch: arm64, variant: musl, naive: true, debian: arm64, rpm: aarch64, pacman: aarch64, alpine: aarch64, openwrt: "aarch64_cortex-a53 aarch64_cortex-a72 aarch64_cortex-a76 aarch64_generic" }
- { os: linux, arch: "386", go386: sse2 }
- { os: linux, arch: "386", variant: glibc, naive: true, go386: sse2 }
- { os: linux, arch: "386", variant: musl, naive: true, go386: sse2, debian: i386, rpm: i386, alpine: x86, openwrt: "i386_pentium4" }
- { os: linux, arch: arm, goarm: "7" }
- { os: linux, arch: arm, variant: glibc, naive: true, goarm: "7" }
- { os: linux, arch: arm, variant: musl, naive: true, goarm: "7", debian: armhf, rpm: armv7hl, pacman: armv7hl, alpine: armv7, openwrt: "arm_cortex-a5_vfpv4 arm_cortex-a7_neon-vfpv4 arm_cortex-a7_vfpv4 arm_cortex-a8_vfpv3 arm_cortex-a9_neon arm_cortex-a9_vfpv3-d16 arm_cortex-a15_neon-vfpv4" }
- { os: linux, arch: mipsle, gomips: hardfloat, naive: true, variant: glibc }
- { os: linux, arch: mipsle, gomips: softfloat, naive: true, variant: musl, debian: mipsel, rpm: mipsel, openwrt: "mipsel_24kc mipsel_74kc mipsel_mips32" }
- { os: linux, arch: mips64le, gomips: hardfloat, naive: true, variant: glibc, debian: mips64el, rpm: mips64el }
- { os: linux, arch: riscv64, naive: true, variant: glibc }
- { os: linux, arch: riscv64, naive: true, variant: musl, debian: riscv64, rpm: riscv64, alpine: riscv64, openwrt: "riscv64_generic" }
- { os: linux, arch: loong64, naive: true, variant: glibc }
- { os: linux, arch: loong64, naive: true, variant: musl, debian: loongarch64, rpm: loongarch64, alpine: loongarch64, openwrt: "loongarch64_generic" }
- { os: linux, arch: "386", go386: softfloat, openwrt: "i386_pentium-mmx" }
- { os: linux, arch: arm, goarm: "5", openwrt: "arm_arm926ej-s arm_cortex-a7 arm_cortex-a9 arm_fa526 arm_xscale" }
- { os: linux, arch: arm, goarm: "6", debian: armel, rpm: armv6hl, openwrt: "arm_arm1176jzf-s_vfp" }
- { os: linux, arch: mips, gomips: softfloat, openwrt: "mips_24kc mips_4kec mips_mips32" }
- { os: linux, arch: mipsle, gomips: hardfloat, openwrt: "mipsel_24kc_24kf" }
- { os: linux, arch: mipsle, gomips: softfloat }
- { os: linux, arch: mips64, gomips: softfloat, openwrt: "mips64_mips64r2 mips64_octeonplus" }
- { os: linux, arch: mips64le, gomips: hardfloat }
- { os: linux, arch: mips64le, gomips: softfloat, openwrt: "mips64el_mips64r2" }
- { os: linux, arch: s390x, debian: s390x, rpm: s390x }
- { os: linux, arch: ppc64le, debian: ppc64el, rpm: ppc64le }
- { os: linux, arch: riscv64 }
- { os: linux, arch: loong64 }
- { os: windows, arch: amd64, legacy_win7: true, legacy_name: "windows-7" }
- { os: windows, arch: "386", legacy_win7: true, legacy_name: "windows-7" }
- { os: android, arch: arm64, ndk: "aarch64-linux-android23" }
- { os: android, arch: arm, ndk: "armv7a-linux-androideabi23" }
- { os: android, arch: amd64, ndk: "x86_64-linux-android23" }
- { os: android, arch: "386", ndk: "i686-linux-android23" }
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
with:
fetch-depth: 0
- name: Setup Go
if: ${{ ! matrix.legacy_win7 }}
uses: actions/setup-go@v5
with:
go-version: ~1.25.9
- name: Cache Go for Windows 7
if: matrix.legacy_win7
id: cache-go-for-windows7
uses: actions/cache@v4
with:
path: |
~/go/go_win7
key: go_win7_1258
- name: Setup Go for Windows 7
if: matrix.legacy_win7 && steps.cache-go-for-windows7.outputs.cache-hit != 'true'
env:
GITHUB_TOKEN: ${{ github.token }}
run: |-
.github/setup_go_for_windows7.sh
- name: Setup Go for Windows 7
if: matrix.legacy_win7
run: |-
echo "PATH=$HOME/go/go_win7/bin:$PATH" >> $GITHUB_ENV
echo "GOROOT=$HOME/go/go_win7" >> $GITHUB_ENV
- name: Setup Android NDK
if: matrix.os == 'android'
uses: nttld/setup-ndk@v1
with:
ndk-version: r28
local-cache: true
- name: Clone cronet-go
if: matrix.naive
run: |
set -xeuo pipefail
CRONET_GO_VERSION=$(cat .github/CRONET_GO_VERSION)
git init ~/cronet-go
git -C ~/cronet-go remote add origin https://github.com/sagernet/cronet-go.git
git -C ~/cronet-go fetch --depth=1 origin "$CRONET_GO_VERSION"
git -C ~/cronet-go checkout FETCH_HEAD
git -C ~/cronet-go submodule update --init --recursive --depth=1
- name: Regenerate Debian keyring
if: matrix.naive
run: |
set -xeuo pipefail
rm -f ~/cronet-go/naiveproxy/src/build/linux/sysroot_scripts/keyring.gpg
cd ~/cronet-go
GPG_TTY=/dev/null ./naiveproxy/src/build/linux/sysroot_scripts/generate_keyring.sh
- name: Cache Chromium toolchain
if: matrix.naive
id: cache-chromium-toolchain
uses: actions/cache@v4
with:
path: |
~/cronet-go/naiveproxy/src/third_party/llvm-build/
~/cronet-go/naiveproxy/src/gn/out/
~/cronet-go/naiveproxy/src/chrome/build/pgo_profiles/
~/cronet-go/naiveproxy/src/out/sysroot-build/
key: chromium-toolchain-${{ matrix.arch }}-${{ matrix.variant }}-${{ hashFiles('.github/CRONET_GO_VERSION') }}
- name: Download Chromium toolchain
if: matrix.naive
run: |
set -xeuo pipefail
cd ~/cronet-go
if [[ "${{ matrix.variant }}" == "musl" ]]; then
go run ./cmd/build-naive --target=linux/${{ matrix.arch }} --libc=musl download-toolchain
else
go run ./cmd/build-naive --target=linux/${{ matrix.arch }} download-toolchain
fi
- name: Set Chromium toolchain environment
if: matrix.naive
run: |
set -xeuo pipefail
cd ~/cronet-go
if [[ "${{ matrix.variant }}" == "musl" ]]; then
go run ./cmd/build-naive --target=linux/${{ matrix.arch }} --libc=musl env >> $GITHUB_ENV
else
go run ./cmd/build-naive --target=linux/${{ matrix.arch }} env >> $GITHUB_ENV
fi
- name: Set tag
run: |-
git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
git tag v${{ needs.calculate_version.outputs.version }} -f
- name: Set build tags
run: |
set -xeuo pipefail
if [[ "${{ matrix.naive }}" == "true" ]]; then
TAGS=$(cat release/DEFAULT_BUILD_TAGS)
else
TAGS=$(cat release/DEFAULT_BUILD_TAGS_OTHERS)
fi
if [[ "${{ matrix.variant }}" == "purego" ]]; then
TAGS="${TAGS},with_purego"
elif [[ "${{ matrix.variant }}" == "musl" ]]; then
TAGS="${TAGS},with_musl"
fi
echo "BUILD_TAGS=${TAGS}" >> "${GITHUB_ENV}"
- name: Set shared ldflags
run: |
echo "LDFLAGS_SHARED=$(cat release/LDFLAGS)" >> "${GITHUB_ENV}"
- name: Build (purego)
if: matrix.variant == 'purego'
run: |
set -xeuo pipefail
mkdir -p dist
go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \
-ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }}' ${LDFLAGS_SHARED} -s -w -buildid=" \
./cmd/sing-box
env:
CGO_ENABLED: "0"
GOOS: ${{ matrix.os }}
GOARCH: ${{ matrix.arch }}
GO386: ${{ matrix.go386 }}
GOARM: ${{ matrix.goarm }}
GOMIPS: ${{ matrix.gomips }}
GOMIPS64: ${{ matrix.gomips }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Extract libcronet.so
if: matrix.variant == 'purego' && matrix.naive
run: |
cd ~/cronet-go
CGO_ENABLED=0 go run -v ./cmd/build-naive extract-lib --target ${{ matrix.os }}/${{ matrix.arch }} -o $GITHUB_WORKSPACE/dist
- name: Build (glibc)
if: matrix.variant == 'glibc'
run: |
set -xeuo pipefail
mkdir -p dist
go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \
-ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }}' ${LDFLAGS_SHARED} -s -w -buildid=" \
./cmd/sing-box
env:
CGO_ENABLED: "1"
GOOS: linux
GOARCH: ${{ matrix.arch }}
GO386: ${{ matrix.go386 }}
GOARM: ${{ matrix.goarm }}
GOMIPS: ${{ matrix.gomips }}
GOMIPS64: ${{ matrix.gomips }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build (musl)
if: matrix.variant == 'musl'
run: |
set -xeuo pipefail
mkdir -p dist
go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \
-ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }}' ${LDFLAGS_SHARED} -s -w -buildid=" \
./cmd/sing-box
env:
CGO_ENABLED: "1"
GOOS: linux
GOARCH: ${{ matrix.arch }}
GO386: ${{ matrix.go386 }}
GOARM: ${{ matrix.goarm }}
GOMIPS: ${{ matrix.gomips }}
GOMIPS64: ${{ matrix.gomips }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build (non-variant)
if: matrix.os != 'android' && matrix.variant == ''
run: |
set -xeuo pipefail
mkdir -p dist
go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \
-ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }}' ${LDFLAGS_SHARED} -s -w -buildid=" \
./cmd/sing-box
env:
CGO_ENABLED: "0"
GOOS: ${{ matrix.os }}
GOARCH: ${{ matrix.arch }}
GO386: ${{ matrix.go386 }}
GOARM: ${{ matrix.goarm }}
GOMIPS: ${{ matrix.gomips }}
GOMIPS64: ${{ matrix.gomips }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build Android
if: matrix.os == 'android'
run: |
set -xeuo pipefail
go install -v ./cmd/internal/build
export CC='${{ matrix.ndk }}-clang'
export CXX="${CC}++"
mkdir -p dist
GOOS=$BUILD_GOOS GOARCH=$BUILD_GOARCH build go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \
-ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }}' ${LDFLAGS_SHARED} -s -w -buildid=" \
./cmd/sing-box
env:
CGO_ENABLED: "1"
BUILD_GOOS: ${{ matrix.os }}
BUILD_GOARCH: ${{ matrix.arch }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Set name
run: |-
DIR_NAME="sing-box-${{ needs.calculate_version.outputs.version }}-${{ matrix.os }}-${{ matrix.arch }}"
if [[ -n "${{ matrix.goarm }}" ]]; then
DIR_NAME="${DIR_NAME}v${{ matrix.goarm }}"
elif [[ -n "${{ matrix.go386 }}" && "${{ matrix.go386 }}" != 'sse2' ]]; then
DIR_NAME="${DIR_NAME}-${{ matrix.go386 }}"
elif [[ -n "${{ matrix.gomips }}" && "${{ matrix.gomips }}" != 'hardfloat' ]]; then
DIR_NAME="${DIR_NAME}-${{ matrix.gomips }}"
elif [[ -n "${{ matrix.legacy_name }}" ]]; then
DIR_NAME="${DIR_NAME}-legacy-${{ matrix.legacy_name }}"
fi
if [[ "${{ matrix.variant }}" == "glibc" ]]; then
DIR_NAME="${DIR_NAME}-glibc"
elif [[ "${{ matrix.variant }}" == "musl" ]]; then
DIR_NAME="${DIR_NAME}-musl"
fi
echo "DIR_NAME=${DIR_NAME}" >> "${GITHUB_ENV}"
PKG_VERSION="${{ needs.calculate_version.outputs.version }}"
PKG_VERSION="${PKG_VERSION//-/\~}"
echo "PKG_VERSION=${PKG_VERSION}" >> "${GITHUB_ENV}"
- name: Package DEB
if: matrix.debian != ''
run: |
set -xeuo pipefail
sudo gem install fpm
sudo apt-get update
sudo apt-get install -y debsigs
cp .fpm_systemd .fpm
fpm -t deb \
-v "$PKG_VERSION" \
-p "dist/sing-box_${{ needs.calculate_version.outputs.version }}_${{ matrix.os }}_${{ matrix.debian }}.deb" \
--architecture ${{ matrix.debian }} \
dist/sing-box=/usr/bin/sing-box
curl -Lo '/tmp/debsigs.diff' 'https://gitlab.com/debsigs/debsigs/-/commit/160138f5de1ec110376d3c807b60a37388bc7c90.diff'
sudo patch /usr/bin/debsigs < '/tmp/debsigs.diff'
rm -rf $HOME/.gnupg
gpg --pinentry-mode loopback --passphrase "${{ secrets.GPG_PASSPHRASE }}" --import <<EOF
${{ secrets.GPG_KEY }}
EOF
debsigs --sign=origin -k ${{ secrets.GPG_KEY_ID }} --gpgopts '--pinentry-mode loopback --passphrase "${{ secrets.GPG_PASSPHRASE }}"' dist/*.deb
- name: Package RPM
if: matrix.rpm != ''
run: |-
set -xeuo pipefail
sudo gem install fpm
cp .fpm_systemd .fpm
fpm -t rpm \
-v "$PKG_VERSION" \
-p "dist/sing-box_${{ needs.calculate_version.outputs.version }}_${{ matrix.os }}_${{ matrix.rpm }}.rpm" \
--architecture ${{ matrix.rpm }} \
dist/sing-box=/usr/bin/sing-box
cat > $HOME/.rpmmacros <<EOF
%_gpg_name ${{ secrets.GPG_KEY_ID }}
%_gpg_sign_cmd_extra_args --pinentry-mode loopback --passphrase ${{ secrets.GPG_PASSPHRASE }}
EOF
gpg --pinentry-mode loopback --passphrase "${{ secrets.GPG_PASSPHRASE }}" --import <<EOF
${{ secrets.GPG_KEY }}
EOF
rpmsign --addsign dist/*.rpm
- name: Package Pacman
if: matrix.pacman != ''
run: |-
set -xeuo pipefail
sudo gem install fpm
sudo apt-get update
sudo apt-get install -y libarchive-tools
cp .fpm_pacman .fpm
fpm -t pacman \
-v "$PKG_VERSION" \
-p "dist/sing-box_${{ needs.calculate_version.outputs.version }}_${{ matrix.os }}_${{ matrix.pacman }}.pkg.tar.zst" \
--architecture ${{ matrix.pacman }} \
dist/sing-box=/usr/bin/sing-box
- name: Package OpenWrt
if: matrix.openwrt != ''
run: |-
set -xeuo pipefail
sudo gem install fpm
cp .fpm_openwrt .fpm
fpm -t deb \
-v "$PKG_VERSION" \
-p "dist/openwrt.deb" \
--architecture all \
dist/sing-box=/usr/bin/sing-box
for architecture in ${{ matrix.openwrt }}; do
.github/deb2ipk.sh "$architecture" "dist/openwrt.deb" "dist/sing-box_${{ needs.calculate_version.outputs.version }}_openwrt_${architecture}.ipk"
done
rm "dist/openwrt.deb"
- name: Install apk-tools
if: matrix.openwrt != '' || matrix.alpine != ''
run: |-
docker run --rm -v /usr/local/bin:/mnt alpine:edge sh -c "apk add --no-cache apk-tools-static && cp /sbin/apk.static /mnt/apk && chmod +x /mnt/apk"
- name: Package OpenWrt APK
if: matrix.openwrt != ''
run: |-
set -xeuo pipefail
for architecture in ${{ matrix.openwrt }}; do
.github/build_openwrt_apk.sh \
"$architecture" \
"${{ needs.calculate_version.outputs.version }}" \
"dist/sing-box" \
"dist/sing-box_${{ needs.calculate_version.outputs.version }}_openwrt_${architecture}.apk"
done
- name: Package Alpine APK
if: matrix.alpine != ''
run: |-
set -xeuo pipefail
.github/build_alpine_apk.sh \
"${{ matrix.alpine }}" \
"${{ needs.calculate_version.outputs.version }}" \
"dist/sing-box" \
"dist/sing-box_${{ needs.calculate_version.outputs.version }}_linux_${{ matrix.alpine }}.apk"
- name: Archive
run: |
set -xeuo pipefail
cd dist
mkdir -p "${DIR_NAME}"
cp ../LICENSE "${DIR_NAME}"
if [ '${{ matrix.os }}' = 'windows' ]; then
cp sing-box "${DIR_NAME}/sing-box.exe"
zip -r "${DIR_NAME}.zip" "${DIR_NAME}"
else
cp sing-box "${DIR_NAME}"
if [ -f libcronet.so ]; then
cp libcronet.so "${DIR_NAME}"
fi
tar -czvf "${DIR_NAME}.tar.gz" "${DIR_NAME}"
fi
rm -r "${DIR_NAME}"
- name: Cleanup
run: rm -f dist/sing-box dist/libcronet.so
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: binary-${{ matrix.os }}_${{ matrix.arch }}${{ matrix.goarm && format('v{0}', matrix.goarm) }}${{ matrix.go386 && format('_{0}', matrix.go386) }}${{ matrix.gomips && format('_{0}', matrix.gomips) }}${{ matrix.legacy_name && format('-legacy-{0}', matrix.legacy_name) }}${{ matrix.variant && format('-{0}', matrix.variant) }}
path: "dist"
build_darwin:
name: Build Darwin binaries
if: github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Binary'
runs-on: macos-latest
needs:
- calculate_version
strategy:
matrix:
include:
- { arch: amd64 }
- { arch: arm64 }
- { arch: amd64, legacy_osx: true, legacy_name: "macos-10.13" }
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
with:
fetch-depth: 0
- name: Setup Go
if: ${{ ! matrix.legacy_osx }}
uses: actions/setup-go@v5
with:
go-version: ^1.25.3
- name: Cache Go for macOS 10.13
if: matrix.legacy_osx
id: cache-go-for-macos1013
uses: actions/cache@v4
with:
path: |
~/go/go_osx
key: go_osx_1258
- name: Setup Go for macOS 10.13
if: matrix.legacy_osx && steps.cache-go-for-macos1013.outputs.cache-hit != 'true'
env:
GITHUB_TOKEN: ${{ github.token }}
run: |-
.github/setup_go_for_macos1013.sh
- name: Setup Go for macOS 10.13
if: matrix.legacy_osx
run: |-
echo "PATH=$HOME/go/go_osx/bin:$PATH" >> $GITHUB_ENV
echo "GOROOT=$HOME/go/go_osx" >> $GITHUB_ENV
- name: Set tag
run: |-
git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
git tag v${{ needs.calculate_version.outputs.version }} -f
- name: Set build tags
run: |
set -xeuo pipefail
if [[ "${{ matrix.legacy_osx }}" != "true" ]]; then
TAGS=$(cat release/DEFAULT_BUILD_TAGS)
else
TAGS=$(cat release/DEFAULT_BUILD_TAGS_OTHERS)
fi
echo "BUILD_TAGS=${TAGS}" >> "${GITHUB_ENV}"
- name: Set shared ldflags
run: |
echo "LDFLAGS_SHARED=$(cat release/LDFLAGS)" >> "${GITHUB_ENV}"
- name: Build
run: |
set -xeuo pipefail
mkdir -p dist
go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \
-ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }}' ${LDFLAGS_SHARED} -s -w -buildid=" \
./cmd/sing-box
env:
CGO_ENABLED: "1"
GOOS: darwin
GOARCH: ${{ matrix.arch }}
MACOSX_DEPLOYMENT_TARGET: ${{ matrix.legacy_osx && '10.13' || '' }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Set name
run: |-
DIR_NAME="sing-box-${{ needs.calculate_version.outputs.version }}-darwin-${{ matrix.arch }}"
if [[ -n "${{ matrix.legacy_name }}" ]]; then
DIR_NAME="${DIR_NAME}-legacy-${{ matrix.legacy_name }}"
fi
echo "DIR_NAME=${DIR_NAME}" >> "${GITHUB_ENV}"
- name: Archive
run: |
set -xeuo pipefail
cd dist
mkdir -p "${DIR_NAME}"
cp ../LICENSE "${DIR_NAME}"
cp sing-box "${DIR_NAME}"
tar -czvf "${DIR_NAME}.tar.gz" "${DIR_NAME}"
rm -r "${DIR_NAME}"
- name: Cleanup
run: rm dist/sing-box
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: binary-darwin_${{ matrix.arch }}${{ matrix.legacy_name && format('-legacy-{0}', matrix.legacy_name) }}
path: "dist"
build_windows:
name: Build Windows binaries
if: github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Binary'
runs-on: windows-latest
needs:
- calculate_version
strategy:
matrix:
include:
- { arch: amd64, naive: true }
- { arch: "386" }
- { arch: arm64, naive: true }
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
with:
fetch-depth: 0
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ^1.25.4
- name: Set tag
run: |-
git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$env:GITHUB_ENV"
git tag v${{ needs.calculate_version.outputs.version }} -f
- name: Build
if: matrix.naive
run: |
$TAGS = Get-Content release/DEFAULT_BUILD_TAGS_WINDOWS
$LDFLAGS_SHARED = Get-Content release/LDFLAGS
mkdir -p dist
go build -v -trimpath -o dist/sing-box.exe -tags "$TAGS" `
-ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }}' $LDFLAGS_SHARED -s -w -buildid=" `
./cmd/sing-box
env:
CGO_ENABLED: "0"
GOOS: windows
GOARCH: ${{ matrix.arch }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build
if: ${{ !matrix.naive }}
run: |
$TAGS = Get-Content release/DEFAULT_BUILD_TAGS_OTHERS
$LDFLAGS_SHARED = Get-Content release/LDFLAGS
mkdir -p dist
go build -v -trimpath -o dist/sing-box.exe -tags "$TAGS" `
-ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }}' $LDFLAGS_SHARED -s -w -buildid=" `
./cmd/sing-box
env:
CGO_ENABLED: "0"
GOOS: windows
GOARCH: ${{ matrix.arch }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Extract libcronet.dll
if: matrix.naive
run: |
$CRONET_GO_VERSION = Get-Content .github/CRONET_GO_VERSION
$env:CGO_ENABLED = "0"
go run -v "github.com/sagernet/cronet-go/cmd/build-naive@$CRONET_GO_VERSION" extract-lib --target windows/${{ matrix.arch }} -o dist
- name: Archive
if: matrix.naive
run: |
$DIR_NAME = "sing-box-${{ needs.calculate_version.outputs.version }}-windows-${{ matrix.arch }}"
mkdir "dist/$DIR_NAME"
Copy-Item LICENSE "dist/$DIR_NAME"
Copy-Item "dist/sing-box.exe" "dist/$DIR_NAME"
Copy-Item "dist/libcronet.dll" "dist/$DIR_NAME"
Compress-Archive -Path "dist/$DIR_NAME" -DestinationPath "dist/$DIR_NAME.zip"
Remove-Item -Recurse "dist/$DIR_NAME"
- name: Archive
if: ${{ !matrix.naive }}
run: |
$DIR_NAME = "sing-box-${{ needs.calculate_version.outputs.version }}-windows-${{ matrix.arch }}"
mkdir "dist/$DIR_NAME"
Copy-Item LICENSE "dist/$DIR_NAME"
Copy-Item "dist/sing-box.exe" "dist/$DIR_NAME"
Compress-Archive -Path "dist/$DIR_NAME" -DestinationPath "dist/$DIR_NAME.zip"
Remove-Item -Recurse "dist/$DIR_NAME"
- name: Cleanup
if: matrix.naive
run: Remove-Item dist/sing-box.exe, dist/libcronet.dll
- name: Cleanup
if: ${{ !matrix.naive }}
run: Remove-Item dist/sing-box.exe
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: binary-windows_${{ matrix.arch }}
path: "dist"
build_android:
name: Build Android
if: (github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Android') && github.ref != 'refs/heads/oldstable'
runs-on: ubuntu-latest
needs:
- calculate_version
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
with:
fetch-depth: 0
submodules: 'recursive'
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ~1.25.9
- name: Setup Android NDK
id: setup-ndk
uses: nttld/setup-ndk@v1
with:
ndk-version: r28
- name: Setup OpenJDK
run: |-
sudo apt update && sudo apt install -y openjdk-17-jdk-headless
/usr/lib/jvm/java-17-openjdk-amd64/bin/java --version
- name: Set tag
run: |-
git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
git tag v${{ needs.calculate_version.outputs.version }} -f
- name: Build library
run: |-
make lib_install
export PATH="$PATH:$(go env GOPATH)/bin"
make lib_android
env:
JAVA_HOME: /usr/lib/jvm/java-17-openjdk-amd64
ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
- name: Checkout main branch
if: github.ref == 'refs/heads/stable' && github.event_name != 'workflow_dispatch'
run: |-
cd clients/android
git checkout main
- name: Checkout dev branch
if: github.ref == 'refs/heads/testing'
run: |-
cd clients/android
git checkout dev
- name: Gradle cache
uses: actions/cache@v4
with:
path: ~/.gradle
key: gradle-${{ hashFiles('**/*.gradle') }}
- name: Update version
if: github.event_name == 'workflow_dispatch'
run: |-
go run -v ./cmd/internal/update_android_version --ci
- name: Update nightly version
if: github.event_name != 'workflow_dispatch'
run: |-
go run -v ./cmd/internal/update_android_version --ci --nightly
- name: Build
run: |-
mkdir clients/android/app/libs
cp *.aar clients/android/app/libs
cd clients/android
./gradlew :app:assembleOtherRelease :app:assembleOtherLegacyRelease
env:
JAVA_HOME: /usr/lib/jvm/java-17-openjdk-amd64
ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
LOCAL_PROPERTIES: ${{ secrets.LOCAL_PROPERTIES }}
- name: Prepare upload
run: |-
mkdir -p dist
#cp clients/android/app/build/outputs/apk/play/release/*.apk dist
cp clients/android/app/build/outputs/apk/other/release/*.apk dist
cp clients/android/app/build/outputs/apk/otherLegacy/release/*.apk dist
VERSION_CODE=$(grep VERSION_CODE clients/android/version.properties | cut -d= -f2)
VERSION_NAME=$(grep VERSION_NAME clients/android/version.properties | cut -d= -f2)
cat > dist/SFA-version-metadata.json << EOF
{
"version_code": ${VERSION_CODE},
"version_name": "${VERSION_NAME}"
}
EOF
cat dist/SFA-version-metadata.json
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: binary-android-apks
path: 'dist'
publish_android:
name: Publish Android
if: github.event_name == 'workflow_dispatch' && inputs.build == 'publish-android' && github.ref != 'refs/heads/oldstable'
runs-on: ubuntu-latest
needs:
- calculate_version
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
with:
fetch-depth: 0
submodules: 'recursive'
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ~1.25.9
- name: Setup Android NDK
id: setup-ndk
uses: nttld/setup-ndk@v1
with:
ndk-version: r28
- name: Setup OpenJDK
run: |-
sudo apt update && sudo apt install -y openjdk-17-jdk-headless
/usr/lib/jvm/java-17-openjdk-amd64/bin/java --version
- name: Set tag
run: |-
git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
git tag v${{ needs.calculate_version.outputs.version }} -f
- name: Build library
run: |-
make lib_install
export PATH="$PATH:$(go env GOPATH)/bin"
make lib_android
env:
JAVA_HOME: /usr/lib/jvm/java-17-openjdk-amd64
ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
- name: Checkout main branch
if: github.ref == 'refs/heads/stable' && github.event_name != 'workflow_dispatch'
run: |-
cd clients/android
git checkout main
- name: Checkout dev branch
if: github.ref == 'refs/heads/testing'
run: |-
cd clients/android
git checkout dev
- name: Gradle cache
uses: actions/cache@v4
with:
path: ~/.gradle
key: gradle-${{ hashFiles('**/*.gradle') }}
- name: Build
run: |-
go run -v ./cmd/internal/update_android_version --ci
mkdir clients/android/app/libs
cp *.aar clients/android/app/libs
cd clients/android
echo -n "$SERVICE_ACCOUNT_CREDENTIALS" | base64 --decode > service-account-credentials.json
./gradlew :app:publishPlayReleaseBundle
env:
JAVA_HOME: /usr/lib/jvm/java-17-openjdk-amd64
ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
LOCAL_PROPERTIES: ${{ secrets.LOCAL_PROPERTIES }}
SERVICE_ACCOUNT_CREDENTIALS: ${{ secrets.SERVICE_ACCOUNT_CREDENTIALS }}
build_apple:
name: Build Apple clients
runs-on: macos-26
if: false # github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Apple' || inputs.build == 'app-store' || inputs.build == 'iOS' || inputs.build == 'macOS' || inputs.build == 'tvOS' || inputs.build == 'macOS-standalone'
needs:
- calculate_version
strategy:
matrix:
include:
- name: iOS
if: ${{ github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Apple' || inputs.build == 'app-store'|| inputs.build == 'iOS' }}
platform: ios
scheme: SFI
destination: 'generic/platform=iOS'
archive: build/SFI.xcarchive
upload: SFI/Upload.plist
- name: macOS
if: ${{ github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Apple' || inputs.build == 'app-store'|| inputs.build == 'macOS' }}
platform: macos
scheme: SFM
destination: 'generic/platform=macOS'
archive: build/SFM.xcarchive
upload: SFI/Upload.plist
- name: tvOS
if: ${{ github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Apple' || inputs.build == 'app-store'|| inputs.build == 'tvOS' }}
platform: tvos
scheme: SFT
destination: 'generic/platform=tvOS'
archive: build/SFT.xcarchive
upload: SFI/Upload.plist
- name: macOS-standalone
if: ${{ github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Apple' || inputs.build == 'macOS-standalone' }}
platform: macos
scheme: SFM.System
destination: 'generic/platform=macOS'
archive: build/SFM.System.xcarchive
export: SFM.System/Export.plist
export_path: build/SFM.System
steps:
- name: Checkout
if: matrix.if
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
with:
fetch-depth: 0
submodules: 'recursive'
- name: Setup Go
if: matrix.if
uses: actions/setup-go@v5
with:
go-version: ~1.25.9
- name: Set tag
if: matrix.if
run: |-
git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
git tag v${{ needs.calculate_version.outputs.version }} -f
echo "VERSION=${{ needs.calculate_version.outputs.version }}" >> "$GITHUB_ENV"
- name: Checkout main branch
if: matrix.if && github.ref == 'refs/heads/stable' && github.event_name != 'workflow_dispatch'
run: |-
cd clients/apple
git checkout main
- name: Checkout dev branch
if: matrix.if && github.ref == 'refs/heads/testing'
run: |-
cd clients/apple
git checkout dev
- name: Setup certificates
if: matrix.if
run: |-
CERTIFICATE_PATH=$RUNNER_TEMP/Certificates.p12
KEYCHAIN_PATH=$RUNNER_TEMP/certificates.keychain-db
echo -n "$CERTIFICATES_P12" | base64 --decode -o $CERTIFICATE_PATH
security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
security import $CERTIFICATE_PATH -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
security list-keychain -d user -s $KEYCHAIN_PATH
PROFILES_ZIP_PATH=$RUNNER_TEMP/Profiles.zip
echo -n "$PROVISIONING_PROFILES" | base64 --decode -o $PROFILES_ZIP_PATH
PROFILES_PATH="$HOME/Library/MobileDevice/Provisioning Profiles"
mkdir -p "$PROFILES_PATH"
unzip $PROFILES_ZIP_PATH -d "$PROFILES_PATH"
ASC_KEY_PATH=$RUNNER_TEMP/Key.p12
echo -n "$ASC_KEY" | base64 --decode -o $ASC_KEY_PATH
xcrun notarytool store-credentials "notarytool-password" \
--key $ASC_KEY_PATH \
--key-id $ASC_KEY_ID \
--issuer $ASC_KEY_ISSUER_ID
echo "ASC_KEY_PATH=$ASC_KEY_PATH" >> "$GITHUB_ENV"
echo "ASC_KEY_ID=$ASC_KEY_ID" >> "$GITHUB_ENV"
echo "ASC_KEY_ISSUER_ID=$ASC_KEY_ISSUER_ID" >> "$GITHUB_ENV"
env:
CERTIFICATES_P12: ${{ secrets.CERTIFICATES_P12 }}
P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
KEYCHAIN_PASSWORD: ${{ secrets.P12_PASSWORD }}
PROVISIONING_PROFILES: ${{ secrets.PROVISIONING_PROFILES }}
ASC_KEY: ${{ secrets.ASC_KEY }}
ASC_KEY_ID: ${{ secrets.ASC_KEY_ID }}
ASC_KEY_ISSUER_ID: ${{ secrets.ASC_KEY_ISSUER_ID }}
- name: Build library
if: matrix.if
run: |-
make lib_install
export PATH="$PATH:$(go env GOPATH)/bin"
go run ./cmd/internal/build_libbox -target apple -platform ${{ matrix.platform }}
mv Libbox.xcframework clients/apple
- name: Update macOS version
if: matrix.if && matrix.name == 'macOS' && github.event_name == 'workflow_dispatch'
run: |-
MACOS_PROJECT_VERSION=$(go run -v ./cmd/internal/app_store_connect next_macos_project_version)
echo "MACOS_PROJECT_VERSION=$MACOS_PROJECT_VERSION"
echo "MACOS_PROJECT_VERSION=$MACOS_PROJECT_VERSION" >> "$GITHUB_ENV"
- name: Update version
if: matrix.if && matrix.name != 'iOS'
run: |-
go run -v ./cmd/internal/update_apple_version --ci
- name: Build
if: matrix.if
run: |-
cd clients/apple
xcodebuild archive \
-scheme "${{ matrix.scheme }}" \
-configuration Release \
-destination "${{ matrix.destination }}" \
-archivePath "${{ matrix.archive }}" \
-allowProvisioningUpdates \
-authenticationKeyPath $ASC_KEY_PATH \
-authenticationKeyID $ASC_KEY_ID \
-authenticationKeyIssuerID $ASC_KEY_ISSUER_ID
- name: Upload to App Store Connect
if: matrix.if && matrix.name != 'macOS-standalone' && github.event_name == 'workflow_dispatch'
run: |-
go run -v ./cmd/internal/app_store_connect cancel_app_store ${{ matrix.platform }}
cd clients/apple
xcodebuild -exportArchive \
-archivePath "${{ matrix.archive }}" \
-exportOptionsPlist ${{ matrix.upload }} \
-allowProvisioningUpdates \
-authenticationKeyPath $ASC_KEY_PATH \
-authenticationKeyID $ASC_KEY_ID \
-authenticationKeyIssuerID $ASC_KEY_ISSUER_ID
- name: Publish to TestFlight
if: matrix.if && matrix.name != 'macOS-standalone' && github.event_name == 'workflow_dispatch' && github.ref =='refs/heads/testing'
run: |-
go run -v ./cmd/internal/app_store_connect publish_testflight ${{ matrix.platform }}
- name: Build image
if: matrix.if && matrix.name == 'macOS-standalone' && github.event_name == 'workflow_dispatch'
run: |-
pushd clients/apple
xcodebuild -exportArchive \
-archivePath "${{ matrix.archive }}" \
-exportOptionsPlist ${{ matrix.export }} \
-exportPath "${{ matrix.export_path }}"
brew install create-dmg
create-dmg \
--volname "sing-box" \
--volicon "${{ matrix.export_path }}/SFM.app/Contents/Resources/AppIcon.icns" \
--icon "SFM.app" 0 0 \
--hide-extension "SFM.app" \
--app-drop-link 0 0 \
--skip-jenkins \
SFM.dmg "${{ matrix.export_path }}/SFM.app"
xcrun notarytool submit "SFM.dmg" --wait --keychain-profile "notarytool-password"
cd "${{ matrix.archive }}"
zip -r SFM.dSYMs.zip dSYMs
popd
mkdir -p dist
cp clients/apple/SFM.dmg "dist/SFM-${VERSION}-universal.dmg"
cp "clients/apple/${{ matrix.archive }}/SFM.dSYMs.zip" "dist/SFM-${VERSION}-universal.dSYMs.zip"
- name: Upload image
if: matrix.if && matrix.name == 'macOS-standalone' && github.event_name == 'workflow_dispatch'
uses: actions/upload-artifact@v4
with:
name: binary-macos-dmg
path: 'dist'
upload:
name: Upload builds
if: "!failure() && github.event_name == 'workflow_dispatch' && (inputs.build == 'All' || inputs.build == 'Binary' || inputs.build == 'Android' || inputs.build == 'Apple' || inputs.build == 'macOS-standalone')"
runs-on: ubuntu-latest
needs:
- calculate_version
- build
- build_darwin
- build_windows
- build_android
- build_apple
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
with:
fetch-depth: 0
- name: Cache ghr
uses: actions/cache@v4
id: cache-ghr
with:
path: |
~/go/bin/ghr
key: ghr
- name: Setup ghr
if: steps.cache-ghr.outputs.cache-hit != 'true'
run: |-
cd $HOME
git clone https://github.com/nekohasekai/ghr ghr
cd ghr
go install -v .
- name: Set tag
run: |-
git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
git tag v${{ needs.calculate_version.outputs.version }} -f
echo "VERSION=${{ needs.calculate_version.outputs.version }}" >> "$GITHUB_ENV"
- name: Download builds
uses: actions/download-artifact@v5
with:
path: dist
merge-multiple: true
- name: Upload builds
if: ${{ env.PUBLISHED == 'false' }}
run: |-
export PATH="$PATH:$HOME/go/bin"
ghr --replace --draft --prerelease -p 5 "v${VERSION}" dist
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Replace builds
if: ${{ env.PUBLISHED != 'false' }}
run: |-
export PATH="$PATH:$HOME/go/bin"
ghr --replace -p 5 "v${VERSION}" dist
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
================================================
FILE: .github/workflows/docker.yml
================================================
name: Publish Docker Images
on:
#push:
# branches:
# - stable
# - testing
release:
types:
- published
workflow_dispatch:
inputs:
tag:
description: "The tag version you want to build"
env:
REGISTRY_IMAGE: ghcr.io/sagernet/sing-box
jobs:
build_binary:
name: Build binary
runs-on: ubuntu-latest
strategy:
fail-fast: true
matrix:
include:
# Naive-enabled builds (musl)
- { arch: amd64, naive: true, docker_platform: "linux/amd64" }
- { arch: arm64, naive: true, docker_platform: "linux/arm64" }
- { arch: "386", naive: true, docker_platform: "linux/386" }
- { arch: arm, goarm: "7", naive: true, docker_platform: "linux/arm/v7" }
- { arch: mipsle, gomips: softfloat, naive: true, docker_platform: "linux/mipsle" }
- { arch: riscv64, naive: true, docker_platform: "linux/riscv64" }
- { arch: loong64, naive: true, docker_platform: "linux/loong64" }
# Non-naive builds
- { arch: arm, goarm: "6", docker_platform: "linux/arm/v6" }
- { arch: ppc64le, docker_platform: "linux/ppc64le" }
- { arch: s390x, docker_platform: "linux/s390x" }
steps:
- name: Get commit to build
id: ref
run: |-
if [[ -z "${{ github.event.inputs.tag }}" ]]; then
ref="${{ github.ref_name }}"
else
ref="${{ github.event.inputs.tag }}"
fi
echo "ref=$ref"
echo "ref=$ref" >> $GITHUB_OUTPUT
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
with:
ref: ${{ steps.ref.outputs.ref }}
fetch-depth: 0
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ~1.25.9
- name: Clone cronet-go
if: matrix.naive
run: |
set -xeuo pipefail
CRONET_GO_VERSION=$(cat .github/CRONET_GO_VERSION)
git init ~/cronet-go
git -C ~/cronet-go remote add origin https://github.com/sagernet/cronet-go.git
git -C ~/cronet-go fetch --depth=1 origin "$CRONET_GO_VERSION"
git -C ~/cronet-go checkout FETCH_HEAD
git -C ~/cronet-go submodule update --init --recursive --depth=1
- name: Regenerate Debian keyring
if: matrix.naive
run: |
set -xeuo pipefail
rm -f ~/cronet-go/naiveproxy/src/build/linux/sysroot_scripts/keyring.gpg
cd ~/cronet-go
GPG_TTY=/dev/null ./naiveproxy/src/build/linux/sysroot_scripts/generate_keyring.sh
- name: Cache Chromium toolchain
if: matrix.naive
id: cache-chromium-toolchain
uses: actions/cache@v4
with:
path: |
~/cronet-go/naiveproxy/src/third_party/llvm-build/
~/cronet-go/naiveproxy/src/gn/out/
~/cronet-go/naiveproxy/src/chrome/build/pgo_profiles/
~/cronet-go/naiveproxy/src/out/sysroot-build/
key: chromium-toolchain-${{ matrix.arch }}-musl-${{ hashFiles('.github/CRONET_GO_VERSION') }}
- name: Download Chromium toolchain
if: matrix.naive
run: |
set -xeuo pipefail
cd ~/cronet-go
go run ./cmd/build-naive --target=linux/${{ matrix.arch }} --libc=musl download-toolchain
- name: Set version
run: |
set -xeuo pipefail
VERSION=$(go run ./cmd/internal/read_tag)
echo "VERSION=${VERSION}" >> "${GITHUB_ENV}"
- name: Set Chromium toolchain environment
if: matrix.naive
run: |
set -xeuo pipefail
cd ~/cronet-go
go run ./cmd/build-naive --target=linux/${{ matrix.arch }} --libc=musl env >> $GITHUB_ENV
- name: Set build tags
run: |
set -xeuo pipefail
if [[ "${{ matrix.naive }}" == "true" ]]; then
TAGS="$(cat release/DEFAULT_BUILD_TAGS),with_musl"
else
TAGS=$(cat release/DEFAULT_BUILD_TAGS_OTHERS)
fi
echo "BUILD_TAGS=${TAGS}" >> "${GITHUB_ENV}"
- name: Set shared ldflags
run: |
echo "LDFLAGS_SHARED=$(cat release/LDFLAGS)" >> "${GITHUB_ENV}"
- name: Build (naive)
if: matrix.naive
run: |
set -xeuo pipefail
go build -v -trimpath -o sing-box -tags "${BUILD_TAGS}" \
-ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${VERSION}' ${LDFLAGS_SHARED} -s -w -buildid=" \
./cmd/sing-box
env:
CGO_ENABLED: "1"
GOOS: linux
GOARCH: ${{ matrix.arch }}
GOARM: ${{ matrix.goarm }}
GOMIPS: ${{ matrix.gomips }}
- name: Build (non-naive)
if: ${{ ! matrix.naive }}
run: |
set -xeuo pipefail
go build -v -trimpath -o sing-box -tags "${BUILD_TAGS}" \
-ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${VERSION}' ${LDFLAGS_SHARED} -s -w -buildid=" \
./cmd/sing-box
env:
CGO_ENABLED: "0"
GOOS: linux
GOARCH: ${{ matrix.arch }}
GOARM: ${{ matrix.goarm }}
- name: Prepare artifact
run: |
platform=${{ matrix.docker_platform }}
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
# Rename binary to include arch info for Dockerfile.binary
BINARY_NAME="sing-box-${{ matrix.arch }}"
if [[ -n "${{ matrix.goarm }}" ]]; then
BINARY_NAME="${BINARY_NAME}v${{ matrix.goarm }}"
fi
mv sing-box "${BINARY_NAME}"
echo "BINARY_NAME=${BINARY_NAME}" >> $GITHUB_ENV
- name: Upload binary
uses: actions/upload-artifact@v4
with:
name: binary-${{ env.PLATFORM_PAIR }}
path: ${{ env.BINARY_NAME }}
if-no-files-found: error
retention-days: 1
build_docker:
name: Build Docker image
runs-on: ubuntu-latest
needs:
- build_binary
strategy:
fail-fast: true
matrix:
include:
- { platform: "linux/amd64" }
- { platform: "linux/arm/v6" }
- { platform: "linux/arm/v7" }
- { platform: "linux/arm64" }
- { platform: "linux/386" }
# mipsle: no base Docker image available for this platform
- { platform: "linux/ppc64le" }
- { platform: "linux/riscv64" }
- { platform: "linux/s390x" }
- { platform: "linux/loong64", base_image: "ghcr.io/loong64/alpine:edge" }
steps:
- name: Get commit to build
id: ref
run: |-
if [[ -z "${{ github.event.inputs.tag }}" ]]; then
ref="${{ github.ref_name }}"
else
ref="${{ github.event.inputs.tag }}"
fi
echo "ref=$ref"
echo "ref=$ref" >> $GITHUB_OUTPUT
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
with:
ref: ${{ steps.ref.outputs.ref }}
fetch-depth: 0
- name: Prepare
run: |
platform=${{ matrix.platform }}
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
- name: Download binary
uses: actions/download-artifact@v5
with:
name: binary-${{ env.PLATFORM_PAIR }}
path: .
- name: Prepare binary
run: |
# Find and make the binary executable
chmod +x sing-box-*
ls -la sing-box-*
- name: Setup QEMU
uses: docker/setup-qemu-action@v3
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY_IMAGE }}
- name: Build and push by digest
id: build
uses: docker/build-push-action@v6
with:
platforms: ${{ matrix.platform }}
context: .
file: Dockerfile.binary
build-args: |
BASE_IMAGE=${{ matrix.base_image || 'alpine' }}
labels: ${{ steps.meta.outputs.labels }}
outputs: type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true
- name: Export digest
run: |
mkdir -p /tmp/digests
digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"
- name: Upload digest
uses: actions/upload-artifact@v4
with:
name: digests-${{ env.PLATFORM_PAIR }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1
merge:
if: github.event_name != 'push'
runs-on: ubuntu-latest
needs:
- build_docker
steps:
- name: Get commit to build
id: ref
run: |-
if [[ -z "${{ github.event.inputs.tag }}" ]]; then
ref="${{ github.ref_name }}"
else
ref="${{ github.event.inputs.tag }}"
fi
echo "ref=$ref"
echo "ref=$ref" >> $GITHUB_OUTPUT
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
with:
ref: ${{ steps.ref.outputs.ref }}
fetch-depth: 0
- name: Detect track
run: bash .github/detect_track.sh
- name: Download digests
uses: actions/download-artifact@v5
with:
path: /tmp/digests
pattern: digests-*
merge-multiple: true
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Create manifest list and push
if: github.event_name != 'push'
working-directory: /tmp/digests
run: |
docker buildx imagetools create \
-t "${{ env.REGISTRY_IMAGE }}:${{ env.DOCKER_TAG }}" \
-t "${{ env.REGISTRY_IMAGE }}:${{ steps.ref.outputs.ref }}" \
$(printf '${{ env.REGISTRY_IMAGE }}@sha256:%s ' *)
- name: Inspect image
if: github.event_name != 'push'
run: |
docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ env.DOCKER_TAG }}
docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ steps.ref.outputs.ref }}
================================================
FILE: .github/workflows/lint.yml
================================================
name: Lint
on:
push:
branches:
- oldstable
- stable
- testing
- unstable
paths-ignore:
- '**.md'
- '.github/**'
- '!.github/workflows/lint.yml'
pull_request:
branches:
- oldstable
- stable
- testing
- unstable
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}-${{ inputs.build }}
cancel-in-progress: true
jobs:
build:
name: Lint ${{ matrix.goos }}/${{ matrix.goarch }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- goos: windows
goarch: amd64
- goos: windows
goarch: '386'
- goos: windows
goarch: arm64
- goos: linux
goarch: amd64
- goos: linux
goarch: arm64
- goos: linux
goarch: arm
- goos: linux
goarch: '386'
- goos: darwin
goarch: amd64
- goos: darwin
goarch: arm64
- goos: android
goarch: arm64
# - goos: freebsd
# goarch: amd64
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ^1.25
- name: Cache go module
uses: actions/cache@v4
with:
path: |
~/go/pkg/mod
key: go-${{ hashFiles('**/go.sum') }}
- name: golangci-lint
uses: golangci/golangci-lint-action@v8
env:
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
with:
version: latest
args: --timeout=30m
install-mode: binary
verify: false
================================================
FILE: .github/workflows/linux.yml
================================================
name: Build Linux Packages
on:
#push:
# branches:
# - stable
# - testing
workflow_dispatch:
inputs:
version:
description: "Version name"
required: true
type: string
release:
types:
- published
jobs:
calculate_version:
name: Calculate version
runs-on: ubuntu-latest
outputs:
version: ${{ steps.outputs.outputs.version }}
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
with:
fetch-depth: 0
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ~1.25.9
- name: Check input version
if: github.event_name == 'workflow_dispatch'
run: |-
echo "version=${{ inputs.version }}"
echo "version=${{ inputs.version }}" >> "$GITHUB_ENV"
- name: Calculate version
if: github.event_name != 'workflow_dispatch'
run: |-
go run -v ./cmd/internal/read_tag --ci --nightly
- name: Set outputs
id: outputs
run: |-
echo "version=$version" >> "$GITHUB_OUTPUT"
build:
name: Build binary
runs-on: ubuntu-latest
needs:
- calculate_version
strategy:
matrix:
include:
# Naive-enabled builds (musl)
- { os: linux, arch: amd64, naive: true, debian: amd64, rpm: x86_64, pacman: x86_64 }
- { os: linux, arch: arm64, naive: true, debian: arm64, rpm: aarch64, pacman: aarch64 }
- { os: linux, arch: "386", naive: true, debian: i386, rpm: i386 }
- { os: linux, arch: arm, goarm: "7", naive: true, debian: armhf, rpm: armv7hl, pacman: armv7hl }
- { os: linux, arch: mipsle, gomips: softfloat, naive: true, debian: mipsel, rpm: mipsel }
- { os: linux, arch: riscv64, naive: true, debian: riscv64, rpm: riscv64 }
- { os: linux, arch: loong64, naive: true, debian: loongarch64, rpm: loongarch64 }
# Non-naive builds (unsupported architectures)
- { os: linux, arch: arm, goarm: "6", debian: armel, rpm: armv6hl }
- { os: linux, arch: mips64le, debian: mips64el, rpm: mips64el }
- { os: linux, arch: s390x, debian: s390x, rpm: s390x }
- { os: linux, arch: ppc64le, debian: ppc64el, rpm: ppc64le }
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
with:
fetch-depth: 0
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ~1.25.9
- name: Clone cronet-go
if: matrix.naive
run: |
set -xeuo pipefail
CRONET_GO_VERSION=$(cat .github/CRONET_GO_VERSION)
git init ~/cronet-go
git -C ~/cronet-go remote add origin https://github.com/sagernet/cronet-go.git
git -C ~/cronet-go fetch --depth=1 origin "$CRONET_GO_VERSION"
git -C ~/cronet-go checkout FETCH_HEAD
git -C ~/cronet-go submodule update --init --recursive --depth=1
- name: Regenerate Debian keyring
if: matrix.naive
run: |
set -xeuo pipefail
rm -f ~/cronet-go/naiveproxy/src/build/linux/sysroot_scripts/keyring.gpg
cd ~/cronet-go
GPG_TTY=/dev/null ./naiveproxy/src/build/linux/sysroot_scripts/generate_keyring.sh
- name: Cache Chromium toolchain
if: matrix.naive
id: cache-chromium-toolchain
uses: actions/cache@v4
with:
path: |
~/cronet-go/naiveproxy/src/third_party/llvm-build/
~/cronet-go/naiveproxy/src/gn/out/
~/cronet-go/naiveproxy/src/chrome/build/pgo_profiles/
~/cronet-go/naiveproxy/src/out/sysroot-build/
key: chromium-toolchain-${{ matrix.arch }}-musl-${{ hashFiles('.github/CRONET_GO_VERSION') }}
- name: Download Chromium toolchain
if: matrix.naive
run: |
set -xeuo pipefail
cd ~/cronet-go
go run ./cmd/build-naive --target=linux/${{ matrix.arch }} --libc=musl download-toolchain
- name: Set Chromium toolchain environment
if: matrix.naive
run: |
set -xeuo pipefail
cd ~/cronet-go
go run ./cmd/build-naive --target=linux/${{ matrix.arch }} --libc=musl env >> $GITHUB_ENV
- name: Set tag
run: |-
git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
git tag v${{ needs.calculate_version.outputs.version }} -f
- name: Set build tags
run: |
set -xeuo pipefail
if [[ "${{ matrix.naive }}" == "true" ]]; then
TAGS="$(cat release/DEFAULT_BUILD_TAGS),with_musl"
else
TAGS=$(cat release/DEFAULT_BUILD_TAGS_OTHERS)
fi
echo "BUILD_TAGS=${TAGS}" >> "${GITHUB_ENV}"
- name: Set shared ldflags
run: |
echo "LDFLAGS_SHARED=$(cat release/LDFLAGS)" >> "${GITHUB_ENV}"
- name: Build (naive)
if: matrix.naive
run: |
set -xeuo pipefail
mkdir -p dist
go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \
-ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }}' ${LDFLAGS_SHARED} -s -w -buildid=" \
./cmd/sing-box
env:
CGO_ENABLED: "1"
GOOS: linux
GOARCH: ${{ matrix.arch }}
GOARM: ${{ matrix.goarm }}
GOMIPS: ${{ matrix.gomips }}
GOMIPS64: ${{ matrix.gomips }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build (non-naive)
if: ${{ ! matrix.naive }}
run: |
set -xeuo pipefail
mkdir -p dist
go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \
-ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }}' ${LDFLAGS_SHARED} -s -w -buildid=" \
./cmd/sing-box
env:
CGO_ENABLED: "0"
GOOS: ${{ matrix.os }}
GOARCH: ${{ matrix.arch }}
GOARM: ${{ matrix.goarm }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Set mtime
run: |-
TZ=UTC touch -t '197001010000' dist/sing-box
- name: Detect track
run: bash .github/detect_track.sh
- name: Set version
run: |-
PKG_VERSION="${{ needs.calculate_version.outputs.version }}"
PKG_VERSION="${PKG_VERSION//-/\~}"
echo "PKG_VERSION=${PKG_VERSION}" >> "${GITHUB_ENV}"
- name: Package DEB
if: matrix.debian != ''
run: |
set -xeuo pipefail
sudo gem install fpm
sudo apt-get install -y debsigs
cp .fpm_systemd .fpm
fpm -t deb \
--name "${NAME}" \
-v "$PKG_VERSION" \
-p "dist/${NAME}_${{ needs.calculate_version.outputs.version }}_linux_${{ matrix.debian }}.deb" \
--architecture ${{ matrix.debian }} \
dist/sing-box=/usr/bin/sing-box
curl -Lo '/tmp/debsigs.diff' 'https://gitlab.com/debsigs/debsigs/-/commit/160138f5de1ec110376d3c807b60a37388bc7c90.diff'
sudo patch /usr/bin/debsigs < '/tmp/debsigs.diff'
rm -rf $HOME/.gnupg
gpg --pinentry-mode loopback --passphrase "${{ secrets.GPG_PASSPHRASE }}" --import <<EOF
${{ secrets.GPG_KEY }}
EOF
debsigs --sign=origin -k ${{ secrets.GPG_KEY_ID }} --gpgopts '--pinentry-mode loopback --passphrase "${{ secrets.GPG_PASSPHRASE }}"' dist/*.deb
- name: Package RPM
if: matrix.rpm != ''
run: |-
set -xeuo pipefail
sudo gem install fpm
cp .fpm_systemd .fpm
fpm -t rpm \
--name "${NAME}" \
-v "$PKG_VERSION" \
-p "dist/${NAME}_${{ needs.calculate_version.outputs.version }}_linux_${{ matrix.rpm }}.rpm" \
--architecture ${{ matrix.rpm }} \
dist/sing-box=/usr/bin/sing-box
cat > $HOME/.rpmmacros <<EOF
%_gpg_name ${{ secrets.GPG_KEY_ID }}
%_gpg_sign_cmd_extra_args --pinentry-mode loopback --passphrase ${{ secrets.GPG_PASSPHRASE }}
EOF
gpg --pinentry-mode loopback --passphrase "${{ secrets.GPG_PASSPHRASE }}" --import <<EOF
${{ secrets.GPG_KEY }}
EOF
rpmsign --addsign dist/*.rpm
- name: Cleanup
run: rm dist/sing-box
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: binary-${{ matrix.os }}_${{ matrix.arch }}${{ matrix.goarm && format('v{0}', matrix.goarm) }}${{ matrix.legacy_go && '-legacy' || '' }}
path: "dist"
upload:
name: Upload builds
runs-on: ubuntu-latest
needs:
- calculate_version
- build
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
with:
fetch-depth: 0
- name: Set tag
run: |-
git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
git tag v${{ needs.calculate_version.outputs.version }} -f
echo "VERSION=${{ needs.calculate_version.outputs.version }}" >> "$GITHUB_ENV"
- name: Download builds
uses: actions/download-artifact@v5
with:
path: dist
merge-multiple: true
- name: Publish packages
if: github.event_name != 'push'
run: |-
ls dist | xargs -I {} curl -F "package=@dist/{}" https://${{ secrets.FURY_TOKEN }}@push.fury.io/sagernet/
================================================
FILE: .github/workflows/stale.yml
================================================
name: Mark stale issues and pull requests
on:
schedule:
- cron: "30 1 * * *"
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v9
with:
stale-issue-message: 'This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 5 days'
days-before-stale: 60
days-before-close: 5
exempt-issue-labels: 'bug,enhancement'
================================================
FILE: .github/workflows/test.yml
================================================
name: Test
on:
push:
branches:
- stable
- testing
- unstable
paths-ignore:
- '**.md'
- '.github/**'
- '!.github/workflows/test.yml'
pull_request:
branches:
- stable
- testing
- unstable
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}-${{ inputs.build }}
cancel-in-progress: true
jobs:
test:
name: Test
strategy:
fail-fast: false
matrix:
os:
- ubuntu-latest
- windows-latest
- macos-latest
go:
- ~1.24
- ~1.25
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go }}
- name: Set build tags and ldflags
shell: bash
run: |
echo "BUILD_TAGS=$(cat release/DEFAULT_BUILD_TAGS_OTHERS)" >> "$GITHUB_ENV"
echo "LDFLAGS_SHARED=$(cat release/LDFLAGS)" >> "$GITHUB_ENV"
- name: Test (unix)
if: matrix.os != 'windows-latest'
run: go test -v -exec sudo -tags "$BUILD_TAGS" -ldflags "$LDFLAGS_SHARED" ./...
- name: Test (windows)
if: matrix.os == 'windows-latest'
shell: bash
run: go test -v -tags "$BUILD_TAGS" -ldflags "$LDFLAGS_SHARED" ./...
================================================
FILE: .gitignore
================================================
/.idea/
/vendor/
/*.json
/*.srs
/*.db
/site/
/bin/
/dist/
/sing-box
/sing-box.exe
/build/
/*.jar
/*.aar
/*.xcframework/
/experimental/libbox/*.aar
/experimental/libbox/*.xcframework/
/experimental/libbox/*.nupkg
.DS_Store
/config.d/
/venv/
CLAUDE.md
AGENTS.md
/.claude/
================================================
FILE: .gitmodules
================================================
[submodule "clients/apple"]
path = clients/apple
url = https://github.com/SagerNet/sing-box-for-apple.git
[submodule "clients/android"]
path = clients/android
url = https://github.com/SagerNet/sing-box-for-android.git
================================================
FILE: .golangci.yml
================================================
version: "2"
run:
go: "1.24"
build-tags:
- with_gvisor
- with_quic
- with_dhcp
- with_wireguard
- with_utls
- with_acme
- with_clash_api
- with_tailscale
- with_ccm
- with_ocm
- badlinkname
- tfogo_checklinkname0
linters:
default: none
enable:
- ineffassign
- staticcheck
- unused
- modernize
settings:
modernize:
disable:
- omitzero # nested struct omitempty -> omitzero changes JSON output semantics
staticcheck:
checks:
- all
- -QF1008 # could remove embedded field "<interface>" from selector
- -ST1003 # should not use ALL_CAPS in Go names; use CamelCase instead
- -QF1001 # could apply De Morgan's law
exclusions:
generated: lax
presets:
- comments
- common-false-positives
paths:
- transport/simple-obfs
- \.pb\.go$
- third_party$
- builtin$
- examples$
formatters:
enable:
- gci
- gofumpt
settings:
gci:
sections:
- standard
- prefix(github.com/sagernet/)
- default
custom-order: true
================================================
FILE: Dockerfile
================================================
FROM --platform=$BUILDPLATFORM golang:1.25-alpine AS builder
LABEL maintainer="nekohasekai <contact-git@sekai.icu>"
COPY . /go/src/github.com/sagernet/sing-box
WORKDIR /go/src/github.com/sagernet/sing-box
ARG TARGETOS TARGETARCH
ARG GOPROXY=""
ENV GOPROXY ${GOPROXY}
ENV CGO_ENABLED=0
ENV GOOS=$TARGETOS
ENV GOARCH=$TARGETARCH
RUN set -ex \
&& apk add git build-base \
&& export COMMIT=$(git rev-parse --short HEAD) \
&& export VERSION=$(go run ./cmd/internal/read_tag) \
&& export TAGS=$(cat release/DEFAULT_BUILD_TAGS_OTHERS) \
&& export LDFLAGS_SHARED=$(cat release/LDFLAGS) \
&& go build -v -trimpath -tags "$TAGS" \
-o /go/bin/sing-box \
-ldflags "-X \"github.com/sagernet/sing-box/constant.Version=$VERSION\" $LDFLAGS_SHARED -s -w -buildid=" \
./cmd/sing-box
FROM --platform=$TARGETPLATFORM alpine AS dist
LABEL maintainer="nekohasekai <contact-git@sekai.icu>"
RUN set -ex \
&& apk add --no-cache --upgrade bash tzdata ca-certificates nftables
COPY --from=builder /go/bin/sing-box /usr/local/bin/sing-box
ENTRYPOINT ["sing-box"]
================================================
FILE: Dockerfile.binary
================================================
ARG BASE_IMAGE=alpine
FROM ${BASE_IMAGE}
ARG TARGETARCH
ARG TARGETVARIANT
LABEL maintainer="nekohasekai <contact-git@sekai.icu>"
RUN set -ex \
&& if command -v apk > /dev/null; then \
apk add --no-cache --upgrade bash tzdata ca-certificates nftables; \
else \
apt-get update && apt-get install -y --no-install-recommends bash tzdata ca-certificates nftables \
&& rm -rf /var/lib/apt/lists/*; \
fi
COPY sing-box-${TARGETARCH}${TARGETVARIANT} /usr/local/bin/sing-box
ENTRYPOINT ["sing-box"]
================================================
FILE: LICENSE
================================================
Copyright (C) 2022 by nekohasekai <contact-sagernet@sekai.icu>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
In addition, no derivative work may use the name or imply association
with this application without prior consent.
================================================
FILE: Makefile
================================================
NAME = sing-box
COMMIT = $(shell git rev-parse --short HEAD)
TAGS ?= $(shell cat release/DEFAULT_BUILD_TAGS_OTHERS)
GOHOSTOS = $(shell go env GOHOSTOS)
GOHOSTARCH = $(shell go env GOHOSTARCH)
VERSION=$(shell CGO_ENABLED=0 GOOS=$(GOHOSTOS) GOARCH=$(GOHOSTARCH) go run github.com/sagernet/sing-box/cmd/internal/read_tag@latest)
LDFLAGS_SHARED = $(shell cat release/LDFLAGS)
PARAMS = -v -trimpath -ldflags "-X 'github.com/sagernet/sing-box/constant.Version=$(VERSION)' $(LDFLAGS_SHARED) -s -w -buildid="
MAIN_PARAMS = $(PARAMS) -tags "$(TAGS)"
MAIN = ./cmd/sing-box
PREFIX ?= $(shell go env GOPATH)
SING_FFI ?= sing-ffi
LIBBOX_FFI_CONFIG ?= ./experimental/libbox/ffi.json
.PHONY: test release docs build
build:
export GOTOOLCHAIN=local && \
go build $(MAIN_PARAMS) $(MAIN)
race:
export GOTOOLCHAIN=local && \
go build -race $(MAIN_PARAMS) $(MAIN)
ci_build:
export GOTOOLCHAIN=local && \
go build $(PARAMS) $(MAIN) && \
go build $(MAIN_PARAMS) $(MAIN)
generate_completions:
go run -v --tags "$(TAGS),generate,generate_completions" $(MAIN)
install:
go build -o $(PREFIX)/bin/$(NAME) $(MAIN_PARAMS) $(MAIN)
fmt:
@golangci-lint fmt
fmt_docs:
go run ./cmd/internal/format_docs
lint:
GOOS=linux golangci-lint run ./...
GOOS=android golangci-lint run ./...
GOOS=windows golangci-lint run ./...
GOOS=darwin golangci-lint run ./...
# GOOS=freebsd golangci-lint run ./...
lint_install:
go install -v github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest
proto:
@go run ./cmd/internal/protogen
@gofumpt -l -w .
@gofumpt -l -w .
proto_install:
go install -v google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install -v google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
update_certificates:
go run ./cmd/internal/update_certificates
release:
go run ./cmd/internal/build goreleaser release --clean --skip publish
mkdir dist/release
mv dist/*.tar.gz \
dist/*.zip \
dist/*.deb \
dist/*.rpm \
dist/*_amd64.pkg.tar.zst \
dist/*_arm64.pkg.tar.zst \
dist/release
ghr --replace --draft --prerelease -p 5 "v${VERSION}" dist/release
rm -r dist/release
release_repo:
go run ./cmd/internal/build goreleaser release -f .goreleaser.fury.yaml --clean
release_install:
go install -v github.com/tcnksm/ghr@latest
update_android_version:
go run ./cmd/internal/update_android_version
build_android:
cd ../sing-box-for-android && ./gradlew :app:clean :app:assembleOtherRelease :app:assembleOtherLegacyRelease && ./gradlew --stop
upload_android:
mkdir -p dist/release_android
cp ../sing-box-for-android/app/build/outputs/apk/other/release/*.apk dist/release_android
cp ../sing-box-for-android/app/build/outputs/apk/otherLegacy/release/*.apk dist/release_android
ghr --replace --draft --prerelease -p 5 "v${VERSION}" dist/release_android
rm -rf dist/release_android
release_android: lib_android update_android_version build_android upload_android
publish_android:
cd ../sing-box-for-android && ./gradlew :app:publishPlayReleaseBundle && ./gradlew --stop
# TODO: find why and remove `-destination 'generic/platform=iOS'`
# TODO: remove xcode clean when fix control widget fixed
build_ios:
cd ../sing-box-for-apple && \
rm -rf build/SFI.xcarchive && \
xcodebuild clean -scheme SFI && \
xcodebuild archive -scheme SFI -configuration Release -destination 'generic/platform=iOS' -archivePath build/SFI.xcarchive -allowProvisioningUpdates | xcbeautify | grep -A 10 -e "Archive Succeeded" -e "ARCHIVE FAILED" -e "❌"
upload_ios_app_store:
cd ../sing-box-for-apple && \
xcodebuild -exportArchive -archivePath build/SFI.xcarchive -exportOptionsPlist SFI/Upload.plist -allowProvisioningUpdates
export_ios_ipa:
cd ../sing-box-for-apple && \
xcodebuild -exportArchive -archivePath build/SFI.xcarchive -exportOptionsPlist SFI/Export.plist -allowProvisioningUpdates -exportPath build/SFI && \
cp build/SFI/sing-box.ipa dist/SFI.ipa
upload_ios_ipa:
cd dist && \
cp SFI.ipa "SFI-${VERSION}.ipa" && \
ghr --replace --draft --prerelease "v${VERSION}" "SFI-${VERSION}.ipa"
release_ios: build_ios upload_ios_app_store
build_macos:
cd ../sing-box-for-apple && \
rm -rf build/SFM.xcarchive && \
xcodebuild archive -scheme SFM -configuration Release -archivePath build/SFM.xcarchive -allowProvisioningUpdates | xcbeautify | grep -A 10 -e "Archive Succeeded" -e "ARCHIVE FAILED" -e "❌"
upload_macos_app_store:
cd ../sing-box-for-apple && \
xcodebuild -exportArchive -archivePath build/SFM.xcarchive -exportOptionsPlist SFI/Upload.plist -allowProvisioningUpdates
release_macos: build_macos upload_macos_app_store
build_macos_standalone:
$(MAKE) -C ../sing-box-for-apple archive_macos_standalone
build_macos_dmg:
$(MAKE) -C ../sing-box-for-apple build_macos_dmg
build_macos_pkg:
$(MAKE) -C ../sing-box-for-apple build_macos_pkg
notarize_macos_dmg:
$(MAKE) -C ../sing-box-for-apple notarize_macos_dmg
notarize_macos_pkg:
$(MAKE) -C ../sing-box-for-apple notarize_macos_pkg
upload_macos_dmg:
mkdir -p dist/SFM
cp ../sing-box-for-apple/build/SFM-Apple.dmg "dist/SFM/SFM-${VERSION}-Apple.dmg"
cp ../sing-box-for-apple/build/SFM-Intel.dmg "dist/SFM/SFM-${VERSION}-Intel.dmg"
cp ../sing-box-for-apple/build/SFM-Universal.dmg "dist/SFM/SFM-${VERSION}-Universal.dmg"
ghr --replace --draft --prerelease "v${VERSION}" "dist/SFM/SFM-${VERSION}-Apple.dmg"
ghr --replace --draft --prerelease "v${VERSION}" "dist/SFM/SFM-${VERSION}-Intel.dmg"
ghr --replace --draft --prerelease "v${VERSION}" "dist/SFM/SFM-${VERSION}-Universal.dmg"
upload_macos_pkg:
mkdir -p dist/SFM
cp ../sing-box-for-apple/build/SFM-Apple.pkg "dist/SFM/SFM-${VERSION}-Apple.pkg"
cp ../sing-box-for-apple/build/SFM-Intel.pkg "dist/SFM/SFM-${VERSION}-Intel.pkg"
cp ../sing-box-for-apple/build/SFM-Universal.pkg "dist/SFM/SFM-${VERSION}-Universal.pkg"
ghr --replace --draft --prerelease "v${VERSION}" "dist/SFM/SFM-${VERSION}-Apple.pkg"
ghr --replace --draft --prerelease "v${VERSION}" "dist/SFM/SFM-${VERSION}-Intel.pkg"
ghr --replace --draft --prerelease "v${VERSION}" "dist/SFM/SFM-${VERSION}-Universal.pkg"
replace_macos_pkg:
mkdir -p dist/SFM
cp ../sing-box-for-apple/build/SFM-Apple.pkg "dist/SFM/SFM-${VERSION}-Apple.pkg"
cp ../sing-box-for-apple/build/SFM-Intel.pkg "dist/SFM/SFM-${VERSION}-Intel.pkg"
cp ../sing-box-for-apple/build/SFM-Universal.pkg "dist/SFM/SFM-${VERSION}-Universal.pkg"
ghr --replace "v${VERSION}" "dist/SFM/SFM-${VERSION}-Apple.pkg"
ghr --replace "v${VERSION}" "dist/SFM/SFM-${VERSION}-Intel.pkg"
ghr --replace "v${VERSION}" "dist/SFM/SFM-${VERSION}-Universal.pkg"
upload_macos_dsyms:
mkdir -p dist/SFM
cd ../sing-box-for-apple/build/SFM.System-universal.xcarchive && zip -r SFM.dSYMs.zip dSYMs
cp ../sing-box-for-apple/build/SFM.System-universal.xcarchive/SFM.dSYMs.zip "dist/SFM/SFM-${VERSION}.dSYMs.zip"
ghr --replace --draft --prerelease "v${VERSION}" "dist/SFM/SFM-${VERSION}.dSYMs.zip"
replace_macos_dsyms:
mkdir -p dist/SFM
cd ../sing-box-for-apple/build/SFM.System-universal.xcarchive && zip -r SFM.dSYMs.zip dSYMs
cp ../sing-box-for-apple/build/SFM.System-universal.xcarchive/SFM.dSYMs.zip "dist/SFM/SFM-${VERSION}.dSYMs.zip"
ghr --replace "v${VERSION}" "dist/SFM/SFM-${VERSION}.dSYMs.zip"
release_macos_standalone: build_macos_pkg notarize_macos_pkg upload_macos_pkg upload_macos_dsyms
replace_macos_standalone: build_macos_pkg notarize_macos_pkg upload_macos_pkg upload_macos_dsyms
build_tvos:
cd ../sing-box-for-apple && \
rm -rf build/SFT.xcarchive && \
xcodebuild archive -scheme SFT -configuration Release -archivePath build/SFT.xcarchive -allowProvisioningUpdates | xcbeautify | grep -A 10 -e "Archive Succeeded" -e "ARCHIVE FAILED" -e "❌"
upload_tvos_app_store:
cd ../sing-box-for-apple && \
xcodebuild -exportArchive -archivePath "build/SFT.xcarchive" -exportOptionsPlist SFI/Upload.plist -allowProvisioningUpdates
export_tvos_ipa:
cd ../sing-box-for-apple && \
xcodebuild -exportArchive -archivePath "build/SFT.xcarchive" -exportOptionsPlist SFI/Export.plist -allowProvisioningUpdates -exportPath build/SFT && \
cp build/SFT/sing-box.ipa dist/SFT.ipa
upload_tvos_ipa:
cd dist && \
cp SFT.ipa "SFT-${VERSION}.ipa" && \
ghr --replace --draft --prerelease "v${VERSION}" "SFT-${VERSION}.ipa"
release_tvos: build_tvos upload_tvos_app_store
update_apple_version:
go run ./cmd/internal/update_apple_version
update_macos_version:
MACOS_PROJECT_VERSION=$(shell go run -v ./cmd/internal/app_store_connect next_macos_project_version) go run ./cmd/internal/update_apple_version
release_apple: lib_apple update_apple_version release_ios release_macos release_tvos release_macos_standalone
release_apple_beta: update_apple_version release_ios release_macos release_tvos
publish_testflight:
go run -v ./cmd/internal/app_store_connect publish_testflight $(filter-out $@,$(MAKECMDGOALS))
prepare_app_store:
go run -v ./cmd/internal/app_store_connect prepare_app_store
publish_app_store:
go run -v ./cmd/internal/app_store_connect publish_app_store
test:
@go test -v ./... && \
cd test && \
go mod tidy && \
go test -v -tags "$(TAGS_TEST)" .
test_stdio:
@go test -v ./... && \
cd test && \
go mod tidy && \
go test -v -tags "$(TAGS_TEST),force_stdio" .
lib_android:
go run ./cmd/internal/build_libbox -target android
lib_apple:
go run ./cmd/internal/build_libbox -target apple
lib_windows:
$(SING_FFI) generate --config $(LIBBOX_FFI_CONFIG) --platform-type csharp
lib_android_new:
$(SING_FFI) generate --config $(LIBBOX_FFI_CONFIG) --platform-type android
lib_apple_new:
$(SING_FFI) generate --config $(LIBBOX_FFI_CONFIG) --platform-type apple
lib_install:
go install -v github.com/sagernet/gomobile/cmd/gomobile@v0.1.12
go install -v github.com/sagernet/gomobile/cmd/gobind@v0.1.12
docs:
venv/bin/mkdocs serve
publish_docs:
venv/bin/mkdocs gh-deploy -m "Update" --force --ignore-version --no-history
docs_install:
python3 -m venv venv
source ./venv/bin/activate && pip install --force-reinstall mkdocs-material=="9.7.2" mkdocs-static-i18n=="1.2.*"
clean:
rm -rf bin dist sing-box
rm -f $(shell go env GOPATH)/sing-box
update:
git fetch
git reset FETCH_HEAD --hard
git clean -fdx
%:
@:
================================================
FILE: README.md
================================================
# sing-box
The universal proxy platform.
[](https://repology.org/project/sing-box/versions)
## Documentation
https://sing-box.sagernet.org
## License
```
Copyright (C) 2022 by nekohasekai <contact-sagernet@sekai.icu>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
In addition, no derivative work may use the name or imply association
with this application without prior consent.
```
================================================
FILE: adapter/certificate/adapter.go
================================================
package certificate
type Adapter struct {
providerType string
providerTag string
}
func NewAdapter(providerType string, providerTag string) Adapter {
return Adapter{
providerType: providerType,
providerTag: providerTag,
}
}
func (a *Adapter) Type() string {
return a.providerType
}
func (a *Adapter) Tag() string {
return a.providerTag
}
================================================
FILE: adapter/certificate/manager.go
================================================
package certificate
import (
"context"
"os"
"sync"
"time"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/taskmonitor"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
F "github.com/sagernet/sing/common/format"
)
var _ adapter.CertificateProviderManager = (*Manager)(nil)
type Manager struct {
logger log.ContextLogger
registry adapter.CertificateProviderRegistry
access sync.Mutex
started bool
stage adapter.StartStage
providers []adapter.CertificateProviderService
providerByTag map[string]adapter.CertificateProviderService
}
func NewManager(logger log.ContextLogger, registry adapter.CertificateProviderRegistry) *Manager {
return &Manager{
logger: logger,
registry: registry,
providerByTag: make(map[string]adapter.CertificateProviderService),
}
}
func (m *Manager) Start(stage adapter.StartStage) error {
m.access.Lock()
if m.started && m.stage >= stage {
panic("already started")
}
m.started = true
m.stage = stage
providers := m.providers
m.access.Unlock()
for _, provider := range providers {
name := "certificate-provider/" + provider.Type() + "[" + provider.Tag() + "]"
m.logger.Trace(stage, " ", name)
startTime := time.Now()
err := adapter.LegacyStart(provider, stage)
if err != nil {
return E.Cause(err, stage, " ", name)
}
m.logger.Trace(stage, " ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
}
return nil
}
func (m *Manager) Close() error {
m.access.Lock()
defer m.access.Unlock()
if !m.started {
return nil
}
m.started = false
providers := m.providers
m.providers = nil
monitor := taskmonitor.New(m.logger, C.StopTimeout)
var err error
for _, provider := range providers {
name := "certificate-provider/" + provider.Type() + "[" + provider.Tag() + "]"
m.logger.Trace("close ", name)
startTime := time.Now()
monitor.Start("close ", name)
err = E.Append(err, provider.Close(), func(err error) error {
return E.Cause(err, "close ", name)
})
monitor.Finish()
m.logger.Trace("close ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
}
return err
}
func (m *Manager) CertificateProviders() []adapter.CertificateProviderService {
m.access.Lock()
defer m.access.Unlock()
return m.providers
}
func (m *Manager) Get(tag string) (adapter.CertificateProviderService, bool) {
m.access.Lock()
provider, found := m.providerByTag[tag]
m.access.Unlock()
return provider, found
}
func (m *Manager) Remove(tag string) error {
m.access.Lock()
provider, found := m.providerByTag[tag]
if !found {
m.access.Unlock()
return os.ErrInvalid
}
delete(m.providerByTag, tag)
index := common.Index(m.providers, func(it adapter.CertificateProviderService) bool {
return it == provider
})
if index == -1 {
panic("invalid certificate provider index")
}
m.providers = append(m.providers[:index], m.providers[index+1:]...)
started := m.started
m.access.Unlock()
if started {
return provider.Close()
}
return nil
}
func (m *Manager) Create(ctx context.Context, logger log.ContextLogger, tag string, providerType string, options any) error {
provider, err := m.registry.Create(ctx, logger, tag, providerType, options)
if err != nil {
return err
}
m.access.Lock()
defer m.access.Unlock()
if m.started {
name := "certificate-provider/" + provider.Type() + "[" + provider.Tag() + "]"
for _, stage := range adapter.ListStartStages {
m.logger.Trace(stage, " ", name)
startTime := time.Now()
err = adapter.LegacyStart(provider, stage)
if err != nil {
return E.Cause(err, stage, " ", name)
}
m.logger.Trace(stage, " ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
}
}
if existsProvider, loaded := m.providerByTag[tag]; loaded {
if m.started {
err = existsProvider.Close()
if err != nil {
return E.Cause(err, "close certificate-provider/", existsProvider.Type(), "[", existsProvider.Tag(), "]")
}
}
existsIndex := common.Index(m.providers, func(it adapter.CertificateProviderService) bool {
return it == existsProvider
})
if existsIndex == -1 {
panic("invalid certificate provider index")
}
m.providers = append(m.providers[:existsIndex], m.providers[existsIndex+1:]...)
}
m.providers = append(m.providers, provider)
m.providerByTag[tag] = provider
return nil
}
================================================
FILE: adapter/certificate/registry.go
================================================
package certificate
import (
"context"
"sync"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
)
type ConstructorFunc[T any] func(ctx context.Context, logger log.ContextLogger, tag string, options T) (adapter.CertificateProviderService, error)
func Register[Options any](registry *Registry, providerType string, constructor ConstructorFunc[Options]) {
registry.register(providerType, func() any {
return new(Options)
}, func(ctx context.Context, logger log.ContextLogger, tag string, rawOptions any) (adapter.CertificateProviderService, error) {
var options *Options
if rawOptions != nil {
options = rawOptions.(*Options)
}
return constructor(ctx, logger, tag, common.PtrValueOrDefault(options))
})
}
var _ adapter.CertificateProviderRegistry = (*Registry)(nil)
type (
optionsConstructorFunc func() any
constructorFunc func(ctx context.Context, logger log.ContextLogger, tag string, options any) (adapter.CertificateProviderService, error)
)
type Registry struct {
access sync.Mutex
optionsType map[string]optionsConstructorFunc
constructor map[string]constructorFunc
}
func NewRegistry() *Registry {
return &Registry{
optionsType: make(map[string]optionsConstructorFunc),
constructor: make(map[string]constructorFunc),
}
}
func (m *Registry) CreateOptions(providerType string) (any, bool) {
m.access.Lock()
defer m.access.Unlock()
optionsConstructor, loaded := m.optionsType[providerType]
if !loaded {
return nil, false
}
return optionsConstructor(), true
}
func (m *Registry) Create(ctx context.Context, logger log.ContextLogger, tag string, providerType string, options any) (adapter.CertificateProviderService, error) {
m.access.Lock()
defer m.access.Unlock()
constructor, loaded := m.constructor[providerType]
if !loaded {
return nil, E.New("certificate provider type not found: " + providerType)
}
return constructor(ctx, logger, tag, options)
}
func (m *Registry) register(providerType string, optionsConstructor optionsConstructorFunc, constructor constructorFunc) {
m.access.Lock()
defer m.access.Unlock()
m.optionsType[providerType] = optionsConstructor
m.constructor[providerType] = constructor
}
================================================
FILE: adapter/certificate.go
================================================
package adapter
import (
"context"
"crypto/x509"
"github.com/sagernet/sing/service"
)
type CertificateStore interface {
LifecycleService
Pool() *x509.CertPool
ExclusiveAnchors() bool
}
func RootPoolFromContext(ctx context.Context) *x509.CertPool {
store := service.FromContext[CertificateStore](ctx)
if store == nil {
return nil
}
return store.Pool()
}
================================================
FILE: adapter/certificate_darwin.go
================================================
//go:build darwin && cgo
package adapter
import "unsafe"
type AppleAnchors interface {
Retain() AppleAnchors
Release()
// Ref returns the underlying CFArrayRef, or nil if the anchor set is empty.
Ref() unsafe.Pointer
}
type AppleCertificateStore interface {
CertificateStore
AppleAnchors() AppleAnchors
}
================================================
FILE: adapter/certificate_provider.go
================================================
package adapter
import (
"context"
"crypto/tls"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
)
type CertificateProvider interface {
GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate, error)
}
type ACMECertificateProvider interface {
CertificateProvider
GetACMENextProtos() []string
}
type CertificateProviderService interface {
Lifecycle
Type() string
Tag() string
CertificateProvider
}
type CertificateProviderRegistry interface {
option.CertificateProviderOptionsRegistry
Create(ctx context.Context, logger log.ContextLogger, tag string, providerType string, options any) (CertificateProviderService, error)
}
type CertificateProviderManager interface {
Lifecycle
CertificateProviders() []CertificateProviderService
Get(tag string) (CertificateProviderService, bool)
Remove(tag string) error
Create(ctx context.Context, logger log.ContextLogger, tag string, providerType string, options any) error
}
================================================
FILE: adapter/connections.go
================================================
package adapter
import (
"context"
"net"
N "github.com/sagernet/sing/common/network"
)
type ConnectionManager interface {
Lifecycle
Count() int
CloseAll()
TrackConn(conn net.Conn) net.Conn
TrackPacketConn(conn net.PacketConn) net.PacketConn
NewConnection(ctx context.Context, this N.Dialer, conn net.Conn, metadata InboundContext, onClose N.CloseHandlerFunc)
NewPacketConnection(ctx context.Context, this N.Dialer, conn N.PacketConn, metadata InboundContext, onClose N.CloseHandlerFunc)
}
================================================
FILE: adapter/dns.go
================================================
package adapter
import (
"context"
"net/netip"
"time"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/logger"
"github.com/sagernet/sing/service"
"github.com/miekg/dns"
)
type DNSRouter interface {
Lifecycle
Exchange(ctx context.Context, message *dns.Msg, options DNSQueryOptions) (*dns.Msg, error)
Lookup(ctx context.Context, domain string, options DNSQueryOptions) ([]netip.Addr, error)
ClearCache()
LookupReverseMapping(ip netip.Addr) (string, bool)
ResetNetwork()
}
type DNSClient interface {
Start()
Exchange(ctx context.Context, transport DNSTransport, message *dns.Msg, options DNSQueryOptions, responseChecker func(response *dns.Msg) bool) (*dns.Msg, error)
Lookup(ctx context.Context, transport DNSTransport, domain string, options DNSQueryOptions, responseChecker func(response *dns.Msg) bool) ([]netip.Addr, error)
ClearCache()
}
type DNSQueryOptions struct {
Transport DNSTransport
Strategy C.DomainStrategy
LookupStrategy C.DomainStrategy
DisableCache bool
DisableOptimisticCache bool
RewriteTTL *uint32
Timeout time.Duration
ClientSubnet netip.Prefix
}
func DNSQueryOptionsFrom(ctx context.Context, options *option.DomainResolveOptions) (DNSQueryOptions, error) {
if options == nil || options.Server == "" {
return DNSQueryOptions{}, nil
}
transportManager := service.FromContext[DNSTransportManager](ctx)
transport, loaded := transportManager.Transport(options.Server)
if !loaded {
return DNSQueryOptions{}, E.New("domain resolver not found: " + options.Server)
}
return DNSQueryOptions{
Transport: transport,
Strategy: C.DomainStrategy(options.Strategy),
DisableCache: options.DisableCache,
DisableOptimisticCache: options.DisableOptimisticCache,
RewriteTTL: options.RewriteTTL,
Timeout: time.Duration(options.Timeout),
ClientSubnet: options.ClientSubnet.Build(netip.Prefix{}),
}, nil
}
type RDRCStore interface {
LoadRDRC(transportName string, qName string, qType uint16) (rejected bool)
SaveRDRC(transportName string, qName string, qType uint16) error
SaveRDRCAsync(transportName string, qName string, qType uint16, logger logger.Logger)
}
type DNSCacheStore interface {
LoadDNSCache(transportName string, qName string, qType uint16) (rawMessage []byte, expireAt time.Time, loaded bool)
SaveDNSCache(transportName string, qName string, qType uint16, rawMessage []byte, expireAt time.Time) error
SaveDNSCacheAsync(transportName string, qName string, qType uint16, rawMessage []byte, expireAt time.Time, logger logger.Logger)
ClearDNSCache() error
}
type DNSTransport interface {
Lifecycle
Type() string
Tag() string
Dependencies() []string
// Reset closes the transport's existing connections so later requests use fresh connections.
// Exchanges that are currently using those connections may fail.
Reset()
Exchange(ctx context.Context, message *dns.Msg) (*dns.Msg, error)
}
type DNSTransportWithPreferredDomain interface {
DNSTransport
PreferredDomain(domain string) bool
}
type DNSTransportRegistry interface {
option.DNSTransportOptionsRegistry
CreateDNSTransport(ctx context.Context, logger log.ContextLogger, tag string, transportType string, options any) (DNSTransport, error)
}
type DNSTransportManager interface {
Lifecycle
Transports() []DNSTransport
Transport(tag string) (DNSTransport, bool)
Default() DNSTransport
FakeIP() FakeIPTransport
Remove(tag string) error
Create(ctx context.Context, logger log.ContextLogger, tag string, outboundType string, options any) error
}
================================================
FILE: adapter/endpoint/adapter.go
================================================
package endpoint
import "github.com/sagernet/sing-box/option"
type Adapter struct {
endpointType string
endpointTag string
network []string
dependencies []string
}
func NewAdapter(endpointType string, endpointTag string, network []string, dependencies []string) Adapter {
return Adapter{
endpointType: endpointType,
endpointTag: endpointTag,
network: network,
dependencies: dependencies,
}
}
func NewAdapterWithDialerOptions(endpointType string, endpointTag string, network []string, dialOptions option.DialerOptions) Adapter {
var dependencies []string
if dialOptions.Detour != "" {
dependencies = []string{dialOptions.Detour}
}
return NewAdapter(endpointType, endpointTag, network, dependencies)
}
func (a *Adapter) Type() string {
return a.endpointType
}
func (a *Adapter) Tag() string {
return a.endpointTag
}
func (a *Adapter) Network() []string {
return a.network
}
func (a *Adapter) Dependencies() []string {
return a.dependencies
}
================================================
FILE: adapter/endpoint/manager.go
================================================
package endpoint
import (
"context"
"os"
"sync"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/taskmonitor"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
)
var _ adapter.EndpointManager = (*Manager)(nil)
type Manager struct {
logger log.ContextLogger
registry adapter.EndpointRegistry
access sync.Mutex
started bool
stage adapter.StartStage
endpoints []adapter.Endpoint
endpointByTag map[string]adapter.Endpoint
}
func NewManager(logger log.ContextLogger, registry adapter.EndpointRegistry) *Manager {
return &Manager{
logger: logger,
registry: registry,
endpointByTag: make(map[string]adapter.Endpoint),
}
}
func (m *Manager) Start(stage adapter.StartStage) error {
m.access.Lock()
defer m.access.Unlock()
if m.started && m.stage >= stage {
panic("already started")
}
m.started = true
m.stage = stage
if stage == adapter.StartStateStart {
// started with outbound manager
return nil
}
for _, endpoint := range m.endpoints {
name := "endpoint/" + endpoint.Type() + "[" + endpoint.Tag() + "]"
done := adapter.LogElapsed(m.logger, stage, " ", name)
err := adapter.LegacyStart(endpoint, stage)
done()
if err != nil {
return E.Cause(err, stage, " ", name)
}
}
return nil
}
func (m *Manager) Close() error {
m.access.Lock()
defer m.access.Unlock()
if !m.started {
return nil
}
m.started = false
endpoints := m.endpoints
m.endpoints = nil
monitor := taskmonitor.New(m.logger, C.StopTimeout)
var err error
for _, endpoint := range endpoints {
name := "endpoint/" + endpoint.Type() + "[" + endpoint.Tag() + "]"
done := adapter.LogElapsed(m.logger, "close ", name)
monitor.Start("close ", name)
err = E.Append(err, endpoint.Close(), func(err error) error {
return E.Cause(err, "close ", name)
})
monitor.Finish()
done()
}
return nil
}
func (m *Manager) Endpoints() []adapter.Endpoint {
m.access.Lock()
defer m.access.Unlock()
return m.endpoints
}
func (m *Manager) Get(tag string) (adapter.Endpoint, bool) {
m.access.Lock()
defer m.access.Unlock()
endpoint, found := m.endpointByTag[tag]
return endpoint, found
}
func (m *Manager) Remove(tag string) error {
m.access.Lock()
endpoint, found := m.endpointByTag[tag]
if !found {
m.access.Unlock()
return os.ErrInvalid
}
delete(m.endpointByTag, tag)
index := common.Index(m.endpoints, func(it adapter.Endpoint) bool {
return it == endpoint
})
if index == -1 {
panic("invalid endpoint index")
}
m.endpoints = append(m.endpoints[:index], m.endpoints[index+1:]...)
started := m.started
m.access.Unlock()
if started {
return endpoint.Close()
}
return nil
}
func (m *Manager) Create(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, outboundType string, options any) error {
endpoint, err := m.registry.Create(ctx, router, logger, tag, outboundType, options)
if err != nil {
return err
}
m.access.Lock()
defer m.access.Unlock()
if m.started {
name := "endpoint/" + endpoint.Type() + "[" + endpoint.Tag() + "]"
for _, stage := range adapter.ListStartStages {
done := adapter.LogElapsed(m.logger, stage, " ", name)
err = adapter.LegacyStart(endpoint, stage)
done()
if err != nil {
return E.Cause(err, stage, " ", name)
}
}
}
if existsEndpoint, loaded := m.endpointByTag[tag]; loaded {
if m.started {
err = existsEndpoint.Close()
if err != nil {
return E.Cause(err, "close endpoint/", existsEndpoint.Type(), "[", existsEndpoint.Tag(), "]")
}
}
existsIndex := common.Index(m.endpoints, func(it adapter.Endpoint) bool {
return it == existsEndpoint
})
if existsIndex == -1 {
panic("invalid endpoint index")
}
m.endpoints = append(m.endpoints[:existsIndex], m.endpoints[existsIndex+1:]...)
}
m.endpoints = append(m.endpoints, endpoint)
m.endpointByTag[tag] = endpoint
return nil
}
================================================
FILE: adapter/endpoint/registry.go
================================================
package endpoint
import (
"context"
"sync"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
)
type ConstructorFunc[T any] func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options T) (adapter.Endpoint, error)
func Register[Options any](registry *Registry, outboundType string, constructor ConstructorFunc[Options]) {
registry.register(outboundType, func() any {
return new(Options)
}, func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, rawOptions any) (adapter.Endpoint, error) {
var options *Options
if rawOptions != nil {
options = rawOptions.(*Options)
}
return constructor(ctx, router, logger, tag, common.PtrValueOrDefault(options))
})
}
var _ adapter.EndpointRegistry = (*Registry)(nil)
type (
optionsConstructorFunc func() any
constructorFunc func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options any) (adapter.Endpoint, error)
)
type Registry struct {
access sync.Mutex
optionsType map[string]optionsConstructorFunc
constructor map[string]constructorFunc
}
func NewRegistry() *Registry {
return &Registry{
optionsType: make(map[string]optionsConstructorFunc),
constructor: make(map[string]constructorFunc),
}
}
func (m *Registry) CreateOptions(outboundType string) (any, bool) {
m.access.Lock()
defer m.access.Unlock()
optionsConstructor, loaded := m.optionsType[outboundType]
if !loaded {
return nil, false
}
return optionsConstructor(), true
}
func (m *Registry) Create(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, outboundType string, options any) (adapter.Endpoint, error) {
m.access.Lock()
defer m.access.Unlock()
constructor, loaded := m.constructor[outboundType]
if !loaded {
return nil, E.New("outbound type not found: " + outboundType)
}
return constructor(ctx, router, logger, tag, options)
}
func (m *Registry) register(outboundType string, optionsConstructor optionsConstructorFunc, constructor constructorFunc) {
m.access.Lock()
defer m.access.Unlock()
m.optionsType[outboundType] = optionsConstructor
m.constructor[outboundType] = constructor
}
================================================
FILE: adapter/endpoint.go
================================================
package adapter
import (
"context"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
)
type Endpoint interface {
Lifecycle
Type() string
Tag() string
Outbound
}
type EndpointRegistry interface {
option.EndpointOptionsRegistry
Create(ctx context.Context, router Router, logger log.ContextLogger, tag string, endpointType string, options any) (Endpoint, error)
}
type EndpointManager interface {
Lifecycle
Endpoints() []Endpoint
Get(tag string) (Endpoint, bool)
Remove(tag string) error
Create(ctx context.Context, router Router, logger log.ContextLogger, tag string, endpointType string, options any) error
}
================================================
FILE: adapter/experimental.go
================================================
package adapter
import (
"bytes"
"context"
"encoding/binary"
"io"
"time"
"github.com/sagernet/sing/common/observable"
"github.com/sagernet/sing/common/varbin"
)
type ClashServer interface {
LifecycleService
ConnectionTracker
Mode() string
ModeList() []string
SetModeUpdateHook(hook *observable.Subscriber[struct{}])
HistoryStorage() URLTestHistoryStorage
}
type URLTestHistory struct {
Time time.Time `json:"time"`
Delay uint16 `json:"delay"`
}
type URLTestHistoryStorage interface {
SetHook(hook *observable.Subscriber[struct{}])
LoadURLTestHistory(tag string) *URLTestHistory
DeleteURLTestHistory(tag string)
StoreURLTestHistory(tag string, history *URLTestHistory)
Close() error
}
type V2RayServer interface {
LifecycleService
StatsService() ConnectionTracker
}
type CacheFile interface {
LifecycleService
StoreFakeIP() bool
FakeIPStorage
StoreRDRC() bool
RDRCStore
StoreDNS() bool
DNSCacheStore
SetDisableExpire(disableExpire bool)
SetOptimisticTimeout(timeout time.Duration)
LoadMode() string
StoreMode(mode string) error
LoadSelected(group string) string
StoreSelected(group string, selected string) error
LoadGroupExpand(group string) (isExpand bool, loaded bool)
StoreGroupExpand(group string, expand bool) error
LoadRuleSet(tag string) *SavedBinary
SaveRuleSet(tag string, set *SavedBinary) error
}
type SavedBinary struct {
Content []byte
LastUpdated time.Time
LastEtag string
}
func (s *SavedBinary) MarshalBinary() ([]byte, error) {
var buffer bytes.Buffer
err := binary.Write(&buffer, binary.BigEndian, uint8(1))
if err != nil {
return nil, err
}
_, err = varbin.WriteUvarint(&buffer, uint64(len(s.Content)))
if err != nil {
return nil, err
}
_, err = buffer.Write(s.Content)
if err != nil {
return nil, err
}
err = binary.Write(&buffer, binary.BigEndian, s.LastUpdated.Unix())
if err != nil {
return nil, err
}
_, err = varbin.WriteUvarint(&buffer, uint64(len(s.LastEtag)))
if err != nil {
return nil, err
}
_, err = buffer.WriteString(s.LastEtag)
if err != nil {
return nil, err
}
return buffer.Bytes(), nil
}
func (s *SavedBinary) UnmarshalBinary(data []byte) error {
reader := bytes.NewReader(data)
var version uint8
err := binary.Read(reader, binary.BigEndian, &version)
if err != nil {
return err
}
contentLength, err := binary.ReadUvarint(reader)
if err != nil {
return err
}
s.Content = make([]byte, contentLength)
_, err = io.ReadFull(reader, s.Content)
if err != nil {
return err
}
var lastUpdated int64
err = binary.Read(reader, binary.BigEndian, &lastUpdated)
if err != nil {
return err
}
s.LastUpdated = time.Unix(lastUpdated, 0)
etagLength, err := binary.ReadUvarint(reader)
if err != nil {
return err
}
etagBytes := make([]byte, etagLength)
_, err = io.ReadFull(reader, etagBytes)
if err != nil {
return err
}
s.LastEtag = string(etagBytes)
return nil
}
type OutboundGroup interface {
Outbound
Now() string
All() []string
}
type URLTestGroup interface {
OutboundGroup
URLTest(ctx context.Context) (map[string]uint16, error)
}
func OutboundTag(detour Outbound) string {
if group, isGroup := detour.(OutboundGroup); isGroup {
return group.Now()
}
return detour.Tag()
}
================================================
FILE: adapter/fakeip.go
================================================
package adapter
import (
"net/netip"
"github.com/sagernet/sing/common/logger"
)
type FakeIPStore interface {
SimpleLifecycle
Contains(address netip.Addr) bool
Create(domain string, isIPv6 bool) (netip.Addr, error)
Lookup(address netip.Addr) (string, bool)
Reset() error
}
type FakeIPStorage interface {
FakeIPMetadata() *FakeIPMetadata
FakeIPSaveMetadata(metadata *FakeIPMetadata) error
FakeIPSaveMetadataAsync(metadata *FakeIPMetadata)
FakeIPStore(address netip.Addr, domain string) error
FakeIPStoreAsync(address netip.Addr, domain string, logger logger.Logger)
FakeIPLoad(address netip.Addr) (string, bool)
FakeIPLoadDomain(domain string, isIPv6 bool) (netip.Addr, bool)
FakeIPReset() error
}
type FakeIPTransport interface {
DNSTransport
Store() FakeIPStore
}
================================================
FILE: adapter/fakeip_metadata.go
================================================
package adapter
import (
"bytes"
"encoding"
"encoding/binary"
"io"
"net/netip"
"github.com/sagernet/sing/common"
)
type FakeIPMetadata struct {
Inet4Range netip.Prefix
Inet6Range netip.Prefix
Inet4Current netip.Addr
Inet6Current netip.Addr
}
func (m *FakeIPMetadata) MarshalBinary() (data []byte, err error) {
var buffer bytes.Buffer
for _, marshaler := range []encoding.BinaryMarshaler{m.Inet4Range, m.Inet6Range, m.Inet4Current, m.Inet6Current} {
data, err = marshaler.MarshalBinary()
if err != nil {
return
}
common.Must(binary.Write(&buffer, binary.BigEndian, uint16(len(data))))
buffer.Write(data)
}
data = buffer.Bytes()
return
}
func (m *FakeIPMetadata) UnmarshalBinary(data []byte) error {
reader := bytes.NewReader(data)
for _, unmarshaler := range []encoding.BinaryUnmarshaler{&m.Inet4Range, &m.Inet6Range, &m.Inet4Current, &m.Inet6Current} {
var length uint16
common.Must(binary.Read(reader, binary.BigEndian, &length))
element := make([]byte, length)
_, err := io.ReadFull(reader, element)
if err != nil {
return err
}
err = unmarshaler.UnmarshalBinary(element)
if err != nil {
return err
}
}
return nil
}
================================================
FILE: adapter/handler.go
================================================
package adapter
import (
"context"
"net"
"github.com/sagernet/sing/common/buf"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
)
type ConnectionHandler interface {
NewConnection(ctx context.Context, conn net.Conn, metadata InboundContext, onClose N.CloseHandlerFunc)
}
type PacketHandler interface {
NewPacket(buffer *buf.Buffer, source M.Socksaddr)
}
type PacketBatchHandler interface {
NewPacketBatch(buffers []*buf.Buffer, sources []M.Socksaddr)
}
type OOBPacketHandler interface {
NewPacket(buffer *buf.Buffer, oob []byte, source M.Socksaddr)
}
type PacketConnectionHandler interface {
NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata InboundContext, onClose N.CloseHandlerFunc)
}
type UpstreamHandlerAdapter interface {
N.TCPConnectionHandlerEx
N.UDPConnectionHandlerEx
}
================================================
FILE: adapter/http.go
================================================
package adapter
import (
"context"
"net/http"
"sync"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing/common/logger"
)
type HTTPTransport interface {
http.RoundTripper
CloseIdleConnections()
Reset()
}
type HTTPClientManager interface {
ResolveTransport(ctx context.Context, logger logger.ContextLogger, options option.HTTPClientOptions) (HTTPTransport, error)
DefaultTransport() HTTPTransport
ResetNetwork()
}
type HTTPStartContext struct {
access sync.Mutex
transports []HTTPTransport
}
func NewHTTPStartContext() *HTTPStartContext {
return &HTTPStartContext{}
}
func (c *HTTPStartContext) Register(transport HTTPTransport) {
c.access.Lock()
defer c.access.Unlock()
c.transports = append(c.transports, transport)
}
func (c *HTTPStartContext) Close() {
for _, transport := range c.transports {
transport.CloseIdleConnections()
}
}
================================================
FILE: adapter/inbound/adapter.go
================================================
package inbound
type Adapter struct {
inboundType string
inboundTag string
}
func NewAdapter(inboundType string, inboundTag string) Adapter {
return Adapter{
inboundType: inboundType,
inboundTag: inboundTag,
}
}
func (a *Adapter) Type() string {
return a.inboundType
}
func (a *Adapter) Tag() string {
return a.inboundTag
}
================================================
FILE: adapter/inbound/manager.go
================================================
package inbound
import (
"context"
"os"
"sync"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/taskmonitor"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
)
var _ adapter.InboundManager = (*Manager)(nil)
type Manager struct {
logger log.ContextLogger
registry adapter.InboundRegistry
endpoint adapter.EndpointManager
access sync.Mutex
started bool
stage adapter.StartStage
inbounds []adapter.Inbound
inboundByTag map[string]adapter.Inbound
}
func NewManager(logger log.ContextLogger, registry adapter.InboundRegistry, endpoint adapter.EndpointManager) *Manager {
return &Manager{
logger: logger,
registry: registry,
endpoint: endpoint,
inboundByTag: make(map[string]adapter.Inbound),
}
}
func (m *Manager) Start(stage adapter.StartStage) error {
m.access.Lock()
if m.started && m.stage >= stage {
panic("already started")
}
m.started = true
m.stage = stage
inbounds := m.inbounds
m.access.Unlock()
for _, inbound := range inbounds {
name := "inbound/" + inbound.Type() + "[" + inbound.Tag() + "]"
done := adapter.LogElapsed(m.logger, stage, " ", name)
err := adapter.LegacyStart(inbound, stage)
done()
if err != nil {
return E.Cause(err, stage, " ", name)
}
}
return nil
}
func (m *Manager) Close() error {
m.access.Lock()
defer m.access.Unlock()
if !m.started {
return nil
}
m.started = false
inbounds := m.inbounds
m.inbounds = nil
monitor := taskmonitor.New(m.logger, C.StopTimeout)
var err error
for _, inbound := range inbounds {
name := "inbound/" + inbound.Type() + "[" + inbound.Tag() + "]"
done := adapter.LogElapsed(m.logger, "close ", name)
monitor.Start("close ", name)
err = E.Append(err, inbound.Close(), func(err error) error {
return E.Cause(err, "close ", name)
})
monitor.Finish()
done()
}
return nil
}
func (m *Manager) Inbounds() []adapter.Inbound {
m.access.Lock()
defer m.access.Unlock()
return m.inbounds
}
func (m *Manager) Get(tag string) (adapter.Inbound, bool) {
m.access.Lock()
inbound, found := m.inboundByTag[tag]
m.access.Unlock()
if found {
return inbound, true
}
return m.endpoint.Get(tag)
}
func (m *Manager) Remove(tag string) error {
m.access.Lock()
inbound, found := m.inboundByTag[tag]
if !found {
m.access.Unlock()
return os.ErrInvalid
}
delete(m.inboundByTag, tag)
index := common.Index(m.inbounds, func(it adapter.Inbound) bool {
return it == inbound
})
if index == -1 {
panic("invalid inbound index")
}
m.inbounds = append(m.inbounds[:index], m.inbounds[index+1:]...)
started := m.started
m.access.Unlock()
if started {
return inbound.Close()
}
return nil
}
func (m *Manager) Create(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, outboundType string, options any) error {
inbound, err := m.registry.Create(ctx, router, logger, tag, outboundType, options)
if err != nil {
return err
}
m.access.Lock()
defer m.access.Unlock()
if m.started {
name := "inbound/" + inbound.Type() + "[" + inbound.Tag() + "]"
for _, stage := range adapter.ListStartStages {
done := adapter.LogElapsed(m.logger, stage, " ", name)
err = adapter.LegacyStart(inbound, stage)
done()
if err != nil {
return E.Cause(err, stage, " ", name)
}
}
}
if existsInbound, loaded := m.inboundByTag[tag]; loaded {
if m.started {
err = existsInbound.Close()
if err != nil {
return E.Cause(err, "close inbound/", existsInbound.Type(), "[", existsInbound.Tag(), "]")
}
}
existsIndex := common.Index(m.inbounds, func(it adapter.Inbound) bool {
return it == existsInbound
})
if existsIndex == -1 {
panic("invalid inbound index")
}
m.inbounds = append(m.inbounds[:existsIndex], m.inbounds[existsIndex+1:]...)
}
m.inbounds = append(m.inbounds, inbound)
m.inboundByTag[tag] = inbound
return nil
}
================================================
FILE: adapter/inbound/registry.go
================================================
package inbound
import (
"context"
"sync"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
)
type ConstructorFunc[T any] func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options T) (adapter.Inbound, error)
func Register[Options any](registry *Registry, outboundType string, constructor ConstructorFunc[Options]) {
registry.register(outboundType, func() any {
return new(Options)
}, func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, rawOptions any) (adapter.Inbound, error) {
var options *Options
if rawOptions != nil {
options = rawOptions.(*Options)
}
return constructor(ctx, router, logger, tag, common.PtrValueOrDefault(options))
})
}
var _ adapter.InboundRegistry = (*Registry)(nil)
type (
optionsConstructorFunc func() any
constructorFunc func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options any) (adapter.Inbound, error)
)
type Registry struct {
access sync.Mutex
optionsType map[string]optionsConstructorFunc
constructor map[string]constructorFunc
}
func NewRegistry() *Registry {
return &Registry{
optionsType: make(map[string]optionsConstructorFunc),
constructor: make(map[string]constructorFunc),
}
}
func (m *Registry) CreateOptions(outboundType string) (any, bool) {
m.access.Lock()
defer m.access.Unlock()
optionsConstructor, loaded := m.optionsType[outboundType]
if !loaded {
return nil, false
}
return optionsConstructor(), true
}
func (m *Registry) Create(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, outboundType string, options any) (adapter.Inbound, error) {
m.access.Lock()
defer m.access.Unlock()
constructor, loaded := m.constructor[outboundType]
if !loaded {
return nil, E.New("outbound type not found: " + outboundType)
}
return constructor(ctx, router, logger, tag, options)
}
func (m *Registry) register(outboundType string, optionsConstructor optionsConstructorFunc, constructor constructorFunc) {
m.access.Lock()
defer m.access.Unlock()
m.optionsType[outboundType] = optionsConstructor
m.constructor[outboundType] = constructor
}
================================================
FILE: adapter/inbound.go
================================================
package adapter
import (
"context"
"net"
"net/netip"
"time"
"github.com/sagernet/sing-box/common/tlsspoof"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
M "github.com/sagernet/sing/common/metadata"
"github.com/miekg/dns"
)
type Inbound interface {
Lifecycle
Type() string
Tag() string
}
type TCPInjectableInbound interface {
Inbound
ConnectionHandler
}
type UDPInjectableInbound interface {
Inbound
PacketConnectionHandler
}
type InboundRegistry interface {
option.InboundOptionsRegistry
Create(ctx context.Context, router Router, logger log.ContextLogger, tag string, inboundType string, options any) (Inbound, error)
}
type InboundManager interface {
Lifecycle
Inbounds() []Inbound
Get(tag string) (Inbound, bool)
Remove(tag string) error
Create(ctx context.Context, router Router, logger log.ContextLogger, tag string, inboundType string, options any) error
}
type InboundContext struct {
Inbound string
InboundType string
IPVersion uint8
Network string
Source M.Socksaddr
Destination M.Socksaddr
User string
Outbound string
// sniffer
Protocol string
Domain string
Client string
SniffContext any
SnifferNames []string
SniffError error
// cache
// Deprecated: implement in rule action
InboundDetour string
LastInbound string
OriginDestination M.Socksaddr
RouteOriginalDestination M.Socksaddr
UDPDisableDomainUnmapping bool
UDPConnect bool
UDPTimeout time.Duration
TLSFragment bool
TLSFragmentFallbackDelay time.Duration
TLSRecordFragment bool
TLSSpoof string
TLSSpoofMethod tlsspoof.Method
NetworkStrategy *C.NetworkStrategy
NetworkType []C.InterfaceType
FallbackNetworkType []C.InterfaceType
FallbackDelay time.Duration
DestinationAddresses []netip.Addr
DNSResponse *dns.Msg
DestinationAddressMatchFromResponse bool
SourceGeoIPCode string
GeoIPCode string
ProcessInfo *ConnectionOwner
SourceMACAddress net.HardwareAddr
SourceHostname string
QueryType uint16
FakeIP bool
// rule cache
IPCIDRMatchSource bool
IPCIDRAcceptEmpty bool
SourceAddressMatch bool
SourcePortMatch bool
DestinationAddressMatch bool
DestinationPortMatch bool
DidMatch bool
IgnoreDestinationIPCIDRMatch bool
}
func (c *InboundContext) ResetRuleCache() {
c.IPCIDRMatchSource = false
c.IPCIDRAcceptEmpty = false
c.ResetRuleMatchCache()
}
func (c *InboundContext) ResetRuleMatchCache() {
c.SourceAddressMatch = false
c.SourcePortMatch = false
c.DestinationAddressMatch = false
c.DestinationPortMatch = false
c.DidMatch = false
}
func (c *InboundContext) DNSResponseAddressesForMatch() []netip.Addr {
return DNSResponseAddresses(c.DNSResponse)
}
func DNSResponseAddresses(response *dns.Msg) []netip.Addr {
if response == nil || response.Rcode != dns.RcodeSuccess {
return nil
}
addresses := make([]netip.Addr, 0, len(response.Answer))
for _, rawRecord := range response.Answer {
switch record := rawRecord.(type) {
case *dns.A:
addr := M.AddrFromIP(record.A)
if addr.IsValid() {
addresses = append(addresses, addr)
}
case *dns.AAAA:
addr := M.AddrFromIP(record.AAAA)
if addr.IsValid() {
addresses = append(addresses, addr)
}
case *dns.HTTPS:
for _, value := range record.SVCB.Value {
switch hint := value.(type) {
case *dns.SVCBIPv4Hint:
for _, ip := range hint.Hint {
addr := M.AddrFromIP(ip).Unmap()
if addr.IsValid() {
addresses = append(addresses, addr)
}
}
case *dns.SVCBIPv6Hint:
for _, ip := range hint.Hint {
addr := M.AddrFromIP(ip)
if addr.IsValid() {
addresses = append(addresses, addr)
}
}
}
}
}
}
return addresses
}
type inboundContextKey struct{}
func WithContext(ctx context.Context, inboundContext *InboundContext) context.Context {
return context.WithValue(ctx, (*inboundContextKey)(nil), inboundContext)
}
func ContextFrom(ctx context.Context) *InboundContext {
metadata := ctx.Value((*inboundContextKey)(nil))
if metadata == nil {
return nil
}
return metadata.(*InboundContext)
}
func ExtendContext(ctx context.Context) (context.Context, *InboundContext) {
var newMetadata InboundContext
if metadata := ContextFrom(ctx); metadata != nil {
newMetadata = *metadata
}
return WithContext(ctx, &newMetadata), &newMetadata
}
func OverrideContext(ctx context.Context) context.Context {
if metadata := ContextFrom(ctx); metadata != nil {
newMetadata := *metadata
return WithContext(ctx, &newMetadata)
}
return ctx
}
================================================
FILE: adapter/inbound_test.go
================================================
package adapter
import (
"net"
"net/netip"
"testing"
"github.com/miekg/dns"
"github.com/stretchr/testify/require"
)
func TestDNSResponseAddressesUnmapsHTTPSIPv4Hints(t *testing.T) {
t.Parallel()
ipv4Hint := net.ParseIP("1.1.1.1")
require.NotNil(t, ipv4Hint)
response := &dns.Msg{
MsgHdr: dns.MsgHdr{
Response: true,
Rcode: dns.RcodeSuccess,
},
Answer: []dns.RR{
&dns.HTTPS{
SVCB: dns.SVCB{
Hdr: dns.RR_Header{
Name: dns.Fqdn("example.com"),
Rrtype: dns.TypeHTTPS,
Class: dns.ClassINET,
Ttl: 60,
},
Priority: 1,
Target: ".",
Value: []dns.SVCBKeyValue{
&dns.SVCBIPv4Hint{Hint: []net.IP{ipv4Hint}},
},
},
},
},
}
addresses := DNSResponseAddresses(response)
require.Equal(t, []netip.Addr{netip.MustParseAddr("1.1.1.1")}, addresses)
require.True(t, addresses[0].Is4())
}
================================================
FILE: adapter/lifecycle.go
================================================
package adapter
import (
"reflect"
"strings"
"time"
"github.com/sagernet/sing-box/log"
E "github.com/sagernet/sing/common/exceptions"
F "github.com/sagernet/sing/common/format"
)
type SimpleLifecycle interface {
Start() error
Close() error
}
type StartStage uint8
const (
StartStateInitialize StartStage = iota
StartStateStart
StartStatePostStart
StartStateStarted
)
var ListStartStages = []StartStage{
StartStateInitialize,
StartStateStart,
StartStatePostStart,
StartStateStarted,
}
func (s StartStage) String() string {
switch s {
case StartStateInitialize:
return "initialize"
case StartStateStart:
return "start"
case StartStatePostStart:
return "post-start"
case StartStateStarted:
return "finish-start"
default:
panic("unknown stage")
}
}
type Lifecycle interface {
Start(stage StartStage) error
Close() error
}
type LifecycleService interface {
Name() string
Lifecycle
}
func getServiceName(service any) string {
if named, ok := service.(interface {
Type() string
Tag() string
}); ok {
tag := named.Tag()
if tag != "" {
return named.Type() + "[" + tag + "]"
}
return named.Type()
}
t := reflect.TypeOf(service)
if t.Kind() == reflect.Ptr {
t = t.Elem()
}
return strings.ToLower(t.Name())
}
func Start(logger log.ContextLogger, stage StartStage, services ...Lifecycle) error {
for _, service := range services {
name := getServiceName(service)
done := LogElapsed(logger, stage, " ", name)
err := service.Start(stage)
done()
if err != nil {
return err
}
}
return nil
}
func StartNamed(logger log.ContextLogger, stage StartStage, services []LifecycleService) error {
for _, service := range services {
done := LogElapsed(logger, stage, " ", service.Name())
err := service.Start(stage)
done()
if err != nil {
return E.Cause(err, stage.String(), " ", service.Name())
}
}
return nil
}
func LogElapsed(logger log.ContextLogger, description ...any) func() {
prefix := F.ToString(description...)
startTime := time.Now()
timer := time.AfterFunc(time.Second, func() {
logger.Trace(prefix, "...")
})
return func() {
if timer.Stop() {
return
}
logger.Trace(prefix, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
}
}
================================================
FILE: adapter/lifecycle_legacy.go
================================================
package adapter
func LegacyStart(starter any, stage StartStage) error {
if lifecycle, isLifecycle := starter.(Lifecycle); isLifecycle {
return lifecycle.Start(stage)
}
switch stage {
case StartStateInitialize:
if preStarter, isPreStarter := starter.(interface {
PreStart() error
}); isPreStarter {
return preStarter.PreStart()
}
case StartStateStart:
if starter, isStarter := starter.(interface {
Start() error
}); isStarter {
return starter.Start()
}
case StartStateStarted:
if postStarter, isPostStarter := starter.(interface {
PostStart() error
}); isPostStarter {
return postStarter.PostStart()
}
}
return nil
}
type lifecycleServiceWrapper struct {
SimpleLifecycle
name string
}
func NewLifecycleService(service SimpleLifecycle, name string) LifecycleService {
return &lifecycleServiceWrapper{
SimpleLifecycle: service,
name: name,
}
}
func (l *lifecycleServiceWrapper) Name() string {
return l.name
}
func (l *lifecycleServiceWrapper) Start(stage StartStage) error {
return LegacyStart(l.SimpleLifecycle, stage)
}
func (l *lifecycleServiceWrapper) Close() error {
return l.SimpleLifecycle.Close()
}
================================================
FILE: adapter/neighbor.go
================================================
package adapter
import (
"net"
"net/netip"
)
type NeighborEntry struct {
Address netip.Addr
MACAddress net.HardwareAddr
Hostname string
}
type NeighborResolver interface {
LookupMAC(address netip.Addr) (net.HardwareAddr, bool)
LookupHostname(address netip.Addr) (string, bool)
LookupAddresses(hostname string) []netip.Addr
Start() error
Close() error
}
type NeighborUpdateListener interface {
UpdateNeighborTable(entries []NeighborEntry)
}
================================================
FILE: adapter/network.go
================================================
package adapter
import (
"encoding/hex"
"net"
"strings"
"time"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-tun"
"github.com/sagernet/sing/common/control"
)
type NetworkManager interface {
Lifecycle
Initialize(ruleSets []RuleSet)
InterfaceFinder() control.InterfaceFinder
UpdateInterfaces() error
DefaultNetworkInterface() *NetworkInterface
NetworkInterfaces() []NetworkInterface
AutoDetectInterface() bool
AutoDetectInterfaceFunc() control.Func
ProtectFunc() control.Func
DefaultOptions() NetworkOptions
RegisterAutoRedirectOutputMark(mark uint32) error
AutoRedirectOutputMark() uint32
AutoRedirectOutputMarkFunc() control.Func
NetworkMonitor() tun.NetworkUpdateMonitor
InterfaceMonitor() tun.DefaultInterfaceMonitor
PackageManager() tun.PackageManager
NeedWIFIState() bool
WIFIState() WIFIState
UpdateWIFIState()
ResetNetwork()
}
type NetworkOptions struct {
BindInterface string
RoutingMark uint32
DomainResolver string
DomainResolveOptions DNSQueryOptions
NetworkStrategy *C.NetworkStrategy
NetworkType []C.InterfaceType
FallbackNetworkType []C.InterfaceType
FallbackDelay time.Duration
}
type InterfaceUpdateListener interface {
InterfaceUpdated()
}
type WIFIState struct {
SSID string
BSSID string
}
func NormalizeWIFIBSSID(bssid string) string {
bssid = strings.TrimSpace(bssid)
if bssid == "" {
return ""
}
parsed, err := net.ParseMAC(bssid)
if err == nil && len(parsed) == 6 {
return parsed.String()
}
if len(bssid) == 12 {
decoded, err := hex.DecodeString(bssid)
if err == nil {
return net.HardwareAddr(decoded).String()
}
}
return bssid
}
type NetworkInterface struct {
control.Interface
Type C.InterfaceType
DNSServers []string
Expensive bool
Constrained bool
}
================================================
FILE: adapter/outbound/adapter.go
================================================
package outbound
import (
"github.com/sagernet/sing-box/option"
)
type Adapter struct {
outboundType string
outboundTag string
network []string
dependencies []string
}
func NewAdapter(outboundType string, outboundTag string, network []string, dependencies []string) Adapter {
return Adapter{
outboundType: outboundType,
outboundTag: outboundTag,
network: network,
dependencies: dependencies,
}
}
func NewAdapterWithDialerOptions(outboundType string, outboundTag string, network []string, dialOptions option.DialerOptions) Adapter {
var dependencies []string
if dialOptions.Detour != "" {
dependencies = []string{dialOptions.Detour}
}
return NewAdapter(outboundType, outboundTag, network, dependencies)
}
func (a *Adapter) Type() string {
return a.outboundType
}
func (a *Adapter) Tag() string {
return a.outboundTag
}
func (a *Adapter) Network() []string {
return a.network
}
func (a *Adapter) Dependencies() []string {
return a.dependencies
}
================================================
FILE: adapter/outbound/manager.go
================================================
package outbound
import (
"context"
"io"
"os"
"strings"
"sync"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/taskmonitor"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/logger"
)
var _ adapter.OutboundManager = (*Manager)(nil)
type Manager struct {
logger log.ContextLogger
registry adapter.OutboundRegistry
endpoint adapter.EndpointManager
defaultTag string
access sync.RWMutex
started bool
stage adapter.StartStage
outbounds []adapter.Outbound
outboundByTag map[string]adapter.Outbound
dependByTag map[string][]string
defaultOutbound adapter.Outbound
defaultOutboundFallback func() (adapter.Outbound, error)
}
func NewManager(logger logger.ContextLogger, registry adapter.OutboundRegistry, endpoint adapter.EndpointManager, defaultTag string) *Manager {
return &Manager{
logger: logger,
registry: registry,
endpoint: endpoint,
defaultTag: defaultTag,
outboundByTag: make(map[string]adapter.Outbound),
dependByTag: make(map[string][]string),
}
}
func (m *Manager) Initialize(defaultOutboundFallback func() (adapter.Outbound, error)) {
m.defaultOutboundFallback = defaultOutboundFallback
}
func (m *Manager) Start(stage adapter.StartStage) error {
m.access.Lock()
if m.started && m.stage >= stage {
panic("already started")
}
m.started = true
m.stage = stage
if stage == adapter.StartStateStart {
if m.defaultTag != "" && m.defaultOutbound == nil {
defaultEndpoint, loaded := m.endpoint.Get(m.defaultTag)
if !loaded {
m.access.Unlock()
return E.New("default outbound not found: ", m.defaultTag)
}
m.defaultOutbound = defaultEndpoint
}
if m.defaultOutbound == nil {
directOutbound, err := m.defaultOutboundFallback()
if err != nil {
m.access.Unlock()
return E.Cause(err, "create direct outbound for fallback")
}
m.outbounds = append(m.outbounds, directOutbound)
m.outboundByTag[directOutbound.Tag()] = directOutbound
m.defaultOutbound = directOutbound
}
outbounds := m.outbounds
m.access.Unlock()
return m.startOutbounds(append(outbounds, common.Map(m.endpoint.Endpoints(), func(it adapter.Endpoint) adapter.Outbound { return it })...))
} else {
outbounds := m.outbounds
m.access.Unlock()
for _, outbound := range outbounds {
name := "outbound/" + outbound.Type() + "[" + outbound.Tag() + "]"
done := adapter.LogElapsed(m.logger, stage, " ", name)
err := adapter.LegacyStart(outbound, stage)
done()
if err != nil {
return E.Cause(err, stage, " ", name)
}
}
}
return nil
}
func (m *Manager) startOutbounds(outbounds []adapter.Outbound) error {
monitor := taskmonitor.New(m.logger, C.StartTimeout)
started := make(map[string]bool)
for {
canContinue := false
startOne:
for _, outboundToStart := range outbounds {
outboundTag := outboundToStart.Tag()
if started[outboundTag] {
continue
}
dependencies := outboundToStart.Dependencies()
for _, dependency := range dependencies {
if !started[dependency] {
continue startOne
}
}
started[outboundTag] = true
canContinue = true
name := "outbound/" + outboundToStart.Type() + "[" + outboundTag + "]"
if starter, isStarter := outboundToStart.(adapter.Lifecycle); isStarter {
done := adapter.LogElapsed(m.logger, "start ", name)
monitor.Start("start ", name)
err := starter.Start(adapter.StartStateStart)
monitor.Finish()
done()
if err != nil {
return E.Cause(err, "start ", name)
}
} else if starter, isStarter := outboundToStart.(interface {
Start() error
}); isStarter {
done := adapter.LogElapsed(m.logger, "start ", name)
monitor.Start("start ", name)
err := starter.Start()
monitor.Finish()
done()
if err != nil {
return E.Cause(err, "start ", name)
}
}
}
if len(started) == len(outbounds) {
break
}
if canContinue {
continue
}
currentOutbound := common.Find(outbounds, func(it adapter.Outbound) bool {
return !started[it.Tag()]
})
var lintOutbound func(oTree []string, oCurrent adapter.Outbound) error
lintOutbound = func(oTree []string, oCurrent adapter.Outbound) error {
problemOutboundTag := common.Find(oCurrent.Dependencies(), func(it string) bool {
return !started[it]
})
if common.Contains(oTree, problemOutboundTag) {
return E.New("circular outbound dependency: ", strings.Join(oTree, " -> "), " -> ", problemOutboundTag)
}
m.access.Lock()
problemOutbound := m.outboundByTag[problemOutboundTag]
m.access.Unlock()
if problemOutbound == nil {
return E.New("dependency[", problemOutboundTag, "] not found for outbound[", oCurrent.Tag(), "]")
}
return lintOutbound(append(oTree, problemOutboundTag), problemOutbound)
}
return lintOutbound([]string{currentOutbound.Tag()}, currentOutbound)
}
return nil
}
func (m *Manager) Close() error {
monitor := taskmonitor.New(m.logger, C.StopTimeout)
m.access.Lock()
if !m.started {
m.access.Unlock()
return nil
}
m.started = false
outbounds := m.outbounds
m.outbounds = nil
m.access.Unlock()
var err error
for _, outbound := range outbounds {
if closer, isCloser := outbound.(io.Closer); isCloser {
name := "outbound/" + outbound.Type() + "[" + outbound.Tag() + "]"
done := adapter.LogElapsed(m.logger, "close ", name)
monitor.Start("close ", name)
err = E.Append(err, closer.Close(), func(err error) error {
return E.Cause(err, "close ", name)
})
monitor.Finish()
done()
}
}
return nil
}
func (m *Manager) Outbounds() []adapter.Outbound {
m.access.RLock()
defer m.access.RUnlock()
return m.outbounds
}
func (m *Manager) Outbound(tag string) (adapter.Outbound, bool) {
m.access.RLock()
outbound, found := m.outboundByTag[tag]
m.access.RUnlock()
if found {
return outbound, true
}
return m.endpoint.Get(tag)
}
func (m *Manager) Default() adapter.Outbound {
m.access.RLock()
defer m.access.RUnlock()
return m.defaultOutbound
}
func (m *Manager) Remove(tag string) error {
m.access.Lock()
defer m.access.Unlock()
outbound, found := m.outboundByTag[tag]
if !found {
return os.ErrInvalid
}
delete(m.outboundByTag, tag)
index := common.Index(m.outbounds, func(it adapter.Outbound) bool {
return it == outbound
})
if index == -1 {
panic("invalid inbound index")
}
m.outbounds = append(m.outbounds[:index], m.outbounds[index+1:]...)
started := m.started
if m.defaultOutbound == outbound {
if len(m.outbounds) > 0 {
m.defaultOutbound = m.outbounds[0]
m.logger.Info("updated default outbound to ", m.defaultOutbound.Tag())
} else {
m.defaultOutbound = nil
}
}
dependBy := m.dependByTag[tag]
if len(dependBy) > 0 {
return E.New("outbound[", tag, "] is depended by ", strings.Join(dependBy, ", "))
}
dependencies := outbound.Dependencies()
for _, dependency := range dependencies {
if len(m.dependByTag[dependency]) == 1 {
delete(m.dependByTag, dependency)
} else {
m.dependByTag[dependency] = common.Filter(m.dependByTag[dependency], func(it string) bool {
return it != tag
})
}
}
if started {
return common.Close(outbound)
}
return nil
}
func (m *Manager) Create(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, inboundType string, options any) error {
if tag == "" {
return os.ErrInvalid
}
outbound, err := m.registry.CreateOutbound(ctx, router, logger, tag, inboundType, options)
if err != nil {
return err
}
if m.started {
name := "outbound/" + outbound.Type() + "[" + outbound.Tag() + "]"
for _, stage := range adapter.ListStartStages {
done := adapter.LogElapsed(m.logger, stage, " ", name)
err = adapter.LegacyStart(outbound, stage)
done()
if err != nil {
return E.Cause(err, stage, " ", name)
}
}
}
m.access.Lock()
defer m.access.Unlock()
if existsOutbound, loaded := m.outboundByTag[tag]; loaded {
if m.started {
err = common.Close(existsOutbound)
if err != nil {
return E.Cause(err, "close outbound/", existsOutbound.Type(), "[", existsOutbound.Tag(), "]")
}
}
existsIndex := common.Index(m.outbounds, func(it adapter.Outbound) bool {
return it == existsOutbound
})
if existsIndex == -1 {
panic("invalid inbound index")
}
m.outbounds = append(m.outbounds[:existsIndex], m.outbounds[existsIndex+1:]...)
}
m.outbounds = append(m.outbounds, outbound)
m.outboundByTag[tag] = outbound
dependencies := outbound.Dependencies()
for _, dependency := range dependencies {
m.dependByTag[dependency] = append(m.dependByTag[dependency], tag)
}
if tag == m.defaultTag || (m.defaultTag == "" && m.defaultOutbound == nil) {
m.defaultOutbound = outbound
if m.started {
m.logger.Info("updated default outbound to ", outbound.Tag())
}
}
return nil
}
================================================
FILE: adapter/outbound/registry.go
================================================
package outbound
import (
"context"
"sync"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
)
type ConstructorFunc[T any] func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options T) (adapter.Outbound, error)
func Register[Options any](registry *Registry, outboundType string, constructor ConstructorFunc[Options]) {
registry.register(outboundType, func() any {
return new(Options)
}, func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, rawOptions any) (adapter.Outbound, error) {
var options *Options
if rawOptions != nil {
options = rawOptions.(*Options)
}
return constructor(ctx, router, logger, tag, common.PtrValueOrDefault(options))
})
}
var _ adapter.OutboundRegistry = (*Registry)(nil)
type (
optionsConstructorFunc func() any
constructorFunc func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options any) (adapter.Outbound, error)
)
type Registry struct {
access sync.Mutex
optionsType map[string]optionsConstructorFunc
constructors map[string]constructorFunc
}
func NewRegistry() *Registry {
return &Registry{
optionsType: make(map[string]optionsConstructorFunc),
constructors: make(map[string]constructorFunc),
}
}
func (r *Registry) CreateOptions(outboundType string) (any, bool) {
r.access.Lock()
defer r.access.Unlock()
optionsConstructor, loaded := r.optionsType[outboundType]
if !loaded {
return nil, false
}
return optionsConstructor(), true
}
func (r *Registry) CreateOutbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, outboundType string, options any) (adapter.Outbound, error) {
r.access.Lock()
defer r.access.Unlock()
constructor, loaded := r.constructors[outboundType]
if !loaded {
return nil, E.New("outbound type not found: " + outboundType)
}
return constructor(ctx, router, logger, tag, options)
}
func (r *Registry) register(outboundType string, optionsConstructor optionsConstructorFunc, constructor constructorFunc) {
r.access.Lock()
defer r.access.Unlock()
r.optionsType[outboundType] = optionsConstructor
r.constructors[outboundType] = constructor
}
================================================
FILE: adapter/outbound.go
================================================
package adapter
import (
"context"
"net/netip"
"time"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-tun"
N "github.com/sagernet/sing/common/network"
)
// Note: for proxy protocols, outbound creates early connections by default.
type Outbound interface {
Type() string
Tag() string
Network() []string
Dependencies() []string
N.Dialer
}
type OutboundWithPreferredRoutes interface {
Outbound
PreferredDomain(domain string) bool
PreferredAddress(address netip.Addr) bool
}
type DirectRouteOutbound interface {
Outbound
NewDirectRouteConnection(metadata InboundContext, routeContext tun.DirectRouteContext, timeout time.Duration) (tun.DirectRouteDestination, error)
}
type OutboundRegistry interface {
option.OutboundOptionsRegistry
CreateOutbound(ctx context.Context, router Router, logger log.ContextLogger, tag string, outboundType string, options any) (Outbound, error)
}
type OutboundManager interface {
Lifecycle
Outbounds() []Outbound
Outbound(tag string) (Outbound, bool)
Default() Outbound
Remove(tag string) error
Create(ctx context.Context, router Router, logger log.ContextLogger, tag string, outboundType string, options any) error
}
================================================
FILE: adapter/platform.go
================================================
package adapter
import (
"net/netip"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-tun"
"github.com/sagernet/sing/common/logger"
)
type PlatformInterface interface {
Initialize(networkManager NetworkManager) error
UsePlatformAutoDetectInterfaceControl() bool
AutoDetectInterfaceControl(fd int) error
UsePlatformInterface() bool
OpenInterface(options *tun.Options, platformOptions option.TunPlatformOptions) (tun.Tun, error)
UsePlatformDefaultInterfaceMonitor() bool
CreateDefaultInterfaceMonitor(logger logger.Logger) tun.DefaultInterfaceMonitor
UsePlatformNetworkInterfaces() bool
NetworkInterfaces() ([]NetworkInterface, error)
UnderNetworkExtension() bool
NetworkExtensionIncludeAllNetworks() bool
ClearDNSCache()
RequestPermissionForWIFIState() error
ReadWIFIState() WIFIState
SystemCertificates() []string
UsePlatformConnectionOwnerFinder() bool
FindConnectionOwner(request *FindConnectionOwnerRequest) (*ConnectionOwner, error)
UsePlatformWIFIMonitor() bool
UsePlatformNotification() bool
SendNotification(notification *Notification) error
MyInterfaceAddress() []netip.Addr
UsePlatformNeighborResolver() bool
StartNeighborMonitor(listener NeighborUpdateListener) error
CloseNeighborMonitor(listener NeighborUpdateListener) error
}
type FindConnectionOwnerRequest struct {
IpProtocol int32
SourceAddress string
SourcePort int32
DestinationAddress string
DestinationPort int32
}
type ConnectionOwner struct {
ProcessID uint32
UserId int32
UserName string
ProcessPath string
AndroidPackageNames []string
}
type Notification struct {
Identifier string
TypeName string
TypeID int32
Title string
Subtitle string
Body string
OpenURL string
}
type SystemProxyStatus struct {
Available bool
Enabled bool
}
================================================
FILE: adapter/prestart.go
================================================
package adapter
================================================
FILE: adapter/router.go
================================================
package adapter
import (
"context"
"net"
"time"
"github.com/sagernet/sing-tun"
N "github.com/sagernet/sing/common/network"
"github.com/sagernet/sing/common/x/list"
"go4.org/netipx"
)
type Router interface {
Lifecycle
ConnectionRouter
PreMatch(metadata InboundContext, context tun.DirectRouteContext, timeout time.Duration, supportBypass bool) (tun.DirectRouteDestination, error)
ConnectionRouterEx
RuleSet(tag string) (RuleSet, bool)
Rules() []Rule
NeedFindProcess() bool
NeedFindNeighbor() bool
NeighborResolver() NeighborResolver
AppendTracker(tracker ConnectionTracker)
ResetNetwork()
}
type ConnectionTracker interface {
RoutedConnection(ctx context.Context, conn net.Conn, metadata InboundContext, matchedRule Rule, matchOutbound Outbound) net.Conn
RoutedPacketConnection(ctx context.Context, conn N.PacketConn, metadata InboundContext, matchedRule Rule, matchOutbound Outbound) N.PacketConn
}
// Deprecated: Use ConnectionRouterEx instead.
type ConnectionRouter interface {
RouteConnection(ctx context.Context, conn net.Conn, metadata InboundContext) error
RoutePacketConnection(ctx context.Context, conn N.PacketConn, metadata InboundContext) error
}
type ConnectionRouterEx interface {
ConnectionRouter
RouteConnectionEx(ctx context.Context, conn net.Conn, metadata InboundContext, onClose N.CloseHandlerFunc)
RoutePacketConnectionEx(ctx context.Context, conn N.PacketConn, metadata InboundContext, onClose N.CloseHandlerFunc)
}
type RuleSet interface {
Name() string
StartContext(ctx context.Context, startContext *HTTPStartContext) error
PostStart() error
Metadata() RuleSetMetadata
ExtractIPSet() []*netipx.IPSet
IncRef()
DecRef()
Cleanup()
RegisterCallback(callback RuleSetUpdateCallback) *list.Element[RuleSetUpdateCallback]
UnregisterCallback(element *list.Element[RuleSetUpdateCallback])
Close() error
HeadlessRule
}
type RuleSetUpdateCallback func(it RuleSet)
type DNSRuleSetUpdateValidator interface {
ValidateRuleSetMetadataUpdate(tag string, metadata RuleSetMetadata) error
}
// ip_version is not a headless-rule item, so ContainsIPVersionRule is intentionally absent.
type RuleSetMetadata struct {
ContainsProcessRule bool
ContainsWIFIRule bool
ContainsIPCIDRRule bool
ContainsDNSQueryTypeRule bool
// ContainsNonIPCIDRRule signals that the rule-set carries at least one sub-rule
// with a predicate other than destination ip_cidr / ip_set, so it can contribute
// to DNS pre-response matching. A rule-set where this is false and
// ContainsIPCIDRRule is true is "pure-IP" and matches nothing before a DNS
// response is available.
ContainsNonIPCIDRRule bool
}
================================================
FILE: adapter/rule.go
================================================
package adapter
import (
C "github.com/sagernet/sing-box/constant"
"github.com/miekg/dns"
)
type HeadlessRule interface {
Match(metadata *InboundContext) bool
String() string
}
type Rule interface {
HeadlessRule
SimpleLifecycle
Type() string
Action() RuleAction
}
type DNSRule interface {
Rule
LegacyPreMatch(metadata *InboundContext) bool
WithAddressLimit() bool
MatchAddressLimit(metadata *InboundContext, response *dns.Msg) bool
}
type RuleAction interface {
Type() string
String() string
}
func IsFinalAction(action RuleAction) bool {
switch action.Type() {
case C.RuleActionTypeSniff, C.RuleActionTypeResolve, C.RuleActionTypeEvaluate:
return false
default:
return true
}
}
================================================
FILE: adapter/service/adapter.go
================================================
package service
type Adapter struct {
serviceType string
serviceTag string
}
func NewAdapter(serviceType string, serviceTag string) Adapter {
return Adapter{
serviceType: serviceType,
serviceTag: serviceTag,
}
}
func (a *Adapter) Type() string {
return a.serviceType
}
func (a *Adapter) Tag() string {
return a.serviceTag
}
================================================
FILE: adapter/service/manager.go
================================================
package service
import (
"context"
"os"
"sync"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/taskmonitor"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
)
var _ adapter.ServiceManager = (*Manager)(nil)
type Manager struct {
logger log.ContextLogger
registry adapter.ServiceRegistry
access sync.Mutex
started bool
stage adapter.StartStage
services []adapter.Service
serviceByTag map[string]adapter.Service
}
func NewManager(logger log.ContextLogger, registry adapter.ServiceRegistry) *Manager {
return &Manager{
logger: logger,
registry: registry,
serviceByTag: make(map[string]adapter.Service),
}
}
func (m *Manager) Start(stage adapter.StartStage) error {
m.access.Lock()
if m.started && m.stage >= stage {
panic("already started")
}
m.started = true
m.stage = stage
services := m.services
m.access.Unlock()
for _, service := range services {
name := "service/" + service.Type() + "[" + service.Tag() + "]"
done := adapter.LogElapsed(m.logger, stage, " ", name)
err := adapter.LegacyStart(service, stage)
done()
if err != nil {
return E.Cause(err, stage, " ", name)
}
}
return nil
}
func (m *Manager) Close() error {
m.access.Lock()
defer m.access.Unlock()
if !m.started {
return nil
}
m.started = false
services := m.services
m.services = nil
monitor := taskmonitor.New(m.logger, C.StopTimeout)
var err error
for _, service := range services {
name := "service/" + service.Type() + "[" + service.Tag() + "]"
done := adapter.LogElapsed(m.logger, "close ", name)
monitor.Start("close ", name)
err = E.Append(err, service.Close(), func(err error) error {
return E.Cause(err, "close ", name)
})
monitor.Finish()
done()
}
return nil
}
func (m *Manager) Services() []adapter.Service {
m.access.Lock()
defer m.access.Unlock()
return m.services
}
func (m *Manager) Get(tag string) (adapter.Service, bool) {
m.access.Lock()
service, found := m.serviceByTag[tag]
m.access.Unlock()
return service, found
}
func (m *Manager) Remove(tag string) error {
m.access.Lock()
service, found := m.serviceByTag[tag]
if !found {
m.access.Unlock()
return os.ErrInvalid
}
delete(m.serviceByTag, tag)
index := common.Index(m.services, func(it adapter.Service) bool {
return it == service
})
if index == -1 {
panic("invalid service index")
}
m.services = append(m.services[:index], m.services[index+1:]...)
started := m.started
m.access.Unlock()
if started {
return service.Close()
}
return nil
}
func (m *Manager) Create(ctx context.Context, logger log.ContextLogger, tag string, serviceType string, options any) error {
service, err := m.registry.Create(ctx, logger, tag, serviceType, options)
if err != nil {
return err
}
m.access.Lock()
defer m.access.Unlock()
if m.started {
name := "service/" + service.Type() + "[" + service.Tag() + "]"
for _, stage := range adapter.ListStartStages {
done := adapter.LogElapsed(m.logger, stage, " ", name)
err = adapter.LegacyStart(service, stage)
done()
if err != nil {
return E.Cause(err, stage, " ", name)
}
}
}
if existsService, loaded := m.serviceByTag[tag]; loaded {
if m.started {
err = existsService.Close()
if err != nil {
return E.Cause(err, "close service/", existsService.Type(), "[", existsService.Tag(), "]")
}
}
existsIndex := common.Index(m.services, func(it adapter.Service) bool {
return it == existsService
})
if existsIndex == -1 {
panic("invalid service index")
}
m.services = append(m.services[:existsIndex], m.services[existsIndex+1:]...)
}
m.services = append(m.services, service)
m.serviceByTag[tag] = service
return nil
}
================================================
FILE: adapter/service/registry.go
================================================
package service
import (
"context"
"sync"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
)
type ConstructorFunc[T any] func(ctx context.Context, logger log.ContextLogger, tag string, options T) (adapter.Service, error)
func Register[Options any](registry *Registry, outboundType string, constructor ConstructorFunc[Options]) {
registry.register(outboundType, func() any {
return new(Options)
}, func(ctx context.Context, logger log.ContextLogger, tag string, rawOptions any) (adapter.Service, error) {
var options *Options
if rawOptions != nil {
options = rawOptions.(*Options)
}
return constructor(ctx, logger, tag, common.PtrValueOrDefault(options))
})
}
var _ adapter.ServiceRegistry = (*Registry)(nil)
type (
optionsConstructorFunc func() any
constructorFunc func(ctx context.Context, logger log.ContextLogger, tag string, options any) (adapter.Service, error)
)
type Registry struct {
access sync.Mutex
optionsType map[string]optionsConstructorFunc
constructor map[string]constructorFunc
}
func NewRegistry() *Registry {
return &Registry{
optionsType: make(map[string]optionsConstructorFunc),
constructor: make(map[string]constructorFunc),
}
}
func (m *Registry) CreateOptions(outboundType string) (any, bool) {
m.access.Lock()
defer m.access.Unlock()
optionsConstructor, loaded := m.optionsType[outboundType]
if !loaded {
return nil, false
}
return optionsConstructor(), true
}
func (m *Registry) Create(ctx context.Context, logger log.ContextLogger, tag string, outboundType string, options any) (adapter.Service, error) {
m.access.Lock()
defer m.access.Unlock()
constructor, loaded := m.constructor[outboundType]
if !loaded {
return nil, E.New("outbound type not found: " + outboundType)
}
return constructor(ctx, logger, tag, options)
}
func (m *Registry) register(outboundType string, optionsConstructor optionsConstructorFunc, constructor constructorFunc) {
m.access.Lock()
defer m.access.Unlock()
m.optionsType[outboundType] = optionsConstructor
m.constructor[outboundType] = constructor
}
================================================
FILE: adapter/service.go
================================================
package adapter
import (
"context"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
)
type Service interface {
Lifecycle
Type() string
Tag() string
}
type ServiceRegistry interface {
option.ServiceOptionsRegistry
Create(ctx context.Context, logger log.ContextLogger, tag string, serviceType string, options any) (Service, error)
}
type ServiceManager interface {
Lifecycle
Services() []Service
Get(tag string) (Service, bool)
Remove(tag string) error
Create(ctx context.Context, logger log.ContextLogger, tag string, serviceType string, options any) error
}
================================================
FILE: adapter/ssm.go
================================================
package adapter
import (
"net"
N "github.com/sagernet/sing/common/network"
)
type ManagedSSMServer interface {
Inbound
SetTracker(tracker SSMTracker)
UpdateUsers(users []string, uPSKs []string) error
}
type SSMTracker interface {
TrackConnection(conn net.Conn, metadata InboundContext) net.Conn
TrackPacketConnection(conn N.PacketConn, metadata InboundContext) N.PacketConn
}
================================================
FILE: adapter/tailscale.go
================================================
package adapter
import "context"
type TailscaleEndpoint interface {
SubscribeTailscaleStatus(ctx context.Context, fn func(*TailscaleEndpointStatus)) error
StartTailscalePing(ctx context.Context, peerIP string, fn func(*TailscalePingResult)) error
}
type TailscalePingResult struct {
LatencyMs float64
IsDirect bool
Endpoint string
DERPRegionID int32
DERPRegionCode string
Error string
}
type TailscaleEndpointStatus struct {
BackendState string
AuthURL string
NetworkName string
MagicDNSSuffix string
Self *TailscalePeer
UserGroups []*TailscaleUserGroup
}
type TailscaleUserGroup struct {
UserID int64
LoginName string
DisplayName string
ProfilePicURL string
Peers []*TailscalePeer
}
type TailscalePeer struct {
HostName string
DNSName string
OS string
TailscaleIPs []string
Online bool
ExitNode bool
ExitNodeOption bool
Active bool
RxBytes int64
TxBytes int64
UserID int64
KeyExpiry int64
}
================================================
FILE: adapter/time.go
================================================
package adapter
import "time"
type TimeService interface {
SimpleLifecycle
TimeFunc() func() time.Time
}
================================================
FILE: adapter/upstream.go
================================================
package adapter
import (
"context"
"net"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
)
type (
ConnectionHandlerFunc = func(ctx context.Context, conn net.Conn, metadata InboundContext, onClose N.CloseHandlerFunc)
PacketConnectionHandlerFunc = func(ctx context.Context, conn N.PacketConn, metadata InboundContext, onClose N.CloseHandlerFunc)
)
func NewUpstreamHandler(
metadata InboundContext,
connectionHandler ConnectionHandlerFunc,
packetHandler PacketConnectionHandlerFunc,
) UpstreamHandlerAdapter {
return &myUpstreamHandlerWrapper{
metadata: metadata,
connectionHandler: connectionHandler,
packetHandler: packetHandler,
}
}
var _ UpstreamHandlerAdapter = (*myUpstreamHandlerWrapper)(nil)
type myUpstreamHandlerWrapper struct {
metadata InboundContext
connectionHandler ConnectionHandlerFunc
packetHandler PacketConnectionHandlerFunc
}
func (w *myUpstreamHandlerWrapper) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
myMetadata := w.metadata
if source.IsValid() {
myMetadata.Source = source
}
if destination.IsValid() {
myMetadata.Destination = destination
}
w.connectionHandler(ctx, conn, myMetadata, onClose)
}
func (w *myUpstreamHandlerWrapper) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
myMetadata := w.metadata
if source.IsValid() {
myMetadata.Source = source
}
if destination.IsValid() {
myMetadata.Destination = destination
}
w.packetHandler(ctx, conn, myMetadata, onClose)
}
var _ UpstreamHandlerAdapter = (*myUpstreamContextHandlerWrapper)(nil)
type myUpstreamContextHandlerWrapper struct {
connectionHandler ConnectionHandlerFunc
packetHandler PacketConnectionHandlerFunc
}
func NewUpstreamContextHandler(
connectionHandler ConnectionHandlerFunc,
packetHandler PacketConnectionHandlerFunc,
) UpstreamHandlerAdapter {
return &myUpstreamContextHandlerWrapper{
connectionHandler: connectionHandler,
packetHandler: packetHandler,
}
}
func (w *myUpstreamContextHandlerWrapper) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
_, myMetadata := ExtendContext(ctx)
if source.IsValid() {
myMetadata.Source = source
}
if destination.IsValid() {
myMetadata.Destination = destination
}
w.connectionHandler(ctx, conn, *myMetadata, onClose)
}
func (w *myUpstreamContextHandlerWrapper) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
_, myMetadata := ExtendContext(ctx)
if source.IsValid() {
myMetadata.Source = source
}
if destination.IsValid() {
myMetadata.Destination = destination
}
w.packetHandler(ctx, conn, *myMetadata, onClose)
}
func NewRouteHandler(
metadata InboundContext,
router ConnectionRouterEx,
) UpstreamHandlerAdapter {
return &routeHandlerWrapper{
metadata: metadata,
router: router,
}
}
var _ UpstreamHandlerAdapter = (*routeHandlerWrapper)(nil)
type routeHandlerWrapper struct {
metadata InboundContext
router ConnectionRouterEx
}
func (r *routeHandlerWrapper) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
if source.IsValid() {
r.metadata.Source = source
}
if destination.IsValid() {
r.metadata.Destination = destination
}
r.router.RouteConnectionEx(ctx, conn, r.metadata, onClose)
}
func (r *routeHandlerWrapper) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
if source.IsValid() {
r.metadata.Source = source
}
if destination.IsValid() {
r.metadata.Destination = destination
}
r.router.RoutePacketConnectionEx(ctx, conn, r.metadata, onClose)
}
func NewRouteContextHandler(
router ConnectionRouterEx,
) UpstreamHandlerAdapter {
return &routeContextHandlerWrapper{
router: router,
}
}
var _ UpstreamHandlerAdapter = (*routeContextHandlerWrapper)(nil)
type routeContextHandlerWrapper struct {
router ConnectionRouterEx
}
func (r *routeContextHandlerWrapper) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
_, metadata := ExtendContext(ctx)
if source.IsValid() {
metadata.Source = source
}
if destination.IsValid() {
metadata.Destination = destination
}
r.router.RouteConnectionEx(ctx, conn, *metadata, onClose)
}
func (r *routeContextHandlerWrapper) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
_, metadata := ExtendContext(ctx)
if source.IsValid() {
metadata.Source = source
}
if destination.IsValid() {
metadata.Destination = destination
}
r.router.RoutePacketConnectionEx(ctx, conn, *metadata, onClose)
}
================================================
FILE: adapter/upstream_legacy.go
================================================
package adapter
import (
"context"
"net"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/logger"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
)
type (
// Deprecated
LegacyConnectionHandlerFunc = func(ctx context.Context, conn net.Conn, metadata InboundContext) error
// Deprecated
LegacyPacketConnectionHandlerFunc = func(ctx context.Context, conn N.PacketConn, metadata InboundContext) error
)
// Deprecated
//
//nolint:staticcheck
type LegacyUpstreamHandlerAdapter interface {
N.TCPConnectionHandler
N.UDPConnectionHandler
E.Handler
}
// Deprecated
//
//nolint:staticcheck
func NewLegacyUpstreamHandler(
metadata InboundContext,
connectionHandler LegacyConnectionHandlerFunc,
packetHandler LegacyPacketConnectionHandlerFunc,
errorHandler E.Handler,
) LegacyUpstreamHandlerAdapter {
return &legacyUpstreamHandlerWrapper{
metadata: metadata,
connectionHandler: connectionHandler,
packetHandler: packetHandler,
errorHandler: errorHandler,
}
}
var _ LegacyUpstreamHandlerAdapter = (*legacyUpstreamHandlerWrapper)(nil)
// Deprecated: use NewUpstreamHandler instead.
//
//nolint:staticcheck
type legacyUpstreamHandlerWrapper struct {
metadata InboundContext
connectionHandler LegacyConnectionHandlerFunc
packetHandler LegacyPacketConnectionHandlerFunc
errorHandler E.Handler
}
// Deprecated: use NewUpstreamHandler instead.
func (w *legacyUpstreamHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
myMetadata := w.metadata
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.connectionHandler(ctx, conn, myMetadata)
}
// Deprecated: use NewUpstreamHandler instead.
func (w *legacyUpstreamHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
myMetadata := w.metadata
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.packetHandler(ctx, conn, myMetadata)
}
// Deprecated: use NewUpstreamHandler instead.
func (w *legacyUpstreamHandlerWrapper) NewError(ctx context.Context, err error) {
w.errorHandler.NewError(ctx, err)
}
// Deprecated: removed
func UpstreamMetadata(metadata InboundContext) M.Metadata {
return M.Metadata{
Source: metadata.Source.Unwrap(),
Destination: metadata.Destination.Unwrap(),
}
}
// Deprecated: Use NewUpstreamContextHandler instead.
type legacyUpstreamContextHandlerWrapper struct {
connectionHandler LegacyConnectionHandlerFunc
packetHandler LegacyPacketConnectionHandlerFunc
errorHandler E.Handler
}
// Deprecated: Use NewUpstreamContextHandler instead.
func NewLegacyUpstreamContextHandler(
connectionHandler LegacyConnectionHandlerFunc,
packetHandler LegacyPacketConnectionHandlerFunc,
errorHandler E.Handler,
) LegacyUpstreamHandlerAdapter {
return &legacyUpstreamContextHandlerWrapper{
connectionHandler: connectionHandler,
packetHandler: packetHandler,
errorHandler: errorHandler,
}
}
// Deprecated: Use NewUpstreamContextHandler instead.
func (w *legacyUpstreamContextHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
myMetadata := ContextFrom(ctx)
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.connectionHandler(ctx, conn, *myMetadata)
}
// Deprecated: Use NewUpstreamContextHandler instead.
func (w *legacyUpstreamContextHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
myMetadata := ContextFrom(ctx)
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.packetHandler(ctx, conn, *myMetadata)
}
// Deprecated: Use NewUpstreamContextHandler instead.
func (w *legacyUpstreamContextHandlerWrapper) NewError(ctx context.Context, err error) {
w.errorHandler.NewError(ctx, err)
}
// Deprecated: Use ConnectionRouterEx instead.
func NewLegacyRouteHandler(
metadata InboundContext,
router ConnectionRouter,
logger logger.ContextLogger,
) LegacyUpstreamHandlerAdapter {
return &legacyRouteHandlerWrapper{
metadata: metadata,
router: router,
logger: logger,
}
}
// Deprecated: Use ConnectionRouterEx instead.
func NewLegacyRouteContextHandler(
router ConnectionRouter,
logger logger.ContextLogger,
) LegacyUpstreamHandlerAdapter {
return &legacyRouteContextHandlerWrapper{
router: router,
logger: logger,
}
}
var _ LegacyUpstreamHandlerAdapter = (*legacyRouteHandlerWrapper)(nil)
// Deprecated: Use ConnectionRouterEx instead.
//
//nolint:staticcheck
type legacyRouteHandlerWrapper struct {
metadata InboundContext
router ConnectionRouter
logger logger.ContextLogger
}
// Deprecated: Use ConnectionRouterEx instead.
func (w *legacyRouteHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
myMetadata := w.metadata
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.router.RouteConnection(ctx, conn, myMetadata)
}
// Deprecated: Use ConnectionRouterEx instead.
func (w *legacyRouteHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
myMetadata := w.metadata
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.router.RoutePacketConnection(ctx, conn, myMetadata)
}
// Deprecated: Use ConnectionRouterEx instead.
func (w *legacyRouteHandlerWrapper) NewError(ctx context.Context, err error) {
w.logger.ErrorContext(ctx, err)
}
var _ LegacyUpstreamHandlerAdapter = (*legacyRouteContextHandlerWrapper)(nil)
// Deprecated: Use ConnectionRouterEx instead.
type legacyRouteContextHandlerWrapper struct {
router ConnectionRouter
logger logger.ContextLogger
}
// Deprecated: Use ConnectionRouterEx instead.
func (w *legacyRouteContextHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata
gitextract_yza4ly9v/
├── .fpm_openwrt
├── .fpm_pacman
├── .fpm_systemd
├── .github/
│ ├── CRONET_GO_VERSION
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.yml
│ │ └── bug_report_zh.yml
│ ├── build_alpine_apk.sh
│ ├── build_openwrt_apk.sh
│ ├── deb2ipk.sh
│ ├── detect_track.sh
│ ├── renovate.json
│ ├── setup_go_for_macos1013.sh
│ ├── setup_go_for_windows7.sh
│ ├── update_clients.sh
│ ├── update_cronet.sh
│ ├── update_cronet_dev.sh
│ ├── update_dependencies.sh
│ └── workflows/
│ ├── build.yml
│ ├── docker.yml
│ ├── lint.yml
│ ├── linux.yml
│ ├── stale.yml
│ └── test.yml
├── .gitignore
├── .gitmodules
├── .golangci.yml
├── Dockerfile
├── Dockerfile.binary
├── LICENSE
├── Makefile
├── README.md
├── adapter/
│ ├── certificate/
│ │ ├── adapter.go
│ │ ├── manager.go
│ │ └── registry.go
│ ├── certificate.go
│ ├── certificate_darwin.go
│ ├── certificate_provider.go
│ ├── connections.go
│ ├── dns.go
│ ├── endpoint/
│ │ ├── adapter.go
│ │ ├── manager.go
│ │ └── registry.go
│ ├── endpoint.go
│ ├── experimental.go
│ ├── fakeip.go
│ ├── fakeip_metadata.go
│ ├── handler.go
│ ├── http.go
│ ├── inbound/
│ │ ├── adapter.go
│ │ ├── manager.go
│ │ └── registry.go
│ ├── inbound.go
│ ├── inbound_test.go
│ ├── lifecycle.go
│ ├── lifecycle_legacy.go
│ ├── neighbor.go
│ ├── network.go
│ ├── outbound/
│ │ ├── adapter.go
│ │ ├── manager.go
│ │ └── registry.go
│ ├── outbound.go
│ ├── platform.go
│ ├── prestart.go
│ ├── router.go
│ ├── rule.go
│ ├── service/
│ │ ├── adapter.go
│ │ ├── manager.go
│ │ └── registry.go
│ ├── service.go
│ ├── ssm.go
│ ├── tailscale.go
│ ├── time.go
│ ├── upstream.go
│ ├── upstream_legacy.go
│ └── v2ray.go
├── box.go
├── cmd/
│ ├── internal/
│ │ ├── app_store_connect/
│ │ │ └── main.go
│ │ ├── build/
│ │ │ └── main.go
│ │ ├── build_libbox/
│ │ │ └── main.go
│ │ ├── build_shared/
│ │ │ ├── sdk.go
│ │ │ └── tag.go
│ │ ├── format_docs/
│ │ │ └── main.go
│ │ ├── protogen/
│ │ │ └── main.go
│ │ ├── read_tag/
│ │ │ └── main.go
│ │ ├── tun_bench/
│ │ │ └── main.go
│ │ ├── update_android_version/
│ │ │ └── main.go
│ │ ├── update_apple_version/
│ │ │ └── main.go
│ │ └── update_certificates/
│ │ └── main.go
│ └── sing-box/
│ ├── cmd.go
│ ├── cmd_check.go
│ ├── cmd_format.go
│ ├── cmd_generate.go
│ ├── cmd_generate_ech.go
│ ├── cmd_generate_tls.go
│ ├── cmd_generate_vapid.go
│ ├── cmd_generate_wireguard.go
│ ├── cmd_geoip.go
│ ├── cmd_geoip_export.go
│ ├── cmd_geoip_list.go
│ ├── cmd_geoip_lookup.go
│ ├── cmd_geosite.go
│ ├── cmd_geosite_export.go
│ ├── cmd_geosite_list.go
│ ├── cmd_geosite_lookup.go
│ ├── cmd_geosite_matcher.go
│ ├── cmd_merge.go
│ ├── cmd_rule_set.go
│ ├── cmd_rule_set_compile.go
│ ├── cmd_rule_set_convert.go
│ ├── cmd_rule_set_decompile.go
│ ├── cmd_rule_set_format.go
│ ├── cmd_rule_set_match.go
│ ├── cmd_rule_set_merge.go
│ ├── cmd_rule_set_upgrade.go
│ ├── cmd_run.go
│ ├── cmd_tools.go
│ ├── cmd_tools_connect.go
│ ├── cmd_tools_fetch.go
│ ├── cmd_tools_fetch_http3.go
│ ├── cmd_tools_fetch_http3_stub.go
│ ├── cmd_tools_networkquality.go
│ ├── cmd_tools_stun.go
│ ├── cmd_tools_synctime.go
│ ├── cmd_version.go
│ ├── generate_completions.go
│ └── main.go
├── common/
│ ├── badtls/
│ │ ├── raw_conn.go
│ │ ├── raw_half_conn.go
│ │ ├── read_wait.go
│ │ ├── read_wait_stub.go
│ │ ├── registry.go
│ │ └── registry_utls.go
│ ├── badversion/
│ │ ├── version.go
│ │ ├── version_json.go
│ │ └── version_test.go
│ ├── certificate/
│ │ ├── anchors_darwin.h
│ │ ├── anchors_darwin.m
│ │ ├── chrome.go
│ │ ├── chrome.pem
│ │ ├── mozilla.go
│ │ ├── mozilla.pem
│ │ ├── store.go
│ │ ├── store_darwin.go
│ │ └── store_other.go
│ ├── compatible/
│ │ └── map.go
│ ├── convertor/
│ │ └── adguard/
│ │ ├── convertor.go
│ │ └── convertor_test.go
│ ├── dialer/
│ │ ├── default.go
│ │ ├── default_parallel_interface.go
│ │ ├── default_parallel_network.go
│ │ ├── detour.go
│ │ ├── dialer.go
│ │ ├── resolve.go
│ │ ├── router.go
│ │ ├── tfo.go
│ │ └── wireguard.go
│ ├── geoip/
│ │ └── reader.go
│ ├── geosite/
│ │ ├── compat_test.go
│ │ ├── geosite_test.go
│ │ ├── reader.go
│ │ ├── rule.go
│ │ └── writer.go
│ ├── httpclient/
│ │ ├── apple_transport_darwin.go
│ │ ├── apple_transport_darwin.h
│ │ ├── apple_transport_darwin.m
│ │ ├── apple_transport_darwin_test.go
│ │ ├── apple_transport_stub.go
│ │ ├── client.go
│ │ ├── context.go
│ │ ├── helpers.go
│ │ ├── helpers_test.go
│ │ ├── http1_transport.go
│ │ ├── http2_config.go
│ │ ├── http2_fallback_transport.go
│ │ ├── http2_fallback_transport_test.go
│ │ ├── http2_transport.go
│ │ ├── http3_transport.go
│ │ ├── http3_transport_stub.go
│ │ ├── http3_transport_test.go
│ │ ├── managed_transport.go
│ │ └── manager.go
│ ├── interrupt/
│ │ ├── conn.go
│ │ ├── context.go
│ │ └── group.go
│ ├── ja3/
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── error.go
│ │ ├── ja3.go
│ │ └── parser.go
│ ├── ktls/
│ │ ├── ktls.go
│ │ ├── ktls_alert.go
│ │ ├── ktls_cipher_suites_linux.go
│ │ ├── ktls_close.go
│ │ ├── ktls_const.go
│ │ ├── ktls_handshake_messages.go
│ │ ├── ktls_key_update.go
│ │ ├── ktls_linux.go
│ │ ├── ktls_prf.go
│ │ ├── ktls_read.go
│ │ ├── ktls_read_wait.go
│ │ ├── ktls_stub_nolinkname.go
│ │ ├── ktls_stub_nonlinux.go
│ │ ├── ktls_stub_oldgo.go
│ │ └── ktls_write.go
│ ├── listener/
│ │ ├── listener.go
│ │ ├── listener_tcp.go
│ │ └── listener_udp.go
│ ├── mux/
│ │ ├── client.go
│ │ └── router.go
│ ├── networkquality/
│ │ ├── http.go
│ │ ├── http3.go
│ │ ├── http3_stub.go
│ │ └── networkquality.go
│ ├── pipelistener/
│ │ └── listener.go
│ ├── process/
│ │ ├── searcher.go
│ │ ├── searcher_android.go
│ │ ├── searcher_darwin.go
│ │ ├── searcher_darwin_shared.go
│ │ ├── searcher_linux.go
│ │ ├── searcher_linux_shared.go
│ │ ├── searcher_linux_shared_test.go
│ │ ├── searcher_stub.go
│ │ └── searcher_windows.go
│ ├── proxybridge/
│ │ └── bridge.go
│ ├── redir/
│ │ ├── redir_darwin.go
│ │ ├── redir_linux.go
│ │ ├── redir_other.go
│ │ ├── tproxy_linux.go
│ │ └── tproxy_other.go
│ ├── schannel/
│ │ ├── doc.go
│ │ ├── schannel_windows.go
│ │ ├── schannel_windows_test.go
│ │ ├── syscall_windows.go
│ │ ├── types_windows.go
│ │ └── zsyscall_windows.go
│ ├── settings/
│ │ ├── proxy_android.go
│ │ ├── proxy_darwin.go
│ │ ├── proxy_linux.go
│ │ ├── proxy_stub.go
│ │ ├── proxy_windows.go
│ │ ├── system_proxy.go
│ │ ├── wifi.go
│ │ ├── wifi_linux.go
│ │ ├── wifi_linux_connman.go
│ │ ├── wifi_linux_iwd.go
│ │ ├── wifi_linux_nm.go
│ │ ├── wifi_linux_wpa.go
│ │ ├── wifi_stub.go
│ │ └── wifi_windows.go
│ ├── sniff/
│ │ ├── bittorrent.go
│ │ ├── bittorrent_test.go
│ │ ├── dns.go
│ │ ├── dns_test.go
│ │ ├── dtls.go
│ │ ├── dtls_test.go
│ │ ├── http.go
│ │ ├── http_test.go
│ │ ├── internal/
│ │ │ └── qtls/
│ │ │ └── qtls.go
│ │ ├── ntp.go
│ │ ├── ntp_test.go
│ │ ├── quic.go
│ │ ├── quic_blacklist.go
│ │ ├── quic_capture_test.go
│ │ ├── quic_test.go
│ │ ├── rdp.go
│ │ ├── rdp_test.go
│ │ ├── sniff.go
│ │ ├── ssh.go
│ │ ├── ssh_test.go
│ │ ├── stun.go
│ │ ├── stun_test.go
│ │ └── tls.go
│ ├── srs/
│ │ ├── binary.go
│ │ ├── compat_test.go
│ │ ├── ip_cidr.go
│ │ └── ip_set.go
│ ├── stun/
│ │ └── stun.go
│ ├── taskmonitor/
│ │ └── monitor.go
│ ├── tls/
│ │ ├── acme.go
│ │ ├── acme_logger.go
│ │ ├── acme_stub.go
│ │ ├── apple_client.go
│ │ ├── apple_client_platform.go
│ │ ├── apple_client_platform_benchmark_test.go
│ │ ├── apple_client_platform_darwin.h
│ │ ├── apple_client_platform_darwin.m
│ │ ├── apple_client_platform_dispatch_test.go
│ │ ├── apple_client_platform_dispatch_testhelper_darwin.go
│ │ ├── apple_client_platform_test.go
│ │ ├── apple_client_stub.go
│ │ ├── client.go
│ │ ├── common.go
│ │ ├── config.go
│ │ ├── ech.go
│ │ ├── ech_shared.go
│ │ ├── ech_tag_stub.go
│ │ ├── ktls.go
│ │ ├── mkcert.go
│ │ ├── reality_client.go
│ │ ├── reality_server.go
│ │ ├── reality_stub.go
│ │ ├── server.go
│ │ ├── std_client.go
│ │ ├── std_server.go
│ │ ├── system_client.go
│ │ ├── system_client_engine.go
│ │ ├── time_wrapper.go
│ │ ├── utls_client.go
│ │ ├── utls_client_test.go
│ │ ├── utls_stub.go
│ │ ├── windows_client.go
│ │ ├── windows_client_stub.go
│ │ └── windows_client_test.go
│ ├── tlsfragment/
│ │ ├── conn.go
│ │ ├── conn_test.go
│ │ ├── index.go
│ │ ├── index_test.go
│ │ ├── wait_darwin.go
│ │ ├── wait_linux.go
│ │ ├── wait_stub.go
│ │ └── wait_windows.go
│ ├── tlsspoof/
│ │ ├── README.md
│ │ ├── client_hello.go
│ │ ├── endpoints.go
│ │ ├── integration_darwin_test.go
│ │ ├── integration_linux_test.go
│ │ ├── integration_test.go
│ │ ├── integration_tls_test.go
│ │ ├── integration_unix_test.go
│ │ ├── integration_windows_test.go
│ │ ├── packet.go
│ │ ├── packet_darwin.go
│ │ ├── raw_darwin.go
│ │ ├── raw_linux.go
│ │ ├── raw_stub.go
│ │ ├── raw_unix.go
│ │ ├── raw_windows.go
│ │ ├── spoof.go
│ │ └── testdata_test.go
│ ├── uot/
│ │ └── router.go
│ ├── urltest/
│ │ └── urltest.go
│ └── windivert/
│ ├── address_test.go
│ ├── assets/
│ │ ├── LICENSE.txt
│ │ ├── WinDivert32.sys
│ │ └── WinDivert64.sys
│ ├── assets_386.go
│ ├── assets_amd64.go
│ ├── assets_unsupported.go
│ ├── driver_windows.go
│ ├── filter.go
│ ├── filter_test.go
│ ├── handle_windows.go
│ ├── handle_windows_test.go
│ ├── integration_windows_test.go
│ └── windivert.go
├── constant/
│ ├── certificate.go
│ ├── cgo.go
│ ├── cgo_disabled.go
│ ├── dhcp.go
│ ├── dns.go
│ ├── err.go
│ ├── goos/
│ │ ├── gengoos.go
│ │ ├── goos.go
│ │ ├── zgoos_aix.go
│ │ ├── zgoos_android.go
│ │ ├── zgoos_darwin.go
│ │ ├── zgoos_dragonfly.go
│ │ ├── zgoos_freebsd.go
│ │ ├── zgoos_hurd.go
│ │ ├── zgoos_illumos.go
│ │ ├── zgoos_ios.go
│ │ ├── zgoos_js.go
│ │ ├── zgoos_linux.go
│ │ ├── zgoos_netbsd.go
│ │ ├── zgoos_openbsd.go
│ │ ├── zgoos_plan9.go
│ │ ├── zgoos_solaris.go
│ │ ├── zgoos_windows.go
│ │ └── zgoos_zos.go
│ ├── hysteria2.go
│ ├── network.go
│ ├── os.go
│ ├── path.go
│ ├── path_unix.go
│ ├── protocol.go
│ ├── proxy.go
│ ├── quic.go
│ ├── quic_stub.go
│ ├── rule.go
│ ├── speed.go
│ ├── time.go
│ ├── timeout.go
│ ├── tls.go
│ ├── v2ray.go
│ └── version.go
├── daemon/
│ ├── deprecated.go
│ ├── instance.go
│ ├── platform.go
│ ├── started_service.go
│ ├── started_service.pb.go
│ ├── started_service.proto
│ └── started_service_grpc.pb.go
├── debug.go
├── debug_http.go
├── debug_stub.go
├── debug_unix.go
├── dns/
│ ├── client.go
│ ├── client_log.go
│ ├── client_truncate.go
│ ├── extension_edns0_subnet.go
│ ├── rcode.go
│ ├── repro_test.go
│ ├── router.go
│ ├── router_test.go
│ ├── transport/
│ │ ├── conn_pool.go
│ │ ├── dhcp/
│ │ │ ├── dhcp.go
│ │ │ └── dhcp_shared.go
│ │ ├── fakeip/
│ │ │ ├── fakeip.go
│ │ │ ├── memory.go
│ │ │ └── store.go
│ │ ├── hosts/
│ │ │ ├── hosts.go
│ │ │ ├── hosts_file.go
│ │ │ ├── hosts_test.go
│ │ │ ├── hosts_unix.go
│ │ │ ├── hosts_windows.go
│ │ │ └── testdata/
│ │ │ └── hosts
│ │ ├── https.go
│ │ ├── https_transport.go
│ │ ├── local/
│ │ │ ├── local.go
│ │ │ ├── local_darwin_cgo.go
│ │ │ ├── local_darwin_stun.go
│ │ │ ├── local_dhcp.go
│ │ │ ├── local_neighbor.go
│ │ │ ├── local_nodhcp.go
│ │ │ ├── local_other.go
│ │ │ ├── local_resolved.go
│ │ │ ├── local_resolved_linux.go
│ │ │ ├── local_resolved_stub.go
│ │ │ ├── local_shared.go
│ │ │ ├── resolv.go
│ │ │ ├── resolv_default.go
│ │ │ ├── resolv_test.go
│ │ │ ├── resolv_unix.go
│ │ │ └── resolv_windows.go
│ │ ├── mdns/
│ │ │ └── mdns.go
│ │ ├── quic/
│ │ │ ├── http3.go
│ │ │ └── quic.go
│ │ ├── tcp.go
│ │ ├── tls.go
│ │ └── udp.go
│ ├── transport_adapter.go
│ ├── transport_dialer.go
│ ├── transport_manager.go
│ └── transport_registry.go
├── docs/
│ ├── CNAME
│ ├── changelog.md
│ ├── clients/
│ │ ├── android/
│ │ │ ├── features.md
│ │ │ └── index.md
│ │ ├── apple/
│ │ │ ├── features.md
│ │ │ └── index.md
│ │ ├── general.md
│ │ ├── index.md
│ │ ├── index.zh.md
│ │ └── privacy.md
│ ├── configuration/
│ │ ├── certificate/
│ │ │ ├── index.md
│ │ │ └── index.zh.md
│ │ ├── dns/
│ │ │ ├── fakeip.md
│ │ │ ├── fakeip.zh.md
│ │ │ ├── index.md
│ │ │ ├── index.zh.md
│ │ │ ├── rule.md
│ │ │ ├── rule.zh.md
│ │ │ ├── rule_action.md
│ │ │ ├── rule_action.zh.md
│ │ │ └── server/
│ │ │ ├── dhcp.md
│ │ │ ├── dhcp.zh.md
│ │ │ ├── fakeip.md
│ │ │ ├── fakeip.zh.md
│ │ │ ├── hosts.md
│ │ │ ├── hosts.zh.md
│ │ │ ├── http3.md
│ │ │ ├── http3.zh.md
│ │ │ ├── https.md
│ │ │ ├── https.zh.md
│ │ │ ├── index.md
│ │ │ ├── index.zh.md
│ │ │ ├── legacy.md
│ │ │ ├── legacy.zh.md
│ │ │ ├── local.md
│ │ │ ├── local.zh.md
│ │ │ ├── mdns.md
│ │ │ ├── mdns.zh.md
│ │ │ ├── quic.md
│ │ │ ├── quic.zh.md
│ │ │ ├── resolved.md
│ │ │ ├── resolved.zh.md
│ │ │ ├── tailscale.md
│ │ │ ├── tailscale.zh.md
│ │ │ ├── tcp.md
│ │ │ ├── tcp.zh.md
│ │ │ ├── tls.md
│ │ │ ├── tls.zh.md
│ │ │ ├── udp.md
│ │ │ └── udp.zh.md
│ │ ├── endpoint/
│ │ │ ├── index.md
│ │ │ ├── index.zh.md
│ │ │ ├── tailscale.md
│ │ │ ├── tailscale.zh.md
│ │ │ ├── wireguard.md
│ │ │ └── wireguard.zh.md
│ │ ├── experimental/
│ │ │ ├── cache-file.md
│ │ │ ├── cache-file.zh.md
│ │ │ ├── clash-api.md
│ │ │ ├── clash-api.zh.md
│ │ │ ├── index.md
│ │ │ ├── index.zh.md
│ │ │ ├── v2ray-api.md
│ │ │ └── v2ray-api.zh.md
│ │ ├── inbound/
│ │ │ ├── anytls.md
│ │ │ ├── anytls.zh.md
│ │ │ ├── cloudflared.md
│ │ │ ├── cloudflared.zh.md
│ │ │ ├── direct.md
│ │ │ ├── direct.zh.md
│ │ │ ├── http.md
│ │ │ ├── http.zh.md
│ │ │ ├── hysteria.md
│ │ │ ├── hysteria.zh.md
│ │ │ ├── hysteria2.md
│ │ │ ├── hysteria2.zh.md
│ │ │ ├── index.md
│ │ │ ├── index.zh.md
│ │ │ ├── mixed.md
│ │ │ ├── mixed.zh.md
│ │ │ ├── naive.md
│ │ │ ├── naive.zh.md
│ │ │ ├── redirect.md
│ │ │ ├── redirect.zh.md
│ │ │ ├── shadowsocks.md
│ │ │ ├── shadowsocks.zh.md
│ │ │ ├── shadowtls.md
│ │ │ ├── shadowtls.zh.md
│ │ │ ├── socks.md
│ │ │ ├── socks.zh.md
│ │ │ ├── tproxy.md
│ │ │ ├── tproxy.zh.md
│ │ │ ├── trojan.md
│ │ │ ├── trojan.zh.md
│ │ │ ├── tuic.md
│ │ │ ├── tuic.zh.md
│ │ │ ├── tun.md
│ │ │ ├── tun.zh.md
│ │ │ ├── vless.md
│ │ │ ├── vless.zh.md
│ │ │ ├── vmess.md
│ │ │ └── vmess.zh.md
│ │ ├── index.md
│ │ ├── index.zh.md
│ │ ├── log/
│ │ │ ├── index.md
│ │ │ └── index.zh.md
│ │ ├── ntp/
│ │ │ ├── index.md
│ │ │ └── index.zh.md
│ │ ├── outbound/
│ │ │ ├── anytls.md
│ │ │ ├── anytls.zh.md
│ │ │ ├── block.md
│ │ │ ├── block.zh.md
│ │ │ ├── direct.md
│ │ │ ├── direct.zh.md
│ │ │ ├── dns.md
│ │ │ ├── dns.zh.md
│ │ │ ├── http.md
│ │ │ ├── http.zh.md
│ │ │ ├── hysteria.md
│ │ │ ├── hysteria.zh.md
│ │ │ ├── hysteria2.md
│ │ │ ├── hysteria2.zh.md
│ │ │ ├── index.md
│ │ │ ├── index.zh.md
│ │ │ ├── naive.md
│ │ │ ├── naive.zh.md
│ │ │ ├── selector.md
│ │ │ ├── selector.zh.md
│ │ │ ├── shadowsocks.md
│ │ │ ├── shadowsocks.zh.md
│ │ │ ├── shadowtls.md
│ │ │ ├── shadowtls.zh.md
│ │ │ ├── socks.md
│ │ │ ├── socks.zh.md
│ │ │ ├── ssh.md
│ │ │ ├── ssh.zh.md
│ │ │ ├── tor.md
│ │ │ ├── tor.zh.md
│ │ │ ├── trojan.md
│ │ │ ├── trojan.zh.md
│ │ │ ├── tuic.md
│ │ │ ├── tuic.zh.md
│ │ │ ├── urltest.md
│ │ │ ├── urltest.zh.md
│ │ │ ├── vless.md
│ │ │ ├── vless.zh.md
│ │ │ ├── vmess.md
│ │ │ ├── vmess.zh.md
│ │ │ ├── wireguard.md
│ │ │ └── wireguard.zh.md
│ │ ├── route/
│ │ │ ├── geoip.md
│ │ │ ├── geoip.zh.md
│ │ │ ├── geosite.md
│ │ │ ├── geosite.zh.md
│ │ │ ├── index.md
│ │ │ ├── index.zh.md
│ │ │ ├── rule.md
│ │ │ ├── rule.zh.md
│ │ │ ├── rule_action.md
│ │ │ ├── rule_action.zh.md
│ │ │ ├── sniff.md
│ │ │ └── sniff.zh.md
│ │ ├── rule-set/
│ │ │ ├── adguard.md
│ │ │ ├── adguard.zh.md
│ │ │ ├── headless-rule.md
│ │ │ ├── headless-rule.zh.md
│ │ │ ├── index.md
│ │ │ ├── index.zh.md
│ │ │ ├── source-format.md
│ │ │ └── source-format.zh.md
│ │ ├── service/
│ │ │ ├── ccm.md
│ │ │ ├── ccm.zh.md
│ │ │ ├── derp.md
│ │ │ ├── derp.zh.md
│ │ │ ├── hysteria-realm.md
│ │ │ ├── hysteria-realm.zh.md
│ │ │ ├── index.md
│ │ │ ├── index.zh.md
│ │ │ ├── ocm.md
│ │ │ ├── ocm.zh.md
│ │ │ ├── resolved.md
│ │ │ ├── resolved.zh.md
│ │ │ ├── ssm-api.md
│ │ │ └── ssm-api.zh.md
│ │ └── shared/
│ │ ├── certificate-provider/
│ │ │ ├── acme.md
│ │ │ ├── acme.zh.md
│ │ │ ├── cloudflare-origin-ca.md
│ │ │ ├── cloudflare-origin-ca.zh.md
│ │ │ ├── index.md
│ │ │ ├── index.zh.md
│ │ │ ├── tailscale.md
│ │ │ └── tailscale.zh.md
│ │ ├── dial.md
│ │ ├── dial.zh.md
│ │ ├── dns01_challenge.md
│ │ ├── dns01_challenge.zh.md
│ │ ├── http-client.md
│ │ ├── http-client.zh.md
│ │ ├── http2.md
│ │ ├── http2.zh.md
│ │ ├── listen.md
│ │ ├── listen.zh.md
│ │ ├── multiplex.md
│ │ ├── multiplex.zh.md
│ │ ├── neighbor.md
│ │ ├── neighbor.zh.md
│ │ ├── pre-match.md
│ │ ├── pre-match.zh.md
│ │ ├── quic.md
│ │ ├── quic.zh.md
│ │ ├── tcp-brutal.md
│ │ ├── tcp-brutal.zh.md
│ │ ├── tls.md
│ │ ├── tls.zh.md
│ │ ├── udp-over-tcp.md
│ │ ├── udp-over-tcp.zh.md
│ │ ├── v2ray-transport.md
│ │ ├── v2ray-transport.zh.md
│ │ ├── wifi-state.md
│ │ └── wifi-state.zh.md
│ ├── deprecated.md
│ ├── deprecated.zh.md
│ ├── index.md
│ ├── index.zh.md
│ ├── installation/
│ │ ├── build-from-source.md
│ │ ├── build-from-source.zh.md
│ │ ├── docker.md
│ │ ├── docker.zh.md
│ │ ├── package-manager.md
│ │ ├── package-manager.zh.md
│ │ └── tools/
│ │ ├── arch-install.sh
│ │ ├── deb-install.sh
│ │ ├── install.sh
│ │ ├── rpm-install.sh
│ │ └── sing-box.repo
│ ├── manual/
│ │ ├── misc/
│ │ │ └── tunnelvision.md
│ │ ├── proxy/
│ │ │ ├── client.md
│ │ │ └── server.md
│ │ └── proxy-protocol/
│ │ ├── hysteria2.md
│ │ ├── shadowsocks.md
│ │ └── trojan.md
│ ├── migration.md
│ ├── migration.zh.md
│ ├── sponsors.md
│ ├── support.md
│ └── support.zh.md
├── experimental/
│ ├── cachefile/
│ │ ├── cache.go
│ │ ├── dns_cache.go
│ │ ├── fakeip.go
│ │ └── rdrc.go
│ ├── clashapi/
│ │ ├── api_meta.go
│ │ ├── api_meta_group.go
│ │ ├── api_meta_upgrade.go
│ │ ├── cache.go
│ │ ├── common.go
│ │ ├── configs.go
│ │ ├── connections.go
│ │ ├── ctxkeys.go
│ │ ├── dns.go
│ │ ├── errors.go
│ │ ├── profile.go
│ │ ├── provider.go
│ │ ├── proxies.go
│ │ ├── ruleprovider.go
│ │ ├── rules.go
│ │ ├── script.go
│ │ ├── server.go
│ │ ├── server_fs.go
│ │ ├── server_resources.go
│ │ └── trafficontrol/
│ │ ├── manager.go
│ │ └── tracker.go
│ ├── clashapi.go
│ ├── deprecated/
│ │ ├── constants.go
│ │ ├── manager.go
│ │ └── stderr.go
│ ├── libbox/
│ │ ├── build_info.go
│ │ ├── command.go
│ │ ├── command_client.go
│ │ ├── command_server.go
│ │ ├── command_types.go
│ │ ├── command_types_nq.go
│ │ ├── command_types_stun.go
│ │ ├── command_types_tailscale.go
│ │ ├── command_types_tailscale_ping.go
│ │ ├── config.go
│ │ ├── connection_owner_darwin.go
│ │ ├── debug.go
│ │ ├── deprecated.go
│ │ ├── dns.go
│ │ ├── fdroid.go
│ │ ├── fdroid_mirrors.go
│ │ ├── ffi.json
│ │ ├── http.go
│ │ ├── internal/
│ │ │ ├── oomprofile/
│ │ │ │ ├── builder.go
│ │ │ │ ├── defs_darwin_amd64.go
│ │ │ │ ├── defs_darwin_arm64.go
│ │ │ │ ├── linkname.go
│ │ │ │ ├── mapping_darwin.go
│ │ │ │ ├── mapping_linux.go
│ │ │ │ ├── mapping_windows.go
│ │ │ │ ├── oomprofile.go
│ │ │ │ └── protobuf.go
│ │ │ └── procfs/
│ │ │ └── procfs.go
│ │ ├── iterator.go
│ │ ├── link_flags_stub.go
│ │ ├── link_flags_unix.go
│ │ ├── log.go
│ │ ├── monitor.go
│ │ ├── neighbor.go
│ │ ├── neighbor_darwin.go
│ │ ├── neighbor_linux.go
│ │ ├── neighbor_stub.go
│ │ ├── neighbor_unix.go
│ │ ├── networkquality.go
│ │ ├── oom_report.go
│ │ ├── panic.go
│ │ ├── pidfd_android.go
│ │ ├── platform.go
│ │ ├── pprof.go
│ │ ├── profile_import.go
│ │ ├── remote_profile.go
│ │ ├── report.go
│ │ ├── semver.go
│ │ ├── semver_test.go
│ │ ├── service.go
│ │ ├── service_other.go
│ │ ├── service_windows.go
│ │ ├── setup.go
│ │ ├── signal_handler_darwin.go
│ │ ├── signal_handler_stub.go
│ │ ├── stun.go
│ │ ├── tun.go
│ │ ├── tun_darwin.go
│ │ ├── tun_name_darwin.go
│ │ ├── tun_name_linux.go
│ │ └── tun_name_other.go
│ ├── locale/
│ │ ├── locale.go
│ │ └── locale_zh_CN.go
│ ├── v2rayapi/
│ │ ├── server.go
│ │ ├── stats.go
│ │ ├── stats.pb.go
│ │ ├── stats.proto
│ │ └── stats_grpc.pb.go
│ └── v2rayapi.go
├── go.mod
├── go.sum
├── include/
│ ├── acme.go
│ ├── acme_stub.go
│ ├── ccm.go
│ ├── ccm_stub.go
│ ├── ccm_stub_darwin.go
│ ├── clashapi.go
│ ├── clashapi_stub.go
│ ├── cloudflared.go
│ ├── cloudflared_stub.go
│ ├── dhcp.go
│ ├── dhcp_stub.go
│ ├── naive_outbound.go
│ ├── naive_outbound_stub.go
│ ├── ocm.go
│ ├── ocm_stub.go
│ ├── oom_killer.go
│ ├── quic.go
│ ├── quic_stub.go
│ ├── registry.go
│ ├── tailscale.go
│ ├── tailscale_stub.go
│ ├── tz_android.go
│ ├── tz_ios.go
│ ├── v2rayapi.go
│ ├── v2rayapi_stub.go
│ ├── wireguard.go
│ └── wireguard_stub.go
├── log/
│ ├── export.go
│ ├── factory.go
│ ├── format.go
│ ├── id.go
│ ├── level.go
│ ├── log.go
│ ├── nop.go
│ ├── observable.go
│ ├── override.go
│ └── platform.go
├── mkdocs.yml
├── option/
│ ├── acme.go
│ ├── anytls.go
│ ├── ccm.go
│ ├── certificate.go
│ ├── certificate_provider.go
│ ├── cloudflared.go
│ ├── debug.go
│ ├── direct.go
│ ├── dns.go
│ ├── dns_record.go
│ ├── dns_record_test.go
│ ├── dns_test.go
│ ├── endpoint.go
│ ├── experimental.go
│ ├── group.go
│ ├── http.go
│ ├── hysteria.go
│ ├── hysteria2.go
│ ├── inbound.go
│ ├── multiplex.go
│ ├── naive.go
│ ├── ntp.go
│ ├── ocm.go
│ ├── oom_killer.go
│ ├── options.go
│ ├── origin_ca.go
│ ├── outbound.go
│ ├── platform.go
│ ├── redir.go
│ ├── resolved.go
│ ├── route.go
│ ├── rule.go
│ ├── rule_action.go
│ ├── rule_action_test.go
│ ├── rule_dns.go
│ ├── rule_nested.go
│ ├── rule_nested_test.go
│ ├── rule_set.go
│ ├── service.go
│ ├── shadowsocks.go
│ ├── shadowsocksr.go
│ ├── shadowtls.go
│ ├── simple.go
│ ├── ssh.go
│ ├── ssmapi.go
│ ├── tailscale.go
│ ├── tls.go
│ ├── tls_acme.go
│ ├── tor.go
│ ├── trojan.go
│ ├── tuic.go
│ ├── tun.go
│ ├── tun_platform.go
│ ├── types.go
│ ├── udp_over_tcp.go
│ ├── v2ray.go
│ ├── v2ray_transport.go
│ ├── vless.go
│ ├── vmess.go
│ └── wireguard.go
├── protocol/
│ ├── anytls/
│ │ ├── inbound.go
│ │ └── outbound.go
│ ├── block/
│ │ └── outbound.go
│ ├── cloudflare/
│ │ └── inbound.go
│ ├── direct/
│ │ ├── inbound.go
│ │ └── outbound.go
│ ├── dns/
│ │ ├── handle.go
│ │ └── outbound.go
│ ├── group/
│ │ ├── selector.go
│ │ └── urltest.go
│ ├── http/
│ │ ├── inbound.go
│ │ └── outbound.go
│ ├── hysteria/
│ │ ├── inbound.go
│ │ ├── outbound.go
│ │ └── quic.go
│ ├── hysteria2/
│ │ ├── inbound.go
│ │ ├── outbound.go
│ │ ├── realm.go
│ │ └── realm_server.go
│ ├── mixed/
│ │ └── inbound.go
│ ├── naive/
│ │ ├── inbound.go
│ │ ├── inbound_conn.go
│ │ ├── outbound.go
│ │ └── quic/
│ │ └── inbound_init.go
│ ├── redirect/
│ │ ├── redirect.go
│ │ └── tproxy.go
│ ├── shadowsocks/
│ │ ├── inbound.go
│ │ ├── inbound_multi.go
│ │ ├── inbound_relay.go
│ │ └── outbound.go
│ ├── shadowtls/
│ │ ├── inbound.go
│ │ └── outbound.go
│ ├── socks/
│ │ ├── inbound.go
│ │ └── outbound.go
│ ├── ssh/
│ │ └── outbound.go
│ ├── tailscale/
│ │ ├── certificate_provider.go
│ │ ├── dns_transport.go
│ │ ├── endpoint.go
│ │ ├── hostinfo_tvos.go
│ │ ├── ping.go
│ │ ├── status.go
│ │ ├── tun_device_unix.go
│ │ └── tun_device_windows.go
│ ├── tor/
│ │ └── outbound.go
│ ├── trojan/
│ │ ├── inbound.go
│ │ └── outbound.go
│ ├── tuic/
│ │ ├── inbound.go
│ │ └── outbound.go
│ ├── tun/
│ │ └── inbound.go
│ ├── vless/
│ │ ├── inbound.go
│ │ └── outbound.go
│ ├── vmess/
│ │ ├── inbound.go
│ │ └── outbound.go
│ └── wireguard/
│ └── endpoint.go
├── release/
│ ├── DEFAULT_BUILD_TAGS
│ ├── DEFAULT_BUILD_TAGS_OTHERS
│ ├── DEFAULT_BUILD_TAGS_WINDOWS
│ ├── LDFLAGS
│ ├── completions/
│ │ ├── sing-box.bash
│ │ ├── sing-box.fish
│ │ └── sing-box.zsh
│ ├── config/
│ │ ├── config.json
│ │ ├── openwrt.conf
│ │ ├── openwrt.init
│ │ ├── openwrt.keep
│ │ ├── openwrt.prerm
│ │ ├── sing-box-split-dns.xml
│ │ ├── sing-box.confd
│ │ ├── sing-box.initd
│ │ ├── sing-box.postinst
│ │ ├── sing-box.rules
│ │ ├── sing-box.service
│ │ ├── sing-box.sysusers
│ │ └── sing-box@.service
│ └── local/
│ ├── common.sh
│ ├── debug.sh
│ ├── enable.sh
│ ├── install.sh
│ ├── install_go.sh
│ ├── reinstall.sh
│ ├── sing-box.service
│ ├── uninstall.sh
│ └── update.sh
├── route/
│ ├── conn.go
│ ├── dns.go
│ ├── neighbor_resolver_darwin.go
│ ├── neighbor_resolver_hostname.go
│ ├── neighbor_resolver_lease.go
│ ├── neighbor_resolver_linux.go
│ ├── neighbor_resolver_parse.go
│ ├── neighbor_resolver_platform.go
│ ├── neighbor_resolver_stub.go
│ ├── neighbor_table_darwin.go
│ ├── neighbor_table_linux.go
│ ├── network.go
│ ├── platform_searcher.go
│ ├── process_cache.go
│ ├── route.go
│ ├── router.go
│ ├── rule/
│ │ ├── match_state.go
│ │ ├── rule_abstract.go
│ │ ├── rule_abstract_test.go
│ │ ├── rule_action.go
│ │ ├── rule_default.go
│ │ ├── rule_default_interface_address.go
│ │ ├── rule_dns.go
│ │ ├── rule_headless.go
│ │ ├── rule_interface_address.go
│ │ ├── rule_item_adguard.go
│ │ ├── rule_item_auth_user.go
│ │ ├── rule_item_cidr.go
│ │ ├── rule_item_clash_mode.go
│ │ ├── rule_item_client.go
│ │ ├── rule_item_domain.go
│ │ ├── rule_item_domain_keyword.go
│ │ ├── rule_item_domain_regex.go
│ │ ├── rule_item_inbound.go
│ │ ├── rule_item_ip_accept_any.go
│ │ ├── rule_item_ip_is_private.go
│ │ ├── rule_item_ipversion.go
│ │ ├── rule_item_network.go
│ │ ├── rule_item_network_is_constrained.go
│ │ ├── rule_item_network_is_expensive.go
│ │ ├── rule_item_network_type.go
│ │ ├── rule_item_outbound.go
│ │ ├── rule_item_package_name.go
│ │ ├── rule_item_package_name_regex.go
│ │ ├── rule_item_port.go
│ │ ├── rule_item_port_range.go
│ │ ├── rule_item_preferred_by.go
│ │ ├── rule_item_preferred_by_dns.go
│ │ ├── rule_item_process_name.go
│ │ ├── rule_item_process_path.go
│ │ ├── rule_item_process_path_regex.go
│ │ ├── rule_item_protocol.go
│ │ ├── rule_item_query_type.go
│ │ ├── rule_item_response_rcode.go
│ │ ├── rule_item_response_record.go
│ │ ├── rule_item_rule_set.go
│ │ ├── rule_item_rule_set_test.go
│ │ ├── rule_item_source_hostname.go
│ │ ├── rule_item_source_mac_address.go
│ │ ├── rule_item_user.go
│ │ ├── rule_item_user_id.go
│ │ ├── rule_item_wifi_bssid.go
│ │ ├── rule_item_wifi_ssid.go
│ │ ├── rule_nested_action.go
│ │ ├── rule_nested_action_test.go
│ │ ├── rule_network_interface_address.go
│ │ ├── rule_set.go
│ │ ├── rule_set_local.go
│ │ ├── rule_set_remote.go
│ │ ├── rule_set_semantics_test.go
│ │ └── rule_set_update_validation_test.go
│ └── rule_conds.go
├── service/
│ ├── acme/
│ │ ├── service.go
│ │ └── stub.go
│ ├── ccm/
│ │ ├── credential.go
│ │ ├── credential_darwin.go
│ │ ├── credential_other.go
│ │ ├── service.go
│ │ ├── service_usage.go
│ │ └── service_user.go
│ ├── derp/
│ │ └── service.go
│ ├── ocm/
│ │ ├── credential.go
│ │ ├── credential_darwin.go
│ │ ├── credential_other.go
│ │ ├── service.go
│ │ ├── service_usage.go
│ │ ├── service_user.go
│ │ └── service_websocket.go
│ ├── oomkiller/
│ │ ├── badcleanup.go
│ │ ├── badcleanup_stub.go
│ │ ├── policy.go
│ │ ├── service.go
│ │ ├── service_darwin.go
│ │ ├── service_stub.go
│ │ ├── timer.go
│ │ └── timer_darwin.go
│ ├── origin_ca/
│ │ └── service.go
│ ├── resolved/
│ │ ├── resolve1.go
│ │ ├── service.go
│ │ ├── stub.go
│ │ └── transport.go
│ └── ssmapi/
│ ├── api.go
│ ├── cache.go
│ ├── server.go
│ ├── traffic.go
│ └── user.go
├── test/
│ ├── box_test.go
│ ├── brutal_test.go
│ ├── clash_darwin_test.go
│ ├── clash_other_test.go
│ ├── clash_test.go
│ ├── config/
│ │ ├── hysteria-client.json
│ │ ├── hysteria-server.json
│ │ ├── hysteria2-client.yml
│ │ ├── hysteria2-server.yml
│ │ ├── naive-nginx.conf
│ │ ├── naive-quic.json
│ │ ├── naive.json
│ │ ├── nginx.conf
│ │ ├── shadowsocksr.json
│ │ ├── trojan.json
│ │ ├── tuic-client.json
│ │ ├── tuic-server.json
│ │ ├── vless-server.json
│ │ ├── vless-tls-client.json
│ │ ├── vless-tls-server.json
│ │ ├── vmess-client.json
│ │ ├── vmess-grpc-client.json
│ │ ├── vmess-grpc-server.json
│ │ ├── vmess-mux-client.json
│ │ ├── vmess-server.json
│ │ ├── vmess-ws-client.json
│ │ ├── vmess-ws-server.json
│ │ └── wireguard.conf
│ ├── direct_test.go
│ ├── docker_test.go
│ ├── domain_inbound_test.go
│ ├── ech_test.go
│ ├── go.mod
│ ├── go.sum
│ ├── http_test.go
│ ├── hysteria2_test.go
│ ├── hysteria_test.go
│ ├── inbound_detour_test.go
│ ├── ktls_test.go
│ ├── mkcert.go
│ ├── mux_cool_test.go
│ ├── mux_test.go
│ ├── naive_self_test.go
│ ├── naive_test.go
│ ├── reality_test.go
│ ├── shadowsocks_legacy_test.go
│ ├── shadowsocks_test.go
│ ├── shadowtls_test.go
│ ├── socks_test.go
│ ├── ss_plugin_test.go
│ ├── tfo_test.go
│ ├── tls_test.go
│ ├── trojan_test.go
│ ├── tuic_test.go
│ ├── v2ray_api_test.go
│ ├── v2ray_grpc_test.go
│ ├── v2ray_httpupgrade_test.go
│ ├── v2ray_transport_test.go
│ ├── v2ray_ws_test.go
│ ├── vmess_test.go
│ └── wrapper_test.go
└── transport/
├── simple-obfs/
│ ├── README.md
│ ├── http.go
│ └── tls.go
├── sip003/
│ ├── args.go
│ ├── obfs.go
│ ├── plugin.go
│ └── v2ray.go
├── trojan/
│ ├── mux.go
│ ├── protocol.go
│ ├── protocol_wait.go
│ ├── service.go
│ └── service_wait.go
├── v2ray/
│ ├── grpc.go
│ ├── grpc_lite.go
│ ├── quic.go
│ └── transport.go
├── v2raygrpc/
│ ├── client.go
│ ├── conn.go
│ ├── credentials/
│ │ ├── credentials.go
│ │ ├── spiffe.go
│ │ ├── syscallconn.go
│ │ └── util.go
│ ├── custom_name.go
│ ├── server.go
│ ├── stream.pb.go
│ ├── stream.proto
│ ├── stream_grpc.pb.go
│ └── tls_credentials.go
├── v2raygrpclite/
│ ├── client.go
│ ├── conn.go
│ └── server.go
├── v2rayhttp/
│ ├── client.go
│ ├── conn.go
│ ├── force_close.go
│ ├── pool.go
│ └── server.go
├── v2rayhttpupgrade/
│ ├── client.go
│ └── server.go
├── v2rayquic/
│ ├── client.go
│ ├── init.go
│ ├── server.go
│ └── stream.go
├── v2raywebsocket/
│ ├── client.go
│ ├── conn.go
│ ├── server.go
│ └── writer.go
└── wireguard/
├── client_bind.go
├── device.go
├── device_nat.go
├── device_stack.go
├── device_stack_gonet.go
├── device_stack_stub.go
├── device_system.go
├── device_system_stack.go
├── endpoint.go
└── endpoint_options.go
Showing preview only (717K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (7773 symbols across 839 files)
FILE: adapter/certificate.go
type CertificateStore (line 10) | type CertificateStore interface
function RootPoolFromContext (line 16) | func RootPoolFromContext(ctx context.Context) *x509.CertPool {
FILE: adapter/certificate/adapter.go
type Adapter (line 3) | type Adapter struct
method Type (line 15) | func (a *Adapter) Type() string {
method Tag (line 19) | func (a *Adapter) Tag() string {
function NewAdapter (line 8) | func NewAdapter(providerType string, providerTag string) Adapter {
FILE: adapter/certificate/manager.go
type Manager (line 20) | type Manager struct
method Start (line 38) | func (m *Manager) Start(stage adapter.StartStage) error {
method Close (line 60) | func (m *Manager) Close() error {
method CertificateProviders (line 85) | func (m *Manager) CertificateProviders() []adapter.CertificateProvider...
method Get (line 91) | func (m *Manager) Get(tag string) (adapter.CertificateProviderService,...
method Remove (line 98) | func (m *Manager) Remove(tag string) error {
method Create (line 121) | func (m *Manager) Create(ctx context.Context, logger log.ContextLogger...
function NewManager (line 30) | func NewManager(logger log.ContextLogger, registry adapter.CertificatePr...
FILE: adapter/certificate/registry.go
type ConstructorFunc (line 13) | type ConstructorFunc
function Register (line 15) | func Register[Options any](registry *Registry, providerType string, cons...
type optionsConstructorFunc (line 30) | type optionsConstructorFunc
type constructorFunc (line 31) | type constructorFunc
type Registry (line 34) | type Registry struct
method CreateOptions (line 47) | func (m *Registry) CreateOptions(providerType string) (any, bool) {
method Create (line 57) | func (m *Registry) Create(ctx context.Context, logger log.ContextLogge...
method register (line 67) | func (m *Registry) register(providerType string, optionsConstructor op...
function NewRegistry (line 40) | func NewRegistry() *Registry {
FILE: adapter/certificate_darwin.go
type AppleAnchors (line 7) | type AppleAnchors interface
type AppleCertificateStore (line 14) | type AppleCertificateStore interface
FILE: adapter/certificate_provider.go
type CertificateProvider (line 11) | type CertificateProvider interface
type ACMECertificateProvider (line 15) | type ACMECertificateProvider interface
type CertificateProviderService (line 20) | type CertificateProviderService interface
type CertificateProviderRegistry (line 27) | type CertificateProviderRegistry interface
type CertificateProviderManager (line 32) | type CertificateProviderManager interface
FILE: adapter/connections.go
type ConnectionManager (line 10) | type ConnectionManager interface
FILE: adapter/dns.go
type DNSRouter (line 18) | type DNSRouter interface
type DNSClient (line 27) | type DNSClient interface
type DNSQueryOptions (line 34) | type DNSQueryOptions struct
function DNSQueryOptionsFrom (line 45) | func DNSQueryOptionsFrom(ctx context.Context, options *option.DomainReso...
type RDRCStore (line 65) | type RDRCStore interface
type DNSCacheStore (line 71) | type DNSCacheStore interface
type DNSTransport (line 78) | type DNSTransport interface
type DNSTransportWithPreferredDomain (line 89) | type DNSTransportWithPreferredDomain interface
type DNSTransportRegistry (line 94) | type DNSTransportRegistry interface
type DNSTransportManager (line 99) | type DNSTransportManager interface
FILE: adapter/endpoint.go
type Endpoint (line 10) | type Endpoint interface
type EndpointRegistry (line 17) | type EndpointRegistry interface
type EndpointManager (line 22) | type EndpointManager interface
FILE: adapter/endpoint/adapter.go
type Adapter (line 5) | type Adapter struct
method Type (line 29) | func (a *Adapter) Type() string {
method Tag (line 33) | func (a *Adapter) Tag() string {
method Network (line 37) | func (a *Adapter) Network() []string {
method Dependencies (line 41) | func (a *Adapter) Dependencies() []string {
function NewAdapter (line 12) | func NewAdapter(endpointType string, endpointTag string, network []strin...
function NewAdapterWithDialerOptions (line 21) | func NewAdapterWithDialerOptions(endpointType string, endpointTag string...
FILE: adapter/endpoint/manager.go
type Manager (line 18) | type Manager struct
method Start (line 36) | func (m *Manager) Start(stage adapter.StartStage) error {
method Close (line 60) | func (m *Manager) Close() error {
method Endpoints (line 84) | func (m *Manager) Endpoints() []adapter.Endpoint {
method Get (line 90) | func (m *Manager) Get(tag string) (adapter.Endpoint, bool) {
method Remove (line 97) | func (m *Manager) Remove(tag string) error {
method Create (line 120) | func (m *Manager) Create(ctx context.Context, router adapter.Router, l...
function NewManager (line 28) | func NewManager(logger log.ContextLogger, registry adapter.EndpointRegis...
FILE: adapter/endpoint/registry.go
type ConstructorFunc (line 13) | type ConstructorFunc
function Register (line 15) | func Register[Options any](registry *Registry, outboundType string, cons...
type optionsConstructorFunc (line 30) | type optionsConstructorFunc
type constructorFunc (line 31) | type constructorFunc
type Registry (line 34) | type Registry struct
method CreateOptions (line 47) | func (m *Registry) CreateOptions(outboundType string) (any, bool) {
method Create (line 57) | func (m *Registry) Create(ctx context.Context, router adapter.Router, ...
method register (line 67) | func (m *Registry) register(outboundType string, optionsConstructor op...
function NewRegistry (line 40) | func NewRegistry() *Registry {
FILE: adapter/experimental.go
type ClashServer (line 14) | type ClashServer interface
type URLTestHistory (line 23) | type URLTestHistory struct
type URLTestHistoryStorage (line 28) | type URLTestHistoryStorage interface
type V2RayServer (line 36) | type V2RayServer interface
type CacheFile (line 41) | type CacheFile interface
type SavedBinary (line 66) | type SavedBinary struct
method MarshalBinary (line 72) | func (s *SavedBinary) MarshalBinary() ([]byte, error) {
method UnmarshalBinary (line 101) | func (s *SavedBinary) UnmarshalBinary(data []byte) error {
type OutboundGroup (line 136) | type OutboundGroup interface
type URLTestGroup (line 142) | type URLTestGroup interface
function OutboundTag (line 147) | func OutboundTag(detour Outbound) string {
FILE: adapter/fakeip.go
type FakeIPStore (line 9) | type FakeIPStore interface
type FakeIPStorage (line 17) | type FakeIPStorage interface
type FakeIPTransport (line 28) | type FakeIPTransport interface
FILE: adapter/fakeip_metadata.go
type FakeIPMetadata (line 13) | type FakeIPMetadata struct
method MarshalBinary (line 20) | func (m *FakeIPMetadata) MarshalBinary() (data []byte, err error) {
method UnmarshalBinary (line 34) | func (m *FakeIPMetadata) UnmarshalBinary(data []byte) error {
FILE: adapter/handler.go
type ConnectionHandler (line 12) | type ConnectionHandler interface
type PacketHandler (line 16) | type PacketHandler interface
type PacketBatchHandler (line 20) | type PacketBatchHandler interface
type OOBPacketHandler (line 24) | type OOBPacketHandler interface
type PacketConnectionHandler (line 28) | type PacketConnectionHandler interface
type UpstreamHandlerAdapter (line 32) | type UpstreamHandlerAdapter interface
FILE: adapter/http.go
type HTTPTransport (line 12) | type HTTPTransport interface
type HTTPClientManager (line 18) | type HTTPClientManager interface
type HTTPStartContext (line 24) | type HTTPStartContext struct
method Register (line 33) | func (c *HTTPStartContext) Register(transport HTTPTransport) {
method Close (line 39) | func (c *HTTPStartContext) Close() {
function NewHTTPStartContext (line 29) | func NewHTTPStartContext() *HTTPStartContext {
FILE: adapter/inbound.go
type Inbound (line 18) | type Inbound interface
type TCPInjectableInbound (line 24) | type TCPInjectableInbound interface
type UDPInjectableInbound (line 29) | type UDPInjectableInbound interface
type InboundRegistry (line 34) | type InboundRegistry interface
type InboundManager (line 39) | type InboundManager interface
type InboundContext (line 47) | type InboundContext struct
method ResetRuleCache (line 111) | func (c *InboundContext) ResetRuleCache() {
method ResetRuleMatchCache (line 117) | func (c *InboundContext) ResetRuleMatchCache() {
method DNSResponseAddressesForMatch (line 125) | func (c *InboundContext) DNSResponseAddressesForMatch() []netip.Addr {
function DNSResponseAddresses (line 129) | func DNSResponseAddresses(response *dns.Msg) []netip.Addr {
type inboundContextKey (line 170) | type inboundContextKey struct
function WithContext (line 172) | func WithContext(ctx context.Context, inboundContext *InboundContext) co...
function ContextFrom (line 176) | func ContextFrom(ctx context.Context) *InboundContext {
function ExtendContext (line 184) | func ExtendContext(ctx context.Context) (context.Context, *InboundContex...
function OverrideContext (line 192) | func OverrideContext(ctx context.Context) context.Context {
FILE: adapter/inbound/adapter.go
type Adapter (line 3) | type Adapter struct
method Type (line 15) | func (a *Adapter) Type() string {
method Tag (line 19) | func (a *Adapter) Tag() string {
function NewAdapter (line 8) | func NewAdapter(inboundType string, inboundTag string) Adapter {
FILE: adapter/inbound/manager.go
type Manager (line 18) | type Manager struct
method Start (line 38) | func (m *Manager) Start(stage adapter.StartStage) error {
method Close (line 59) | func (m *Manager) Close() error {
method Inbounds (line 83) | func (m *Manager) Inbounds() []adapter.Inbound {
method Get (line 89) | func (m *Manager) Get(tag string) (adapter.Inbound, bool) {
method Remove (line 99) | func (m *Manager) Remove(tag string) error {
method Create (line 122) | func (m *Manager) Create(ctx context.Context, router adapter.Router, l...
function NewManager (line 29) | func NewManager(logger log.ContextLogger, registry adapter.InboundRegist...
FILE: adapter/inbound/registry.go
type ConstructorFunc (line 13) | type ConstructorFunc
function Register (line 15) | func Register[Options any](registry *Registry, outboundType string, cons...
type optionsConstructorFunc (line 30) | type optionsConstructorFunc
type constructorFunc (line 31) | type constructorFunc
type Registry (line 34) | type Registry struct
method CreateOptions (line 47) | func (m *Registry) CreateOptions(outboundType string) (any, bool) {
method Create (line 57) | func (m *Registry) Create(ctx context.Context, router adapter.Router, ...
method register (line 67) | func (m *Registry) register(outboundType string, optionsConstructor op...
function NewRegistry (line 40) | func NewRegistry() *Registry {
FILE: adapter/inbound_test.go
function TestDNSResponseAddressesUnmapsHTTPSIPv4Hints (line 12) | func TestDNSResponseAddressesUnmapsHTTPSIPv4Hints(t *testing.T) {
FILE: adapter/lifecycle.go
type SimpleLifecycle (line 13) | type SimpleLifecycle interface
type StartStage (line 18) | type StartStage
method String (line 34) | func (s StartStage) String() string {
constant StartStateInitialize (line 21) | StartStateInitialize StartStage = iota
constant StartStateStart (line 22) | StartStateStart
constant StartStatePostStart (line 23) | StartStatePostStart
constant StartStateStarted (line 24) | StartStateStarted
type Lifecycle (line 49) | type Lifecycle interface
type LifecycleService (line 54) | type LifecycleService interface
function getServiceName (line 59) | func getServiceName(service any) string {
function Start (line 77) | func Start(logger log.ContextLogger, stage StartStage, services ...Lifec...
function StartNamed (line 90) | func StartNamed(logger log.ContextLogger, stage StartStage, services []L...
function LogElapsed (line 102) | func LogElapsed(logger log.ContextLogger, description ...any) func() {
FILE: adapter/lifecycle_legacy.go
function LegacyStart (line 3) | func LegacyStart(starter any, stage StartStage) error {
type lifecycleServiceWrapper (line 30) | type lifecycleServiceWrapper struct
method Name (line 42) | func (l *lifecycleServiceWrapper) Name() string {
method Start (line 46) | func (l *lifecycleServiceWrapper) Start(stage StartStage) error {
method Close (line 50) | func (l *lifecycleServiceWrapper) Close() error {
function NewLifecycleService (line 35) | func NewLifecycleService(service SimpleLifecycle, name string) Lifecycle...
FILE: adapter/neighbor.go
type NeighborEntry (line 8) | type NeighborEntry struct
type NeighborResolver (line 14) | type NeighborResolver interface
type NeighborUpdateListener (line 22) | type NeighborUpdateListener interface
FILE: adapter/network.go
type NetworkManager (line 14) | type NetworkManager interface
type NetworkOptions (line 37) | type NetworkOptions struct
type InterfaceUpdateListener (line 48) | type InterfaceUpdateListener interface
type WIFIState (line 52) | type WIFIState struct
function NormalizeWIFIBSSID (line 57) | func NormalizeWIFIBSSID(bssid string) string {
type NetworkInterface (line 75) | type NetworkInterface struct
FILE: adapter/outbound.go
type Outbound (line 16) | type Outbound interface
type OutboundWithPreferredRoutes (line 24) | type OutboundWithPreferredRoutes interface
type DirectRouteOutbound (line 30) | type DirectRouteOutbound interface
type OutboundRegistry (line 35) | type OutboundRegistry interface
type OutboundManager (line 40) | type OutboundManager interface
FILE: adapter/outbound/adapter.go
type Adapter (line 7) | type Adapter struct
method Type (line 31) | func (a *Adapter) Type() string {
method Tag (line 35) | func (a *Adapter) Tag() string {
method Network (line 39) | func (a *Adapter) Network() []string {
method Dependencies (line 43) | func (a *Adapter) Dependencies() []string {
function NewAdapter (line 14) | func NewAdapter(outboundType string, outboundTag string, network []strin...
function NewAdapterWithDialerOptions (line 23) | func NewAdapterWithDialerOptions(outboundType string, outboundTag string...
FILE: adapter/outbound/manager.go
type Manager (line 21) | type Manager struct
method Initialize (line 47) | func (m *Manager) Initialize(defaultOutboundFallback func() (adapter.O...
method Start (line 51) | func (m *Manager) Start(stage adapter.StartStage) error {
method startOutbounds (line 96) | func (m *Manager) startOutbounds(outbounds []adapter.Outbound) error {
method Close (line 168) | func (m *Manager) Close() error {
method Outbounds (line 195) | func (m *Manager) Outbounds() []adapter.Outbound {
method Outbound (line 201) | func (m *Manager) Outbound(tag string) (adapter.Outbound, bool) {
method Default (line 211) | func (m *Manager) Default() adapter.Outbound {
method Remove (line 217) | func (m *Manager) Remove(tag string) error {
method Create (line 261) | func (m *Manager) Create(ctx context.Context, router adapter.Router, l...
function NewManager (line 36) | func NewManager(logger logger.ContextLogger, registry adapter.OutboundRe...
FILE: adapter/outbound/registry.go
type ConstructorFunc (line 13) | type ConstructorFunc
function Register (line 15) | func Register[Options any](registry *Registry, outboundType string, cons...
type optionsConstructorFunc (line 30) | type optionsConstructorFunc
type constructorFunc (line 31) | type constructorFunc
type Registry (line 34) | type Registry struct
method CreateOptions (line 47) | func (r *Registry) CreateOptions(outboundType string) (any, bool) {
method CreateOutbound (line 57) | func (r *Registry) CreateOutbound(ctx context.Context, router adapter....
method register (line 67) | func (r *Registry) register(outboundType string, optionsConstructor op...
function NewRegistry (line 40) | func NewRegistry() *Registry {
FILE: adapter/platform.go
type PlatformInterface (line 11) | type PlatformInterface interface
type FindConnectionOwnerRequest (line 49) | type FindConnectionOwnerRequest struct
type ConnectionOwner (line 57) | type ConnectionOwner struct
type Notification (line 65) | type Notification struct
type SystemProxyStatus (line 75) | type SystemProxyStatus struct
FILE: adapter/router.go
type Router (line 15) | type Router interface
type ConnectionTracker (line 29) | type ConnectionTracker interface
type ConnectionRouter (line 35) | type ConnectionRouter interface
type ConnectionRouterEx (line 40) | type ConnectionRouterEx interface
type RuleSet (line 46) | type RuleSet interface
type RuleSetUpdateCallback (line 61) | type RuleSetUpdateCallback
type DNSRuleSetUpdateValidator (line 63) | type DNSRuleSetUpdateValidator interface
type RuleSetMetadata (line 68) | type RuleSetMetadata struct
FILE: adapter/rule.go
type HeadlessRule (line 9) | type HeadlessRule interface
type Rule (line 14) | type Rule interface
type DNSRule (line 21) | type DNSRule interface
type RuleAction (line 28) | type RuleAction interface
function IsFinalAction (line 33) | func IsFinalAction(action RuleAction) bool {
FILE: adapter/service.go
type Service (line 10) | type Service interface
type ServiceRegistry (line 16) | type ServiceRegistry interface
type ServiceManager (line 21) | type ServiceManager interface
FILE: adapter/service/adapter.go
type Adapter (line 3) | type Adapter struct
method Type (line 15) | func (a *Adapter) Type() string {
method Tag (line 19) | func (a *Adapter) Tag() string {
function NewAdapter (line 8) | func NewAdapter(serviceType string, serviceTag string) Adapter {
FILE: adapter/service/manager.go
type Manager (line 18) | type Manager struct
method Start (line 36) | func (m *Manager) Start(stage adapter.StartStage) error {
method Close (line 57) | func (m *Manager) Close() error {
method Services (line 81) | func (m *Manager) Services() []adapter.Service {
method Get (line 87) | func (m *Manager) Get(tag string) (adapter.Service, bool) {
method Remove (line 94) | func (m *Manager) Remove(tag string) error {
method Create (line 117) | func (m *Manager) Create(ctx context.Context, logger log.ContextLogger...
function NewManager (line 28) | func NewManager(logger log.ContextLogger, registry adapter.ServiceRegist...
FILE: adapter/service/registry.go
type ConstructorFunc (line 13) | type ConstructorFunc
function Register (line 15) | func Register[Options any](registry *Registry, outboundType string, cons...
type optionsConstructorFunc (line 30) | type optionsConstructorFunc
type constructorFunc (line 31) | type constructorFunc
type Registry (line 34) | type Registry struct
method CreateOptions (line 47) | func (m *Registry) CreateOptions(outboundType string) (any, bool) {
method Create (line 57) | func (m *Registry) Create(ctx context.Context, logger log.ContextLogge...
method register (line 67) | func (m *Registry) register(outboundType string, optionsConstructor op...
function NewRegistry (line 40) | func NewRegistry() *Registry {
FILE: adapter/ssm.go
type ManagedSSMServer (line 9) | type ManagedSSMServer interface
type SSMTracker (line 15) | type SSMTracker interface
FILE: adapter/tailscale.go
type TailscaleEndpoint (line 5) | type TailscaleEndpoint interface
type TailscalePingResult (line 10) | type TailscalePingResult struct
type TailscaleEndpointStatus (line 19) | type TailscaleEndpointStatus struct
type TailscaleUserGroup (line 28) | type TailscaleUserGroup struct
type TailscalePeer (line 36) | type TailscalePeer struct
FILE: adapter/time.go
type TimeService (line 5) | type TimeService interface
FILE: adapter/upstream.go
function NewUpstreamHandler (line 16) | func NewUpstreamHandler(
type myUpstreamHandlerWrapper (line 30) | type myUpstreamHandlerWrapper struct
method NewConnectionEx (line 36) | func (w *myUpstreamHandlerWrapper) NewConnectionEx(ctx context.Context...
method NewPacketConnectionEx (line 47) | func (w *myUpstreamHandlerWrapper) NewPacketConnectionEx(ctx context.C...
type myUpstreamContextHandlerWrapper (line 60) | type myUpstreamContextHandlerWrapper struct
method NewConnectionEx (line 75) | func (w *myUpstreamContextHandlerWrapper) NewConnectionEx(ctx context....
method NewPacketConnectionEx (line 86) | func (w *myUpstreamContextHandlerWrapper) NewPacketConnectionEx(ctx co...
function NewUpstreamContextHandler (line 65) | func NewUpstreamContextHandler(
function NewRouteHandler (line 97) | func NewRouteHandler(
type routeHandlerWrapper (line 109) | type routeHandlerWrapper struct
method NewConnectionEx (line 114) | func (r *routeHandlerWrapper) NewConnectionEx(ctx context.Context, con...
method NewPacketConnectionEx (line 124) | func (r *routeHandlerWrapper) NewPacketConnectionEx(ctx context.Contex...
function NewRouteContextHandler (line 134) | func NewRouteContextHandler(
type routeContextHandlerWrapper (line 144) | type routeContextHandlerWrapper struct
method NewConnectionEx (line 148) | func (r *routeContextHandlerWrapper) NewConnectionEx(ctx context.Conte...
method NewPacketConnectionEx (line 159) | func (r *routeContextHandlerWrapper) NewPacketConnectionEx(ctx context...
FILE: adapter/upstream_legacy.go
type LegacyUpstreamHandlerAdapter (line 23) | type LegacyUpstreamHandlerAdapter interface
function NewLegacyUpstreamHandler (line 32) | func NewLegacyUpstreamHandler(
type legacyUpstreamHandlerWrapper (line 51) | type legacyUpstreamHandlerWrapper struct
method NewConnection (line 59) | func (w *legacyUpstreamHandlerWrapper) NewConnection(ctx context.Conte...
method NewPacketConnection (line 71) | func (w *legacyUpstreamHandlerWrapper) NewPacketConnection(ctx context...
method NewError (line 83) | func (w *legacyUpstreamHandlerWrapper) NewError(ctx context.Context, e...
function UpstreamMetadata (line 88) | func UpstreamMetadata(metadata InboundContext) M.Metadata {
type legacyUpstreamContextHandlerWrapper (line 96) | type legacyUpstreamContextHandlerWrapper struct
method NewConnection (line 116) | func (w *legacyUpstreamContextHandlerWrapper) NewConnection(ctx contex...
method NewPacketConnection (line 128) | func (w *legacyUpstreamContextHandlerWrapper) NewPacketConnection(ctx ...
method NewError (line 140) | func (w *legacyUpstreamContextHandlerWrapper) NewError(ctx context.Con...
function NewLegacyUpstreamContextHandler (line 103) | func NewLegacyUpstreamContextHandler(
function NewLegacyRouteHandler (line 145) | func NewLegacyRouteHandler(
function NewLegacyRouteContextHandler (line 158) | func NewLegacyRouteContextHandler(
type legacyRouteHandlerWrapper (line 173) | type legacyRouteHandlerWrapper struct
method NewConnection (line 180) | func (w *legacyRouteHandlerWrapper) NewConnection(ctx context.Context,...
method NewPacketConnection (line 192) | func (w *legacyRouteHandlerWrapper) NewPacketConnection(ctx context.Co...
method NewError (line 204) | func (w *legacyRouteHandlerWrapper) NewError(ctx context.Context, err ...
type legacyRouteContextHandlerWrapper (line 211) | type legacyRouteContextHandlerWrapper struct
method NewConnection (line 217) | func (w *legacyRouteContextHandlerWrapper) NewConnection(ctx context.C...
method NewPacketConnection (line 229) | func (w *legacyRouteContextHandlerWrapper) NewPacketConnection(ctx con...
method NewError (line 241) | func (w *legacyRouteContextHandlerWrapper) NewError(ctx context.Contex...
FILE: adapter/v2ray.go
type V2RayServerTransport (line 10) | type V2RayServerTransport interface
type V2RayServerTransportHandler (line 17) | type V2RayServerTransportHandler interface
type V2RayClientTransport (line 21) | type V2RayClientTransport interface
FILE: box.go
type Box (line 41) | type Box struct
method PreStart (line 452) | func (s *Box) PreStart() error {
method Start (line 471) | func (s *Box) Start() error {
method preStart (line 490) | func (s *Box) preStart() error {
method start (line 521) | func (s *Box) start() error {
method Close (line 561) | func (s *Box) Close() error {
method Network (line 613) | func (s *Box) Network() adapter.NetworkManager {
method Router (line 617) | func (s *Box) Router() adapter.Router {
method Inbound (line 621) | func (s *Box) Inbound() adapter.InboundManager {
method Outbound (line 625) | func (s *Box) Outbound() adapter.OutboundManager {
method Endpoint (line 629) | func (s *Box) Endpoint() adapter.EndpointManager {
method LogFactory (line 633) | func (s *Box) LogFactory() log.Factory {
type Options (line 60) | type Options struct
function Context (line 66) | func Context(
function New (line 105) | func New(options Options) (*Box, error) {
FILE: cmd/internal/app_store_connect/main.go
function main (line 19) | func main() {
constant appID (line 53) | appID = "6673731168"
constant groupID (line 54) | groupID = "5c5f3b78-b7a0-40c0-bcad-e6ef87bbefda"
function createClient (line 57) | func createClient(expireDuration time.Duration) *asc.Client {
function fetchMacOSVersion (line 69) | func fetchMacOSVersion(ctx context.Context) error {
function publishTestflight (line 102) | func publishTestflight(ctx context.Context) error {
function cancelAppStore (line 213) | func cancelAppStore(ctx context.Context, platform string) error {
function prepareAppStore (line 262) | func prepareAppStore(ctx context.Context) error {
function publishAppStore (line 402) | func publishAppStore(ctx context.Context) error {
function isRetryable (line 442) | func isRetryable(response *asc.Response) bool {
FILE: cmd/internal/build/main.go
function main (line 12) | func main() {
FILE: cmd/internal/build_libbox/main.go
function init (line 26) | func init() {
function main (line 33) | func main() {
function init (line 56) | func init() {
type AndroidBuildConfig (line 74) | type AndroidBuildConfig struct
function filterTags (line 80) | func filterTags(tags []string, exclude ...string) []string {
function checkJavaVersion (line 94) | func checkJavaVersion() {
function getAndroidBindTarget (line 112) | func getAndroidBindTarget() string {
function buildAndroidVariant (line 121) | func buildAndroidVariant(config AndroidBuildConfig, bindTarget string) {
function buildAndroid (line 160) | func buildAndroid() {
function buildApple (line 191) | func buildApple() {
FILE: cmd/internal/build_shared/sdk.go
function FindSDK (line 22) | func FindSDK() {
function findNDK (line 50) | func findNDK() bool {
function FindMobile (line 94) | func FindMobile() {
FILE: cmd/internal/build_shared/tag.go
function ReadTag (line 9) | func ReadTag() (string, error) {
function ReadTagVersionRev (line 23) | func ReadTagVersionRev() (badversion.Version, error) {
function ReadTagVersion (line 28) | func ReadTagVersion() (badversion.Version, error) {
FILE: cmd/internal/format_docs/main.go
function main (line 12) | func main() {
function processFile (line 30) | func processFile(path string) error {
FILE: cmd/internal/protogen/main.go
function envFile (line 18) | func envFile() (string, error) {
function GetRuntimeEnv (line 37) | func GetRuntimeEnv(key string) (string, error) {
function GetGOBIN (line 63) | func GetGOBIN() string {
function main (line 82) | func main() {
function NormalizeGeneratedProtoFile (line 184) | func NormalizeGeneratedProtoFile(path string) error {
FILE: cmd/internal/read_tag/main.go
function init (line 17) | func init() {
function main (line 22) | func main() {
function setGitHubEnv (line 55) | func setGitHubEnv(name string, value string) error {
FILE: cmd/internal/tun_bench/main.go
function main (line 26) | func main() {
function main0 (line 33) | func main0() error {
function runTests (line 47) | func runTests() ([]TestResult, error) {
type TestResult (line 93) | type TestResult struct
function testOnce (line 103) | func testOnce(boxPath string, stackName string, mtu int, multiThread boo...
type stderrWriter (line 280) | type stderrWriter struct
method Write (line 282) | func (w *stderrWriter) Write(p []byte) (n int, err error) {
FILE: cmd/internal/update_android_version/main.go
function init (line 21) | func init() {
function main (line 26) | func main() {
FILE: cmd/internal/update_apple_version/main.go
function init (line 19) | func init() {
function main (line 23) | func main() {
function findAndReplace (line 60) | func findAndReplace(objectsMap map[string]any, projectContent string, bu...
function findAndReplaceProjectVersion (line 84) | func findAndReplaceProjectVersion(objectsMap map[string]any, projectCont...
function findObjectKey (line 108) | func findObjectKey(objectsMap map[string]any, bundleIDList []string) []s...
function findObjectKeyByDirectory (line 126) | func findObjectKeyByDirectory(objectsMap map[string]any, directoryList [...
FILE: cmd/internal/update_certificates/main.go
function main (line 15) | func main() {
function updateMozillaIncludedRootCAs (line 26) | func updateMozillaIncludedRootCAs() error {
function fetchChinaFingerprints (line 69) | func fetchChinaFingerprints() (map[string]bool, error) {
function updateChromeIncludedRootCAs (line 98) | func updateChromeIncludedRootCAs() error {
FILE: cmd/sing-box/cmd.go
function init (line 32) | func init() {
function preRun (line 39) | func preRun(cmd *cobra.Command, args []string) {
FILE: cmd/sing-box/cmd_check.go
function init (line 24) | func init() {
function check (line 28) | func check() error {
FILE: cmd/sing-box/cmd_format.go
function init (line 30) | func init() {
function format (line 35) | func format() error {
FILE: cmd/sing-box/cmd_generate.go
function init (line 21) | func init() {
function init (line 45) | func init() {
function generateRandom (line 50) | func generateRandom(args []string) error {
function generateUUID (line 85) | func generateUUID() error {
FILE: cmd/sing-box/cmd_generate_ech.go
function init (line 24) | func init() {
function generateECHKeyPair (line 28) | func generateECHKeyPair(serverName string) error {
FILE: cmd/sing-box/cmd_generate_tls.go
function init (line 27) | func init() {
function generateTLSKeyPair (line 32) | func generateTLSKeyPair(serverName string) error {
FILE: cmd/sing-box/cmd_generate_vapid.go
function init (line 27) | func init() {
function generateVAPIDKeyPair (line 31) | func generateVAPIDKeyPair() error {
FILE: cmd/sing-box/cmd_generate_wireguard.go
function init (line 13) | func init() {
function generateWireGuardKey (line 30) | func generateWireGuardKey() error {
function generateRealityKey (line 52) | func generateRealityKey() error {
FILE: cmd/sing-box/cmd_geoip.go
function init (line 27) | func init() {
function geoipPreRun (line 32) | func geoipPreRun() error {
FILE: cmd/sing-box/cmd_geoip_export.go
constant flagGeoipExportDefaultOutput (line 21) | flagGeoipExportDefaultOutput = "geoip-<country>.srs"
function init (line 35) | func init() {
function geoipExport (line 40) | func geoipExport(countryCode string) error {
FILE: cmd/sing-box/cmd_geoip_list.go
function init (line 22) | func init() {
function listGeoip (line 26) | func listGeoip() error {
FILE: cmd/sing-box/cmd_geoip_lookup.go
function init (line 26) | func init() {
function geoipLookup (line 30) | func geoipLookup(address string) error {
FILE: cmd/sing-box/cmd_geosite.go
function init (line 28) | func init() {
function geositePreRun (line 33) | func geositePreRun() error {
FILE: cmd/sing-box/cmd_geosite_export.go
constant commandGeositeExportDefaultOutput (line 18) | commandGeositeExportDefaultOutput = "geosite-<category>.json"
function init (line 32) | func init() {
function geositeExport (line 37) | func geositeExport(category string) error {
FILE: cmd/sing-box/cmd_geosite_list.go
function init (line 24) | func init() {
function geositeList (line 28) | func geositeList() error {
FILE: cmd/sing-box/cmd_geosite_lookup.go
function init (line 36) | func init() {
function geositeLookup (line 40) | func geositeLookup(source string, target string) error {
FILE: cmd/sing-box/cmd_geosite_matcher.go
type searchGeositeMatcher (line 10) | type searchGeositeMatcher struct
method Match (line 32) | func (r *searchGeositeMatcher) Match(domain string) string {
function newSearchGeositeMatcher (line 17) | func newSearchGeositeMatcher(items []geosite.Item) (*searchGeositeMatche...
FILE: cmd/sing-box/cmd_merge.go
function init (line 32) | func init() {
function merge (line 36) | func merge(outputPath string) error {
function mergePathResources (line 70) | func mergePathResources(options *option.Options) error {
function mergeTLSInboundOptions (line 88) | func mergeTLSInboundOptions(options *option.InboundTLSOptions) *option.I...
function mergeTLSOutboundOptions (line 112) | func mergeTLSOutboundOptions(options *option.OutboundTLSOptions) *option...
function mergeSSHOutboundOptions (line 131) | func mergeSSHOutboundOptions(options *option.SSHOutboundOptions) {
function trimStringArray (line 139) | func trimStringArray(array []string) []string {
FILE: cmd/sing-box/cmd_rule_set.go
function init (line 12) | func init() {
FILE: cmd/sing-box/cmd_rule_set_compile.go
constant flagRuleSetCompileDefaultOutput (line 20) | flagRuleSetCompileDefaultOutput = "<file_name>.srs"
function init (line 34) | func init() {
function compileRuleSet (line 39) | func compileRuleSet(sourcePath string) error {
function downgradeRuleSetVersion (line 84) | func downgradeRuleSetVersion(version uint8, options option.PlainRuleSet)...
FILE: cmd/sing-box/cmd_rule_set_convert.go
function init (line 35) | func init() {
function convertRuleSet (line 41) | func convertRuleSet(sourcePath string) error {
FILE: cmd/sing-box/cmd_rule_set_decompile.go
constant flagRuleSetDecompileDefaultOutput (line 20) | flagRuleSetDecompileDefaultOutput = "<file_name>.json"
function init (line 34) | func init() {
function decompileRuleSet (line 39) | func decompileRuleSet(sourcePath string) error {
function hasRule (line 87) | func hasRule(rules []option.HeadlessRule, cond func(rule option.DefaultH...
FILE: cmd/sing-box/cmd_rule_set_format.go
function init (line 31) | func init() {
function formatRuleSet (line 36) | func formatRuleSet(sourcePath string) error {
FILE: cmd/sing-box/cmd_rule_set_match.go
function init (line 38) | func init() {
function ruleSetMatch (line 43) | func ruleSetMatch(sourcePath string, domain string) error {
FILE: cmd/sing-box/cmd_rule_set_merge.go
function init (line 38) | func init() {
type RuleSetEntry (line 44) | type RuleSetEntry struct
function readRuleSetAt (line 50) | func readRuleSetAt(path string) (*RuleSetEntry, error) {
function readRuleSet (line 74) | func readRuleSet() ([]*RuleSetEntry, error) {
function readRuleSetAndMerge (line 105) | func readRuleSetAndMerge() (option.PlainRuleSetCompat, error) {
function mergeRuleSet (line 134) | func mergeRuleSet(outputPath string) error {
FILE: cmd/sing-box/cmd_rule_set_upgrade.go
function init (line 32) | func init() {
function upgradeRuleSet (line 37) | func upgradeRuleSet(sourcePath string) error {
FILE: cmd/sing-box/cmd_run.go
function init (line 37) | func init() {
type OptionsEntry (line 41) | type OptionsEntry struct
function readConfigAt (line 47) | func readConfigAt(path string) (*OptionsEntry, error) {
function readConfig (line 71) | func readConfig() ([]*OptionsEntry, error) {
function readConfigAndMerge (line 102) | func readConfigAndMerge() (option.Options, error) {
function create (line 125) | func create() (*box.Box, context.CancelFunc, error) {
function run (line 169) | func run() error {
function closeMonitor (line 204) | func closeMonitor(ctx context.Context) {
FILE: cmd/sing-box/cmd_tools.go
function init (line 21) | func init() {
function createPreStartedClient (line 26) | func createPreStartedClient() (*box.Box, error) {
function createDialer (line 44) | func createDialer(instance *box.Box, outboundTag string) (N.Dialer, erro...
FILE: cmd/sing-box/cmd_tools_connect.go
function init (line 32) | func init() {
function connect (line 37) | func connect(address string) error {
FILE: cmd/sing-box/cmd_tools_fetch.go
function init (line 33) | func init() {
function fetch (line 42) | func fetch(args []string) error {
function fetchHTTP (line 99) | func fetchHTTP(httpClient *http.Client, parsedURL *url.URL) error {
FILE: cmd/sing-box/cmd_tools_fetch_http3.go
function initializeHTTP3Client (line 18) | func initializeHTTP3Client(instance *box.Box) error {
FILE: cmd/sing-box/cmd_tools_fetch_http3_stub.go
function initializeHTTP3Client (line 12) | func initializeHTTP3Client(instance *box.Box) error {
function fetchHTTP3 (line 16) | func fetchHTTP3(parsedURL *url.URL) error {
FILE: cmd/sing-box/cmd_tools_networkquality.go
function init (line 33) | func init() {
function runNetworkQuality (line 57) | func runNetworkQuality() error {
FILE: cmd/sing-box/cmd_tools_stun.go
function init (line 27) | func init() {
function runSTUN (line 32) | func runSTUN() error {
FILE: cmd/sing-box/cmd_tools_synctime.go
function init (line 34) | func init() {
function syncTime (line 41) | func syncTime() error {
FILE: cmd/sing-box/cmd_version.go
function init (line 22) | func init() {
function printVersion (line 27) | func printVersion(cmd *cobra.Command, args []string) {
FILE: cmd/sing-box/generate_completions.go
function main (line 7) | func main() {
function generateCompletions (line 14) | func generateCompletions() error {
FILE: cmd/sing-box/main.go
function main (line 7) | func main() {
FILE: common/badtls/raw_conn.go
type RawConn (line 16) | type RawConn struct
method ReadRecord (line 166) | func (c *RawConn) ReadRecord() error {
method HandlePostHandshakeMessage (line 170) | func (c *RawConn) HandlePostHandshakeMessage() error {
method WriteRecordLocked (line 174) | func (c *RawConn) WriteRecordLocked(typ uint16, data []byte) (int, err...
function NewRawConn (line 42) | func NewRawConn(rawTLSConn tls.Conn) (*RawConn, error) {
FILE: common/badtls/raw_half_conn.go
type RawHalfConn (line 14) | type RawHalfConn struct
method Decrypt (line 107) | func (hc *RawHalfConn) Decrypt(record []byte) ([]byte, uint8, error) {
method SetErrorLocked (line 111) | func (hc *RawHalfConn) SetErrorLocked(err error) error {
method SetTrafficSecret (line 115) | func (hc *RawHalfConn) SetTrafficSecret(suite unsafe.Pointer, level in...
method ExplicitNonceLen (line 119) | func (hc *RawHalfConn) ExplicitNonceLen() int {
function NewRawHalfConn (line 30) | func NewRawHalfConn(rawHalfConn reflect.Value, methods *Methods) (*RawHa...
FILE: common/badtls/read_wait.go
type ReadWaitConn (line 13) | type ReadWaitConn struct
method InitializeReadWaiter (line 33) | func (c *ReadWaitConn) InitializeReadWaiter(options N.ReadWaitOptions)...
method WaitReadBuffer (line 38) | func (c *ReadWaitConn) WaitReadBuffer() (buffer *buf.Buffer, err error) {
method Upstream (line 76) | func (c *ReadWaitConn) Upstream() any {
method ReaderReplaceable (line 80) | func (c *ReadWaitConn) ReaderReplaceable() bool {
function NewReadWaitConn (line 19) | func NewReadWaitConn(conn tls.Conn) (tls.Conn, error) {
FILE: common/badtls/read_wait_stub.go
function NewReadWaitConn (line 11) | func NewReadWaitConn(conn tls.Conn) (tls.Conn, error) {
FILE: common/badtls/registry.go
type Methods (line 11) | type Methods struct
function init (line 24) | func init() {
function stdTLSReadRecord (line 44) | func stdTLSReadRecord(c unsafe.Pointer) error
function stdTLSHandlePostHandshakeMessage (line 47) | func stdTLSHandlePostHandshakeMessage(c unsafe.Pointer) error
function stdWriteRecordLocked (line 50) | func stdWriteRecordLocked(c unsafe.Pointer, typ uint16, data []byte) (in...
function stdSetErrorLocked (line 53) | func stdSetErrorLocked(hc unsafe.Pointer, err error) error
function stdDecrypt (line 56) | func stdDecrypt(hc unsafe.Pointer, record []byte) ([]byte, uint8, error)
function stdSetTrafficSecret (line 59) | func stdSetTrafficSecret(hc unsafe.Pointer, suite unsafe.Pointer, level ...
function stdExplicitNonceLen (line 62) | func stdExplicitNonceLen(hc unsafe.Pointer) int
FILE: common/badtls/registry_utls.go
function init (line 14) | func init() {
function utlsReadRecord (line 38) | func utlsReadRecord(c unsafe.Pointer) error
function utlsHandlePostHandshakeMessage (line 41) | func utlsHandlePostHandshakeMessage(c unsafe.Pointer) error
function utlsWriteRecordLocked (line 44) | func utlsWriteRecordLocked(hc unsafe.Pointer, typ uint16, data []byte) (...
function utlsSetErrorLocked (line 47) | func utlsSetErrorLocked(hc unsafe.Pointer, err error) error
function utlsDecrypt (line 50) | func utlsDecrypt(hc unsafe.Pointer, record []byte) ([]byte, uint8, error)
function utlsSetTrafficSecret (line 53) | func utlsSetTrafficSecret(hc unsafe.Pointer, suite unsafe.Pointer, level...
function utlsExplicitNonceLen (line 56) | func utlsExplicitNonceLen(hc unsafe.Pointer) int
FILE: common/badversion/version.go
type Version (line 12) | type Version struct
method LessThan (line 21) | func (v Version) LessThan(anotherVersion Version) bool {
method LessThanOrEqual (line 25) | func (v Version) LessThanOrEqual(anotherVersion Version) bool {
method GreaterThanOrEqual (line 29) | func (v Version) GreaterThanOrEqual(anotherVersion Version) bool {
method GreaterThan (line 33) | func (v Version) GreaterThan(anotherVersion Version) bool {
method VersionString (line 84) | func (v Version) VersionString() string {
method String (line 88) | func (v Version) String() string {
method BadString (line 96) | func (v Version) BadString() string {
function parsePreReleaseIdentifier (line 73) | func parsePreReleaseIdentifier(identifier string) int {
function IsValid (line 110) | func IsValid(versionName string) bool {
function Parse (line 114) | func Parse(versionName string) (version Version) {
FILE: common/badversion/version_json.go
method MarshalJSON (line 5) | func (v Version) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 9) | func (v *Version) UnmarshalJSON(data []byte) error {
FILE: common/badversion/version_test.go
function TestCompareVersion (line 9) | func TestCompareVersion(t *testing.T) {
FILE: common/certificate/chrome.go
function chromeIncludedPEM (line 5) | func chromeIncludedPEM() string {
FILE: common/certificate/mozilla.go
function mozillaIncludedPEM (line 5) | func mozillaIncludedPEM() string {
FILE: common/certificate/store.go
type Store (line 24) | type Store struct
method Name (line 104) | func (s *Store) Name() string {
method Start (line 108) | func (s *Store) Start(stage adapter.StartStage) error {
method Close (line 118) | func (s *Store) Close() error {
method Pool (line 133) | func (s *Store) Pool() *x509.CertPool {
method StoreKind (line 139) | func (s *Store) StoreKind() string {
method ExclusiveAnchors (line 143) | func (s *Store) ExclusiveAnchors() bool {
method update (line 147) | func (s *Store) update() error {
method newBasePool (line 216) | func (s *Store) newBasePool() (*x509.CertPool, error) {
function NewStore (line 37) | func NewStore(ctx context.Context, logger logger.Logger, options option....
function appendPEMBlock (line 208) | func appendPEMBlock(buffer *bytes.Buffer, block string) {
function readUniqueDirectoryEntries (line 232) | func readUniqueDirectoryEntries(dir string) ([]fs.DirEntry, error) {
function isSameDirSymlink (line 246) | func isSameDirSymlink(f fs.DirEntry, dir string) bool {
FILE: common/certificate/store_darwin.go
type storePlatform (line 30) | type storePlatform struct
type appleAnchors (line 35) | type appleAnchors struct
method Retain (line 98) | func (a *appleAnchors) Retain() adapter.AppleAnchors {
method Release (line 103) | func (a *appleAnchors) Release() {
method Ref (line 112) | func (a *appleAnchors) Ref() unsafe.Pointer {
function newAppleAnchors (line 40) | func newAppleAnchors(pemBytes []byte) (*appleAnchors, error) {
function NewAppleAnchors (line 77) | func NewAppleAnchors(pemBytes []byte) (adapter.AppleAnchors, error) {
function AcquireAnchors (line 84) | func AcquireAnchors(userAnchors adapter.AppleAnchors, store adapter.Cert...
method AppleAnchors (line 116) | func (s *Store) AppleAnchors() adapter.AppleAnchors {
method updatePlatformLocked (line 125) | func (s *Store) updatePlatformLocked(pemBytes []byte) error {
method closePlatform (line 143) | func (s *Store) closePlatform() error {
function decodeCertificatePEM (line 153) | func decodeCertificatePEM(pemBytes []byte) [][]byte {
FILE: common/certificate/store_other.go
type storePlatform (line 6) | type storePlatform struct
method updatePlatformLocked (line 8) | func (s *Store) updatePlatformLocked(_ []byte) error {
method closePlatform (line 12) | func (s *Store) closePlatform() error {
FILE: common/compatible/map.go
type Map (line 6) | type Map struct
method Len (line 10) | func (m *Map[K, V]) Len() int {
method Load (line 19) | func (m *Map[K, V]) Load(key K) (V, bool) {
method Store (line 28) | func (m *Map[K, V]) Store(key K, value V) {
method Delete (line 32) | func (m *Map[K, V]) Delete(key K) {
method Range (line 36) | func (m *Map[K, V]) Range(f func(key K, value V) bool) {
method LoadOrStore (line 42) | func (m *Map[K, V]) LoadOrStore(key K, value V) (V, bool) {
method LoadAndDelete (line 47) | func (m *Map[K, V]) LoadAndDelete(key K) (V, bool) {
function New (line 56) | func New[K comparable, V any]() *Map[K, V] {
FILE: common/convertor/adguard/convertor.go
type agdguardRuleLine (line 20) | type agdguardRuleLine struct
function ToOptions (line 31) | func ToOptions(reader io.Reader, logger logger.Logger) ([]option.Headles...
function FromOptions (line 302) | func FromOptions(rules []option.HeadlessRule) ([]byte, error) {
function ignoreIPCIDRRegexp (line 400) | func ignoreIPCIDRRegexp(ruleLine string) bool {
function parseAdGuardHostLine (line 412) | func parseAdGuardHostLine(ruleLine string) (string, error) {
function parseADGuardIPCIDRLine (line 431) | func parseADGuardIPCIDRLine(ruleLine string) (netip.Prefix, error) {
FILE: common/convertor/adguard/convertor_test.go
function TestConverter (line 15) | func TestConverter(t *testing.T) {
function TestHosts (line 84) | func TestHosts(t *testing.T) {
function TestSimpleHosts (line 115) | func TestSimpleHosts(t *testing.T) {
FILE: common/dialer/default.go
type DefaultDialer (line 30) | type DefaultDialer struct
method DialContext (line 242) | func (d *DefaultDialer) DialContext(ctx context.Context, network strin...
method DialParallelInterface (line 269) | func (d *DefaultDialer) DialParallelInterface(ctx context.Context, net...
method ListenPacket (line 317) | func (d *DefaultDialer) ListenPacket(ctx context.Context, destination ...
method DialerForICMPDestination (line 333) | func (d *DefaultDialer) DialerForICMPDestination(destination netip.Add...
method ListenSerialInterfacePacket (line 341) | func (d *DefaultDialer) ListenSerialInterfacePacket(ctx context.Contex...
method WireGuardControl (line 374) | func (d *DefaultDialer) WireGuardControl() control.Func {
method trackConn (line 378) | func (d *DefaultDialer) trackConn(conn net.Conn, err error) (net.Conn,...
method trackPacketConn (line 385) | func (d *DefaultDialer) trackPacketConn(conn net.PacketConn, err error...
function NewDefault (line 49) | func NewDefault(ctx context.Context, options option.DialerOptions) (*Def...
function setMarkWrapper (line 226) | func setMarkWrapper(networkManager adapter.NetworkManager, mark uint32, ...
FILE: common/dialer/default_parallel_interface.go
method dialParallelInterface (line 16) | func (d *DefaultDialer) dialParallelInterface(ctx context.Context, diale...
method dialParallelInterfaceFastFallback (line 90) | func (d *DefaultDialer) dialParallelInterfaceFastFallback(ctx context.Co...
method listenSerialInterfacePacket (line 151) | func (d *DefaultDialer) listenSerialInterfacePacket(ctx context.Context,...
function selectInterfaces (line 183) | func selectInterfaces(networkManager adapter.NetworkManager, strategy C....
FILE: common/dialer/default_parallel_network.go
function DialSerialNetwork (line 16) | func DialSerialNetwork(ctx context.Context, dialer N.Dialer, network str...
function DialParallelNetwork (line 47) | func DialParallelNetwork(ctx context.Context, dialer ParallelInterfaceDi...
function ListenSerialNetworkPacket (line 132) | func ListenSerialNetworkPacket(ctx context.Context, dialer N.Dialer, des...
FILE: common/dialer/detour.go
type DirectDialer (line 15) | type DirectDialer interface
type DetourDialer (line 19) | type DetourDialer struct
method Dialer (line 52) | func (d *DetourDialer) Dialer() (N.Dialer, error) {
method init (line 57) | func (d *DetourDialer) init() {
method DialContext (line 80) | func (d *DetourDialer) DialContext(ctx context.Context, network string...
method ListenPacket (line 88) | func (d *DetourDialer) ListenPacket(ctx context.Context, destination M...
method Upstream (line 96) | func (d *DetourDialer) Upstream() any {
function NewDetour (line 29) | func NewDetour(outboundManager adapter.OutboundManager, detour string, d...
function NewDefaultOutboundDetour (line 37) | func NewDefaultOutboundDetour(outboundManager adapter.OutboundManager) N...
function InitializeDetour (line 44) | func InitializeDetour(dialer N.Dialer) error {
FILE: common/dialer/dialer.go
type Options (line 19) | type Options struct
function New (line 32) | func New(ctx context.Context, options option.DialerOptions, remoteIsDoma...
function NewWithOptions (line 40) | func NewWithOptions(options Options) (N.Dialer, error) {
type ParallelInterfaceDialer (line 148) | type ParallelInterfaceDialer interface
type ParallelNetworkDialer (line 154) | type ParallelNetworkDialer interface
type PacketDialerWithDestination (line 159) | type PacketDialerWithDestination interface
FILE: common/dialer/resolve.go
type ResolveDialer (line 24) | type ResolveDialer interface
type ParallelInterfaceResolveDialer (line 29) | type ParallelInterfaceResolveDialer interface
type resolveDialer (line 34) | type resolveDialer struct
method initialize (line 77) | func (d *resolveDialer) initialize() error {
method initServer (line 82) | func (d *resolveDialer) initServer() {
method DialContext (line 94) | func (d *resolveDialer) DialContext(ctx context.Context, network strin...
method ListenPacket (line 114) | func (d *resolveDialer) ListenPacket(ctx context.Context, destination ...
method QueryOptions (line 134) | func (d *resolveDialer) QueryOptions() adapter.DNSQueryOptions {
method Upstream (line 138) | func (d *resolveDialer) Upstream() any {
function NewResolveDialer (line 46) | func NewResolveDialer(ctx context.Context, dialer N.Dialer, parallel boo...
type resolveParallelNetworkDialer (line 72) | type resolveParallelNetworkDialer struct
method DialParallelInterface (line 142) | func (d *resolveParallelNetworkDialer) DialParallelInterface(ctx conte...
method ListenSerialInterfacePacket (line 165) | func (d *resolveParallelNetworkDialer) ListenSerialInterfacePacket(ctx...
method QueryOptions (line 188) | func (d *resolveParallelNetworkDialer) QueryOptions() adapter.DNSQuery...
method Upstream (line 192) | func (d *resolveParallelNetworkDialer) Upstream() any {
FILE: common/dialer/router.go
type DefaultOutboundDialer (line 13) | type DefaultOutboundDialer struct
method DialContext (line 23) | func (d *DefaultOutboundDialer) DialContext(ctx context.Context, netwo...
method ListenPacket (line 27) | func (d *DefaultOutboundDialer) ListenPacket(ctx context.Context, dest...
method Upstream (line 31) | func (d *DefaultOutboundDialer) Upstream() any {
function NewDefaultOutbound (line 17) | func NewDefaultOutbound(ctx context.Context) N.Dialer {
FILE: common/dialer/tfo.go
type slowOpenConn (line 20) | type slowOpenConn struct
method Read (line 52) | func (c *slowOpenConn) Read(b []byte) (n int, err error) {
method Write (line 68) | func (c *slowOpenConn) Write(b []byte) (n int, err error) {
method Close (line 96) | func (c *slowOpenConn) Close() error {
method LocalAddr (line 107) | func (c *slowOpenConn) LocalAddr() net.Addr {
method RemoteAddr (line 115) | func (c *slowOpenConn) RemoteAddr() net.Addr {
method SetDeadline (line 123) | func (c *slowOpenConn) SetDeadline(t time.Time) error {
method SetReadDeadline (line 131) | func (c *slowOpenConn) SetReadDeadline(t time.Time) error {
method SetWriteDeadline (line 139) | func (c *slowOpenConn) SetWriteDeadline(t time.Time) error {
method Upstream (line 147) | func (c *slowOpenConn) Upstream() any {
method ReaderReplaceable (line 151) | func (c *slowOpenConn) ReaderReplaceable() bool {
method WriterReplaceable (line 155) | func (c *slowOpenConn) WriterReplaceable() bool {
method LazyHeadroom (line 159) | func (c *slowOpenConn) LazyHeadroom() bool {
method NeedHandshake (line 163) | func (c *slowOpenConn) NeedHandshake() bool {
method WriteTo (line 167) | func (c *slowOpenConn) WriteTo(w io.Writer) (n int64, err error) {
function DialSlowContext (line 33) | func DialSlowContext(dialer *tfo.Dialer, ctx context.Context, network st...
FILE: common/dialer/wireguard.go
type WireGuardListener (line 7) | type WireGuardListener interface
FILE: common/geoip/reader.go
type Reader (line 11) | type Reader struct
method Lookup (line 27) | func (r *Reader) Lookup(addr netip.Addr) string {
method Close (line 36) | func (r *Reader) Close() error {
function Open (line 15) | func Open(path string) (*Reader, []string, error) {
FILE: common/geosite/compat_test.go
function oldWriteString (line 17) | func oldWriteString(writer varbin.Writer, value string) error {
function oldReadString (line 22) | func oldReadString(reader varbin.Reader) (string, error) {
function oldReadItem (line 27) | func oldReadItem(reader varbin.Reader) (Item, error) {
function TestStringCompat (line 32) | func TestStringCompat(t *testing.T) {
function TestItemCompat (line 81) | func TestItemCompat(t *testing.T) {
function TestGeositeWriteReadCompat (line 135) | func TestGeositeWriteReadCompat(t *testing.T) {
function generateLargeItems (line 220) | func generateLargeItems(count int) map[string][]Item {
FILE: common/geosite/geosite_test.go
function TestGeosite (line 12) | func TestGeosite(t *testing.T) {
FILE: common/geosite/reader.go
type Reader (line 14) | type Reader struct
method readMetadata (line 51) | func (r *Reader) readMetadata() error {
method Read (line 97) | func (r *Reader) Read(code string) ([]Item, error) {
method Upstream (line 125) | func (r *Reader) Upstream() any {
function Open (line 23) | func Open(path string) (*Reader, []string, error) {
function NewReader (line 36) | func NewReader(readSeeker io.ReadSeeker) (*Reader, []string, error) {
type readCounter (line 129) | type readCounter struct
method Read (line 134) | func (r *readCounter) Read(p []byte) (n int, err error) {
function readString (line 142) | func readString(reader io.ByteReader) (string, error) {
FILE: common/geosite/rule.go
constant RuleTypeDomain (line 8) | RuleTypeDomain ItemType = iota
constant RuleTypeDomainSuffix (line 9) | RuleTypeDomainSuffix
constant RuleTypeDomainKeyword (line 10) | RuleTypeDomainKeyword
constant RuleTypeDomainRegex (line 11) | RuleTypeDomainRegex
type Item (line 14) | type Item struct
function Compile (line 19) | func Compile(code []Item) option.DefaultRule {
function Merge (line 64) | func Merge(rules []option.DefaultRule) option.DefaultRule {
FILE: common/geosite/writer.go
function Write (line 10) | func Write(writer varbin.Writer, domains map[string][]Item) error {
function writeString (line 66) | func writeString(writer varbin.Writer, value string) error {
FILE: common/httpclient/apple_transport_darwin.go
constant applePinnedHashSize (line 40) | applePinnedHashSize = sha256.Size
function verifyApplePinnedPublicKeySHA256 (line 51) | func verifyApplePinnedPublicKeySHA256(flatHashes []byte, leafCertificate...
function box_apple_http_verify_public_key_sha256 (line 63) | func box_apple_http_verify_public_key_sha256(knownHashValues *C.uint8_t,...
type appleSessionConfig (line 73) | type appleSessionConfig struct
method close (line 200) | func (c *appleSessionConfig) close() {
type appleTransportShared (line 84) | type appleTransportShared struct
method retain (line 207) | func (s *appleTransportShared) retain() {
method release (line 211) | func (s *appleTransportShared) release() error {
method newSession (line 219) | func (s *appleTransportShared) newSession() (*C.box_apple_http_session...
type appleTransport (line 92) | type appleTransport struct
method RoundTrip (line 258) | func (t *appleTransport) RoundTrip(request *http.Request) (*http.Respo...
method CloseIdleConnections (line 376) | func (t *appleTransport) CloseIdleConnections() {
method Close (line 400) | func (t *appleTransport) Close() error {
function newAppleTransport (line 99) | func newAppleTransport(ctx context.Context, logger logger.ContextLogger,...
function newAppleSessionConfig (line 134) | func newAppleSessionConfig(ctx context.Context, options option.HTTPClien...
function flattenRequestHeaders (line 414) | func flattenRequestHeaders(request *http.Request) ([]string, []string) {
function parseAppleHTTPResponse (line 432) | func parseAppleHTTPResponse(request *http.Request, response *C.box_apple...
function appleCStringError (line 455) | func appleCStringError(cErr *C.char, message string) error {
FILE: common/httpclient/apple_transport_darwin.h
type box_apple_http_session_t (line 5) | typedef struct box_apple_http_session box_apple_http_session_t;
type box_apple_http_task_t (line 6) | typedef struct box_apple_http_task box_apple_http_task_t;
type box_apple_http_session_config_t (line 8) | typedef struct box_apple_http_session_config {
type box_apple_http_request_t (line 22) | typedef struct box_apple_http_request {
type box_apple_http_response_t (line 34) | typedef struct box_apple_http_response {
FILE: common/httpclient/apple_transport_darwin_test.go
constant appleHTTPTestTimeout (line 37) | appleHTTPTestTimeout = 5 * time.Second
constant appleHTTPRecoveryLoops (line 39) | appleHTTPRecoveryLoops = 5
type appleHTTPTestDialer (line 41) | type appleHTTPTestDialer struct
method DialContext (line 843) | func (d *appleHTTPTestDialer) DialContext(ctx context.Context, network...
method ListenPacket (line 854) | func (d *appleHTTPTestDialer) ListenPacket(ctx context.Context, destin...
type appleHTTPObservedRequest (line 47) | type appleHTTPObservedRequest struct
type appleHTTPTestServer (line 55) | type appleHTTPTestServer struct
method URL (line 779) | func (s *appleHTTPTestServer) URL(path string) string {
type appleTestAnchors (line 64) | type appleTestAnchors struct
method Retain (line 69) | func (a *appleTestAnchors) Retain() adapter.AppleAnchors {
method Release (line 73) | func (a *appleTestAnchors) Release() {
method Ref (line 77) | func (a *appleTestAnchors) Ref() unsafe.Pointer {
function TestNewAppleSessionConfig (line 81) | func TestNewAppleSessionConfig(t *testing.T) {
function TestAppleTransportVerifyPublicKeySHA256 (line 393) | func TestAppleTransportVerifyPublicKeySHA256(t *testing.T) {
function TestNewAppleTransportClosesSessionConfigOnBridgeFailure (line 421) | func TestNewAppleTransportClosesSessionConfigOnBridgeFailure(t *testing....
function TestNewAppleTransportClosesSessionConfigOnSessionFailure (line 441) | func TestNewAppleTransportClosesSessionConfigOnSessionFailure(t *testing...
function TestAppleTransportRoundTripHTTPS (line 461) | func TestAppleTransportRoundTripHTTPS(t *testing.T) {
function TestAppleTransportPinnedPublicKey (line 545) | func TestAppleTransportPinnedPublicKey(t *testing.T) {
function TestAppleTransportGuardrails (line 590) | func TestAppleTransportGuardrails(t *testing.T) {
function TestAppleTransportCancellationRecovery (line 667) | func TestAppleTransportCancellationRecovery(t *testing.T) {
function TestAppleTransportLifecycle (line 715) | func TestAppleTransportLifecycle(t *testing.T) {
function startAppleHTTPTestServer (line 749) | func startAppleHTTPTestServer(t *testing.T, handler http.HandlerFunc) *a...
function newAppleHTTPTestTransport (line 789) | func newAppleHTTPTestTransport(t *testing.T, server *appleHTTPTestServer...
function newAppleHTTPTestContext (line 810) | func newAppleHTTPTestContext() context.Context {
function appleTransportAnchorOptions (line 817) | func appleTransportAnchorOptions(certificatePEM string) option.HTTPClien...
function restoreAppleTransportFactories (line 831) | func restoreAppleTransportFactories(t *testing.T) {
function newAppleHTTPTestCertificate (line 868) | func newAppleHTTPTestCertificate(t *testing.T, serverName string) (stdtl...
function certificatePublicKeySHA256 (line 882) | func certificatePublicKeySHA256(t *testing.T, certificateDER []byte) []b...
function appleHTTPServerTLSOptions (line 897) | func appleHTTPServerTLSOptions(server *appleHTTPTestServer) *option.Outb...
function newAppleHTTPRequest (line 905) | func newAppleHTTPRequest(t *testing.T, method string, rawURL string, bod...
function newAppleHTTPRequestWithContext (line 910) | func newAppleHTTPRequestWithContext(t *testing.T, ctx context.Context, m...
function waitObservedRequest (line 919) | func waitObservedRequest(t *testing.T, requests <-chan appleHTTPObserved...
function readResponseBody (line 931) | func readResponseBody(t *testing.T, response *http.Response) string {
function assertAppleHTTPSucceeds (line 941) | func assertAppleHTTPSucceeds(t *testing.T, transport http.RoundTripper, ...
FILE: common/httpclient/apple_transport_stub.go
function newAppleTransport (line 14) | func newAppleTransport(ctx context.Context, logger logger.ContextLogger,...
FILE: common/httpclient/client.go
function NewTransport (line 17) | func NewTransport(ctx context.Context, logger logger.ContextLogger, tag ...
function newTransport (line 87) | func newTransport(rawDialer N.Dialer, baseTLSConfig tls.Config, options ...
FILE: common/httpclient/context.go
type transportKey (line 5) | type transportKey struct
function contextWithTransportTag (line 7) | func contextWithTransportTag(ctx context.Context, transportTag string) c...
function transportTagFromContext (line 11) | func transportTagFromContext(ctx context.Context) (string, bool) {
FILE: common/httpclient/helpers.go
function dialTLS (line 19) | func dialTLS(ctx context.Context, rawDialer N.Dialer, baseTLSConfig tls....
function applyHeaders (line 44) | func applyHeaders(request *http.Request, headers http.Header, host strin...
function requestRequiresHTTP1 (line 53) | func requestRequiresHTTP1(request *http.Request) bool {
function requestReplayable (line 58) | func requestReplayable(request *http.Request) bool {
function cloneRequestForRetry (line 62) | func cloneRequestForRetry(request *http.Request) *http.Request {
function mustGetBody (line 70) | func mustGetBody(request *http.Request) io.ReadCloser {
function requestAuthority (line 78) | func requestAuthority(request *http.Request) string {
function buildSTDTLSConfig (line 106) | func buildSTDTLSConfig(baseTLSConfig tls.Config, destination M.Socksaddr...
FILE: common/httpclient/helpers_test.go
function TestRequestAuthority (line 9) | func TestRequestAuthority(t *testing.T) {
FILE: common/httpclient/http1_transport.go
type http1Transport (line 13) | type http1Transport struct
method RoundTrip (line 31) | func (t *http1Transport) RoundTrip(request *http.Request) (*http.Respo...
method CloseIdleConnections (line 35) | func (t *http1Transport) CloseIdleConnections() {
method Close (line 39) | func (t *http1Transport) Close() error {
function newHTTP1Transport (line 17) | func newHTTP1Transport(rawDialer N.Dialer, baseTLSConfig tls.Config) *ht...
FILE: common/httpclient/http2_config.go
function CloneHTTP2Transport (line 14) | func CloneHTTP2Transport(transport *http2.Transport) *http2.Transport {
function ConfigureHTTP2Transport (line 22) | func ConfigureHTTP2Transport(options option.HTTP2Options) (*http2.Transp...
FILE: common/httpclient/http2_fallback_transport.go
type http2FallbackTransport (line 22) | type http2FallbackTransport struct
method isH2Fallback (line 45) | func (t *http2FallbackTransport) isH2Fallback(authority string) bool {
method markH2Fallback (line 55) | func (t *http2FallbackTransport) markH2Fallback(authority string) {
method RoundTrip (line 64) | func (t *http2FallbackTransport) RoundTrip(request *http.Request) (*ht...
method roundTrip (line 68) | func (t *http2FallbackTransport) roundTrip(request *http.Request, allo...
method CloseIdleConnections (line 90) | func (t *http2FallbackTransport) CloseIdleConnections() {
method Close (line 95) | func (t *http2FallbackTransport) Close() error {
function newHTTP2FallbackTransport (line 29) | func newHTTP2FallbackTransport(rawDialer N.Dialer, baseTLSConfig tls.Con...
FILE: common/httpclient/http2_fallback_transport_test.go
function TestHTTP2FallbackAuthorityIsolation (line 7) | func TestHTTP2FallbackAuthorityIsolation(t *testing.T) {
function TestHTTP2FallbackEmptyAuthorityNoOp (line 27) | func TestHTTP2FallbackEmptyAuthorityNoOp(t *testing.T) {
FILE: common/httpclient/http2_transport.go
type http2Transport (line 17) | type http2Transport struct
method RoundTrip (line 37) | func (t *http2Transport) RoundTrip(request *http.Request) (*http.Respo...
method CloseIdleConnections (line 44) | func (t *http2Transport) CloseIdleConnections() {
method Close (line 49) | func (t *http2Transport) Close() error {
function newHTTP2Transport (line 22) | func newHTTP2Transport(rawDialer N.Dialer, baseTLSConfig tls.Config, opt...
FILE: common/httpclient/http3_transport.go
type http3Transport (line 23) | type http3Transport struct
method RoundTrip (line 125) | func (t *http3Transport) RoundTrip(request *http.Request) (*http.Respo...
method CloseIdleConnections (line 129) | func (t *http3Transport) CloseIdleConnections() {
method Close (line 133) | func (t *http3Transport) Close() error {
type http3BrokenEntry (line 27) | type http3BrokenEntry struct
type http3FallbackTransport (line 32) | type http3FallbackTransport struct
method RoundTrip (line 138) | func (t *http3FallbackTransport) RoundTrip(request *http.Request) (*ht...
method roundTripHTTP3 (line 145) | func (t *http3FallbackTransport) roundTripHTTP3(request *http.Request)...
method roundTripHTTP3Race (line 171) | func (t *http3FallbackTransport) roundTripHTTP3Race(request *http.Requ...
method h2FallbackRoundTrip (line 261) | func (t *http3FallbackTransport) h2FallbackRoundTrip(request *http.Req...
method CloseIdleConnections (line 268) | func (t *http3FallbackTransport) CloseIdleConnections() {
method Close (line 273) | func (t *http3FallbackTransport) Close() error {
method h3Broken (line 278) | func (t *http3FallbackTransport) h3Broken(authority string) bool {
method clearH3Broken (line 295) | func (t *http3FallbackTransport) clearH3Broken(authority string) {
method markH3Broken (line 304) | func (t *http3FallbackTransport) markH3Broken(authority string) {
function newHTTP3RoundTripper (line 40) | func newHTTP3RoundTripper(
function newHTTP3Transport (line 100) | func newHTTP3Transport(
function newHTTP3FallbackTransport (line 110) | func newHTTP3FallbackTransport(
FILE: common/httpclient/http3_transport_stub.go
function newHTTP3FallbackTransport (line 14) | func newHTTP3FallbackTransport(
function newHTTP3Transport (line 24) | func newHTTP3Transport(
FILE: common/httpclient/http3_transport_test.go
function TestHTTP3BrokenAuthorityIsolation (line 10) | func TestHTTP3BrokenAuthorityIsolation(t *testing.T) {
function TestHTTP3BrokenBackoffPerAuthority (line 22) | func TestHTTP3BrokenBackoffPerAuthority(t *testing.T) {
function TestHTTP3BrokenBackoffCap (line 48) | func TestHTTP3BrokenBackoffCap(t *testing.T) {
function TestHTTP3BrokenClearDeletesEntry (line 58) | func TestHTTP3BrokenClearDeletesEntry(t *testing.T) {
function TestHTTP3BrokenExpiredEntryGarbageCollected (line 73) | func TestHTTP3BrokenExpiredEntryGarbageCollected(t *testing.T) {
function TestHTTP3BrokenEmptyAuthorityNoOp (line 88) | func TestHTTP3BrokenEmptyAuthorityNoOp(t *testing.T) {
FILE: common/httpclient/managed_transport.go
type innerTransport (line 14) | type innerTransport interface
type ManagedTransport (line 22) | type ManagedTransport struct
method getEpoch (line 63) | func (t *ManagedTransport) getEpoch() (*transportEpoch, error) {
method acquireEpoch (line 83) | func (t *ManagedTransport) acquireEpoch() (*transportEpoch, error) {
method releaseEpoch (line 97) | func (t *ManagedTransport) releaseEpoch(epoch *transportEpoch) {
method retireEpoch (line 103) | func (t *ManagedTransport) retireEpoch(epoch *transportEpoch) {
method RoundTrip (line 113) | func (t *ManagedTransport) RoundTrip(request *http.Request) (*http.Res...
method CloseIdleConnections (line 140) | func (t *ManagedTransport) CloseIdleConnections() {
method Reset (line 149) | func (t *ManagedTransport) Reset() {
method close (line 164) | func (t *ManagedTransport) close() error {
type transportEpoch (line 34) | type transportEpoch struct
method tryClose (line 47) | func (e *transportEpoch) tryClose() {
type managedResponseBody (line 41) | type managedResponseBody struct
method Read (line 53) | func (b *managedResponseBody) Read(p []byte) (int, error) {
method Close (line 57) | func (b *managedResponseBody) Close() error {
type sharedRef (line 174) | type sharedRef struct
method RoundTrip (line 192) | func (r *sharedRef) RoundTrip(request *http.Request) (*http.Response, ...
method CloseIdleConnections (line 199) | func (r *sharedRef) CloseIdleConnections() {
method Reset (line 207) | func (r *sharedRef) Reset() {
type sharedState (line 180) | type sharedState struct
function newSharedRef (line 184) | func newSharedRef(managed *ManagedTransport, shared *sharedState) *share...
FILE: common/httpclient/manager.go
type Manager (line 19) | type Manager struct
method Initialize (line 54) | func (m *Manager) Initialize(defaultTransportFallback func() (*Managed...
method Name (line 58) | func (m *Manager) Name() string {
method Start (line 62) | func (m *Manager) Start(stage adapter.StartStage) error {
method DefaultTransport (line 76) | func (m *Manager) DefaultTransport() adapter.HTTPTransport {
method ResolveTransport (line 97) | func (m *Manager) ResolveTransport(ctx context.Context, logger logger....
method trackTransport (line 127) | func (m *Manager) trackTransport(transport *ManagedTransport) {
method resolveShared (line 133) | func (m *Manager) resolveShared(tag string) (*sharedManagedTransport, ...
method ResetNetwork (line 156) | func (m *Manager) ResetNetwork() {
method Close (line 164) | func (m *Manager) Close() error {
type sharedManagedTransport (line 31) | type sharedManagedTransport struct
function NewManager (line 36) | func NewManager(ctx context.Context, logger log.ContextLogger, clients [...
FILE: common/interrupt/conn.go
type Conn (line 20) | type Conn struct
method Close (line 30) | func (c *Conn) Close() error {
method ReaderReplaceable (line 37) | func (c *Conn) ReaderReplaceable() bool {
method WriterReplaceable (line 41) | func (c *Conn) WriterReplaceable() bool {
method Upstream (line 45) | func (c *Conn) Upstream() any {
type PacketConn (line 49) | type PacketConn struct
method Close (line 59) | func (c *PacketConn) Close() error {
method ReaderReplaceable (line 66) | func (c *PacketConn) ReaderReplaceable() bool {
method WriterReplaceable (line 70) | func (c *PacketConn) WriterReplaceable() bool {
method Upstream (line 74) | func (c *PacketConn) Upstream() any {
FILE: common/interrupt/context.go
type contextKeyIsExternalConnection (line 5) | type contextKeyIsExternalConnection struct
function ContextWithIsExternalConnection (line 7) | func ContextWithIsExternalConnection(ctx context.Context) context.Context {
function IsExternalConnectionFromContext (line 11) | func IsExternalConnectionFromContext(ctx context.Context) bool {
FILE: common/interrupt/group.go
type Group (line 11) | type Group struct
method NewConn (line 25) | func (g *Group) NewConn(conn net.Conn, isExternal bool) net.Conn {
method NewPacketConn (line 32) | func (g *Group) NewPacketConn(conn net.PacketConn, isExternal bool) ne...
method Interrupt (line 39) | func (g *Group) Interrupt(interruptExternalConnections bool) {
type groupConnItem (line 16) | type groupConnItem struct
function NewGroup (line 21) | func NewGroup() *Group {
FILE: common/ja3/error.go
constant LengthErr (line 13) | LengthErr string = "length check %v failed"
constant ContentTypeErr (line 14) | ContentTypeErr string = "content type not matching"
constant VersionErr (line 15) | VersionErr string = "version check %v failed"
constant HandshakeTypeErr (line 16) | HandshakeTypeErr string = "handshake type not matching"
constant SNITypeErr (line 17) | SNITypeErr string = "SNI type not supported"
type ParseError (line 21) | type ParseError struct
method Error (line 26) | func (e *ParseError) Error() string {
FILE: common/ja3/ja3.go
type ClientHello (line 16) | type ClientHello struct
method Equals (line 29) | func (j *ClientHello) Equals(another *ClientHello, ignoreExtensionsSeq...
method sortedExtensions (line 54) | func (j *ClientHello) sortedExtensions() []uint16 {
method String (line 67) | func (j *ClientHello) String() string {
method Hash (line 74) | func (j *ClientHello) Hash() string {
function Compute (line 61) | func Compute(payload []byte) (*ClientHello, error) {
FILE: common/ja3/parser.go
constant recordLayerHeaderLen (line 16) | recordLayerHeaderLen int = 5
constant handshakeHeaderLen (line 17) | handshakeHeaderLen int = 6
constant randomDataLen (line 18) | randomDataLen int = 32
constant sessionIDHeaderLen (line 19) | sessionIDHeaderLen int = 1
constant cipherSuiteHeaderLen (line 20) | cipherSuiteHeaderLen int = 2
constant compressMethodHeaderLen (line 21) | compressMethodHeaderLen int = 1
constant extensionsHeaderLen (line 22) | extensionsHeaderLen int = 2
constant extensionHeaderLen (line 23) | extensionHeaderLen int = 4
constant sniExtensionHeaderLen (line 24) | sniExtensionHeaderLen int = 5
constant ecExtensionHeaderLen (line 25) | ecExtensionHeaderLen int = 2
constant ecpfExtensionHeaderLen (line 26) | ecpfExtensionHeaderLen int = 1
constant versionExtensionHeaderLen (line 27) | versionExtensionHeaderLen int = 1
constant signatureAlgorithmsExtensionHeaderLen (line 28) | signatureAlgorithmsExtensionHeaderLen int = 2
constant contentType (line 29) | contentType uint8 = 22
constant handshakeType (line 30) | handshakeType uint8 = 1
constant sniExtensionType (line 31) | sniExtensionType uint16 = 0
constant sniNameDNSHostnameType (line 32) | sniNameDNSHostnameType uint8 = 0
constant ecExtensionType (line 33) | ecExtensionType uint16 = 10
constant ecpfExtensionType (line 34) | ecpfExtensionType uint16 = 11
constant versionExtensionType (line 35) | versionExtensionType uint16 = 43
constant signatureAlgorithmsExtensionType (line 36) | signatureAlgorithmsExtensionType uint16 = 13
constant tlsVersionBitmask (line 40) | tlsVersionBitmask uint16 = 0xFFFC
constant tls13 (line 41) | tls13 uint16 = 0x0304
constant GreaseBitmask (line 45) | GreaseBitmask uint16 = 0x0F0F
constant dashByte (line 48) | dashByte = byte(45)
constant commaByte (line 49) | commaByte = byte(44)
method parseSegment (line 53) | func (j *ClientHello) parseSegment(segment []byte) error {
method parseHandshake (line 85) | func (j *ClientHello) parseHandshake(hs []byte) error {
method parseExtensions (line 155) | func (j *ClientHello) parseExtensions(exs []byte) error {
method marshalJA3 (line 291) | func (j *ClientHello) marshalJA3() {
FILE: common/ktls/ktls.go
type Conn (line 24) | type Conn struct
method Upstream (line 89) | func (c *Conn) Upstream() any {
method SyscallConnForRead (line 93) | func (c *Conn) SyscallConnForRead() syscall.RawConn {
method HandleSyscallReadError (line 105) | func (c *Conn) HandleSyscallReadError(inputErr error) ([]byte, error) {
method SyscallConnForWrite (line 127) | func (c *Conn) SyscallConnForWrite() syscall.RawConn {
function NewConn (line 38) | func NewConn(ctx context.Context, logger logger.ContextLogger, conn aTLS...
FILE: common/ktls/ktls_alert.go
constant alertLevelWarning (line 16) | alertLevelWarning = 1
constant alertLevelError (line 17) | alertLevelError = 2
constant alertCloseNotify (line 21) | alertCloseNotify = 0
constant alertUnexpectedMessage (line 22) | alertUnexpectedMessage = 10
constant alertBadRecordMAC (line 23) | alertBadRecordMAC = 20
constant alertDecryptionFailed (line 24) | alertDecryptionFailed = 21
constant alertRecordOverflow (line 25) | alertRecordOverflow = 22
constant alertDecompressionFailure (line 26) | alertDecompressionFailure = 30
constant alertHandshakeFailure (line 27) | alertHandshakeFailure = 40
constant alertBadCertificate (line 28) | alertBadCertificate = 42
constant alertUnsupportedCertificate (line 29) | alertUnsupportedCertificate = 43
constant alertCertificateRevoked (line 30) | alertCertificateRevoked = 44
constant alertCertificateExpired (line 31) | alertCertificateExpired = 45
constant alertCertificateUnknown (line 32) | alertCertificateUnknown = 46
constant alertIllegalParameter (line 33) | alertIllegalParameter = 47
constant alertUnknownCA (line 34) | alertUnknownCA = 48
constant alertAccessDenied (line 35) | alertAccessDenied = 49
constant alertDecodeError (line 36) | alertDecodeError = 50
constant alertDecryptError (line 37) | alertDecryptError = 51
constant alertExportRestriction (line 38) | alertExportRestriction = 60
constant alertProtocolVersion (line 39) | alertProtocolVersion = 70
constant alertInsufficientSecurity (line 40) | alertInsufficientSecurity = 71
constant alertInternalError (line 41) | alertInternalError = 80
constant alertInappropriateFallback (line 42) | alertInappropriateFallback = 86
constant alertUserCanceled (line 43) | alertUserCanceled = 90
constant alertNoRenegotiation (line 44) | alertNoRenegotiation = 100
constant alertMissingExtension (line 45) | alertMissingExtension = 109
constant alertUnsupportedExtension (line 46) | alertUnsupportedExtension = 110
constant alertCertificateUnobtainable (line 47) | alertCertificateUnobtainable = 111
constant alertUnrecognizedName (line 48) | alertUnrecognizedName = 112
constant alertBadCertificateStatusResponse (line 49) | alertBadCertificateStatusResponse = 113
constant alertBadCertificateHashValue (line 50) | alertBadCertificateHashValue = 114
constant alertUnknownPSKIdentity (line 51) | alertUnknownPSKIdentity = 115
constant alertCertificateRequired (line 52) | alertCertificateRequired = 116
constant alertNoApplicationProtocol (line 53) | alertNoApplicationProtocol = 120
constant alertECHRequired (line 54) | alertECHRequired = 121
method sendAlertLocked (line 57) | func (c *Conn) sendAlertLocked(err uint8) error {
method sendAlert (line 76) | func (c *Conn) sendAlert(err uint8) error {
FILE: common/ktls/ktls_cipher_suites_linux.go
type kernelCryptoCipherType (line 16) | type kernelCryptoCipherType
constant TLS_CIPHER_AES_GCM_128 (line 19) | TLS_CIPHER_AES_GCM_128 kernelCryptoCipherType = 51
constant TLS_CIPHER_AES_GCM_128_IV_SIZE (line 20) | TLS_CIPHER_AES_GCM_128_IV_SIZE kernelCryptoCipherType = 8
constant TLS_CIPHER_AES_GCM_128_KEY_SIZE (line 21) | TLS_CIPHER_AES_GCM_128_KEY_SIZE kernelCryptoCipherType = 16
constant TLS_CIPHER_AES_GCM_128_SALT_SIZE (line 22) | TLS_CIPHER_AES_GCM_128_SALT_SIZE kernelCryptoCipherType = 4
constant TLS_CIPHER_AES_GCM_128_TAG_SIZE (line 23) | TLS_CIPHER_AES_GCM_128_TAG_SIZE kernelCryptoCipherType = 16
constant TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE (line 24) | TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE kernelCryptoCipherType = 8
constant TLS_CIPHER_AES_GCM_256 (line 26) | TLS_CIPHER_AES_GCM_256 kernelCryptoCipherType = 52
constant TLS_CIPHER_AES_GCM_256_IV_SIZE (line 27) | TLS_CIPHER_AES_GCM_256_IV_SIZE kernelCryptoCipherType = 8
constant TLS_CIPHER_AES_GCM_256_KEY_SIZE (line 28) | TLS_CIPHER_AES_GCM_256_KEY_SIZE kernelCryptoCipherType = 32
constant TLS_CIPHER_AES_GCM_256_SALT_SIZE (line 29) | TLS_CIPHER_AES_GCM_256_SALT_SIZE kernelCryptoCipherType = 4
constant TLS_CIPHER_AES_GCM_256_TAG_SIZE (line 30) | TLS_CIPHER_AES_GCM_256_TAG_SIZE kernelCryptoCipherType = 16
constant TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE (line 31) | TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE kernelCryptoCipherType = 8
constant TLS_CIPHER_AES_CCM_128 (line 33) | TLS_CIPHER_AES_CCM_128 kernelCryptoCipherType = 53
constant TLS_CIPHER_AES_CCM_128_IV_SIZE (line 34) | TLS_CIPHER_AES_CCM_128_IV_SIZE kernelCryptoCipherType = 8
constant TLS_CIPHER_AES_CCM_128_KEY_SIZE (line 35) | TLS_CIPHER_AES_CCM_128_KEY_SIZE kernelCryptoCipherType = 16
constant TLS_CIPHER_AES_CCM_128_SALT_SIZE (line 36) | TLS_CIPHER_AES_CCM_128_SALT_SIZE kernelCryptoCipherType = 4
constant TLS_CIPHER_AES_CCM_128_TAG_SIZE (line 37) | TLS_CIPHER_AES_CCM_128_TAG_SIZE kernelCryptoCipherType = 16
constant TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE (line 38) | TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE kernelCryptoCipherType = 8
constant TLS_CIPHER_CHACHA20_POLY1305 (line 40) | TLS_CIPHER_CHACHA20_POLY1305 kernelCryptoCipherType = 54
constant TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE (line 41) | TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE kernelCryptoCipherType = 12
constant TLS_CIPHER_CHACHA20_POLY1305_KEY_SIZE (line 42) | TLS_CIPHER_CHACHA20_POLY1305_KEY_SIZE kernelCryptoCipherType = 32
constant TLS_CIPHER_CHACHA20_POLY1305_SALT_SIZE (line 43) | TLS_CIPHER_CHACHA20_POLY1305_SALT_SIZE kernelCryptoCipherType = 0
constant TLS_CIPHER_CHACHA20_POLY1305_TAG_SIZE (line 44) | TLS_CIPHER_CHACHA20_POLY1305_TAG_SIZE kernelCryptoCipherType = 16
constant TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE (line 45) | TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE kernelCryptoCipherType = 8
constant TLS_CIPHER_ARIA_GCM_128 (line 61) | TLS_CIPHER_ARIA_GCM_128 kernelCryptoCipherType = 57
constant TLS_CIPHER_ARIA_GCM_128_IV_SIZE (line 62) | TLS_CIPHER_ARIA_GCM_128_IV_SIZE kernelCryptoCipherType = 8
constant TLS_CIPHER_ARIA_GCM_128_KEY_SIZE (line 63) | TLS_CIPHER_ARIA_GCM_128_KEY_SIZE kernelCryptoCipherType = 16
constant TLS_CIPHER_ARIA_GCM_128_SALT_SIZE (line 64) | TLS_CIPHER_ARIA_GCM_128_SALT_SIZE kernelCryptoCipherType = 4
constant TLS_CIPHER_ARIA_GCM_128_TAG_SIZE (line 65) | TLS_CIPHER_ARIA_GCM_128_TAG_SIZE kernelCryptoCipherType = 16
constant TLS_CIPHER_ARIA_GCM_128_REC_SEQ_SIZE (line 66) | TLS_CIPHER_ARIA_GCM_128_REC_SEQ_SIZE kernelCryptoCipherType = 8
constant TLS_CIPHER_ARIA_GCM_256 (line 68) | TLS_CIPHER_ARIA_GCM_256 kernelCryptoCipherType = 58
constant TLS_CIPHER_ARIA_GCM_256_IV_SIZE (line 69) | TLS_CIPHER_ARIA_GCM_256_IV_SIZE kernelCryptoCipherType = 8
constant TLS_CIPHER_ARIA_GCM_256_KEY_SIZE (line 70) | TLS_CIPHER_ARIA_GCM_256_KEY_SIZE kernelCryptoCipherType = 32
constant TLS_CIPHER_ARIA_GCM_256_SALT_SIZE (line 71) | TLS_CIPHER_ARIA_GCM_256_SALT_SIZE kernelCryptoCipherType = 4
constant TLS_CIPHER_ARIA_GCM_256_TAG_SIZE (line 72) | TLS_CIPHER_ARIA_GCM_256_TAG_SIZE kernelCryptoCipherType = 16
constant TLS_CIPHER_ARIA_GCM_256_REC_SEQ_SIZE (line 73) | TLS_CIPHER_ARIA_GCM_256_REC_SEQ_SIZE kernelCryptoCipherType = 8
type kernelCrypto (line 76) | type kernelCrypto interface
type kernelCryptoInfo (line 80) | type kernelCryptoInfo struct
type kernelCryptoAES128GCM (line 87) | type kernelCryptoAES128GCM struct
method String (line 95) | func (crypto *kernelCryptoAES128GCM) String() string {
type kernelCryptoAES256GCM (line 102) | type kernelCryptoAES256GCM struct
method String (line 110) | func (crypto *kernelCryptoAES256GCM) String() string {
type kernelCryptoAES128CCM (line 117) | type kernelCryptoAES128CCM struct
method String (line 125) | func (crypto *kernelCryptoAES128CCM) String() string {
type kernelCryptoChacha20Poly1035 (line 132) | type kernelCryptoChacha20Poly1035 struct
method String (line 140) | func (crypto *kernelCryptoChacha20Poly1035) String() string {
type kernelCryptoARIA128GCM (line 177) | type kernelCryptoARIA128GCM struct
method String (line 185) | func (crypto *kernelCryptoARIA128GCM) String() string {
type kernelCryptoARIA256GCM (line 192) | type kernelCryptoARIA256GCM struct
method String (line 200) | func (crypto *kernelCryptoARIA256GCM) String() string {
function kernelCipher (line 205) | func kernelCipher(kernel *Support, hc *badtls.RawHalfConn, cipherSuite u...
FILE: common/ktls/ktls_close.go
method Close (line 15) | func (c *Conn) Close() error {
method closeNotify (line 54) | func (c *Conn) closeNotify() error {
FILE: common/ktls/ktls_const.go
constant maxPlaintext (line 10) | maxPlaintext = 16384
constant maxCiphertext (line 11) | maxCiphertext = 16384 + 2048
constant maxCiphertextTLS13 (line 12) | maxCiphertextTLS13 = 16384 + 256
constant recordHeaderLen (line 13) | recordHeaderLen = 5
constant maxHandshake (line 14) | maxHandshake = 65536
constant maxHandshakeCertificateMsg (line 15) | maxHandshakeCertificateMsg = 262144
constant maxUselessRecords (line 16) | maxUselessRecords = 16
constant recordTypeChangeCipherSpec (line 20) | recordTypeChangeCipherSpec = 20
constant recordTypeAlert (line 21) | recordTypeAlert = 21
constant recordTypeHandshake (line 22) | recordTypeHandshake = 22
constant recordTypeApplicationData (line 23) | recordTypeApplicationData = 23
FILE: common/ktls/ktls_handshake_messages.go
function readUint8LengthPrefixed (line 13) | func readUint8LengthPrefixed(s *cryptobyte.String, out *[]byte) bool {
function readUint16LengthPrefixed (line 19) | func readUint16LengthPrefixed(s *cryptobyte.String, out *[]byte) bool {
type keyUpdateMsg (line 23) | type keyUpdateMsg struct
method marshal (line 27) | func (m *keyUpdateMsg) marshal() ([]byte, error) {
method unmarshal (line 41) | func (m *keyUpdateMsg) unmarshal(data []byte) bool {
constant typeHelloRequest (line 62) | typeHelloRequest uint8 = 0
constant typeClientHello (line 63) | typeClientHello uint8 = 1
constant typeServerHello (line 64) | typeServerHello uint8 = 2
constant typeNewSessionTicket (line 65) | typeNewSessionTicket uint8 = 4
constant typeEndOfEarlyData (line 66) | typeEndOfEarlyData uint8 = 5
constant typeEncryptedExtensions (line 67) | typeEncryptedExtensions uint8 = 8
constant typeCertificate (line 68) | typeCertificate uint8 = 11
constant typeServerKeyExchange (line 69) | typeServerKeyExchange uint8 = 12
constant typeCertificateRequest (line 70) | typeCertificateRequest uint8 = 13
constant typeServerHelloDone (line 71) | typeServerHelloDone uint8 = 14
constant typeCertificateVerify (line 72) | typeCertificateVerify uint8 = 15
constant typeClientKeyExchange (line 73) | typeClientKeyExchange uint8 = 16
constant typeFinished (line 74) | typeFinished uint8 = 20
constant typeCertificateStatus (line 75) | typeCertificateStatus uint8 = 22
constant typeKeyUpdate (line 76) | typeKeyUpdate uint8 = 24
constant typeCompressedCertificate (line 77) | typeCompressedCertificate uint8 = 25
constant typeMessageHash (line 78) | typeMessageHash uint8 = 254
constant extensionServerName (line 83) | extensionServerName uint16 = 0
constant extensionStatusRequest (line 84) | extensionStatusRequest uint16 = 5
constant extensionSupportedCurves (line 85) | extensionSupportedCurves uint16 = 10
constant extensionSupportedPoints (line 86) | extensionSupportedPoints uint16 = 11
constant extensionSignatureAlgorithms (line 87) | extensionSignatureAlgorithms uint16 = 13
constant extensionALPN (line 88) | extensionALPN uint16 = 16
constant extensionSCT (line 89) | extensionSCT uint16 = 18
constant extensionPadding (line 90) | extensionPadding uint16 = 21
constant extensionExtendedMasterSecret (line 91) | extensionExtendedMasterSecret uint16 = 23
constant extensionCompressCertificate (line 92) | extensionCompressCertificate uint16 = 27
constant extensionSessionTicket (line 93) | extensionSessionTicket uint16 = 35
constant extensionPreSharedKey (line 94) | extensionPreSharedKey uint16 = 41
constant extensionEarlyData (line 95) | extensionEarlyData uint16 = 42
constant extensionSupportedVersions (line 96) | extensionSupportedVersions uint16 = 43
constant extensionCookie (line 97) | extensionCookie uint16 = 44
constant extensionPSKModes (line 98) | extensionPSKModes uint16 = 45
constant extensionCertificateAuthorities (line 99) | extensionCertificateAuthorities uint16 = 47
constant extensionSignatureAlgorithmsCert (line 100) | extensionSignatureAlgorithmsCert uint16 = 50
constant extensionKeyShare (line 101) | extensionKeyShare uint16 = 51
constant extensionQUICTransportParameters (line 102) | extensionQUICTransportParameters uint16 = 57
constant extensionALPS (line 103) | extensionALPS uint16 = 17513
constant extensionRenegotiationInfo (line 104) | extensionRenegotiationInfo uint16 = 0xff01
constant extensionECHOuterExtensions (line 105) | extensionECHOuterExtensions uint16 = 0xfd00
constant extensionEncryptedClientHello (line 106) | extensionEncryptedClientHello uint16 = 0xfe0d
type handshakeMessage (line 109) | type handshakeMessage interface
type newSessionTicketMsgTLS13 (line 113) | type newSessionTicketMsgTLS13 struct
method marshal (line 121) | func (m *newSessionTicketMsgTLS13) marshal() ([]byte, error) {
method unmarshal (line 147) | func (m *newSessionTicketMsgTLS13) unmarshal(data []byte) bool {
FILE: common/ktls/ktls_key_update.go
method handlePostHandshakeMessage (line 19) | func (c *Conn) handlePostHandshakeMessage() error {
method handleKeyUpdate (line 49) | func (c *Conn) handleKeyUpdate(keyUpdate *keyUpdateMsg) error {
method readHandshakeBytes (line 103) | func (c *Conn) readHandshakeBytes(n int) error {
method readHandshake (line 115) | func (c *Conn) readHandshake(transcript io.Writer) (any, error) {
method unmarshalHandshakeMessage (line 144) | func (c *Conn) unmarshalHandshakeMessage(data []byte, transcript io.Writ...
FILE: common/ktls/ktls_linux.go
constant TLS_TX (line 26) | TLS_TX = 1
constant TLS_RX (line 27) | TLS_RX = 2
constant TLS_TX_ZEROCOPY_RO (line 28) | TLS_TX_ZEROCOPY_RO = 3
constant TLS_RX_EXPECT_NO_PAD (line 29) | TLS_RX_EXPECT_NO_PAD = 4
constant TLS_SET_RECORD_TYPE (line 31) | TLS_SET_RECORD_TYPE = 1
constant TLS_GET_RECORD_TYPE (line 32) | TLS_GET_RECORD_TYPE = 2
type Support (line 35) | type Support struct
function Load (line 114) | func Load() error {
method setupKernel (line 125) | func (c *Conn) setupKernel(txOffload, rxOffload bool) error {
method resetupTX (line 193) | func (c *Conn) resetupTX() (func() error, error) {
method resetupRX (line 215) | func (c *Conn) resetupRX() error {
method readKernelRecord (line 235) | func (c *Conn) readKernelRecord() (uint8, []byte, error) {
method writeKernelRecord (line 290) | func (c *Conn) writeKernelRecord(typ uint16, data []byte) (int, error) {
function recvmsg (line 326) | func recvmsg(fd int, msg *unix.Msghdr, flags int) (n int, err error)
function sendmsg (line 329) | func sendmsg(fd int, msg *unix.Msghdr, flags int) (n int, err error)
FILE: common/ktls/ktls_prf.go
function cipherSuiteByID (line 12) | func cipherSuiteByID(id uint16) unsafe.Pointer
function keysFromMasterSecret (line 15) | func keysFromMasterSecret(version uint16, suite unsafe.Pointer, masterSe...
function cipherSuiteTLS13ByID (line 18) | func cipherSuiteTLS13ByID(id uint16) unsafe.Pointer
function nextTrafficSecret (line 21) | func nextTrafficSecret(cs unsafe.Pointer, trafficSecret []byte) []byte
function trafficKey (line 24) | func trafficKey(cs unsafe.Pointer, trafficSecret []byte) (key, iv []byte)
FILE: common/ktls/ktls_read.go
method Read (line 18) | func (c *Conn) Read(b []byte) (int, error) {
method readRecord (line 62) | func (c *Conn) readRecord() error {
method readRawRecord (line 170) | func (c *Conn) readRawRecord() (typ uint8, data []byte, err error) {
method retryReadRecord (line 241) | func (c *Conn) retryReadRecord( /*expectChangeCipherSpec bool*/ ) error {
type atLeastReader (line 253) | type atLeastReader struct
method Read (line 258) | func (r *atLeastReader) Read(p []byte) (int, error) {
method readFromUntil (line 275) | func (c *Conn) readFromUntil(r io.Reader, n int) error {
method newRecordHeaderError (line 288) | func (c *Conn) newRecordHeaderError(conn net.Conn, msg string) (err tls....
FILE: common/ktls/ktls_read_wait.go
method InitializeReadWaiter (line 14) | func (c *Conn) InitializeReadWaiter(options N.ReadWaitOptions) (needCopy...
method WaitReadBuffer (line 19) | func (c *Conn) WaitReadBuffer() (buffer *buf.Buffer, err error) {
FILE: common/ktls/ktls_stub_nolinkname.go
function NewConn (line 13) | func NewConn(ctx context.Context, logger logger.ContextLogger, conn aTLS...
FILE: common/ktls/ktls_stub_nonlinux.go
function NewConn (line 13) | func NewConn(ctx context.Context, logger logger.ContextLogger, conn aTLS...
FILE: common/ktls/ktls_stub_oldgo.go
function NewConn (line 13) | func NewConn(ctx context.Context, logger logger.ContextLogger, conn aTLS...
FILE: common/ktls/ktls_write.go
method Write (line 16) | func (c *Conn) Write(b []byte) (int, error) {
method writeRecordLocked (line 76) | func (c *Conn) writeRecordLocked(typ uint16, data []byte) (n int, err er...
FILE: common/listener/listener.go
type Listener (line 23) | type Listener struct
method Start (line 80) | func (l *Listener) Start() error {
method Close (line 122) | func (l *Listener) Close() error {
method TCPListener (line 134) | func (l *Listener) TCPListener() net.Listener {
method UDPConn (line 138) | func (l *Listener) UDPConn() *net.UDPConn {
method ListenOptions (line 142) | func (l *Listener) ListenOptions() option.ListenOptions {
type Options (line 46) | type Options struct
function New (line 61) | func New(
function ListenNetworkNamespace (line 146) | func ListenNetworkNamespace[T any](nameOrPath string, block func() (T, e...
FILE: common/listener/listener_tcp.go
method ListenTCP (line 23) | func (l *Listener) ListenTCP() (net.Listener, error) {
method loopTCPIn (line 85) | func (l *Listener) loopTCPIn() {
FILE: common/listener/listener_udp.go
constant udpOutputBatchSize (line 22) | udpOutputBatchSize = 128
method ListenUDP (line 24) | func (l *Listener) ListenUDP() (net.PacketConn, error) {
method DialContext (line 64) | func (l *Listener) DialContext(dialer net.Dialer, ctx context.Context, n...
method ListenPacket (line 79) | func (l *Listener) ListenPacket(listenConfig net.ListenConfig, ctx conte...
method UDPAddr (line 94) | func (l *Listener) UDPAddr() M.Socksaddr {
method PacketWriter (line 98) | func (l *Listener) PacketWriter() N.PacketWriter {
method loopUDPIn (line 102) | func (l *Listener) loopUDPIn() {
method loopUDPInBatch (line 168) | func (l *Listener) loopUDPInBatch(handler adapter.PacketBatchHandler, re...
method loopUDPOut (line 188) | func (l *Listener) loopUDPOut() {
method releasePacketOutbound (line 231) | func (l *Listener) releasePacketOutbound() {
type packetWriter (line 243) | type packetWriter
method WritePacket (line 245) | func (w *packetWriter) WritePacket(buffer *buf.Buffer, destination M.S...
method WritePacketBatch (line 263) | func (w *packetWriter) WritePacketBatch(buffers []*buf.Buffer, destina...
method WriteIsThreadUnsafe (line 288) | func (w *packetWriter) WriteIsThreadUnsafe() {
FILE: common/mux/client.go
function NewClientWithOptions (line 19) | func NewClientWithOptions(dialer N.Dialer, logger logger.Logger, options...
type clientDialer (line 49) | type clientDialer struct
method DialContext (line 53) | func (d *clientDialer) DialContext(ctx context.Context, network string...
method ListenPacket (line 57) | func (d *clientDialer) ListenPacket(ctx context.Context, destination M...
FILE: common/mux/router.go
type Router (line 17) | type Router struct
method RouteConnection (line 56) | func (r *Router) RouteConnection(ctx context.Context, conn net.Conn, m...
method RoutePacketConnection (line 66) | func (r *Router) RoutePacketConnection(ctx context.Context, conn N.Pac...
method RouteConnectionEx (line 70) | func (r *Router) RouteConnectionEx(ctx context.Context, conn net.Conn,...
method RoutePacketConnectionEx (line 78) | func (r *Router) RoutePacketConnectionEx(ctx context.Context, conn N.P...
function NewRouterWithOptions (line 22) | func NewRouterWithOptions(router adapter.ConnectionRouterEx, logger logg...
FILE: common/networkquality/http.go
function FormatBitrate (line 17) | func FormatBitrate(bps int64) string {
function NewHTTPClient (line 30) | func NewHTTPClient(dialer N.Dialer) *http.Client {
function baseTransportFromClient (line 43) | func baseTransportFromClient(client *http.Client) (*http.Transport, erro...
function newMeasurementClient (line 57) | func newMeasurementClient(
type MeasurementClientFactory (line 105) | type MeasurementClientFactory
function defaultMeasurementClientFactory (line 113) | func defaultMeasurementClientFactory(baseClient *http.Client) Measuremen...
function NewOptionalHTTP3Factory (line 119) | func NewOptionalHTTP3Factory(dialer N.Dialer, useHTTP3 bool) (Measuremen...
function rewriteDialAddress (line 126) | func rewriteDialAddress(addr string, connectEndpoint string) string {
FILE: common/networkquality/http3.go
function NewHTTP3MeasurementClientFactory (line 18) | func NewHTTP3MeasurementClientFactory(dialer N.Dialer) (MeasurementClien...
FILE: common/networkquality/http3_stub.go
function NewHTTP3MeasurementClientFactory (line 10) | func NewHTTP3MeasurementClientFactory(dialer N.Dialer) (MeasurementClien...
FILE: common/networkquality/networkquality.go
constant DefaultConfigURL (line 25) | DefaultConfigURL = "https://mensura.cdn-apple.com/api/v1/gm/config"
type Config (line 27) | type Config struct
type URLs (line 33) | type URLs struct
method smallDownloadURL (line 42) | func (u *URLs) smallDownloadURL() string {
method largeDownloadURL (line 49) | func (u *URLs) largeDownloadURL() string {
method uploadURL (line 56) | func (u *URLs) uploadURL() string {
type Accuracy (line 63) | type Accuracy
method String (line 71) | func (a Accuracy) String() string {
constant AccuracyLow (line 66) | AccuracyLow Accuracy = 0
constant AccuracyMedium (line 67) | AccuracyMedium Accuracy = 1
constant AccuracyHigh (line 68) | AccuracyHigh Accuracy = 2
type Result (line 82) | type Result struct
type Progress (line 94) | type Progress struct
type Phase (line 108) | type Phase
constant PhaseIdle (line 111) | PhaseIdle Phase = 0
constant PhaseDownload (line 112) | PhaseDownload Phase = 1
constant PhaseUpload (line 113) | PhaseUpload Phase = 2
constant PhaseDone (line 114) | PhaseDone Phase = 3
type Options (line 117) | type Options struct
constant DefaultMaxRuntime (line 127) | DefaultMaxRuntime = 20 * time.Second
type measurementSettings (line 129) | type measurementSettings struct
type resolvedConfig (line 159) | type resolvedConfig struct
type directionPlan (line 166) | type directionPlan struct
type probeTrace (line 173) | type probeTrace struct
type probeMeasurement (line 185) | type probeMeasurement struct
type probeRound (line 195) | type probeRound struct
method responsivenessLatency (line 203) | func (p probeRound) responsivenessLatency() float64 {
constant maxConsecutiveErrors (line 220) | maxConsecutiveErrors = 3
type loadConnection (line 222) | type loadConnection struct
method run (line 230) | func (c *loadConnection) run(ctx context.Context, onError func(error)) {
type intervalThroughput (line 266) | type intervalThroughput struct
type intervalWindow (line 271) | type intervalWindow struct
type stabilityTracker (line 276) | type stabilityTracker struct
method add (line 283) | func (s *stabilityTracker) add(value float64) bool {
method ready (line 298) | func (s *stabilityTracker) ready() bool {
method accuracy (line 302) | func (s *stabilityTracker) accuracy() Accuracy {
method stable (line 312) | func (s *stabilityTracker) stable() bool {
type directionMeasurement (line 323) | type directionMeasurement struct
type directionRunner (line 330) | type directionRunner struct
method fail (line 364) | func (r *directionRunner) fail(err error) {
method onConnectionFailed (line 376) | func (r *directionRunner) onConnectionFailed(err error) {
method addConnection (line 390) | func (r *directionRunner) addConnection(ctx context.Context) error {
method connectionCount (line 418) | func (r *directionRunner) connectionCount() int {
method pickReadyConnection (line 424) | func (r *directionRunner) pickReadyConnection() *loadConnection {
method startProber (line 439) | func (r *directionRunner) startProber(ctx context.Context) {
method runProbeRound (line 461) | func (r *directionRunner) runProbeRound(ctx context.Context, selfClien...
method probeInterval (line 480) | func (r *directionRunner) probeInterval() time.Duration {
method recordProbeRound (line 498) | func (r *directionRunner) recordProbeRound(round probeRound) {
method swapIntervalProbeValues (line 508) | func (r *directionRunner) swapIntervalProbeValues() []float64 {
method setResponsivenessWindow (line 516) | func (r *directionRunner) setResponsivenessWindow(currentInterval int) {
method recordThroughput (line 523) | func (r *directionRunner) recordThroughput(interval int, bps float64) {
method setThroughputWindow (line 529) | func (r *directionRunner) setThroughputWindow(currentInterval int) {
method finalRPM (line 536) | func (r *directionRunner) finalRPM() int32 {
method finalCapacity (line 554) | func (r *directionRunner) finalCapacity(totalDuration time.Duration) i...
method wait (line 579) | func (r *directionRunner) wait() {
function newDirectionRunner (line 355) | func newDirectionRunner(factory MeasurementClientFactory, plan direction...
function Run (line 583) | func Run(options Options) (*Result, error) {
function normalizeMaxRuntime (line 680) | func normalizeMaxRuntime(maxRuntime time.Duration) (time.Duration, error) {
function measureSerial (line 690) | func measureSerial(
function measureParallel (line 744) | func measureParallel(
function resolveConfigURL (line 843) | func resolveConfigURL(rawURL string) string {
function fetchConfig (line 862) | func fetchConfig(ctx context.Context, client *http.Client, configURL str...
function validateConfig (line 882) | func validateConfig(config *Config) (*resolvedConfig, error) {
function measureIdleLatency (line 931) | func measureIdleLatency(ctx context.Context, factory MeasurementClientFa...
function measureDirection (line 958) | func measureDirection(
function splitRuntimeBudget (line 1076) | func splitRuntimeBudget(total time.Duration, directions int) (time.Durat...
function collectProbeRound (line 1085) | func collectProbeRound(ctx context.Context, foreignClient *http.Client, ...
function runProbe (line 1117) | func runProbe(ctx context.Context, client *http.Client, rawURL string, e...
function runDownloadRequest (line 1213) | func runDownloadRequest(ctx context.Context, client *http.Client, rawURL...
function runUploadRequest (line 1237) | func runUploadRequest(ctx context.Context, client *http.Client, rawURL s...
function newRequest (line 1265) | func newRequest(ctx context.Context, method string, rawURL string, body ...
function closeMeasurementClient (line 1274) | func closeMeasurementClient(client *http.Client) {
function validateResponse (line 1284) | func validateResponse(resp *http.Response) error {
function calculateRPM (line 1294) | func calculateRPM(rounds []probeRound) int32 {
function tlsHandshakeRoundTrips (line 1339) | func tlsHandshakeRoundTrips(version uint16) int {
function durationMillis (line 1348) | func durationMillis(value time.Duration) float64 {
function upperTrimmedMean (line 1352) | func upperTrimmedMean(values []float64, trimPercent int) float64 {
function upperTrimFloat64s (line 1360) | func upperTrimFloat64s(values []float64, trimPercent int) []float64 {
function meanFloat64s (line 1376) | func meanFloat64s(values []float64) float64 {
function stdDevFloat64s (line 1387) | func stdDevFloat64s(values []float64) float64 {
type uploadBody (line 1400) | type uploadBody struct
method Read (line 1406) | func (u *uploadBody) Read(p []byte) (int, error) {
method Close (line 1418) | func (u *uploadBody) Close() error {
FILE: common/pipelistener/listener.go
type Listener (line 10) | type Listener struct
method Serve (line 22) | func (l *Listener) Serve(conn net.Conn) {
method Accept (line 26) | func (l *Listener) Accept() (net.Conn, error) {
method Close (line 35) | func (l *Listener) Close() error {
method Addr (line 45) | func (l *Listener) Addr() net.Addr {
function New (line 15) | func New(channelSize int) *Listener {
type addr (line 49) | type addr struct
method Network (line 51) | func (a addr) Network() string {
method String (line 55) | func (a addr) String() string {
FILE: common/process/searcher.go
type Searcher (line 15) | type Searcher interface
type Config (line 22) | type Config struct
function FindProcessInfo (line 27) | func FindProcessInfo(searcher Searcher, ctx context.Context, network str...
FILE: common/process/searcher_android.go
type androidSearcher (line 14) | type androidSearcher struct
method Close (line 22) | func (s *androidSearcher) Close() error {
method FindProcessInfo (line 26) | func (s *androidSearcher) FindProcessInfo(ctx context.Context, network...
function NewSearcher (line 18) | func NewSearcher(config Config) (Searcher, error) {
FILE: common/process/searcher_darwin.go
type darwinSearcher (line 17) | type darwinSearcher struct
method Close (line 23) | func (d *darwinSearcher) Close() error {
method FindProcessInfo (line 27) | func (d *darwinSearcher) FindProcessInfo(ctx context.Context, network ...
function NewSearcher (line 19) | func NewSearcher(_ Config) (Searcher, error) {
FILE: common/process/searcher_darwin_shared.go
constant darwinSnapshotTTL (line 21) | darwinSnapshotTTL = 200 * time.Millisecond
constant darwinXinpgenSize (line 23) | darwinXinpgenSize = 24
constant darwinXsocketOffset (line 24) | darwinXsocketOffset = 104
constant darwinXinpcbForeignPort (line 25) | darwinXinpcbForeignPort = 16
constant darwinXinpcbLocalPort (line 26) | darwinXinpcbLocalPort = 18
constant darwinXinpcbVFlag (line 27) | darwinXinpcbVFlag = 44
constant darwinXinpcbForeignAddr (line 28) | darwinXinpcbForeignAddr = 48
constant darwinXinpcbLocalAddr (line 29) | darwinXinpcbLocalAddr = 64
constant darwinXinpcbIPv4Addr (line 30) | darwinXinpcbIPv4Addr = 12
constant darwinXsocketUID (line 31) | darwinXsocketUID = 64
constant darwinXsocketLastPID (line 32) | darwinXsocketLastPID = 68
constant darwinTCPExtraStructSize (line 33) | darwinTCPExtraStructSize = 208
type darwinConnectionEntry (line 36) | type darwinConnectionEntry struct
type darwinConnectionMatchKind (line 45) | type darwinConnectionMatchKind
constant darwinConnectionMatchExact (line 48) | darwinConnectionMatchExact darwinConnectionMatchKind = iota
constant darwinConnectionMatchLocalFallback (line 49) | darwinConnectionMatchLocalFallback
constant darwinConnectionMatchWildcardFallback (line 50) | darwinConnectionMatchWildcardFallback
type darwinSnapshot (line 53) | type darwinSnapshot struct
type darwinConnectionFinder (line 58) | type darwinConnectionFinder struct
method find (line 79) | func (f *darwinConnectionFinder) find(network string, source netip.Add...
method loadSnapshot (line 122) | func (f *darwinConnectionFinder) loadSnapshot(network string, forceRef...
function newDarwinConnectionFinder (line 67) | func newDarwinConnectionFinder(ttl time.Duration) *darwinConnectionFinder {
function FindDarwinConnectionOwner (line 75) | func FindDarwinConnectionOwner(network string, source netip.AddrPort, de...
function buildDarwinSnapshot (line 138) | func buildDarwinSnapshot(network string) (darwinSnapshot, error) {
function darwinSnapshotSettings (line 153) | func darwinSnapshotSettings(network string) (string, int, error) {
function parseDarwinSnapshot (line 165) | func parseDarwinSnapshot(buf []byte, itemSize int) []darwinConnectionEnt...
function parseDarwinConnectionEntry (line 178) | func parseDarwinConnectionEntry(inp []byte, so []byte) (darwinConnection...
function matchDarwinConnectionEntry (line 203) | func matchDarwinConnectionEntry(entries []darwinConnectionEntry, network...
function normalizeDarwinAddrPort (line 243) | func normalizeDarwinAddrPort(addrPort netip.AddrPort) netip.AddrPort {
function getExecPathFromPID (line 250) | func getExecPathFromPID(pid uint32) (string, error) {
FILE: common/process/searcher_linux.go
type linuxSearcher (line 19) | type linuxSearcher struct
method Close (line 38) | func (s *linuxSearcher) Close() error {
method FindProcessInfo (line 49) | func (s *linuxSearcher) FindProcessInfo(ctx context.Context, network s...
method resolveSocketByNetlink (line 66) | func (s *linuxSearcher) resolveSocketByNetlink(network string, source ...
function NewSearcher (line 25) | func NewSearcher(config Config) (Searcher, error) {
FILE: common/process/searcher_linux_shared.go
constant sizeOfSocketDiagRequestData (line 26) | sizeOfSocketDiagRequestData = 56
constant sizeOfSocketDiagRequest (line 27) | sizeOfSocketDiagRequest = syscall.SizeofNlMsghdr + sizeOfSocketDiagR...
constant socketDiagResponseMinSize (line 28) | socketDiagResponseMinSize = 72
constant socketDiagByFamily (line 29) | socketDiagByFamily = 20
constant pathProc (line 30) | pathProc = "/proc"
type socketDiagConn (line 33) | type socketDiagConn struct
method Close (line 111) | func (c *socketDiagConn) Close() error {
method query (line 117) | func (c *socketDiagConn) query(source netip.AddrPort, destination neti...
method ensureOpenLocked (line 147) | func (c *socketDiagConn) ensureOpenLocked() error {
method closeLocked (line 184) | func (c *socketDiagConn) closeLocked() error {
type uidProcessPathCache (line 40) | type uidProcessPathCache struct
method findProcessPath (line 93) | func (c *uidProcessPathCache) findProcessPath(targetInode, uid uint32)...
type uidProcessPaths (line 44) | type uidProcessPaths struct
function newSocketDiagConn (line 48) | func newSocketDiagConn(family, protocol uint8) *socketDiagConn {
function socketDiagConnIndex (line 56) | func socketDiagConnIndex(family, protocol uint8) int {
function socketDiagSettings (line 67) | func socketDiagSettings(network string, source netip.AddrPort) (family, ...
function newUIDProcessPathCache (line 87) | func newUIDProcessPathCache(ttl time.Duration) *uidProcessPathCache {
function querySocketDiagOnce (line 138) | func querySocketDiagOnce(family, protocol uint8, source netip.AddrPort) ...
function openSocketDiag (line 159) | func openSocketDiag() (int, error) {
function packSocketDiagRequest (line 193) | func packSocketDiagRequest(family, protocol byte, source netip.AddrPort,...
function querySocketDiag (line 237) | func querySocketDiag(fd int, request []byte) (inode, uid uint32, err err...
function unpackSocketDiagMessages (line 254) | func unpackSocketDiagMessages(messages []syscall.NetlinkMessage) (inode,...
function unpackSocketDiagResponse (line 274) | func unpackSocketDiagResponse(msg *syscall.NetlinkMessage) (inode, uid u...
function unpackSocketDiagError (line 283) | func unpackSocketDiagError(msg *syscall.NetlinkMessage) error {
function shouldRetrySocketDiag (line 303) | func shouldRetrySocketDiag(err error) bool {
function buildProcessPathByUIDCache (line 307) | func buildProcessPathByUIDCache(uid uint32) (map[uint32]string, error) {
function isIgnorableProcError (line 358) | func isIgnorableProcError(err error) bool {
function parseSocketInode (line 362) | func parseSocketInode(link []byte) (uint32, bool) {
function isPid (line 380) | func isPid(s string) bool {
FILE: common/process/searcher_linux_shared_test.go
function TestQuerySocketDiagUDPExact (line 16) | func TestQuerySocketDiagUDPExact(t *testing.T) {
function addrPortFromUDPAddr (line 50) | func addrPortFromUDPAddr(t *testing.T, addr net.Addr) netip.AddrPort {
FILE: common/process/searcher_stub.go
function NewSearcher (line 9) | func NewSearcher(_ Config) (Searcher, error) {
FILE: common/process/searcher_windows.go
type windowsSearcher (line 17) | type windowsSearcher struct
method Close (line 31) | func (s *windowsSearcher) Close() error {
method FindProcessInfo (line 35) | func (s *windowsSearcher) FindProcessInfo(ctx context.Context, network...
function NewSearcher (line 19) | func NewSearcher(_ Config) (Searcher, error) {
function initWin32API (line 27) | func initWin32API() error {
function getProcessPath (line 47) | func getProcessPath(pid uint32) (string, error) {
FILE: common/proxybridge/bridge.go
type Bridge (line 22) | type Bridge struct
method Port (line 62) | func (b *Bridge) Port() uint16 {
method Username (line 66) | func (b *Bridge) Username() string {
method Password (line 70) | func (b *Bridge) Password() string {
method Close (line 74) | func (b *Bridge) Close() error {
method acceptLoop (line 78) | func (b *Bridge) acceptLoop() {
method NewConnectionEx (line 99) | func (b *Bridge) NewConnectionEx(ctx context.Context, conn net.Conn, s...
method NewPacketConnectionEx (line 108) | func (b *Bridge) NewPacketConnectionEx(ctx context.Context, conn N.Pac...
function New (line 34) | func New(ctx context.Context, logger logger.ContextLogger, tag string, d...
function randomHex (line 56) | func randomHex(size int) string {
FILE: common/redir/redir_darwin.go
constant PF_OUT (line 13) | PF_OUT = 0x2
constant DIOCNATLOOK (line 14) | DIOCNATLOOK = 0xc0544417
function GetOriginalDestination (line 17) | func GetOriginalDestination(conn net.Conn) (destination netip.AddrPort, ...
FILE: common/redir/redir_linux.go
function GetOriginalDestination (line 15) | func GetOriginalDestination(conn net.Conn) (destination netip.AddrPort, ...
FILE: common/redir/redir_other.go
function GetOriginalDestination (line 11) | func GetOriginalDestination(conn net.Conn) (destination netip.AddrPort, ...
FILE: common/redir/tproxy_linux.go
function TProxy (line 15) | func TProxy(fd uintptr, isIPv6 bool, isUDP bool) error {
function TProxyWriteBack (line 34) | func TProxyWriteBack() control.Func {
function GetOriginalDestinationFromOOB (line 46) | func GetOriginalDestinationFromOOB(oob []byte) (netip.AddrPort, error) {
FILE: common/redir/tproxy_other.go
function TProxy (line 12) | func TProxy(fd uintptr, isIPv6 bool, isUDP bool) error {
function TProxyWriteBack (line 16) | func TProxyWriteBack() control.Func {
function GetOriginalDestinationFromOOB (line 20) | func GetOriginalDestinationFromOOB(oob []byte) (netip.AddrPort, error) {
FILE: common/schannel/schannel_windows.go
constant clientCredentialFlags (line 17) | clientCredentialFlags = schCredManualCredValidation | schCredNoDefaultCr...
function CheckPlatform (line 30) | func CheckPlatform() error {
type clientCredentialKey (line 34) | type clientCredentialKey struct
type clientCredential (line 39) | type clientCredential struct
method acquire (line 66) | func (c *clientCredential) acquire() error {
function cachedClientCredential (line 49) | func cachedClientCredential(minVersion, maxVersion uint16) (*clientCrede...
type ClientContext (line 98) | type ClientContext struct
method Close (line 147) | func (c *ClientContext) Close() {
method Step (line 171) | func (c *ClientContext) Step(input []byte) (StepResult, error) {
method StreamSizes (line 224) | func (c *ClientContext) StreamSizes() (header, trailer, maxMessage uin...
method Encrypt (line 237) | func (c *ClientContext) Encrypt(header, trailer uint32, plaintext []by...
method Decrypt (line 283) | func (c *ClientContext) Decrypt(input []byte) (DecryptResult, error) {
method PostHandshake (line 321) | func (c *ClientContext) PostHandshake(input []byte) (StepResult, error) {
method ApplicationProtocol (line 388) | func (c *ClientContext) ApplicationProtocol() (string, error) {
method ConnectionInfo (line 407) | func (c *ClientContext) ConnectionInfo() (version, cipherSuite uint16,...
method RemoteCertificateChain (line 440) | func (c *ClientContext) RemoteCertificateChain() ([][]byte, error) {
method runInitializeSecurityContext (line 470) | func (c *ClientContext) runInitializeSecurityContext(inputDesc *secBuf...
function NewClientContext (line 115) | func NewClientContext(minVersion, maxVersion uint16, serverName string, ...
type StepResult (line 158) | type StepResult struct
type DecryptResult (line 265) | type DecryptResult struct
function parseDecryptResult (line 353) | func parseDecryptResult(input []byte, bufs []secBuffer, renegotiate bool...
function cipherSuiteID (line 424) | func cipherSuiteID(name string) uint16 {
constant handshakeContextReq (line 458) | handshakeContextReq = iscReqSequenceDetect |
function consumedFromExtra (line 534) | func consumedFromExtra(extraBuf *secBuffer, inputLen int) (int, error) {
function disabledProtocolsMask (line 542) | func disabledProtocolsMask(minVersion, maxVersion uint16) uint32 {
function sspProtocolToTLSVersion (line 575) | func sspProtocolToTLSVersion(sp uint32) uint16 {
function encodeAlpnBuffer (line 589) | func encodeAlpnBuffer(protocols []string) ([]byte, error) {
function unsafeSliceCopy (line 615) | func unsafeSliceCopy(ptr *byte, size int) []byte {
function certContextDER (line 624) | func certContextDER(ctx *windows.CertContext) []byte {
function buildCertChainDER (line 633) | func buildCertChainDER(leaf *windows.CertContext) ([][]byte, error) {
function extractCertChainDER (line 645) | func extractCertChainDER(chainCtx *windows.CertChainContext) ([][]byte, ...
function isSelfSignedCertContext (line 674) | func isSelfSignedCertContext(ctx *windows.CertContext) bool {
function certNameBlobBytes (line 684) | func certNameBlobBytes(blob windows.CertNameBlob) []byte {
function sspiError (line 691) | func sspiError(where string, status syscall.Errno) error {
function formatStatus (line 713) | func formatStatus(status syscall.Errno) string {
FILE: common/schannel/schannel_windows_test.go
function TestExtractCertChainDERExcludesSelfSignedRoot (line 14) | func TestExtractCertChainDERExcludesSelfSignedRoot(t *testing.T) {
function TestExtractCertChainDERKeepsLastIntermediateWithoutRoot (line 35) | func TestExtractCertChainDERKeepsLastIntermediateWithoutRoot(t *testing....
function TestDisabledProtocolsMask (line 52) | func TestDisabledProtocolsMask(t *testing.T) {
function TestClientCredentialCacheReusesVersionRange (line 86) | func TestClientCredentialCacheReusesVersionRange(t *testing.T) {
function TestParseDecryptResultKeepsRenegotiateExtraToken (line 117) | func TestParseDecryptResultKeepsRenegotiateExtraToken(t *testing.T) {
function TestParseDecryptResultKeepsRenegotiateWholeBufferWithoutExtra (line 136) | func TestParseDecryptResultKeepsRenegotiateWholeBufferWithoutExtra(t *te...
function certChainContextForTest (line 155) | func certChainContextForTest(certs ...*windows.CertContext) *windows.Cer...
function certContextForTest (line 171) | func certContextForTest(der, issuer, subject []byte) *windows.CertContext {
function certNameBlobForTest (line 183) | func certNameBlobForTest(value []byte) windows.CertNameBlob {
FILE: common/schannel/syscall_windows.go
function sspiCompleteAuthToken (line 24) | func sspiCompleteAuthToken(context *secHandle, token *secBufferDesc) (re...
FILE: common/schannel/types_windows.go
constant unispNameW (line 10) | unispNameW = "Microsoft Unified Security Protocol Provider"
constant schCredentialsVersion (line 12) | schCredentialsVersion = 5
constant secPkgCredOutbound (line 14) | secPkgCredOutbound = 2
constant iscReqSequenceDetect (line 16) | iscReqSequenceDetect = 0x00000008
constant iscReqReplayDetect (line 17) | iscReqReplayDetect = 0x00000004
constant iscReqConfidentiality (line 18) | iscReqConfidentiality = 0x00000010
constant iscReqAllocateMemory (line 19) | iscReqAllocateMemory = 0x00000100
constant iscReqStream (line 20) | iscReqStream = 0x00008000
constant iscReqUseSuppliedCreds (line 21) | iscReqUseSuppliedCreds = 0x00000080
constant iscReqManualCredValidation (line 22) | iscReqManualCredValidation = 0x00080000
constant iscReqExtendedError (line 23) | iscReqExtendedError = 0x00004000
constant secbufferEmpty (line 25) | secbufferEmpty = 0
constant secbufferData (line 26) | secbufferData = 1
constant secbufferToken (line 27) | secbufferToken = 2
constant secbufferExtra (line 28) | secbufferExtra = 5
constant secbufferStreamTrailer (line 29) | secbufferStreamTrailer = 6
constant secbufferStreamHeader (line 30) | secbufferStreamHeader = 7
constant secbufferApplicationProtocols (line 31) | secbufferApplicationProtocols = 18
constant secbufferVersion (line 32) | secbufferVersion = 0
constant secApplicationProtocolNegotiationExtALPN (line 34) | secApplicationProtocolNegotiationExtALPN = 2
constant secApplicationProtocolNegotiationStatusSuccess (line 36) | secApplicationProtocolNegotiationStatusSuccess = 1
constant schCredManualCredValidation (line 38) | schCredManualCredValidation = 0x00000008
constant schCredNoDefaultCreds (line 39) | schCredNoDefaultCreds = 0x00000010
constant schUseStrongCrypto (line 40) | schUseStrongCrypto = 0x00400000
constant spProtTLS10Client (line 42) | spProtTLS10Client = 0x00000080
constant spProtTLS11Client (line 43) | spProtTLS11Client = 0x00000200
constant spProtTLS12Client (line 44) | spProtTLS12Client = 0x00000800
constant spProtTLS13Client (line 45) | spProtTLS13Client = 0x00002000
constant spProtAllTLSClients (line 47) | spProtAllTLSClients = spProtTLS10Client | spProtTLS11Client | spProtTLS1...
constant secpkgAttrStreamSizes (line 49) | secpkgAttrStreamSizes = 4
constant secpkgAttrConnectionInfo (line 50) | secpkgAttrConnectionInfo = 0x5A
constant secpkgAttrApplicationProtocol (line 51) | secpkgAttrApplicationProtocol = 0x23
constant secpkgAttrCipherInfo (line 52) | secpkgAttrCipherInfo = 0x64
constant secpkgAttrRemoteCertContext (line 53) | secpkgAttrRemoteCertContext = 0x53
constant secEOK (line 57) | secEOK = syscall.Errno(windows.SEC_E_OK)
constant secICompleteNeeded (line 58) | secICompleteNeeded = syscall.Errno(windows.SEC_I_COMPLETE_NEE...
constant secICompleteAndContinue (line 59) | secICompleteAndContinue = syscall.Errno(windows.SEC_I_COMPLETE_AND...
constant secIContinueNeeded (line 60) | secIContinueNeeded = syscall.Errno(windows.SEC_I_CONTINUE_NEE...
constant secIContextExpired (line 61) | secIContextExpired = syscall.Errno(windows.SEC_I_CONTEXT_EXPI...
constant secIRenegotiate (line 62) | secIRenegotiate = syscall.Errno(windows.SEC_I_RENEGOTIATE)
constant secEIncompleteMessage (line 63) | secEIncompleteMessage = syscall.Errno(windows.SEC_E_INCOMPLETE_M...
constant secEIncompleteCreds (line 64) | secEIncompleteCreds = syscall.Errno(windows.SEC_E_INCOMPLETE_C...
constant secEBufferTooSmall (line 65) | secEBufferTooSmall = syscall.Errno(windows.SEC_E_BUFFER_TOO_S...
constant secEMessageAltered (line 66) | secEMessageAltered = syscall.Errno(windows.SEC_E_MESSAGE_ALTE...
constant secEContextExpired (line 67) | secEContextExpired = syscall.Errno(windows.SEC_E_CONTEXT_EXPI...
constant secEUnsupportedFunc (line 68) | secEUnsupportedFunc = syscall.Errno(windows.SEC_E_UNSUPPORTED_...
constant secEInvalidToken (line 69) | secEInvalidToken = syscall.Errno(windows.SEC_E_INVALID_TOKEN)
constant secELogonDenied (line 70) | secELogonDenied = syscall.Errno(windows.SEC_E_LOGON_DENIED)
constant secEIllegalMessage (line 71) | secEIllegalMessage = syscall.Errno(windows.SEC_E_ILLEGAL_MESS...
constant secEWrongPrincipal (line 72) | secEWrongPrincipal = syscall.Errno(windows.SEC_E_WRONG_PRINCI...
constant secECertUnknown (line 73) | secECertUnknown = syscall.Errno(windows.SEC_E_CERT_UNKNOWN)
constant secECertExpired (line 74) | secECertExpired = syscall.Errno(windows.SEC_E_CERT_EXPIRED)
constant secEAlgorithmMismatch (line 75) | secEAlgorithmMismatch = syscall.Errno(windows.SEC_E_ALGORITHM_MI...
constant secEInternalError (line 76) | secEInternalError = syscall.Errno(windows.SEC_E_INTERNAL_ERROR)
constant secENoAuthenticatingAuthority (line 77) | secENoAuthenticatingAuthority = syscall.Errno(windows.SEC_E_NO_AUTHENTIC...
type secHandle (line 80) | type secHandle struct
type secBuffer (line 85) | type secBuffer struct
type secBufferDesc (line 91) | type secBufferDesc struct
type schCredentials (line 97) | type schCredentials struct
type tlsParameters (line 111) | type tlsParameters struct
type secPkgContextStreamSizes (line 120) | type secPkgContextStreamSizes struct
type secPkgContextConnectionInfo (line 128) | type secPkgContextConnectionInfo struct
type secPkgContextApplicationProtocol (line 138) | type secPkgContextApplicationProtocol struct
type secPkgContextCipherInfo (line 145) | type secPkgContextCipherInfo struct
FILE: common/schannel/zsyscall_windows.go
constant errnoERROR_IO_PENDING (line 17) | errnoERROR_IO_PENDING = 997
function errnoErr (line 27) | func errnoErr(e syscall.Errno) error {
function sspiAcquireCredentialsHandle (line 53) | func sspiAcquireCredentialsHandle(principal *uint16, pkgname *uint16, cr...
function sspiDecryptMessage (line 59) | func sspiDecryptMessage(context *secHandle, message *secBufferDesc, sequ...
function sspiDeleteSecurityContext (line 65) | func sspiDeleteSecurityContext(context *secHandle) (ret syscall.Errno) {
function sspiEncryptMessage (line 71) | func sspiEncryptMessage(context *secHandle, qop uint32, message *secBuff...
function sspiFreeContextBuffer (line 77) | func sspiFreeContextBuffer(buffer *byte) (ret syscall.Errno) {
function sspiFreeCredentialsHandle (line 83) | func sspiFreeCredentialsHandle(credential *secHandle) (ret syscall.Errno) {
function sspiInitializeSecurityContext (line 89) | func sspiInitializeSecurityContext(credential *secHandle, context *secHa...
function sspiQueryContextAttributes (line 95) | func sspiQueryContextAttributes(context *secHandle, attribute uint32, bu...
FILE: common/settings/proxy_android.go
type AndroidSystemProxy (line 15) | type AndroidSystemProxy struct
method IsEnabled (line 45) | func (p *AndroidSystemProxy) IsEnabled() bool {
method Enable (line 49) | func (p *AndroidSystemProxy) Enable() error {
method Disable (line 58) | func (p *AndroidSystemProxy) Disable() error {
method runAndroidShell (line 67) | func (p *AndroidSystemProxy) runAndroidShell(name string, args ...stri...
function NewSystemProxy (line 23) | func NewSystemProxy(ctx context.Context, serverAddr M.Socksaddr, support...
FILE: common/settings/proxy_darwin.go
type DarwinSystemProxy (line 18) | type DarwinSystemProxy struct
method IsEnabled (line 41) | func (p *DarwinSystemProxy) IsEnabled() bool {
method Enable (line 45) | func (p *DarwinSystemProxy) Enable() error {
method Disable (line 49) | func (p *DarwinSystemProxy) Disable() error {
method routeUpdate (line 69) | func (p *DarwinSystemProxy) routeUpdate(defaultInterface *control.Inte...
method update0 (line 76) | func (p *DarwinSystemProxy) update0() error {
function NewSystemProxy (line 27) | func NewSystemProxy(ctx context.Context, serverAddr M.Socksaddr, support...
function getInterfaceDisplayName (line 107) | func getInterfaceDisplayName(name string) (string, error) {
FILE: common/settings/proxy_linux.go
type LinuxSystemProxy (line 18) | type LinuxSystemProxy struct
method IsEnabled (line 56) | func (p *LinuxSystemProxy) IsEnabled() bool {
method Enable (line 60) | func (p *LinuxSystemProxy) Enable() error {
method Disable (line 109) | func (p *LinuxSystemProxy) Disable() error {
method runAsUser (line 130) | func (p *LinuxSystemProxy) runAsUser(name string, args ...string) error {
method setGnomeProxy (line 140) | func (p *LinuxSystemProxy) setGnomeProxy(proxyTypes ...string) error {
method setKDEProxy (line 154) | func (p *LinuxSystemProxy) setKDEProxy(proxyTypes ...string) error {
function NewSystemProxy (line 27) | func NewSystemProxy(ctx context.Context, serverAddr M.Socksaddr, support...
FILE: common/settings/proxy_stub.go
function NewSystemProxy (line 12) | func NewSystemProxy(ctx context.Context, serverAddr M.Socksaddr, support...
FILE: common/settings/proxy_windows.go
type WindowsSystemProxy (line 10) | type WindowsSystemProxy struct
method IsEnabled (line 23) | func (p *WindowsSystemProxy) IsEnabled() bool {
method Enable (line 27) | func (p *WindowsSystemProxy) Enable() error {
method Disable (line 36) | func (p *WindowsSystemProxy) Disable() error {
function NewSystemProxy (line 16) | func NewSystemProxy(ctx context.Context, serverAddr M.Socksaddr, support...
FILE: common/settings/system_proxy.go
type SystemProxy (line 3) | type SystemProxy interface
FILE: common/settings/wifi.go
type WIFIMonitor (line 5) | type WIFIMonitor interface
FILE: common/settings/wifi_linux.go
type LinuxWIFIMonitor (line 8) | type LinuxWIFIMonitor struct
method ReadWIFIState (line 30) | func (m *LinuxWIFIMonitor) ReadWIFIState() adapter.WIFIState {
method Start (line 34) | func (m *LinuxWIFIMonitor) Start() error {
method Close (line 41) | func (m *LinuxWIFIMonitor) Close() error {
function NewWIFIMonitor (line 12) | func NewWIFIMonitor(callback func(adapter.WIFIState)) (WIFIMonitor, erro...
FILE: common/settings/wifi_linux_connman.go
type connmanMonitor (line 15) | type connmanMonitor struct
method ReadWIFIState (line 38) | func (m *connmanMonitor) ReadWIFIState() adapter.WIFIState {
method Start (line 105) | func (m *connmanMonitor) Start() error {
method monitorSignals (line 130) | func (m *connmanMonitor) monitorSignals(ctx context.Context, signalCha...
method Close (line 152) | func (m *connmanMonitor) Close() error {
function newConnManMonitor (line 22) | func newConnManMonitor(callback func(adapter.WIFIState)) (WIFIMonitor, e...
FILE: common/settings/wifi_linux_iwd.go
type iwdMonitor (line 15) | type iwdMonitor struct
method ReadWIFIState (line 38) | func (m *iwdMonitor) ReadWIFIState() adapter.WIFIState {
method Start (line 129) | func (m *iwdMonitor) Start() error {
method monitorSignals (line 154) | func (m *iwdMonitor) monitorSignals(ctx context.Context, signalChan ch...
method Close (line 174) | func (m *iwdMonitor) Close() error {
function newIWDMonitor (line 22) | func newIWDMonitor(callback func(adapter.WIFIState)) (WIFIMonitor, error) {
FILE: common/settings/wifi_linux_nm.go
type networkManagerMonitor (line 15) | type networkManagerMonitor struct
method ReadWIFIState (line 39) | func (m *networkManagerMonitor) ReadWIFIState() adapter.WIFIState {
method Start (line 104) | func (m *networkManagerMonitor) Start() error {
method monitorSignals (line 129) | func (m *networkManagerMonitor) monitorSignals(ctx context.Context, si...
method Close (line 149) | func (m *networkManagerMonitor) Close() error {
function newNetworkManagerMonitor (line 22) | func newNetworkManagerMonitor(callback func(adapter.WIFIState)) (WIFIMon...
FILE: common/settings/wifi_linux_wpa.go
type wpaSupplicantMonitor (line 21) | type wpaSupplicantMonitor struct
method ReadWIFIState (line 55) | func (m *wpaSupplicantMonitor) ReadWIFIState() adapter.WIFIState {
method sendCommand (line 100) | func (m *wpaSupplicantMonitor) sendCommand(conn *net.UnixConn, command...
method Start (line 120) | func (m *wpaSupplicantMonitor) Start() error {
method monitorEvents (line 134) | func (m *wpaSupplicantMonitor) monitorEvents(ctx context.Context, last...
method Close (line 216) | func (m *wpaSupplicantMonitor) Close() error {
function newWpaSupplicantMonitor (line 29) | func newWpaSupplicantMonitor(callback func(adapter.WIFIState)) (WIFIMoni...
FILE: common/settings/wifi_stub.go
type stubWIFIMonitor (line 12) | type stubWIFIMonitor struct
method ReadWIFIState (line 18) | func (m *stubWIFIMonitor) ReadWIFIState() adapter.WIFIState {
method Start (line 22) | func (m *stubWIFIMonitor) Start() error {
method Close (line 26) | func (m *stubWIFIMonitor) Close() error {
function NewWIFIMonitor (line 14) | func NewWIFIMonitor(callback func(adapter.WIFIState)) (WIFIMonitor, erro...
FILE: common/settings/wifi_windows.go
type windowsWIFIMonitor (line 18) | type windowsWIFIMonitor struct
method ReadWIFIState (line 48) | func (m *windowsWIFIMonitor) ReadWIFIState() adapter.WIFIState {
method Start (line 87) | func (m *windowsWIFIMonitor) Start() error {
method checkAndNotify (line 125) | func (m *windowsWIFIMonitor) checkAndNotify() {
method Close (line 138) | func (m *windowsWIFIMonitor) Close() error {
function NewWIFIMonitor (line 26) | func NewWIFIMonitor(callback func(adapter.WIFIState)) (WIFIMonitor, erro...
function formatBSSID (line 82) | func formatBSSID(mac winwlanapi.Dot11MacAddress) string {
FILE: common/sniff/bittorrent.go
constant trackerConnectFlag (line 16) | trackerConnectFlag = 0
constant trackerProtocolID (line 17) | trackerProtocolID = 0x41727101980
constant trackerConnectMinSize (line 18) | trackerConnectMinSize = 16
function BitTorrent (line 23) | func BitTorrent(_ context.Context, metadata *adapter.InboundContext, rea...
function UTP (line 56) | func UTP(_ context.Context, metadata *adapter.InboundContext, packet []b...
function UDPTracker (line 95) | func UDPTracker(_ context.Context, metadata *adapter.InboundContext, pac...
FILE: common/sniff/bittorrent_test.go
function TestSniffBittorrent (line 16) | func TestSniffBittorrent(t *testing.T) {
function TestSniffIncompleteBittorrent (line 35) | func TestSniffIncompleteBittorrent(t *testing.T) {
function TestSniffNotBittorrent (line 45) | func TestSniffNotBittorrent(t *testing.T) {
function TestSniffUTP (line 56) | func TestSniffUTP(t *testing.T) {
function TestSniffUDPTracker (line 76) | func TestSniffUDPTracker(t *testing.T) {
function TestSniffNotUTP (line 96) | func TestSniffNotUTP(t *testing.T) {
FILE: common/sniff/dns.go
function StreamDomainNameQuery (line 17) | func StreamDomainNameQuery(readCtx context.Context, metadata *adapter.In...
function DomainNameQuery (line 49) | func DomainNameQuery(ctx context.Context, metadata *adapter.InboundConte...
FILE: common/sniff/dns_test.go
function TestSniffDNS (line 16) | func TestSniffDNS(t *testing.T) {
function TestSniffStreamDNS (line 26) | func TestSniffStreamDNS(t *testing.T) {
function TestSniffIncompleteStreamDNS (line 36) | func TestSniffIncompleteStreamDNS(t *testing.T) {
function TestSniffNotStreamDNS (line 45) | func TestSniffNotStreamDNS(t *testing.T) {
FILE: common/sniff/dtls.go
function DTLSRecord (line 11) | func DTLSRecord(ctx context.Context, metadata *adapter.InboundContext, p...
FILE: common/sniff/dtls_test.go
function TestSniffDTLSClientHello (line 15) | func TestSniffDTLSClientHello(t *testing.T) {
function TestSniffDTLSClientApplicationData (line 25) | func TestSniffDTLSClientApplicationData(t *testing.T) {
FILE: common/sniff/http.go
function HTTPHost (line 16) | func HTTPHost(_ context.Context, metadata *adapter.InboundContext, reade...
FILE: common/sniff/http_test.go
function TestSniffHTTP1 (line 14) | func TestSniffHTTP1(t *testing.T) {
function TestSniffHTTP1WithPort (line 23) | func TestSniffHTTP1WithPort(t *testing.T) {
FILE: common/sniff/internal/qtls/qtls.go
constant VersionDraft29 (line 14) | VersionDraft29 = 0xff00001d
constant Version1 (line 15) | Version1 = 0x1
constant Version2 (line 16) | Version2 = 0x6b3343cf
constant HKDFLabelKeyV1 (line 26) | HKDFLabelKeyV1 = "quic key"
constant HKDFLabelKeyV2 (line 27) | HKDFLabelKeyV2 = "quicv2 key"
constant HKDFLabelIVV1 (line 28) | HKDFLabelIVV1 = "quic iv"
constant HKDFLabelIVV2 (line 29) | HKDFLabelIVV2 = "quicv2 iv"
constant HKDFLabelHeaderProtectionV1 (line 30) | HKDFLabelHeaderProtectionV1 = "quic hp"
constant HKDFLabelHeaderProtectionV2 (line 31) | HKDFLabelHeaderProtectionV2 = "quicv2 hp"
function AEADAESGCMTLS13 (line 34) | func AEADAESGCMTLS13(key, nonceMask []byte) cipher.AEAD {
type xorNonceAEAD (line 52) | type xorNonceAEAD struct
method NonceSize (line 57) | func (f *xorNonceAEAD) NonceSize() int { return 8 }
method Overhead (line 58) | func (f *xorNonceAEAD) Overhead() int { return f.aead.Overhead() }
method Seal (line 60) | func (f *xorNonceAEAD) Seal(out, nonce, plaintext, additionalData []by...
method Open (line 72) | func (f *xorNonceAEAD) Open(out, nonce, ciphertext, additionalData []b...
function HKDFExpandLabel (line 84) | func HKDFExpandLabel(hash crypto.Hash, secret, context []byte, label str...
function ReadUvarint (line 101) | func ReadUvarint(r io.ByteReader) (uint64, error) {
FILE: common/sniff/ntp.go
function NTP (line 12) | func NTP(ctx context.Context, metadata *adapter.InboundContext, packet [...
FILE: common/sniff/ntp_test.go
function TestSniffNTP (line 16) | func TestSniffNTP(t *testing.T) {
function TestSniffNTPFailed (line 26) | func TestSniffNTPFailed(t *testing.T) {
FILE: common/sniff/quic.go
function QUICClientHello (line 23) | func QUICClientHello(ctx context.Context, metadata *adapter.InboundConte...
function isZero (line 350) | func isZero(slices []uint8) bool {
function count (line 359) | func count(slices []uint8, value uint8) int {
type qCryptoFragment (line 369) | type qCryptoFragment struct
FILE: common/sniff/quic_blacklist.go
constant x25519Kyber768Draft00 (line 11) | x25519Kyber768Draft00 uint16 = 0x11EC
constant extensionRenegotiationInfo (line 13) | extensionRenegotiationInfo uint16 = 0xFF01
function isQUICGo (line 19) | func isQUICGo(fingerprint *ja3.ClientHello) bool {
FILE: common/sniff/quic_capture_test.go
function TestSniffQUICQuicGoFingerprint (line 19) | func TestSniffQUICQuicGoFingerprint(t *testing.T) {
function TestSniffQUICInitialFromQuicGo (line 88) | func TestSniffQUICInitialFromQuicGo(t *testing.T) {
FILE: common/sniff/quic_test.go
function TestSniffQUICChromeNew (line 15) | func TestSniffQUICChromeNew(t *testing.T) {
function TestSniffQUICChromium (line 35) | func TestSniffQUICChromium(t *testing.T) {
function TestSniffUQUICChrome115 (line 51) | func TestSniffUQUICChrome115(t *testing.T) {
function TestSniffQUICFirefox (line 63) | func TestSniffQUICFirefox(t *testing.T) {
function TestSniffQUICSafari (line 75) | func TestSniffQUICSafari(t *testing.T) {
function FuzzSniffQUIC (line 87) | func FuzzSniffQUIC(f *testing.F) {
FILE: common/sniff/rdp.go
function RDP (line 15) | func RDP(_ context.Context, metadata *adapter.InboundContext, reader io....
FILE: common/sniff/rdp_test.go
function TestSniffRDP (line 16) | func TestSniffRDP(t *testing.T) {
FILE: common/sniff/sniff.go
function Skip (line 25) | func Skip(metadata *adapter.InboundContext) bool {
function PeekStream (line 41) | func PeekStream(ctx context.Context, metadata *adapter.InboundContext, c...
function PeekPacket (line 78) | func PeekPacket(ctx context.Context, metadata *adapter.InboundContext, p...
FILE: common/sniff/ssh.go
function SSH (line 14) | func SSH(_ context.Context, metadata *adapter.InboundContext, reader io....
FILE: common/sniff/ssh_test.go
function TestSniffSSH (line 16) | func TestSniffSSH(t *testing.T) {
function TestSniffIncompleteSSH (line 28) | func TestSniffIncompleteSSH(t *testing.T) {
function TestSniffNotSSH (line 38) | func TestSniffNotSSH(t *testing.T) {
FILE: common/sniff/stun.go
function STUNMessage (line 12) | func STUNMessage(_ context.Context, metadata *adapter.InboundContext, pa...
FILE: common/sniff/stun_test.go
function TestSniffSTUN (line 15) | func TestSniffSTUN(t *testing.T) {
function FuzzSniffSTUN (line 25) | func FuzzSniffSTUN(f *testing.F) {
FILE: common/sniff/tls.go
function TLSClientHello (line 15) | func TLSClientHello(ctx context.Context, metadata *adapter.InboundContex...
FILE: common/srs/binary.go
constant ruleItemQueryType (line 26) | ruleItemQueryType uint8 = iota
constant ruleItemNetwork (line 27) | ruleItemNetwork
constant ruleItemDomain (line 28) | ruleItemDomain
constant ruleItemDomainKeyword (line 29) | ruleItemDomainKeyword
constant ruleItemDomainRegex (line 30) | ruleItemDomainRegex
constant ruleItemSourceIPCIDR (line 31) | ruleItemSourceIPCIDR
constant ruleItemIPCIDR (line 32) | ruleItemIPCIDR
constant ruleItemSourcePort (line 33) | ruleItemSourcePort
constant ruleItemSourcePortRange (line 34) | ruleItemSourcePortRange
constant ruleItemPort (line 35) | ruleItemPort
constant ruleItemPortRange (line 36) | ruleItemPortRange
constant ruleItemProcessName (line 37) | ruleItemProcessName
constant ruleItemProcessPath (line 38) | ruleItemProcessPath
constant ruleItemPackageName (line 39) | ruleItemPackageName
constant ruleItemWIFISSID (line 40) | ruleItemWIFISSID
constant ruleItemWIFIBSSID (line 41) | ruleItemWIFIBSSID
constant ruleItemAdGuardDomain (line 42) | ruleItemAdGuardDomain
constant ruleItemProcessPathRegex (line 43) | ruleItemProcessPathRegex
constant ruleItemNetworkType (line 44) | ruleItemNetworkType
constant ruleItemNetworkIsExpensive (line 45) | ruleItemNetworkIsExpensive
constant ruleItemNetworkIsConstrained (line 46) | ruleItemNetworkIsConstrained
constant ruleItemNetworkInterfaceAddress (line 47) | ruleItemNetworkInterfaceAddress
constant ruleItemDefaultInterfaceAddress (line 48) | ruleItemDefaultInterfaceAddress
constant ruleItemPackageNameRegex (line 49) | ruleItemPackageNameRegex
constant ruleItemFinal (line 50) | ruleItemFinal uint8 = 0xFF
function Read (line 53) | func Read(reader io.Reader, recover bool) (ruleSetCompat option.PlainRul...
function Write (line 92) | func Write(writer io.Writer, ruleSet option.PlainRuleSet, generateVersio...
function readRule (line 123) | func readRule(reader varbin.Reader, recover bool) (rule option.HeadlessR...
function writeRule (line 142) | func writeRule(writer varbin.Writer, rule option.HeadlessRule, generateV...
function readDefaultRule (line 153) | func readDefaultRule(reader varbin.Reader, recover bool) (rule option.De...
function writeDefaultRule (line 299) | func writeDefaultRule(writer varbin.Writer, rule option.DefaultHeadlessR...
function readRuleItemString (line 520) | func readRuleItemString(reader varbin.Reader) ([]string, error) {
function writeRuleItemString (line 541) | func writeRuleItemString(writer varbin.Writer, itemType uint8, value []s...
function readRuleItemUint8 (line 563) | func readRuleItemUint8[E ~uint8](reader varbin.Reader) ([]E, error) {
function writeRuleItemUint8 (line 576) | func writeRuleItemUint8[E ~uint8](writer varbin.Writer, itemType uint8, ...
function readRuleItemUint16 (line 589) | func readRuleItemUint16(reader varbin.Reader) ([]uint16, error) {
function writeRuleItemUint16 (line 602) | func writeRuleItemUint16(writer varbin.Writer, itemType uint8, value []u...
function writeRuleItemCIDR (line 614) | func writeRuleItemCIDR(writer varbin.Writer, itemType uint8, value []str...
function readLogicalRule (line 640) | func readLogicalRule(reader varbin.Reader, recovery bool) (logicalRule o...
function writeLogicalRule (line 673) | func writeLogicalRule(writer varbin.Writer, logicalRule option.LogicalHe...
FILE: common/srs/compat_test.go
function oldWriteStringSlice (line 21) | func oldWriteStringSlice(writer varbin.Writer, value []string) error {
function oldReadStringSlice (line 26) | func oldReadStringSlice(reader varbin.Reader) ([]string, error) {
function oldWriteUint8Slice (line 31) | func oldWriteUint8Slice[E ~uint8](writer varbin.Writer, value []E) error {
function oldReadUint8Slice (line 36) | func oldReadUint8Slice[E ~uint8](reader varbin.Reader) ([]E, error) {
function oldWriteUint16Slice (line 41) | func oldWriteUint16Slice(writer varbin.Writer, value []uint16) error {
function oldReadUint16Slice (line 46) | func oldReadUint16Slice(reader varbin.Reader) ([]uint16, error) {
function oldWritePrefix (line 51) | func oldWritePrefix(writer varbin.Writer, prefix netip.Prefix) error {
type oldIPRangeData (line 60) | type oldIPRangeData struct
function oldReadIPSet (line 78) | func oldReadIPSet(reader varbin.Reader) (*netipx.IPSet, error) {
function newWriteStringSlice (line 109) | func newWriteStringSlice(writer varbin.Writer, value []string) error {
function newWriteUint8Slice (line 127) | func newWriteUint8Slice[E ~uint8](writer varbin.Writer, value []E) error {
function newWriteUint16Slice (line 136) | func newWriteUint16Slice(writer varbin.Writer, value []uint16) error {
function newWritePrefix (line 144) | func newWritePrefix(writer varbin.Writer, prefix netip.Prefix) error {
function TestStringSliceCompat (line 159) | func TestStringSliceCompat(t *testing.T) {
function TestUint8SliceCompat (line 212) | func TestUint8SliceCompat(t *testing.T) {
function TestUint16SliceCompat (line 261) | func TestUint16SliceCompat(t *testing.T) {
function TestPrefixCompat (line 310) | func TestPrefixCompat(t *testing.T) {
function TestIPSetCompat (line 361) | func TestIPSetCompat(t *testing.T) {
function generateStrings (line 409) | func generateStrings(count int) []string {
function generateUint8Slice (line 417) | func generateUint8Slice(count int) []uint8 {
function generateUint16Slice (line 425) | func generateUint16Slice(count int) []uint16 {
function buildIPSet (line 433) | func buildIPSet(cidrs ...string) *netipx.IPSet {
function buildLargeIPSet (line 451) | func buildLargeIPSet(count int) *netipx.IPSet {
function requireStringSliceEqual (line 461) | func requireStringSliceEqual(t *testing.T, expected, actual []string) {
function requireUint8SliceEqual (line 469) | func requireUint8SliceEqual(t *testing.T, expected, actual []uint8) {
function requireUint16SliceEqual (line 477) | func requireUint16SliceEqual(t *testing.T, expected, actual []uint16) {
function requireIPSetEqual (line 485) | func requireIPSetEqual(t *testing.T, expected, actual *netipx.IPSet) {
FILE: common/srs/ip_cidr.go
function readPrefix (line 12) | func readPrefix(reader varbin.Reader) (netip.Prefix, error) {
function writePrefix (line 29) | func writePrefix(writer varbin.Writer, prefix netip.Prefix) error {
FILE: common/srs/ip_set.go
type myIPSet (line 16) | type myIPSet struct
type myIPRange (line 20) | type myIPRange struct
function readIPSet (line 25) | func readIPSet(reader varbin.Reader) (*netipx.IPSet, error) {
function writeIPSet (line 67) | func writeIPSet(writer varbin.Writer, set *netipx.IPSet) error {
FILE: common/stun/stun.go
constant DefaultServer (line 20) | DefaultServer = "stun.voipgate.com:3478"
constant magicCookie (line 22) | magicCookie = 0x2112A442
constant headerSize (line 23) | headerSize = 20
constant bindingRequest (line 25) | bindingRequest = 0x0001
constant bindingSuccessResponse (line 26) | bindingSuccessResponse = 0x0101
constant bindingErrorResponse (line 27) | bindingErrorResponse = 0x0111
constant attrMappedAddress (line 29) | attrMappedAddress = 0x0001
constant attrChangeRequest (line 30) | attrChangeRequest = 0x0003
constant attrErrorCode (line 31) | attrErrorCode = 0x0009
constant attrXORMappedAddress (line 32) | attrXORMappedAddress = 0x0020
constant attrOtherAddress (line 33) | attrOtherAddress = 0x802c
constant familyIPv4 (line 35) | familyIPv4 = 0x01
constant familyIPv6 (line 36) | familyIPv6 = 0x02
constant changeIP (line 38) | changeIP = 0x04
constant changePort (line 39) | changePort = 0x02
constant defaultRTO (line 41) | defaultRTO = 500 * time.Millisecond
constant minRTO (line 42) | minRTO = 250 * time.Millisecond
constant maxRetransmit (line 43) | maxRetransmit = 2
type Phase (line 46) | type Phase
constant PhaseBinding (line 49) | PhaseBinding Phase = iota
constant PhaseNATMapping (line 50) | PhaseNATMapping
constant PhaseNATFiltering (line 51) | PhaseNATFiltering
constant PhaseDone (line 52) | PhaseDone
type NATMapping (line 55) | type NATMapping
method String (line 65) | func (m NATMapping) String() string {
constant NATMappingUnknown (line 58) | NATMappingUnknown NATMapping = iota
constant _ (line 59) | _
constant NATMappingEndpointIndependent (line 60) | NATMappingEndpointIndependent
constant NATMappingAddressDependent (line 61) | NATMappingAddressDependent
constant NATMappingAddressAndPortDependent (line 62) | NATMappingAddressAndPortDependent
type NATFiltering (line 78) | type NATFiltering
method String (line 87) | func (f NATFiltering) String() string {
constant NATFilteringUnknown (line 81) | NATFilteringUnknown NATFiltering = iota
constant NATFilteringEndpointIndependent (line 82) | NATFilteringEndpointIndependent
constant NATFilteringAddressDependent (line 83) | NATFilteringAddressDependent
constant NATFilteringAddressAndPortDependent (line 84) | NATFilteringAddressAndPortDependent
type TransactionID (line 100) | type TransactionID
type Options (line 102) | type Options struct
type Progress (line 109) | type Progress struct
type Result (line 117) | type Result struct
type parsedResponse (line 125) | type parsedResponse struct
method externalAddr (line 131) | func (r *parsedResponse) externalAddr() (netip.AddrPort, bool) {
type stunAttribute (line 141) | type stunAttribute struct
function newTransactionID (line 146) | func newTransactionID() TransactionID {
function buildBindingRequest (line 152) | func buildBindingRequest(txID TransactionID, attrs ...stunAttribute) []b...
function changeRequestAttr (line 175) | func changeRequestAttr(flags byte) stunAttribute {
function parseResponse (line 182) | func parseResponse(data []byte, expectedTxID TransactionID) (*parsedResp...
function parseErrorResponse (line 251) | func parseErrorResponse(data []byte) error {
function parseXORMappedAddress (line 274) | func parseXORMappedAddress(data []byte, txID TransactionID) (netip.AddrP...
function parseMappedAddress (line 308) | func parseMappedAddress(data []byte) (netip.AddrPort, error) {
function roundTrip (line 336) | func roundTrip(conn net.PacketConn, addr net.Addr, txID TransactionID, a...
function Run (line 390) | func Run(options Options) (*Result, error) {
function detectNATMapping (line 538) | func detectNATMapping(
function detectNATFiltering (line 583) | func detectNATFiltering(
function paddingLen (line 607) | func paddingLen(n int) int {
FILE: common/taskmonitor/monitor.go
type Monitor (line 10) | type Monitor struct
method Start (line 23) | func (m *Monitor) Start(taskName ...any) {
method Finish (line 29) | func (m *Monitor) Finish() {
function New (line 16) | func New(logger logger.Logger, timeout time.Duration) *Monitor {
FILE: common/tls/acme.go
type acmeWrapper (line 26) | type acmeWrapper struct
method Start (line 33) | func (w *acmeWrapper) Start() error {
method Close (line 37) | func (w *acmeWrapper) Close() error {
function startACME (line 42) | func startACME(ctx context.Context, logger logger.Logger, options option...
FILE: common/tls/acme_logger.go
type ACMELogWriter (line 12) | type ACMELogWriter struct
method Write (line 16) | func (w *ACMELogWriter) Write(p []byte) (n int, err error) {
method Sync (line 33) | func (w *ACMELogWriter) Sync() error {
function ACMEEncoderConfig (line 37) | func ACMEEncoderConfig() zapcore.EncoderConfig {
FILE: common/tls/acme_stub.go
function startACME (line 15) | func startACME(ctx context.Context, logger logger.Logger, options option...
FILE: common/tls/apple_client.go
constant appleTLSEngineName (line 14) | appleTLSEngineName = "Apple TLS engine"
type appleClientConfig (line 16) | type appleClientConfig struct
method Clone (line 21) | func (c *appleClientConfig) Clone() Config {
method resolveAnchors (line 28) | func (c *appleClientConfig) resolveAnchors() (adapter.AppleAnchors, er...
function newAppleClient (line 35) | func newAppleClient(ctx context.Context, logger logger.ContextLogger, se...
FILE: common/tls/apple_client_platform.go
method ClientHandshake (line 36) | func (c *appleClientConfig) ClientHandshake(ctx context.Context, conn ne...
constant appleTLSHandshakePollInterval (line 151) | appleTLSHandshakePollInterval = 100 * time.Millisecond
constant appleTLSWriteChunkSize (line 152) | appleTLSWriteChunkSize = 32 * 1024
function waitAppleTLSClientReady (line 155) | func waitAppleTLSClientReady(ctx context.Context, client *C.box_apple_tl...
type appleTLSConn (line 199) | type appleTLSConn struct
method Read (line 224) | func (c *appleTLSConn) Read(p []byte) (int, error) {
method ReadBuffer (line 237) | func (c *appleTLSConn) ReadBuffer(buffer *buf.Buffer) error {
method readIntoLocked (line 249) | func (c *appleTLSConn) readIntoLocked(p []byte) (int, error) {
method Write (line 295) | func (c *appleTLSConn) Write(p []byte) (int, error) {
method WriteBuffer (line 340) | func (c *appleTLSConn) WriteBuffer(buffer *buf.Buffer) error {
method CreateReadWaiter (line 346) | func (c *appleTLSConn) CreateReadWaiter() (N.ReadWaiter, bool) {
method Close (line 353) | func (c *appleTLSConn) Close() error {
method LocalAddr (line 368) | func (c *appleTLSConn) LocalAddr() net.Addr {
method RemoteAddr (line 372) | func (c *appleTLSConn) RemoteAddr() net.Addr {
method SetDeadline (line 385) | func (c *appleTLSConn) SetDeadline(t time.Time) error {
method SetReadDeadline (line 395) | func (c *appleTLSConn) SetReadDeadline(t time.Time) error {
method SetWriteDeadline (line 403) | func (c *appleTLSConn) SetWriteDeadline(t time.Time) error {
method prepareReadTimeout (line 411) | func (c *appleTLSConn) prepareReadTimeout() (int, error) {
method prepareWriteDeadline (line 425) | func (c *appleTLSConn) prepareWriteDeadline() (time.Time, error) {
method markReadTimedOut (line 439) | func (c *appleTLSConn) markReadTimedOut() {
method markWriteTimedOut (line 445) | func (c *appleTLSConn) markWriteTimedOut() {
method isClosed (line 462) | func (c *appleTLSConn) isClosed() bool {
method acquireClient (line 471) | func (c *appleTLSConn) acquireClient() (*C.box_apple_tls_client_t, err...
method releaseClient (line 485) | func (c *appleTLSConn) releaseClient() {
method errorFromPointer (line 489) | func (c *appleTLSConn) errorFromPointer(errorPtr *C.char) error {
method readWaitResultToBuffer (line 565) | func (c *appleTLSConn) readWaitResultToBuffer(result *C.box_apple_tls_...
method NetConn (line 621) | func (c *appleTLSConn) NetConn() net.Conn {
method HandshakeContext (line 625) | func (c *appleTLSConn) HandshakeContext(ctx context.Context) error {
method ConnectionState (line 629) | func (c *appleTLSConn) ConnectionState() ConnectionState {
function deadlineTimeoutMs (line 451) | func deadlineTimeoutMs(deadline time.Time) (int, bool) {
type appleTLSReadWaiter (line 500) | type appleTLSReadWaiter struct
method InitializeReadWaiter (line 508) | func (w *appleTLSReadWaiter) InitializeReadWaiter(options N.ReadWaitOp...
method WaitReadBuffer (line 516) | func (w *appleTLSReadWaiter) WaitReadBuffer() (*buf.Buffer, error) {
function readWaitFreeLen (line 596) | func readWaitFreeLen(options N.ReadWaitOptions) int {
function box_apple_tls_read_callback (line 607) | func box_apple_tls_read_callback(callbackHandle C.uintptr_t, result *C.b...
function parseAppleTLSState (line 635) | func parseAppleTLSState(state *C.box_apple_tls_state_t) (tls.ConnectionS...
function parseAppleCertChain (line 658) | func parseAppleCertChain(chain *C.uint8_t, chainLen C.size_t) ([][]byte,...
function timeoutFromDuration (line 688) | func timeoutFromDuration(timeout time.Duration) int {
function cStringOrNil (line 702) | func cStringOrNil(value string) *C.char {
function cFree (line 709) | func cFree(pointer *C.char) {
FILE: common/tls/apple_client_platform_benchmark_test.go
constant appleTLSBenchmarkReadPayloadSize (line 21) | appleTLSBenchmarkReadPayloadSize = 16 * 1024
constant appleTLSBenchmarkWritePayloadSize (line 22) | appleTLSBenchmarkWritePayloadSize = 48 * 1024
function BenchmarkAppleClientReadBuffer (line 25) | func BenchmarkAppleClientReadBuffer(b *testing.B) {
function BenchmarkAppleClientReadWaiter (line 63) | func BenchmarkAppleClientReadWaiter(b *testing.B) {
function BenchmarkAppleClientWriteBuffer (line 108) | func BenchmarkAppleClientWriteBuffer(b *testing.B) {
function BenchmarkStdlibClientReadBuffer (line 143) | func BenchmarkStdlibClientReadBuffer(b *testing.B) {
function BenchmarkStdlibClientWriteBuffer (line 182) | func BenchmarkStdlibClientWriteBuffer(b *testing.B) {
function newAppleBenchmarkClientConn (line 216) | func newAppleBenchmarkClientConn(b *testing.B, handler func(*stdtls.Conn...
function newStdlibBenchmarkClientConn (line 240) | func newStdlibBenchmarkClientConn(b *testing.B, handler func(*stdtls.Con...
function writeBenchmarkPayload (line 269) | func writeBenchmarkPayload(writer io.Writer, payload []byte) error {
FILE: common/tls/apple_client_platform_darwin.h
type box_apple_tls_client_t (line 6) | typedef struct box_apple_tls_client box_apple_tls_client_t;
type box_apple_tls_read_result_t (line 7) | typedef struct box_apple_tls_read_result box_apple_tls_read_result_t;
type box_apple_tls_state_t (line 9) | typedef struct box_apple_tls_state {
FILE: common/tls/apple_client_platform_dispatch_test.go
function TestAppleTLSDispatchDataCopySegments (line 11) | func TestAppleTLSDispatchDataCopySegments(t *testing.T) {
function TestAppleTLSDispatchDataCopyRejectsSmallBuffer (line 28) | func TestAppleTLSDispatchDataCopyRejectsSmallBuffer(t *testing.T) {
function TestAppleTLSDispatchDataCopyEmpty (line 42) | func TestAppleTLSDispatchDataCopyEmpty(t *testing.T) {
FILE: common/tls/apple_client_platform_dispatch_testhelper_darwin.go
function appleTLSCopyDispatchDataForTest (line 13) | func appleTLSCopyDispatchDataForTest(first, second []byte, buffer []byte...
FILE: common/tls/apple_client_platform_test.go
constant appleTLSTestTimeout (line 23) | appleTLSTestTimeout = 5 * time.Second
constant appleTLSSuccessHandshakeLoops (line 26) | appleTLSSuccessHandshakeLoops = 20
constant appleTLSFailureRecoveryLoops (line 27) | appleTLSFailureRecoveryLoops = 10
type appleTLSServerResult (line 30) | type appleTLSServerResult struct
function TestAppleClientHandshakeAppliesALPNAndVersion (line 40) | func TestAppleClientHandshakeAppliesALPNAndVersion(t *testing.T) {
function TestAppleClientHandshakeRejectsOpaqueConn (line 87) | func TestAppleClientHandshakeRejectsOpaqueConn(t *testing.T) {
function TestAppleClientHandshakeRejectsVersionMismatch (line 110) | func TestAppleClientHandshakeRejectsVersionMismatch(t *testing.T) {
function TestAppleClientHandshakeRejectsServerNameMismatch (line 135) | func TestAppleClientHandshakeRejectsServerNameMismatch(t *testing.T) {
function TestAppleClientHandshakeRecoversAfterFailure (line 157) | func TestAppleClientHandshakeRecoversAfterFailure(t *testing.T) {
function TestAppleClientConfigCloneWithInlineCertificate (line 244) | func TestAppleClientConfigCloneWithInlineCertificate(t *testing.T) {
function TestAppleClientReadBuffer (line 303) | func TestAppleClientReadBuffer(t *testing.T) {
function TestAppleClientWriteBuffer (line 360) | func TestAppleClientWriteBuffer(t *testing.T) {
function TestAppleClientCreateReadWaiter (line 410) | func TestAppleClientCreateReadWaiter(t *testing.T) {
function TestAppleClientReadDeadline (line 475) | func TestAppleClientReadDeadline(t *testing.T) {
function TestAppleClientSetDeadlineClearsPreExpiredSticky (line 524) | func TestAppleClientSetDeadlineClearsPreExpiredSticky(t *testing.T) {
function startAppleTLSSilentServer (line 581) | func startAppleTLSSilentServer(t *testing.T, tlsConfig *stdtls.Config) (...
function startAppleTLSIOTestServer (line 625) | func startAppleTLSIOTestServer(t testing.TB, tlsConfig *stdtls.Config, h...
function newAppleTestCertificate (line 670) | func newAppleTestCertificate(t testing.TB, serverName string) (stdtls.Ce...
function startAppleTLSTestServer (line 684) | func startAppleTLSTestServer(t *testing.T, tlsConfig *stdtls.Config) (<-...
function newAppleTestClientConn (line 734) | func newAppleTestClientConn(t testing.TB, serverAddress string, options ...
function dialAppleTestClientConn (line 749) | func dialAppleTestClientConn(t testing.TB, serverAddress string, clientC...
FILE: common/tls/apple_client_stub.go
function newAppleClient (line 13) | func newAppleClient(ctx context.Context, logger logger.ContextLogger, se...
FILE: common/tls/client.go
function parseTLSSpoofOptions (line 24) | func parseTLSSpoofOptions(serverName string, options option.OutboundTLSO...
function applyTLSSpoof (line 41) | func applyTLSSpoof(conn net.Conn, spoof string, method tlsspoof.Method) ...
function NewDialerFromOptions (line 48) | func NewDialerFromOptions(ctx context.Context, logger logger.ContextLogg...
function NewClient (line 64) | func NewClient(ctx context.Context, logger logger.ContextLogger, serverA...
type ClientOptions (line 73) | type ClientOptions struct
function NewClientWithOptions (line 82) | func NewClientWithOptions(options ClientOptions) (Config, error) {
function ClientHandshake (line 111) | func ClientHandshake(ctx context.Context, conn net.Conn, config Config) ...
type Dialer (line 125) | type Dialer interface
type defaultDialer (line 130) | type defaultDialer struct
method DialContext (line 139) | func (d *defaultDialer) DialContext(ctx context.Context, network strin...
method ListenPacket (line 146) | func (d *defaultDialer) ListenPacket(ctx context.Context, destination ...
method DialTLSContext (line 150) | func (d *defaultDialer) DialTLSContext(ctx context.Context, destinatio...
method dialContext (line 154) | func (d *defaultDialer) dialContext(ctx context.Context, destination M...
method Upstream (line 174) | func (d *defaultDialer) Upstream() any {
function NewDialer (line 135) | func NewDialer(dialer N.Dialer, config Config) Dialer {
FILE: common/tls/common.go
constant VersionTLS10 (line 4) | VersionTLS10 = 0x0301
constant VersionTLS11 (line 5) | VersionTLS11 = 0x0302
constant VersionTLS12 (line 6) | VersionTLS12 = 0x0303
constant VersionTLS13 (line 7) | VersionTLS13 = 0x0304
constant VersionSSL30 (line 11) | VersionSSL30 = 0x0300
FILE: common/tls/config.go
function ParseTLSVersion (line 24) | func ParseTLSVersion(version string) (uint16, error) {
FILE: common/tls/ech.go
function parseECHClientConfig (line 27) | func parseECHClientConfig(ctx context.Context, clientConfig ECHCapableCo...
function parseECHServerConfig (line 58) | func parseECHServerConfig(ctx context.Context, options option.InboundTLS...
method setECHServerConfig (line 84) | func (c *STDServerConfig) setECHServerConfig(echKey []byte) error {
function parseECHKeys (line 97) | func parseECHKeys(echKey []byte) ([]tls.EncryptedClientHelloKey, error) {
type ECHClientConfig (line 109) | type ECHClientConfig struct
method ClientHandshake (line 118) | func (s *ECHClientConfig) ClientHandshake(ctx context.Context, conn ne...
method fetchAndHandshake (line 130) | func (s *ECHClientConfig) fetchAndHandshake(ctx context.Context, conn ...
method Clone (line 182) | func (s *ECHClientConfig) Clone() Config {
function UnmarshalECHKeys (line 191) | func UnmarshalECHKeys(raw []byte) ([]tls.EncryptedClientHelloKey, error) {
FILE: common/tls/ech_shared.go
type ECHCapableConfig (line 11) | type ECHCapableConfig interface
function ECHKeygenDefault (line 17) | func ECHKeygenDefault(publicName string) (configPem string, keyPem strin...
function marshalECHConfig (line 50) | func marshalECHConfig(id uint8, pubKey []byte, publicName string, maxNam...
FILE: common/tls/ktls.go
type KTLSClientConfig (line 13) | type KTLSClientConfig struct
method ClientHandshake (line 19) | func (w *KTLSClientConfig) ClientHandshake(ctx context.Context, conn n...
method Clone (line 32) | func (w *KTLSClientConfig) Clone() Config {
type KTlSServerConfig (line 41) | type KTlSServerConfig struct
method ServerHandshake (line 47) | func (w *KTlSServerConfig) ServerHandshake(ctx context.Context, conn n...
method Clone (line 60) | func (w *KTlSServerConfig) Clone() Config {
FILE: common/tls/mkcert.go
function GenerateKeyPair (line 14) | func GenerateKeyPair(parent *x509.Certificate, parentKey any, timeFunc f...
function GenerateCertificate (line 29) | func GenerateCertificate(parent *x509.Certificate, parentKey any, timeFu...
FILE: common/tls/reality_client.go
type RealityClientConfig (line 47) | type RealityClientConfig struct
method ServerName (line 102) | func (e *RealityClientConfig) ServerName() string {
method SetServerName (line 106) | func (e *RealityClientConfig) SetServerName(serverName string) {
method NextProtos (line 110) | func (e *RealityClientConfig) NextProtos() []string {
method SetNextProtos (line 114) | func (e *RealityClientConfig) SetNextProtos(nextProto []string) {
method HandshakeTimeout (line 118) | func (e *RealityClientConfig) HandshakeTimeout() time.Duration {
method SetHandshakeTimeout (line 122) | func (e *RealityClientConfig) SetHandshakeTimeout(timeout time.Duratio...
method STDConfig (line 126) | func (e *RealityClientConfig) STDConfig() (*STDConfig, error) {
method Client (line 130) | func (e *RealityClientConfig) Client(conn net.Conn) (Conn, error) {
method ClientHandshake (line 134) | func (e *RealityClientConfig) ClientHandshake(ctx context.Context, con...
method Clone (line 268) | func (e *RealityClientConfig) Clone() Config {
function NewRealityClient (line 54) | func NewRealityClient(ctx context.Context, logger logger.ContextLogger, ...
function newRealityClient (line 58) | func newRealityClient(ctx context.Context, logger logger.ContextLogger, ...
function realityClientFallback (line 244) | func realityClientFallback(ctx context.Context, uConn net.Conn, serverNa...
type realityVerifier (line 277) | type realityVerifier struct
method VerifyPeerCertificate (line 284) | func (c *realityVerifier) VerifyPeerCertificate(rawCerts [][]byte, ver...
type realityClientConnWrapper (line 308) | type realityClientConnWrapper struct
method ConnectionState (line 312) | func (c *realityClientConnWrapper) ConnectionState() tls.ConnectionSta...
method Upstream (line 331) | func (c *realityClientConnWrapper) Upstream() any {
method CloseWrite (line 337) | func (c *realityClientConnWrapper) CloseWrite() error {
method ReaderReplaceable (line 341) | func (c *realityClientConnWrapper) ReaderReplaceable() bool {
method WriterReplaceable (line 345) | func (c *realityClientConnWrapper) WriterReplaceable() bool {
FILE: common/tls/reality_server.go
type RealityServerConfig (line 28) | type RealityServerConfig struct
method ServerName (line 158) | func (c *RealityServerConfig) ServerName() string {
method SetServerName (line 162) | func (c *RealityServerConfig) SetServerName(serverName string) {
method NextProtos (line 166) | func (c *RealityServerConfig) NextProtos() []string {
method SetNextProtos (line 170) | func (c *RealityServerConfig) SetNextProtos(nextProto []string) {
method HandshakeTimeout (line 174) | func (c *RealityServerConfig) HandshakeTimeout() time.Duration {
method SetHandshakeTimeout (line 178) | func (c *RealityServerConfig) SetHandshakeTimeout(timeout time.Duratio...
method STDConfig (line 182) | func (c *RealityServerConfig) STDConfig() (*tls.Config, error) {
method Client (line 186) | func (c *RealityServerConfig) Client(conn net.Conn) (Conn, error) {
method Start (line 190) | func (c *RealityServerConfig) Start() error {
method Close (line 194) | func (c *RealityServerConfig) Close() error {
method Server (line 198) | func (c *RealityServerConfig) Server(conn net.Conn) (Conn, error) {
method ServerHandshake (line 202) | func (c *RealityServerConfig) ServerHandshake(ctx context.Context, con...
method Clone (line 210) | func (c *RealityServerConfig) Clone() Config {
function NewRealityServer (line 33) | func NewRealityServer(ctx context.Context, logger log.ContextLogger, opt...
type realityConnWrapper (line 219) | type realityConnWrapper struct
method ConnectionState (line 223) | func (c *realityConnWrapper) ConnectionState() ConnectionState {
method Upstream (line 242) | func (c *realityConnWrapper) Upstream() any {
method CloseWrite (line 248) | func (c *realityConnWrapper) CloseWrite() error {
method ReaderReplaceable (line 252) | func (c *realityConnWrapper) ReaderReplaceable() bool {
method WriterReplaceable (line 256) | func (c *realityConnWrapper) WriterReplaceable() bool {
FILE: common/tls/server.go
type ServerOptions (line 15) | type ServerOptions struct
function NewServer (line 22) | func NewServer(ctx context.Context, logger log.ContextLogger, options op...
function NewServerWithOptions (line 30) | func NewServerWithOptions(options ServerOptions) (ServerConfig, error) {
function ServerHandshake (line 48) | func ServerHandshake(ctx context.Context, conn net.Conn, config ServerCo...
FILE: common/tls/std_client.go
type STDClientConfig (line 25) | type STDClientConfig struct
method ServerName (line 39) | func (c *STDClientConfig) ServerName() string {
method SetServerName (line 43) | func (c *STDClientConfig) SetServerName(serverName string) {
method NextProtos (line 57) | func (c *STDClientConfig) NextProtos() []string {
method SetNextProtos (line 61) | func (c *STDClientConfig) SetNextProtos(nextProto []string) {
method HandshakeTimeout (line 65) | func (c *STDClientConfig) HandshakeTimeout() time.Duration {
method SetHandshakeTimeout (line 69) | func (c *STDClientConfig) SetHandshakeTimeout(timeout time.Duration) {
method STDConfig (line 73) | func (c *STDClientConfig) STDConfig() (*STDConfig, error) {
method Client (line 77) | func (c *STDClientConfig) Client(conn net.Conn) (Conn, error) {
method Clone (line 88) | func (c *STDClientConfig) Clone() Config {
method ECHConfigList (line 106) | func (c *STDClientConfig) ECHConfigList() []byte {
method SetECHConfigList (line 110) | func (c *STDClientConfig) SetECHConfigList(EncryptedClientHelloConfigL...
function NewSTDClient (line 114) | func NewSTDClient(ctx context.Context, logger logger.ContextLogger, serv...
function newSTDClient (line 118) | func newSTDClient(ctx context.Context, logger logger.ContextLogger, serv...
function verifyConnection (line 269) | func verifyConnection(rootCAs *x509.CertPool, timeFunc func() time.Time,...
function VerifyPublicKeySHA256 (line 278) | func VerifyPublicKeySHA256(knownHashValues [][]byte, rawCerts [][]byte) ...
FILE: common/tls/std_server.go
type managedCertificateProvider (line 27) | type managedCertificateProvider interface
type sharedCertificateProvider (line 32) | type sharedCertificateProvider struct
method Start (line 38) | func (p *sharedCertificateProvider) Start() error {
method Close (line 47) | func (p *sharedCertificateProvider) Close() error {
method GetCertificate (line 51) | func (p *sharedCertificateProvider) GetCertificate(hello *tls.ClientHe...
method GetACMENextProtos (line 55) | func (p *sharedCertificateProvider) GetACMENextProtos() []string {
type inlineCertificateProvider (line 59) | type inlineCertificateProvider struct
method Start (line 63) | func (p *inlineCertificateProvider) Start() error {
method Close (line 73) | func (p *inlineCertificateProvider) Close() error {
method GetCertificate (line 77) | func (p *inlineCertificateProvider) GetCertificate(hello *tls.ClientHe...
method GetACMENextProtos (line 81) | func (p *inlineCertificateProvider) GetACMENextProtos() []string {
function getACMENextProtos (line 85) | func getACMENextProtos(provider adapter.CertificateProvider) []string {
type STDServerConfig (line 92) | type STDServerConfig struct
method ServerName (line 108) | func (c *STDServerConfig) ServerName() string {
method SetServerName (line 114) | func (c *STDServerConfig) SetServerName(serverName string) {
method NextProtos (line 122) | func (c *STDServerConfig) NextProtos() []string {
method SetNextProtos (line 131) | func (c *STDServerConfig) SetNextProtos(nextProto []string) {
method HandshakeTimeout (line 143) | func (c *STDServerConfig) HandshakeTimeout() time.Duration {
method SetHandshakeTimeout (line 149) | func (c *STDServerConfig) SetHandshakeTimeout(timeout time.Duration) {
method hasACMEALPN (line 155) | func (c *STDServerConfig) hasACMEALPN() bool {
method STDConfig (line 167) | func (c *STDServerConfig) STDConfig() (*STDConfig, error) {
method Client (line 171) | func (c *STDServerConfig) Client(conn net.Conn) (Conn, error) {
method Server (line 175) | func (c *STDServerConfig) Server(conn net.Conn) (Conn, error) {
method Clone (line 179) | func (c *STDServerConfig) Clone() Config {
method Start (line 186) | func (c *STDServerConfig) Start() error {
method startWatcher (line 222) | func (c *STDServerConfig) startWatcher() error {
method certificateUpdated (line 259) | func (c *STDServerConfig) certificateUpdated(path string) error {
method Close (line 323) | func (c *STDServerConfig) Close() error {
function NewSTDServer (line 327) | func NewSTDServer(ctx context.Context, logger log.ContextLogger, options...
function newCertificateProvider (line 529) | func newCertificateProvider(ctx context.Context, logger log.ContextLogge...
FILE: common/tls/system_client.go
type SystemTLSValidated (line 16) | type SystemTLSValidated struct
function ValidateSystemTLSOptions (line 24) | func ValidateSystemTLSOptions(ctx context.Context, options option.Outbou...
function resolveSystemAnchors (line 87) | func resolveSystemAnchors(ctx context.Context, options option.OutboundTL...
function verifySystemTLSPeer (line 105) | func verifySystemTLSPeer(roots *x509.CertPool, serverName string, timeFu...
FILE: common/tls/system_client_engine.go
type systemTLSConfig (line 18) | type systemTLSConfig struct
method ServerName (line 31) | func (c *systemTLSConfig) ServerName() string {
method SetServerName (line 35) | func (c *systemTLSConfig) SetServerName(serverName string) {
method NextProtos (line 39) | func (c *systemTLSConfig) NextProtos() []string {
method SetNextProtos (line 43) | func (c *systemTLSConfig) SetNextProtos(nextProto []string) {
method HandshakeTimeout (line 47) | func (c *systemTLSConfig) HandshakeTimeout() time.Duration {
method SetHandshakeTimeout (line 51) | func (c *systemTLSConfig) SetHandshakeTimeout(timeout time.Duration) {
method STDConfig (line 55) | func (c *systemTLSConfig) STDConfig() (*STDConfig, error) {
method Client (line 59) | func (c *systemTLSConfig) Client(conn net.Conn) (Conn, error) {
method clone (line 63) | func (c *systemTLSConfig) clone() systemTLSConfig {
function newSystemTLSConfig (line 78) | func newSystemTLSConfig(ctx context.Context, serverAddress string, optio...
FILE: common/tls/time_wrapper.go
type TimeServiceWrapper (line 9) | type TimeServiceWrapper struct
method TimeFunc (line 13) | func (w *TimeServiceWrapper) TimeFunc() func() time.Time {
method Upstream (line 23) | func (w *TimeServiceWrapper) Upstream() any {
FILE: common/tls/utls_client.go
type UTLSClientConfig (line 29) | type UTLSClientConfig struct
method ServerName (line 44) | func (c *UTLSClientConfig) ServerName() string {
method SetServerName (line 48) | func (c *UTLSClientConfig) SetServerName(serverName string) {
method NextProtos (line 62) | func (c *UTLSClientConfig) NextProtos() []string {
method SetNextProtos (line 66) | func (c *UTLSClientConfig) SetNextProtos(nextProto []string) {
method HandshakeTimeout (line 73) | func (c *UTLSClientConfig) HandshakeTimeout() time.Duration {
method SetHandshakeTimeout (line 77) | func (c *UTLSClientConfig) SetHandshakeTimeout(timeout time.Duration) {
method STDConfig (line 81) | func (c *UTLSClientConfig) STDConfig() (*STDConfig, error) {
method Client (line 85) | func (c *UTLSClientConfig) Client(conn net.Conn) (Conn, error) {
method SetSessionIDGenerator (line 96) | func (c *UTLSClientConfig) SetSessionIDGenerator(generator func(client...
method Clone (line 100) | func (c *UTLSClientConfig) Clone() Config {
method ECHConfigList (line 119) | func (c *UTLSClientConfig) ECHConfigList() []byte {
method SetECHConfigList (line 123) | func (c *UTLSClientConfig) SetECHConfigList(EncryptedClientHelloConfig...
type utlsConnWrapper (line 127) | type utlsConnWrapper struct
method ConnectionState (line 131) | func (c *utlsConnWrapper) ConnectionState() tls.ConnectionState {
method Upstream (line 150) | func (c *utlsConnWrapper) Upstream() any {
method ReaderReplaceable (line 154) | func (c *utlsConnWrapper) ReaderReplaceable() bool {
method WriterReplaceable (line 158) | func (c *utlsConnWrapper) WriterReplaceable() bool {
type utlsALPNWrapper (line 162) | type utlsALPNWrapper struct
method HandshakeContext (line 167) | func (c *utlsALPNWrapper) HandshakeContext(ctx context.Context) error {
function NewUTLSClient (line 187) | func NewUTLSClient(ctx context.Context, logger logger.ContextLogger, ser...
function newUTLSClient (line 191) | func newUTLSClient(ctx context.Context, logger logger.ContextLogger, ser...
function init (line 353) | func init() {
function uTLSClientHelloID (line 371) | func uTLSClientHelloID(name string) (utls.ClientHelloID, error) {
FILE: common/tls/utls_client_test.go
function newUTLSClientConfigForGateTest (line 21) | func newUTLSClientConfigForGateTest(fragment, recordFragment bool) *UTLS...
function TestUTLSClient_Client_NoFragment_DoesNotWrap (line 31) | func TestUTLSClient_Client_NoFragment_DoesNotWrap(t *testing.T) {
function TestUTLSClient_Client_FragmentOnly_Wraps (line 42) | func TestUTLSClient_Client_FragmentOnly_Wraps(t *testing.T) {
function TestUTLSClient_Client_RecordFragmentOnly_Wraps (line 53) | func TestUTLSClient_Client_RecordFragmentOnly_Wraps(t *testing.T) {
function TestUTLSClient_Client_BothFragment_Wraps (line 64) | func TestUTLSClient_Client_BothFragment_Wraps(t *testing.T) {
FILE: common/tls/utls_stub.go
function NewUTLSClient (line 14) | func NewUTLSClient(ctx context.Context, logger logger.ContextLogger, ser...
function newUTLSClient (line 18) | func newUTLSClient(ctx context.Context, logger logger.ContextLogger, ser...
function NewRealityClient (line 22) | func NewRealityClient(ctx context.Context, logger logger.ContextLogger, ...
function newRealityClient (line 26) | func newRealityClient(ctx context.Context, logger logger.ContextLogger, ...
function NewRealityServer (line 30) | func NewRealityServer(ctx context.Context, logger log.Logger, options op...
FILE: common/tls/windows_client.go
constant windowsTLSEngineName (line 27) | windowsTLSEngineName = "Windows TLS engine"
constant handshakeReadChunkSize (line 28) | handshakeReadChunkSize = 8192
constant readScratchSize (line 29) | readScratchSize = 16 * 1024
constant readWaitCiphertextChunkSize (line 30) | readWaitCiphertextChunkSize = 4096
type windowsClientConfig (line 33) | type windowsClientConfig struct
method Clone (line 38) | func (c *windowsClientConfig) Clone() Config {
method ClientHandshake (line 67) | func (c *windowsClientConfig) ClientHandshake(ctx context.Context, con...
method verifyPeerCertificates (line 280) | func (c *windowsClientConfig) verifyPeerCertificates(peerCertificates ...
function newWindowsClient (line 45) | func newWindowsClient(ctx context.Context, logger logger.ContextLogger, ...
function driveHandshake (line 129) | func driveHandshake(ctx context.Context, conn net.Conn, client *schannel...
function driveSteps (line 151) | func driveSteps(
function installHandshakeCancel (line 200) | func installHandshakeCancel(ctx context.Context, conn net.Conn) func() {
function handshakeIOError (line 219) | func handshakeIOError(ctx context.Context, err error, message string) er...
function readTLSRaw (line 227) | func readTLSRaw(conn net.Conn, scratch []byte, requireMore bool) ([]byte...
function isTimeoutError (line 241) | func isTimeoutError(err error) bool {
function buildConnectionState (line 249) | func buildConnectionState(serverName string, client *schannel.ClientCont...
type windowsTLSConn (line 294) | type windowsTLSConn struct
method Read (line 334) | func (c *windowsTLSConn) Read(p []byte) (int, error) {
method ReadBuffer (line 346) | func (c *windowsTLSConn) ReadBuffer(buffer *buf.Buffer) error {
method readIntoLocked (line 361) | func (c *windowsTLSConn) readIntoLocked(p []byte, appendCipher windows...
method readPlaintextLocked (line 373) | func (c *windowsTLSConn) readPlaintextLocked(appendCipher windowsTLSAp...
method drivePostHandshake (line 431) | func (c *windowsTLSConn) drivePostHandshake(readRaw windowsTLSReadRawF...
method writePostHandshakeReplyLocked (line 474) | func (c *windowsTLSConn) writePostHandshakeReplyLocked(data []byte) er...
method decrypt (line 487) | func (c *windowsTLSConn) decrypt(input []byte) (schannel.DecryptResult...
method encrypt (line 496) | func (c *windowsTLSConn) encrypt(plaintext []byte) ([]byte, error) {
method readRaw (line 508) | func (c *windowsTLSConn) readRaw(requireMore bool) ([]byte, error) {
method appendRaw (line 515) | func (c *windowsTLSConn) appendRaw(requireMore bool) error {
method Write (line 524) | func (c *windowsTLSConn) Write(p []byte) (int, error) {
method WriteBuffer (line 568) | func (c *windowsTLSConn) WriteBuffer(buffer *buf.Buffer) error {
method CreateReadWaiter (line 574) | func (c *windowsTLSConn) CreateReadWaiter() (N.ReadWaiter, bool) {
method Close (line 585) | func (c *windowsTLSConn) Close() error {
method LocalAddr (line 603) | func (c *windowsTLSConn) LocalAddr() net.Addr {
method RemoteAddr (line 607) | func (c *windowsTLSConn) RemoteAddr() net.Addr {
method SetDeadline (line 611) | func (c *windowsTLSConn) SetDeadline(t time.Time) error {
method SetReadDeadline (line 623) | func (c *windowsTLSConn) SetReadDeadline(t time.Time) error {
method SetWriteDeadline (line 634) | func (c *windowsTLSConn) SetWriteDeadline(t time.Time) error {
method NetConn (line 645) | func (c *windowsTLSConn) NetConn() net.Conn {
method HandshakeContext (line 649) | func (c *windowsTLSConn) HandshakeContext(ctx context.Context) error {
method ConnectionState (line 653) | func (c *windowsTLSConn) ConnectionState() ConnectionState {
method applyReadDeadline (line 657) | func (c *windowsTLSConn) applyReadDeadline() (func(), error) {
method applyWriteDeadline (line 664) | func (c *windowsTLSConn) applyWriteDeadline() (func(), error) {
method applyDeadline (line 671) | func (c *windowsTLSConn) applyDeadline(deadline time.Time, set func(ti...
method beginWrite (line 685) | func (c *windowsTLSConn) beginWrite() error {
method finishWrite (line 710) | func (c *windowsTLSConn) finishWrite() {
method beginPostHandshakeWrite (line 719) | func (c *windowsTLSConn) beginPostHandshakeWrite() error {
method finishPostHandshakeWrite (line 748) | func (c *windowsTLSConn) finishPostHandshakeWrite() {
method writeCondition (line 758) | func (c *windowsTLSConn) writeCondition() *sync.Cond {
method isClosed (line 765) | func (c *windowsTLSConn) isClosed() bool {
type windowsTLSAppendCipherFunc (line 330) | type windowsTLSAppendCipherFunc
type windowsTLSReadRawFunc (line 331) | type windowsTLSReadRawFunc
type windowsTLSReadWaiter (line 769) | type windowsTLSReadWaiter struct
method InitializeReadWaiter (line 777) | func (w *windowsTLSReadWaiter) InitializeReadWaiter(options N.ReadWait...
method WaitReadBuffer (line 785) | func (w *windowsTLSReadWaiter) WaitReadBuffer() (*buf.Buffer, error) {
method appendRaw (line 813) | func (w *windowsTLSReadWaiter) appendRaw(requireMore bool) error {
method readRaw (line 823) | func (w *windowsTLSReadWaiter) readRaw(requireMore bool) ([]byte, erro...
method readRawBuffer (line 833) | func (w *windowsTLSReadWaiter) readRawBuffer(requireMore bool) (*buf.B...
FILE: common/tls/windows_client_stub.go
function newWindowsClient (line 13) | func newWindowsClient(ctx context.Context, logger logger.ContextLogger, ...
FILE: common/tls/windows_client_test.go
constant windowsTLSTestTimeout (line 30) | windowsTLSTestTimeout = 5 * time.Second
function newTestWindowsTLSConn (line 37) | func newTestWindowsTLSConn(rawConn net.Conn) *windowsTLSConn {
method writePostHandshakeReply (line 46) | func (c *windowsTLSConn) writePostHandshakeReply(data []byte) error {
type windowsTLSServerResult (line 56) | type windowsTLSServerResult struct
type windowsTestDeadlineConn (line 61) | type windowsTestDeadlineConn struct
method Read (line 87) | func (c *windowsTestDeadlineConn) Read(_ []byte) (int, error) {
method Write (line 109) | func (c *windowsTestDeadlineConn) Write(_ []byte) (int, error) {
method Close (line 131) | func (c *windowsTestDeadlineConn) Close() error {
method LocalAddr (line 135) | func (c *windowsTestDeadlineConn) LocalAddr() net.Addr {
method RemoteAddr (line 139) | func (c *windowsTestDeadlineConn) RemoteAddr() net.Addr {
method SetDeadline (line 143) | func (c *windowsTestDeadlineConn) SetDeadline(t time.Time) error {
method SetReadDeadline (line 153) | func (c *windowsTestDeadlineConn) SetReadDeadline(t time.Time) error {
method SetWriteDeadline (line 161) | func (c *windowsTestDeadlineConn) SetWriteDeadline(t time.Time) error {
method recordedWriteDeadlines (line 169) | func (c *windowsTestDeadlineConn) recordedWriteDeadlines() []time.Time {
method recordedReadDeadlines (line 175) | func (c *windowsTestDeadlineConn) recordedReadDeadlines() []time.Time {
type windowsTestWriteGateConn (line 73) | type windowsTestWriteGateConn struct
method Read (line 181) | func (c *windowsTestWriteGateConn) Read(_ []byte) (int, error) {
method Write (line 185) | func (c *windowsTestWriteGateConn) Write(p []byte) (int, error) {
method Close (line 191) | func (c *windowsTestWriteGateConn) Close() error {
method LocalAddr (line 195) | func (c *windowsTestWriteGateConn) LocalAddr() net.Addr {
method RemoteAddr (line 199) | func (c *windowsTestWriteGateConn) RemoteAddr() net.Addr {
method SetDeadline (line 203) | func (c *windowsTestWriteGateConn) SetDeadline(time.Time) error {
method SetReadDeadline (line 207) | func (c *windowsTestWriteGateConn) SetReadDeadline(time.Time) error {
method SetWriteDeadline (line 211) | func (c *windowsTestWriteGateConn) SetWriteDeadline(time.Time) error {
type windowsTestIOConn (line 78) | type windowsTestIOConn struct
method Read (line 215) | func (c *windowsTestIOConn) Read(_ []byte) (int, error) {
method Write (line 219) | func (c *windowsTestIOConn) Write(p []byte) (int, error) {
method Close (line 233) | func (c *windowsTestIOConn) Close() error {
method LocalAddr (line 240) | func (c *windowsTestIOConn) LocalAddr() net.Addr {
method RemoteAddr (line 244) | func (c *windowsTestIOConn) RemoteAddr() net.Addr {
method SetDeadline (line 248) | func (c *windowsTestIOConn) SetDeadline(time.Time) error {
method SetReadDeadline (line 252) | func (c *windowsTestIOConn) SetReadDeadline(time.Time) error {
method SetWriteDeadline (line 256) | func (c *windowsTestIOConn) SetWriteDeadline(time.Time) error {
method isClosed (line 260) | func (c *windowsTestIOConn) isClosed() bool {
method totalWriteCalls (line 266) | func (c *windowsTestIOConn) totalWriteCalls() int {
type windowsTestAddr (line 272) | type windowsTestAddr
method Network (line 274) | func (a windowsTestAddr) Network() string {
method String (line 278) | func (a windowsTestAddr) String() string {
type windowsOpaqueConn (line 282) | type windowsOpaqueConn struct
function TestWindowsClientHandshakeTLS12 (line 286) | func TestWindowsClientHandshakeTLS12(t *testing.T) {
function TestWindowsClientHandshakeWrappedConn (line 335) | func TestWindowsClientHandshakeWrappedConn(t *testing.T) {
function TestWindowsClientHandshakeTLS13 (line 380) | func TestWindowsClientHandshakeTLS13(t *testing.T) {
function TestWindowsClientHandshakeALPNNoOverlap (line 419) | func TestWindowsClientHandshakeALPNNoOverlap(t *testing.T) {
function TestWindowsClientHandshakeMultipleALPN (line 445) | func TestWindowsClientHandshakeMultipleALPN(t *testing.T) {
function TestWindowsClientHandshakeRejectsVersionMismatch (line 474) | func TestWindowsClientHandshakeRejectsVersionMismatch(t *testing.T) {
function TestWindowsClientHandshakeRejectsServerNameMismatch (line 500) | func TestWindowsClientHandshakeRejectsServerNameMismatch(t *testing.T) {
function TestWindowsClientHandshakeRejectsUntrustedCA (line 518) | func TestWindowsClientHandshakeRejectsUntrustedCA(t *testing.T) {
function TestWindowsClientHandshakeInsecureSkipsValidation (line 535) | func TestWindowsClientHandshakeInsecureSkipsValidation(t *testing.T) {
function TestWindowsClientHandshakeHonorsPublicKeyPinSuccess (line 558) | func TestWindowsClientHandshakeHonorsPublicKeyPinSuccess(t *testing.T) {
function TestWindowsClientHandshakeHonorsPublicKeyPinFailure (line 577) | func TestWindowsClientHandshakeHonorsPublicKeyPinFailure(t *testing.T) {
function TestWindowsClientHandshakeContextCancellation (line 596) | func TestWindowsClientHandshakeContextCancellation(t *testing.T) {
function TestWindowsClientHandshakeTimeout (line 670) | func TestWindowsClientHandshakeTimeout(t *testing.T) {
function TestWindowsClientRoundtrip (line 724) | func TestWindowsClientRoundtrip(t *testing.T) {
function TestWindowsClientRoundtripTLS13 (line 745) | func TestWindowsClientRoundtripTLS13(t *testing.T) {
function TestWindowsClientReadBuffer (line 767) | func TestWindowsClientReadBuffer(t *testing.T) {
function TestWindowsClientWriteBuffer (line 796) | func TestWindowsClientWriteBuffer(t *testing.T) {
function TestWindowsClientCreateReadWaiter (line 828) | func TestWindowsClientCreateReadWaiter(t *testing.T) {
function TestWindowsClientCreateReadWaiterFallback (line 862) | func TestWindowsClientCreateReadWaiterFallback(t *testing.T) {
function TestWindowsClientTLS13PostHandshakeConcurrentWrite (line 870) | func TestWindowsClientTLS13PostHandshakeConcurrentWrite(t *testing.T) {
function TestWindowsClientLargeMessage (line 976) | func TestWindowsClientLargeMessage(t *testing.T) {
function TestWindowsClientFullDuplexLargePayload (line 1009) | func TestWindowsClientFullDuplexLargePayload(t *testing.T) {
function TestWindowsClientMultipleRoundtrips (line 1109) | func TestWindowsClientMultipleRoundtrips(t *testing.T) {
function TestWindowsClientConcurrentReadWrite (line 1133) | func TestWindowsClientConcurrentReadWrite(t *testing.T) {
function TestWindowsClientServerCloseReturnsEOF (line 1185) | func TestWindowsClientServerCloseReturnsEOF(t *testing.T) {
function TestWindowsClientCloseUnblocksRead (line 1231) | func TestWindowsClientCloseUnblocksRead(t *testing.T) {
function TestWindowsClientReadAfterCloseReturnsError (line 1270) | func TestWindowsClientReadAfterCloseReturnsError(t *testing.T) {
function TestWindowsClientReadAfterCloseDoesNotServeBufferedPlaintext (line 1282) | func TestWindowsClientReadAfterCloseDoesNotServeBufferedPlaintext(t *tes...
function TestWindowsClientWriteAfterCloseReturnsError (line 1360) | func TestWindowsClientWriteAfterCloseReturnsError(t *testing.T) {
function TestWindowsClientReadDeadline (line 1371) | func TestWindowsClientReadDeadline(t *testing.T) {
function TestWindowsClientSetReadDeadlinePreExpired (line 1414) | func TestWindowsClientSetReadDeadlinePreExpired(t *testing.T) {
function TestWindowsClientSetDeadlinePropagatesToRawConn (line 1466) | func TestWindowsClientSetDeadlinePropagatesToRawConn(t *testing.T) {
function TestWindowsClientSetReadDeadlineCancelsBlockedRead (line 1493) | func TestWindowsClientSetReadDeadlineCancelsBlockedRead(t *testing.T) {
function TestWindowsClientSetWriteDeadlineCancelsBlockedWrite (line 1536) | func TestWindowsClientSetWriteDeadlineCancelsBlockedWrite(t *testing.T) {
function TestWindowsClientPostHandshakeReplyUsesReadDeadline (line 1602) | func TestWindowsClientPostHandshakeReplyUsesReadDeadline(t *testing.T) {
function TestWindowsClientPostHandshakeReplyPreExpiredReadDeadline (line 1634) | func TestWindowsClientPostHandshakeReplyPreExpiredReadDeadline(t *testin...
function TestDriveStepsPreservesBufferedHandshakeBytes (line 1659) | func TestDriveStepsPreservesBufferedHandshakeBytes(t *testing.T) {
function TestWindowsTLSRawReadEOFAtRecordBoundary (line 1703) | func TestWindowsTLSRawReadEOFAtRecordBoundary(t *testing.T) {
function TestWindowsTLSRawReadEOFWithPendingRecord (line 1711) | func TestWindowsTLSRawReadEOFWithPendingRecord(t *testing.T) {
function TestWindowsClientPostHandshakeReplyWaitsForWriteAccess (line 1719) | func TestWindowsClientPostHandshakeReplyWaitsForWriteAccess(t *testing.T) {
function TestWindowsClientPostHandshakeWritePreemptsNewWrite (line 1753) | func TestWindowsClientPostHandshakeWritePreemptsNewWrite(t *testing.T) {
function TestWindowsClientPostHandshakeReplyErrorClosesConn (line 1817) | func TestWindowsClientPostHandshakeReplyErrorClosesConn(t *testing.T) {
function TestWindowsClientWriteErrorClosesConn (line 1836) | func TestWindowsClientWriteErrorClosesConn(t *testing.T) {
function TestWindowsClientConnectionStateFields (line 1892) | func TestWindowsClientConnectionStateFields(t *testing.T) {
function TestWindowsClientNetConnReturnsUnderlying (line 1940) | func TestWindowsClientNetConnReturnsUnderlying(t *testing.T) {
function TestNewWindowsClientMissingServerName (line 1951) | func TestNewWindowsClientMissingServerName(t *testing.T) {
function TestNewWindowsClientInsecureAllowsMissingServerName (line 1965) | func TestNewWindowsClientInsecureAllowsMissingServerName(t *testing.T) {
function TestWindowsClientConfigSTDConfigReturnsError (line 1980) | func TestWindowsClientConfigSTDConfigReturnsError(t *testing.T) {
function TestWindowsClientConfigClientReturnsErrInvalid (line 2002) | func TestWindowsClientConfigClientReturnsErrInvalid(t *testing.T) {
function TestWindowsClientConfigClone (line 2021) | func TestWindowsClientConfigClone(t *testing.T) {
function TestValidateWindowsTLSOptionsRejections (line 2049) | func TestValidateWindowsTLSOptionsRejections(t *testing.T) {
function startWindowsTLSSilentServer (line 2126) | func startWindowsTLSSilentServer(t *testing.T, tlsConfig *stdtls.Config)...
function newWindowsTestCertificate (line 2174) | func newWindowsTestCertificate(t *testing.T, serverName string) (stdtls....
function generateWindowsTestCertificate (line 2182) | func generateWindowsTestCertificate(serverName
Condensed preview — 1205 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (5,881K chars).
[
{
"path": ".fpm_openwrt",
"chars": 963,
"preview": "-s dir\n--name sing-box\n--category net\n--license GPL-3.0-or-later\n--description \"The universal proxy platform.\"\n--url \"ht"
},
{
"path": ".fpm_pacman",
"chars": 1013,
"preview": "-s dir\n--name sing-box\n--category net\n--license GPL-3.0-or-later\n--description \"The universal proxy platform.\"\n--url \"ht"
},
{
"path": ".fpm_systemd",
"chars": 1121,
"preview": "-s dir\n--name sing-box\n--category net\n--license GPL-3.0-or-later\n--description \"The universal proxy platform.\"\n--url \"ht"
},
{
"path": ".github/CRONET_GO_VERSION",
"chars": 41,
"preview": "2faf34666c2cc8234f10f2ab6d4c4d6104d34ae2\n"
},
{
"path": ".github/FUNDING.yml",
"chars": 19,
"preview": "github: nekohasekai"
},
{
"path": ".github/ISSUE_TEMPLATE/bug_report.yml",
"chars": 4024,
"preview": "name: Bug report\ndescription: \"Report sing-box bug\"\nbody:\n - type: dropdown\n attributes:\n label: Operating syst"
},
{
"path": ".github/ISSUE_TEMPLATE/bug_report_zh.yml",
"chars": 2413,
"preview": "name: 错误反馈\ndescription: \"提交 sing-box 漏洞\"\nbody:\n - type: dropdown\n attributes:\n label: 操作系统\n description: 请"
},
{
"path": ".github/build_alpine_apk.sh",
"chars": 3137,
"preview": "#!/usr/bin/env bash\n\nset -e -o pipefail\n\nprepare_apk_root() {\n # apk mkpkg resolves owner/group names through --root/et"
},
{
"path": ".github/build_openwrt_apk.sh",
"chars": 3113,
"preview": "#!/usr/bin/env bash\n\nset -e -o pipefail\n\nprepare_apk_root() {\n # apk mkpkg resolves owner/group names through --root/et"
},
{
"path": ".github/deb2ipk.sh",
"chars": 555,
"preview": "#!/usr/bin/env bash\n# mod from https://gist.github.com/pldubouilh/c5703052986bfdd404005951dee54683\n\nset -e -o pipefail\n\n"
},
{
"path": ".github/detect_track.sh",
"chars": 1044,
"preview": "#!/usr/bin/env bash\nset -euo pipefail\n\nbranches=$(git branch -r --contains HEAD)\nif echo \"$branches\" | grep -q 'origin/s"
},
{
"path": ".github/renovate.json",
"chars": 489,
"preview": "{\n \"$schema\": \"https://docs.renovatebot.com/renovate-schema.json\",\n \"commitMessagePrefix\": \"[dependencies]\",\n \"extend"
},
{
"path": ".github/setup_go_for_macos1013.sh",
"chars": 1338,
"preview": "#!/usr/bin/env bash\n\nset -euo pipefail\n\nVERSION=\"1.25.9\"\nPATCH_COMMITS=(\n \"afe69d3cec1c6dcf0f1797b20546795730850070\"\n "
},
{
"path": ".github/setup_go_for_windows7.sh",
"chars": 1687,
"preview": "#!/usr/bin/env bash\n\nset -euo pipefail\n\nVERSION=\"1.25.9\"\nPATCH_COMMITS=(\n \"466f6c7a29bc098b0d4c987b803c779222894a11\"\n "
},
{
"path": ".github/update_clients.sh",
"chars": 215,
"preview": "#!/usr/bin/env bash\n\nPROJECTS=$(dirname \"$0\")/../..\n\nfunction updateClient() {\n pushd clients/$1\n git fetch\n git rese"
},
{
"path": ".github/update_cronet.sh",
"chars": 461,
"preview": "#!/usr/bin/env bash\n\nset -e -o pipefail\n\nSCRIPT_DIR=$(dirname \"$0\")\nPROJECTS=$SCRIPT_DIR/../..\n\ngit -C $PROJECTS/cronet-"
},
{
"path": ".github/update_cronet_dev.sh",
"chars": 473,
"preview": "#!/usr/bin/env bash\n\nset -e -o pipefail\n\nSCRIPT_DIR=$(dirname \"$0\")\nPROJECTS=$SCRIPT_DIR/../..\n\ngit -C $PROJECTS/cronet-"
},
{
"path": ".github/update_dependencies.sh",
"chars": 135,
"preview": "#!/usr/bin/env bash\n\nPROJECTS=$(dirname \"$0\")/../..\ngo get -x github.com/sagernet/$1@$(git -C $PROJECTS/$1 rev-parse HEA"
},
{
"path": ".github/workflows/build.yml",
"chars": 43490,
"preview": "name: Build\n\non:\n workflow_dispatch:\n inputs:\n version:\n description: \"Version name\"\n required: t"
},
{
"path": ".github/workflows/docker.yml",
"chars": 10724,
"preview": "name: Publish Docker Images\n\non:\n #push:\n # branches:\n # - stable\n # - testing\n release:\n types:\n - "
},
{
"path": ".github/workflows/lint.yml",
"chars": 1816,
"preview": "name: Lint\n\non:\n push:\n branches:\n - oldstable\n - stable\n - testing\n - unstable\n paths-ignore"
},
{
"path": ".github/workflows/linux.yml",
"chars": 9774,
"preview": "name: Build Linux Packages\n\non:\n #push:\n # branches:\n # - stable\n # - testing\n workflow_dispatch:\n inputs"
},
{
"path": ".github/workflows/stale.yml",
"chars": 462,
"preview": "name: Mark stale issues and pull requests\n\non:\n schedule:\n - cron: \"30 1 * * *\"\n\njobs:\n stale:\n runs-on: ubuntu-"
},
{
"path": ".github/workflows/test.yml",
"chars": 1421,
"preview": "name: Test\n\non:\n push:\n branches:\n - stable\n - testing\n - unstable\n paths-ignore:\n - '**.md'\n"
},
{
"path": ".gitignore",
"chars": 270,
"preview": "/.idea/\n/vendor/\n/*.json\n/*.srs\n/*.db\n/site/\n/bin/\n/dist/\n/sing-box\n/sing-box.exe\n/build/\n/*.jar\n/*.aar\n/*.xcframework/\n"
},
{
"path": ".gitmodules",
"chars": 222,
"preview": "[submodule \"clients/apple\"]\n\tpath = clients/apple\n\turl = https://github.com/SagerNet/sing-box-for-apple.git\n[submodule \""
},
{
"path": ".golangci.yml",
"chars": 1135,
"preview": "version: \"2\"\nrun:\n go: \"1.24\"\n build-tags:\n - with_gvisor\n - with_quic\n - with_dhcp\n - with_wireguard\n "
},
{
"path": "Dockerfile",
"chars": 1087,
"preview": "FROM --platform=$BUILDPLATFORM golang:1.25-alpine AS builder\nLABEL maintainer=\"nekohasekai <contact-git@sekai.icu>\"\nCOPY"
},
{
"path": "Dockerfile.binary",
"chars": 525,
"preview": "ARG BASE_IMAGE=alpine\nFROM ${BASE_IMAGE}\nARG TARGETARCH\nARG TARGETVARIANT\nLABEL maintainer=\"nekohasekai <contact-git@sek"
},
{
"path": "LICENSE",
"chars": 791,
"preview": "Copyright (C) 2022 by nekohasekai <contact-sagernet@sekai.icu>\n\nThis program is free software: you can redistribute it a"
},
{
"path": "Makefile",
"chars": 10131,
"preview": "NAME = sing-box\nCOMMIT = $(shell git rev-parse --short HEAD)\nTAGS ?= $(shell cat release/DEFAULT_BUILD_TAGS_OTHERS)\n\nGOH"
},
{
"path": "README.md",
"chars": 1032,
"preview": "# sing-box\n\nThe universal proxy platform.\n\n[\n\ntype CertificateStore interf"
},
{
"path": "adapter/certificate_darwin.go",
"chars": 315,
"preview": "//go:build darwin && cgo\n\npackage adapter\n\nimport \"unsafe\"\n\ntype AppleAnchors interface {\n\tRetain() AppleAnchors\n\tReleas"
},
{
"path": "adapter/certificate_provider.go",
"chars": 966,
"preview": "package adapter\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\t\"github.com/sagernet/sing-box/o"
},
{
"path": "adapter/connections.go",
"chars": 502,
"preview": "package adapter\n\nimport (\n\t\"context\"\n\t\"net\"\n\n\tN \"github.com/sagernet/sing/common/network\"\n)\n\ntype ConnectionManager inte"
},
{
"path": "adapter/dns.go",
"chars": 3797,
"preview": "package adapter\n\nimport (\n\t\"context\"\n\t\"net/netip\"\n\t\"time\"\n\n\tC \"github.com/sagernet/sing-box/constant\"\n\t\"github.com/sager"
},
{
"path": "adapter/endpoint/adapter.go",
"chars": 984,
"preview": "package endpoint\n\nimport \"github.com/sagernet/sing-box/option\"\n\ntype Adapter struct {\n\tendpointType string\n\tendpointTag "
},
{
"path": "adapter/endpoint/manager.go",
"chars": 4030,
"preview": "package endpoint\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"sync\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.com/sagernet/sing-"
},
{
"path": "adapter/endpoint/registry.go",
"chars": 2300,
"preview": "package endpoint\n\nimport (\n\t\"context\"\n\t\"sync\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.com/sagernet/sing-box/lo"
},
{
"path": "adapter/endpoint.go",
"chars": 650,
"preview": "package adapter\n\nimport (\n\t\"context\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\t\"github.com/sagernet/sing-box/option\"\n)\n\ntype"
},
{
"path": "adapter/experimental.go",
"chars": 3246,
"preview": "package adapter\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/binary\"\n\t\"io\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing/common/observ"
},
{
"path": "adapter/fakeip.go",
"chars": 786,
"preview": "package adapter\n\nimport (\n\t\"net/netip\"\n\n\t\"github.com/sagernet/sing/common/logger\"\n)\n\ntype FakeIPStore interface {\n\tSimpl"
},
{
"path": "adapter/fakeip_metadata.go",
"chars": 1183,
"preview": "package adapter\n\nimport (\n\t\"bytes\"\n\t\"encoding\"\n\t\"encoding/binary\"\n\t\"io\"\n\t\"net/netip\"\n\n\t\"github.com/sagernet/sing/common\""
},
{
"path": "adapter/handler.go",
"chars": 858,
"preview": "package adapter\n\nimport (\n\t\"context\"\n\t\"net\"\n\n\t\"github.com/sagernet/sing/common/buf\"\n\tM \"github.com/sagernet/sing/common/"
},
{
"path": "adapter/http.go",
"chars": 879,
"preview": "package adapter\n\nimport (\n\t\"context\"\n\t\"net/http\"\n\t\"sync\"\n\n\t\"github.com/sagernet/sing-box/option\"\n\t\"github.com/sagernet/s"
},
{
"path": "adapter/inbound/adapter.go",
"chars": 340,
"preview": "package inbound\n\ntype Adapter struct {\n\tinboundType string\n\tinboundTag string\n}\n\nfunc NewAdapter(inboundType string, in"
},
{
"path": "adapter/inbound/manager.go",
"chars": 4018,
"preview": "package inbound\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"sync\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.com/sagernet/sing-b"
},
{
"path": "adapter/inbound/registry.go",
"chars": 2294,
"preview": "package inbound\n\nimport (\n\t\"context\"\n\t\"sync\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.com/sagernet/sing-box/log"
},
{
"path": "adapter/inbound.go",
"chars": 4971,
"preview": "package adapter\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"net/netip\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/common/tlsspoof\"\n\tC \"gi"
},
{
"path": "adapter/inbound_test.go",
"chars": 884,
"preview": "package adapter\n\nimport (\n\t\"net\"\n\t\"net/netip\"\n\t\"testing\"\n\n\t\"github.com/miekg/dns\"\n\t\"github.com/stretchr/testify/require\""
},
{
"path": "adapter/lifecycle.go",
"chars": 2254,
"preview": "package adapter\n\nimport (\n\t\"reflect\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\tE \"github.com/sagernet/sin"
},
{
"path": "adapter/lifecycle_legacy.go",
"chars": 1179,
"preview": "package adapter\n\nfunc LegacyStart(starter any, stage StartStage) error {\n\tif lifecycle, isLifecycle := starter.(Lifecycl"
},
{
"path": "adapter/neighbor.go",
"chars": 460,
"preview": "package adapter\n\nimport (\n\t\"net\"\n\t\"net/netip\"\n)\n\ntype NeighborEntry struct {\n\tAddress netip.Addr\n\tMACAddress net.Hard"
},
{
"path": "adapter/network.go",
"chars": 1825,
"preview": "package adapter\n\nimport (\n\t\"encoding/hex\"\n\t\"net\"\n\t\"strings\"\n\t\"time\"\n\n\tC \"github.com/sagernet/sing-box/constant\"\n\t\"github"
},
{
"path": "adapter/outbound/adapter.go",
"chars": 989,
"preview": "package outbound\n\nimport (\n\t\"github.com/sagernet/sing-box/option\"\n)\n\ntype Adapter struct {\n\toutboundType string\n\toutboun"
},
{
"path": "adapter/outbound/manager.go",
"chars": 9082,
"preview": "package outbound\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.c"
},
{
"path": "adapter/outbound/registry.go",
"chars": 2315,
"preview": "package outbound\n\nimport (\n\t\"context\"\n\t\"sync\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.com/sagernet/sing-box/lo"
},
{
"path": "adapter/outbound.go",
"chars": 1228,
"preview": "package adapter\n\nimport (\n\t\"context\"\n\t\"net/netip\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\t\"github.com/sagernet/sin"
},
{
"path": "adapter/platform.go",
"chars": 1876,
"preview": "package adapter\n\nimport (\n\t\"net/netip\"\n\n\t\"github.com/sagernet/sing-box/option\"\n\t\"github.com/sagernet/sing-tun\"\n\t\"github."
},
{
"path": "adapter/prestart.go",
"chars": 16,
"preview": "package adapter\n"
},
{
"path": "adapter/router.go",
"chars": 2659,
"preview": "package adapter\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-tun\"\n\tN \"github.com/sagernet/sing/common"
},
{
"path": "adapter/rule.go",
"chars": 708,
"preview": "package adapter\n\nimport (\n\tC \"github.com/sagernet/sing-box/constant\"\n\n\t\"github.com/miekg/dns\"\n)\n\ntype HeadlessRule inter"
},
{
"path": "adapter/service/adapter.go",
"chars": 340,
"preview": "package service\n\ntype Adapter struct {\n\tserviceType string\n\tserviceTag string\n}\n\nfunc NewAdapter(serviceType string, se"
},
{
"path": "adapter/service/manager.go",
"chars": 3844,
"preview": "package service\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"sync\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.com/sagernet/sing-b"
},
{
"path": "adapter/service/registry.go",
"chars": 2186,
"preview": "package service\n\nimport (\n\t\"context\"\n\t\"sync\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.com/sagernet/sing-box/log"
},
{
"path": "adapter/service.go",
"chars": 600,
"preview": "package adapter\n\nimport (\n\t\"context\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\t\"github.com/sagernet/sing-box/option\"\n)\n\ntype"
},
{
"path": "adapter/ssm.go",
"chars": 387,
"preview": "package adapter\n\nimport (\n\t\"net\"\n\n\tN \"github.com/sagernet/sing/common/network\"\n)\n\ntype ManagedSSMServer interface {\n\tInb"
},
{
"path": "adapter/tailscale.go",
"chars": 1080,
"preview": "package adapter\n\nimport \"context\"\n\ntype TailscaleEndpoint interface {\n\tSubscribeTailscaleStatus(ctx context.Context, fn "
},
{
"path": "adapter/time.go",
"chars": 109,
"preview": "package adapter\n\nimport \"time\"\n\ntype TimeService interface {\n\tSimpleLifecycle\n\tTimeFunc() func() time.Time\n}\n"
},
{
"path": "adapter/upstream.go",
"chars": 5048,
"preview": "package adapter\n\nimport (\n\t\"context\"\n\t\"net\"\n\n\tM \"github.com/sagernet/sing/common/metadata\"\n\tN \"github.com/sagernet/sing/"
},
{
"path": "adapter/upstream_legacy.go",
"chars": 7364,
"preview": "package adapter\n\nimport (\n\t\"context\"\n\t\"net\"\n\n\tE \"github.com/sagernet/sing/common/exceptions\"\n\t\"github.com/sagernet/sing/"
},
{
"path": "adapter/v2ray.go",
"chars": 430,
"preview": "package adapter\n\nimport (\n\t\"context\"\n\t\"net\"\n\n\tN \"github.com/sagernet/sing/common/network\"\n)\n\ntype V2RayServerTransport i"
},
{
"path": "box.go",
"chars": 21758,
"preview": "package box\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"runtime/debug\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\tb"
},
{
"path": "cmd/internal/app_store_connect/main.go",
"chars": 13764,
"preview": "package main\n\nimport (\n\t\"context\"\n\t\"net/http\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/sagernet/asc-go/asc\"\n\t\"g"
},
{
"path": "cmd/internal/build/main.go",
"chars": 439,
"preview": "package main\n\nimport (\n\t\"go/build\"\n\t\"os\"\n\t\"os/exec\"\n\n\t\"github.com/sagernet/sing-box/cmd/internal/build_shared\"\n\t\"github."
},
{
"path": "cmd/internal/build_libbox/main.go",
"chars": 6358,
"preview": "package main\n\nimport (\n\t\"flag\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"strconv\"\n\t\"strings\"\n\n\t_ \"github.com/sagernet/gomobile"
},
{
"path": "cmd/internal/build_shared/sdk.go",
"chars": 2774,
"preview": "package build_shared\n\nimport (\n\t\"go/build\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com"
},
{
"path": "cmd/internal/build_shared/tag.go",
"chars": 1260,
"preview": "package build_shared\n\nimport (\n\t\"github.com/sagernet/sing-box/common/badversion\"\n\t\"github.com/sagernet/sing/common\"\n\t\"gi"
},
{
"path": "cmd/internal/format_docs/main.go",
"chars": 2667,
"preview": "package main\n\nimport (\n\t\"bytes\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/sagernet/sing-box/log\"\n)\n\nfunc main() {\n"
},
{
"path": "cmd/internal/protogen/main.go",
"chars": 4966,
"preview": "package main\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"go/build\"\n\t\"io\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"strings"
},
{
"path": "cmd/internal/read_tag/main.go",
"chars": 1375,
"preview": "package main\n\nimport (\n\t\"flag\"\n\t\"os\"\n\n\t\"github.com/sagernet/sing-box/cmd/internal/build_shared\"\n\t\"github.com/sagernet/si"
},
{
"path": "cmd/internal/tun_bench/main.go",
"chars": 6881,
"preview": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/netip\"\n\t\"os\"\n\t\"os/exec\"\n\t\"strings\"\n\t\"syscall\"\n\t\"time\"\n\n\tC \"github.c"
},
{
"path": "cmd/internal/update_android_version/main.go",
"chars": 2158,
"preview": "package main\n\nimport (\n\t\"flag\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/sagernet/sing-box/c"
},
{
"path": "cmd/internal/update_apple_version/main.go",
"chars": 5178,
"preview": "package main\n\nimport (\n\t\"flag\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"strings\"\n\n\t\"github.com/sagernet/sing-box/cmd/internal/"
},
{
"path": "cmd/internal/update_certificates/main.go",
"chars": 3657,
"preview": "package main\n\nimport (\n\t\"encoding/csv\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\n\t\"golang"
},
{
"path": "cmd/sing-box/cmd.go",
"chars": 2202,
"preview": "package main\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"os/user\"\n\t\"strconv\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/experimental/depre"
},
{
"path": "cmd/sing-box/cmd_check.go",
"chars": 684,
"preview": "package main\n\nimport (\n\t\"context\"\n\n\t\"github.com/sagernet/sing-box\"\n\t\"github.com/sagernet/sing-box/log\"\n\n\t\"github.com/spf"
},
{
"path": "cmd/sing-box/cmd_format.go",
"chars": 1824,
"preview": "package main\n\nimport (\n\t\"bytes\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\tE \"github.com/sagernet/sing"
},
{
"path": "cmd/sing-box/cmd_generate.go",
"chars": 1820,
"preview": "package main\n\nimport (\n\t\"crypto/rand\"\n\t\"encoding/base64\"\n\t\"encoding/hex\"\n\t\"os\"\n\t\"strconv\"\n\n\t\"github.com/sagernet/sing-bo"
},
{
"path": "cmd/sing-box/cmd_generate_ech.go",
"chars": 722,
"preview": "package main\n\nimport (\n\t\"os\"\n\n\t\"github.com/sagernet/sing-box/common/tls\"\n\t\"github.com/sagernet/sing-box/log\"\n\n\t\"github.c"
},
{
"path": "cmd/sing-box/cmd_generate_tls.go",
"chars": 1005,
"preview": "package main\n\nimport (\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/common/tls\"\n\t\"github.com/sagernet/sing-box/log\"\n\n\t\""
},
{
"path": "cmd/sing-box/cmd_generate_vapid.go",
"chars": 860,
"preview": "//go:build go1.20\n\npackage main\n\nimport (\n\t\"crypto/ecdh\"\n\t\"crypto/rand\"\n\t\"encoding/base64\"\n\t\"os\"\n\n\t\"github.com/sagernet/"
},
{
"path": "cmd/sing-box/cmd_generate_wireguard.go",
"chars": 1469,
"preview": "package main\n\nimport (\n\t\"encoding/base64\"\n\t\"os\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\n\t\"github.com/spf13/cobra\"\n\t\"golang"
},
{
"path": "cmd/sing-box/cmd_geoip.go",
"chars": 940,
"preview": "package main\n\nimport (\n\t\"github.com/sagernet/sing-box/log\"\n\tE \"github.com/sagernet/sing/common/exceptions\"\n\n\t\"github.com"
},
{
"path": "cmd/sing-box/cmd_geoip_export.go",
"chars": 2455,
"preview": "package main\n\nimport (\n\t\"io\"\n\t\"net\"\n\t\"os\"\n\t\"strings\"\n\n\tC \"github.com/sagernet/sing-box/constant\"\n\t\"github.com/sagernet/s"
},
{
"path": "cmd/sing-box/cmd_geoip_list.go",
"chars": 497,
"preview": "package main\n\nimport (\n\t\"os\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\n\t\"github.com/spf13/cobra\"\n)\n\nvar commandGeoipList = &"
},
{
"path": "cmd/sing-box/cmd_geoip_lookup.go",
"chars": 960,
"preview": "package main\n\nimport (\n\t\"net/netip\"\n\t\"os\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\tE \"github.com/sagernet/sing/common/excep"
},
{
"path": "cmd/sing-box/cmd_geosite.go",
"chars": 902,
"preview": "package main\n\nimport (\n\t\"github.com/sagernet/sing-box/common/geosite\"\n\t\"github.com/sagernet/sing-box/log\"\n\tE \"github.com"
},
{
"path": "cmd/sing-box/cmd_geosite_export.go",
"chars": 2100,
"preview": "package main\n\nimport (\n\t\"io\"\n\t\"os\"\n\n\t\"github.com/sagernet/sing-box/common/geosite\"\n\tC \"github.com/sagernet/sing-box/cons"
},
{
"path": "cmd/sing-box/cmd_geosite_list.go",
"chars": 1016,
"preview": "package main\n\nimport (\n\t\"os\"\n\t\"sort\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\tF \"github.com/sagernet/sing/common/format\"\n\n\t"
},
{
"path": "cmd/sing-box/cmd_geosite_lookup.go",
"chars": 2084,
"preview": "package main\n\nimport (\n\t\"os\"\n\t\"sort\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\tE \"github.com/sagernet/sing/common/exceptions"
},
{
"path": "cmd/sing-box/cmd_geosite_matcher.go",
"chars": 1220,
"preview": "package main\n\nimport (\n\t\"regexp\"\n\t\"strings\"\n\n\t\"github.com/sagernet/sing-box/common/geosite\"\n)\n\ntype searchGeositeMatcher"
},
{
"path": "cmd/sing-box/cmd_merge.go",
"chars": 3876,
"preview": "package main\n\nimport (\n\t\"bytes\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\tC \"github.com/sagernet/sing-box/constant\"\n\t\"github.c"
},
{
"path": "cmd/sing-box/cmd_rule_set.go",
"chars": 196,
"preview": "package main\n\nimport (\n\t\"github.com/spf13/cobra\"\n)\n\nvar commandRuleSet = &cobra.Command{\n\tUse: \"rule-set\",\n\tShort: \"Ma"
},
{
"path": "cmd/sing-box/cmd_rule_set_compile.go",
"chars": 2735,
"preview": "package main\n\nimport (\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/sagernet/sing-box/common/srs\"\n\tC \"github.com/sagernet/sing-b"
},
{
"path": "cmd/sing-box/cmd_rule_set_convert.go",
"chars": 2140,
"preview": "package main\n\nimport (\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/sagernet/sing-box/common/convertor/adguard\"\n\t\"github.com/sag"
},
{
"path": "cmd/sing-box/cmd_rule_set_decompile.go",
"chars": 2354,
"preview": "package main\n\nimport (\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/sagernet/sing-box/common/srs\"\n\tC \"github.com/sagernet/sing-b"
},
{
"path": "cmd/sing-box/cmd_rule_set_format.go",
"chars": 1853,
"preview": "package main\n\nimport (\n\t\"bytes\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\t\"github.com/sagernet/"
},
{
"path": "cmd/sing-box/cmd_rule_set_match.go",
"chars": 2674,
"preview": "package main\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"githu"
},
{
"path": "cmd/sing-box/cmd_rule_set_merge.go",
"chars": 4185,
"preview": "package main\n\nimport (\n\t\"bytes\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"sort\"\n\t\"strings\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\t\"g"
},
{
"path": "cmd/sing-box/cmd_rule_set_upgrade.go",
"chars": 2190,
"preview": "package main\n\nimport (\n\t\"bytes\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\n\tC \"github.com/sagernet/sing-box/constant\"\n\t\"github.com/sa"
},
{
"path": "cmd/sing-box/cmd_run.go",
"chars": 4783,
"preview": "package main\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"os\"\n\t\"os/signal\"\n\t\"path/filepath\"\n\truntimeDebug \"runtime/debug\"\n\t\"sort\"\n\t\"stri"
},
{
"path": "cmd/sing-box/cmd_tools.go",
"chars": 1357,
"preview": "package main\n\nimport (\n\t\"errors\"\n\t\"os\"\n\n\t\"github.com/sagernet/sing-box\"\n\tE \"github.com/sagernet/sing/common/exceptions\"\n"
},
{
"path": "cmd/sing-box/cmd_tools_connect.go",
"chars": 1791,
"preview": "package main\n\nimport (\n\t\"context\"\n\t\"os\"\n\n\t\"github.com/sagernet/sing-box/log\"\n\t\"github.com/sagernet/sing/common\"\n\t\"github"
},
{
"path": "cmd/sing-box/cmd_tools_fetch.go",
"chars": 2375,
"preview": "package main\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"os\"\n\n\tC \"github.com/sagernet/sing-box/"
},
{
"path": "cmd/sing-box/cmd_tools_fetch_http3.go",
"chars": 935,
"preview": "//go:build with_quic\n\npackage main\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"net/http\"\n\n\t\"github.com/sagernet/quic-go\"\n\t\"gith"
},
{
"path": "cmd/sing-box/cmd_tools_fetch_http3_stub.go",
"chars": 250,
"preview": "//go:build !with_quic\n\npackage main\n\nimport (\n\t\"net/url\"\n\t\"os\"\n\n\tbox \"github.com/sagernet/sing-box\"\n)\n\nfunc initializeHT"
},
{
"path": "cmd/sing-box/cmd_tools_networkquality.go",
"chars": 3992,
"preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/common/networkquality\"\n\t\"github.c"
},
{
"path": "cmd/sing-box/cmd_tools_stun.go",
"chars": 1914,
"preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/sagernet/sing-box/common/stun\"\n\t\"github.com/sagernet/sing-box/log\"\n\n\t\""
},
{
"path": "cmd/sing-box/cmd_tools_synctime.go",
"chars": 1718,
"preview": "package main\n\nimport (\n\t\"context\"\n\t\"os\"\n\n\tC \"github.com/sagernet/sing-box/constant\"\n\t\"github.com/sagernet/sing-box/log\"\n"
},
{
"path": "cmd/sing-box/cmd_version.go",
"chars": 1252,
"preview": "package main\n\nimport (\n\t\"os\"\n\t\"runtime\"\n\t\"runtime/debug\"\n\n\tC \"github.com/sagernet/sing-box/constant\"\n\n\t\"github.com/spf13"
},
{
"path": "cmd/sing-box/generate_completions.go",
"chars": 573,
"preview": "//go:build generate && generate_completions\n\npackage main\n\nimport \"github.com/sagernet/sing-box/log\"\n\nfunc main() {\n\terr"
},
{
"path": "cmd/sing-box/main.go",
"chars": 162,
"preview": "//go:build !generate\n\npackage main\n\nimport \"github.com/sagernet/sing-box/log\"\n\nfunc main() {\n\tif err := mainCommand.Exec"
},
{
"path": "common/badtls/raw_conn.go",
"chars": 5218,
"preview": "//go:build go1.25 && badlinkname\n\npackage badtls\n\nimport (\n\t\"bytes\"\n\t\"os\"\n\t\"reflect\"\n\t\"sync/atomic\"\n\t\"unsafe\"\n\n\tE \"githu"
},
{
"path": "common/badtls/raw_half_conn.go",
"chars": 4200,
"preview": "//go:build go1.25 && badlinkname\n\npackage badtls\n\nimport (\n\t\"hash\"\n\t\"reflect\"\n\t\"sync\"\n\t\"unsafe\"\n\n\tE \"github.com/sagernet"
},
{
"path": "common/badtls/read_wait.go",
"chars": 1768,
"preview": "//go:build go1.25 && badlinkname\n\npackage badtls\n\nimport (\n\t\"github.com/sagernet/sing/common/buf\"\n\tN \"github.com/sagerne"
},
{
"path": "common/badtls/read_wait_stub.go",
"chars": 195,
"preview": "//go:build !go1.25 || !badlinkname\n\npackage badtls\n\nimport (\n\t\"os\"\n\n\t\"github.com/sagernet/sing/common/tls\"\n)\n\nfunc NewRe"
},
{
"path": "common/badtls/registry.go",
"chars": 2219,
"preview": "//go:build go1.25 && badlinkname\n\npackage badtls\n\nimport (\n\t\"crypto/tls\"\n\t\"net\"\n\t\"unsafe\"\n)\n\ntype Methods struct {\n\tread"
},
{
"path": "common/badtls/registry_utls.go",
"chars": 1989,
"preview": "//go:build go1.25 && badlinkname\n\npackage badtls\n\nimport (\n\t\"net\"\n\t\"unsafe\"\n\n\tN \"github.com/sagernet/sing/common/network"
},
{
"path": "common/badversion/version.go",
"chars": 4190,
"preview": "package badversion\n\nimport (\n\t\"strconv\"\n\t\"strings\"\n\n\tF \"github.com/sagernet/sing/common/format\"\n\n\t\"golang.org/x/mod/semv"
},
{
"path": "common/badversion/version_json.go",
"chars": 332,
"preview": "package badversion\n\nimport \"github.com/sagernet/sing/common/json\"\n\nfunc (v Version) MarshalJSON() ([]byte, error) {\n\tret"
},
{
"path": "common/badversion/version_test.go",
"chars": 596,
"preview": "package badversion\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestCompareVersion(t *testing.T)"
},
{
"path": "common/certificate/anchors_darwin.h",
"chars": 741,
"preview": "#ifndef BOX_CERTIFICATE_ANCHORS_DARWIN_H\n#define BOX_CERTIFICATE_ANCHORS_DARWIN_H\n\n#include <stddef.h>\n#include <stdint."
},
{
"path": "common/certificate/anchors_darwin.m",
"chars": 1100,
"preview": "#import \"anchors_darwin.h\"\n\n#import <Foundation/Foundation.h>\n#import <Security/Security.h>\n\nvoid *box_certificate_ancho"
},
{
"path": "common/certificate/chrome.go",
"chars": 151510,
"preview": "// Code generated by 'make update_certificates'. DO NOT EDIT.\n\npackage certificate\n\nfunc chromeIncludedPEM() string {\n\tr"
},
{
"path": "common/certificate/chrome.pem",
"chars": 161006,
"preview": "-----BEGIN CERTIFICATE-----\nMIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE\nBhMCSVQxDjAMBgNVBAcMBU1pbGF"
},
{
"path": "common/certificate/mozilla.go",
"chars": 244603,
"preview": "// Code generated by 'make update_certificates'. DO NOT EDIT.\n\npackage certificate\n\nfunc mozillaIncludedPEM() string {\n\t"
},
{
"path": "common/certificate/mozilla.pem",
"chars": 258460,
"preview": "-----BEGIN CERTIFICATE-----\nMIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE\nBhMCSVQxDjAMBgNVBAcMBU1pbGF"
},
{
"path": "common/certificate/store.go",
"chars": 6564,
"preview": "package certificate\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/x509\"\n\t\"io/fs\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"g"
},
{
"path": "common/certificate/store_darwin.go",
"chars": 4095,
"preview": "//go:build darwin && cgo\n\npackage certificate\n\n/*\n#cgo CFLAGS: -x objective-c -fobjc-arc\n#cgo LDFLAGS: -framework Founda"
},
{
"path": "common/certificate/store_other.go",
"chars": 287,
"preview": "//go:build !(darwin && cgo)\n\npackage certificate\n\n//nolint:unused // referenced by Store.platform; populated only in sto"
},
{
"path": "common/compatible/map.go",
"chars": 982,
"preview": "package compatible\n\nimport \"sync\"\n\n// Map is a generics sync.Map\ntype Map[K comparable, V any] struct {\n\tm sync.Map\n}\n\nf"
},
{
"path": "common/convertor/adguard/convertor.go",
"chars": 13926,
"preview": "package adguard\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"io\"\n\t\"net/netip\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\n\tC \"github.com/sagernet/sing"
},
{
"path": "common/convertor/adguard/convertor_test.go",
"chars": 3234,
"preview": "package adguard\n\nimport (\n\t\"context\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.com/sagerne"
},
{
"path": "common/dialer/default.go",
"chars": 14297,
"preview": "package dialer\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"net\"\n\t\"net/netip\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/ada"
},
{
"path": "common/dialer/default_parallel_interface.go",
"chars": 9040,
"preview": "package dialer\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\tC \"github.com/sagernet/sing"
},
{
"path": "common/dialer/default_parallel_network.go",
"chars": 5487,
"preview": "package dialer\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"net/netip\"\n\t\"time\"\n\n\tC \"github.com/sagernet/sing-box/constant\"\n\t\"github.com"
},
{
"path": "common/dialer/detour.go",
"chars": 2440,
"preview": "package dialer\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"sync\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.com/sagernet/sing/c"
},
{
"path": "common/dialer/dialer.go",
"chars": 6571,
"preview": "package dialer\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"net/netip\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\tC \"github.com/"
},
{
"path": "common/dialer/resolve.go",
"chars": 6091,
"preview": "package dialer\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\tC \"github.com/sager"
},
{
"path": "common/dialer/router.go",
"chars": 901,
"preview": "package dialer\n\nimport (\n\t\"context\"\n\t\"net\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\tM \"github.com/sagernet/sing/common/"
},
{
"path": "common/dialer/tfo.go",
"chars": 3613,
"preview": "package dialer\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"net\"\n\t\"os\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing/common"
},
{
"path": "common/dialer/wireguard.go",
"chars": 141,
"preview": "package dialer\n\nimport (\n\t\"github.com/sagernet/sing/common/control\"\n)\n\ntype WireGuardListener interface {\n\tWireGuardCont"
},
{
"path": "common/geoip/reader.go",
"chars": 789,
"preview": "package geoip\n\nimport (\n\t\"net/netip\"\n\n\tE \"github.com/sagernet/sing/common/exceptions\"\n\n\t\"github.com/oschwald/maxminddb-g"
},
{
"path": "common/geosite/compat_test.go",
"chars": 6254,
"preview": "package geosite\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/sagernet/sing/common/"
},
{
"path": "common/geosite/geosite_test.go",
"chars": 699,
"preview": "package geosite_test\n\nimport (\n\t\"bytes\"\n\t\"testing\"\n\n\t\"github.com/sagernet/sing-box/common/geosite\"\n\n\t\"github.com/stretch"
},
{
"path": "common/geosite/reader.go",
"chars": 3209,
"preview": "package geosite\n\nimport (\n\t\"bufio\"\n\t\"encoding/binary\"\n\t\"io\"\n\t\"os\"\n\t\"sync\"\n\t\"sync/atomic\"\n\n\tE \"github.com/sagernet/sing/c"
},
{
"path": "common/geosite/rule.go",
"chars": 2763,
"preview": "package geosite\n\nimport \"github.com/sagernet/sing-box/option\"\n\ntype ItemType = uint8\n\nconst (\n\tRuleTypeDomain ItemType ="
},
{
"path": "common/geosite/writer.go",
"chars": 1358,
"preview": "package geosite\n\nimport (\n\t\"bytes\"\n\t\"sort\"\n\n\t\"github.com/sagernet/sing/common/varbin\"\n)\n\nfunc Write(writer varbin.Writer"
},
{
"path": "common/httpclient/apple_transport_darwin.go",
"chars": 14310,
"preview": "//go:build darwin && cgo\n\npackage httpclient\n\n/*\n#cgo CFLAGS: -x objective-c -fobjc-arc\n#cgo LDFLAGS: -framework Foundat"
},
{
"path": "common/httpclient/apple_transport_darwin.h",
"chars": 1921,
"preview": "#include <stdbool.h>\n#include <stddef.h>\n#include <stdint.h>\n\ntypedef struct box_apple_http_session box_apple_http_sessi"
},
{
"path": "common/httpclient/apple_transport_darwin.m",
"chars": 13734,
"preview": "#import \"apple_transport_darwin.h\"\n\n#import <CoreFoundation/CFStream.h>\n#import <Foundation/Foundation.h>\n#import <Secur"
},
{
"path": "common/httpclient/apple_transport_darwin_test.go",
"chars": 28632,
"preview": "//go:build darwin && cgo\n\npackage httpclient\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/sha256\"\n\tstdtls \"crypto/tls\"\n\t\"crypt"
},
{
"path": "common/httpclient/apple_transport_stub.go",
"chars": 481,
"preview": "//go:build !darwin || !cgo\n\npackage httpclient\n\nimport (\n\t\"context\"\n\n\t\"github.com/sagernet/sing-box/option\"\n\tE \"github.c"
},
{
"path": "common/httpclient/client.go",
"chars": 3940,
"preview": "package httpclient\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/common/dialer\"\n\t\"github.com/sagernet/sin"
},
{
"path": "common/httpclient/context.go",
"chars": 363,
"preview": "package httpclient\n\nimport \"context\"\n\ntype transportKey struct{}\n\nfunc contextWithTransportTag(ctx context.Context, tran"
},
{
"path": "common/httpclient/helpers.go",
"chars": 3093,
"preview": "package httpclient\n\nimport (\n\t\"context\"\n\tstdTLS \"crypto/tls\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"strings\"\n\n\t\"github.com/sagernet/"
},
{
"path": "common/httpclient/helpers_test.go",
"chars": 1643,
"preview": "package httpclient\n\nimport (\n\t\"net/http\"\n\t\"net/url\"\n\t\"testing\"\n)\n\nfunc TestRequestAuthority(t *testing.T) {\n\ttestCases :"
},
{
"path": "common/httpclient/http1_transport.go",
"chars": 1110,
"preview": "package httpclient\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"net/http\"\n\n\t\"github.com/sagernet/sing-box/common/tls\"\n\tM \"github.com/sa"
},
{
"path": "common/httpclient/http2_config.go",
"chars": 1424,
"preview": "package httpclient\n\nimport (\n\tstdTLS \"crypto/tls\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/option\"\n\tE \"github"
},
{
"path": "common/httpclient/http2_fallback_transport.go",
"chars": 2742,
"preview": "package httpclient\n\nimport (\n\t\"context\"\n\tstdTLS \"crypto/tls\"\n\t\"errors\"\n\t\"net\"\n\t\"net/http\"\n\t\"sync\"\n\n\t\"github.com/sagernet"
},
{
"path": "common/httpclient/http2_fallback_transport_test.go",
"chars": 1141,
"preview": "package httpclient\n\nimport (\n\t\"testing\"\n)\n\nfunc TestHTTP2FallbackAuthorityIsolation(t *testing.T) {\n\ttransport := &http2"
},
{
"path": "common/httpclient/http2_transport.go",
"chars": 1419,
"preview": "package httpclient\n\nimport (\n\t\"context\"\n\tstdTLS \"crypto/tls\"\n\t\"net\"\n\t\"net/http\"\n\n\t\"github.com/sagernet/sing-box/common/t"
},
{
"path": "common/httpclient/http3_transport.go",
"chars": 8429,
"preview": "//go:build with_quic\n\npackage httpclient\n\nimport (\n\t\"context\"\n\tstdTLS \"crypto/tls\"\n\t\"errors\"\n\t\"net/http\"\n\t\"sync\"\n\t\"time\""
},
{
"path": "common/httpclient/http3_transport_stub.go",
"chars": 708,
"preview": "//go:build !with_quic\n\npackage httpclient\n\nimport (\n\t\"time\"\n\n\t\"github.com/sagernet/sing-box/common/tls\"\n\t\"github.com/sag"
},
{
"path": "common/httpclient/http3_transport_test.go",
"chars": 3459,
"preview": "//go:build with_quic\n\npackage httpclient\n\nimport (\n\t\"testing\"\n\t\"time\"\n)\n\nfunc TestHTTP3BrokenAuthorityIsolation(t *testi"
},
{
"path": "common/httpclient/managed_transport.go",
"chars": 4481,
"preview": "package httpclient\n\nimport (\n\t\"io\"\n\t\"net/http\"\n\t\"sync\"\n\t\"sync/atomic\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\tE \"githu"
},
{
"path": "common/httpclient/manager.go",
"chars": 4952,
"preview": "package httpclient\n\nimport (\n\t\"context\"\n\t\"sync\"\n\n\t\"github.com/sagernet/sing-box/adapter\"\n\t\"github.com/sagernet/sing-box/"
},
{
"path": "common/interrupt/conn.go",
"chars": 1351,
"preview": "package interrupt\n\nimport (\n\t\"net\"\n\n\t\"github.com/sagernet/sing/common/bufio\"\n\t\"github.com/sagernet/sing/common/x/list\"\n)"
},
{
"path": "common/interrupt/context.go",
"chars": 359,
"preview": "package interrupt\n\nimport \"context\"\n\ntype contextKeyIsExternalConnection struct{}\n\nfunc ContextWithIsExternalConnection("
},
{
"path": "common/interrupt/group.go",
"chars": 1232,
"preview": "package interrupt\n\nimport (\n\t\"io\"\n\t\"net\"\n\t\"sync\"\n\n\t\"github.com/sagernet/sing/common/x/list\"\n)\n\ntype Group struct {\n\tacce"
},
{
"path": "common/ja3/LICENSE",
"chars": 1515,
"preview": "BSD 3-Clause License\n\nCopyright (c) 2018, Open Systems AG\nAll rights reserved.\n\nRedistribution and use in source and bin"
},
{
"path": "common/ja3/README.md",
"chars": 47,
"preview": "# JA3\n\nmod from: https://github.com/open-ch/ja3"
},
{
"path": "common/ja3/error.go",
"chars": 809,
"preview": "// Copyright (c) 2018, Open Systems AG. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style li"
},
{
"path": "common/ja3/ja3.go",
"chars": 1938,
"preview": "// Copyright (c) 2018, Open Systems AG. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style li"
},
{
"path": "common/ja3/parser.go",
"chars": 10704,
"preview": "// Copyright (c) 2018, Open Systems AG. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style li"
},
{
"path": "common/ktls/ktls.go",
"chars": 3091,
"preview": "//go:build linux && go1.25 && badlinkname\n\npackage ktls\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/tls\"\n\t\"errors\"\n\t\"io\"\n\t\"ne"
},
{
"path": "common/ktls/ktls_alert.go",
"chars": 2389,
"preview": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
},
{
"path": "common/ktls/ktls_cipher_suites_linux.go",
"chars": 10804,
"preview": "// Copyright 2010 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
},
{
"path": "common/ktls/ktls_close.go",
"chars": 1682,
"preview": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
},
{
"path": "common/ktls/ktls_const.go",
"chars": 965,
"preview": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
},
{
"path": "common/ktls/ktls_handshake_messages.go",
"chars": 5199,
"preview": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
},
{
"path": "common/ktls/ktls_key_update.go",
"chars": 5162,
"preview": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
},
{
"path": "common/ktls/ktls_linux.go",
"chars": 8784,
"preview": "//go:build linux && go1.25 && badlinkname\n\npackage ktls\n\nimport (\n\t\"crypto/tls\"\n\t\"errors\"\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n\t\"sync\""
},
{
"path": "common/ktls/ktls_prf.go",
"chars": 1108,
"preview": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
},
{
"path": "common/ktls/ktls_read.go",
"chars": 9946,
"preview": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
}
]
// ... and 1005 more files (download for full content)
About this extraction
This page contains the full source code of the reF1nd/sing-box GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1205 files (5.1 MB), approximately 1.4M tokens, and a symbol index with 7773 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.