Full Code of v2ray/v2ray-core for AI

master d80440f3d57b cached
752 files
14.0 MB
634.2k tokens
5273 symbols
1 requests
Download .txt
Showing preview only (2,521K chars total). Download the full file or copy to clipboard to get everything.
Repository: v2ray/v2ray-core
Branch: master
Commit: d80440f3d57b
Files: 752
Total size: 14.0 MB

Directory structure:
gitextract_4w26szfn/

├── .dev/
│   └── protoc/
│       ├── linux/
│       │   └── protoc
│       └── macos/
│           └── protoc
├── .github/
│   ├── CODE_OF_CONDUCT.md
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_cn.md
│   │   ├── bug_en.md
│   │   └── other_en.md
│   ├── ISSUE_TEMPLATE.md
│   ├── dependabot.yml
│   ├── linters/
│   │   └── .golangci.yml
│   ├── pull_request_template.md
│   └── workflows/
│       ├── codeql-analysis.yml
│       ├── coverage.yml
│       ├── linter.yml
│       ├── sign.yml
│       ├── stale.yml
│       ├── test.yml
│       └── updateGeofile.yml
├── .gitignore
├── Dockerfile
├── LICENSE
├── README.md
├── SECURITY.md
├── WORKSPACE
├── annotations.go
├── app/
│   ├── app.go
│   ├── commander/
│   │   ├── commander.go
│   │   ├── config.pb.go
│   │   ├── config.proto
│   │   ├── errors.generated.go
│   │   ├── outbound.go
│   │   └── service.go
│   ├── dispatcher/
│   │   ├── config.pb.go
│   │   ├── config.proto
│   │   ├── default.go
│   │   ├── dispatcher.go
│   │   ├── errors.generated.go
│   │   ├── sniffer.go
│   │   ├── stats.go
│   │   └── stats_test.go
│   ├── dns/
│   │   ├── config.pb.go
│   │   ├── config.proto
│   │   ├── dns.go
│   │   ├── dnscommon.go
│   │   ├── dnscommon_test.go
│   │   ├── dohdns.go
│   │   ├── errors.generated.go
│   │   ├── hosts.go
│   │   ├── hosts_test.go
│   │   ├── nameserver.go
│   │   ├── nameserver_test.go
│   │   ├── server.go
│   │   ├── server_test.go
│   │   └── udpns.go
│   ├── log/
│   │   ├── command/
│   │   │   ├── command.go
│   │   │   ├── command_test.go
│   │   │   ├── config.pb.go
│   │   │   ├── config.proto
│   │   │   ├── config_grpc.pb.go
│   │   │   └── errors.generated.go
│   │   ├── config.pb.go
│   │   ├── config.proto
│   │   ├── errors.generated.go
│   │   ├── log.go
│   │   ├── log_creator.go
│   │   └── log_test.go
│   ├── policy/
│   │   ├── config.go
│   │   ├── config.pb.go
│   │   ├── config.proto
│   │   ├── errors.generated.go
│   │   ├── manager.go
│   │   ├── manager_test.go
│   │   └── policy.go
│   ├── proxyman/
│   │   ├── command/
│   │   │   ├── command.go
│   │   │   ├── command.pb.go
│   │   │   ├── command.proto
│   │   │   ├── command_grpc.pb.go
│   │   │   ├── doc.go
│   │   │   └── errors.generated.go
│   │   ├── config.go
│   │   ├── config.pb.go
│   │   ├── config.proto
│   │   ├── inbound/
│   │   │   ├── always.go
│   │   │   ├── dynamic.go
│   │   │   ├── errors.generated.go
│   │   │   ├── inbound.go
│   │   │   └── worker.go
│   │   ├── outbound/
│   │   │   ├── errors.generated.go
│   │   │   ├── handler.go
│   │   │   ├── handler_test.go
│   │   │   └── outbound.go
│   │   └── proxyman.go
│   ├── reverse/
│   │   ├── bridge.go
│   │   ├── config.go
│   │   ├── config.pb.go
│   │   ├── config.proto
│   │   ├── errors.generated.go
│   │   ├── portal.go
│   │   ├── portal_test.go
│   │   └── reverse.go
│   ├── router/
│   │   ├── balancing.go
│   │   ├── command/
│   │   │   ├── command.go
│   │   │   ├── command.pb.go
│   │   │   ├── command.proto
│   │   │   ├── command_grpc.pb.go
│   │   │   ├── command_test.go
│   │   │   ├── config.go
│   │   │   └── errors.generated.go
│   │   ├── condition.go
│   │   ├── condition_geoip.go
│   │   ├── condition_geoip_test.go
│   │   ├── condition_test.go
│   │   ├── config.go
│   │   ├── config.pb.go
│   │   ├── config.proto
│   │   ├── errors.generated.go
│   │   ├── router.go
│   │   └── router_test.go
│   └── stats/
│       ├── channel.go
│       ├── channel_test.go
│       ├── command/
│       │   ├── command.go
│       │   ├── command.pb.go
│       │   ├── command.proto
│       │   ├── command_grpc.pb.go
│       │   ├── command_test.go
│       │   └── errors.generated.go
│       ├── config.pb.go
│       ├── config.proto
│       ├── counter.go
│       ├── counter_test.go
│       ├── errors.generated.go
│       ├── stats.go
│       └── stats_test.go
├── azure-pipelines.yml
├── common/
│   ├── antireplay/
│   │   └── antireplay.go
│   ├── bitmask/
│   │   ├── byte.go
│   │   └── byte_test.go
│   ├── buf/
│   │   ├── buf.go
│   │   ├── buffer.go
│   │   ├── buffer_test.go
│   │   ├── copy.go
│   │   ├── copy_test.go
│   │   ├── errors.generated.go
│   │   ├── io.go
│   │   ├── io_test.go
│   │   ├── multi_buffer.go
│   │   ├── multi_buffer_test.go
│   │   ├── reader.go
│   │   ├── reader_test.go
│   │   ├── readv_posix.go
│   │   ├── readv_reader.go
│   │   ├── readv_reader_wasm.go
│   │   ├── readv_test.go
│   │   ├── readv_unix.go
│   │   ├── readv_windows.go
│   │   ├── writer.go
│   │   └── writer_test.go
│   ├── bytespool/
│   │   └── pool.go
│   ├── cmdarg/
│   │   └── cmdarg.go
│   ├── common.go
│   ├── common_test.go
│   ├── crypto/
│   │   ├── aes.go
│   │   ├── auth.go
│   │   ├── auth_test.go
│   │   ├── benchmark_test.go
│   │   ├── chacha20.go
│   │   ├── chacha20_test.go
│   │   ├── chunk.go
│   │   ├── chunk_test.go
│   │   ├── crypto.go
│   │   ├── errors.generated.go
│   │   ├── internal/
│   │   │   ├── chacha.go
│   │   │   ├── chacha_core.generated.go
│   │   │   └── chacha_core_gen.go
│   │   └── io.go
│   ├── dice/
│   │   ├── dice.go
│   │   └── dice_test.go
│   ├── errors/
│   │   ├── errorgen/
│   │   │   └── main.go
│   │   ├── errors.go
│   │   ├── errors_test.go
│   │   └── multi_error.go
│   ├── errors.generated.go
│   ├── interfaces.go
│   ├── log/
│   │   ├── access.go
│   │   ├── log.go
│   │   ├── log.pb.go
│   │   ├── log.proto
│   │   ├── log_test.go
│   │   ├── logger.go
│   │   └── logger_test.go
│   ├── mux/
│   │   ├── client.go
│   │   ├── client_test.go
│   │   ├── errors.generated.go
│   │   ├── frame.go
│   │   ├── frame_test.go
│   │   ├── mux.go
│   │   ├── mux_test.go
│   │   ├── reader.go
│   │   ├── server.go
│   │   ├── session.go
│   │   ├── session_test.go
│   │   └── writer.go
│   ├── net/
│   │   ├── address.go
│   │   ├── address.pb.go
│   │   ├── address.proto
│   │   ├── address_test.go
│   │   ├── connection.go
│   │   ├── destination.go
│   │   ├── destination.pb.go
│   │   ├── destination.proto
│   │   ├── destination_test.go
│   │   ├── errors.generated.go
│   │   ├── net.go
│   │   ├── network.go
│   │   ├── network.pb.go
│   │   ├── network.proto
│   │   ├── port.go
│   │   ├── port.pb.go
│   │   ├── port.proto
│   │   ├── port_test.go
│   │   └── system.go
│   ├── peer/
│   │   ├── latency.go
│   │   └── peer.go
│   ├── platform/
│   │   ├── ctlcmd/
│   │   │   ├── attr_other.go
│   │   │   ├── attr_windows.go
│   │   │   ├── ctlcmd.go
│   │   │   └── errors.generated.go
│   │   ├── filesystem/
│   │   │   └── file.go
│   │   ├── others.go
│   │   ├── platform.go
│   │   ├── platform_test.go
│   │   └── windows.go
│   ├── protocol/
│   │   ├── account.go
│   │   ├── address.go
│   │   ├── address_test.go
│   │   ├── bittorrent/
│   │   │   └── bittorrent.go
│   │   ├── context.go
│   │   ├── dns/
│   │   │   ├── errors.generated.go
│   │   │   └── io.go
│   │   ├── errors.generated.go
│   │   ├── headers.go
│   │   ├── headers.pb.go
│   │   ├── headers.proto
│   │   ├── http/
│   │   │   ├── headers.go
│   │   │   ├── headers_test.go
│   │   │   ├── sniff.go
│   │   │   └── sniff_test.go
│   │   ├── id.go
│   │   ├── id_test.go
│   │   ├── payload.go
│   │   ├── protocol.go
│   │   ├── server_picker.go
│   │   ├── server_picker_test.go
│   │   ├── server_spec.go
│   │   ├── server_spec.pb.go
│   │   ├── server_spec.proto
│   │   ├── server_spec_test.go
│   │   ├── time.go
│   │   ├── time_test.go
│   │   ├── tls/
│   │   │   ├── cert/
│   │   │   │   ├── .gitignore
│   │   │   │   ├── cert.go
│   │   │   │   ├── cert_test.go
│   │   │   │   ├── errors.generated.go
│   │   │   │   └── privateKey.go
│   │   │   ├── sniff.go
│   │   │   └── sniff_test.go
│   │   ├── udp/
│   │   │   ├── packet.go
│   │   │   └── udp.go
│   │   ├── user.go
│   │   ├── user.pb.go
│   │   └── user.proto
│   ├── retry/
│   │   ├── errors.generated.go
│   │   ├── retry.go
│   │   └── retry_test.go
│   ├── serial/
│   │   ├── serial.go
│   │   ├── serial_test.go
│   │   ├── string.go
│   │   ├── string_test.go
│   │   ├── typed_message.go
│   │   ├── typed_message.pb.go
│   │   ├── typed_message.proto
│   │   └── typed_message_test.go
│   ├── session/
│   │   ├── context.go
│   │   └── session.go
│   ├── signal/
│   │   ├── done/
│   │   │   └── done.go
│   │   ├── notifier.go
│   │   ├── notifier_test.go
│   │   ├── pubsub/
│   │   │   ├── pubsub.go
│   │   │   └── pubsub_test.go
│   │   ├── semaphore/
│   │   │   └── semaphore.go
│   │   ├── timer.go
│   │   └── timer_test.go
│   ├── stack/
│   │   └── bytes.go
│   ├── strmatcher/
│   │   ├── benchmark_test.go
│   │   ├── domain_matcher.go
│   │   ├── domain_matcher_test.go
│   │   ├── full_matcher.go
│   │   ├── full_matcher_test.go
│   │   ├── matchers.go
│   │   ├── matchers_test.go
│   │   ├── strmatcher.go
│   │   └── strmatcher_test.go
│   ├── task/
│   │   ├── common.go
│   │   ├── periodic.go
│   │   ├── periodic_test.go
│   │   ├── task.go
│   │   └── task_test.go
│   ├── type.go
│   ├── type_test.go
│   └── uuid/
│       ├── uuid.go
│       └── uuid_test.go
├── config.go
├── config.pb.go
├── config.proto
├── context.go
├── context_test.go
├── core.go
├── errors.generated.go
├── features/
│   ├── dns/
│   │   ├── client.go
│   │   └── localdns/
│   │       └── client.go
│   ├── errors.generated.go
│   ├── feature.go
│   ├── inbound/
│   │   └── inbound.go
│   ├── outbound/
│   │   └── outbound.go
│   ├── policy/
│   │   ├── default.go
│   │   └── policy.go
│   ├── routing/
│   │   ├── context.go
│   │   ├── dispatcher.go
│   │   ├── dns/
│   │   │   ├── context.go
│   │   │   └── errors.generated.go
│   │   ├── router.go
│   │   └── session/
│   │       └── context.go
│   └── stats/
│       ├── errors.generated.go
│       └── stats.go
├── functions.go
├── functions_test.go
├── go.mod
├── go.sum
├── infra/
│   ├── bazel/
│   │   ├── BUILD
│   │   ├── build.bzl
│   │   ├── matrix.bzl
│   │   └── zip.bzl
│   ├── conf/
│   │   ├── api.go
│   │   ├── blackhole.go
│   │   ├── blackhole_test.go
│   │   ├── buildable.go
│   │   ├── command/
│   │   │   ├── command.go
│   │   │   └── errors.generated.go
│   │   ├── common.go
│   │   ├── common_test.go
│   │   ├── conf.go
│   │   ├── dns.go
│   │   ├── dns_proxy.go
│   │   ├── dns_proxy_test.go
│   │   ├── dns_test.go
│   │   ├── dokodemo.go
│   │   ├── dokodemo_test.go
│   │   ├── errors.generated.go
│   │   ├── freedom.go
│   │   ├── freedom_test.go
│   │   ├── general_test.go
│   │   ├── http.go
│   │   ├── http_test.go
│   │   ├── json/
│   │   │   ├── reader.go
│   │   │   └── reader_test.go
│   │   ├── loader.go
│   │   ├── log.go
│   │   ├── mtproto.go
│   │   ├── mtproto_test.go
│   │   ├── policy.go
│   │   ├── policy_test.go
│   │   ├── reverse.go
│   │   ├── reverse_test.go
│   │   ├── router.go
│   │   ├── router_test.go
│   │   ├── serial/
│   │   │   ├── errors.generated.go
│   │   │   ├── loader.go
│   │   │   ├── loader_test.go
│   │   │   └── serial.go
│   │   ├── shadowsocks.go
│   │   ├── shadowsocks_test.go
│   │   ├── socks.go
│   │   ├── socks_test.go
│   │   ├── transport.go
│   │   ├── transport_authenticators.go
│   │   ├── transport_internet.go
│   │   ├── transport_test.go
│   │   ├── trojan.go
│   │   ├── v2ray.go
│   │   ├── v2ray_test.go
│   │   ├── vless.go
│   │   ├── vless_test.go
│   │   ├── vmess.go
│   │   └── vmess_test.go
│   ├── control/
│   │   ├── api.go
│   │   ├── cert.go
│   │   ├── command.go
│   │   ├── config.go
│   │   ├── control.go
│   │   ├── errors.generated.go
│   │   ├── fetch.go
│   │   ├── love.go
│   │   ├── main/
│   │   │   ├── BUILD
│   │   │   ├── main.go
│   │   │   └── targets.bzl
│   │   ├── tlsping.go
│   │   ├── uuid.go
│   │   └── verify.go
│   └── vprotogen/
│       └── main.go
├── main/
│   ├── BUILD
│   ├── confloader/
│   │   ├── confloader.go
│   │   ├── errors.generated.go
│   │   └── external/
│   │       ├── errors.generated.go
│   │       └── external.go
│   ├── distro/
│   │   ├── all/
│   │   │   └── all.go
│   │   └── debug/
│   │       └── debug.go
│   ├── errors.generated.go
│   ├── json/
│   │   ├── config_json.go
│   │   └── errors.generated.go
│   ├── jsonem/
│   │   ├── errors.generated.go
│   │   └── jsonem.go
│   ├── main.go
│   ├── main_test.go
│   └── targets.bzl
├── mocks.go
├── proto.go
├── proxy/
│   ├── blackhole/
│   │   ├── blackhole.go
│   │   ├── blackhole_test.go
│   │   ├── config.go
│   │   ├── config.pb.go
│   │   ├── config.proto
│   │   ├── config_test.go
│   │   └── errors.generated.go
│   ├── dns/
│   │   ├── config.pb.go
│   │   ├── config.proto
│   │   ├── dns.go
│   │   ├── dns_test.go
│   │   └── errors.generated.go
│   ├── dokodemo/
│   │   ├── config.go
│   │   ├── config.pb.go
│   │   ├── config.proto
│   │   ├── dokodemo.go
│   │   └── errors.generated.go
│   ├── freedom/
│   │   ├── config.go
│   │   ├── config.pb.go
│   │   ├── config.proto
│   │   ├── errors.generated.go
│   │   └── freedom.go
│   ├── http/
│   │   ├── client.go
│   │   ├── config.go
│   │   ├── config.pb.go
│   │   ├── config.proto
│   │   ├── errors.generated.go
│   │   ├── http.go
│   │   └── server.go
│   ├── mtproto/
│   │   ├── auth.go
│   │   ├── auth_test.go
│   │   ├── client.go
│   │   ├── config.go
│   │   ├── config.pb.go
│   │   ├── config.proto
│   │   ├── errors.generated.go
│   │   ├── mtproto.go
│   │   └── server.go
│   ├── proxy.go
│   ├── shadowsocks/
│   │   ├── client.go
│   │   ├── config.go
│   │   ├── config.pb.go
│   │   ├── config.proto
│   │   ├── config_test.go
│   │   ├── errors.generated.go
│   │   ├── protocol.go
│   │   ├── protocol_test.go
│   │   ├── server.go
│   │   └── shadowsocks.go
│   ├── socks/
│   │   ├── client.go
│   │   ├── config.go
│   │   ├── config.pb.go
│   │   ├── config.proto
│   │   ├── errors.generated.go
│   │   ├── protocol.go
│   │   ├── protocol_test.go
│   │   ├── server.go
│   │   └── socks.go
│   ├── trojan/
│   │   ├── client.go
│   │   ├── config.go
│   │   ├── config.pb.go
│   │   ├── config.proto
│   │   ├── errors.generated.go
│   │   ├── protocol.go
│   │   ├── protocol_test.go
│   │   ├── server.go
│   │   ├── trojan.go
│   │   └── validator.go
│   ├── vless/
│   │   ├── account.go
│   │   ├── account.pb.go
│   │   ├── account.proto
│   │   ├── encoding/
│   │   │   ├── addons.go
│   │   │   ├── addons.pb.go
│   │   │   ├── addons.proto
│   │   │   ├── encoding.go
│   │   │   ├── encoding_test.go
│   │   │   └── errors.generated.go
│   │   ├── errors.generated.go
│   │   ├── inbound/
│   │   │   ├── config.go
│   │   │   ├── config.pb.go
│   │   │   ├── config.proto
│   │   │   ├── errors.generated.go
│   │   │   └── inbound.go
│   │   ├── outbound/
│   │   │   ├── config.go
│   │   │   ├── config.pb.go
│   │   │   ├── config.proto
│   │   │   ├── errors.generated.go
│   │   │   └── outbound.go
│   │   ├── validator.go
│   │   └── vless.go
│   └── vmess/
│       ├── account.go
│       ├── account.pb.go
│       ├── account.proto
│       ├── aead/
│       │   ├── authid.go
│       │   ├── authid_test.go
│       │   ├── consts.go
│       │   ├── encrypt.go
│       │   ├── encrypt_test.go
│       │   └── kdf.go
│       ├── encoding/
│       │   ├── auth.go
│       │   ├── auth_test.go
│       │   ├── client.go
│       │   ├── commands.go
│       │   ├── commands_test.go
│       │   ├── encoding.go
│       │   ├── encoding_test.go
│       │   ├── errors.generated.go
│       │   └── server.go
│       ├── errors.generated.go
│       ├── inbound/
│       │   ├── config.go
│       │   ├── config.pb.go
│       │   ├── config.proto
│       │   ├── errors.generated.go
│       │   └── inbound.go
│       ├── outbound/
│       │   ├── command.go
│       │   ├── config.go
│       │   ├── config.pb.go
│       │   ├── config.proto
│       │   ├── errors.generated.go
│       │   └── outbound.go
│       ├── validator.go
│       ├── validator_test.go
│       ├── vmess.go
│       └── vmessCtxInterface.go
├── release/
│   ├── BUILD
│   ├── bleedingrelease.sh
│   ├── config/
│   │   ├── config.json
│   │   ├── systemd/
│   │   │   └── system/
│   │   │       ├── v2ray.service
│   │   │       └── v2ray@.service
│   │   ├── vpoint_socks_vmess.json
│   │   └── vpoint_vmess_freedom.json
│   ├── install-release.sh
│   ├── mapping.bzl
│   ├── mutilate/
│   │   └── removeVSign.sh
│   ├── requestsign.sh
│   ├── requestsign_github.sh
│   ├── tagrelease.sh
│   └── user-package.sh
├── testing/
│   ├── coverage/
│   │   ├── coverall
│   │   └── coverall2
│   ├── mocks/
│   │   ├── dns.go
│   │   ├── io.go
│   │   ├── log.go
│   │   ├── mux.go
│   │   ├── outbound.go
│   │   └── proxy.go
│   ├── scenarios/
│   │   ├── command_test.go
│   │   ├── common.go
│   │   ├── common_coverage.go
│   │   ├── common_regular.go
│   │   ├── dns_test.go
│   │   ├── dokodemo_test.go
│   │   ├── feature_test.go
│   │   ├── http_test.go
│   │   ├── policy_test.go
│   │   ├── reverse_test.go
│   │   ├── shadowsocks_test.go
│   │   ├── socks_test.go
│   │   ├── tls_test.go
│   │   ├── transport_test.go
│   │   └── vmess_test.go
│   └── servers/
│       ├── http/
│       │   └── http.go
│       ├── tcp/
│       │   ├── port.go
│       │   └── tcp.go
│       └── udp/
│           ├── port.go
│           └── udp.go
├── transport/
│   ├── config.go
│   ├── config.pb.go
│   ├── config.proto
│   ├── internet/
│   │   ├── config.go
│   │   ├── config.pb.go
│   │   ├── config.proto
│   │   ├── connection.go
│   │   ├── dialer.go
│   │   ├── dialer_test.go
│   │   ├── domainsocket/
│   │   │   ├── config.go
│   │   │   ├── config.pb.go
│   │   │   ├── config.proto
│   │   │   ├── dial.go
│   │   │   ├── errgen.go
│   │   │   ├── errors.generated.go
│   │   │   ├── listener.go
│   │   │   └── listener_test.go
│   │   ├── errors.generated.go
│   │   ├── header.go
│   │   ├── header_test.go
│   │   ├── headers/
│   │   │   ├── http/
│   │   │   │   ├── config.go
│   │   │   │   ├── config.pb.go
│   │   │   │   ├── config.proto
│   │   │   │   ├── errors.generated.go
│   │   │   │   ├── http.go
│   │   │   │   ├── http_test.go
│   │   │   │   ├── linkedreadRequest.go
│   │   │   │   └── resp.go
│   │   │   ├── noop/
│   │   │   │   ├── config.pb.go
│   │   │   │   ├── config.proto
│   │   │   │   └── noop.go
│   │   │   ├── srtp/
│   │   │   │   ├── config.pb.go
│   │   │   │   ├── config.proto
│   │   │   │   ├── srtp.go
│   │   │   │   └── srtp_test.go
│   │   │   ├── tls/
│   │   │   │   ├── config.pb.go
│   │   │   │   ├── config.proto
│   │   │   │   ├── dtls.go
│   │   │   │   └── dtls_test.go
│   │   │   ├── utp/
│   │   │   │   ├── config.pb.go
│   │   │   │   ├── config.proto
│   │   │   │   ├── utp.go
│   │   │   │   └── utp_test.go
│   │   │   ├── wechat/
│   │   │   │   ├── config.pb.go
│   │   │   │   ├── config.proto
│   │   │   │   ├── wechat.go
│   │   │   │   └── wechat_test.go
│   │   │   └── wireguard/
│   │   │       ├── config.pb.go
│   │   │       ├── config.proto
│   │   │       └── wireguard.go
│   │   ├── http/
│   │   │   ├── config.go
│   │   │   ├── config.pb.go
│   │   │   ├── config.proto
│   │   │   ├── dialer.go
│   │   │   ├── errors.generated.go
│   │   │   ├── http.go
│   │   │   ├── http_test.go
│   │   │   └── hub.go
│   │   ├── internet.go
│   │   ├── kcp/
│   │   │   ├── config.go
│   │   │   ├── config.pb.go
│   │   │   ├── config.proto
│   │   │   ├── connection.go
│   │   │   ├── connection_test.go
│   │   │   ├── crypt.go
│   │   │   ├── crypt_test.go
│   │   │   ├── cryptreal.go
│   │   │   ├── dialer.go
│   │   │   ├── errors.generated.go
│   │   │   ├── io.go
│   │   │   ├── io_test.go
│   │   │   ├── kcp.go
│   │   │   ├── kcp_test.go
│   │   │   ├── listener.go
│   │   │   ├── output.go
│   │   │   ├── receiving.go
│   │   │   ├── segment.go
│   │   │   ├── segment_test.go
│   │   │   ├── sending.go
│   │   │   ├── xor.go
│   │   │   ├── xor_amd64.go
│   │   │   └── xor_amd64.s
│   │   ├── memory_settings.go
│   │   ├── quic/
│   │   │   ├── config.go
│   │   │   ├── config.pb.go
│   │   │   ├── config.proto
│   │   │   ├── conn.go
│   │   │   ├── dialer.go
│   │   │   ├── errors.generated.go
│   │   │   ├── hub.go
│   │   │   ├── pool.go
│   │   │   ├── quic.go
│   │   │   └── quic_test.go
│   │   ├── sockopt.go
│   │   ├── sockopt_darwin.go
│   │   ├── sockopt_freebsd.go
│   │   ├── sockopt_linux.go
│   │   ├── sockopt_linux_test.go
│   │   ├── sockopt_other.go
│   │   ├── sockopt_test.go
│   │   ├── sockopt_windows.go
│   │   ├── system_dialer.go
│   │   ├── system_listener.go
│   │   ├── system_listener_test.go
│   │   ├── tcp/
│   │   │   ├── config.go
│   │   │   ├── config.pb.go
│   │   │   ├── config.proto
│   │   │   ├── dialer.go
│   │   │   ├── errors.generated.go
│   │   │   ├── hub.go
│   │   │   ├── sockopt_freebsd.go
│   │   │   ├── sockopt_linux.go
│   │   │   ├── sockopt_linux_test.go
│   │   │   ├── sockopt_other.go
│   │   │   └── tcp.go
│   │   ├── tcp_hub.go
│   │   ├── tls/
│   │   │   ├── config.go
│   │   │   ├── config.pb.go
│   │   │   ├── config.proto
│   │   │   ├── config_other.go
│   │   │   ├── config_test.go
│   │   │   ├── config_windows.go
│   │   │   ├── errors.generated.go
│   │   │   └── tls.go
│   │   ├── udp/
│   │   │   ├── config.go
│   │   │   ├── config.pb.go
│   │   │   ├── config.proto
│   │   │   ├── dialer.go
│   │   │   ├── dispatcher.go
│   │   │   ├── dispatcher_test.go
│   │   │   ├── errors.generated.go
│   │   │   ├── hub.go
│   │   │   ├── hub_freebsd.go
│   │   │   ├── hub_linux.go
│   │   │   ├── hub_other.go
│   │   │   └── udp.go
│   │   ├── websocket/
│   │   │   ├── config.go
│   │   │   ├── config.pb.go
│   │   │   ├── config.proto
│   │   │   ├── connection.go
│   │   │   ├── dialer.go
│   │   │   ├── errors.generated.go
│   │   │   ├── hub.go
│   │   │   ├── ws.go
│   │   │   └── ws_test.go
│   │   └── xtls/
│   │       ├── config.go
│   │       ├── config.pb.go
│   │       ├── config.proto
│   │       ├── config_other.go
│   │       ├── config_test.go
│   │       ├── config_windows.go
│   │       ├── errors.generated.go
│   │       └── xtls.go
│   ├── link.go
│   └── pipe/
│       ├── impl.go
│       ├── pipe.go
│       ├── pipe_test.go
│       ├── reader.go
│       └── writer.go
├── v2ray.go
└── v2ray_test.go

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

================================================
FILE: .dev/protoc/macos/protoc
================================================
[File too large to display: 11.8 MB]

================================================
FILE: .github/CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct

## Our Pledge

In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.

## Our Standards

Examples of behavior that contributes to creating a positive environment include:

* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

* The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting

## Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.

## Scope

This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at love@v2ray.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]

[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/


================================================
FILE: .github/ISSUE_TEMPLATE/bug_cn.md
================================================
---
name: V2Ray 程序问题
about: "提交一个 V2Ray 的程序问题报告。"
---

除非特殊情况,请完整填写所有问题。不按模板发的 issue 将直接被关闭。
如果你遇到的问题不是 V2Ray 的 bug,比如你不清楚要如何配置,请使用[Discussion](https://github.com/v2fly/discussion/issues)进行讨论。

1) 你正在使用哪个版本的 V2Ray?(如果服务器和客户端使用了不同版本,请注明)

2) 你的使用场景是什么?比如使用 Chrome 通过 Socks/VMess 代理观看 YouTube 视频。

3) 你看到的不正常的现象是什么?(请描述具体现象,比如访问超时,TLS 证书错误等)

4) 你期待看到的正确表现是怎样的?

5) 请附上你的配置(提交 Issue 前请隐藏服务器端IP地址)。

服务器端配置:

```javascript
    // 在这里附上服务器端配置文件
```

客户端配置:

```javascript
    // 在这里附上客户端配置
```

6)  请附上出错时软件输出的错误日志。在 Linux 中,日志通常在 `/var/log/v2ray/error.log` 文件中。

服务器端错误日志:

```javascript
    // 在这里附上服务器端日志
```

客户端错误日志:

```javascript
    // 在这里附上客户端日志
```

7) 请附上访问日志。在 Linux 中,日志通常在 `/var/log/v2ray/access.log` 文件中。

```javascript
    // 在这里附上服务器端日志
```

8) 其它相关的配置文件(如 Nginx)和相关日志。

9) 如果 V2Ray 无法启动,请附上 `--test` 输出。

通常的命令为 `/usr/bin/v2ray/v2ray --test --config /etc/v2ray/config.json`。请按实际情况修改。

10) 如果 V2Ray 服务运行不正常,请附上 journal 日志。

通常的命令为 `journalctl -u v2ray`。

请预览一下你填的内容再提交。


================================================
FILE: .github/ISSUE_TEMPLATE/bug_en.md
================================================
---
name: Bug report
about: "Create a bug report to help us improve"
---

Please answer all the questions with enough information. All issues not following this template will be closed immediately.
If you are not sure if your question is truely a bug in V2Ray, please discuss it [here](https://github.com/v2fly/discussion/issues) first.

1) What version of V2Ray are you using (If you deploy different version on server and client, please explicitly point out)?

2) What's your scenario of using V2Ray? E.g., Watching YouTube videos in Chrome via Socks/VMess proxy.

3) What did you see? (Please describe in detail, such as timeout, fake TLS certificate etc)

4) What's your expectation?

5) Please attach your configuration file (**Mask IP addresses before submit this issue**).

Server configuration:

```javascript
    // Please attach your server configuration here.
```

Client configuration:

```javascript
    // Please attach your client configuration here.
```

6) Please attach error logs, especially the bottom lines if the file is large. Error log file is usually at `/var/log/v2ray/error.log` on Linux.

Server error log:

```javascript
    // Please attach your server error log here.
```

Client error log:

```javascript
    // Please attach your client error log here.
```

7) Please attach access log. Access log is usually at '/var/log/v2ray/access.log' on Linux.

```javascript
    // Please attach your server access log here.
```

8) Other configurations (such as Nginx) and logs.

9) If V2Ray doesn't run, please attach output from `--test`.

The command is usually `/usr/bin/v2ray/v2ray --test --config /etc/v2ray/config.json`, but may vary according to your scenario.

10) If V2Ray service doesn't run, please attach journal log.

Usual command is `journalctl -u v2ray`.

Please review your issue before submitting.

================================================
FILE: .github/ISSUE_TEMPLATE/other_en.md
================================================
---
name: Other
about: "其它问题请使用 https://github.com/v2fly/discussion/issues 进行讨论 / Please discuss other issues at https://github.com/v2fly/discussion/issues"
---

如果你遇到的问题不是 V2Ray 的 bug,比如你不清楚要如何配置,请使用[Discussion](https://github.com/v2fly/discussion/issues)进行讨论。

此 Issue 会被立即关闭。

If you are not sure if your question is truely a bug in V2Ray, please discuss it [here](https://github.com/v2fly/discussion/issues) first.

This issue will be closed immediately.


================================================
FILE: .github/ISSUE_TEMPLATE.md
================================================
如果你遇到的问题不是 V2Ray 的 bug,比如你不清楚要如何配置,请使用[Discussion](https://github.com/v2fly/discussion/issues)进行讨论。

此 Issue 会被立即关闭。

If you are not sure if your question is truely a bug in V2Ray, please discuss it [here](https://github.com/v2fly/discussion/issues) first.

This issue will be closed immediately.


================================================
FILE: .github/dependabot.yml
================================================
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates

version: 2
updates:
  - package-ecosystem: "gomod"
    directory: "/"
    schedule:
      interval: "daily"
    open-pull-requests-limit: 10

  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "daily"


================================================
FILE: .github/linters/.golangci.yml
================================================
run:
  timeout: 5m
  skip-files:
    - generated.*

issues:
  new: true

linters:
  enable:
    - bodyclose
    - depguard
    - gocritic
    - gofmt
    - goimports
    - golint
    - goprintffuncname
    - gosimple
    - govet
    - ineffassign
    - misspell
    - nakedret
    - noctx
    - nolintlint
    - rowserrcheck
    - scopelint
    - staticcheck
    - structcheck
    - stylecheck
    - typecheck
    - unconvert
    - unparam
    - varcheck
    - whitespace
  disable:
    - deadcode
    - errcheck
    - unused


================================================
FILE: .github/pull_request_template.md
================================================
Please Move to https://github.com/v2fly/v2ray-core/pulls


================================================
FILE: .github/workflows/codeql-analysis.yml
================================================
name: CodeQL

on:
  push:
    branches: [master]
    paths:
      - "**/*.go"
  pull_request:
    branches: [master]
    types: [opened, synchronize, reopened]
    paths:
      - "**/*.go"
  schedule:
    - cron: '0 0 * * 1'

jobs:
  analyze:
    if: github.repository != 'v2ray/v2ray-core'
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        # Override automatic language detection by changing the below list
        # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
        language: ['go']
        # Learn more...
        # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection

    steps:
    - name: Checkout repository
      uses: actions/checkout@v2
      with:
        # We must fetch at least the immediate parents so that if this is
        # a pull request then we can checkout the head.
        fetch-depth: 2

    # If this run was triggered by a pull request event, then checkout
    # the head of the pull request instead of the merge commit.
    - run: git checkout HEAD^2
      if: ${{ github.event_name == 'pull_request' }}

    # Initializes the CodeQL tools for scanning.
    - name: Initialize CodeQL
      uses: github/codeql-action/init@v1
      with:
        languages: ${{ matrix.language }}
        # If you wish to specify custom queries, you can do so here or in a config file.
        # By default, queries listed here will override any specified in a config file. 
        # Prefix the list here with "+" to use these queries and those in the config file.
        # queries: ./path/to/local/query, your-org/your-repo/queries@main

    # Autobuild attempts to build any compiled languages  (C/C++, C#, or Java).
    # If this step fails, then you should remove it and run the build manually (see below)
    - name: Autobuild
      uses: github/codeql-action/autobuild@v1

    # ℹ️ Command-line programs to run using the OS shell.
    # 📚 https://git.io/JvXDl

    # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
    #    and modify them (or add more) to build your code if your project
    #    uses a compiled language

    #- run: |
    #   make bootstrap
    #   make release

    - name: Perform CodeQL Analysis
      uses: github/codeql-action/analyze@v1


================================================
FILE: .github/workflows/coverage.yml
================================================
name: Coverage

on:
  push:
    branches: [master]
    paths:
      - "**/*.go"

jobs:
  coverage:
    if: github.repository != 'v2ray/v2ray-core'
    runs-on: ubuntu-latest
    steps:
      - name: Set up Go 1.x
        uses: actions/setup-go@v2
        with:
          go-version: ^1.15

      - name: Checkout codebase
        uses: actions/checkout@v2

      - name: Cache go module
        uses: actions/cache@v2
        id: cache-gomodules
        with:
          path: ~/go/pkg/mod
          key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
          restore-keys: |
            ${{ runner.os }}-go-

      - name: Get dependencies
        if: steps.cache-gomodules.outputs.cache-hit != 'true'
        run: |
          go get -v -t -d ./...

      - name: Run coverage
        run: ./testing/coverage/coverall2

      - name: Upload coverage to Codecov
        uses: codecov/codecov-action@v1
        with:
          file: ./coverage.txt
          fail_ci_if_error: true


================================================
FILE: .github/workflows/linter.yml
================================================
name: Linter

on:
  push:
    branches: [master]
    paths:
      - "**/*.go"
  pull_request:
    branches: [master]
    types: [opened, synchronize, reopened]
    paths:
      - "**/*.go"

jobs:
  lint:
    if: github.repository != 'v2ray/v2ray-core'
    runs-on: ubuntu-latest
    steps:
      - name: Set up Go 1.x
        uses: actions/setup-go@v2
        with:
          go-version: ^1.15

      - name: Checkout codebase
        uses: actions/checkout@v2

      - name: golangci-lint
        uses: golangci/golangci-lint-action@v2
        with:
          version: v1.31
          args: --config=.github/linters/.golangci.yml
          only-new-issues: true


================================================
FILE: .github/workflows/sign.yml
================================================
name: Sign

on:
  release:
    types: [released]

jobs:
  sign:
    if: github.repository != 'v2ray/v2ray-core'
    runs-on: ubuntu-latest
    steps:
      - name: Checkout default branch
        uses: actions/checkout@v2

      - name: Grant it execution permission
        run: |
          chmod +x $GITHUB_WORKSPACE/release/requestsign_github.sh
          chmod +x $GITHUB_WORKSPACE/release/requestsign.sh

      - name: Invoke release signing
        env:
          SIGN_SERVICE_PASSWORD: ${{ secrets.SIGN_SERVICE_PASSWORD }}
          SIGN_SERIVCE_URL: ${{ secrets.SIGN_SERIVCE_URL }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: $GITHUB_WORKSPACE/release/requestsign_github.sh


================================================
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@v3.0.13
        with:
          repo-token: ${{ secrets.GITHUB_TOKEN }}
          stale-issue-message: "This issue is stale because it has been open 120 days with no activity. Remove stale label or comment or this will be closed in 5 days"
          stale-pr-message: 'It has been open 120 days with no activity. Remove stale label or comment or this will be closed in 5 days'
          days-before-stale: 120
          days-before-close: 5


================================================
FILE: .github/workflows/test.yml
================================================
name: Test

on:
  push:
    branches: [master]
    paths:
      - "**/*.go"
      - "go.mod"
      - "go.sum"
  pull_request:
    branches: [master]
    types: [opened, synchronize, reopened]
    paths:
      - "**/*.go"
      - "go.mod"
      - "go.sum"

jobs:
  test:
    if: github.repository != 'v2ray/v2ray-core'
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [windows-latest, ubuntu-latest, macos-latest]
    steps:
      - name: Set up Go 1.x
        uses: actions/setup-go@v2
        with:
          go-version: ^1.15

      - name: Checkout codebase
        uses: actions/checkout@v2

      - name: Cache go module
        uses: actions/cache@v2
        with:
          path: ~/go/pkg/mod
          key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
          restore-keys: ${{ runner.os }}-go-

      - name: Test
        run: go test -timeout 1h -v ./...


================================================
FILE: .github/workflows/updateGeofile.yml
================================================
name: Update Geofiles

on:
  schedule:
    - cron: "0 0 * * FRI"

jobs:
  update:
    if: github.repository == 'v2fly/v2ray-core'
    runs-on: ubuntu-latest
    steps:
      - name: Checkout codebase
        uses: actions/checkout@v2

      - name: Download
        run: |
          curl -L -o release/config/geoip.dat "https://github.com/v2fly/geoip/raw/release/geoip.dat"
          curl -L -o release/config/geosite.dat "https://github.com/v2fly/domain-list-community/raw/release/dlc.dat"

      - name: push
        run: |
          git config --local user.email "action@github.com"
          git config --local user.name "GitHub Action"
          git commit -am "update geoip, geosite"
          git push -v --progress


================================================
FILE: .gitignore
================================================
*.DS_Store
bazel-*
.idea

================================================
FILE: Dockerfile
================================================
############################
# STEP 1 build executable binary
############################
FROM golang:alpine AS builder

RUN apk update && apk add --no-cache git bash wget curl
WORKDIR /build
RUN git clone --progress https://github.com/v2fly/v2ray-core.git . && \
    bash ./release/user-package.sh nosource noconf codename=$(git describe --abbrev=0 --tags) buildname=docker-fly abpathtgz=/tmp/v2ray.tgz

############################
# STEP 2 build a small image
############################
FROM alpine

LABEL maintainer "V2Fly Community <admin@v2fly.org>"
COPY --from=builder /tmp/v2ray.tgz /tmp
RUN apk update && apk add ca-certificates && \
    mkdir -p /usr/bin/v2ray && \
    tar xvfz /tmp/v2ray.tgz -C /usr/bin/v2ray

#ENTRYPOINT ["/usr/bin/v2ray/v2ray"]
ENV PATH /usr/bin/v2ray:$PATH
CMD ["v2ray", "-config=/etc/v2ray/config.json"]


================================================
FILE: LICENSE
================================================
The MIT License (MIT)

Copyright (c) 2015-2020 V2Fly Community

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.



================================================
FILE: README.md
================================================
# Move To https://github.com/v2fly/v2ray-core

***

# Project V

[![GitHub Test Badge][1]][2] [![codecov.io][3]][4] [![GoDoc][5]][6] [![codebeat][7]][8] [![Downloads][9]][10] [![Downloads][11]][12]

[1]: https://github.com/v2fly/v2ray-core/workflows/Test/badge.svg "GitHub Test Badge"
[2]: https://github.com/v2fly/v2ray-core/actions "GitHub Actions Page"
[3]: https://codecov.io/gh/v2fly/v2ray-core/branch/master/graph/badge.svg?branch=master "Coverage Badge"
[4]: https://codecov.io/gh/v2fly/v2ray-core?branch=master "Codecov Status"
[5]: https://godoc.org/v2ray.com/core?status.svg "GoDoc Badge"
[6]: https://godoc.org/v2ray.com/core "GoDoc"
[7]: https://goreportcard.com/badge/github.com/v2fly/v2ray-core "Goreportcard Badge"
[8]: https://goreportcard.com/report/github.com/v2fly/v2ray-core "Goreportcard Result"
[9]: https://img.shields.io/github/downloads/v2ray/v2ray-core/total.svg "v2ray/v2ray-core downloads count"
[10]: https://github.com/v2ray/v2ray-core/releases "v2ray/v2ray-core release page"
[11]: https://img.shields.io/github/downloads/v2fly/v2ray-core/total.svg "v2fly/v2ray-core downloads count"
[12]: https://github.com/v2fly/v2ray-core/releases "v2fly/v2ray-core release page"

Project V is a set of network tools that help you to build your own computer network. It secures your network connections and thus protects your privacy. See [our website](https://www.v2fly.org/) for more information.

## License

[The MIT License (MIT)](https://raw.githubusercontent.com/v2fly/v2ray-core/master/LICENSE)

## Credits

This repo relies on the following third-party projects:

- In production:
  - [gorilla/websocket](https://github.com/gorilla/websocket)
  - [gRPC](https://google.golang.org/grpc)
- For testing only:
  - [miekg/dns](https://github.com/miekg/dns)
  - [h12w/socks](https://github.com/h12w/socks)


================================================
FILE: SECURITY.md
================================================
# 安全策略 Security Policy

## 受支持的版本 Supported Versions

目前 v2ray-core 项目由 [V2Fly 社区](https://github.com/v2fly) 继续提供代码维护,由于精力有限且项目复杂度较高,只维护主线代码的功能和安全性完整。原则上主页的兼容性保证继续遵循,
如有例外另行说明。

Currently v2ray-core project is maintained by [V2Fly community](https://github.com/v2fly). Feature and security guarantee may only be limited to the
master branch, though we would still try our best to follow the compatiblity claims listed on the official website.


## 汇报安全风险 Reporting a Vulnerability

使用邮箱: security |at| v2fly.org。

Report to email: security |at| v2fly.org.

GPG public key:

```
pub   rsa4096 2020-06-02 [SC] [有效至:2022-01-02]
      E2E35E27914FB007C0D4B6DDB117BA3BE8B494A7
uid           [ 绝对 ] V2Fly Developers <dev@v2fly.org>
sub   rsa4096 2020-06-02 [E] [有效至:2022-01-02]
sub   rsa4096 2020-11-08 [S] [有效至:2022-01-02] // 用于 Debian / Ubuntu 签名


-----BEGIN PGP PUBLIC KEY BLOCK-----

mQINBF7V7pQBEACozcw4/BlPgFWaz4AdN8HKSrCDLlN+/g7m4AKZIo13fAnDh+sJ
2H4NrWNr0xxgovbco5Xw4OSSwY1BuUhnb4AmIyxbwqUQD2UADe5xD6gMBwNiJTP4
02VCHhh7DnWTeLbAsUgRotxUCxsWVvd2F08SYGfJggOVftOnG+VNnwzTOvHWFVEw
1Pv1DaY7bKSA0voACerRbAPCYqhmElAGJHYNjBMaxqCaWFJWpAFfBxkvS1FDVyZk
BsABhn6sOcGJn8EYSHUIXhWwqtkQCjBB4OOik+Jn+S2DFGyk5l1NrGRQtX8C0BYn
nc7VaxtFOp5fnJ4y0GNd4AM9KO0/Ojosi6b64l407Fj9i9OXznmZUACQw2u+VcL3
qNy768hsTmka3pXzpRHZwYcOLOEr3jGHmLOtXgQ656OjF8Xd9DJ4cB42X8iBeqTp
iQchHIdBpnu27ZbBFy09OMak+STB5zA0JmxDaC8b48mVkc0BMRXdYl7wWXJsEJf1
roAOr3RCBKiE840w0PLOTnUljfqazPYTwzs91oP+SeZjBmGOpaAh7bh5BVOpzPSE
bdA61/n01GEb5bpOKpaTi9GviF3RCbfFnLKJnBq0vHvW9BqKTVFRPAKkBGuOPBdy
8MBNY+VY/2aP3ukZUoYe8Ypl9Q7dVPRjnoWaH0sEMzftoh+3s7GSSgAylQARAQAB
tCBWMkZseSBEZXZlbG9wZXJzIDxkZXZAdjJmbHkub3JnPokCVAQTAQgAPgIbAwUL
CQgHAgYVCgkICwIEFgIDAQIeAQIXgBYhBOLjXieRT7AHwNS23bEXujvotJSnBQJf
p4leBQkC+1DKAAoJELEXujvotJSn124P/0swu9POvEQtxVlRzNh2VjAGHZ5NEDnl
pMrhfC5ryCYtlVS/kc2WwRhIRHKzr9nbamgSxUCiyLagfnIjhIvAohun49grYNzG
MZWRURiuFrCnYbD7juJTvfbzZCzJk7LPsdnqHWr8fYcOZMTOZVzQiQB2jUx2KeRm
yV8aV21Z8gMLqSGjs06a0UaRbKB0FSysTURm91/jFmiH43aG1s/LcB9/lKf5HpNl
9or6LrEOrokAwtkMSBYTqm7Dp1j+cK0iOMw2CmMqmQZkV+i6msYrQRiX/X6YufiM
wfMMSdOZOz9KG+k+C6N1swSbGeDMrJfnDUDbvrAXKhDjNgY7UBwbk69Abd7Y9aQz
/jVmrFEWt4lisBxglBot60CRUTM2boK/uQS5zBCJhemeg14F9Q/FRiUTlS8jQoeK
PWeK2lagYJS8lpJZLXkqe4xSpjCgoT0Z+lYSfTjx+T0AFF+xz5E243Lb5kDxwnR9
Y5CZt3vV6GWBYOt9MEL3pk7AnYyNT1y1KIiMyONh/Z1koUdHr4J9exllnsmAJQUa
W/j0UtVsLsvUjFv9RTr9w5p/U0J0VLIN0YOpx4wYaBEwFIa8lsL+Ey1Vphkvvjfz
uMRAHe4v+axWb1f1hVCBjtyCVyvzf+i9RTAYsBJ3MJ0C8cvvrm10N9B7MHh0JZA5
PcJSilailp1TuQINBF7V7pQBEADkQdO75smeKnmPt0/aNNlb7JDOSWW5VY0kYgx3
6Toh139JstIQ2xz0CLSGReizUFB6eR3DXmezLrmhkgN2Aq5A+hCtFAJwWKuKr1HS
usvJ1el9h0oh7IO+tF8E/gNYwWfabjPX27FGVCHR1qG7ffN51Bghrnwi1T4YC98E
R9EGU6N0Xs9DeIJL9WQPH/DF22251i/OAXkqKVGn3PNe2cBsp0yKxr9mlSyzjrha
KXokPiPcvNqlnkiDCgfiRj7c2C2Lyl9PoEiGpsNZaCZYkMPgjM0xiLenQddwRyOU
z2cLG3d8WdCTRyHSZd/YQtSi5R6AnkJEsVtUiDN5zwNFVpQlTq3jNHsVUpjFU2nK
ourTZVCCLbAC60VTdxLN6eFO0f+lS2WjyJ7uZ9SGbS6uP0jMNphH/QjVF848bWXs
1CuZty5QQY7+MTNUAhSWWntrpTkdXYqT0zUqiOc1YNnkfg3hvC4d0dbnFTfcyZnB
Sg8e7/9n6+ms75/deYgnLuA6h7pkIcflm7pUMfVKXKz5Vlc8FC9ia0UtobeKBKqi
jObfiO/zmNL0HQBeX0e8GkJrCyv6ikD8cUqsmVtgw7jdxGsV0SL5CddDnGKsc68O
pGDmkAuRqR3QtXju/4r7a8IEVveGWc3rUvddYrtqbbCNWCN0JKX13PEvbNAm+2eD
MGQtcQARAQABiQI8BBgBCAAmAhsMFiEE4uNeJ5FPsAfA1LbdsRe6O+i0lKcFAl+n
dwcFCQL7PnMACgkQsRe6O+i0lKeWfxAApopL5I9p4btmkcLIg2lkA1n+czFekbdr
2tjFKrBER4QWkyDCUE8QaVo/ECveTHmnxrTB/djW6xqPVS77PL8xOATIYTo6qU38
oTCB1T7/P2L9qI72BzcRY5f9ZPyJhCtrkvjCPzjUjw+ZIPIOgQcWgKHWnE+OyUKD
0GkVEUME3QP5S4Nr3XGrgS7oxDAmD52u7pn0mSk5WmEcLW0oGwsVdc4aDXxpX+u/
gkBZysmAuomPov7iXVosMakl+4rz30yPcrL9A81m1WAeB3PGkpaO3B++8Ql+FBCQ
OrLtPn/nnIzEuAXB1Hd8vYzxtRM2CZvhRExM7xofnhkBJOtR/ddfbJa7H5+Aruc0
4S0JIaqMCrC6tZezjTACAzrWULmZZGmrHbLrmXBuLk0huRkeIRnDzHP+DoE2UciL
3hR9EGOHX9O/dGb3bb3y11LAf7GI28ZG7So1GeoFkEOga1IJnsBnXCqwM8vbDDWq
/7aLb3/m0gT7DUfjeXKfWPJXcnaq8r4llHzDn2i6ax4Uq/brCOLj9ovVGIctZTbt
yvsFOc1bVkSuUM+pMkCtBx80/sJSB2Nu94S6osdaUlRE+jaCcqEbPd+G68Yd0Khi
CL8zF1a3dX1dpuVFTLNpXOgrviGBzXQmzFeil7mWFs0l+1XZOPz9nhmRrMn6wV3n
i4KItRSJAXy5Ag0EX6d5hQEQAMsVyLTXdybeei2nWDb5jtzzC3AtSnPWtKG4B86C
BXncaZpU43hKI3oduW2+42eM8n8KTvO11r9xv4zKATfaHBZq2hkKZdDQjuSstovr
a3hapHHknHeNVTg3yuiakKzpr6FK23W/GE1lJfhz254v9+dRV0KazWksXvpGEdgI
+6sC4Nr5bKgJVEQibyrrL0gmzlVB/oQU/W4eGvk21zmgMlHri+edBLpVtlCmn7k/
0t+2X9D1Pq2nkjMUurB9EJ1z24LMldmPOl6P7iJCx9kSUjcHrEg56q5VSZq50FAj
DeSjAqsdussI8cdstCMktE9nhizxVKFXpbXifqoYfJwCo23wFqQJpyPgQqHIT12s
GWRUa/MF6hRYg/5CyeadDmkmnKPTPjmQ2S2SFNXX7xs+dZKvIvXP30z4cpuVY8i8
chZSRNb8K0L9T0Jme7CPm28F6lvDUkNDQ1WErXZruHbOKwQOfQBdXK3nedOiUpBt
401HVlGUJSInfEb3JXU01tRqnnzI/y5z7cWCGEMEa6TeaCrMbVvl8xeAA1w/nw0y
zHz6/Pnf4TITuCH22aa7+xfgpq8gRLhUUws89mbQT+9fd8tT65+Q8xcaLCyzrLAq
zND5sVZ4/PwaYc8UNZcHjeQR7aYWI1xgr/IwY1wyDWZLbWgkk0HVxpvYdMEpJryD
AyMdABEBAAGJBHIEGAEIACYWIQTi414nkU+wB8DUtt2xF7o76LSUpwUCX6d5hQIb
AgUJAim2AAJACRCxF7o76LSUp8F0IAQZAQgAHRYhBK8FZLGpNMztuW02YbJOz+X/
ddOBBQJfp3mFAAoJELJOz+X/ddOBNKQP/0nwIC4R9gQhY53vME7VA7elIrBiSM6d
Va26a7J1nrCcpDAE7Lp0TqzrDMqyen+IL4X5QK5sKTgenYTgjppEJIQn+Wup54ix
I+YOQ8MVLfN6/3QPACWMngSPRF+UKDg4hyTCEL+/GCgTp58oXrl/YIO6Oqt5drog
w4+4ufU1/eKTb2ruGULGl9jZvFSZpLdsvJ19xJB2kC1k8GVNu7MnUL+S2pU/9kO4
5EZ/jEa1wT45zev+HdmzX5TYW6SLaI9HKHMqbQz2EHc3tRYIDaz3FE3s4VdMjqpp
e42SvkOYaguc6cXToDbzBmU+iWGlXCTHfNhxwxoUYcKZlDEkEtvSYHJOb0k9eqbT
gvMb5GjbAgqqwOBwtN3v790j8jEG+cdXR3qHcEx0bw3F2Bd18U7j946OxHLKE5Xk
2sWEG422maVrE9o1DdeTV5oDFNNPBzqfjgGBZCCKrjkpldhDOHeoDU2aFMJ7yVqw
ZwKwJ5f8fdNS13UnQVwGsZ2BsW1cox5ZGZ/C5A7mfSF1WAgJcYIw4M2JQbDn4Yuw
yqjyg53lT3OurBONbEZ7unnsLqpT9qKwZ1qCemqGRJieXXxJwl7G4gBgZbH0rBJR
6dhbyt4c2JE8MMdC65mDWneltNM6pttC/j5jCuvIlZGACZ91UuLLediJJWAlOJ+1
fBQ0m8TD6d8ZrakP/RFMLZrxh9WPaFB43sW/b1Fq2h933HQ29oSQFuXhsHsx1Vaq
HTRTcBB7kywAr9+zMYsOsk0/WnoZNGoMkUWu/gFkb6CdUcsdEumgyZ8S24VoBCHB
T1fD/8eOA5K82hwAFcKbPwuuTLtf9b9HB4/xsObfcczTeqIknzIPsGlgVz4w1c9a
StSo4iI4bCSLL+/mqiXZ+ArXJ/z4Vejl92fNLWVOlOrjkBV+AY6iAFCCsxJ1O5ud
5a5r1bUeBXd0BcQ1m/hpjawMC1y0SkIBTQCgxIQoPoxJ27hHNIN1R2nkqfY9vboQ
7O0uIHF8fmuz93xg68ZTW0JHwOw4Mz88lGibE2laHApjKWZAtF/i+LlhbnewtESL
EuGTT7gt7cSHgnBiDEIm5UJVEGeM0sMReztxy9V7glohH5DV8GpVK/GncKlsrh1K
BuEuz7IrqKlBzhsDy0SrNZpX7EzsiU1uvoA6teT4EPey8qXH+7WR9B2ad1Zc5yE3
zv4BpnWkkJp8qdYu4fdCs/mrmnBR5G1YdOAIlNWhU74Wdyq+W4HfTWMgvJHmElnZ
UvQ9RDTWnw2+3n2ATeLf9ZwW1g4/Dqh55OaLtJZo5me8vU9W+vkm34xzfVfD/mus
ljogw5eiGyj8j3lUVjYWu28l/bz0zDUueWmHhV8E8z0Cn7OhrHPpUCHx2Aep
=quYd
-----END PGP PUBLIC KEY BLOCK-----

```


================================================
FILE: WORKSPACE
================================================
workspace(name = "v2ray_core")


================================================
FILE: annotations.go
================================================
package core

// Annotation is a concept in V2Ray. This struct is only for documentation. It is not used anywhere.
// Annotations begin with "v2ray:" in comment, as metadata of functions or types.
type Annotation struct {
	// API is for types or functions that can be used in other libs. Possible values are:
	//
	// * v2ray:api:beta for types or functions that are ready for use, but maybe changed in the future.
	// * v2ray:api:stable for types or functions with guarantee of backward compatibility.
	// * v2ray:api:deprecated for types or functions that should not be used anymore.
	//
	// Types or functions without api annotation should not be used externally.
	API string
}


================================================
FILE: app/app.go
================================================
// Package app contains feature implementations of V2Ray. The features may be enabled during runtime.
package app


================================================
FILE: app/commander/commander.go
================================================
// +build !confonly

package commander

//go:generate go run v2ray.com/core/common/errors/errorgen

import (
	"context"
	"net"
	"sync"

	"google.golang.org/grpc"

	"v2ray.com/core"
	"v2ray.com/core/common"
	"v2ray.com/core/common/signal/done"
	"v2ray.com/core/features/outbound"
)

// Commander is a V2Ray feature that provides gRPC methods to external clients.
type Commander struct {
	sync.Mutex
	server   *grpc.Server
	services []Service
	ohm      outbound.Manager
	tag      string
}

// NewCommander creates a new Commander based on the given config.
func NewCommander(ctx context.Context, config *Config) (*Commander, error) {
	c := &Commander{
		tag: config.Tag,
	}

	common.Must(core.RequireFeatures(ctx, func(om outbound.Manager) {
		c.ohm = om
	}))

	for _, rawConfig := range config.Service {
		config, err := rawConfig.GetInstance()
		if err != nil {
			return nil, err
		}
		rawService, err := common.CreateObject(ctx, config)
		if err != nil {
			return nil, err
		}
		service, ok := rawService.(Service)
		if !ok {
			return nil, newError("not a Service.")
		}
		c.services = append(c.services, service)
	}

	return c, nil
}

// Type implements common.HasType.
func (c *Commander) Type() interface{} {
	return (*Commander)(nil)
}

// Start implements common.Runnable.
func (c *Commander) Start() error {
	c.Lock()
	c.server = grpc.NewServer()
	for _, service := range c.services {
		service.Register(c.server)
	}
	c.Unlock()

	listener := &OutboundListener{
		buffer: make(chan net.Conn, 4),
		done:   done.New(),
	}

	go func() {
		if err := c.server.Serve(listener); err != nil {
			newError("failed to start grpc server").Base(err).AtError().WriteToLog()
		}
	}()

	if err := c.ohm.RemoveHandler(context.Background(), c.tag); err != nil {
		newError("failed to remove existing handler").WriteToLog()
	}

	return c.ohm.AddHandler(context.Background(), &Outbound{
		tag:      c.tag,
		listener: listener,
	})
}

// Close implements common.Closable.
func (c *Commander) Close() error {
	c.Lock()
	defer c.Unlock()

	if c.server != nil {
		c.server.Stop()
		c.server = nil
	}

	return nil
}

func init() {
	common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, cfg interface{}) (interface{}, error) {
		return NewCommander(ctx, cfg.(*Config))
	}))
}


================================================
FILE: app/commander/config.pb.go
================================================
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// 	protoc-gen-go v1.25.0
// 	protoc        v3.13.0
// source: app/commander/config.proto

package commander

import (
	proto "github.com/golang/protobuf/proto"
	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
	reflect "reflect"
	sync "sync"
	serial "v2ray.com/core/common/serial"
)

const (
	// Verify that this generated code is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
	// Verify that runtime/protoimpl is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)

// This is a compile-time assertion that a sufficiently up-to-date version
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4

// Config is the settings for Commander.
type Config struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	// Tag of the outbound handler that handles grpc connections.
	Tag string `protobuf:"bytes,1,opt,name=tag,proto3" json:"tag,omitempty"`
	// Services that supported by this server. All services must implement Service
	// interface.
	Service []*serial.TypedMessage `protobuf:"bytes,2,rep,name=service,proto3" json:"service,omitempty"`
}

func (x *Config) Reset() {
	*x = Config{}
	if protoimpl.UnsafeEnabled {
		mi := &file_app_commander_config_proto_msgTypes[0]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *Config) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*Config) ProtoMessage() {}

func (x *Config) ProtoReflect() protoreflect.Message {
	mi := &file_app_commander_config_proto_msgTypes[0]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use Config.ProtoReflect.Descriptor instead.
func (*Config) Descriptor() ([]byte, []int) {
	return file_app_commander_config_proto_rawDescGZIP(), []int{0}
}

func (x *Config) GetTag() string {
	if x != nil {
		return x.Tag
	}
	return ""
}

func (x *Config) GetService() []*serial.TypedMessage {
	if x != nil {
		return x.Service
	}
	return nil
}

var File_app_commander_config_proto protoreflect.FileDescriptor

var file_app_commander_config_proto_rawDesc = []byte{
	0x0a, 0x1a, 0x61, 0x70, 0x70, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x65, 0x72, 0x2f,
	0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x18, 0x76, 0x32,
	0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x63, 0x6f, 0x6d,
	0x6d, 0x61, 0x6e, 0x64, 0x65, 0x72, 0x1a, 0x21, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x73,
	0x65, 0x72, 0x69, 0x61, 0x6c, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x73, 0x73,
	0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x5c, 0x0a, 0x06, 0x43, 0x6f, 0x6e,
	0x66, 0x69, 0x67, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
	0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x40, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
	0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63,
	0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x73, 0x65, 0x72, 0x69, 0x61,
	0x6c, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x07,
	0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x59, 0x0a, 0x1c, 0x63, 0x6f, 0x6d, 0x2e, 0x76,
	0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x63, 0x6f,
	0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x65, 0x72, 0x50, 0x01, 0x5a, 0x1c, 0x76, 0x32, 0x72, 0x61, 0x79,
	0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x63, 0x6f,
	0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x65, 0x72, 0xaa, 0x02, 0x18, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e,
	0x43, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64,
	0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}

var (
	file_app_commander_config_proto_rawDescOnce sync.Once
	file_app_commander_config_proto_rawDescData = file_app_commander_config_proto_rawDesc
)

func file_app_commander_config_proto_rawDescGZIP() []byte {
	file_app_commander_config_proto_rawDescOnce.Do(func() {
		file_app_commander_config_proto_rawDescData = protoimpl.X.CompressGZIP(file_app_commander_config_proto_rawDescData)
	})
	return file_app_commander_config_proto_rawDescData
}

var file_app_commander_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_app_commander_config_proto_goTypes = []interface{}{
	(*Config)(nil),              // 0: v2ray.core.app.commander.Config
	(*serial.TypedMessage)(nil), // 1: v2ray.core.common.serial.TypedMessage
}
var file_app_commander_config_proto_depIdxs = []int32{
	1, // 0: v2ray.core.app.commander.Config.service:type_name -> v2ray.core.common.serial.TypedMessage
	1, // [1:1] is the sub-list for method output_type
	1, // [1:1] is the sub-list for method input_type
	1, // [1:1] is the sub-list for extension type_name
	1, // [1:1] is the sub-list for extension extendee
	0, // [0:1] is the sub-list for field type_name
}

func init() { file_app_commander_config_proto_init() }
func file_app_commander_config_proto_init() {
	if File_app_commander_config_proto != nil {
		return
	}
	if !protoimpl.UnsafeEnabled {
		file_app_commander_config_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*Config); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
	}
	type x struct{}
	out := protoimpl.TypeBuilder{
		File: protoimpl.DescBuilder{
			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
			RawDescriptor: file_app_commander_config_proto_rawDesc,
			NumEnums:      0,
			NumMessages:   1,
			NumExtensions: 0,
			NumServices:   0,
		},
		GoTypes:           file_app_commander_config_proto_goTypes,
		DependencyIndexes: file_app_commander_config_proto_depIdxs,
		MessageInfos:      file_app_commander_config_proto_msgTypes,
	}.Build()
	File_app_commander_config_proto = out.File
	file_app_commander_config_proto_rawDesc = nil
	file_app_commander_config_proto_goTypes = nil
	file_app_commander_config_proto_depIdxs = nil
}


================================================
FILE: app/commander/config.proto
================================================
syntax = "proto3";

package v2ray.core.app.commander;
option csharp_namespace = "V2Ray.Core.App.Commander";
option go_package = "v2ray.com/core/app/commander";
option java_package = "com.v2ray.core.app.commander";
option java_multiple_files = true;

import "common/serial/typed_message.proto";

// Config is the settings for Commander.
message Config {
  // Tag of the outbound handler that handles grpc connections.
  string tag = 1;
  // Services that supported by this server. All services must implement Service
  // interface.
  repeated v2ray.core.common.serial.TypedMessage service = 2;
}


================================================
FILE: app/commander/errors.generated.go
================================================
package commander

import "v2ray.com/core/common/errors"

type errPathObjHolder struct{}

func newError(values ...interface{}) *errors.Error {
	return errors.New(values...).WithPathObj(errPathObjHolder{})
}


================================================
FILE: app/commander/outbound.go
================================================
// +build !confonly

package commander

import (
	"context"
	"sync"

	"v2ray.com/core/common"
	"v2ray.com/core/common/net"
	"v2ray.com/core/common/signal/done"
	"v2ray.com/core/transport"
)

// OutboundListener is a net.Listener for listening gRPC connections.
type OutboundListener struct {
	buffer chan net.Conn
	done   *done.Instance
}

func (l *OutboundListener) add(conn net.Conn) {
	select {
	case l.buffer <- conn:
	case <-l.done.Wait():
		conn.Close() // nolint: errcheck
	default:
		conn.Close() // nolint: errcheck
	}
}

// Accept implements net.Listener.
func (l *OutboundListener) Accept() (net.Conn, error) {
	select {
	case <-l.done.Wait():
		return nil, newError("listen closed")
	case c := <-l.buffer:
		return c, nil
	}
}

// Close implement net.Listener.
func (l *OutboundListener) Close() error {
	common.Must(l.done.Close())
L:
	for {
		select {
		case c := <-l.buffer:
			c.Close() // nolint: errcheck
		default:
			break L
		}
	}
	return nil
}

// Addr implements net.Listener.
func (l *OutboundListener) Addr() net.Addr {
	return &net.TCPAddr{
		IP:   net.IP{0, 0, 0, 0},
		Port: 0,
	}
}

// Outbound is a outbound.Handler that handles gRPC connections.
type Outbound struct {
	tag      string
	listener *OutboundListener
	access   sync.RWMutex
	closed   bool
}

// Dispatch implements outbound.Handler.
func (co *Outbound) Dispatch(ctx context.Context, link *transport.Link) {
	co.access.RLock()

	if co.closed {
		common.Interrupt(link.Reader)
		common.Interrupt(link.Writer)
		co.access.RUnlock()
		return
	}

	closeSignal := done.New()
	c := net.NewConnection(net.ConnectionInputMulti(link.Writer), net.ConnectionOutputMulti(link.Reader), net.ConnectionOnClose(closeSignal))
	co.listener.add(c)
	co.access.RUnlock()
	<-closeSignal.Wait()
}

// Tag implements outbound.Handler.
func (co *Outbound) Tag() string {
	return co.tag
}

// Start implements common.Runnable.
func (co *Outbound) Start() error {
	co.access.Lock()
	co.closed = false
	co.access.Unlock()
	return nil
}

// Close implements common.Closable.
func (co *Outbound) Close() error {
	co.access.Lock()
	defer co.access.Unlock()

	co.closed = true
	return co.listener.Close()
}


================================================
FILE: app/commander/service.go
================================================
// +build !confonly

package commander

import (
	"google.golang.org/grpc"
)

// Service is a Commander service.
type Service interface {
	// Register registers the service itself to a gRPC server.
	Register(*grpc.Server)
}


================================================
FILE: app/dispatcher/config.pb.go
================================================
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// 	protoc-gen-go v1.25.0
// 	protoc        v3.13.0
// source: app/dispatcher/config.proto

package dispatcher

import (
	proto "github.com/golang/protobuf/proto"
	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
	reflect "reflect"
	sync "sync"
)

const (
	// Verify that this generated code is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
	// Verify that runtime/protoimpl is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)

// This is a compile-time assertion that a sufficiently up-to-date version
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4

type SessionConfig struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields
}

func (x *SessionConfig) Reset() {
	*x = SessionConfig{}
	if protoimpl.UnsafeEnabled {
		mi := &file_app_dispatcher_config_proto_msgTypes[0]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *SessionConfig) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*SessionConfig) ProtoMessage() {}

func (x *SessionConfig) ProtoReflect() protoreflect.Message {
	mi := &file_app_dispatcher_config_proto_msgTypes[0]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use SessionConfig.ProtoReflect.Descriptor instead.
func (*SessionConfig) Descriptor() ([]byte, []int) {
	return file_app_dispatcher_config_proto_rawDescGZIP(), []int{0}
}

type Config struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Settings *SessionConfig `protobuf:"bytes,1,opt,name=settings,proto3" json:"settings,omitempty"`
}

func (x *Config) Reset() {
	*x = Config{}
	if protoimpl.UnsafeEnabled {
		mi := &file_app_dispatcher_config_proto_msgTypes[1]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *Config) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*Config) ProtoMessage() {}

func (x *Config) ProtoReflect() protoreflect.Message {
	mi := &file_app_dispatcher_config_proto_msgTypes[1]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use Config.ProtoReflect.Descriptor instead.
func (*Config) Descriptor() ([]byte, []int) {
	return file_app_dispatcher_config_proto_rawDescGZIP(), []int{1}
}

func (x *Config) GetSettings() *SessionConfig {
	if x != nil {
		return x.Settings
	}
	return nil
}

var File_app_dispatcher_config_proto protoreflect.FileDescriptor

var file_app_dispatcher_config_proto_rawDesc = []byte{
	0x0a, 0x1b, 0x61, 0x70, 0x70, 0x2f, 0x64, 0x69, 0x73, 0x70, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72,
	0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x19, 0x76,
	0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x69,
	0x73, 0x70, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x22, 0x15, 0x0a, 0x0d, 0x53, 0x65, 0x73, 0x73,
	0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x22,
	0x4e, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x44, 0x0a, 0x08, 0x73, 0x65, 0x74,
	0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x76, 0x32,
	0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x69, 0x73,
	0x70, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43,
	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x08, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x42,
	0x5c, 0x0a, 0x1d, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72,
	0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x69, 0x73, 0x70, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72,
	0x50, 0x01, 0x5a, 0x1d, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f,
	0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x64, 0x69, 0x73, 0x70, 0x61, 0x74, 0x63, 0x68, 0x65,
	0x72, 0xaa, 0x02, 0x19, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x41,
	0x70, 0x70, 0x2e, 0x44, 0x69, 0x73, 0x70, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x62, 0x06, 0x70,
	0x72, 0x6f, 0x74, 0x6f, 0x33,
}

var (
	file_app_dispatcher_config_proto_rawDescOnce sync.Once
	file_app_dispatcher_config_proto_rawDescData = file_app_dispatcher_config_proto_rawDesc
)

func file_app_dispatcher_config_proto_rawDescGZIP() []byte {
	file_app_dispatcher_config_proto_rawDescOnce.Do(func() {
		file_app_dispatcher_config_proto_rawDescData = protoimpl.X.CompressGZIP(file_app_dispatcher_config_proto_rawDescData)
	})
	return file_app_dispatcher_config_proto_rawDescData
}

var file_app_dispatcher_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_app_dispatcher_config_proto_goTypes = []interface{}{
	(*SessionConfig)(nil), // 0: v2ray.core.app.dispatcher.SessionConfig
	(*Config)(nil),        // 1: v2ray.core.app.dispatcher.Config
}
var file_app_dispatcher_config_proto_depIdxs = []int32{
	0, // 0: v2ray.core.app.dispatcher.Config.settings:type_name -> v2ray.core.app.dispatcher.SessionConfig
	1, // [1:1] is the sub-list for method output_type
	1, // [1:1] is the sub-list for method input_type
	1, // [1:1] is the sub-list for extension type_name
	1, // [1:1] is the sub-list for extension extendee
	0, // [0:1] is the sub-list for field type_name
}

func init() { file_app_dispatcher_config_proto_init() }
func file_app_dispatcher_config_proto_init() {
	if File_app_dispatcher_config_proto != nil {
		return
	}
	if !protoimpl.UnsafeEnabled {
		file_app_dispatcher_config_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*SessionConfig); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_app_dispatcher_config_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*Config); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
	}
	type x struct{}
	out := protoimpl.TypeBuilder{
		File: protoimpl.DescBuilder{
			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
			RawDescriptor: file_app_dispatcher_config_proto_rawDesc,
			NumEnums:      0,
			NumMessages:   2,
			NumExtensions: 0,
			NumServices:   0,
		},
		GoTypes:           file_app_dispatcher_config_proto_goTypes,
		DependencyIndexes: file_app_dispatcher_config_proto_depIdxs,
		MessageInfos:      file_app_dispatcher_config_proto_msgTypes,
	}.Build()
	File_app_dispatcher_config_proto = out.File
	file_app_dispatcher_config_proto_rawDesc = nil
	file_app_dispatcher_config_proto_goTypes = nil
	file_app_dispatcher_config_proto_depIdxs = nil
}


================================================
FILE: app/dispatcher/config.proto
================================================
syntax = "proto3";

package v2ray.core.app.dispatcher;
option csharp_namespace = "V2Ray.Core.App.Dispatcher";
option go_package = "v2ray.com/core/app/dispatcher";
option java_package = "com.v2ray.core.app.dispatcher";
option java_multiple_files = true;

message SessionConfig {
  reserved 1;
}

message Config {
  SessionConfig settings = 1;
}


================================================
FILE: app/dispatcher/default.go
================================================
// +build !confonly

package dispatcher

//go:generate go run v2ray.com/core/common/errors/errorgen

import (
	"context"
	"strings"
	"sync"
	"time"

	"v2ray.com/core"
	"v2ray.com/core/common"
	"v2ray.com/core/common/buf"
	"v2ray.com/core/common/log"
	"v2ray.com/core/common/net"
	"v2ray.com/core/common/protocol"
	"v2ray.com/core/common/session"
	"v2ray.com/core/features/outbound"
	"v2ray.com/core/features/policy"
	"v2ray.com/core/features/routing"
	routing_session "v2ray.com/core/features/routing/session"
	"v2ray.com/core/features/stats"
	"v2ray.com/core/transport"
	"v2ray.com/core/transport/pipe"
)

var (
	errSniffingTimeout = newError("timeout on sniffing")
)

type cachedReader struct {
	sync.Mutex
	reader *pipe.Reader
	cache  buf.MultiBuffer
}

func (r *cachedReader) Cache(b *buf.Buffer) {
	mb, _ := r.reader.ReadMultiBufferTimeout(time.Millisecond * 100)
	r.Lock()
	if !mb.IsEmpty() {
		r.cache, _ = buf.MergeMulti(r.cache, mb)
	}
	b.Clear()
	rawBytes := b.Extend(buf.Size)
	n := r.cache.Copy(rawBytes)
	b.Resize(0, int32(n))
	r.Unlock()
}

func (r *cachedReader) readInternal() buf.MultiBuffer {
	r.Lock()
	defer r.Unlock()

	if r.cache != nil && !r.cache.IsEmpty() {
		mb := r.cache
		r.cache = nil
		return mb
	}

	return nil
}

func (r *cachedReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
	mb := r.readInternal()
	if mb != nil {
		return mb, nil
	}

	return r.reader.ReadMultiBuffer()
}

func (r *cachedReader) ReadMultiBufferTimeout(timeout time.Duration) (buf.MultiBuffer, error) {
	mb := r.readInternal()
	if mb != nil {
		return mb, nil
	}

	return r.reader.ReadMultiBufferTimeout(timeout)
}

func (r *cachedReader) Interrupt() {
	r.Lock()
	if r.cache != nil {
		r.cache = buf.ReleaseMulti(r.cache)
	}
	r.Unlock()
	r.reader.Interrupt()
}

// DefaultDispatcher is a default implementation of Dispatcher.
type DefaultDispatcher struct {
	ohm    outbound.Manager
	router routing.Router
	policy policy.Manager
	stats  stats.Manager
}

func init() {
	common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
		d := new(DefaultDispatcher)
		if err := core.RequireFeatures(ctx, func(om outbound.Manager, router routing.Router, pm policy.Manager, sm stats.Manager) error {
			return d.Init(config.(*Config), om, router, pm, sm)
		}); err != nil {
			return nil, err
		}
		return d, nil
	}))
}

// Init initializes DefaultDispatcher.
func (d *DefaultDispatcher) Init(config *Config, om outbound.Manager, router routing.Router, pm policy.Manager, sm stats.Manager) error {
	d.ohm = om
	d.router = router
	d.policy = pm
	d.stats = sm
	return nil
}

// Type implements common.HasType.
func (*DefaultDispatcher) Type() interface{} {
	return routing.DispatcherType()
}

// Start implements common.Runnable.
func (*DefaultDispatcher) Start() error {
	return nil
}

// Close implements common.Closable.
func (*DefaultDispatcher) Close() error { return nil }

func (d *DefaultDispatcher) getLink(ctx context.Context) (*transport.Link, *transport.Link) {
	opt := pipe.OptionsFromContext(ctx)
	uplinkReader, uplinkWriter := pipe.New(opt...)
	downlinkReader, downlinkWriter := pipe.New(opt...)

	inboundLink := &transport.Link{
		Reader: downlinkReader,
		Writer: uplinkWriter,
	}

	outboundLink := &transport.Link{
		Reader: uplinkReader,
		Writer: downlinkWriter,
	}

	sessionInbound := session.InboundFromContext(ctx)
	var user *protocol.MemoryUser
	if sessionInbound != nil {
		user = sessionInbound.User
	}

	if user != nil && len(user.Email) > 0 {
		p := d.policy.ForLevel(user.Level)
		if p.Stats.UserUplink {
			name := "user>>>" + user.Email + ">>>traffic>>>uplink"
			if c, _ := stats.GetOrRegisterCounter(d.stats, name); c != nil {
				inboundLink.Writer = &SizeStatWriter{
					Counter: c,
					Writer:  inboundLink.Writer,
				}
			}
		}
		if p.Stats.UserDownlink {
			name := "user>>>" + user.Email + ">>>traffic>>>downlink"
			if c, _ := stats.GetOrRegisterCounter(d.stats, name); c != nil {
				outboundLink.Writer = &SizeStatWriter{
					Counter: c,
					Writer:  outboundLink.Writer,
				}
			}
		}
	}

	return inboundLink, outboundLink
}

func shouldOverride(result SniffResult, domainOverride []string) bool {
	for _, p := range domainOverride {
		if strings.HasPrefix(result.Protocol(), p) {
			return true
		}
	}
	return false
}

// Dispatch implements routing.Dispatcher.
func (d *DefaultDispatcher) Dispatch(ctx context.Context, destination net.Destination) (*transport.Link, error) {
	if !destination.IsValid() {
		panic("Dispatcher: Invalid destination.")
	}
	ob := &session.Outbound{
		Target: destination,
	}
	ctx = session.ContextWithOutbound(ctx, ob)

	inbound, outbound := d.getLink(ctx)
	content := session.ContentFromContext(ctx)
	if content == nil {
		content = new(session.Content)
		ctx = session.ContextWithContent(ctx, content)
	}
	sniffingRequest := content.SniffingRequest
	if destination.Network != net.Network_TCP || !sniffingRequest.Enabled {
		go d.routedDispatch(ctx, outbound, destination)
	} else {
		go func() {
			cReader := &cachedReader{
				reader: outbound.Reader.(*pipe.Reader),
			}
			outbound.Reader = cReader
			result, err := sniffer(ctx, cReader)
			if err == nil {
				content.Protocol = result.Protocol()
			}
			if err == nil && shouldOverride(result, sniffingRequest.OverrideDestinationForProtocol) {
				domain := result.Domain()
				newError("sniffed domain: ", domain).WriteToLog(session.ExportIDToError(ctx))
				destination.Address = net.ParseAddress(domain)
				ob.Target = destination
			}
			d.routedDispatch(ctx, outbound, destination)
		}()
	}
	return inbound, nil
}

func sniffer(ctx context.Context, cReader *cachedReader) (SniffResult, error) {
	payload := buf.New()
	defer payload.Release()

	sniffer := NewSniffer()
	totalAttempt := 0
	for {
		select {
		case <-ctx.Done():
			return nil, ctx.Err()
		default:
			totalAttempt++
			if totalAttempt > 2 {
				return nil, errSniffingTimeout
			}

			cReader.Cache(payload)
			if !payload.IsEmpty() {
				result, err := sniffer.Sniff(payload.Bytes())
				if err != common.ErrNoClue {
					return result, err
				}
			}
			if payload.IsFull() {
				return nil, errUnknownContent
			}
		}
	}
}

func (d *DefaultDispatcher) routedDispatch(ctx context.Context, link *transport.Link, destination net.Destination) {
	var handler outbound.Handler

	skipRoutePick := false
	if content := session.ContentFromContext(ctx); content != nil {
		skipRoutePick = content.SkipRoutePick
	}

	if d.router != nil && !skipRoutePick {
		if route, err := d.router.PickRoute(routing_session.AsRoutingContext(ctx)); err == nil {
			tag := route.GetOutboundTag()
			if h := d.ohm.GetHandler(tag); h != nil {
				newError("taking detour [", tag, "] for [", destination, "]").WriteToLog(session.ExportIDToError(ctx))
				handler = h
			} else {
				newError("non existing tag: ", tag).AtWarning().WriteToLog(session.ExportIDToError(ctx))
			}
		} else {
			newError("default route for ", destination).WriteToLog(session.ExportIDToError(ctx))
		}
	}

	if handler == nil {
		handler = d.ohm.GetDefaultHandler()
	}

	if handler == nil {
		newError("default outbound handler not exist").WriteToLog(session.ExportIDToError(ctx))
		common.Close(link.Writer)
		common.Interrupt(link.Reader)
		return
	}

	if accessMessage := log.AccessMessageFromContext(ctx); accessMessage != nil {
		if tag := handler.Tag(); tag != "" {
			accessMessage.Detour = tag
		}
		log.Record(accessMessage)
	}

	handler.Dispatch(ctx, link)
}


================================================
FILE: app/dispatcher/dispatcher.go
================================================
// +build !confonly

package dispatcher

//go:generate go run v2ray.com/core/common/errors/errorgen


================================================
FILE: app/dispatcher/errors.generated.go
================================================
package dispatcher

import "v2ray.com/core/common/errors"

type errPathObjHolder struct{}

func newError(values ...interface{}) *errors.Error {
	return errors.New(values...).WithPathObj(errPathObjHolder{})
}


================================================
FILE: app/dispatcher/sniffer.go
================================================
// +build !confonly

package dispatcher

import (
	"v2ray.com/core/common"
	"v2ray.com/core/common/protocol/bittorrent"
	"v2ray.com/core/common/protocol/http"
	"v2ray.com/core/common/protocol/tls"
)

type SniffResult interface {
	Protocol() string
	Domain() string
}

type protocolSniffer func([]byte) (SniffResult, error)

type Sniffer struct {
	sniffer []protocolSniffer
}

func NewSniffer() *Sniffer {
	return &Sniffer{
		sniffer: []protocolSniffer{
			func(b []byte) (SniffResult, error) { return http.SniffHTTP(b) },
			func(b []byte) (SniffResult, error) { return tls.SniffTLS(b) },
			func(b []byte) (SniffResult, error) { return bittorrent.SniffBittorrent(b) },
		},
	}
}

var errUnknownContent = newError("unknown content")

func (s *Sniffer) Sniff(payload []byte) (SniffResult, error) {
	var pendingSniffer []protocolSniffer
	for _, s := range s.sniffer {
		result, err := s(payload)
		if err == common.ErrNoClue {
			pendingSniffer = append(pendingSniffer, s)
			continue
		}

		if err == nil && result != nil {
			return result, nil
		}
	}

	if len(pendingSniffer) > 0 {
		s.sniffer = pendingSniffer
		return nil, common.ErrNoClue
	}

	return nil, errUnknownContent
}


================================================
FILE: app/dispatcher/stats.go
================================================
// +build !confonly

package dispatcher

import (
	"v2ray.com/core/common"
	"v2ray.com/core/common/buf"
	"v2ray.com/core/features/stats"
)

type SizeStatWriter struct {
	Counter stats.Counter
	Writer  buf.Writer
}

func (w *SizeStatWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
	w.Counter.Add(int64(mb.Len()))
	return w.Writer.WriteMultiBuffer(mb)
}

func (w *SizeStatWriter) Close() error {
	return common.Close(w.Writer)
}

func (w *SizeStatWriter) Interrupt() {
	common.Interrupt(w.Writer)
}


================================================
FILE: app/dispatcher/stats_test.go
================================================
package dispatcher_test

import (
	"testing"

	. "v2ray.com/core/app/dispatcher"
	"v2ray.com/core/common"
	"v2ray.com/core/common/buf"
)

type TestCounter int64

func (c *TestCounter) Value() int64 {
	return int64(*c)
}

func (c *TestCounter) Add(v int64) int64 {
	x := int64(*c) + v
	*c = TestCounter(x)
	return x
}

func (c *TestCounter) Set(v int64) int64 {
	*c = TestCounter(v)
	return v
}

func TestStatsWriter(t *testing.T) {
	var c TestCounter
	writer := &SizeStatWriter{
		Counter: &c,
		Writer:  buf.Discard,
	}

	mb := buf.MergeBytes(nil, []byte("abcd"))
	common.Must(writer.WriteMultiBuffer(mb))

	mb = buf.MergeBytes(nil, []byte("efg"))
	common.Must(writer.WriteMultiBuffer(mb))

	if c.Value() != 7 {
		t.Fatal("unexpected counter value. want 7, but got ", c.Value())
	}
}


================================================
FILE: app/dns/config.pb.go
================================================
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// 	protoc-gen-go v1.25.0
// 	protoc        v3.13.0
// source: app/dns/config.proto

package dns

import (
	proto "github.com/golang/protobuf/proto"
	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
	reflect "reflect"
	sync "sync"
	router "v2ray.com/core/app/router"
	net "v2ray.com/core/common/net"
)

const (
	// Verify that this generated code is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
	// Verify that runtime/protoimpl is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)

// This is a compile-time assertion that a sufficiently up-to-date version
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4

type DomainMatchingType int32

const (
	DomainMatchingType_Full      DomainMatchingType = 0
	DomainMatchingType_Subdomain DomainMatchingType = 1
	DomainMatchingType_Keyword   DomainMatchingType = 2
	DomainMatchingType_Regex     DomainMatchingType = 3
)

// Enum value maps for DomainMatchingType.
var (
	DomainMatchingType_name = map[int32]string{
		0: "Full",
		1: "Subdomain",
		2: "Keyword",
		3: "Regex",
	}
	DomainMatchingType_value = map[string]int32{
		"Full":      0,
		"Subdomain": 1,
		"Keyword":   2,
		"Regex":     3,
	}
)

func (x DomainMatchingType) Enum() *DomainMatchingType {
	p := new(DomainMatchingType)
	*p = x
	return p
}

func (x DomainMatchingType) String() string {
	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}

func (DomainMatchingType) Descriptor() protoreflect.EnumDescriptor {
	return file_app_dns_config_proto_enumTypes[0].Descriptor()
}

func (DomainMatchingType) Type() protoreflect.EnumType {
	return &file_app_dns_config_proto_enumTypes[0]
}

func (x DomainMatchingType) Number() protoreflect.EnumNumber {
	return protoreflect.EnumNumber(x)
}

// Deprecated: Use DomainMatchingType.Descriptor instead.
func (DomainMatchingType) EnumDescriptor() ([]byte, []int) {
	return file_app_dns_config_proto_rawDescGZIP(), []int{0}
}

type NameServer struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Address           *net.Endpoint                `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
	PrioritizedDomain []*NameServer_PriorityDomain `protobuf:"bytes,2,rep,name=prioritized_domain,json=prioritizedDomain,proto3" json:"prioritized_domain,omitempty"`
	Geoip             []*router.GeoIP              `protobuf:"bytes,3,rep,name=geoip,proto3" json:"geoip,omitempty"`
	OriginalRules     []*NameServer_OriginalRule   `protobuf:"bytes,4,rep,name=original_rules,json=originalRules,proto3" json:"original_rules,omitempty"`
}

func (x *NameServer) Reset() {
	*x = NameServer{}
	if protoimpl.UnsafeEnabled {
		mi := &file_app_dns_config_proto_msgTypes[0]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *NameServer) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*NameServer) ProtoMessage() {}

func (x *NameServer) ProtoReflect() protoreflect.Message {
	mi := &file_app_dns_config_proto_msgTypes[0]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use NameServer.ProtoReflect.Descriptor instead.
func (*NameServer) Descriptor() ([]byte, []int) {
	return file_app_dns_config_proto_rawDescGZIP(), []int{0}
}

func (x *NameServer) GetAddress() *net.Endpoint {
	if x != nil {
		return x.Address
	}
	return nil
}

func (x *NameServer) GetPrioritizedDomain() []*NameServer_PriorityDomain {
	if x != nil {
		return x.PrioritizedDomain
	}
	return nil
}

func (x *NameServer) GetGeoip() []*router.GeoIP {
	if x != nil {
		return x.Geoip
	}
	return nil
}

func (x *NameServer) GetOriginalRules() []*NameServer_OriginalRule {
	if x != nil {
		return x.OriginalRules
	}
	return nil
}

type Config struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	// Nameservers used by this DNS. Only traditional UDP servers are support at
	// the moment. A special value 'localhost' as a domain address can be set to
	// use DNS on local system.
	//
	// Deprecated: Do not use.
	NameServers []*net.Endpoint `protobuf:"bytes,1,rep,name=NameServers,proto3" json:"NameServers,omitempty"`
	// NameServer list used by this DNS client.
	NameServer []*NameServer `protobuf:"bytes,5,rep,name=name_server,json=nameServer,proto3" json:"name_server,omitempty"`
	// Static hosts. Domain to IP.
	// Deprecated. Use static_hosts.
	//
	// Deprecated: Do not use.
	Hosts map[string]*net.IPOrDomain `protobuf:"bytes,2,rep,name=Hosts,proto3" json:"Hosts,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
	// Client IP for EDNS client subnet. Must be 4 bytes (IPv4) or 16 bytes
	// (IPv6).
	ClientIp    []byte                `protobuf:"bytes,3,opt,name=client_ip,json=clientIp,proto3" json:"client_ip,omitempty"`
	StaticHosts []*Config_HostMapping `protobuf:"bytes,4,rep,name=static_hosts,json=staticHosts,proto3" json:"static_hosts,omitempty"`
	// Tag is the inbound tag of DNS client.
	Tag string `protobuf:"bytes,6,opt,name=tag,proto3" json:"tag,omitempty"`
}

func (x *Config) Reset() {
	*x = Config{}
	if protoimpl.UnsafeEnabled {
		mi := &file_app_dns_config_proto_msgTypes[1]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *Config) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*Config) ProtoMessage() {}

func (x *Config) ProtoReflect() protoreflect.Message {
	mi := &file_app_dns_config_proto_msgTypes[1]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use Config.ProtoReflect.Descriptor instead.
func (*Config) Descriptor() ([]byte, []int) {
	return file_app_dns_config_proto_rawDescGZIP(), []int{1}
}

// Deprecated: Do not use.
func (x *Config) GetNameServers() []*net.Endpoint {
	if x != nil {
		return x.NameServers
	}
	return nil
}

func (x *Config) GetNameServer() []*NameServer {
	if x != nil {
		return x.NameServer
	}
	return nil
}

// Deprecated: Do not use.
func (x *Config) GetHosts() map[string]*net.IPOrDomain {
	if x != nil {
		return x.Hosts
	}
	return nil
}

func (x *Config) GetClientIp() []byte {
	if x != nil {
		return x.ClientIp
	}
	return nil
}

func (x *Config) GetStaticHosts() []*Config_HostMapping {
	if x != nil {
		return x.StaticHosts
	}
	return nil
}

func (x *Config) GetTag() string {
	if x != nil {
		return x.Tag
	}
	return ""
}

type NameServer_PriorityDomain struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Type   DomainMatchingType `protobuf:"varint,1,opt,name=type,proto3,enum=v2ray.core.app.dns.DomainMatchingType" json:"type,omitempty"`
	Domain string             `protobuf:"bytes,2,opt,name=domain,proto3" json:"domain,omitempty"`
}

func (x *NameServer_PriorityDomain) Reset() {
	*x = NameServer_PriorityDomain{}
	if protoimpl.UnsafeEnabled {
		mi := &file_app_dns_config_proto_msgTypes[2]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *NameServer_PriorityDomain) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*NameServer_PriorityDomain) ProtoMessage() {}

func (x *NameServer_PriorityDomain) ProtoReflect() protoreflect.Message {
	mi := &file_app_dns_config_proto_msgTypes[2]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use NameServer_PriorityDomain.ProtoReflect.Descriptor instead.
func (*NameServer_PriorityDomain) Descriptor() ([]byte, []int) {
	return file_app_dns_config_proto_rawDescGZIP(), []int{0, 0}
}

func (x *NameServer_PriorityDomain) GetType() DomainMatchingType {
	if x != nil {
		return x.Type
	}
	return DomainMatchingType_Full
}

func (x *NameServer_PriorityDomain) GetDomain() string {
	if x != nil {
		return x.Domain
	}
	return ""
}

type NameServer_OriginalRule struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Rule string `protobuf:"bytes,1,opt,name=rule,proto3" json:"rule,omitempty"`
	Size uint32 `protobuf:"varint,2,opt,name=size,proto3" json:"size,omitempty"`
}

func (x *NameServer_OriginalRule) Reset() {
	*x = NameServer_OriginalRule{}
	if protoimpl.UnsafeEnabled {
		mi := &file_app_dns_config_proto_msgTypes[3]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *NameServer_OriginalRule) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*NameServer_OriginalRule) ProtoMessage() {}

func (x *NameServer_OriginalRule) ProtoReflect() protoreflect.Message {
	mi := &file_app_dns_config_proto_msgTypes[3]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use NameServer_OriginalRule.ProtoReflect.Descriptor instead.
func (*NameServer_OriginalRule) Descriptor() ([]byte, []int) {
	return file_app_dns_config_proto_rawDescGZIP(), []int{0, 1}
}

func (x *NameServer_OriginalRule) GetRule() string {
	if x != nil {
		return x.Rule
	}
	return ""
}

func (x *NameServer_OriginalRule) GetSize() uint32 {
	if x != nil {
		return x.Size
	}
	return 0
}

type Config_HostMapping struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Type   DomainMatchingType `protobuf:"varint,1,opt,name=type,proto3,enum=v2ray.core.app.dns.DomainMatchingType" json:"type,omitempty"`
	Domain string             `protobuf:"bytes,2,opt,name=domain,proto3" json:"domain,omitempty"`
	Ip     [][]byte           `protobuf:"bytes,3,rep,name=ip,proto3" json:"ip,omitempty"`
	// ProxiedDomain indicates the mapped domain has the same IP address on this
	// domain. V2Ray will use this domain for IP queries. This field is only
	// effective if ip is empty.
	ProxiedDomain string `protobuf:"bytes,4,opt,name=proxied_domain,json=proxiedDomain,proto3" json:"proxied_domain,omitempty"`
}

func (x *Config_HostMapping) Reset() {
	*x = Config_HostMapping{}
	if protoimpl.UnsafeEnabled {
		mi := &file_app_dns_config_proto_msgTypes[5]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *Config_HostMapping) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*Config_HostMapping) ProtoMessage() {}

func (x *Config_HostMapping) ProtoReflect() protoreflect.Message {
	mi := &file_app_dns_config_proto_msgTypes[5]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use Config_HostMapping.ProtoReflect.Descriptor instead.
func (*Config_HostMapping) Descriptor() ([]byte, []int) {
	return file_app_dns_config_proto_rawDescGZIP(), []int{1, 1}
}

func (x *Config_HostMapping) GetType() DomainMatchingType {
	if x != nil {
		return x.Type
	}
	return DomainMatchingType_Full
}

func (x *Config_HostMapping) GetDomain() string {
	if x != nil {
		return x.Domain
	}
	return ""
}

func (x *Config_HostMapping) GetIp() [][]byte {
	if x != nil {
		return x.Ip
	}
	return nil
}

func (x *Config_HostMapping) GetProxiedDomain() string {
	if x != nil {
		return x.ProxiedDomain
	}
	return ""
}

var File_app_dns_config_proto protoreflect.FileDescriptor

var file_app_dns_config_proto_rawDesc = []byte{
	0x0a, 0x14, 0x61, 0x70, 0x70, 0x2f, 0x64, 0x6e, 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f,
	0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x1a, 0x18, 0x63, 0x6f, 0x6d, 0x6d,
	0x6f, 0x6e, 0x2f, 0x6e, 0x65, 0x74, 0x2f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x70,
	0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6e, 0x65, 0x74,
	0x2f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f,
	0x74, 0x6f, 0x1a, 0x17, 0x61, 0x70, 0x70, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2f, 0x63,
	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xcb, 0x03, 0x0a, 0x0a,
	0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x39, 0x0a, 0x07, 0x61, 0x64,
	0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x76, 0x32,
	0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e,
	0x6e, 0x65, 0x74, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x07, 0x61, 0x64,
	0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x5c, 0x0a, 0x12, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74,
	0x69, 0x7a, 0x65, 0x64, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28,
	0x0b, 0x32, 0x2d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61,
	0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65,
	0x72, 0x2e, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e,
	0x52, 0x11, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x64, 0x44, 0x6f, 0x6d,
	0x61, 0x69, 0x6e, 0x12, 0x32, 0x0a, 0x05, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x18, 0x03, 0x20, 0x03,
	0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e,
	0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x6f, 0x49, 0x50,
	0x52, 0x05, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x12, 0x52, 0x0a, 0x0e, 0x6f, 0x72, 0x69, 0x67, 0x69,
	0x6e, 0x61, 0x6c, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32,
	0x2b, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70,
	0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e,
	0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0d, 0x6f, 0x72,
	0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x1a, 0x64, 0x0a, 0x0e, 0x50,
	0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x3a, 0x0a,
	0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x76, 0x32,
	0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73,
	0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x54,
	0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d,
	0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69,
	0x6e, 0x1a, 0x36, 0x0a, 0x0c, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x75, 0x6c,
	0x65, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
	0x04, 0x72, 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20,
	0x01, 0x28, 0x0d, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x22, 0xc3, 0x04, 0x0a, 0x06, 0x43, 0x6f,
	0x6e, 0x66, 0x69, 0x67, 0x12, 0x45, 0x0a, 0x0b, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76,
	0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x76, 0x32, 0x72, 0x61,
	0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65,
	0x74, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0b,
	0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, 0x3f, 0x0a, 0x0b, 0x6e,
	0x61, 0x6d, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b,
	0x32, 0x1e, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70,
	0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72,
	0x52, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x3f, 0x0a, 0x05,
	0x48, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x76, 0x32,
	0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73,
	0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x45, 0x6e, 0x74,
	0x72, 0x79, 0x42, 0x02, 0x18, 0x01, 0x52, 0x05, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x1b, 0x0a,
	0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c,
	0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x70, 0x12, 0x49, 0x0a, 0x0c, 0x73, 0x74,
	0x61, 0x74, 0x69, 0x63, 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b,
	0x32, 0x26, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70,
	0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x48, 0x6f, 0x73,
	0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x0b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63,
	0x48, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x06, 0x20, 0x01,
	0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x1a, 0x5b, 0x0a, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x73,
	0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
	0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x37, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
	0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63,
	0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x49,
	0x50, 0x4f, 0x72, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
	0x3a, 0x02, 0x38, 0x01, 0x1a, 0x98, 0x01, 0x0a, 0x0b, 0x48, 0x6f, 0x73, 0x74, 0x4d, 0x61, 0x70,
	0x70, 0x69, 0x6e, 0x67, 0x12, 0x3a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01,
	0x28, 0x0e, 0x32, 0x26, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e,
	0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61,
	0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65,
	0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
	0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x03,
	0x20, 0x03, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x70, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x78,
	0x69, 0x65, 0x64, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
	0x52, 0x0d, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x65, 0x64, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2a,
	0x45, 0x0a, 0x12, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e,
	0x67, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x46, 0x75, 0x6c, 0x6c, 0x10, 0x00, 0x12,
	0x0d, 0x0a, 0x09, 0x53, 0x75, 0x62, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x10, 0x01, 0x12, 0x0b,
	0x0a, 0x07, 0x4b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x52,
	0x65, 0x67, 0x65, 0x78, 0x10, 0x03, 0x42, 0x47, 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32,
	0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73,
	0x50, 0x01, 0x5a, 0x16, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f,
	0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x64, 0x6e, 0x73, 0xaa, 0x02, 0x12, 0x56, 0x32, 0x52,
	0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x44, 0x6e, 0x73, 0x62,
	0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}

var (
	file_app_dns_config_proto_rawDescOnce sync.Once
	file_app_dns_config_proto_rawDescData = file_app_dns_config_proto_rawDesc
)

func file_app_dns_config_proto_rawDescGZIP() []byte {
	file_app_dns_config_proto_rawDescOnce.Do(func() {
		file_app_dns_config_proto_rawDescData = protoimpl.X.CompressGZIP(file_app_dns_config_proto_rawDescData)
	})
	return file_app_dns_config_proto_rawDescData
}

var file_app_dns_config_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_app_dns_config_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
var file_app_dns_config_proto_goTypes = []interface{}{
	(DomainMatchingType)(0),           // 0: v2ray.core.app.dns.DomainMatchingType
	(*NameServer)(nil),                // 1: v2ray.core.app.dns.NameServer
	(*Config)(nil),                    // 2: v2ray.core.app.dns.Config
	(*NameServer_PriorityDomain)(nil), // 3: v2ray.core.app.dns.NameServer.PriorityDomain
	(*NameServer_OriginalRule)(nil),   // 4: v2ray.core.app.dns.NameServer.OriginalRule
	nil,                               // 5: v2ray.core.app.dns.Config.HostsEntry
	(*Config_HostMapping)(nil),        // 6: v2ray.core.app.dns.Config.HostMapping
	(*net.Endpoint)(nil),              // 7: v2ray.core.common.net.Endpoint
	(*router.GeoIP)(nil),              // 8: v2ray.core.app.router.GeoIP
	(*net.IPOrDomain)(nil),            // 9: v2ray.core.common.net.IPOrDomain
}
var file_app_dns_config_proto_depIdxs = []int32{
	7,  // 0: v2ray.core.app.dns.NameServer.address:type_name -> v2ray.core.common.net.Endpoint
	3,  // 1: v2ray.core.app.dns.NameServer.prioritized_domain:type_name -> v2ray.core.app.dns.NameServer.PriorityDomain
	8,  // 2: v2ray.core.app.dns.NameServer.geoip:type_name -> v2ray.core.app.router.GeoIP
	4,  // 3: v2ray.core.app.dns.NameServer.original_rules:type_name -> v2ray.core.app.dns.NameServer.OriginalRule
	7,  // 4: v2ray.core.app.dns.Config.NameServers:type_name -> v2ray.core.common.net.Endpoint
	1,  // 5: v2ray.core.app.dns.Config.name_server:type_name -> v2ray.core.app.dns.NameServer
	5,  // 6: v2ray.core.app.dns.Config.Hosts:type_name -> v2ray.core.app.dns.Config.HostsEntry
	6,  // 7: v2ray.core.app.dns.Config.static_hosts:type_name -> v2ray.core.app.dns.Config.HostMapping
	0,  // 8: v2ray.core.app.dns.NameServer.PriorityDomain.type:type_name -> v2ray.core.app.dns.DomainMatchingType
	9,  // 9: v2ray.core.app.dns.Config.HostsEntry.value:type_name -> v2ray.core.common.net.IPOrDomain
	0,  // 10: v2ray.core.app.dns.Config.HostMapping.type:type_name -> v2ray.core.app.dns.DomainMatchingType
	11, // [11:11] is the sub-list for method output_type
	11, // [11:11] is the sub-list for method input_type
	11, // [11:11] is the sub-list for extension type_name
	11, // [11:11] is the sub-list for extension extendee
	0,  // [0:11] is the sub-list for field type_name
}

func init() { file_app_dns_config_proto_init() }
func file_app_dns_config_proto_init() {
	if File_app_dns_config_proto != nil {
		return
	}
	if !protoimpl.UnsafeEnabled {
		file_app_dns_config_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*NameServer); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_app_dns_config_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*Config); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_app_dns_config_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*NameServer_PriorityDomain); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_app_dns_config_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*NameServer_OriginalRule); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_app_dns_config_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*Config_HostMapping); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
	}
	type x struct{}
	out := protoimpl.TypeBuilder{
		File: protoimpl.DescBuilder{
			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
			RawDescriptor: file_app_dns_config_proto_rawDesc,
			NumEnums:      1,
			NumMessages:   6,
			NumExtensions: 0,
			NumServices:   0,
		},
		GoTypes:           file_app_dns_config_proto_goTypes,
		DependencyIndexes: file_app_dns_config_proto_depIdxs,
		EnumInfos:         file_app_dns_config_proto_enumTypes,
		MessageInfos:      file_app_dns_config_proto_msgTypes,
	}.Build()
	File_app_dns_config_proto = out.File
	file_app_dns_config_proto_rawDesc = nil
	file_app_dns_config_proto_goTypes = nil
	file_app_dns_config_proto_depIdxs = nil
}


================================================
FILE: app/dns/config.proto
================================================
syntax = "proto3";

package v2ray.core.app.dns;
option csharp_namespace = "V2Ray.Core.App.Dns";
option go_package = "v2ray.com/core/app/dns";
option java_package = "com.v2ray.core.app.dns";
option java_multiple_files = true;

import "common/net/address.proto";
import "common/net/destination.proto";
import "app/router/config.proto";

message NameServer {
  v2ray.core.common.net.Endpoint address = 1;

  message PriorityDomain {
    DomainMatchingType type = 1;
    string domain = 2;
  }

  message OriginalRule {
    string rule = 1;
    uint32 size = 2;
  }

  repeated PriorityDomain prioritized_domain = 2;
  repeated v2ray.core.app.router.GeoIP geoip = 3;
  repeated OriginalRule original_rules = 4;
}

enum DomainMatchingType {
  Full = 0;
  Subdomain = 1;
  Keyword = 2;
  Regex = 3;
}

message Config {
  // Nameservers used by this DNS. Only traditional UDP servers are support at
  // the moment. A special value 'localhost' as a domain address can be set to
  // use DNS on local system.
  repeated v2ray.core.common.net.Endpoint NameServers = 1 [deprecated = true];

  // NameServer list used by this DNS client.
  repeated NameServer name_server = 5;

  // Static hosts. Domain to IP.
  // Deprecated. Use static_hosts.
  map<string, v2ray.core.common.net.IPOrDomain> Hosts = 2 [deprecated = true];

  // Client IP for EDNS client subnet. Must be 4 bytes (IPv4) or 16 bytes
  // (IPv6).
  bytes client_ip = 3;

  message HostMapping {
    DomainMatchingType type = 1;
    string domain = 2;

    repeated bytes ip = 3;

    // ProxiedDomain indicates the mapped domain has the same IP address on this
    // domain. V2Ray will use this domain for IP queries. This field is only
    // effective if ip is empty.
    string proxied_domain = 4;
  }

  repeated HostMapping static_hosts = 4;

  // Tag is the inbound tag of DNS client.
  string tag = 6;
}


================================================
FILE: app/dns/dns.go
================================================
// Package dns is an implementation of core.DNS feature.
package dns

//go:generate go run v2ray.com/core/common/errors/errorgen


================================================
FILE: app/dns/dnscommon.go
================================================
// +build !confonly

package dns

import (
	"encoding/binary"
	"time"

	"golang.org/x/net/dns/dnsmessage"
	"v2ray.com/core/common"
	"v2ray.com/core/common/errors"
	"v2ray.com/core/common/net"
	dns_feature "v2ray.com/core/features/dns"
)

// Fqdn normalize domain make sure it ends with '.'
func Fqdn(domain string) string {
	if len(domain) > 0 && domain[len(domain)-1] == '.' {
		return domain
	}
	return domain + "."
}

type record struct {
	A    *IPRecord
	AAAA *IPRecord
}

// IPRecord is a cacheable item for a resolved domain
type IPRecord struct {
	ReqID  uint16
	IP     []net.Address
	Expire time.Time
	RCode  dnsmessage.RCode
}

func (r *IPRecord) getIPs() ([]net.Address, error) {
	if r == nil || r.Expire.Before(time.Now()) {
		return nil, errRecordNotFound
	}
	if r.RCode != dnsmessage.RCodeSuccess {
		return nil, dns_feature.RCodeError(r.RCode)
	}
	return r.IP, nil
}

func isNewer(baseRec *IPRecord, newRec *IPRecord) bool {
	if newRec == nil {
		return false
	}
	if baseRec == nil {
		return true
	}
	return baseRec.Expire.Before(newRec.Expire)
}

var (
	errRecordNotFound = errors.New("record not found")
)

type dnsRequest struct {
	reqType dnsmessage.Type
	domain  string
	start   time.Time
	expire  time.Time
	msg     *dnsmessage.Message
}

func genEDNS0Options(clientIP net.IP) *dnsmessage.Resource {
	if len(clientIP) == 0 {
		return nil
	}

	var netmask int
	var family uint16

	if len(clientIP) == 4 {
		family = 1
		netmask = 24 // 24 for IPV4, 96 for IPv6
	} else {
		family = 2
		netmask = 96
	}

	b := make([]byte, 4)
	binary.BigEndian.PutUint16(b[0:], family)
	b[2] = byte(netmask)
	b[3] = 0
	switch family {
	case 1:
		ip := clientIP.To4().Mask(net.CIDRMask(netmask, net.IPv4len*8))
		needLength := (netmask + 8 - 1) / 8 // division rounding up
		b = append(b, ip[:needLength]...)
	case 2:
		ip := clientIP.Mask(net.CIDRMask(netmask, net.IPv6len*8))
		needLength := (netmask + 8 - 1) / 8 // division rounding up
		b = append(b, ip[:needLength]...)
	}

	const EDNS0SUBNET = 0x08

	opt := new(dnsmessage.Resource)
	common.Must(opt.Header.SetEDNS0(1350, 0xfe00, true))

	opt.Body = &dnsmessage.OPTResource{
		Options: []dnsmessage.Option{
			{
				Code: EDNS0SUBNET,
				Data: b,
			},
		},
	}

	return opt
}

func buildReqMsgs(domain string, option IPOption, reqIDGen func() uint16, reqOpts *dnsmessage.Resource) []*dnsRequest {
	qA := dnsmessage.Question{
		Name:  dnsmessage.MustNewName(domain),
		Type:  dnsmessage.TypeA,
		Class: dnsmessage.ClassINET,
	}

	qAAAA := dnsmessage.Question{
		Name:  dnsmessage.MustNewName(domain),
		Type:  dnsmessage.TypeAAAA,
		Class: dnsmessage.ClassINET,
	}

	var reqs []*dnsRequest
	now := time.Now()

	if option.IPv4Enable {
		msg := new(dnsmessage.Message)
		msg.Header.ID = reqIDGen()
		msg.Header.RecursionDesired = true
		msg.Questions = []dnsmessage.Question{qA}
		if reqOpts != nil {
			msg.Additionals = append(msg.Additionals, *reqOpts)
		}
		reqs = append(reqs, &dnsRequest{
			reqType: dnsmessage.TypeA,
			domain:  domain,
			start:   now,
			msg:     msg,
		})
	}

	if option.IPv6Enable {
		msg := new(dnsmessage.Message)
		msg.Header.ID = reqIDGen()
		msg.Header.RecursionDesired = true
		msg.Questions = []dnsmessage.Question{qAAAA}
		if reqOpts != nil {
			msg.Additionals = append(msg.Additionals, *reqOpts)
		}
		reqs = append(reqs, &dnsRequest{
			reqType: dnsmessage.TypeAAAA,
			domain:  domain,
			start:   now,
			msg:     msg,
		})
	}

	return reqs
}

// parseResponse parse DNS answers from the returned payload
func parseResponse(payload []byte) (*IPRecord, error) {
	var parser dnsmessage.Parser
	h, err := parser.Start(payload)
	if err != nil {
		return nil, newError("failed to parse DNS response").Base(err).AtWarning()
	}
	if err := parser.SkipAllQuestions(); err != nil {
		return nil, newError("failed to skip questions in DNS response").Base(err).AtWarning()
	}

	now := time.Now()
	ipRecord := &IPRecord{
		ReqID:  h.ID,
		RCode:  h.RCode,
		Expire: now.Add(time.Second * 600),
	}

L:
	for {
		ah, err := parser.AnswerHeader()
		if err != nil {
			if err != dnsmessage.ErrSectionDone {
				newError("failed to parse answer section for domain: ", ah.Name.String()).Base(err).WriteToLog()
			}
			break
		}

		ttl := ah.TTL
		if ttl == 0 {
			ttl = 600
		}
		expire := now.Add(time.Duration(ttl) * time.Second)
		if ipRecord.Expire.After(expire) {
			ipRecord.Expire = expire
		}

		switch ah.Type {
		case dnsmessage.TypeA:
			ans, err := parser.AResource()
			if err != nil {
				newError("failed to parse A record for domain: ", ah.Name).Base(err).WriteToLog()
				break L
			}
			ipRecord.IP = append(ipRecord.IP, net.IPAddress(ans.A[:]))
		case dnsmessage.TypeAAAA:
			ans, err := parser.AAAAResource()
			if err != nil {
				newError("failed to parse A record for domain: ", ah.Name).Base(err).WriteToLog()
				break L
			}
			ipRecord.IP = append(ipRecord.IP, net.IPAddress(ans.AAAA[:]))
		default:
			if err := parser.SkipAnswer(); err != nil {
				newError("failed to skip answer").Base(err).WriteToLog()
				break L
			}
			continue
		}
	}

	return ipRecord, nil
}


================================================
FILE: app/dns/dnscommon_test.go
================================================
// +build !confonly

package dns

import (
	"math/rand"
	"testing"
	"time"

	"github.com/google/go-cmp/cmp"
	"github.com/miekg/dns"
	"golang.org/x/net/dns/dnsmessage"
	"v2ray.com/core/common"
	"v2ray.com/core/common/net"
)

func Test_parseResponse(t *testing.T) {
	var p [][]byte

	ans := new(dns.Msg)
	ans.Id = 0
	p = append(p, common.Must2(ans.Pack()).([]byte))

	p = append(p, []byte{})

	ans = new(dns.Msg)
	ans.Id = 1
	ans.Answer = append(ans.Answer,
		common.Must2(dns.NewRR("google.com. IN CNAME m.test.google.com")).(dns.RR),
		common.Must2(dns.NewRR("google.com. IN CNAME fake.google.com")).(dns.RR),
		common.Must2(dns.NewRR("google.com. IN A 8.8.8.8")).(dns.RR),
		common.Must2(dns.NewRR("google.com. IN A 8.8.4.4")).(dns.RR),
	)
	p = append(p, common.Must2(ans.Pack()).([]byte))

	ans = new(dns.Msg)
	ans.Id = 2
	ans.Answer = append(ans.Answer,
		common.Must2(dns.NewRR("google.com. IN CNAME m.test.google.com")).(dns.RR),
		common.Must2(dns.NewRR("google.com. IN CNAME fake.google.com")).(dns.RR),
		common.Must2(dns.NewRR("google.com. IN CNAME m.test.google.com")).(dns.RR),
		common.Must2(dns.NewRR("google.com. IN CNAME test.google.com")).(dns.RR),
		common.Must2(dns.NewRR("google.com. IN AAAA 2001::123:8888")).(dns.RR),
		common.Must2(dns.NewRR("google.com. IN AAAA 2001::123:8844")).(dns.RR),
	)
	p = append(p, common.Must2(ans.Pack()).([]byte))

	tests := []struct {
		name    string
		want    *IPRecord
		wantErr bool
	}{
		{"empty",
			&IPRecord{0, []net.Address(nil), time.Time{}, dnsmessage.RCodeSuccess},
			false,
		},
		{"error",
			nil,
			true,
		},
		{"a record",
			&IPRecord{1, []net.Address{net.ParseAddress("8.8.8.8"), net.ParseAddress("8.8.4.4")},
				time.Time{}, dnsmessage.RCodeSuccess},
			false,
		},
		{"aaaa record",
			&IPRecord{2, []net.Address{net.ParseAddress("2001::123:8888"), net.ParseAddress("2001::123:8844")}, time.Time{}, dnsmessage.RCodeSuccess},
			false,
		},
	}
	for i, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			got, err := parseResponse(p[i])
			if (err != nil) != tt.wantErr {
				t.Errorf("handleResponse() error = %v, wantErr %v", err, tt.wantErr)
				return
			}

			if got != nil {
				// reset the time
				got.Expire = time.Time{}
			}
			if cmp.Diff(got, tt.want) != "" {
				t.Errorf(cmp.Diff(got, tt.want))
				// t.Errorf("handleResponse() = %#v, want %#v", got, tt.want)
			}
		})
	}
}

func Test_buildReqMsgs(t *testing.T) {

	stubID := func() uint16 {
		return uint16(rand.Uint32())
	}
	type args struct {
		domain  string
		option  IPOption
		reqOpts *dnsmessage.Resource
	}
	tests := []struct {
		name string
		args args
		want int
	}{
		{"dual stack", args{"test.com", IPOption{true, true}, nil}, 2},
		{"ipv4 only", args{"test.com", IPOption{true, false}, nil}, 1},
		{"ipv6 only", args{"test.com", IPOption{false, true}, nil}, 1},
		{"none/error", args{"test.com", IPOption{false, false}, nil}, 0},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if got := buildReqMsgs(tt.args.domain, tt.args.option, stubID, tt.args.reqOpts); !(len(got) == tt.want) {
				t.Errorf("buildReqMsgs() = %v, want %v", got, tt.want)
			}
		})
	}
}

func Test_genEDNS0Options(t *testing.T) {
	type args struct {
		clientIP net.IP
	}
	tests := []struct {
		name string
		args args
		want *dnsmessage.Resource
	}{
		// TODO: Add test cases.
		{"ipv4", args{net.ParseIP("4.3.2.1")}, nil},
		{"ipv6", args{net.ParseIP("2001::4321")}, nil},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if got := genEDNS0Options(tt.args.clientIP); got == nil {
				t.Errorf("genEDNS0Options() = %v, want %v", got, tt.want)
			}
		})
	}
}

func TestFqdn(t *testing.T) {
	type args struct {
		domain string
	}
	tests := []struct {
		name string
		args args
		want string
	}{
		{"with fqdn", args{"www.v2ray.com."}, "www.v2ray.com."},
		{"without fqdn", args{"www.v2ray.com"}, "www.v2ray.com."},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if got := Fqdn(tt.args.domain); got != tt.want {
				t.Errorf("Fqdn() = %v, want %v", got, tt.want)
			}
		})
	}
}


================================================
FILE: app/dns/dohdns.go
================================================
// +build !confonly

package dns

import (
	"bytes"
	"context"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"sync"
	"sync/atomic"
	"time"

	"golang.org/x/net/dns/dnsmessage"
	"v2ray.com/core/common"
	"v2ray.com/core/common/net"
	"v2ray.com/core/common/protocol/dns"
	"v2ray.com/core/common/session"
	"v2ray.com/core/common/signal/pubsub"
	"v2ray.com/core/common/task"
	dns_feature "v2ray.com/core/features/dns"
	"v2ray.com/core/features/routing"
	"v2ray.com/core/transport/internet"
)

// DoHNameServer implemented DNS over HTTPS (RFC8484) Wire Format,
// which is compatible with traditional dns over udp(RFC1035),
// thus most of the DOH implementation is copied from udpns.go
type DoHNameServer struct {
	sync.RWMutex
	ips        map[string]record
	pub        *pubsub.Service
	cleanup    *task.Periodic
	reqID      uint32
	clientIP   net.IP
	httpClient *http.Client
	dohURL     string
	name       string
}

// NewDoHNameServer creates DOH client object for remote resolving
func NewDoHNameServer(url *url.URL, dispatcher routing.Dispatcher, clientIP net.IP) (*DoHNameServer, error) {

	newError("DNS: created Remote DOH client for ", url.String()).AtInfo().WriteToLog()
	s := baseDOHNameServer(url, "DOH", clientIP)

	// Dispatched connection will be closed (interrupted) after each request
	// This makes DOH inefficient without a keep-alived connection
	// See: core/app/proxyman/outbound/handler.go:113
	// Using mux (https request wrapped in a stream layer) improves the situation.
	// Recommend to use NewDoHLocalNameServer (DOHL:) if v2ray instance is running on
	//  a normal network eg. the server side of v2ray
	tr := &http.Transport{
		MaxIdleConns:        30,
		IdleConnTimeout:     90 * time.Second,
		TLSHandshakeTimeout: 30 * time.Second,
		ForceAttemptHTTP2:   true,
		DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
			dest, err := net.ParseDestination(network + ":" + addr)
			if err != nil {
				return nil, err
			}

			link, err := dispatcher.Dispatch(ctx, dest)
			if err != nil {
				return nil, err
			}
			return net.NewConnection(
				net.ConnectionInputMulti(link.Writer),
				net.ConnectionOutputMulti(link.Reader),
			), nil
		},
	}

	dispatchedClient := &http.Client{
		Transport: tr,
		Timeout:   60 * time.Second,
	}

	s.httpClient = dispatchedClient
	return s, nil
}

// NewDoHLocalNameServer creates DOH client object for local resolving
func NewDoHLocalNameServer(url *url.URL, clientIP net.IP) *DoHNameServer {
	url.Scheme = "https"
	s := baseDOHNameServer(url, "DOHL", clientIP)
	tr := &http.Transport{
		IdleConnTimeout:   90 * time.Second,
		ForceAttemptHTTP2: true,
		DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
			dest, err := net.ParseDestination(network + ":" + addr)
			if err != nil {
				return nil, err
			}
			conn, err := internet.DialSystem(ctx, dest, nil)
			if err != nil {
				return nil, err
			}
			return conn, nil
		},
	}
	s.httpClient = &http.Client{
		Timeout:   time.Second * 180,
		Transport: tr,
	}
	newError("DNS: created Local DOH client for ", url.String()).AtInfo().WriteToLog()
	return s
}

func baseDOHNameServer(url *url.URL, prefix string, clientIP net.IP) *DoHNameServer {

	s := &DoHNameServer{
		ips:      make(map[string]record),
		clientIP: clientIP,
		pub:      pubsub.NewService(),
		name:     prefix + "//" + url.Host,
		dohURL:   url.String(),
	}
	s.cleanup = &task.Periodic{
		Interval: time.Minute,
		Execute:  s.Cleanup,
	}

	return s
}

// Name returns client name
func (s *DoHNameServer) Name() string {
	return s.name
}

// Cleanup clears expired items from cache
func (s *DoHNameServer) Cleanup() error {
	now := time.Now()
	s.Lock()
	defer s.Unlock()

	if len(s.ips) == 0 {
		return newError("nothing to do. stopping...")
	}

	for domain, record := range s.ips {
		if record.A != nil && record.A.Expire.Before(now) {
			record.A = nil
		}
		if record.AAAA != nil && record.AAAA.Expire.Before(now) {
			record.AAAA = nil
		}

		if record.A == nil && record.AAAA == nil {
			newError(s.name, " cleanup ", domain).AtDebug().WriteToLog()
			delete(s.ips, domain)
		} else {
			s.ips[domain] = record
		}
	}

	if len(s.ips) == 0 {
		s.ips = make(map[string]record)
	}

	return nil
}

func (s *DoHNameServer) updateIP(req *dnsRequest, ipRec *IPRecord) {
	elapsed := time.Since(req.start)

	s.Lock()
	rec := s.ips[req.domain]
	updated := false

	switch req.reqType {
	case dnsmessage.TypeA:
		if isNewer(rec.A, ipRec) {
			rec.A = ipRec
			updated = true
		}
	case dnsmessage.TypeAAAA:
		addr := make([]net.Address, 0)
		for _, ip := range ipRec.IP {
			if len(ip.IP()) == net.IPv6len {
				addr = append(addr, ip)
			}
		}
		ipRec.IP = addr
		if isNewer(rec.AAAA, ipRec) {
			rec.AAAA = ipRec
			updated = true
		}
	}
	newError(s.name, " got answer: ", req.domain, " ", req.reqType, " -> ", ipRec.IP, " ", elapsed).AtInfo().WriteToLog()

	if updated {
		s.ips[req.domain] = rec
	}
	switch req.reqType {
	case dnsmessage.TypeA:
		s.pub.Publish(req.domain+"4", nil)
	case dnsmessage.TypeAAAA:
		s.pub.Publish(req.domain+"6", nil)
	}
	s.Unlock()
	common.Must(s.cleanup.Start())
}

func (s *DoHNameServer) newReqID() uint16 {
	return uint16(atomic.AddUint32(&s.reqID, 1))
}

func (s *DoHNameServer) sendQuery(ctx context.Context, domain string, option IPOption) {
	newError(s.name, " querying: ", domain).AtInfo().WriteToLog(session.ExportIDToError(ctx))

	reqs := buildReqMsgs(domain, option, s.newReqID, genEDNS0Options(s.clientIP))

	var deadline time.Time
	if d, ok := ctx.Deadline(); ok {
		deadline = d
	} else {
		deadline = time.Now().Add(time.Second * 5)
	}

	for _, req := range reqs {
		go func(r *dnsRequest) {
			// generate new context for each req, using same context
			// may cause reqs all aborted if any one encounter an error
			dnsCtx := context.Background()

			// reserve internal dns server requested Inbound
			if inbound := session.InboundFromContext(ctx); inbound != nil {
				dnsCtx = session.ContextWithInbound(dnsCtx, inbound)
			}

			dnsCtx = session.ContextWithContent(dnsCtx, &session.Content{
				Protocol:      "https",
				SkipRoutePick: true,
			})

			// forced to use mux for DOH
			dnsCtx = session.ContextWithMuxPrefered(dnsCtx, true)

			var cancel context.CancelFunc
			dnsCtx, cancel = context.WithDeadline(dnsCtx, deadline)
			defer cancel()

			b, err := dns.PackMessage(r.msg)
			if err != nil {
				newError("failed to pack dns query").Base(err).AtError().WriteToLog()
				return
			}
			resp, err := s.dohHTTPSContext(dnsCtx, b.Bytes())
			if err != nil {
				newError("failed to retrieve response").Base(err).AtError().WriteToLog()
				return
			}
			rec, err := parseResponse(resp)
			if err != nil {
				newError("failed to handle DOH response").Base(err).AtError().WriteToLog()
				return
			}
			s.updateIP(r, rec)
		}(req)
	}
}

func (s *DoHNameServer) dohHTTPSContext(ctx context.Context, b []byte) ([]byte, error) {
	body := bytes.NewBuffer(b)
	req, err := http.NewRequest("POST", s.dohURL, body)
	if err != nil {
		return nil, err
	}

	req.Header.Add("Accept", "application/dns-message")
	req.Header.Add("Content-Type", "application/dns-message")

	resp, err := s.httpClient.Do(req.WithContext(ctx))
	if err != nil {
		return nil, err
	}

	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		io.Copy(ioutil.Discard, resp.Body) // flush resp.Body so that the conn is reusable
		return nil, fmt.Errorf("DOH server returned code %d", resp.StatusCode)
	}

	return ioutil.ReadAll(resp.Body)
}

func (s *DoHNameServer) findIPsForDomain(domain string, option IPOption) ([]net.IP, error) {
	s.RLock()
	record, found := s.ips[domain]
	s.RUnlock()

	if !found {
		return nil, errRecordNotFound
	}

	var ips []net.Address
	var lastErr error
	if option.IPv6Enable && record.AAAA != nil && record.AAAA.RCode == dnsmessage.RCodeSuccess {
		aaaa, err := record.AAAA.getIPs()
		if err != nil {
			lastErr = err
		}
		ips = append(ips, aaaa...)
	}

	if option.IPv4Enable && record.A != nil && record.A.RCode == dnsmessage.RCodeSuccess {
		a, err := record.A.getIPs()
		if err != nil {
			lastErr = err
		}
		ips = append(ips, a...)
	}

	if len(ips) > 0 {
		return toNetIP(ips), nil
	}

	if lastErr != nil {
		return nil, lastErr
	}

	if (option.IPv4Enable && record.A != nil) || (option.IPv6Enable && record.AAAA != nil) {
		return nil, dns_feature.ErrEmptyResponse
	}

	return nil, errRecordNotFound
}

// QueryIP is called from dns.Server->queryIPTimeout
func (s *DoHNameServer) QueryIP(ctx context.Context, domain string, option IPOption) ([]net.IP, error) {
	fqdn := Fqdn(domain)

	ips, err := s.findIPsForDomain(fqdn, option)
	if err != errRecordNotFound {
		newError(s.name, " cache HIT ", domain, " -> ", ips).Base(err).AtDebug().WriteToLog()
		return ips, err
	}

	// ipv4 and ipv6 belong to different subscription groups
	var sub4, sub6 *pubsub.Subscriber
	if option.IPv4Enable {
		sub4 = s.pub.Subscribe(fqdn + "4")
		defer sub4.Close()
	}
	if option.IPv6Enable {
		sub6 = s.pub.Subscribe(fqdn + "6")
		defer sub6.Close()
	}
	done := make(chan interface{})
	go func() {
		if sub4 != nil {
			select {
			case <-sub4.Wait():
			case <-ctx.Done():
			}
		}
		if sub6 != nil {
			select {
			case <-sub6.Wait():
			case <-ctx.Done():
			}
		}
		close(done)
	}()
	s.sendQuery(ctx, fqdn, option)

	for {
		ips, err := s.findIPsForDomain(fqdn, option)
		if err != errRecordNotFound {
			return ips, err
		}

		select {
		case <-ctx.Done():
			return nil, ctx.Err()
		case <-done:
		}
	}
}


================================================
FILE: app/dns/errors.generated.go
================================================
package dns

import "v2ray.com/core/common/errors"

type errPathObjHolder struct{}

func newError(values ...interface{}) *errors.Error {
	return errors.New(values...).WithPathObj(errPathObjHolder{})
}


================================================
FILE: app/dns/hosts.go
================================================
// +build !confonly

package dns

import (
	"v2ray.com/core/common"
	"v2ray.com/core/common/net"
	"v2ray.com/core/common/strmatcher"
	"v2ray.com/core/features"
)

// StaticHosts represents static domain-ip mapping in DNS server.
type StaticHosts struct {
	ips      [][]net.Address
	matchers *strmatcher.MatcherGroup
}

var typeMap = map[DomainMatchingType]strmatcher.Type{
	DomainMatchingType_Full:      strmatcher.Full,
	DomainMatchingType_Subdomain: strmatcher.Domain,
	DomainMatchingType_Keyword:   strmatcher.Substr,
	DomainMatchingType_Regex:     strmatcher.Regex,
}

func toStrMatcher(t DomainMatchingType, domain string) (strmatcher.Matcher, error) {
	strMType, f := typeMap[t]
	if !f {
		return nil, newError("unknown mapping type", t).AtWarning()
	}
	matcher, err := strMType.New(domain)
	if err != nil {
		return nil, newError("failed to create str matcher").Base(err)
	}
	return matcher, nil
}

// NewStaticHosts creates a new StaticHosts instance.
func NewStaticHosts(hosts []*Config_HostMapping, legacy map[string]*net.IPOrDomain) (*StaticHosts, error) {
	g := new(strmatcher.MatcherGroup)
	sh := &StaticHosts{
		ips:      make([][]net.Address, len(hosts)+len(legacy)+16),
		matchers: g,
	}

	if legacy != nil {
		features.PrintDeprecatedFeatureWarning("simple host mapping")

		for domain, ip := range legacy {
			matcher, err := strmatcher.Full.New(domain)
			common.Must(err)
			id := g.Add(matcher)

			address := ip.AsAddress()
			if address.Family().IsDomain() {
				return nil, newError("invalid domain address in static hosts: ", address.Domain()).AtWarning()
			}

			sh.ips[id] = []net.Address{address}
		}
	}

	for _, mapping := range hosts {
		matcher, err := toStrMatcher(mapping.Type, mapping.Domain)
		if err != nil {
			return nil, newError("failed to create domain matcher").Base(err)
		}
		id := g.Add(matcher)
		ips := make([]net.Address, 0, len(mapping.Ip)+1)
		if len(mapping.Ip) > 0 {
			for _, ip := range mapping.Ip {
				addr := net.IPAddress(ip)
				if addr == nil {
					return nil, newError("invalid IP address in static hosts: ", ip).AtWarning()
				}
				ips = append(ips, addr)
			}
		} else if len(mapping.ProxiedDomain) > 0 {
			ips = append(ips, net.DomainAddress(mapping.ProxiedDomain))
		} else {
			return nil, newError("neither IP address nor proxied domain specified for domain: ", mapping.Domain).AtWarning()
		}

		// Special handling for localhost IPv6. This is a dirty workaround as JSON config supports only single IP mapping.
		if len(ips) == 1 && ips[0] == net.LocalHostIP {
			ips = append(ips, net.LocalHostIPv6)
		}

		sh.ips[id] = ips
	}

	return sh, nil
}

func filterIP(ips []net.Address, option IPOption) []net.Address {
	filtered := make([]net.Address, 0, len(ips))
	for _, ip := range ips {
		if (ip.Family().IsIPv4() && option.IPv4Enable) || (ip.Family().IsIPv6() && option.IPv6Enable) {
			filtered = append(filtered, ip)
		}
	}
	if len(filtered) == 0 {
		return nil
	}
	return filtered
}

// LookupIP returns IP address for the given domain, if exists in this StaticHosts.
func (h *StaticHosts) LookupIP(domain string, option IPOption) []net.Address {
	indices := h.matchers.Match(domain)
	if len(indices) == 0 {
		return nil
	}
	ips := []net.Address{}
	for _, id := range indices {
		ips = append(ips, h.ips[id]...)
	}
	if len(ips) == 1 && ips[0].Family().IsDomain() {
		return ips
	}
	return filterIP(ips, option)
}


================================================
FILE: app/dns/hosts_test.go
================================================
package dns_test

import (
	"testing"

	"github.com/google/go-cmp/cmp"

	. "v2ray.com/core/app/dns"
	"v2ray.com/core/common"
	"v2ray.com/core/common/net"
)

func TestStaticHosts(t *testing.T) {
	pb := []*Config_HostMapping{
		{
			Type:   DomainMatchingType_Full,
			Domain: "v2ray.com",
			Ip: [][]byte{
				{1, 1, 1, 1},
			},
		},
		{
			Type:   DomainMatchingType_Subdomain,
			Domain: "v2ray.cn",
			Ip: [][]byte{
				{2, 2, 2, 2},
			},
		},
		{
			Type:   DomainMatchingType_Subdomain,
			Domain: "baidu.com",
			Ip: [][]byte{
				{127, 0, 0, 1},
			},
		},
	}

	hosts, err := NewStaticHosts(pb, nil)
	common.Must(err)

	{
		ips := hosts.LookupIP("v2ray.com", IPOption{
			IPv4Enable: true,
			IPv6Enable: true,
		})
		if len(ips) != 1 {
			t.Error("expect 1 IP, but got ", len(ips))
		}
		if diff := cmp.Diff([]byte(ips[0].IP()), []byte{1, 1, 1, 1}); diff != "" {
			t.Error(diff)
		}
	}

	{
		ips := hosts.LookupIP("www.v2ray.cn", IPOption{
			IPv4Enable: true,
			IPv6Enable: true,
		})
		if len(ips) != 1 {
			t.Error("expect 1 IP, but got ", len(ips))
		}
		if diff := cmp.Diff([]byte(ips[0].IP()), []byte{2, 2, 2, 2}); diff != "" {
			t.Error(diff)
		}
	}

	{
		ips := hosts.LookupIP("baidu.com", IPOption{
			IPv4Enable: false,
			IPv6Enable: true,
		})
		if len(ips) != 1 {
			t.Error("expect 1 IP, but got ", len(ips))
		}
		if diff := cmp.Diff([]byte(ips[0].IP()), []byte(net.LocalHostIPv6.IP())); diff != "" {
			t.Error(diff)
		}
	}
}


================================================
FILE: app/dns/nameserver.go
================================================
// +build !confonly

package dns

import (
	"context"

	"v2ray.com/core/common/net"
	"v2ray.com/core/features/dns/localdns"
)

// IPOption is an object for IP query options.
type IPOption struct {
	IPv4Enable bool
	IPv6Enable bool
}

// Client is the interface for DNS client.
type Client interface {
	// Name of the Client.
	Name() string

	// QueryIP sends IP queries to its configured server.
	QueryIP(ctx context.Context, domain string, option IPOption) ([]net.IP, error)
}

type localNameServer struct {
	client *localdns.Client
}

func (s *localNameServer) QueryIP(ctx context.Context, domain string, option IPOption) ([]net.IP, error) {
	if option.IPv4Enable && option.IPv6Enable {
		return s.client.LookupIP(domain)
	}

	if option.IPv4Enable {
		return s.client.LookupIPv4(domain)
	}

	if option.IPv6Enable {
		return s.client.LookupIPv6(domain)
	}

	return nil, newError("neither IPv4 nor IPv6 is enabled")
}

func (s *localNameServer) Name() string {
	return "localhost"
}

func NewLocalNameServer() *localNameServer {
	newError("DNS: created localhost client").AtInfo().WriteToLog()
	return &localNameServer{
		client: localdns.New(),
	}
}


================================================
FILE: app/dns/nameserver_test.go
================================================
package dns_test

import (
	"context"
	"testing"
	"time"

	. "v2ray.com/core/app/dns"
	"v2ray.com/core/common"
)

func TestLocalNameServer(t *testing.T) {
	s := NewLocalNameServer()
	ctx, cancel := context.WithTimeout(context.Background(), time.Second*2)
	ips, err := s.QueryIP(ctx, "google.com", IPOption{
		IPv4Enable: true,
		IPv6Enable: true,
	})
	cancel()
	common.Must(err)
	if len(ips) == 0 {
		t.Error("expect some ips, but got 0")
	}
}


================================================
FILE: app/dns/server.go
================================================
// +build !confonly

package dns

//go:generate go run v2ray.com/core/common/errors/errorgen

import (
	"context"
	"fmt"
	"log"
	"net/url"
	"strings"
	"sync"
	"time"

	"v2ray.com/core"
	"v2ray.com/core/app/router"
	"v2ray.com/core/common"
	"v2ray.com/core/common/errors"
	"v2ray.com/core/common/net"
	"v2ray.com/core/common/session"
	"v2ray.com/core/common/strmatcher"
	"v2ray.com/core/common/uuid"
	"v2ray.com/core/features"
	"v2ray.com/core/features/dns"
	"v2ray.com/core/features/routing"
)

// Server is a DNS rely server.
type Server struct {
	sync.Mutex
	hosts         *StaticHosts
	clientIP      net.IP
	clients       []Client             // clientIdx -> Client
	ipIndexMap    []*MultiGeoIPMatcher // clientIdx -> *MultiGeoIPMatcher
	domainRules   [][]string           // clientIdx -> domainRuleIdx -> DomainRule
	domainMatcher strmatcher.IndexMatcher
	matcherInfos  []DomainMatcherInfo // matcherIdx -> DomainMatcherInfo
	tag           string
}

// DomainMatcherInfo contains information attached to index returned by Server.domainMatcher
type DomainMatcherInfo struct {
	clientIdx     uint16
	domainRuleIdx uint16
}

// MultiGeoIPMatcher for match
type MultiGeoIPMatcher struct {
	matchers []*router.GeoIPMatcher
}

var errExpectedIPNonMatch = errors.New("expectIPs not match")

// Match check ip match
func (c *MultiGeoIPMatcher) Match(ip net.IP) bool {
	for _, matcher := range c.matchers {
		if matcher.Match(ip) {
			return true
		}
	}
	return false
}

// HasMatcher check has matcher
func (c *MultiGeoIPMatcher) HasMatcher() bool {
	return len(c.matchers) > 0
}

func generateRandomTag() string {
	id := uuid.New()
	return "v2ray.system." + id.String()
}

// New creates a new DNS server with given configuration.
func New(ctx context.Context, config *Config) (*Server, error) {
	server := &Server{
		clients: make([]Client, 0, len(config.NameServers)+len(config.NameServer)),
		tag:     config.Tag,
	}
	if server.tag == "" {
		server.tag = generateRandomTag()
	}
	if len(config.ClientIp) > 0 {
		if len(config.ClientIp) != net.IPv4len && len(config.ClientIp) != net.IPv6len {
			return nil, newError("unexpected IP length", len(config.ClientIp))
		}
		server.clientIP = net.IP(config.ClientIp)
	}

	hosts, err := NewStaticHosts(config.StaticHosts, config.Hosts)
	if err != nil {
		return nil, newError("failed to create hosts").Base(err)
	}
	server.hosts = hosts

	addNameServer := func(ns *NameServer) int {
		endpoint := ns.Address
		address := endpoint.Address.AsAddress()
		if address.Family().IsDomain() && address.Domain() == "localhost" {
			server.clients = append(server.clients, NewLocalNameServer())
			// Priotize local domains with specific TLDs or without any dot to local DNS
			// References:
			// https://www.iana.org/assignments/special-use-domain-names/special-use-domain-names.xhtml
			// https://unix.stackexchange.com/questions/92441/whats-the-difference-between-local-home-and-lan
			localTLDsAndDotlessDomains := []*NameServer_PriorityDomain{
				{Type: DomainMatchingType_Regex, Domain: "^[^.]+$"}, // This will only match domains without any dot
				{Type: DomainMatchingType_Subdomain, Domain: "local"},
				{Type: DomainMatchingType_Subdomain, Domain: "localdomain"},
				{Type: DomainMatchingType_Subdomain, Domain: "localhost"},
				{Type: DomainMatchingType_Subdomain, Domain: "lan"},
				{Type: DomainMatchingType_Subdomain, Domain: "home.arpa"},
				{Type: DomainMatchingType_Subdomain, Domain: "example"},
				{Type: DomainMatchingType_Subdomain, Domain: "invalid"},
				{Type: DomainMatchingType_Subdomain, Domain: "test"},
			}
			ns.PrioritizedDomain = append(ns.PrioritizedDomain, localTLDsAndDotlessDomains...)
		} else if address.Family().IsDomain() && strings.HasPrefix(address.Domain(), "https+local://") {
			// URI schemed string treated as domain
			// DOH Local mode
			u, err := url.Parse(address.Domain())
			if err != nil {
				log.Fatalln(newError("DNS config error").Base(err))
			}
			server.clients = append(server.clients, NewDoHLocalNameServer(u, server.clientIP))
		} else if address.Family().IsDomain() && strings.HasPrefix(address.Domain(), "https://") {
			// DOH Remote mode
			u, err := url.Parse(address.Domain())
			if err != nil {
				log.Fatalln(newError("DNS config error").Base(err))
			}
			idx := len(server.clients)
			server.clients = append(server.clients, nil)

			// need the core dispatcher, register DOHClient at callback
			common.Must(core.RequireFeatures(ctx, func(d routing.Dispatcher) {
				c, err := NewDoHNameServer(u, d, server.clientIP)
				if err != nil {
					log.Fatalln(newError("DNS config error").Base(err))
				}
				server.clients[idx] = c
			}))
		} else {
			// UDP classic DNS mode
			dest := endpoint.AsDestination()
			if dest.Network == net.Network_Unknown {
				dest.Network = net.Network_UDP
			}
			if dest.Network == net.Network_UDP {
				idx := len(server.clients)
				server.clients = append(server.clients, nil)

				common.Must(core.RequireFeatures(ctx, func(d routing.Dispatcher) {
					server.clients[idx] = NewClassicNameServer(dest, d, server.clientIP)
				}))
			}
		}
		server.ipIndexMap = append(server.ipIndexMap, nil)
		return len(server.clients) - 1
	}

	if len(config.NameServers) > 0 {
		features.PrintDeprecatedFeatureWarning("simple DNS server")
		for _, destPB := range config.NameServers {
			addNameServer(&NameServer{Address: destPB})
		}
	}

	if len(config.NameServer) > 0 {
		clientIndices := []int{}
		domainRuleCount := 0
		for _, ns := range config.NameServer {
			idx := addNameServer(ns)
			clientIndices = append(clientIndices, idx)
			domainRuleCount += len(ns.PrioritizedDomain)
		}

		domainRules := make([][]string, len(server.clients))
		domainMatcher := &strmatcher.MatcherGroup{}
		matcherInfos := make([]DomainMatcherInfo, domainRuleCount+1) // matcher index starts from 1
		var geoIPMatcherContainer router.GeoIPMatcherContainer
		for nidx, ns := range config.NameServer {
			idx := clientIndices[nidx]

			// Establish domain rule matcher
			rules := []string{}
			ruleCurr := 0
			ruleIter := 0
			for _, domain := range ns.PrioritizedDomain {
				matcher, err := toStrMatcher(domain.Type, domain.Domain)
				if err != nil {
					return nil, newError("failed to create prioritized domain").Base(err).AtWarning()
				}
				midx := domainMatcher.Add(matcher)
				if midx >= uint32(len(matcherInfos)) { // This rarely happens according to current matcher's implementation
					newError("expanding domain matcher info array to size ", midx, " when adding ", matcher).AtDebug().WriteToLog()
					matcherInfos = append(matcherInfos, make([]DomainMatcherInfo, midx-uint32(len(matcherInfos))+1)...)
				}
				info := &matcherInfos[midx]
				info.clientIdx = uint16(idx)
				if ruleCurr < len(ns.OriginalRules) {
					info.domainRuleIdx = uint16(ruleCurr)
					rule := ns.OriginalRules[ruleCurr]
					if ruleCurr >= len(rules) {
						rules = append(rules, rule.Rule)
					}
					ruleIter++
					if ruleIter >= int(rule.Size) {
						ruleIter = 0
						ruleCurr++
					}
				} else { // No original rule, generate one according to current domain matcher (majorly for compatibility with tests)
					info.domainRuleIdx = uint16(len(rules))
					rules = append(rules, matcher.String())
				}
			}
			domainRules[idx] = rules

			// only add to ipIndexMap if GeoIP is configured
			if len(ns.Geoip) > 0 {
				var matchers []*router.GeoIPMatcher
				for _, geoip := range ns.Geoip {
					matcher, err := geoIPMatcherContainer.Add(geoip)
					if err != nil {
						return nil, newError("failed to create ip matcher").Base(err).AtWarning()
					}
					matchers = append(matchers, matcher)
				}
				matcher := &MultiGeoIPMatcher{matchers: matchers}
				server.ipIndexMap[idx] = matcher
			}
		}
		server.domainRules = domainRules
		server.domainMatcher = domainMatcher
		server.matcherInfos = matcherInfos
	}

	if len(server.clients) == 0 {
		server.clients = append(server.clients, NewLocalNameServer())
		server.ipIndexMap = append(server.ipIndexMap, nil)
	}

	return server, nil
}

// Type implements common.HasType.
func (*Server) Type() interface{} {
	return dns.ClientType()
}

// Start implements common.Runnable.
func (s *Server) Start() error {
	return nil
}

// Close implements common.Closable.
func (s *Server) Close() error {
	return nil
}

func (s *Server) IsOwnLink(ctx context.Context) bool {
	inbound := session.InboundFromContext(ctx)
	return inbound != nil && inbound.Tag == s.tag
}

// Match check dns ip match geoip
func (s *Server) Match(idx int, client Client, domain string, ips []net.IP) ([]net.IP, error) {
	var matcher *MultiGeoIPMatcher
	if idx < len(s.ipIndexMap) {
		matcher = s.ipIndexMap[idx]
	}
	if matcher == nil {
		return ips, nil
	}

	if !matcher.HasMatcher() {
		newError("domain ", domain, " server has no valid matcher: ", client.Name(), " idx:", idx).AtDebug().WriteToLog()
		return ips, nil
	}

	newIps := []net.IP{}
	for _, ip := range ips {
		if matcher.Match(ip) {
			newIps = append(newIps, ip)
		}
	}
	if len(newIps) == 0 {
		return nil, errExpectedIPNonMatch
	}
	newError("domain ", domain, " expectIPs ", newIps, " matched at server ", client.Name(), " idx:", idx).AtDebug().WriteToLog()
	return newIps, nil
}

func (s *Server) queryIPTimeout(idx int, client Client, domain string, option IPOption) ([]net.IP, error) {
	ctx, cancel := context.WithTimeout(context.Background(), time.Second*4)
	if len(s.tag) > 0 {
		ctx = session.ContextWithInbound(ctx, &session.Inbound{
			Tag: s.tag,
		})
	}
	ips, err := client.QueryIP(ctx, domain, option)
	cancel()

	if err != nil {
		return ips, err
	}

	ips, err = s.Match(idx, client, domain, ips)
	return ips, err
}

// LookupIP implements dns.Client.
func (s *Server) LookupIP(domain string) ([]net.IP, error) {
	return s.lookupIPInternal(domain, IPOption{
		IPv4Enable: true,
		IPv6Enable: true,
	})
}

// LookupIPv4 implements dns.IPv4Lookup.
func (s *Server) LookupIPv4(domain string) ([]net.IP, error) {
	return s.lookupIPInternal(domain, IPOption{
		IPv4Enable: true,
		IPv6Enable: false,
	})
}

// LookupIPv6 implements dns.IPv6Lookup.
func (s *Server) LookupIPv6(domain string) ([]net.IP, error) {
	return s.lookupIPInternal(domain, IPOption{
		IPv4Enable: false,
		IPv6Enable: true,
	})
}

func (s *Server) lookupStatic(domain string, option IPOption, depth int32) []net.Address {
	ips := s.hosts.LookupIP(domain, option)
	if ips == nil {
		return nil
	}
	if ips[0].Family().IsDomain() && depth < 5 {
		if newIPs := s.lookupStatic(ips[0].Domain(), option, depth+1); newIPs != nil {
			return newIPs
		}
	}
	return ips
}

func toNetIP(ips []net.Address) []net.IP {
	if len(ips) == 0 {
		return nil
	}
	netips := make([]net.IP, 0, len(ips))
	for _, ip := range ips {
		netips = append(netips, ip.IP())
	}
	return netips
}

func (s *Server) lookupIPInternal(domain string, option IPOption) ([]net.IP, error) {
	if domain == "" {
		return nil, newError("empty domain name")
	}

	// normalize the FQDN form query
	if domain[len(domain)-1] == '.' {
		domain = domain[:len(domain)-1]
	}

	ips := s.lookupStatic(domain, option, 0)
	if ips != nil && ips[0].Family().IsIP() {
		newError("returning ", len(ips), " IPs for domain ", domain).WriteToLog()
		return toNetIP(ips), nil
	}

	if ips != nil && ips[0].Family().IsDomain() {
		newdomain := ips[0].Domain()
		newError("domain replaced: ", domain, " -> ", newdomain).WriteToLog()
		domain = newdomain
	}

	var lastErr error
	var matchedClient Client
	if s.domainMatcher != nil {
		indices := s.domainMatcher.Match(domain)
		domainRules := []string{}
		matchingDNS := []string{}
		for _, idx := range indices {
			info := s.matcherInfos[idx]
			rule := s.domainRules[info.clientIdx][info.domainRuleIdx]
			domainRules = append(domainRules, fmt.Sprintf("%s(DNS idx:%d)", rule, info.clientIdx))
			matchingDNS = append(matchingDNS, s.clients[info.clientIdx].Name())
		}
		if len(domainRules) > 0 {
			newError("domain ", domain, " matches following rules: ", domainRules).AtDebug().WriteToLog()
		}
		if len(matchingDNS) > 0 {
			newError("domain ", domain, " uses following DNS first: ", matchingDNS).AtDebug().WriteToLog()
		}
		for _, idx := range indices {
			clientIdx := int(s.matcherInfos[idx].clientIdx)
			matchedClient = s.clients[clientIdx]
			ips, err := s.queryIPTimeout(clientIdx, matchedClient, domain, option)
			if len(ips) > 0 {
				return ips, nil
			}
			if err == dns.ErrEmptyResponse {
				return nil, err
			}
			if err != nil {
				newError("failed to lookup ip for domain ", domain, " at server ", matchedClient.Name()).Base(err).WriteToLog()
				lastErr = err
			}
		}
	}

	for idx, client := range s.clients {
		if client == matchedClient {
			newError("domain ", domain, " at server ", client.Name(), " idx:", idx, " already lookup failed, just ignore").AtDebug().WriteToLog()
			continue
		}

		ips, err := s.queryIPTimeout(idx, client, domain, option)
		if len(ips) > 0 {
			return ips, nil
		}

		if err != nil {
			newError("failed to lookup ip for domain ", domain, " at server ", client.Name()).Base(err).WriteToLog()
			lastErr = err
		}
		if err != context.Canceled && err != context.DeadlineExceeded && err != errExpectedIPNonMatch {
			return nil, err
		}
	}

	return nil, newError("returning nil for domain ", domain).Base(lastErr)
}

func init() {
	common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
		return New(ctx, config.(*Config))
	}))
}


================================================
FILE: app/dns/server_test.go
================================================
package dns_test

import (
	"testing"
	"time"

	"github.com/google/go-cmp/cmp"
	"github.com/miekg/dns"

	"v2ray.com/core"
	"v2ray.com/core/app/dispatcher"
	. "v2ray.com/core/app/dns"
	"v2ray.com/core/app/policy"
	"v2ray.com/core/app/proxyman"
	_ "v2ray.com/core/app/proxyman/outbound"
	"v2ray.com/core/app/router"
	"v2ray.com/core/common"
	"v2ray.com/core/common/net"
	"v2ray.com/core/common/serial"
	feature_dns "v2ray.com/core/features/dns"
	"v2ray.com/core/proxy/freedom"
	"v2ray.com/core/testing/servers/udp"
)

type staticHandler struct {
}

func (*staticHandler) ServeDNS(w dns.ResponseWriter, r *dns.Msg) {
	ans := new(dns.Msg)
	ans.Id = r.Id

	var clientIP net.IP

	opt := r.IsEdns0()
	if opt != nil {
		for _, o := range opt.Option {
			if o.Option() == dns.EDNS0SUBNET {
				subnet := o.(*dns.EDNS0_SUBNET)
				clientIP = subnet.Address
			}
		}
	}

	for _, q := range r.Question {
		if q.Name == "google.com." && q.Qtype == dns.TypeA {
			if clientIP == nil {
				rr, _ := dns.NewRR("google.com. IN A 8.8.8.8")
				ans.Answer = append(ans.Answer, rr)
			} else {
				rr, _ := dns.NewRR("google.com. IN A 8.8.4.4")
				ans.Answer = append(ans.Answer, rr)
			}
		} else if q.Name == "api.google.com." && q.Qtype == dns.TypeA {
			rr, _ := dns.NewRR("api.google.com. IN A 8.8.7.7")
			ans.Answer = append(ans.Answer, rr)
		} else if q.Name == "v2.api.google.com." && q.Qtype == dns.TypeA {
			rr, _ := dns.NewRR("v2.api.google.com. IN A 8.8.7.8")
			ans.Answer = append(ans.Answer, rr)
		} else if q.Name == "facebook.com." && q.Qtype == dns.TypeA {
			rr, _ := dns.NewRR("facebook.com. IN A 9.9.9.9")
			ans.Answer = append(ans.Answer, rr)
		} else if q.Name == "ipv6.google.com." && q.Qtype == dns.TypeA {
			rr, err := dns.NewRR("ipv6.google.com. IN A 8.8.8.7")
			common.Must(err)
			ans.Answer = append(ans.Answer, rr)
		} else if q.Name == "ipv6.google.com." && q.Qtype == dns.TypeAAAA {
			rr, err := dns.NewRR("ipv6.google.com. IN AAAA 2001:4860:4860::8888")
			common.Must(err)
			ans.Answer = append(ans.Answer, rr)
		} else if q.Name == "notexist.google.com." && q.Qtype == dns.TypeAAAA {
			ans.MsgHdr.Rcode = dns.RcodeNameError
		} else if q.Name == "hostname." && q.Qtype == dns.TypeA {
			rr, _ := dns.NewRR("hostname. IN A 127.0.0.1")
			ans.Answer = append(ans.Answer, rr)
		} else if q.Name == "hostname.local." && q.Qtype == dns.TypeA {
			rr, _ := dns.NewRR("hostname.local. IN A 127.0.0.1")
			ans.Answer = append(ans.Answer, rr)
		} else if q.Name == "hostname.localdomain." && q.Qtype == dns.TypeA {
			rr, _ := dns.NewRR("hostname.localdomain. IN A 127.0.0.1")
			ans.Answer = append(ans.Answer, rr)
		} else if q.Name == "localhost." && q.Qtype == dns.TypeA {
			rr, _ := dns.NewRR("localhost. IN A 127.0.0.2")
			ans.Answer = append(ans.Answer, rr)
		} else if q.Name == "localhost-a." && q.Qtype == dns.TypeA {
			rr, _ := dns.NewRR("localhost-a. IN A 127.0.0.3")
			ans.Answer = append(ans.Answer, rr)
		} else if q.Name == "localhost-b." && q.Qtype == dns.TypeA {
			rr, _ := dns.NewRR("localhost-b. IN A 127.0.0.4")
			ans.Answer = append(ans.Answer, rr)
		} else if q.Name == "Mijia\\ Cloud." && q.Qtype == dns.TypeA {
			rr, _ := dns.NewRR("Mijia\\ Cloud. IN A 127.0.0.1")
			ans.Answer = append(ans.Answer, rr)
		}
	}
	w.WriteMsg(ans)
}

func TestUDPServerSubnet(t *testing.T) {
	port := udp.PickPort()

	dnsServer := dns.Server{
		Addr:    "127.0.0.1:" + port.String(),
		Net:     "udp",
		Handler: &staticHandler{},
		UDPSize: 1200,
	}

	go dnsServer.ListenAndServe()
	time.Sleep(time.Second)

	config := &core.Config{
		App: []*serial.TypedMessage{
			serial.ToTypedMessage(&Config{
				NameServers: []*net.Endpoint{
					{
						Network: net.Network_UDP,
						Address: &net.IPOrDomain{
							Address: &net.IPOrDomain_Ip{
								Ip: []byte{127, 0, 0, 1},
							},
						},
						Port: uint32(port),
					},
				},
				ClientIp: []byte{7, 8, 9, 10},
			}),
			serial.ToTypedMessage(&dispatcher.Config{}),
			serial.ToTypedMessage(&proxyman.OutboundConfig{}),
			serial.ToTypedMessage(&policy.Config{}),
		},
		Outbound: []*core.OutboundHandlerConfig{
			{
				ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
			},
		},
	}

	v, err := core.New(config)
	common.Must(err)

	client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)

	ips, err := client.LookupIP("google.com")
	if err != nil {
		t.Fatal("unexpected error: ", err)
	}

	if r := cmp.Diff(ips, []net.IP{{8, 8, 4, 4}}); r != "" {
		t.Fatal(r)
	}
}

func TestUDPServer(t *testing.T) {
	port := udp.PickPort()

	dnsServer := dns.Server{
		Addr:    "127.0.0.1:" + port.String(),
		Net:     "udp",
		Handler: &staticHandler{},
		UDPSize: 1200,
	}

	go dnsServer.ListenAndServe()
	time.Sleep(time.Second)

	config := &core.Config{
		App: []*serial.TypedMessage{
			serial.ToTypedMessage(&Config{
				NameServers: []*net.Endpoint{
					{
						Network: net.Network_UDP,
						Address: &net.IPOrDomain{
							Address: &net.IPOrDomain_Ip{
								Ip: []byte{127, 0, 0, 1},
							},
						},
						Port: uint32(port),
					},
				},
			}),
			serial.ToTypedMessage(&dispatcher.Config{}),
			serial.ToTypedMessage(&proxyman.OutboundConfig{}),
			serial.ToTypedMessage(&policy.Config{}),
		},
		Outbound: []*core.OutboundHandlerConfig{
			{
				ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
			},
		},
	}

	v, err := core.New(config)
	common.Must(err)

	client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)

	{
		ips, err := client.LookupIP("google.com")
		if err != nil {
			t.Fatal("unexpected error: ", err)
		}

		if r := cmp.Diff(ips, []net.IP{{8, 8, 8, 8}}); r != "" {
			t.Fatal(r)
		}
	}

	{
		ips, err := client.LookupIP("facebook.com")
		if err != nil {
			t.Fatal("unexpected error: ", err)
		}

		if r := cmp.Diff(ips, []net.IP{{9, 9, 9, 9}}); r != "" {
			t.Fatal(r)
		}
	}

	{
		_, err := client.LookupIP("notexist.google.com")
		if err == nil {
			t.Fatal("nil error")
		}
		if r := feature_dns.RCodeFromError(err); r != uint16(dns.RcodeNameError) {
			t.Fatal("expected NameError, but got ", r)
		}
	}

	{
		clientv6 := client.(feature_dns.IPv6Lookup)
		ips, err := clientv6.LookupIPv6("ipv4only.google.com")
		if err != feature_dns.ErrEmptyResponse {
			t.Fatal("error: ", err)
		}
		if len(ips) != 0 {
			t.Fatal("ips: ", ips)
		}
	}

	dnsServer.Shutdown()

	{
		ips, err := client.LookupIP("google.com")
		if err != nil {
			t.Fatal("unexpected error: ", err)
		}

		if r := cmp.Diff(ips, []net.IP{{8, 8, 8, 8}}); r != "" {
			t.Fatal(r)
		}
	}
}

func TestPrioritizedDomain(t *testing.T) {
	port := udp.PickPort()

	dnsServer := dns.Server{
		Addr:    "127.0.0.1:" + port.String(),
		Net:     "udp",
		Handler: &staticHandler{},
		UDPSize: 1200,
	}

	go dnsServer.ListenAndServe()
	time.Sleep(time.Second)

	config := &core.Config{
		App: []*serial.TypedMessage{
			serial.ToTypedMessage(&Config{
				NameServers: []*net.Endpoint{
					{
						Network: net.Network_UDP,
						Address: &net.IPOrDomain{
							Address: &net.IPOrDomain_Ip{
								Ip: []byte{127, 0, 0, 1},
							},
						},
						Port: 9999, /* unreachable */
					},
				},
				NameServer: []*NameServer{
					{
						Address: &net.Endpoint{
							Network: net.Network_UDP,
							Address: &net.IPOrDomain{
								Address: &net.IPOrDomain_Ip{
									Ip: []byte{127, 0, 0, 1},
								},
							},
							Port: uint32(port),
						},
						PrioritizedDomain: []*NameServer_PriorityDomain{
							{
								Type:   DomainMatchingType_Full,
								Domain: "google.com",
							},
						},
					},
				},
			}),
			serial.ToTypedMessage(&dispatcher.Config{}),
			serial.ToTypedMessage(&proxyman.OutboundConfig{}),
			serial.ToTypedMessage(&policy.Config{}),
		},
		Outbound: []*core.OutboundHandlerConfig{
			{
				ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
			},
		},
	}

	v, err := core.New(config)
	common.Must(err)

	client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)

	startTime := time.Now()

	{
		ips, err := client.LookupIP("google.com")
		if err != nil {
			t.Fatal("unexpected error: ", err)
		}

		if r := cmp.Diff(ips, []net.IP{{8, 8, 8, 8}}); r != "" {
			t.Fatal(r)
		}
	}

	endTime := time.Now()
	if startTime.After(endTime.Add(time.Second * 2)) {
		t.Error("DNS query doesn't finish in 2 seconds.")
	}
}

func TestUDPServerIPv6(t *testing.T) {
	port := udp.PickPort()

	dnsServer := dns.Server{
		Addr:    "127.0.0.1:" + port.String(),
		Net:     "udp",
		Handler: &staticHandler{},
		UDPSize: 1200,
	}

	go dnsServer.ListenAndServe()
	time.Sleep(time.Second)

	config := &core.Config{
		App: []*serial.TypedMessage{
			serial.ToTypedMessage(&Config{
				NameServers: []*net.Endpoint{
					{
						Network: net.Network_UDP,
						Address: &net.IPOrDomain{
							Address: &net.IPOrDomain_Ip{
								Ip: []byte{127, 0, 0, 1},
							},
						},
						Port: uint32(port),
					},
				},
			}),
			serial.ToTypedMessage(&dispatcher.Config{}),
			serial.ToTypedMessage(&proxyman.OutboundConfig{}),
			serial.ToTypedMessage(&policy.Config{}),
		},
		Outbound: []*core.OutboundHandlerConfig{
			{
				ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
			},
		},
	}

	v, err := core.New(config)
	common.Must(err)

	client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)
	client6 := client.(feature_dns.IPv6Lookup)

	{
		ips, err := client6.LookupIPv6("ipv6.google.com")
		if err != nil {
			t.Fatal("unexpected error: ", err)
		}

		if r := cmp.Diff(ips, []net.IP{{32, 1, 72, 96, 72, 96, 0, 0, 0, 0, 0, 0, 0, 0, 136, 136}}); r != "" {
			t.Fatal(r)
		}
	}
}

func TestStaticHostDomain(t *testing.T) {
	port := udp.PickPort()

	dnsServer := dns.Server{
		Addr:    "127.0.0.1:" + port.String(),
		Net:     "udp",
		Handler: &staticHandler{},
		UDPSize: 1200,
	}

	go dnsServer.ListenAndServe()
	time.Sleep(time.Second)

	config := &core.Config{
		App: []*serial.TypedMessage{
			serial.ToTypedMessage(&Config{
				NameServers: []*net.Endpoint{
					{
						Network: net.Network_UDP,
						Address: &net.IPOrDomain{
							Address: &net.IPOrDomain_Ip{
								Ip: []byte{127, 0, 0, 1},
							},
						},
						Port: uint32(port),
					},
				},
				StaticHosts: []*Config_HostMapping{
					{
						Type:          DomainMatchingType_Full,
						Domain:        "example.com",
						ProxiedDomain: "google.com",
					},
				},
			}),
			serial.ToTypedMessage(&dispatcher.Config{}),
			serial.ToTypedMessage(&proxyman.OutboundConfig{}),
			serial.ToTypedMessage(&policy.Config{}),
		},
		Outbound: []*core.OutboundHandlerConfig{
			{
				ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
			},
		},
	}

	v, err := core.New(config)
	common.Must(err)

	client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)

	{
		ips, err := client.LookupIP("example.com")
		if err != nil {
			t.Fatal("unexpected error: ", err)
		}

		if r := cmp.Diff(ips, []net.IP{{8, 8, 8, 8}}); r != "" {
			t.Fatal(r)
		}
	}

	dnsServer.Shutdown()
}

func TestIPMatch(t *testing.T) {
	port := udp.PickPort()

	dnsServer := dns.Server{
		Addr:    "127.0.0.1:" + port.String(),
		Net:     "udp",
		Handler: &staticHandler{},
		UDPSize: 1200,
	}

	go dnsServer.ListenAndServe()
	time.Sleep(time.Second)

	config := &core.Config{
		App: []*serial.TypedMessage{
			serial.ToTypedMessage(&Config{
				NameServer: []*NameServer{
					// private dns, not match
					{
						Address: &net.Endpoint{
							Network: net.Network_UDP,
							Address: &net.IPOrDomain{
								Address: &net.IPOrDomain_Ip{
									Ip: []byte{127, 0, 0, 1},
								},
							},
							Port: uint32(port),
						},
						Geoip: []*router.GeoIP{
							{
								CountryCode: "local",
								Cidr: []*router.CIDR{
									{
										// inner ip, will not match
										Ip:     []byte{192, 168, 11, 1},
										Prefix: 32,
									},
								},
							},
						},
					},
					// second dns, match ip
					{
						Address: &net.Endpoint{
							Network: net.Network_UDP,
							Address: &net.IPOrDomain{
								Address: &net.IPOrDomain_Ip{
									Ip: []byte{127, 0, 0, 1},
								},
							},
							Port: uint32(port),
						},
						Geoip: []*router.GeoIP{
							{
								CountryCode: "test",
								Cidr: []*router.CIDR{
									{
										Ip:     []byte{8, 8, 8, 8},
										Prefix: 32,
									},
								},
							},
							{
								CountryCode: "test",
								Cidr: []*router.CIDR{
									{
										Ip:     []byte{8, 8, 8, 4},
										Prefix: 32,
									},
								},
							},
						},
					},
				},
			}),
			serial.ToTypedMessage(&dispatcher.Config{}),
			serial.ToTypedMessage(&proxyman.OutboundConfig{}),
			serial.ToTypedMessage(&policy.Config{}),
		},
		Outbound: []*core.OutboundHandlerConfig{
			{
				ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
			},
		},
	}

	v, err := core.New(config)
	common.Must(err)

	client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)

	startTime := time.Now()

	{
		ips, err := client.LookupIP("google.com")
		if err != nil {
			t.Fatal("unexpected error: ", err)
		}

		if r := cmp.Diff(ips, []net.IP{{8, 8, 8, 8}}); r != "" {
			t.Fatal(r)
		}
	}

	endTime := time.Now()
	if startTime.After(endTime.Add(time.Second * 2)) {
		t.Error("DNS query doesn't finish in 2 seconds.")
	}
}

func TestLocalDomain(t *testing.T) {
	port := udp.PickPort()

	dnsServer := dns.Server{
		Addr:    "127.0.0.1:" + port.String(),
		Net:     "udp",
		Handler: &staticHandler{},
		UDPSize: 1200,
	}

	go dnsServer.ListenAndServe()
	time.Sleep(time.Second)

	config := &core.Config{
		App: []*serial.TypedMessage{
			serial.ToTypedMessage(&Config{
				NameServers: []*net.Endpoint{
					{
						Network: net.Network_UDP,
						Address: &net.IPOrDomain{
							Address: &net.IPOrDomain_Ip{
								Ip: []byte{127, 0, 0, 1},
							},
						},
						Port: 9999, /* unreachable */
					},
				},
				NameServer: []*NameServer{
					{
						Address: &net.Endpoint{
							Network: net.Network_UDP,
							Address: &net.IPOrDomain{
								Address: &net.IPOrDomain_Ip{
									Ip: []byte{127, 0, 0, 1},
								},
							},
							Port: uint32(port),
						},
						PrioritizedDomain: []*NameServer_PriorityDomain{
							// Equivalent of dotless:localhost
							{Type: DomainMatchingType_Regex, Domain: "^[^.]*localhost[^.]*$"},
						},
						Geoip: []*router.GeoIP{
							{ // Will match localhost, localhost-a and localhost-b,
								CountryCode: "local",
								Cidr: []*router.CIDR{
									{Ip: []byte{127, 0, 0, 2}, Prefix: 32},
									{Ip: []byte{127, 0, 0, 3}, Prefix: 32},
									{Ip: []byte{127, 0, 0, 4}, Prefix: 32},
								},
							},
						},
					},
					{
						Address: &net.Endpoint{
							Network: net.Network_UDP,
							Address: &net.IPOrDomain{
								Address: &net.IPOrDomain_Ip{
									Ip: []byte{127, 0, 0, 1},
								},
							},
							Port: uint32(port),
						},
						PrioritizedDomain: []*NameServer_PriorityDomain{
							// Equivalent of dotless: and domain:local
							{Type: DomainMatchingType_Regex, Domain: "^[^.]*$"},
							{Type: DomainMatchingType_Subdomain, Domain: "local"},
							{Type: DomainMatchingType_Subdomain, Domain: "localdomain"},
						},
					},
				},
				StaticHosts: []*Config_HostMapping{
					{
						Type:   DomainMatchingType_Full,
						Domain: "hostnamestatic",
						Ip:     [][]byte{{127, 0, 0, 53}},
					},
					{
						Type:          DomainMatchingType_Full,
						Domain:        "hostnamealias",
						ProxiedDomain: "hostname.localdomain",
					},
				},
			}),
			serial.ToTypedMessage(&dispatcher.Config{}),
			serial.ToTypedMessage(&proxyman.OutboundConfig{}),
			serial.ToTypedMessage(&policy.Config{}),
		},
		Outbound: []*core.OutboundHandlerConfig{
			{
				ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
			},
		},
	}

	v, err := core.New(config)
	common.Must(err)

	client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)

	startTime := time.Now()

	{ // Will match dotless:
		ips, err := client.LookupIP("hostname")
		if err != nil {
			t.Fatal("unexpected error: ", err)
		}

		if r := cmp.Diff(ips, []net.IP{{127, 0, 0, 1}}); r != "" {
			t.Fatal(r)
		}
	}

	{ // Will match domain:local
		ips, err := client.LookupIP("hostname.local")
		if err != nil {
			t.Fatal("unexpected error: ", err)
		}

		if r := cmp.Diff(ips, []net.IP{{127, 0, 0, 1}}); r != "" {
			t.Fatal(r)
		}
	}

	{ // Will match static ip
		ips, err := client.LookupIP("hostnamestatic")
		if err != nil {
			t.Fatal("unexpected error: ", err)
		}

		if r := cmp.Diff(ips, []net.IP{{127, 0, 0, 53}}); r != "" {
			t.Fatal(r)
		}
	}

	{ // Will match domain replacing
		ips, err := client.LookupIP("hostnamealias")
		if err != nil {
			t.Fatal("unexpected error: ", err)
		}

		if r := cmp.Diff(ips, []net.IP{{127, 0, 0, 1}}); r != "" {
			t.Fatal(r)
		}
	}

	{ // Will match dotless:localhost, but not expectIPs: 127.0.0.2, 127.0.0.3, then matches at dotless:
		ips, err := client.LookupIP("localhost")
		if err != nil {
			t.Fatal("unexpected error: ", err)
		}

		if r := cmp.Diff(ips, []net.IP{{127, 0, 0, 2}}); r != "" {
			t.Fatal(r)
		}
	}

	{ // Will match dotless:localhost, and expectIPs: 127.0.0.2, 127.0.0.3
		ips, err := client.LookupIP("localhost-a")
		if err != nil {
			t.Fatal("unexpected error: ", err)
		}

		if r := cmp.Diff(ips, []net.IP{{127, 0, 0, 3}}); r != "" {
			t.Fatal(r)
		}
	}

	{ // Will match dotless:localhost, and expectIPs: 127.0.0.2, 127.0.0.3
		ips, err := client.LookupIP("localhost-b")
		if err != nil {
			t.Fatal("unexpected error: ", err)
		}

		if r := cmp.Diff(ips, []net.IP{{127, 0, 0, 4}}); r != "" {
			t.Fatal(r)
		}
	}

	{ // Will match dotless:
		ips, err := client.LookupIP("Mijia Cloud")
		if err != nil {
			t.Fatal("unexpected error: ", err)
		}

		if r := cmp.Diff(ips, []net.IP{{127, 0, 0, 1}}); r != "" {
			t.Fatal(r)
		}
	}

	endTime := time.Now()
	if startTime.After(endTime.Add(time.Second * 2)) {
		t.Error("DNS query doesn't finish in 2 seconds.")
	}
}

func TestMultiMatchPrioritizedDomain(t *testing.T) {
	port := udp.PickPort()

	dnsServer := dns.Server{
		Addr:    "127.0.0.1:" + port.String(),
		Net:     "udp",
		Handler: &staticHandler{},
		UDPSize: 1200,
	}

	go dnsServer.ListenAndServe()
	time.Sleep(time.Second)

	config := &core.Config{
		App: []*serial.TypedMessage{
			serial.ToTypedMessage(&Config{
				NameServers: []*net.Endpoint{
					{
						Network: net.Network_UDP,
						Address: &net.IPOrDomain{
							Address: &net.IPOrDomain_Ip{
								Ip: []byte{127, 0, 0, 1},
							},
						},
						Port: 9999, /* unreachable */
					},
				},
				NameServer: []*NameServer{
					{
						Address: &net.Endpoint{
							Network: net.Network_UDP,
							Address: &net.IPOrDomain{
								Address: &net.IPOrDomain_Ip{
									Ip: []byte{127, 0, 0, 1},
								},
							},
							Port: uint32(port),
						},
						PrioritizedDomain: []*NameServer_PriorityDomain{
							{
								Type:   DomainMatchingType_Subdomain,
								Domain: "google.com",
							},
						},
						Geoip: []*router.GeoIP{
							{ // Will only match 8.8.8.8 and 8.8.4.4
								Cidr: []*router.CIDR{
									{Ip: []byte{8, 8, 8, 8}, Prefix: 32},
									{Ip: []byte{8, 8, 4, 4}, Prefix: 32},
								},
							},
						},
					},
					{
						Address: &net.Endpoint{
							Network: net.Network_UDP,
							Address: &net.IPOrDomain{
								Address: &net.IPOrDomain_Ip{
									Ip: []byte{127, 0, 0, 1},
								},
							},
							Port: uint32(port),
						},
						PrioritizedDomain: []*NameServer_PriorityDomain{
							{
								Type:   DomainMatchingType_Subdomain,
								Domain: "google.com",
							},
						},
						Geoip: []*router.GeoIP{
							{ // Will match 8.8.8.8 and 8.8.8.7, etc
								Cidr: []*router.CIDR{
									{Ip: []byte{8, 8, 8, 7}, Prefix: 24},
								},
							},
						},
					},
					{
						Address: &net.Endpoint{
							Network: net.Network_UDP,
							Address: &net.IPOrDomain{
								Address: &net.IPOrDomain_Ip{
									Ip: []byte{127, 0, 0, 1},
								},
							},
							Port: uint32(port),
						},
						PrioritizedDomain: []*NameServer_PriorityDomain{
							{
								Type:   DomainMatchingType_Subdomain,
								Domain: "api.google.com",
							},
						},
						Geoip: []*router.GeoIP{
							{ // Will only match 8.8.7.7 (api.google.com)
								Cidr: []*router.CIDR{
									{Ip: []byte{8, 8, 7, 7}, Prefix: 32},
								},
							},
						},
					},
					{
						Address: &net.Endpoint{
							Network: net.Network_UDP,
							Address: &net.IPOrDomain{
								Address: &net.IPOrDomain_Ip{
									Ip: []byte{127, 0, 0, 1},
								},
							},
							Port: uint32(port),
						},
						PrioritizedDomain: []*NameServer_PriorityDomain{
							{
								Type:   DomainMatchingType_Full,
								Domain: "v2.api.google.com",
							},
						},
						Geoip: []*router.GeoIP{
							{ // Will only match 8.8.7.8 (v2.api.google.com)
								Cidr: []*router.CIDR{
									{Ip: []byte{8, 8, 7, 8}, Prefix: 32},
								},
							},
						},
					},
				},
			}),
			serial.ToTypedMessage(&dispatcher.Config{}),
			serial.ToTypedMessage(&proxyman.OutboundConfig{}),
			serial.ToTypedMessage(&policy.Config{}),
		},
		Outbound: []*core.OutboundHandlerConfig{
			{
				ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
			},
		},
	}

	v, err := core.New(config)
	common.Must(err)

	client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)

	startTime := time.Now()

	{ // Will match server 1,2 and server 1 returns expected ip
		ips, err := client.LookupIP("google.com")
		if err != nil {
			t.Fatal("unexpected error: ", err)
		}

		if r := cmp.Diff(ips, []net.IP{{8, 8, 8, 8}}); r != "" {
			t.Fatal(r)
		}
	}

	{ // Will match server 1,2 and server 1 returns unexpected ip, then server 2 returns expected one
		clientv4 := client.(feature_dns.IPv4Lookup)
		ips, err := clientv4.LookupIPv4("ipv6.google.com")
		if err != nil {
			t.Fatal("unexpected error: ", err)
		}

		if r := cmp.Diff(ips, []net.IP{{8, 8, 8, 7}}); r != "" {
			t.Fatal(r)
		}
	}

	{ // Will match server 3,1,2 and server 3 returns expected one
		ips, err := client.LookupIP("api.google.com")
		if err != nil {
			t.Fatal("unexpected error: ", err)
		}

		if r := cmp.Diff(ips, []net.IP{{8, 8, 7, 7}}); r != "" {
			t.Fatal(r)
		}
	}

	{ // Will match server 4,3,1,2 and server 4 returns expected one
		ips, err := client.LookupIP("v2.api.google.com")
		if err != nil {
			t.Fatal("unexpected error: ", err)
		}

		if r := cmp.Diff(ips, []net.IP{{8, 8, 7, 8}}); r != "" {
			t.Fatal(r)
		}
	}

	endTime := time.Now()
	if startTime.After(endTime.Add(time.Second * 2)) {
		t.Error("DNS query doesn't finish in 2 seconds.")
	}
}


================================================
FILE: app/dns/udpns.go
================================================
// +build !confonly

package dns

import (
	"context"
	"strings"
	"sync"
	"sync/atomic"
	"time"

	"golang.org/x/net/dns/dnsmessage"
	"v2ray.com/core/common"
	"v2ray.com/core/common/net"
	"v2ray.com/core/common/protocol/dns"
	udp_proto "v2ray.com/core/common/protocol/udp"
	"v2ray.com/core/common/session"
	"v2ray.com/core/common/signal/pubsub"
	"v2ray.com/core/common/task"
	dns_feature "v2ray.com/core/features/dns"
	"v2ray.com/core/features/routing"
	"v2ray.com/core/transport/internet/udp"
)

type ClassicNameServer struct {
	sync.RWMutex
	name      string
	address   net.Destination
	ips       map[string]record
	requests  map[uint16]dnsRequest
	pub       *pubsub.Service
	udpServer *udp.Dispatcher
	cleanup   *task.Periodic
	reqID     uint32
	clientIP  net.IP
}

func NewClassicNameServer(address net.Destination, dispatcher routing.Dispatcher, clientIP net.IP) *ClassicNameServer {

	// default to 53 if unspecific
	if address.Port == 0 {
		address.Port = net.Port(53)
	}

	s := &ClassicNameServer{
		address:  address,
		ips:      make(map[string]record),
		requests: make(map[uint16]dnsRequest),
		clientIP: clientIP,
		pub:      pubsub.NewService(),
		name:     strings.ToUpper(address.String()),
	}
	s.cleanup = &task.Periodic{
		Interval: time.Minute,
		Execute:  s.Cleanup,
	}
	s.udpServer = udp.NewDispatcher(dispatcher, s.HandleResponse)
	newError("DNS: created udp client inited for ", address.NetAddr()).AtInfo().WriteToLog()
	return s
}

func (s *ClassicNameServer) Name() string {
	return s.name
}

func (s *ClassicNameServer) Cleanup() error {
	now := time.Now()
	s.Lock()
	defer s.Unlock()

	if len(s.ips) == 0 && len(s.requests) == 0 {
		return newError(s.name, " nothing to do. stopping...")
	}

	for domain, record := range s.ips {
		if record.A != nil && record.A.Expire.Before(now) {
			record.A = nil
		}
		if record.AAAA != nil && record.AAAA.Expire.Before(now) {
			record.AAAA = nil
		}

		if record.A == nil && record.AAAA == nil {
			delete(s.ips, domain)
		} else {
			s.ips[domain] = record
		}
	}

	if len(s.ips) == 0 {
		s.ips = make(map[string]record)
	}

	for id, req := range s.requests {
		if req.expire.Before(now) {
			delete(s.requests, id)
		}
	}

	if len(s.requests) == 0 {
		s.requests = make(map[uint16]dnsRequest)
	}

	return nil
}

func (s *ClassicNameServer) HandleResponse(ctx context.Context, packet *udp_proto.Packet) {

	ipRec, err := parseResponse(packet.Payload.Bytes())
	if err != nil {
		newError(s.name, " fail to parse responded DNS udp").AtError().WriteToLog()
		return
	}

	s.Lock()
	id := ipRec.ReqID
	req, ok := s.requests[id]
	if ok {
		// remove the pending request
		delete(s.requests, id)
	}
	s.Unlock()
	if !ok {
		newError(s.name, " cannot find the pending request").AtError().WriteToLog()
		return
	}

	var rec record
	switch req.reqType {
	case dnsmessage.TypeA:
		rec.A = ipRec
	case dnsmessage.TypeAAAA:
		rec.AAAA = ipRec
	}

	elapsed := time.Since(req.start)
	newError(s.name, " got answer: ", req.domain, " ", req.reqType, " -> ", ipRec.IP, " ", elapsed).AtInfo().WriteToLog()
	if len(req.domain) > 0 && (rec.A != nil || rec.AAAA != nil) {
		s.updateIP(req.domain, rec)
	}
}

func (s *ClassicNameServer) updateIP(domain string, newRec record) {
	s.Lock()

	newError(s.name, " updating IP records for domain:", domain).AtDebug().WriteToLog()
	rec := s.ips[domain]

	updated := false
	if isNewer(rec.A, newRec.A) {
		rec.A = newRec.A
		updated = true
	}
	if isNewer(rec.AAAA, newRec.AAAA) {
		rec.AAAA = newRec.AAAA
		updated = true
	}

	if updated {
		s.ips[domain] = rec
	}
	if newRec.A != nil {
		s.pub.Publish(domain+"4", nil)
	}
	if newRec.AAAA != nil {
		s.pub.Publish(domain+"6", nil)
	}
	s.Unlock()
	common.Must(s.cleanup.Start())
}

func (s *ClassicNameServer) newReqID() uint16 {
	return uint16(atomic.AddUint32(&s.reqID, 1))
}

func (s *ClassicNameServer) addPendingRequest(req *dnsRequest) {
	s.Lock()
	defer s.Unlock()

	id := req.msg.ID
	req.expire = time.Now().Add(time.Second * 8)
	s.requests[id] = *req
}

func (s *ClassicNameServer) sendQuery(ctx context.Context, domain string, option IPOption) {
	newError(s.name, " querying DNS for: ", domain).AtDebug().WriteToLog(session.ExportIDToError(ctx))

	reqs := buildReqMsgs(domain, option, s.newReqID, genEDNS0Options(s.clientIP))

	for _, req := range reqs {
		s.addPendingRequest(req)
		b, _ := dns.PackMessage(req.msg)
		udpCtx := context.Background()
		if inbound := session.InboundFromContext(ctx); inbound != nil {
			udpCtx = session.ContextWithInbound(udpCtx, inbound)
		}
		udpCtx = session.ContextWithContent(udpCtx, &session.Content{
			Protocol: "dns",
		})
		s.udpServer.Dispatch(udpCtx, s.address, b)
	}
}

func (s *ClassicNameServer) findIPsForDomain(domain string, option IPOption) ([]net.IP, error) {
	s.RLock()
	record, found := s.ips[domain]
	s.RUnlock()

	if !found {
		return nil, errRecordNotFound
	}

	var ips []net.Address
	var lastErr error
	if option.IPv4Enable {
		a, err := record.A.getIPs()
		if err != nil {
			lastErr = err
		}
		ips = append(ips, a...)
	}

	if option.IPv6Enable {
		aaaa, err := record.AAAA.getIPs()
		if err != nil {
			lastErr = err
		}
		ips = append(ips, aaaa...)
	}

	if len(ips) > 0 {
		return toNetIP(ips), nil
	}

	if lastErr != nil {
		return nil, lastErr
	}

	return nil, dns_feature.ErrEmptyResponse
}

func (s *ClassicNameServer) QueryIP(ctx context.Context, domain string, option IPOption) ([]net.IP, error) {

	fqdn := Fqdn(domain)

	ips, err := s.findIPsForDomain(fqdn, option)
	if err != errRecordNotFound {
		newError(s.name, " cache HIT ", domain, " -> ", ips).Base(err).AtDebug().WriteToLog()
		return ips, err
	}

	// ipv4 and ipv6 belong to different subscription groups
	var sub4, sub6 *pubsub.Subscriber
	if option.IPv4Enable {
		sub4 = s.pub.Subscribe(fqdn + "4")
		defer sub4.Close()
	}
	if option.IPv6Enable {
		sub6 = s.pub.Subscribe(fqdn + "6")
		defer sub6.Close()
	}
	done := make(chan interface{})
	go func() {
		if sub4 != nil {
			select {
			case <-sub4.Wait():
			case <-ctx.Done():
			}
		}
		if sub6 != nil {
			select {
			case <-sub6.Wait():
			case <-ctx.Done():
			}
		}
		close(done)
	}()
	s.sendQuery(ctx, fqdn, option)

	for {
		ips, err := s.findIPsForDomain(fqdn, option)
		if err != errRecordNotFound {
			return ips, err
		}

		select {
		case <-ctx.Done():
			return nil, ctx.Err()
		case <-done:
		}
	}
}


================================================
FILE: app/log/command/command.go
================================================
// +build !confonly

package command

//go:generate go run v2ray.com/core/common/errors/errorgen

import (
	"context"

	grpc "google.golang.org/grpc"

	"v2ray.com/core"
	"v2ray.com/core/app/log"
	"v2ray.com/core/common"
)

type LoggerServer struct {
	V *core.Instance
}

// RestartLogger implements LoggerService.
func (s *LoggerServer) RestartLogger(ctx context.Context, request *RestartLoggerRequest) (*RestartLoggerResponse, error) {
	logger := s.V.GetFeature((*log.Instance)(nil))
	if logger == nil {
		return nil, newError("unable to get logger instance")
	}
	if err := logger.Close(); err != nil {
		return nil, newError("failed to close logger").Base(err)
	}
	if err := logger.Start(); err != nil {
		return nil, newError("failed to start logger").Base(err)
	}
	return &RestartLoggerResponse{}, nil
}

func (s *LoggerServer) mustEmbedUnimplementedLoggerServiceServer() {}

type service struct {
	v *core.Instance
}

func (s *service) Register(server *grpc.Server) {
	RegisterLoggerServiceServer(server, &LoggerServer{
		V: s.v,
	})
}

func init() {
	common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, cfg interface{}) (interface{}, error) {
		s := core.MustFromContext(ctx)
		return &service{v: s}, nil
	}))
}


================================================
FILE: app/log/command/command_test.go
================================================
package command_test

import (
	"context"
	"testing"

	"v2ray.com/core"
	"v2ray.com/core/app/dispatcher"
	"v2ray.com/core/app/log"
	. "v2ray.com/core/app/log/command"
	"v2ray.com/core/app/proxyman"
	_ "v2ray.com/core/app/proxyman/inbound"
	_ "v2ray.com/core/app/proxyman/outbound"
	"v2ray.com/core/common"
	"v2ray.com/core/common/serial"
)

func TestLoggerRestart(t *testing.T) {
	v, err := core.New(&core.Config{
		App: []*serial.TypedMessage{
			serial.ToTypedMessage(&log.Config{}),
			serial.ToTypedMessage(&dispatcher.Config{}),
			serial.ToTypedMessage(&proxyman.InboundConfig{}),
			serial.ToTypedMessage(&proxyman.OutboundConfig{}),
		},
	})
	common.Must(err)
	common.Must(v.Start())

	server := &LoggerServer{
		V: v,
	}
	common.Must2(server.RestartLogger(context.Background(), &RestartLoggerRequest{}))
}


================================================
FILE: app/log/command/config.pb.go
================================================
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// 	protoc-gen-go v1.25.0
// 	protoc        v3.13.0
// source: app/log/command/config.proto

package command

import (
	proto "github.com/golang/protobuf/proto"
	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
	reflect "reflect"
	sync "sync"
)

const (
	// Verify that this generated code is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
	// Verify that runtime/protoimpl is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)

// This is a compile-time assertion that a sufficiently up-to-date version
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4

type Config struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields
}

func (x *Config) Reset() {
	*x = Config{}
	if protoimpl.UnsafeEnabled {
		mi := &file_app_log_command_config_proto_msgTypes[0]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *Config) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*Config) ProtoMessage() {}

func (x *Config) ProtoReflect() protoreflect.Message {
	mi := &file_app_log_command_config_proto_msgTypes[0]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use Config.ProtoReflect.Descriptor instead.
func (*Config) Descriptor() ([]byte, []int) {
	return file_app_log_command_config_proto_rawDescGZIP(), []int{0}
}

type RestartLoggerRequest struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields
}

func (x *RestartLoggerRequest) Reset() {
	*x = RestartLoggerRequest{}
	if protoimpl.UnsafeEnabled {
		mi := &file_app_log_command_config_proto_msgTypes[1]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *RestartLoggerRequest) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*RestartLoggerRequest) ProtoMessage() {}

func (x *RestartLoggerRequest) ProtoReflect() protoreflect.Message {
	mi := &file_app_log_command_config_proto_msgTypes[1]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use RestartLoggerRequest.ProtoReflect.Descriptor instead.
func (*RestartLoggerRequest) Descriptor() ([]byte, []int) {
	return file_app_log_command_config_proto_rawDescGZIP(), []int{1}
}

type RestartLoggerResponse struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields
}

func (x *RestartLoggerResponse) Reset() {
	*x = RestartLoggerResponse{}
	if protoimpl.UnsafeEnabled {
		mi := &file_app_log_command_config_proto_msgTypes[2]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *RestartLoggerResponse) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*RestartLoggerResponse) ProtoMessage() {}

func (x *RestartLoggerResponse) ProtoReflect() protoreflect.Message {
	mi := &file_app_log_command_config_proto_msgTypes[2]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use RestartLoggerResponse.ProtoReflect.Descriptor instead.
func (*RestartLoggerResponse) Descriptor() ([]byte, []int) {
	return file_app_log_command_config_proto_rawDescGZIP(), []int{2}
}

var File_app_log_command_config_proto protoreflect.FileDescriptor

var file_app_log_command_config_proto_rawDesc = []byte{
	0x0a, 0x1c, 0x61, 0x70, 0x70, 0x2f, 0x6c, 0x6f, 0x67, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e,
	0x64, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1a,
	0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x6c,
	0x6f, 0x67, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x22, 0x08, 0x0a, 0x06, 0x43, 0x6f,
	0x6e, 0x66, 0x69, 0x67, 0x22, 0x16, 0x0a, 0x14, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4c,
	0x6f, 0x67, 0x67, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x17, 0x0a, 0x15,
	0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4c, 0x6f, 0x67, 0x67, 0x65, 0x72, 0x52, 0x65, 0x73,
	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x87, 0x01, 0x0a, 0x0d, 0x4c, 0x6f, 0x67, 0x67, 0x65, 0x72,
	0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x76, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x74, 0x61,
	0x72, 0x74, 0x4c, 0x6f, 0x67, 0x67, 0x65, 0x72, 0x12, 0x30, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79,
	0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x6c, 0x6f, 0x67, 0x2e, 0x63, 0x6f,
	0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4c, 0x6f, 0x67,
	0x67, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x76, 0x32, 0x72,
	0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x6c, 0x6f, 0x67, 0x2e,
	0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4c,
	0x6f, 0x67, 0x67, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42,
	0x5f, 0x0a, 0x1e, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72,
	0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x6c, 0x6f, 0x67, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e,
	0x64, 0x50, 0x01, 0x5a, 0x1e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63,
	0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x6c, 0x6f, 0x67, 0x2f, 0x63, 0x6f, 0x6d, 0x6d,
	0x61, 0x6e, 0x64, 0xaa, 0x02, 0x1a, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65,
	0x2e, 0x41, 0x70, 0x70, 0x2e, 0x4c, 0x6f, 0x67, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64,
	0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}

var (
	file_app_log_command_config_proto_rawDescOnce sync.Once
	file_app_log_command_config_proto_rawDescData = file_app_log_command_config_proto_rawDesc
)

func file_app_log_command_config_proto_rawDescGZIP() []byte {
	file_app_log_command_config_proto_rawDescOnce.Do(func() {
		file_app_log_command_config_proto_rawDescData = protoimpl.X.CompressGZIP(file_app_log_command_config_proto_rawDescData)
	})
	return file_app_log_command_config_proto_rawDescData
}

var file_app_log_command_config_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
var file_app_log_command_config_proto_goTypes = []interface{}{
	(*Config)(nil),                // 0: v2ray.core.app.log.command.Config
	(*RestartLoggerRequest)(nil),  // 1: v2ray.core.app.log.command.RestartLoggerRequest
	(*RestartLoggerResponse)(nil), // 2: v2ray.core.app.log.command.RestartLoggerResponse
}
var file_app_log_command_config_proto_depIdxs = []int32{
	1, // 0: v2ray.core.app.log.command.LoggerService.RestartLogger:input_type -> v2ray.core.app.log.command.RestartLoggerRequest
	2, // 1: v2ray.core.app.log.command.LoggerService.RestartLogger:output_type -> v2ray.core.app.log.command.RestartLoggerResponse
	1, // [1:2] is the sub-list for method output_type
	0, // [0:1] is the sub-list for method input_type
	0, // [0:0] is the sub-list for extension type_name
	0, // [0:0] is the sub-list for extension extendee
	0, // [0:0] is the sub-list for field type_name
}

func init() { file_app_log_command_config_proto_init() }
func file_app_log_command_config_proto_init() {
	if File_app_log_command_config_proto != nil {
		return
	}
	if !protoimpl.UnsafeEnabled {
		file_app_log_command_config_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*Config); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_app_log_command_config_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*RestartLoggerRequest); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_app_log_command_config_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*RestartLoggerResponse); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
	}
	type x struct{}
	out := protoimpl.TypeBuilder{
		File: protoimpl.DescBuilder{
			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
			RawDescriptor: file_app_log_command_config_proto_rawDesc,
			NumEnums:      0,
			NumMessages:   3,
			NumExtensions: 0,
			NumServices:   1,
		},
		GoTypes:           file_app_log_command_config_proto_goTypes,
		DependencyIndexes: file_app_log_command_config_proto_depIdxs,
		MessageInfos:      file_app_log_command_config_proto_msgTypes,
	}.Build()
	File_app_log_command_config_proto = out.File
	file_app_log_command_config_proto_rawDesc = nil
	file_app_log_command_config_proto_goTypes = nil
	file_app_log_command_config_proto_depIdxs = nil
}


================================================
FILE: app/log/command/config.proto
================================================
syntax = "proto3";

package v2ray.core.app.log.command;
option csharp_namespace = "V2Ray.Core.App.Log.Command";
option go_package = "v2ray.com/core/app/log/command";
option java_package = "com.v2ray.core.app.log.command";
option java_multiple_files = true;

message Config {}

message RestartLoggerRequest {}

message RestartLoggerResponse {}

service LoggerService {
  rpc RestartLogger(RestartLoggerRequest) returns (RestartLoggerResponse) {}
}


================================================
FILE: app/log/command/config_grpc.pb.go
================================================
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.

package command

import (
	context "context"
	grpc "google.golang.org/grpc"
	codes "google.golang.org/grpc/codes"
	status "google.golang.org/grpc/status"
)

// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion7

// LoggerServiceClient is the client API for LoggerService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type LoggerServiceClient interface {
	RestartLogger(ctx context.Context, in *RestartLoggerRequest, opts ...grpc.CallOption) (*RestartLoggerResponse, error)
}

type loggerServiceClient struct {
	cc grpc.ClientConnInterface
}

func NewLoggerServiceClient(cc grpc.ClientConnInterface) LoggerServiceClient {
	return &loggerServiceClient{cc}
}

func (c *loggerServiceClient) RestartLogger(ctx context.Context, in *RestartLoggerRequest, opts ...grpc.CallOption) (*RestartLoggerResponse, error) {
	out := new(RestartLoggerResponse)
	err := c.cc.Invoke(ctx, "/v2ray.core.app.log.command.LoggerService/RestartLogger", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// LoggerServiceServer is the server API for LoggerService service.
// All implementations must embed UnimplementedLoggerServiceServer
// for forward compatibility
type LoggerServiceServer interface {
	RestartLogger(context.Context, *RestartLoggerRequest) (*RestartLoggerResponse, error)
	mustEmbedUnimplementedLoggerServiceServer()
}

// UnimplementedLoggerServiceServer must be embedded to have forward compatible implementations.
type UnimplementedLoggerServiceServer struct {
}

func (UnimplementedLoggerServiceServer) RestartLogger(context.Context, *RestartLoggerRequest) (*RestartLoggerResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method RestartLogger not implemented")
}
func (UnimplementedLoggerServiceServer) mustEmbedUnimplementedLoggerServiceServer() {}

// UnsafeLoggerServiceServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to LoggerServiceServer will
// result in compilation errors.
type UnsafeLoggerServiceServer interface {
	mustEmbedUnimplementedLoggerServiceServer()
}

func RegisterLoggerServiceServer(s *grpc.Server, srv LoggerServiceServer) {
	s.RegisterService(&_LoggerService_serviceDesc, srv)
}

func _LoggerService_RestartLogger_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(RestartLoggerRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(LoggerServiceServer).RestartLogger(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/v2ray.core.app.log.command.LoggerService/RestartLogger",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(LoggerServiceServer).RestartLogger(ctx, req.(*RestartLoggerRequest))
	}
	return interceptor(ctx, in, info, handler)
}

var _LoggerService_serviceDesc = grpc.ServiceDesc{
	ServiceName: "v2ray.core.app.log.command.LoggerService",
	HandlerType: (*LoggerServiceServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "RestartLogger",
			Handler:    _LoggerService_RestartLogger_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "app/log/command/config.proto",
}


================================================
FILE: app/log/command/errors.generated.go
================================================
package command

import "v2ray.com/core/common/errors"

type errPathObjHolder struct{}

func newError(values ...interface{}) *errors.Error {
	return errors.New(values...).WithPathObj(errPathObjHolder{})
}


================================================
FILE: app/log/config.pb.go
================================================
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// 	protoc-gen-go v1.25.0
// 	protoc        v3.13.0
// source: app/log/config.proto

package log

import (
	proto "github.com/golang/protobuf/proto"
	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
	reflect "reflect"
	sync "sync"
	log "v2ray.com/core/common/log"
)

const (
	// Verify that this generated code is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
	// Verify that runtime/protoimpl is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)

// This is a compile-time assertion that a sufficiently up-to-date version
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4

type LogType int32

const (
	LogType_None    LogType = 0
	LogType_Console LogType = 1
	LogType_File    LogType = 2
	LogType_Event   LogType = 3
)

// Enum value maps for LogType.
var (
	LogType_name = map[int32]string{
		0: "None",
		1: "Console",
		2: "File",
		3: "Event",
	}
	LogType_value = map[string]int32{
		"None":    0,
		"Console": 1,
		"File":    2,
		"Event":   3,
	}
)

func (x LogType) Enum() *LogType {
	p := new(LogType)
	*p = x
	return p
}

func (x LogType) String() string {
	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}

func (LogType) Descriptor() protoreflect.EnumDescriptor {
	return file_app_log_config_proto_enumTypes[0].Descriptor()
}

func (LogType) Type() protoreflect.EnumType {
	return &file_app_log_config_proto_enumTypes[0]
}

func (x LogType) Number() protoreflect.EnumNumber {
	return protoreflect.EnumNumber(x)
}

// Deprecated: Use LogType.Descriptor instead.
func (LogType) EnumDescriptor() ([]byte, []int) {
	return file_app_log_config_proto_rawDescGZIP(), []int{0}
}

type Config struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	ErrorLogType  LogType      `protobuf:"varint,1,opt,name=error_log_type,json=errorLogType,proto3,enum=v2ray.core.app.log.LogType" json:"error_log_type,omitempty"`
	ErrorLogLevel log.Severity `protobuf:"varint,2,opt,name=error_log_level,json=errorLogLevel,proto3,enum=v2ray.core.common.log.Severity" json:"error_log_level,omitempty"`
	ErrorLogPath  string       `protobuf:"bytes,3,opt,name=error_log_path,json=errorLogPath,proto3" json:"error_log_path,omitempty"`
	AccessLogType LogType      `protobuf:"varint,4,opt,name=access_log_type,json=accessLogType,proto3,enum=v2ray.core.app.log.LogType" json:"access_log_type,omitempty"`
	AccessLogPath string       `protobuf:"bytes,5,opt,name=access_log_path,json=accessLogPath,proto3" json:"access_log_path,omitempty"`
}

func (x *Config) Reset() {
	*x = Config{}
	if protoimpl.UnsafeEnabled {
		mi := &file_app_log_config_proto_msgTypes[0]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *Config) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*Config) ProtoMessage() {}

func (x *Config) ProtoReflect() protoreflect.Message {
	mi := &file_app_log_config_proto_msgTypes[0]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use Config.ProtoReflect.Descriptor instead.
func (*Config) Descriptor() ([]byte, []int) {
	return file_app_log_config_proto_rawDescGZIP(), []int{0}
}

func (x *Config) GetErrorLogType() LogType {
	if x != nil {
		return x.ErrorLogType
	}
	return LogType_None
}

func (x *Config) GetErrorLogLevel() log.Severity {
	if x != nil {
		return x.ErrorLogLevel
	}
	return log.Severity_Unknown
}

func (x *Config) GetErrorLogPath() string {
	if x != nil {
		return x.ErrorLogPath
	}
	return ""
}

func (x *Config) GetAccessLogType() LogType {
	if x != nil {
		return x.AccessLogType
	}
	return LogType_None
}

func (x *Config) GetAccessLogPath() string {
	if x != nil {
		return x.AccessLogPath
	}
	return ""
}

var File_app_log_config_proto protoreflect.FileDescriptor

var file_app_log_config_proto_rawDesc = []byte{
	0x0a, 0x14, 0x61, 0x70, 0x70, 0x2f, 0x6c, 0x6f, 0x67, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f,
	0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x6c, 0x6f, 0x67, 0x1a, 0x14, 0x63, 0x6f, 0x6d, 0x6d,
	0x6f, 0x6e, 0x2f, 0x6c, 0x6f, 0x67, 0x2f, 0x6c, 0x6f, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
	0x22, 0xa7, 0x02, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x41, 0x0a, 0x0e, 0x65,
	0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6c, 0x6f, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20,
	0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65,
	0x2e, 0x61, 0x70, 0x70, 0x2e, 0x6c, 0x6f, 0x67, 0x2e, 0x4c, 0x6f, 0x67, 0x54, 0x79, 0x70, 0x65,
	0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4c, 0x6f, 0x67, 0x54, 0x79, 0x70, 0x65, 0x12, 0x47,
	0x0a, 0x0f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6c, 0x6f, 0x67, 0x5f, 0x6c, 0x65, 0x76, 0x65,
	0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e,
	0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6c, 0x6f, 0x67, 0x2e,
	0x53, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x52, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4c,
	0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x24, 0x0a, 0x0e, 0x65, 0x72, 0x72, 0x6f, 0x72,
	0x5f, 0x6c, 0x6f, 0x67, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
	0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4c, 0x6f, 0x67, 0x50, 0x61, 0x74, 0x68, 0x12, 0x43, 0x0a,
	0x0f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x6f, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65,
	0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63,
	0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x6c, 0x6f, 0x67, 0x2e, 0x4c, 0x6f, 0x67, 0x54,
	0x79, 0x70, 0x65, 0x52, 0x0d, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x67, 0x54, 0x79,
	0x70, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x6f, 0x67,
	0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x61, 0x63, 0x63,
	0x65, 0x73, 0x73, 0x4c, 0x6f, 0x67, 0x50, 0x61, 0x74, 0x68, 0x2a, 0x35, 0x0a, 0x07, 0x4c, 0x6f,
	0x67, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x6f, 0x6e, 0x65, 0x10, 0x00, 0x12,
	0x0b, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04,
	0x46, 0x69, 0x6c, 0x65, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x10,
	0x03, 0x42, 0x47, 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63,
	0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x6c, 0x6f, 0x67, 0x50, 0x01, 0x5a, 0x16, 0x76,
	0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70,
	0x70, 0x2f, 0x6c, 0x6f, 0x67, 0xaa, 0x02, 0x12, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f,
	0x72, 0x65, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x4c, 0x6f, 0x67, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
	0x6f, 0x33,
}

var (
	file_app_log_config_proto_rawDescOnce sync.Once
	file_app_log_config_proto_rawDescData = file_app_log_config_proto_rawDesc
)

func file_app_log_config_proto_rawDescGZIP() []byte {
	file_app_log_config_proto_rawDescOnce.Do(func() {
		file_app_log_config_proto_rawDescData = protoimpl.X.CompressGZIP(file_app_log_config_proto_rawDescData)
	})
	return file_app_log_config_proto_rawDescData
}

var file_app_log_config_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_app_log_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_app_log_config_proto_goTypes = []interface{}{
	(LogType)(0),      // 0: v2ray.core.app.log.LogType
	(*Config)(nil),    // 1: v2ray.core.app.log.Config
	(log.Severity)(0), // 2: v2ray.core.common.log.Severity
}
var file_app_log_config_proto_depIdxs = []int32{
	0, // 0: v2ray.core.app.log.Config.error_log_type:type_name -> v2ray.core.app.log.LogType
	2, // 1: v2ray.core.app.log.Config.error_log_level:type_name -> v2ray.core.common.log.Severity
	0, // 2: v2ray.core.app.log.Config.access_log_type:type_name -> v2ray.core.app.log.LogType
	3, // [3:3] is the sub-list for method output_type
	3, // [3:3] is the sub-list for method input_type
	3, // [3:3] is the sub-list for extension type_name
	3, // [3:3] is the sub-list for extension extendee
	0, // [0:3] is the sub-list for field type_name
}

func init() { file_app_log_config_proto_init() }
func file_app_log_config_proto_init() {
	if File_app_log_config_proto != nil {
		return
	}
	if !protoimpl.UnsafeEnabled {
		file_app_log_config_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*Config); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
	}
	type x struct{}
	out := protoimpl.TypeBuilder{
		File: protoimpl.DescBuilder{
			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
			RawDescriptor: file_app_log_config_proto_rawDesc,
			NumEnums:      1,
			NumMessages:   1,
			NumExtensions: 0,
			NumServices:   0,
		},
		GoTypes:           file_app_log_config_proto_goTypes,
		DependencyIndexes: file_app_log_config_proto_depIdxs,
		EnumInfos:         file_app_log_config_proto_enumTypes,
		MessageInfos:      file_app_log_config_proto_msgTypes,
	}.Build()
	File_app_log_config_proto = out.File
	file_app_log_config_proto_rawDesc = nil
	file_app_log_config_proto_goTypes = nil
	file_app_log_config_proto_depIdxs = nil
}


================================================
FILE: app/log/config.proto
================================================
syntax = "proto3";

package v2ray.core.app.log;
option csharp_namespace = "V2Ray.Core.App.Log";
option go_package = "v2ray.com/core/app/log";
option java_package = "com.v2ray.core.app.log";
option java_multiple_files = true;

import "common/log/log.proto";

enum LogType {
  None = 0;
  Console = 1;
  File = 2;
  Event = 3;
}

message Config {
  LogType error_log_type = 1;
  v2ray.core.common.log.Severity error_log_level = 2;
  string error_log_path = 3;

  LogType access_log_type = 4;
  string access_log_path = 5;
}


================================================
FILE: app/log/errors.generated.go
================================================
package log

import "v2ray.com/core/common/errors"

type errPathObjHolder struct{}

func newError(values ...interface{}) *errors.Error {
	return errors.New(values...).WithPathObj(errPathObjHolder{})
}


================================================
FILE: app/log/log.go
================================================
// +build !confonly

package log

//go:generate go run v2ray.com/core/common/errors/errorgen

import (
	"context"
	"sync"

	"v2ray.com/core/common"
	"v2ray.com/core/common/log"
)

// Instance is a log.Handler that handles logs.
type Instance struct {
	sync.RWMutex
	config       *Config
	accessLogger log.Handler
	errorLogger  log.Handler
	active       bool
}

// New creates a new log.Instance based on the given config.
func New(ctx context.Context, config *Config) (*Instance, error) {
	g := &Instance{
		config: config,
		active: false,
	}
	log.RegisterHandler(g)

	// start logger instantly on inited
	// other modules would log during init
	if err := g.startInternal(); err != nil {
		return nil, err
	}

	newError("Logger started").AtDebug().WriteToLog()
	return g, nil
}

func (g *Instance) initAccessLogger() error {
	handler, err := createHandler(g.config.AccessLogType, HandlerCreatorOptions{
		Path: g.config.AccessLogPath,
	})
	if err != nil {
		return err
	}
	g.accessLogger = handler
	return nil
}

func (g *Instance) initErrorLogger() error {
	handler, err := createHandler(g.config.ErrorLogType, HandlerCreatorOptions{
		Path: g.config.ErrorLogPath,
	})
	if err != nil {
		return err
	}
	g.errorLogger = handler
	return nil
}

// Type implements common.HasType.
func (*Instance) Type() interface{} {
	return (*Instance)(nil)
}

func (g *Instance) startInternal() error {
	g.Lock()
	defer g.Unlock()

	if g.active {
		return nil
	}

	g.active = true

	if err := g.initAccessLogger(); err != nil {
		return newError("failed to initialize access logger").Base(err).AtWarning()
	}
	if err := g.initErrorLogger(); err != nil {
		return newError("failed to initialize error logger").Base(err).AtWarning()
	}

	return nil
}

// Start implements common.Runnable.Start().
func (g *Instance) Start() error {
	return g.startInternal()
}

// Handle implements log.Handler.
func (g *Instance) Handle(msg log.Message) {
	g.RLock()
	defer g.RUnlock()

	if !g.active {
		return
	}

	switch msg := msg.(type) {
	case *log.AccessMessage:
		if g.accessLogger != nil {
			g.accessLogger.Handle(msg)
		}
	case *log.GeneralMessage:
		if g.errorLogger != nil && msg.Severity <= g.config.ErrorLogLevel {
			g.errorLogger.Handle(msg)
		}
	default:
		// Swallow
	}
}

// Close implements common.Closable.Close().
func (g *Instance) Close() error {
	newError("Logger closing").AtDebug().WriteToLog()

	g.Lock()
	defer g.Unlock()

	if !g.active {
		return nil
	}

	g.active = false

	common.Close(g.accessLogger) // nolint: errcheck
	g.accessLogger = nil

	common.Close(g.errorLogger) // nolint: errcheck
	g.errorLogger = nil

	return nil
}

func init() {
	common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
		return New(ctx, config.(*Config))
	}))
}


================================================
FILE: app/log/log_creator.go
================================================
// +build !confonly

package log

import (
	"v2ray.com/core/common"
	"v2ray.com/core/common/log"
)

type HandlerCreatorOptions struct {
	Path string
}

type HandlerCreator func(LogType, HandlerCreatorOptions) (log.Handler, error)

var (
	handlerCreatorMap = make(map[LogType]HandlerCreator)
)

func RegisterHandlerCreator(logType LogType, f HandlerCreator) error {
	if f == nil {
		return newError("nil HandlerCreator")
	}

	handlerCreatorMap[logType] = f
	return nil
}

func createHandler(logType LogType, options HandlerCreatorOptions) (log.Handler, error) {
	creator, found := handlerCreatorMap[logType]
	if !found {
		return nil, newError("unable to create log handler for ", logType)
	}
	return creator(logType, options)
}

func init() {
	common.Must(RegisterHandlerCreator(LogType_Console, func(lt LogType, options HandlerCreatorOptions) (log.Handler, error) {
		return log.NewLogger(log.CreateStdoutLogWriter()), nil
	}))

	common.Must(RegisterHandlerCreator(LogType_File, func(lt LogType, options HandlerCreatorOptions) (log.Handler, error) {
		creator, err := log.CreateFileLogWriter(options.Path)
		if err != nil {
			return nil, err
		}
		return log.NewLogger(creator), nil
	}))

	common.Must(RegisterHandlerCreator(LogType_None, func(lt LogType, options HandlerCreatorOptions) (log.Handler, error) {
		return nil, nil
	}))
}


================================================
FILE: app/log/log_test.go
================================================
package log_test

import (
	"context"
	"testing"

	"github.com/golang/mock/gomock"
	"v2ray.com/core/app/log"
	"v2ray.com/core/common"
	clog "v2ray.com/core/common/log"
	"v2ray.com/core/testing/mocks"
)

func TestCustomLogHandler(t *testing.T) {
	mockCtl := gomock.NewController(t)
	defer mockCtl.Finish()

	var loggedValue []string

	mockHandler := mocks.NewLogHandler(mockCtl)
	mockHandler.EXPECT().Handle(gomock.Any()).AnyTimes().DoAndReturn(func(msg clog.Message) {
		loggedValue = append(loggedValue, msg.String())
	})

	log.RegisterHandlerCreator(log.LogType_Console, func(lt log.LogType, options log.HandlerCreatorOptions) (clog.Handler, error) {
		return mockHandler, nil
	})

	logger, err := log.New(context.Background(), &log.Config{
		ErrorLogLevel: clog.Severity_Debug,
		ErrorLogType:  log.LogType_Console,
		AccessLogType: log.LogType_None,
	})
	common.Must(err)

	common.Must(logger.Start())

	clog.Record(&clog.GeneralMessage{
		Severity: clog.Severity_Debug,
		Content:  "test",
	})

	if len(loggedValue) < 2 {
		t.Fatal("expected 2 log messages, but actually ", loggedValue)
	}

	if loggedValue[1] != "[Debug] test" {
		t.Fatal("expected '[Debug] test', but actually ", loggedValue[1])
	}

	common.Must(logger.Close())
}


================================================
FILE: app/policy/config.go
================================================
package policy

import (
	"time"

	"v2ray.com/core/features/policy"
)

// Duration converts Second to time.Duration.
func (s *Second) Duration() time.Duration {
	if s == nil {
		return 0
	}
	return time.Second * time.Duration(s.Value)
}

func defaultPolicy() *Policy {
	p := policy.SessionDefault()

	return &Policy{
		Timeout: &Policy_Timeout{
			Handshake:      &Second{Value: uint32(p.Timeouts.Handshake / time.Second)},
			ConnectionIdle: &Second{Value: uint32(p.Timeouts.ConnectionIdle / time.Second)},
			UplinkOnly:     &Second{Value: uint32(p.Timeouts.UplinkOnly / time.Second)},
			DownlinkOnly:   &Second{Value: uint32(p.Timeouts.DownlinkOnly / time.Second)},
		},
		Buffer: &Policy_Buffer{
			Connection: p.Buffer.PerConnection,
		},
	}
}

func (p *Policy_Timeout) overrideWith(another *Policy_Timeout) {
	if another.Handshake != nil {
		p.Handshake = &Second{Value: another.Handshake.Value}
	}
	if another.ConnectionIdle != nil {
		p.ConnectionIdle = &Second{Value: another.ConnectionIdle.Value}
	}
	if another.UplinkOnly != nil {
		p.UplinkOnly = &Second{Value: another.UplinkOnly.Value}
	}
	if another.DownlinkOnly != nil {
		p.DownlinkOnly = &Second{Value: another.DownlinkOnly.Value}
	}
}

func (p *Policy) overrideWith(another *Policy) {
	if another.Timeout != nil {
		p.Timeout.overrideWith(another.Timeout)
	}
	if another.Stats != nil && p.Stats == nil {
		p.Stats = &Policy_Stats{}
		p.Stats = another.Stats
	}
	if another.Buffer != nil {
		p.Buffer = &Policy_Buffer{
			Connection: another.Buffer.Connection,
		}
	}
}

// ToCorePolicy converts this Policy to policy.Session.
func (p *Policy) ToCorePolicy() policy.Session {
	cp := policy.SessionDefault()

	if p.Timeout != nil {
		cp.Timeouts.ConnectionIdle = p.Timeout.ConnectionIdle.Duration()
		cp.Timeouts.Handshake = p.Timeout.Handshake.Duration()
		cp.Timeouts.DownlinkOnly = p.Timeout.DownlinkOnly.Duration()
		cp.Timeouts.UplinkOnly = p.Timeout.UplinkOnly.Duration()
	}
	if p.Stats != nil {
		cp.Stats.UserUplink = p.Stats.UserUplink
		cp.Stats.UserDownlink = p.Stats.UserDownlink
	}
	if p.Buffer != nil {
		cp.Buffer.PerConnection = p.Buffer.Connection
	}
	return cp
}

// ToCorePolicy converts this SystemPolicy to policy.System.
func (p *SystemPolicy) ToCorePolicy() policy.System {
	return policy.System{
		Stats: policy.SystemStats{
			InboundUplink:    p.Stats.InboundUplink,
			InboundDownlink:  p.Stats.InboundDownlink,
			OutboundUplink:   p.Stats.OutboundUplink,
			OutboundDownlink: p.Stats.OutboundDownlink,
		},
	}
}


================================================
FILE: app/policy/config.pb.go
================================================
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// 	protoc-gen-go v1.25.0
// 	protoc        v3.13.0
// source: app/policy/config.proto

package policy

import (
	proto "github.com/golang/protobuf/proto"
	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
	reflect "reflect"
	sync "sync"
)

const (
	// Verify that this generated code is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
	// Verify that runtime/protoimpl is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)

// This is a compile-time assertion that a sufficiently up-to-date version
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4

type Second struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Value uint32 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"`
}

func (x *Second) Reset() {
	*x = Second{}
	if protoimpl.UnsafeEnabled {
		mi := &file_app_policy_config_proto_msgTypes[0]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *Second) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*Second) ProtoMessage() {}

func (x *Second) ProtoReflect() protoreflect.Message {
	mi := &file_app_policy_config_proto_msgTypes[0]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use Second.ProtoReflect.Descriptor instead.
func (*Second) Descriptor() ([]byte, []int) {
	return file_app_policy_config_proto_rawDescGZIP(), []int{0}
}

func (x *Second) GetValue() uint32 {
	if x != nil {
		return x.Value
	}
	return 0
}

type Policy struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Timeout *Policy_Timeout `protobuf:"bytes,1,opt,name=timeout,proto3" json:"timeout,omitempty"`
	Stats   *Policy_Stats   `protobuf:"bytes,2,opt,name=stats,proto3" json:"stats,omitempty"`
	Buffer  *Policy_Buffer  `protobuf:"bytes,3,opt,name=buffer,proto3" json:"buffer,omitempty"`
}

func (x *Policy) Reset() {
	*x = Policy{}
	if protoimpl.UnsafeEnabled {
		mi := &file_app_policy_config_proto_msgTypes[1]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *Policy) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*Policy) ProtoMessage() {}

func (x *Policy) ProtoReflect() protoreflect.Message {
	mi := &file_app_policy_config_proto_msgTypes[1]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use Policy.ProtoReflect.Descriptor instead.
func (*Policy) Descriptor() ([]byte, []int) {
	return file_app_policy_config_proto_rawDescGZIP(), []int{1}
}

func (x *Policy) GetTimeout() *Policy_Timeout {
	if x != nil {
		return x.Timeout
	}
	return nil
}

func (x *Policy) GetStats() *Policy_Stats {
	if x != nil {
		return x.Stats
	}
	return nil
}

func (x *Policy) GetBuffer() *Policy_Buffer {
	if x != nil {
		return x.Buffer
	}
	return nil
}

type SystemPolicy struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Stats *SystemPolicy_Stats `protobuf:"bytes,1,opt,name=stats,proto3" json:"stats,omitempty"`
}

func (x *SystemPolicy) Reset() {
	*x = SystemPolicy{}
	if protoimpl.UnsafeEnabled {
		mi := &file_app_policy_config_proto_msgTypes[2]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *SystemPolicy) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*SystemPolicy) ProtoMessage() {}

func (x *SystemPolicy) ProtoReflect() protoreflect.Message {
	mi := &file_app_policy_config_proto_msgTypes[2]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use SystemPolicy.ProtoReflect.Descriptor instead.
func (*SystemPolicy) Descriptor() ([]byte, []int) {
	return file_app_policy_config_proto_rawDescGZIP(), []int{2}
}

func (x *SystemPolicy) GetStats() *SystemPolicy_Stats {
	if x != nil {
		return x.Stats
	}
	return nil
}

type Config struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Level  map[uint32]*Policy `protobuf:"bytes,1,rep,name=level,proto3" json:"level,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
	System *SystemPolicy      `protobuf:"bytes,2,opt,name=system,proto3" json:"system,omitempty"`
}

func (x *Config) Reset() {
	*x = Config{}
	if protoimpl.UnsafeEnabled {
		mi := &file_app_policy_config_proto_msgTypes[3]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *Config) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*Config) ProtoMessage() {}

func (x *Config) ProtoReflect() protoreflect.Message {
	mi := &file_app_policy_config_proto_msgTypes[3]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use Config.ProtoReflect.Descriptor instead.
func (*Config) Descriptor() ([]byte, []int) {
	return file_app_policy_config_proto_rawDescGZIP(), []int{3}
}

func (x *Config) GetLevel() map[uint32]*Policy {
	if x != nil {
		return x.Level
	}
	return nil
}

func (x *Config) GetSystem() *SystemPolicy {
	if x != nil {
		return x.System
	}
	return nil
}

// Timeout is a message for timeout settings in various stages, in seconds.
type Policy_Timeout struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Handshake      *Second `protobuf:"bytes,1,opt,name=handshake,proto3" json:"handshake,omitempty"`
	ConnectionIdle *Second `protobuf:"bytes,2,opt,name=connection_idle,json=connectionIdle,proto3" json:"connection_idle,omitempty"`
	UplinkOnly     *Second `protobuf:"bytes,3,opt,name=uplink_only,json=uplinkOnly,proto3" json:"uplink_only,omitempty"`
	DownlinkOnly   *Second `protobuf:"bytes,4,opt,name=downlink_only,json=downlinkOnly,proto3" json:"downlink_only,omitempty"`
}

func (x *Policy_Timeout) Reset() {
	*x = Policy_Timeout{}
	if protoimpl.UnsafeEnabled {
		mi := &file_app_policy_config_proto_msgTypes[4]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *Policy_Timeout) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*Policy_Timeout) ProtoMessage() {}

func (x *
Download .txt
gitextract_4w26szfn/

├── .dev/
│   └── protoc/
│       ├── linux/
│       │   └── protoc
│       └── macos/
│           └── protoc
├── .github/
│   ├── CODE_OF_CONDUCT.md
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_cn.md
│   │   ├── bug_en.md
│   │   └── other_en.md
│   ├── ISSUE_TEMPLATE.md
│   ├── dependabot.yml
│   ├── linters/
│   │   └── .golangci.yml
│   ├── pull_request_template.md
│   └── workflows/
│       ├── codeql-analysis.yml
│       ├── coverage.yml
│       ├── linter.yml
│       ├── sign.yml
│       ├── stale.yml
│       ├── test.yml
│       └── updateGeofile.yml
├── .gitignore
├── Dockerfile
├── LICENSE
├── README.md
├── SECURITY.md
├── WORKSPACE
├── annotations.go
├── app/
│   ├── app.go
│   ├── commander/
│   │   ├── commander.go
│   │   ├── config.pb.go
│   │   ├── config.proto
│   │   ├── errors.generated.go
│   │   ├── outbound.go
│   │   └── service.go
│   ├── dispatcher/
│   │   ├── config.pb.go
│   │   ├── config.proto
│   │   ├── default.go
│   │   ├── dispatcher.go
│   │   ├── errors.generated.go
│   │   ├── sniffer.go
│   │   ├── stats.go
│   │   └── stats_test.go
│   ├── dns/
│   │   ├── config.pb.go
│   │   ├── config.proto
│   │   ├── dns.go
│   │   ├── dnscommon.go
│   │   ├── dnscommon_test.go
│   │   ├── dohdns.go
│   │   ├── errors.generated.go
│   │   ├── hosts.go
│   │   ├── hosts_test.go
│   │   ├── nameserver.go
│   │   ├── nameserver_test.go
│   │   ├── server.go
│   │   ├── server_test.go
│   │   └── udpns.go
│   ├── log/
│   │   ├── command/
│   │   │   ├── command.go
│   │   │   ├── command_test.go
│   │   │   ├── config.pb.go
│   │   │   ├── config.proto
│   │   │   ├── config_grpc.pb.go
│   │   │   └── errors.generated.go
│   │   ├── config.pb.go
│   │   ├── config.proto
│   │   ├── errors.generated.go
│   │   ├── log.go
│   │   ├── log_creator.go
│   │   └── log_test.go
│   ├── policy/
│   │   ├── config.go
│   │   ├── config.pb.go
│   │   ├── config.proto
│   │   ├── errors.generated.go
│   │   ├── manager.go
│   │   ├── manager_test.go
│   │   └── policy.go
│   ├── proxyman/
│   │   ├── command/
│   │   │   ├── command.go
│   │   │   ├── command.pb.go
│   │   │   ├── command.proto
│   │   │   ├── command_grpc.pb.go
│   │   │   ├── doc.go
│   │   │   └── errors.generated.go
│   │   ├── config.go
│   │   ├── config.pb.go
│   │   ├── config.proto
│   │   ├── inbound/
│   │   │   ├── always.go
│   │   │   ├── dynamic.go
│   │   │   ├── errors.generated.go
│   │   │   ├── inbound.go
│   │   │   └── worker.go
│   │   ├── outbound/
│   │   │   ├── errors.generated.go
│   │   │   ├── handler.go
│   │   │   ├── handler_test.go
│   │   │   └── outbound.go
│   │   └── proxyman.go
│   ├── reverse/
│   │   ├── bridge.go
│   │   ├── config.go
│   │   ├── config.pb.go
│   │   ├── config.proto
│   │   ├── errors.generated.go
│   │   ├── portal.go
│   │   ├── portal_test.go
│   │   └── reverse.go
│   ├── router/
│   │   ├── balancing.go
│   │   ├── command/
│   │   │   ├── command.go
│   │   │   ├── command.pb.go
│   │   │   ├── command.proto
│   │   │   ├── command_grpc.pb.go
│   │   │   ├── command_test.go
│   │   │   ├── config.go
│   │   │   └── errors.generated.go
│   │   ├── condition.go
│   │   ├── condition_geoip.go
│   │   ├── condition_geoip_test.go
│   │   ├── condition_test.go
│   │   ├── config.go
│   │   ├── config.pb.go
│   │   ├── config.proto
│   │   ├── errors.generated.go
│   │   ├── router.go
│   │   └── router_test.go
│   └── stats/
│       ├── channel.go
│       ├── channel_test.go
│       ├── command/
│       │   ├── command.go
│       │   ├── command.pb.go
│       │   ├── command.proto
│       │   ├── command_grpc.pb.go
│       │   ├── command_test.go
│       │   └── errors.generated.go
│       ├── config.pb.go
│       ├── config.proto
│       ├── counter.go
│       ├── counter_test.go
│       ├── errors.generated.go
│       ├── stats.go
│       └── stats_test.go
├── azure-pipelines.yml
├── common/
│   ├── antireplay/
│   │   └── antireplay.go
│   ├── bitmask/
│   │   ├── byte.go
│   │   └── byte_test.go
│   ├── buf/
│   │   ├── buf.go
│   │   ├── buffer.go
│   │   ├── buffer_test.go
│   │   ├── copy.go
│   │   ├── copy_test.go
│   │   ├── errors.generated.go
│   │   ├── io.go
│   │   ├── io_test.go
│   │   ├── multi_buffer.go
│   │   ├── multi_buffer_test.go
│   │   ├── reader.go
│   │   ├── reader_test.go
│   │   ├── readv_posix.go
│   │   ├── readv_reader.go
│   │   ├── readv_reader_wasm.go
│   │   ├── readv_test.go
│   │   ├── readv_unix.go
│   │   ├── readv_windows.go
│   │   ├── writer.go
│   │   └── writer_test.go
│   ├── bytespool/
│   │   └── pool.go
│   ├── cmdarg/
│   │   └── cmdarg.go
│   ├── common.go
│   ├── common_test.go
│   ├── crypto/
│   │   ├── aes.go
│   │   ├── auth.go
│   │   ├── auth_test.go
│   │   ├── benchmark_test.go
│   │   ├── chacha20.go
│   │   ├── chacha20_test.go
│   │   ├── chunk.go
│   │   ├── chunk_test.go
│   │   ├── crypto.go
│   │   ├── errors.generated.go
│   │   ├── internal/
│   │   │   ├── chacha.go
│   │   │   ├── chacha_core.generated.go
│   │   │   └── chacha_core_gen.go
│   │   └── io.go
│   ├── dice/
│   │   ├── dice.go
│   │   └── dice_test.go
│   ├── errors/
│   │   ├── errorgen/
│   │   │   └── main.go
│   │   ├── errors.go
│   │   ├── errors_test.go
│   │   └── multi_error.go
│   ├── errors.generated.go
│   ├── interfaces.go
│   ├── log/
│   │   ├── access.go
│   │   ├── log.go
│   │   ├── log.pb.go
│   │   ├── log.proto
│   │   ├── log_test.go
│   │   ├── logger.go
│   │   └── logger_test.go
│   ├── mux/
│   │   ├── client.go
│   │   ├── client_test.go
│   │   ├── errors.generated.go
│   │   ├── frame.go
│   │   ├── frame_test.go
│   │   ├── mux.go
│   │   ├── mux_test.go
│   │   ├── reader.go
│   │   ├── server.go
│   │   ├── session.go
│   │   ├── session_test.go
│   │   └── writer.go
│   ├── net/
│   │   ├── address.go
│   │   ├── address.pb.go
│   │   ├── address.proto
│   │   ├── address_test.go
│   │   ├── connection.go
│   │   ├── destination.go
│   │   ├── destination.pb.go
│   │   ├── destination.proto
│   │   ├── destination_test.go
│   │   ├── errors.generated.go
│   │   ├── net.go
│   │   ├── network.go
│   │   ├── network.pb.go
│   │   ├── network.proto
│   │   ├── port.go
│   │   ├── port.pb.go
│   │   ├── port.proto
│   │   ├── port_test.go
│   │   └── system.go
│   ├── peer/
│   │   ├── latency.go
│   │   └── peer.go
│   ├── platform/
│   │   ├── ctlcmd/
│   │   │   ├── attr_other.go
│   │   │   ├── attr_windows.go
│   │   │   ├── ctlcmd.go
│   │   │   └── errors.generated.go
│   │   ├── filesystem/
│   │   │   └── file.go
│   │   ├── others.go
│   │   ├── platform.go
│   │   ├── platform_test.go
│   │   └── windows.go
│   ├── protocol/
│   │   ├── account.go
│   │   ├── address.go
│   │   ├── address_test.go
│   │   ├── bittorrent/
│   │   │   └── bittorrent.go
│   │   ├── context.go
│   │   ├── dns/
│   │   │   ├── errors.generated.go
│   │   │   └── io.go
│   │   ├── errors.generated.go
│   │   ├── headers.go
│   │   ├── headers.pb.go
│   │   ├── headers.proto
│   │   ├── http/
│   │   │   ├── headers.go
│   │   │   ├── headers_test.go
│   │   │   ├── sniff.go
│   │   │   └── sniff_test.go
│   │   ├── id.go
│   │   ├── id_test.go
│   │   ├── payload.go
│   │   ├── protocol.go
│   │   ├── server_picker.go
│   │   ├── server_picker_test.go
│   │   ├── server_spec.go
│   │   ├── server_spec.pb.go
│   │   ├── server_spec.proto
│   │   ├── server_spec_test.go
│   │   ├── time.go
│   │   ├── time_test.go
│   │   ├── tls/
│   │   │   ├── cert/
│   │   │   │   ├── .gitignore
│   │   │   │   ├── cert.go
│   │   │   │   ├── cert_test.go
│   │   │   │   ├── errors.generated.go
│   │   │   │   └── privateKey.go
│   │   │   ├── sniff.go
│   │   │   └── sniff_test.go
│   │   ├── udp/
│   │   │   ├── packet.go
│   │   │   └── udp.go
│   │   ├── user.go
│   │   ├── user.pb.go
│   │   └── user.proto
│   ├── retry/
│   │   ├── errors.generated.go
│   │   ├── retry.go
│   │   └── retry_test.go
│   ├── serial/
│   │   ├── serial.go
│   │   ├── serial_test.go
│   │   ├── string.go
│   │   ├── string_test.go
│   │   ├── typed_message.go
│   │   ├── typed_message.pb.go
│   │   ├── typed_message.proto
│   │   └── typed_message_test.go
│   ├── session/
│   │   ├── context.go
│   │   └── session.go
│   ├── signal/
│   │   ├── done/
│   │   │   └── done.go
│   │   ├── notifier.go
│   │   ├── notifier_test.go
│   │   ├── pubsub/
│   │   │   ├── pubsub.go
│   │   │   └── pubsub_test.go
│   │   ├── semaphore/
│   │   │   └── semaphore.go
│   │   ├── timer.go
│   │   └── timer_test.go
│   ├── stack/
│   │   └── bytes.go
│   ├── strmatcher/
│   │   ├── benchmark_test.go
│   │   ├── domain_matcher.go
│   │   ├── domain_matcher_test.go
│   │   ├── full_matcher.go
│   │   ├── full_matcher_test.go
│   │   ├── matchers.go
│   │   ├── matchers_test.go
│   │   ├── strmatcher.go
│   │   └── strmatcher_test.go
│   ├── task/
│   │   ├── common.go
│   │   ├── periodic.go
│   │   ├── periodic_test.go
│   │   ├── task.go
│   │   └── task_test.go
│   ├── type.go
│   ├── type_test.go
│   └── uuid/
│       ├── uuid.go
│       └── uuid_test.go
├── config.go
├── config.pb.go
├── config.proto
├── context.go
├── context_test.go
├── core.go
├── errors.generated.go
├── features/
│   ├── dns/
│   │   ├── client.go
│   │   └── localdns/
│   │       └── client.go
│   ├── errors.generated.go
│   ├── feature.go
│   ├── inbound/
│   │   └── inbound.go
│   ├── outbound/
│   │   └── outbound.go
│   ├── policy/
│   │   ├── default.go
│   │   └── policy.go
│   ├── routing/
│   │   ├── context.go
│   │   ├── dispatcher.go
│   │   ├── dns/
│   │   │   ├── context.go
│   │   │   └── errors.generated.go
│   │   ├── router.go
│   │   └── session/
│   │       └── context.go
│   └── stats/
│       ├── errors.generated.go
│       └── stats.go
├── functions.go
├── functions_test.go
├── go.mod
├── go.sum
├── infra/
│   ├── bazel/
│   │   ├── BUILD
│   │   ├── build.bzl
│   │   ├── matrix.bzl
│   │   └── zip.bzl
│   ├── conf/
│   │   ├── api.go
│   │   ├── blackhole.go
│   │   ├── blackhole_test.go
│   │   ├── buildable.go
│   │   ├── command/
│   │   │   ├── command.go
│   │   │   └── errors.generated.go
│   │   ├── common.go
│   │   ├── common_test.go
│   │   ├── conf.go
│   │   ├── dns.go
│   │   ├── dns_proxy.go
│   │   ├── dns_proxy_test.go
│   │   ├── dns_test.go
│   │   ├── dokodemo.go
│   │   ├── dokodemo_test.go
│   │   ├── errors.generated.go
│   │   ├── freedom.go
│   │   ├── freedom_test.go
│   │   ├── general_test.go
│   │   ├── http.go
│   │   ├── http_test.go
│   │   ├── json/
│   │   │   ├── reader.go
│   │   │   └── reader_test.go
│   │   ├── loader.go
│   │   ├── log.go
│   │   ├── mtproto.go
│   │   ├── mtproto_test.go
│   │   ├── policy.go
│   │   ├── policy_test.go
│   │   ├── reverse.go
│   │   ├── reverse_test.go
│   │   ├── router.go
│   │   ├── router_test.go
│   │   ├── serial/
│   │   │   ├── errors.generated.go
│   │   │   ├── loader.go
│   │   │   ├── loader_test.go
│   │   │   └── serial.go
│   │   ├── shadowsocks.go
│   │   ├── shadowsocks_test.go
│   │   ├── socks.go
│   │   ├── socks_test.go
│   │   ├── transport.go
│   │   ├── transport_authenticators.go
│   │   ├── transport_internet.go
│   │   ├── transport_test.go
│   │   ├── trojan.go
│   │   ├── v2ray.go
│   │   ├── v2ray_test.go
│   │   ├── vless.go
│   │   ├── vless_test.go
│   │   ├── vmess.go
│   │   └── vmess_test.go
│   ├── control/
│   │   ├── api.go
│   │   ├── cert.go
│   │   ├── command.go
│   │   ├── config.go
│   │   ├── control.go
│   │   ├── errors.generated.go
│   │   ├── fetch.go
│   │   ├── love.go
│   │   ├── main/
│   │   │   ├── BUILD
│   │   │   ├── main.go
│   │   │   └── targets.bzl
│   │   ├── tlsping.go
│   │   ├── uuid.go
│   │   └── verify.go
│   └── vprotogen/
│       └── main.go
├── main/
│   ├── BUILD
│   ├── confloader/
│   │   ├── confloader.go
│   │   ├── errors.generated.go
│   │   └── external/
│   │       ├── errors.generated.go
│   │       └── external.go
│   ├── distro/
│   │   ├── all/
│   │   │   └── all.go
│   │   └── debug/
│   │       └── debug.go
│   ├── errors.generated.go
│   ├── json/
│   │   ├── config_json.go
│   │   └── errors.generated.go
│   ├── jsonem/
│   │   ├── errors.generated.go
│   │   └── jsonem.go
│   ├── main.go
│   ├── main_test.go
│   └── targets.bzl
├── mocks.go
├── proto.go
├── proxy/
│   ├── blackhole/
│   │   ├── blackhole.go
│   │   ├── blackhole_test.go
│   │   ├── config.go
│   │   ├── config.pb.go
│   │   ├── config.proto
│   │   ├── config_test.go
│   │   └── errors.generated.go
│   ├── dns/
│   │   ├── config.pb.go
│   │   ├── config.proto
│   │   ├── dns.go
│   │   ├── dns_test.go
│   │   └── errors.generated.go
│   ├── dokodemo/
│   │   ├── config.go
│   │   ├── config.pb.go
│   │   ├── config.proto
│   │   ├── dokodemo.go
│   │   └── errors.generated.go
│   ├── freedom/
│   │   ├── config.go
│   │   ├── config.pb.go
│   │   ├── config.proto
│   │   ├── errors.generated.go
│   │   └── freedom.go
│   ├── http/
│   │   ├── client.go
│   │   ├── config.go
│   │   ├── config.pb.go
│   │   ├── config.proto
│   │   ├── errors.generated.go
│   │   ├── http.go
│   │   └── server.go
│   ├── mtproto/
│   │   ├── auth.go
│   │   ├── auth_test.go
│   │   ├── client.go
│   │   ├── config.go
│   │   ├── config.pb.go
│   │   ├── config.proto
│   │   ├── errors.generated.go
│   │   ├── mtproto.go
│   │   └── server.go
│   ├── proxy.go
│   ├── shadowsocks/
│   │   ├── client.go
│   │   ├── config.go
│   │   ├── config.pb.go
│   │   ├── config.proto
│   │   ├── config_test.go
│   │   ├── errors.generated.go
│   │   ├── protocol.go
│   │   ├── protocol_test.go
│   │   ├── server.go
│   │   └── shadowsocks.go
│   ├── socks/
│   │   ├── client.go
│   │   ├── config.go
│   │   ├── config.pb.go
│   │   ├── config.proto
│   │   ├── errors.generated.go
│   │   ├── protocol.go
│   │   ├── protocol_test.go
│   │   ├── server.go
│   │   └── socks.go
│   ├── trojan/
│   │   ├── client.go
│   │   ├── config.go
│   │   ├── config.pb.go
│   │   ├── config.proto
│   │   ├── errors.generated.go
│   │   ├── protocol.go
│   │   ├── protocol_test.go
│   │   ├── server.go
│   │   ├── trojan.go
│   │   └── validator.go
│   ├── vless/
│   │   ├── account.go
│   │   ├── account.pb.go
│   │   ├── account.proto
│   │   ├── encoding/
│   │   │   ├── addons.go
│   │   │   ├── addons.pb.go
│   │   │   ├── addons.proto
│   │   │   ├── encoding.go
│   │   │   ├── encoding_test.go
│   │   │   └── errors.generated.go
│   │   ├── errors.generated.go
│   │   ├── inbound/
│   │   │   ├── config.go
│   │   │   ├── config.pb.go
│   │   │   ├── config.proto
│   │   │   ├── errors.generated.go
│   │   │   └── inbound.go
│   │   ├── outbound/
│   │   │   ├── config.go
│   │   │   ├── config.pb.go
│   │   │   ├── config.proto
│   │   │   ├── errors.generated.go
│   │   │   └── outbound.go
│   │   ├── validator.go
│   │   └── vless.go
│   └── vmess/
│       ├── account.go
│       ├── account.pb.go
│       ├── account.proto
│       ├── aead/
│       │   ├── authid.go
│       │   ├── authid_test.go
│       │   ├── consts.go
│       │   ├── encrypt.go
│       │   ├── encrypt_test.go
│       │   └── kdf.go
│       ├── encoding/
│       │   ├── auth.go
│       │   ├── auth_test.go
│       │   ├── client.go
│       │   ├── commands.go
│       │   ├── commands_test.go
│       │   ├── encoding.go
│       │   ├── encoding_test.go
│       │   ├── errors.generated.go
│       │   └── server.go
│       ├── errors.generated.go
│       ├── inbound/
│       │   ├── config.go
│       │   ├── config.pb.go
│       │   ├── config.proto
│       │   ├── errors.generated.go
│       │   └── inbound.go
│       ├── outbound/
│       │   ├── command.go
│       │   ├── config.go
│       │   ├── config.pb.go
│       │   ├── config.proto
│       │   ├── errors.generated.go
│       │   └── outbound.go
│       ├── validator.go
│       ├── validator_test.go
│       ├── vmess.go
│       └── vmessCtxInterface.go
├── release/
│   ├── BUILD
│   ├── bleedingrelease.sh
│   ├── config/
│   │   ├── config.json
│   │   ├── systemd/
│   │   │   └── system/
│   │   │       ├── v2ray.service
│   │   │       └── v2ray@.service
│   │   ├── vpoint_socks_vmess.json
│   │   └── vpoint_vmess_freedom.json
│   ├── install-release.sh
│   ├── mapping.bzl
│   ├── mutilate/
│   │   └── removeVSign.sh
│   ├── requestsign.sh
│   ├── requestsign_github.sh
│   ├── tagrelease.sh
│   └── user-package.sh
├── testing/
│   ├── coverage/
│   │   ├── coverall
│   │   └── coverall2
│   ├── mocks/
│   │   ├── dns.go
│   │   ├── io.go
│   │   ├── log.go
│   │   ├── mux.go
│   │   ├── outbound.go
│   │   └── proxy.go
│   ├── scenarios/
│   │   ├── command_test.go
│   │   ├── common.go
│   │   ├── common_coverage.go
│   │   ├── common_regular.go
│   │   ├── dns_test.go
│   │   ├── dokodemo_test.go
│   │   ├── feature_test.go
│   │   ├── http_test.go
│   │   ├── policy_test.go
│   │   ├── reverse_test.go
│   │   ├── shadowsocks_test.go
│   │   ├── socks_test.go
│   │   ├── tls_test.go
│   │   ├── transport_test.go
│   │   └── vmess_test.go
│   └── servers/
│       ├── http/
│       │   └── http.go
│       ├── tcp/
│       │   ├── port.go
│       │   └── tcp.go
│       └── udp/
│           ├── port.go
│           └── udp.go
├── transport/
│   ├── config.go
│   ├── config.pb.go
│   ├── config.proto
│   ├── internet/
│   │   ├── config.go
│   │   ├── config.pb.go
│   │   ├── config.proto
│   │   ├── connection.go
│   │   ├── dialer.go
│   │   ├── dialer_test.go
│   │   ├── domainsocket/
│   │   │   ├── config.go
│   │   │   ├── config.pb.go
│   │   │   ├── config.proto
│   │   │   ├── dial.go
│   │   │   ├── errgen.go
│   │   │   ├── errors.generated.go
│   │   │   ├── listener.go
│   │   │   └── listener_test.go
│   │   ├── errors.generated.go
│   │   ├── header.go
│   │   ├── header_test.go
│   │   ├── headers/
│   │   │   ├── http/
│   │   │   │   ├── config.go
│   │   │   │   ├── config.pb.go
│   │   │   │   ├── config.proto
│   │   │   │   ├── errors.generated.go
│   │   │   │   ├── http.go
│   │   │   │   ├── http_test.go
│   │   │   │   ├── linkedreadRequest.go
│   │   │   │   └── resp.go
│   │   │   ├── noop/
│   │   │   │   ├── config.pb.go
│   │   │   │   ├── config.proto
│   │   │   │   └── noop.go
│   │   │   ├── srtp/
│   │   │   │   ├── config.pb.go
│   │   │   │   ├── config.proto
│   │   │   │   ├── srtp.go
│   │   │   │   └── srtp_test.go
│   │   │   ├── tls/
│   │   │   │   ├── config.pb.go
│   │   │   │   ├── config.proto
│   │   │   │   ├── dtls.go
│   │   │   │   └── dtls_test.go
│   │   │   ├── utp/
│   │   │   │   ├── config.pb.go
│   │   │   │   ├── config.proto
│   │   │   │   ├── utp.go
│   │   │   │   └── utp_test.go
│   │   │   ├── wechat/
│   │   │   │   ├── config.pb.go
│   │   │   │   ├── config.proto
│   │   │   │   ├── wechat.go
│   │   │   │   └── wechat_test.go
│   │   │   └── wireguard/
│   │   │       ├── config.pb.go
│   │   │       ├── config.proto
│   │   │       └── wireguard.go
│   │   ├── http/
│   │   │   ├── config.go
│   │   │   ├── config.pb.go
│   │   │   ├── config.proto
│   │   │   ├── dialer.go
│   │   │   ├── errors.generated.go
│   │   │   ├── http.go
│   │   │   ├── http_test.go
│   │   │   └── hub.go
│   │   ├── internet.go
│   │   ├── kcp/
│   │   │   ├── config.go
│   │   │   ├── config.pb.go
│   │   │   ├── config.proto
│   │   │   ├── connection.go
│   │   │   ├── connection_test.go
│   │   │   ├── crypt.go
│   │   │   ├── crypt_test.go
│   │   │   ├── cryptreal.go
│   │   │   ├── dialer.go
│   │   │   ├── errors.generated.go
│   │   │   ├── io.go
│   │   │   ├── io_test.go
│   │   │   ├── kcp.go
│   │   │   ├── kcp_test.go
│   │   │   ├── listener.go
│   │   │   ├── output.go
│   │   │   ├── receiving.go
│   │   │   ├── segment.go
│   │   │   ├── segment_test.go
│   │   │   ├── sending.go
│   │   │   ├── xor.go
│   │   │   ├── xor_amd64.go
│   │   │   └── xor_amd64.s
│   │   ├── memory_settings.go
│   │   ├── quic/
│   │   │   ├── config.go
│   │   │   ├── config.pb.go
│   │   │   ├── config.proto
│   │   │   ├── conn.go
│   │   │   ├── dialer.go
│   │   │   ├── errors.generated.go
│   │   │   ├── hub.go
│   │   │   ├── pool.go
│   │   │   ├── quic.go
│   │   │   └── quic_test.go
│   │   ├── sockopt.go
│   │   ├── sockopt_darwin.go
│   │   ├── sockopt_freebsd.go
│   │   ├── sockopt_linux.go
│   │   ├── sockopt_linux_test.go
│   │   ├── sockopt_other.go
│   │   ├── sockopt_test.go
│   │   ├── sockopt_windows.go
│   │   ├── system_dialer.go
│   │   ├── system_listener.go
│   │   ├── system_listener_test.go
│   │   ├── tcp/
│   │   │   ├── config.go
│   │   │   ├── config.pb.go
│   │   │   ├── config.proto
│   │   │   ├── dialer.go
│   │   │   ├── errors.generated.go
│   │   │   ├── hub.go
│   │   │   ├── sockopt_freebsd.go
│   │   │   ├── sockopt_linux.go
│   │   │   ├── sockopt_linux_test.go
│   │   │   ├── sockopt_other.go
│   │   │   └── tcp.go
│   │   ├── tcp_hub.go
│   │   ├── tls/
│   │   │   ├── config.go
│   │   │   ├── config.pb.go
│   │   │   ├── config.proto
│   │   │   ├── config_other.go
│   │   │   ├── config_test.go
│   │   │   ├── config_windows.go
│   │   │   ├── errors.generated.go
│   │   │   └── tls.go
│   │   ├── udp/
│   │   │   ├── config.go
│   │   │   ├── config.pb.go
│   │   │   ├── config.proto
│   │   │   ├── dialer.go
│   │   │   ├── dispatcher.go
│   │   │   ├── dispatcher_test.go
│   │   │   ├── errors.generated.go
│   │   │   ├── hub.go
│   │   │   ├── hub_freebsd.go
│   │   │   ├── hub_linux.go
│   │   │   ├── hub_other.go
│   │   │   └── udp.go
│   │   ├── websocket/
│   │   │   ├── config.go
│   │   │   ├── config.pb.go
│   │   │   ├── config.proto
│   │   │   ├── connection.go
│   │   │   ├── dialer.go
│   │   │   ├── errors.generated.go
│   │   │   ├── hub.go
│   │   │   ├── ws.go
│   │   │   └── ws_test.go
│   │   └── xtls/
│   │       ├── config.go
│   │       ├── config.pb.go
│   │       ├── config.proto
│   │       ├── config_other.go
│   │       ├── config_test.go
│   │       ├── config_windows.go
│   │       ├── errors.generated.go
│   │       └── xtls.go
│   ├── link.go
│   └── pipe/
│       ├── impl.go
│       ├── pipe.go
│       ├── pipe_test.go
│       ├── reader.go
│       └── writer.go
├── v2ray.go
└── v2ray_test.go
Download .txt
Showing preview only (449K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (5273 symbols across 609 files)

FILE: annotations.go
  type Annotation (line 5) | type Annotation struct

FILE: app/commander/commander.go
  type Commander (line 21) | type Commander struct
    method Type (line 59) | func (c *Commander) Type() interface{} {
    method Start (line 64) | func (c *Commander) Start() error {
    method Close (line 94) | func (c *Commander) Close() error {
  function NewCommander (line 30) | func NewCommander(ctx context.Context, config *Config) (*Commander, erro...
  function init (line 106) | func init() {

FILE: app/commander/config.pb.go
  constant _ (line 20) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 22) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  constant _ (line 27) | _ = proto.ProtoPackageIsVersion4
  type Config (line 30) | type Config struct
    method Reset (line 42) | func (x *Config) Reset() {
    method String (line 51) | func (x *Config) String() string {
    method ProtoMessage (line 55) | func (*Config) ProtoMessage() {}
    method ProtoReflect (line 57) | func (x *Config) ProtoReflect() protoreflect.Message {
    method Descriptor (line 70) | func (*Config) Descriptor() ([]byte, []int) {
    method GetTag (line 74) | func (x *Config) GetTag() string {
    method GetService (line 81) | func (x *Config) GetService() []*serial.TypedMessage {
  function file_app_commander_config_proto_rawDescGZIP (line 116) | func file_app_commander_config_proto_rawDescGZIP() []byte {
  function init (line 137) | func init() { file_app_commander_config_proto_init() }
  function file_app_commander_config_proto_init (line 138) | func file_app_commander_config_proto_init() {

FILE: app/commander/errors.generated.go
  type errPathObjHolder (line 5) | type errPathObjHolder struct
  function newError (line 7) | func newError(values ...interface{}) *errors.Error {

FILE: app/commander/outbound.go
  type OutboundListener (line 16) | type OutboundListener struct
    method add (line 21) | func (l *OutboundListener) add(conn net.Conn) {
    method Accept (line 32) | func (l *OutboundListener) Accept() (net.Conn, error) {
    method Close (line 42) | func (l *OutboundListener) Close() error {
    method Addr (line 57) | func (l *OutboundListener) Addr() net.Addr {
  type Outbound (line 65) | type Outbound struct
    method Dispatch (line 73) | func (co *Outbound) Dispatch(ctx context.Context, link *transport.Link) {
    method Tag (line 91) | func (co *Outbound) Tag() string {
    method Start (line 96) | func (co *Outbound) Start() error {
    method Close (line 104) | func (co *Outbound) Close() error {

FILE: app/commander/service.go
  type Service (line 10) | type Service interface

FILE: app/dispatcher/config.pb.go
  constant _ (line 19) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 21) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  constant _ (line 26) | _ = proto.ProtoPackageIsVersion4
  type SessionConfig (line 28) | type SessionConfig struct
    method Reset (line 34) | func (x *SessionConfig) Reset() {
    method String (line 43) | func (x *SessionConfig) String() string {
    method ProtoMessage (line 47) | func (*SessionConfig) ProtoMessage() {}
    method ProtoReflect (line 49) | func (x *SessionConfig) ProtoReflect() protoreflect.Message {
    method Descriptor (line 62) | func (*SessionConfig) Descriptor() ([]byte, []int) {
  type Config (line 66) | type Config struct
    method Reset (line 74) | func (x *Config) Reset() {
    method String (line 83) | func (x *Config) String() string {
    method ProtoMessage (line 87) | func (*Config) ProtoMessage() {}
    method ProtoReflect (line 89) | func (x *Config) ProtoReflect() protoreflect.Message {
    method Descriptor (line 102) | func (*Config) Descriptor() ([]byte, []int) {
    method GetSettings (line 106) | func (x *Config) GetSettings() *SessionConfig {
  function file_app_dispatcher_config_proto_rawDescGZIP (line 140) | func file_app_dispatcher_config_proto_rawDescGZIP() []byte {
  function init (line 161) | func init() { file_app_dispatcher_config_proto_init() }
  function file_app_dispatcher_config_proto_init (line 162) | func file_app_dispatcher_config_proto_init() {

FILE: app/dispatcher/default.go
  type cachedReader (line 33) | type cachedReader struct
    method Cache (line 39) | func (r *cachedReader) Cache(b *buf.Buffer) {
    method readInternal (line 52) | func (r *cachedReader) readInternal() buf.MultiBuffer {
    method ReadMultiBuffer (line 65) | func (r *cachedReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
    method ReadMultiBufferTimeout (line 74) | func (r *cachedReader) ReadMultiBufferTimeout(timeout time.Duration) (...
    method Interrupt (line 83) | func (r *cachedReader) Interrupt() {
  type DefaultDispatcher (line 93) | type DefaultDispatcher struct
    method Init (line 113) | func (d *DefaultDispatcher) Init(config *Config, om outbound.Manager, ...
    method Type (line 122) | func (*DefaultDispatcher) Type() interface{} {
    method Start (line 127) | func (*DefaultDispatcher) Start() error {
    method Close (line 132) | func (*DefaultDispatcher) Close() error { return nil }
    method getLink (line 134) | func (d *DefaultDispatcher) getLink(ctx context.Context) (*transport.L...
    method Dispatch (line 190) | func (d *DefaultDispatcher) Dispatch(ctx context.Context, destination ...
    method routedDispatch (line 260) | func (d *DefaultDispatcher) routedDispatch(ctx context.Context, link *...
  function init (line 100) | func init() {
  function shouldOverride (line 180) | func shouldOverride(result SniffResult, domainOverride []string) bool {
  function sniffer (line 230) | func sniffer(ctx context.Context, cReader *cachedReader) (SniffResult, e...

FILE: app/dispatcher/errors.generated.go
  type errPathObjHolder (line 5) | type errPathObjHolder struct
  function newError (line 7) | func newError(values ...interface{}) *errors.Error {

FILE: app/dispatcher/sniffer.go
  type SniffResult (line 12) | type SniffResult interface
  type protocolSniffer (line 17) | type protocolSniffer
  type Sniffer (line 19) | type Sniffer struct
    method Sniff (line 35) | func (s *Sniffer) Sniff(payload []byte) (SniffResult, error) {
  function NewSniffer (line 23) | func NewSniffer() *Sniffer {

FILE: app/dispatcher/stats.go
  type SizeStatWriter (line 11) | type SizeStatWriter struct
    method WriteMultiBuffer (line 16) | func (w *SizeStatWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
    method Close (line 21) | func (w *SizeStatWriter) Close() error {
    method Interrupt (line 25) | func (w *SizeStatWriter) Interrupt() {

FILE: app/dispatcher/stats_test.go
  type TestCounter (line 11) | type TestCounter
    method Value (line 13) | func (c *TestCounter) Value() int64 {
    method Add (line 17) | func (c *TestCounter) Add(v int64) int64 {
    method Set (line 23) | func (c *TestCounter) Set(v int64) int64 {
  function TestStatsWriter (line 28) | func TestStatsWriter(t *testing.T) {

FILE: app/dns/config.pb.go
  constant _ (line 21) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 23) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  constant _ (line 28) | _ = proto.ProtoPackageIsVersion4
  type DomainMatchingType (line 30) | type DomainMatchingType
    method Enum (line 55) | func (x DomainMatchingType) Enum() *DomainMatchingType {
    method String (line 61) | func (x DomainMatchingType) String() string {
    method Descriptor (line 65) | func (DomainMatchingType) Descriptor() protoreflect.EnumDescriptor {
    method Type (line 69) | func (DomainMatchingType) Type() protoreflect.EnumType {
    method Number (line 73) | func (x DomainMatchingType) Number() protoreflect.EnumNumber {
    method EnumDescriptor (line 78) | func (DomainMatchingType) EnumDescriptor() ([]byte, []int) {
  constant DomainMatchingType_Full (line 33) | DomainMatchingType_Full      DomainMatchingType = 0
  constant DomainMatchingType_Subdomain (line 34) | DomainMatchingType_Subdomain DomainMatchingType = 1
  constant DomainMatchingType_Keyword (line 35) | DomainMatchingType_Keyword   DomainMatchingType = 2
  constant DomainMatchingType_Regex (line 36) | DomainMatchingType_Regex     DomainMatchingType = 3
  type NameServer (line 82) | type NameServer struct
    method Reset (line 93) | func (x *NameServer) Reset() {
    method String (line 102) | func (x *NameServer) String() string {
    method ProtoMessage (line 106) | func (*NameServer) ProtoMessage() {}
    method ProtoReflect (line 108) | func (x *NameServer) ProtoReflect() protoreflect.Message {
    method Descriptor (line 121) | func (*NameServer) Descriptor() ([]byte, []int) {
    method GetAddress (line 125) | func (x *NameServer) GetAddress() *net.Endpoint {
    method GetPrioritizedDomain (line 132) | func (x *NameServer) GetPrioritizedDomain() []*NameServer_PriorityDoma...
    method GetGeoip (line 139) | func (x *NameServer) GetGeoip() []*router.GeoIP {
    method GetOriginalRules (line 146) | func (x *NameServer) GetOriginalRules() []*NameServer_OriginalRule {
  type Config (line 153) | type Config struct
    method Reset (line 179) | func (x *Config) Reset() {
    method String (line 188) | func (x *Config) String() string {
    method ProtoMessage (line 192) | func (*Config) ProtoMessage() {}
    method ProtoReflect (line 194) | func (x *Config) ProtoReflect() protoreflect.Message {
    method Descriptor (line 207) | func (*Config) Descriptor() ([]byte, []int) {
    method GetNameServers (line 212) | func (x *Config) GetNameServers() []*net.Endpoint {
    method GetNameServer (line 219) | func (x *Config) GetNameServer() []*NameServer {
    method GetHosts (line 227) | func (x *Config) GetHosts() map[string]*net.IPOrDomain {
    method GetClientIp (line 234) | func (x *Config) GetClientIp() []byte {
    method GetStaticHosts (line 241) | func (x *Config) GetStaticHosts() []*Config_HostMapping {
    method GetTag (line 248) | func (x *Config) GetTag() string {
  type NameServer_PriorityDomain (line 255) | type NameServer_PriorityDomain struct
    method Reset (line 264) | func (x *NameServer_PriorityDomain) Reset() {
    method String (line 273) | func (x *NameServer_PriorityDomain) String() string {
    method ProtoMessage (line 277) | func (*NameServer_PriorityDomain) ProtoMessage() {}
    method ProtoReflect (line 279) | func (x *NameServer_PriorityDomain) ProtoReflect() protoreflect.Message {
    method Descriptor (line 292) | func (*NameServer_PriorityDomain) Descriptor() ([]byte, []int) {
    method GetType (line 296) | func (x *NameServer_PriorityDomain) GetType() DomainMatchingType {
    method GetDomain (line 303) | func (x *NameServer_PriorityDomain) GetDomain() string {
  type NameServer_OriginalRule (line 310) | type NameServer_OriginalRule struct
    method Reset (line 319) | func (x *NameServer_OriginalRule) Reset() {
    method String (line 328) | func (x *NameServer_OriginalRule) String() string {
    method ProtoMessage (line 332) | func (*NameServer_OriginalRule) ProtoMessage() {}
    method ProtoReflect (line 334) | func (x *NameServer_OriginalRule) ProtoReflect() protoreflect.Message {
    method Descriptor (line 347) | func (*NameServer_OriginalRule) Descriptor() ([]byte, []int) {
    method GetRule (line 351) | func (x *NameServer_OriginalRule) GetRule() string {
    method GetSize (line 358) | func (x *NameServer_OriginalRule) GetSize() uint32 {
  type Config_HostMapping (line 365) | type Config_HostMapping struct
    method Reset (line 379) | func (x *Config_HostMapping) Reset() {
    method String (line 388) | func (x *Config_HostMapping) String() string {
    method ProtoMessage (line 392) | func (*Config_HostMapping) ProtoMessage() {}
    method ProtoReflect (line 394) | func (x *Config_HostMapping) ProtoReflect() protoreflect.Message {
    method Descriptor (line 407) | func (*Config_HostMapping) Descriptor() ([]byte, []int) {
    method GetType (line 411) | func (x *Config_HostMapping) GetType() DomainMatchingType {
    method GetDomain (line 418) | func (x *Config_HostMapping) GetDomain() string {
    method GetIp (line 425) | func (x *Config_HostMapping) GetIp() [][]byte {
    method GetProxiedDomain (line 432) | func (x *Config_HostMapping) GetProxiedDomain() string {
  function file_app_dns_config_proto_rawDescGZIP (line 532) | func file_app_dns_config_proto_rawDescGZIP() []byte {
  function init (line 572) | func init() { file_app_dns_config_proto_init() }
  function file_app_dns_config_proto_init (line 573) | func file_app_dns_config_proto_init() {

FILE: app/dns/dnscommon.go
  function Fqdn (line 17) | func Fqdn(domain string) string {
  type record (line 24) | type record struct
  type IPRecord (line 30) | type IPRecord struct
    method getIPs (line 37) | func (r *IPRecord) getIPs() ([]net.Address, error) {
  function isNewer (line 47) | func isNewer(baseRec *IPRecord, newRec *IPRecord) bool {
  type dnsRequest (line 61) | type dnsRequest struct
  function genEDNS0Options (line 69) | func genEDNS0Options(clientIP net.IP) *dnsmessage.Resource {
  function buildReqMsgs (line 117) | func buildReqMsgs(domain string, option IPOption, reqIDGen func() uint16...
  function parseResponse (line 169) | func parseResponse(payload []byte) (*IPRecord, error) {

FILE: app/dns/dnscommon_test.go
  function Test_parseResponse (line 17) | func Test_parseResponse(t *testing.T) {
  function Test_buildReqMsgs (line 91) | func Test_buildReqMsgs(t *testing.T) {
  function Test_genEDNS0Options (line 120) | func Test_genEDNS0Options(t *testing.T) {
  function TestFqdn (line 142) | func TestFqdn(t *testing.T) {

FILE: app/dns/dohdns.go
  type DoHNameServer (line 32) | type DoHNameServer struct
    method Name (line 132) | func (s *DoHNameServer) Name() string {
    method Cleanup (line 137) | func (s *DoHNameServer) Cleanup() error {
    method updateIP (line 169) | func (s *DoHNameServer) updateIP(req *dnsRequest, ipRec *IPRecord) {
    method newReqID (line 210) | func (s *DoHNameServer) newReqID() uint16 {
    method sendQuery (line 214) | func (s *DoHNameServer) sendQuery(ctx context.Context, domain string, ...
    method dohHTTPSContext (line 269) | func (s *DoHNameServer) dohHTTPSContext(ctx context.Context, b []byte)...
    method findIPsForDomain (line 293) | func (s *DoHNameServer) findIPsForDomain(domain string, option IPOptio...
    method QueryIP (line 336) | func (s *DoHNameServer) QueryIP(ctx context.Context, domain string, op...
  function NewDoHNameServer (line 45) | func NewDoHNameServer(url *url.URL, dispatcher routing.Dispatcher, clien...
  function NewDoHLocalNameServer (line 88) | func NewDoHLocalNameServer(url *url.URL, clientIP net.IP) *DoHNameServer {
  function baseDOHNameServer (line 114) | func baseDOHNameServer(url *url.URL, prefix string, clientIP net.IP) *Do...

FILE: app/dns/errors.generated.go
  type errPathObjHolder (line 5) | type errPathObjHolder struct
  function newError (line 7) | func newError(values ...interface{}) *errors.Error {

FILE: app/dns/hosts.go
  type StaticHosts (line 13) | type StaticHosts struct
    method LookupIP (line 108) | func (h *StaticHosts) LookupIP(domain string, option IPOption) []net.A...
  function toStrMatcher (line 25) | func toStrMatcher(t DomainMatchingType, domain string) (strmatcher.Match...
  function NewStaticHosts (line 38) | func NewStaticHosts(hosts []*Config_HostMapping, legacy map[string]*net....
  function filterIP (line 94) | func filterIP(ips []net.Address, option IPOption) []net.Address {

FILE: app/dns/hosts_test.go
  function TestStaticHosts (line 13) | func TestStaticHosts(t *testing.T) {

FILE: app/dns/nameserver.go
  type IPOption (line 13) | type IPOption struct
  type Client (line 19) | type Client interface
  type localNameServer (line 27) | type localNameServer struct
    method QueryIP (line 31) | func (s *localNameServer) QueryIP(ctx context.Context, domain string, ...
    method Name (line 47) | func (s *localNameServer) Name() string {
  function NewLocalNameServer (line 51) | func NewLocalNameServer() *localNameServer {

FILE: app/dns/nameserver_test.go
  function TestLocalNameServer (line 12) | func TestLocalNameServer(t *testing.T) {

FILE: app/dns/server.go
  type Server (line 30) | type Server struct
    method Type (line 247) | func (*Server) Type() interface{} {
    method Start (line 252) | func (s *Server) Start() error {
    method Close (line 257) | func (s *Server) Close() error {
    method IsOwnLink (line 261) | func (s *Server) IsOwnLink(ctx context.Context) bool {
    method Match (line 267) | func (s *Server) Match(idx int, client Client, domain string, ips []ne...
    method queryIPTimeout (line 294) | func (s *Server) queryIPTimeout(idx int, client Client, domain string,...
    method LookupIP (line 313) | func (s *Server) LookupIP(domain string) ([]net.IP, error) {
    method LookupIPv4 (line 321) | func (s *Server) LookupIPv4(domain string) ([]net.IP, error) {
    method LookupIPv6 (line 329) | func (s *Server) LookupIPv6(domain string) ([]net.IP, error) {
    method lookupStatic (line 336) | func (s *Server) lookupStatic(domain string, option IPOption, depth in...
    method lookupIPInternal (line 360) | func (s *Server) lookupIPInternal(domain string, option IPOption) ([]n...
  type DomainMatcherInfo (line 43) | type DomainMatcherInfo struct
  type MultiGeoIPMatcher (line 49) | type MultiGeoIPMatcher struct
    method Match (line 56) | func (c *MultiGeoIPMatcher) Match(ip net.IP) bool {
    method HasMatcher (line 66) | func (c *MultiGeoIPMatcher) HasMatcher() bool {
  function generateRandomTag (line 70) | func generateRandomTag() string {
  function New (line 76) | func New(ctx context.Context, config *Config) (*Server, error) {
  function toNetIP (line 349) | func toNetIP(ips []net.Address) []net.IP {
  function init (line 440) | func init() {

FILE: app/dns/server_test.go
  type staticHandler (line 25) | type staticHandler struct
    method ServeDNS (line 28) | func (*staticHandler) ServeDNS(w dns.ResponseWriter, r *dns.Msg) {
  function TestUDPServerSubnet (line 98) | func TestUDPServerSubnet(t *testing.T) {
  function TestUDPServer (line 153) | func TestUDPServer(t *testing.T) {
  function TestPrioritizedDomain (line 254) | func TestPrioritizedDomain(t *testing.T) {
  function TestUDPServerIPv6 (line 336) | func TestUDPServerIPv6(t *testing.T) {
  function TestStaticHostDomain (line 393) | func TestStaticHostDomain(t *testing.T) {
  function TestIPMatch (line 458) | func TestIPMatch(t *testing.T) {
  function TestLocalDomain (line 568) | func TestLocalDomain(t *testing.T) {
  function TestMultiMatchPrioritizedDomain (line 764) | func TestMultiMatchPrioritizedDomain(t *testing.T) {

FILE: app/dns/udpns.go
  type ClassicNameServer (line 25) | type ClassicNameServer struct
    method Name (line 62) | func (s *ClassicNameServer) Name() string {
    method Cleanup (line 66) | func (s *ClassicNameServer) Cleanup() error {
    method HandleResponse (line 107) | func (s *ClassicNameServer) HandleResponse(ctx context.Context, packet...
    method updateIP (line 143) | func (s *ClassicNameServer) updateIP(domain string, newRec record) {
    method newReqID (line 172) | func (s *ClassicNameServer) newReqID() uint16 {
    method addPendingRequest (line 176) | func (s *ClassicNameServer) addPendingRequest(req *dnsRequest) {
    method sendQuery (line 185) | func (s *ClassicNameServer) sendQuery(ctx context.Context, domain stri...
    method findIPsForDomain (line 204) | func (s *ClassicNameServer) findIPsForDomain(domain string, option IPO...
    method QueryIP (line 242) | func (s *ClassicNameServer) QueryIP(ctx context.Context, domain string...
  function NewClassicNameServer (line 38) | func NewClassicNameServer(address net.Destination, dispatcher routing.Di...

FILE: app/log/command/command.go
  type LoggerServer (line 17) | type LoggerServer struct
    method RestartLogger (line 22) | func (s *LoggerServer) RestartLogger(ctx context.Context, request *Res...
    method mustEmbedUnimplementedLoggerServiceServer (line 36) | func (s *LoggerServer) mustEmbedUnimplementedLoggerServiceServer() {}
  type service (line 38) | type service struct
    method Register (line 42) | func (s *service) Register(server *grpc.Server) {
  function init (line 48) | func init() {

FILE: app/log/command/command_test.go
  function TestLoggerRestart (line 18) | func TestLoggerRestart(t *testing.T) {

FILE: app/log/command/config.pb.go
  constant _ (line 19) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 21) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  constant _ (line 26) | _ = proto.ProtoPackageIsVersion4
  type Config (line 28) | type Config struct
    method Reset (line 34) | func (x *Config) Reset() {
    method String (line 43) | func (x *Config) String() string {
    method ProtoMessage (line 47) | func (*Config) ProtoMessage() {}
    method ProtoReflect (line 49) | func (x *Config) ProtoReflect() protoreflect.Message {
    method Descriptor (line 62) | func (*Config) Descriptor() ([]byte, []int) {
  type RestartLoggerRequest (line 66) | type RestartLoggerRequest struct
    method Reset (line 72) | func (x *RestartLoggerRequest) Reset() {
    method String (line 81) | func (x *RestartLoggerRequest) String() string {
    method ProtoMessage (line 85) | func (*RestartLoggerRequest) ProtoMessage() {}
    method ProtoReflect (line 87) | func (x *RestartLoggerRequest) ProtoReflect() protoreflect.Message {
    method Descriptor (line 100) | func (*RestartLoggerRequest) Descriptor() ([]byte, []int) {
  type RestartLoggerResponse (line 104) | type RestartLoggerResponse struct
    method Reset (line 110) | func (x *RestartLoggerResponse) Reset() {
    method String (line 119) | func (x *RestartLoggerResponse) String() string {
    method ProtoMessage (line 123) | func (*RestartLoggerResponse) ProtoMessage() {}
    method ProtoReflect (line 125) | func (x *RestartLoggerResponse) ProtoReflect() protoreflect.Message {
    method Descriptor (line 138) | func (*RestartLoggerResponse) Descriptor() ([]byte, []int) {
  function file_app_log_command_config_proto_rawDescGZIP (line 175) | func file_app_log_command_config_proto_rawDescGZIP() []byte {
  function init (line 198) | func init() { file_app_log_command_config_proto_init() }
  function file_app_log_command_config_proto_init (line 199) | func file_app_log_command_config_proto_init() {

FILE: app/log/command/config_grpc.pb.go
  constant _ (line 14) | _ = grpc.SupportPackageIsVersion7
  type LoggerServiceClient (line 19) | type LoggerServiceClient interface
  type loggerServiceClient (line 23) | type loggerServiceClient struct
    method RestartLogger (line 31) | func (c *loggerServiceClient) RestartLogger(ctx context.Context, in *R...
  function NewLoggerServiceClient (line 27) | func NewLoggerServiceClient(cc grpc.ClientConnInterface) LoggerServiceCl...
  type LoggerServiceServer (line 43) | type LoggerServiceServer interface
  type UnimplementedLoggerServiceServer (line 49) | type UnimplementedLoggerServiceServer struct
    method RestartLogger (line 52) | func (UnimplementedLoggerServiceServer) RestartLogger(context.Context,...
    method mustEmbedUnimplementedLoggerServiceServer (line 55) | func (UnimplementedLoggerServiceServer) mustEmbedUnimplementedLoggerSe...
  type UnsafeLoggerServiceServer (line 60) | type UnsafeLoggerServiceServer interface
  function RegisterLoggerServiceServer (line 64) | func RegisterLoggerServiceServer(s *grpc.Server, srv LoggerServiceServer) {
  function _LoggerService_RestartLogger_Handler (line 68) | func _LoggerService_RestartLogger_Handler(srv interface{}, ctx context.C...

FILE: app/log/command/errors.generated.go
  type errPathObjHolder (line 5) | type errPathObjHolder struct
  function newError (line 7) | func newError(values ...interface{}) *errors.Error {

FILE: app/log/config.pb.go
  constant _ (line 20) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 22) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  constant _ (line 27) | _ = proto.ProtoPackageIsVersion4
  type LogType (line 29) | type LogType
    method Enum (line 54) | func (x LogType) Enum() *LogType {
    method String (line 60) | func (x LogType) String() string {
    method Descriptor (line 64) | func (LogType) Descriptor() protoreflect.EnumDescriptor {
    method Type (line 68) | func (LogType) Type() protoreflect.EnumType {
    method Number (line 72) | func (x LogType) Number() protoreflect.EnumNumber {
    method EnumDescriptor (line 77) | func (LogType) EnumDescriptor() ([]byte, []int) {
  constant LogType_None (line 32) | LogType_None    LogType = 0
  constant LogType_Console (line 33) | LogType_Console LogType = 1
  constant LogType_File (line 34) | LogType_File    LogType = 2
  constant LogType_Event (line 35) | LogType_Event   LogType = 3
  type Config (line 81) | type Config struct
    method Reset (line 93) | func (x *Config) Reset() {
    method String (line 102) | func (x *Config) String() string {
    method ProtoMessage (line 106) | func (*Config) ProtoMessage() {}
    method ProtoReflect (line 108) | func (x *Config) ProtoReflect() protoreflect.Message {
    method Descriptor (line 121) | func (*Config) Descriptor() ([]byte, []int) {
    method GetErrorLogType (line 125) | func (x *Config) GetErrorLogType() LogType {
    method GetErrorLogLevel (line 132) | func (x *Config) GetErrorLogLevel() log.Severity {
    method GetErrorLogPath (line 139) | func (x *Config) GetErrorLogPath() string {
    method GetAccessLogType (line 146) | func (x *Config) GetAccessLogType() LogType {
    method GetAccessLogPath (line 153) | func (x *Config) GetAccessLogPath() string {
  function file_app_log_config_proto_rawDescGZIP (line 202) | func file_app_log_config_proto_rawDescGZIP() []byte {
  function init (line 227) | func init() { file_app_log_config_proto_init() }
  function file_app_log_config_proto_init (line 228) | func file_app_log_config_proto_init() {

FILE: app/log/errors.generated.go
  type errPathObjHolder (line 5) | type errPathObjHolder struct
  function newError (line 7) | func newError(values ...interface{}) *errors.Error {

FILE: app/log/log.go
  type Instance (line 16) | type Instance struct
    method initAccessLogger (line 42) | func (g *Instance) initAccessLogger() error {
    method initErrorLogger (line 53) | func (g *Instance) initErrorLogger() error {
    method Type (line 65) | func (*Instance) Type() interface{} {
    method startInternal (line 69) | func (g *Instance) startInternal() error {
    method Start (line 90) | func (g *Instance) Start() error {
    method Handle (line 95) | func (g *Instance) Handle(msg log.Message) {
    method Close (line 118) | func (g *Instance) Close() error {
  function New (line 25) | func New(ctx context.Context, config *Config) (*Instance, error) {
  function init (line 139) | func init() {

FILE: app/log/log_creator.go
  type HandlerCreatorOptions (line 10) | type HandlerCreatorOptions struct
  type HandlerCreator (line 14) | type HandlerCreator
  function RegisterHandlerCreator (line 20) | func RegisterHandlerCreator(logType LogType, f HandlerCreator) error {
  function createHandler (line 29) | func createHandler(logType LogType, options HandlerCreatorOptions) (log....
  function init (line 37) | func init() {

FILE: app/log/log_test.go
  function TestCustomLogHandler (line 14) | func TestCustomLogHandler(t *testing.T) {

FILE: app/policy/config.go
  method Duration (line 10) | func (s *Second) Duration() time.Duration {
  function defaultPolicy (line 17) | func defaultPolicy() *Policy {
  method overrideWith (line 33) | func (p *Policy_Timeout) overrideWith(another *Policy_Timeout) {
  method overrideWith (line 48) | func (p *Policy) overrideWith(another *Policy) {
  method ToCorePolicy (line 64) | func (p *Policy) ToCorePolicy() policy.Session {
  method ToCorePolicy (line 84) | func (p *SystemPolicy) ToCorePolicy() policy.System {

FILE: app/policy/config.pb.go
  constant _ (line 19) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 21) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  constant _ (line 26) | _ = proto.ProtoPackageIsVersion4
  type Second (line 28) | type Second struct
    method Reset (line 36) | func (x *Second) Reset() {
    method String (line 45) | func (x *Second) String() string {
    method ProtoMessage (line 49) | func (*Second) ProtoMessage() {}
    method ProtoReflect (line 51) | func (x *Second) ProtoReflect() protoreflect.Message {
    method Descriptor (line 64) | func (*Second) Descriptor() ([]byte, []int) {
    method GetValue (line 68) | func (x *Second) GetValue() uint32 {
  type Policy (line 75) | type Policy struct
    method Reset (line 85) | func (x *Policy) Reset() {
    method String (line 94) | func (x *Policy) String() string {
    method ProtoMessage (line 98) | func (*Policy) ProtoMessage() {}
    method ProtoReflect (line 100) | func (x *Policy) ProtoReflect() protoreflect.Message {
    method Descriptor (line 113) | func (*Policy) Descriptor() ([]byte, []int) {
    method GetTimeout (line 117) | func (x *Policy) GetTimeout() *Policy_Timeout {
    method GetStats (line 124) | func (x *Policy) GetStats() *Policy_Stats {
    method GetBuffer (line 131) | func (x *Policy) GetBuffer() *Policy_Buffer {
  type SystemPolicy (line 138) | type SystemPolicy struct
    method Reset (line 146) | func (x *SystemPolicy) Reset() {
    method String (line 155) | func (x *SystemPolicy) String() string {
    method ProtoMessage (line 159) | func (*SystemPolicy) ProtoMessage() {}
    method ProtoReflect (line 161) | func (x *SystemPolicy) ProtoReflect() protoreflect.Message {
    method Descriptor (line 174) | func (*SystemPolicy) Descriptor() ([]byte, []int) {
    method GetStats (line 178) | func (x *SystemPolicy) GetStats() *SystemPolicy_Stats {
  type Config (line 185) | type Config struct
    method Reset (line 194) | func (x *Config) Reset() {
    method String (line 203) | func (x *Config) String() string {
    method ProtoMessage (line 207) | func (*Config) ProtoMessage() {}
    method ProtoReflect (line 209) | func (x *Config) ProtoReflect() protoreflect.Message {
    method Descriptor (line 222) | func (*Config) Descriptor() ([]byte, []int) {
    method GetLevel (line 226) | func (x *Config) GetLevel() map[uint32]*Policy {
    method GetSystem (line 233) | func (x *Config) GetSystem() *SystemPolicy {
  type Policy_Timeout (line 241) | type Policy_Timeout struct
    method Reset (line 252) | func (x *Policy_Timeout) Reset() {
    method String (line 261) | func (x *Policy_Timeout) String() string {
    method ProtoMessage (line 265) | func (*Policy_Timeout) ProtoMessage() {}
    method ProtoReflect (line 267) | func (x *Policy_Timeout) ProtoReflect() protoreflect.Message {
    method Descriptor (line 280) | func (*Policy_Timeout) Descriptor() ([]byte, []int) {
    method GetHandshake (line 284) | func (x *Policy_Timeout) GetHandshake() *Second {
    method GetConnectionIdle (line 291) | func (x *Policy_Timeout) GetConnectionIdle() *Second {
    method GetUplinkOnly (line 298) | func (x *Policy_Timeout) GetUplinkOnly() *Second {
    method GetDownlinkOnly (line 305) | func (x *Policy_Timeout) GetDownlinkOnly() *Second {
  type Policy_Stats (line 312) | type Policy_Stats struct
    method Reset (line 321) | func (x *Policy_Stats) Reset() {
    method String (line 330) | func (x *Policy_Stats) String() string {
    method ProtoMessage (line 334) | func (*Policy_Stats) ProtoMessage() {}
    method ProtoReflect (line 336) | func (x *Policy_Stats) ProtoReflect() protoreflect.Message {
    method Descriptor (line 349) | func (*Policy_Stats) Descriptor() ([]byte, []int) {
    method GetUserUplink (line 353) | func (x *Policy_Stats) GetUserUplink() bool {
    method GetUserDownlink (line 360) | func (x *Policy_Stats) GetUserDownlink() bool {
  type Policy_Buffer (line 367) | type Policy_Buffer struct
    method Reset (line 376) | func (x *Policy_Buffer) Reset() {
    method String (line 385) | func (x *Policy_Buffer) String() string {
    method ProtoMessage (line 389) | func (*Policy_Buffer) ProtoMessage() {}
    method ProtoReflect (line 391) | func (x *Policy_Buffer) ProtoReflect() protoreflect.Message {
    method Descriptor (line 404) | func (*Policy_Buffer) Descriptor() ([]byte, []int) {
    method GetConnection (line 408) | func (x *Policy_Buffer) GetConnection() int32 {
  type SystemPolicy_Stats (line 415) | type SystemPolicy_Stats struct
    method Reset (line 426) | func (x *SystemPolicy_Stats) Reset() {
    method String (line 435) | func (x *SystemPolicy_Stats) String() string {
    method ProtoMessage (line 439) | func (*SystemPolicy_Stats) ProtoMessage() {}
    method ProtoReflect (line 441) | func (x *SystemPolicy_Stats) ProtoReflect() protoreflect.Message {
    method Descriptor (line 454) | func (*SystemPolicy_Stats) Descriptor() ([]byte, []int) {
    method GetInboundUplink (line 458) | func (x *SystemPolicy_Stats) GetInboundUplink() bool {
    method GetInboundDownlink (line 465) | func (x *SystemPolicy_Stats) GetInboundDownlink() bool {
    method GetOutboundUplink (line 472) | func (x *SystemPolicy_Stats) GetOutboundUplink() bool {
    method GetOutboundDownlink (line 479) | func (x *SystemPolicy_Stats) GetOutboundDownlink() bool {
  function file_app_policy_config_proto_rawDescGZIP (line 575) | func file_app_policy_config_proto_rawDescGZIP() []byte {
  function init (line 613) | func init() { file_app_policy_config_proto_init() }
  function file_app_policy_config_proto_init (line 614) | func file_app_policy_config_proto_init() {

FILE: app/policy/errors.generated.go
  type errPathObjHolder (line 5) | type errPathObjHolder struct
  function newError (line 7) | func newError(values ...interface{}) *errors.Error {

FILE: app/policy/manager.go
  type Instance (line 11) | type Instance struct
    method Type (line 34) | func (*Instance) Type() interface{} {
    method ForLevel (line 39) | func (m *Instance) ForLevel(level uint32) policy.Session {
    method ForSystem (line 47) | func (m *Instance) ForSystem() policy.System {
    method Start (line 55) | func (m *Instance) Start() error {
    method Close (line 60) | func (m *Instance) Close() error {
  function New (line 17) | func New(ctx context.Context, config *Config) (*Instance, error) {
  function init (line 64) | func init() {

FILE: app/policy/manager_test.go
  function TestPolicy (line 13) | func TestPolicy(t *testing.T) {

FILE: app/proxyman/command/command.go
  type InboundOperation (line 18) | type InboundOperation interface
  type OutboundOperation (line 24) | type OutboundOperation interface
  function getInbound (line 29) | func getInbound(handler inbound.Handler) (proxy.Inbound, error) {
  method ApplyInbound (line 38) | func (op *AddUserOperation) ApplyInbound(ctx context.Context, handler in...
  method ApplyInbound (line 55) | func (op *RemoveUserOperation) ApplyInbound(ctx context.Context, handler...
  type handlerServer (line 67) | type handlerServer struct
    method AddInbound (line 73) | func (s *handlerServer) AddInbound(ctx context.Context, request *AddIn...
    method RemoveInbound (line 81) | func (s *handlerServer) RemoveInbound(ctx context.Context, request *Re...
    method AlterInbound (line 85) | func (s *handlerServer) AlterInbound(ctx context.Context, request *Alt...
    method AddOutbound (line 103) | func (s *handlerServer) AddOutbound(ctx context.Context, request *AddO...
    method RemoveOutbound (line 110) | func (s *handlerServer) RemoveOutbound(ctx context.Context, request *R...
    method AlterOutbound (line 114) | func (s *handlerServer) AlterOutbound(ctx context.Context, request *Al...
    method mustEmbedUnimplementedHandlerServiceServer (line 128) | func (s *handlerServer) mustEmbedUnimplementedHandlerServiceServer() {}
  type service (line 130) | type service struct
    method Register (line 134) | func (s *service) Register(server *grpc.Server) {
  function init (line 145) | func init() {

FILE: app/proxyman/command/command.pb.go
  constant _ (line 22) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 24) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  constant _ (line 29) | _ = proto.ProtoPackageIsVersion4
  type AddUserOperation (line 31) | type AddUserOperation struct
    method Reset (line 39) | func (x *AddUserOperation) Reset() {
    method String (line 48) | func (x *AddUserOperation) String() string {
    method ProtoMessage (line 52) | func (*AddUserOperation) ProtoMessage() {}
    method ProtoReflect (line 54) | func (x *AddUserOperation) ProtoReflect() protoreflect.Message {
    method Descriptor (line 67) | func (*AddUserOperation) Descriptor() ([]byte, []int) {
    method GetUser (line 71) | func (x *AddUserOperation) GetUser() *protocol.User {
  type RemoveUserOperation (line 78) | type RemoveUserOperation struct
    method Reset (line 86) | func (x *RemoveUserOperation) Reset() {
    method String (line 95) | func (x *RemoveUserOperation) String() string {
    method ProtoMessage (line 99) | func (*RemoveUserOperation) ProtoMessage() {}
    method ProtoReflect (line 101) | func (x *RemoveUserOperation) ProtoReflect() protoreflect.Message {
    method Descriptor (line 114) | func (*RemoveUserOperation) Descriptor() ([]byte, []int) {
    method GetEmail (line 118) | func (x *RemoveUserOperation) GetEmail() string {
  type AddInboundRequest (line 125) | type AddInboundRequest struct
    method Reset (line 133) | func (x *AddInboundRequest) Reset() {
    method String (line 142) | func (x *AddInboundRequest) String() string {
    method ProtoMessage (line 146) | func (*AddInboundRequest) ProtoMessage() {}
    method ProtoReflect (line 148) | func (x *AddInboundRequest) ProtoReflect() protoreflect.Message {
    method Descriptor (line 161) | func (*AddInboundRequest) Descriptor() ([]byte, []int) {
    method GetInbound (line 165) | func (x *AddInboundRequest) GetInbound() *core.InboundHandlerConfig {
  type AddInboundResponse (line 172) | type AddInboundResponse struct
    method Reset (line 178) | func (x *AddInboundResponse) Reset() {
    method String (line 187) | func (x *AddInboundResponse) String() string {
    method ProtoMessage (line 191) | func (*AddInboundResponse) ProtoMessage() {}
    method ProtoReflect (line 193) | func (x *AddInboundResponse) ProtoReflect() protoreflect.Message {
    method Descriptor (line 206) | func (*AddInboundResponse) Descriptor() ([]byte, []int) {
  type RemoveInboundRequest (line 210) | type RemoveInboundRequest struct
    method Reset (line 218) | func (x *RemoveInboundRequest) Reset() {
    method String (line 227) | func (x *RemoveInboundRequest) String() string {
    method ProtoMessage (line 231) | func (*RemoveInboundRequest) ProtoMessage() {}
    method ProtoReflect (line 233) | func (x *RemoveInboundRequest) ProtoReflect() protoreflect.Message {
    method Descriptor (line 246) | func (*RemoveInboundRequest) Descriptor() ([]byte, []int) {
    method GetTag (line 250) | func (x *RemoveInboundRequest) GetTag() string {
  type RemoveInboundResponse (line 257) | type RemoveInboundResponse struct
    method Reset (line 263) | func (x *RemoveInboundResponse) Reset() {
    method String (line 272) | func (x *RemoveInboundResponse) String() string {
    method ProtoMessage (line 276) | func (*RemoveInboundResponse) ProtoMessage() {}
    method ProtoReflect (line 278) | func (x *RemoveInboundResponse) ProtoReflect() protoreflect.Message {
    method Descriptor (line 291) | func (*RemoveInboundResponse) Descriptor() ([]byte, []int) {
  type AlterInboundRequest (line 295) | type AlterInboundRequest struct
    method Reset (line 304) | func (x *AlterInboundRequest) Reset() {
    method String (line 313) | func (x *AlterInboundRequest) String() string {
    method ProtoMessage (line 317) | func (*AlterInboundRequest) ProtoMessage() {}
    method ProtoReflect (line 319) | func (x *AlterInboundRequest) ProtoReflect() protoreflect.Message {
    method Descriptor (line 332) | func (*AlterInboundRequest) Descriptor() ([]byte, []int) {
    method GetTag (line 336) | func (x *AlterInboundRequest) GetTag() string {
    method GetOperation (line 343) | func (x *AlterInboundRequest) GetOperation() *serial.TypedMessage {
  type AlterInboundResponse (line 350) | type AlterInboundResponse struct
    method Reset (line 356) | func (x *AlterInboundResponse) Reset() {
    method String (line 365) | func (x *AlterInboundResponse) String() string {
    method ProtoMessage (line 369) | func (*AlterInboundResponse) ProtoMessage() {}
    method ProtoReflect (line 371) | func (x *AlterInboundResponse) ProtoReflect() protoreflect.Message {
    method Descriptor (line 384) | func (*AlterInboundResponse) Descriptor() ([]byte, []int) {
  type AddOutboundRequest (line 388) | type AddOutboundRequest struct
    method Reset (line 396) | func (x *AddOutboundRequest) Reset() {
    method String (line 405) | func (x *AddOutboundRequest) String() string {
    method ProtoMessage (line 409) | func (*AddOutboundRequest) ProtoMessage() {}
    method ProtoReflect (line 411) | func (x *AddOutboundRequest) ProtoReflect() protoreflect.Message {
    method Descriptor (line 424) | func (*AddOutboundRequest) Descriptor() ([]byte, []int) {
    method GetOutbound (line 428) | func (x *AddOutboundRequest) GetOutbound() *core.OutboundHandlerConfig {
  type AddOutboundResponse (line 435) | type AddOutboundResponse struct
    method Reset (line 441) | func (x *AddOutboundResponse) Reset() {
    method String (line 450) | func (x *AddOutboundResponse) String() string {
    method ProtoMessage (line 454) | func (*AddOutboundResponse) ProtoMessage() {}
    method ProtoReflect (line 456) | func (x *AddOutboundResponse) ProtoReflect() protoreflect.Message {
    method Descriptor (line 469) | func (*AddOutboundResponse) Descriptor() ([]byte, []int) {
  type RemoveOutboundRequest (line 473) | type RemoveOutboundRequest struct
    method Reset (line 481) | func (x *RemoveOutboundRequest) Reset() {
    method String (line 490) | func (x *RemoveOutboundRequest) String() string {
    method ProtoMessage (line 494) | func (*RemoveOutboundRequest) ProtoMessage() {}
    method ProtoReflect (line 496) | func (x *RemoveOutboundRequest) ProtoReflect() protoreflect.Message {
    method Descriptor (line 509) | func (*RemoveOutboundRequest) Descriptor() ([]byte, []int) {
    method GetTag (line 513) | func (x *RemoveOutboundRequest) GetTag() string {
  type RemoveOutboundResponse (line 520) | type RemoveOutboundResponse struct
    method Reset (line 526) | func (x *RemoveOutboundResponse) Reset() {
    method String (line 535) | func (x *RemoveOutboundResponse) String() string {
    method ProtoMessage (line 539) | func (*RemoveOutboundResponse) ProtoMessage() {}
    method ProtoReflect (line 541) | func (x *RemoveOutboundResponse) ProtoReflect() protoreflect.Message {
    method Descriptor (line 554) | func (*RemoveOutboundResponse) Descriptor() ([]byte, []int) {
  type AlterOutboundRequest (line 558) | type AlterOutboundRequest struct
    method Reset (line 567) | func (x *AlterOutboundRequest) Reset() {
    method String (line 576) | func (x *AlterOutboundRequest) String() string {
    method ProtoMessage (line 580) | func (*AlterOutboundRequest) ProtoMessage() {}
    method ProtoReflect (line 582) | func (x *AlterOutboundRequest) ProtoReflect() protoreflect.Message {
    method Descriptor (line 595) | func (*AlterOutboundRequest) Descriptor() ([]byte, []int) {
    method GetTag (line 599) | func (x *AlterOutboundRequest) GetTag() string {
    method GetOperation (line 606) | func (x *AlterOutboundRequest) GetOperation() *serial.TypedMessage {
  type AlterOutboundResponse (line 613) | type AlterOutboundResponse struct
    method Reset (line 619) | func (x *AlterOutboundResponse) Reset() {
    method String (line 628) | func (x *AlterOutboundResponse) String() string {
    method ProtoMessage (line 632) | func (*AlterOutboundResponse) ProtoMessage() {}
    method ProtoReflect (line 634) | func (x *AlterOutboundResponse) ProtoReflect() protoreflect.Message {
    method Descriptor (line 647) | func (*AlterOutboundResponse) Descriptor() ([]byte, []int) {
  type Config (line 651) | type Config struct
    method Reset (line 657) | func (x *Config) Reset() {
    method String (line 666) | func (x *Config) String() string {
    method ProtoMessage (line 670) | func (*Config) ProtoMessage() {}
    method ProtoReflect (line 672) | func (x *Config) ProtoReflect() protoreflect.Message {
    method Descriptor (line 685) | func (*Config) Descriptor() ([]byte, []int) {
  function file_app_proxyman_command_command_proto_rawDescGZIP (line 812) | func file_app_proxyman_command_command_proto_rawDescGZIP() []byte {
  function init (line 866) | func init() { file_app_proxyman_command_command_proto_init() }
  function file_app_proxyman_command_command_proto_init (line 867) | func file_app_proxyman_command_command_proto_init() {

FILE: app/proxyman/command/command_grpc.pb.go
  constant _ (line 14) | _ = grpc.SupportPackageIsVersion7
  type HandlerServiceClient (line 19) | type HandlerServiceClient interface
  type handlerServiceClient (line 28) | type handlerServiceClient struct
    method AddInbound (line 36) | func (c *handlerServiceClient) AddInbound(ctx context.Context, in *Add...
    method RemoveInbound (line 45) | func (c *handlerServiceClient) RemoveInbound(ctx context.Context, in *...
    method AlterInbound (line 54) | func (c *handlerServiceClient) AlterInbound(ctx context.Context, in *A...
    method AddOutbound (line 63) | func (c *handlerServiceClient) AddOutbound(ctx context.Context, in *Ad...
    method RemoveOutbound (line 72) | func (c *handlerServiceClient) RemoveOutbound(ctx context.Context, in ...
    method AlterOutbound (line 81) | func (c *handlerServiceClient) AlterOutbound(ctx context.Context, in *...
  function NewHandlerServiceClient (line 32) | func NewHandlerServiceClient(cc grpc.ClientConnInterface) HandlerService...
  type HandlerServiceServer (line 93) | type HandlerServiceServer interface
  type UnimplementedHandlerServiceServer (line 104) | type UnimplementedHandlerServiceServer struct
    method AddInbound (line 107) | func (UnimplementedHandlerServiceServer) AddInbound(context.Context, *...
    method RemoveInbound (line 110) | func (UnimplementedHandlerServiceServer) RemoveInbound(context.Context...
    method AlterInbound (line 113) | func (UnimplementedHandlerServiceServer) AlterInbound(context.Context,...
    method AddOutbound (line 116) | func (UnimplementedHandlerServiceServer) AddOutbound(context.Context, ...
    method RemoveOutbound (line 119) | func (UnimplementedHandlerServiceServer) RemoveOutbound(context.Contex...
    method AlterOutbound (line 122) | func (UnimplementedHandlerServiceServer) AlterOutbound(context.Context...
    method mustEmbedUnimplementedHandlerServiceServer (line 125) | func (UnimplementedHandlerServiceServer) mustEmbedUnimplementedHandler...
  type UnsafeHandlerServiceServer (line 130) | type UnsafeHandlerServiceServer interface
  function RegisterHandlerServiceServer (line 134) | func RegisterHandlerServiceServer(s *grpc.Server, srv HandlerServiceServ...
  function _HandlerService_AddInbound_Handler (line 138) | func _HandlerService_AddInbound_Handler(srv interface{}, ctx context.Con...
  function _HandlerService_RemoveInbound_Handler (line 156) | func _HandlerService_RemoveInbound_Handler(srv interface{}, ctx context....
  function _HandlerService_AlterInbound_Handler (line 174) | func _HandlerService_AlterInbound_Handler(srv interface{}, ctx context.C...
  function _HandlerService_AddOutbound_Handler (line 192) | func _HandlerService_AddOutbound_Handler(srv interface{}, ctx context.Co...
  function _HandlerService_RemoveOutbound_Handler (line 210) | func _HandlerService_RemoveOutbound_Handler(srv interface{}, ctx context...
  function _HandlerService_AlterOutbound_Handler (line 228) | func _HandlerService_AlterOutbound_Handler(srv interface{}, ctx context....

FILE: app/proxyman/command/errors.generated.go
  type errPathObjHolder (line 5) | type errPathObjHolder struct
  function newError (line 7) | func newError(values ...interface{}) *errors.Error {

FILE: app/proxyman/config.go
  method GetConcurrencyValue (line 3) | func (s *AllocationStrategy) GetConcurrencyValue() uint32 {
  method GetRefreshValue (line 10) | func (s *AllocationStrategy) GetRefreshValue() uint32 {
  method GetEffectiveSniffingSettings (line 17) | func (c *ReceiverConfig) GetEffectiveSniffingSettings() *SniffingConfig {

FILE: app/proxyman/config.pb.go
  constant _ (line 22) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 24) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  constant _ (line 29) | _ = proto.ProtoPackageIsVersion4
  type KnownProtocols (line 31) | type KnownProtocols
    method Enum (line 50) | func (x KnownProtocols) Enum() *KnownProtocols {
    method String (line 56) | func (x KnownProtocols) String() string {
    method Descriptor (line 60) | func (KnownProtocols) Descriptor() protoreflect.EnumDescriptor {
    method Type (line 64) | func (KnownProtocols) Type() protoreflect.EnumType {
    method Number (line 68) | func (x KnownProtocols) Number() protoreflect.EnumNumber {
    method EnumDescriptor (line 73) | func (KnownProtocols) EnumDescriptor() ([]byte, []int) {
  constant KnownProtocols_HTTP (line 34) | KnownProtocols_HTTP KnownProtocols = 0
  constant KnownProtocols_TLS (line 35) | KnownProtocols_TLS  KnownProtocols = 1
  type AllocationStrategy_Type (line 77) | type AllocationStrategy_Type
    method Enum (line 102) | func (x AllocationStrategy_Type) Enum() *AllocationStrategy_Type {
    method String (line 108) | func (x AllocationStrategy_Type) String() string {
    method Descriptor (line 112) | func (AllocationStrategy_Type) Descriptor() protoreflect.EnumDescriptor {
    method Type (line 116) | func (AllocationStrategy_Type) Type() protoreflect.EnumType {
    method Number (line 120) | func (x AllocationStrategy_Type) Number() protoreflect.EnumNumber {
    method EnumDescriptor (line 125) | func (AllocationStrategy_Type) EnumDescriptor() ([]byte, []int) {
  constant AllocationStrategy_Always (line 81) | AllocationStrategy_Always AllocationStrategy_Type = 0
  constant AllocationStrategy_Random (line 83) | AllocationStrategy_Random AllocationStrategy_Type = 1
  constant AllocationStrategy_External (line 85) | AllocationStrategy_External AllocationStrategy_Type = 2
  type InboundConfig (line 129) | type InboundConfig struct
    method Reset (line 135) | func (x *InboundConfig) Reset() {
    method String (line 144) | func (x *InboundConfig) String() string {
    method ProtoMessage (line 148) | func (*InboundConfig) ProtoMessage() {}
    method ProtoReflect (line 150) | func (x *InboundConfig) ProtoReflect() protoreflect.Message {
    method Descriptor (line 163) | func (*InboundConfig) Descriptor() ([]byte, []int) {
  type AllocationStrategy (line 167) | type AllocationStrategy struct
    method Reset (line 181) | func (x *AllocationStrategy) Reset() {
    method String (line 190) | func (x *AllocationStrategy) String() string {
    method ProtoMessage (line 194) | func (*AllocationStrategy) ProtoMessage() {}
    method ProtoReflect (line 196) | func (x *AllocationStrategy) ProtoReflect() protoreflect.Message {
    method Descriptor (line 209) | func (*AllocationStrategy) Descriptor() ([]byte, []int) {
    method GetType (line 213) | func (x *AllocationStrategy) GetType() AllocationStrategy_Type {
    method GetConcurrency (line 220) | func (x *AllocationStrategy) GetConcurrency() *AllocationStrategy_Allo...
    method GetRefresh (line 227) | func (x *AllocationStrategy) GetRefresh() *AllocationStrategy_Allocati...
  type SniffingConfig (line 234) | type SniffingConfig struct
    method Reset (line 246) | func (x *SniffingConfig) Reset() {
    method String (line 255) | func (x *SniffingConfig) String() string {
    method ProtoMessage (line 259) | func (*SniffingConfig) ProtoMessage() {}
    method ProtoReflect (line 261) | func (x *SniffingConfig) ProtoReflect() protoreflect.Message {
    method Descriptor (line 274) | func (*SniffingConfig) Descriptor() ([]byte, []int) {
    method GetEnabled (line 278) | func (x *SniffingConfig) GetEnabled() bool {
    method GetDestinationOverride (line 285) | func (x *SniffingConfig) GetDestinationOverride() []string {
  type ReceiverConfig (line 292) | type ReceiverConfig struct
    method Reset (line 312) | func (x *ReceiverConfig) Reset() {
    method String (line 321) | func (x *ReceiverConfig) String() string {
    method ProtoMessage (line 325) | func (*ReceiverConfig) ProtoMessage() {}
    method ProtoReflect (line 327) | func (x *ReceiverConfig) ProtoReflect() protoreflect.Message {
    method Descriptor (line 340) | func (*ReceiverConfig) Descriptor() ([]byte, []int) {
    method GetPortRange (line 344) | func (x *ReceiverConfig) GetPortRange() *net.PortRange {
    method GetListen (line 351) | func (x *ReceiverConfig) GetListen() *net.IPOrDomain {
    method GetAllocationStrategy (line 358) | func (x *ReceiverConfig) GetAllocationStrategy() *AllocationStrategy {
    method GetStreamSettings (line 365) | func (x *ReceiverConfig) GetStreamSettings() *internet.StreamConfig {
    method GetReceiveOriginalDestination (line 372) | func (x *ReceiverConfig) GetReceiveOriginalDestination() bool {
    method GetDomainOverride (line 380) | func (x *ReceiverConfig) GetDomainOverride() []KnownProtocols {
    method GetSniffingSettings (line 387) | func (x *ReceiverConfig) GetSniffingSettings() *SniffingConfig {
  type InboundHandlerConfig (line 394) | type InboundHandlerConfig struct
    method Reset (line 404) | func (x *InboundHandlerConfig) Reset() {
    method String (line 413) | func (x *InboundHandlerConfig) String() string {
    method ProtoMessage (line 417) | func (*InboundHandlerConfig) ProtoMessage() {}
    method ProtoReflect (line 419) | func (x *InboundHandlerConfig) ProtoReflect() protoreflect.Message {
    method Descriptor (line 432) | func (*InboundHandlerConfig) Descriptor() ([]byte, []int) {
    method GetTag (line 436) | func (x *InboundHandlerConfig) GetTag() string {
    method GetReceiverSettings (line 443) | func (x *InboundHandlerConfig) GetReceiverSettings() *serial.TypedMess...
    method GetProxySettings (line 450) | func (x *InboundHandlerConfig) GetProxySettings() *serial.TypedMessage {
  type OutboundConfig (line 457) | type OutboundConfig struct
    method Reset (line 463) | func (x *OutboundConfig) Reset() {
    method String (line 472) | func (x *OutboundConfig) String() string {
    method ProtoMessage (line 476) | func (*OutboundConfig) ProtoMessage() {}
    method ProtoReflect (line 478) | func (x *OutboundConfig) ProtoReflect() protoreflect.Message {
    method Descriptor (line 491) | func (*OutboundConfig) Descriptor() ([]byte, []int) {
  type SenderConfig (line 495) | type SenderConfig struct
    method Reset (line 507) | func (x *SenderConfig) Reset() {
    method String (line 516) | func (x *SenderConfig) String() string {
    method ProtoMessage (line 520) | func (*SenderConfig) ProtoMessage() {}
    method ProtoReflect (line 522) | func (x *SenderConfig) ProtoReflect() protoreflect.Message {
    method Descriptor (line 535) | func (*SenderConfig) Descriptor() ([]byte, []int) {
    method GetVia (line 539) | func (x *SenderConfig) GetVia() *net.IPOrDomain {
    method GetStreamSettings (line 546) | func (x *SenderConfig) GetStreamSettings() *internet.StreamConfig {
    method GetProxySettings (line 553) | func (x *SenderConfig) GetProxySettings() *internet.ProxyConfig {
    method GetMultiplexSettings (line 560) | func (x *SenderConfig) GetMultiplexSettings() *MultiplexingConfig {
  type MultiplexingConfig (line 567) | type MultiplexingConfig struct
    method Reset (line 578) | func (x *MultiplexingConfig) Reset() {
    method String (line 587) | func (x *MultiplexingConfig) String() string {
    method ProtoMessage (line 591) | func (*MultiplexingConfig) ProtoMessage() {}
    method ProtoReflect (line 593) | func (x *MultiplexingConfig) ProtoReflect() protoreflect.Message {
    method Descriptor (line 606) | func (*MultiplexingConfig) Descriptor() ([]byte, []int) {
    method GetEnabled (line 610) | func (x *MultiplexingConfig) GetEnabled() bool {
    method GetConcurrency (line 617) | func (x *MultiplexingConfig) GetConcurrency() uint32 {
  type AllocationStrategy_AllocationStrategyConcurrency (line 624) | type AllocationStrategy_AllocationStrategyConcurrency struct
    method Reset (line 632) | func (x *AllocationStrategy_AllocationStrategyConcurrency) Reset() {
    method String (line 641) | func (x *AllocationStrategy_AllocationStrategyConcurrency) String() st...
    method ProtoMessage (line 645) | func (*AllocationStrategy_AllocationStrategyConcurrency) ProtoMessage(...
    method ProtoReflect (line 647) | func (x *AllocationStrategy_AllocationStrategyConcurrency) ProtoReflec...
    method Descriptor (line 660) | func (*AllocationStrategy_AllocationStrategyConcurrency) Descriptor() ...
    method GetValue (line 664) | func (x *AllocationStrategy_AllocationStrategyConcurrency) GetValue() ...
  type AllocationStrategy_AllocationStrategyRefresh (line 671) | type AllocationStrategy_AllocationStrategyRefresh struct
    method Reset (line 679) | func (x *AllocationStrategy_AllocationStrategyRefresh) Reset() {
    method String (line 688) | func (x *AllocationStrategy_AllocationStrategyRefresh) String() string {
    method ProtoMessage (line 692) | func (*AllocationStrategy_AllocationStrategyRefresh) ProtoMessage() {}
    method ProtoReflect (line 694) | func (x *AllocationStrategy_AllocationStrategyRefresh) ProtoReflect() ...
    method Descriptor (line 707) | func (*AllocationStrategy_AllocationStrategyRefresh) Descriptor() ([]b...
    method GetValue (line 711) | func (x *AllocationStrategy_AllocationStrategyRefresh) GetValue() uint...
  function file_app_proxyman_config_proto_rawDescGZIP (line 858) | func file_app_proxyman_config_proto_rawDescGZIP() []byte {
  function init (line 909) | func init() { file_app_proxyman_config_proto_init() }
  function file_app_proxyman_config_proto_init (line 910) | func file_app_proxyman_config_proto_init() {

FILE: app/proxyman/inbound/always.go
  function getStatCounter (line 19) | func getStatCounter(v *core.Instance, tag string) (stats.Counter, stats....
  type AlwaysOnInboundHandler (line 44) | type AlwaysOnInboundHandler struct
    method Start (line 130) | func (h *AlwaysOnInboundHandler) Start() error {
    method Close (line 140) | func (h *AlwaysOnInboundHandler) Close() error {
    method GetRandomInboundProxy (line 152) | func (h *AlwaysOnInboundHandler) GetRandomInboundProxy() (interface{},...
    method Tag (line 160) | func (h *AlwaysOnInboundHandler) Tag() string {
    method GetInbound (line 164) | func (h *AlwaysOnInboundHandler) GetInbound() proxy.Inbound {
  function NewAlwaysOnInboundHandler (line 51) | func NewAlwaysOnInboundHandler(ctx context.Context, tag string, receiver...

FILE: app/proxyman/inbound/dynamic.go
  type DynamicInboundHandler (line 18) | type DynamicInboundHandler struct
    method allocatePort (line 71) | func (h *DynamicInboundHandler) allocatePort() net.Port {
    method closeWorkers (line 89) | func (h *DynamicInboundHandler) closeWorkers(workers []worker) {
    method refresh (line 105) | func (h *DynamicInboundHandler) refresh() error {
    method Start (line 179) | func (h *DynamicInboundHandler) Start() error {
    method Close (line 183) | func (h *DynamicInboundHandler) Close() error {
    method GetRandomInboundProxy (line 187) | func (h *DynamicInboundHandler) GetRandomInboundProxy() (interface{}, ...
    method Tag (line 199) | func (h *DynamicInboundHandler) Tag() string {
  function NewDynamicInboundHandler (line 35) | func NewDynamicInboundHandler(ctx context.Context, tag string, receiverC...

FILE: app/proxyman/inbound/errors.generated.go
  type errPathObjHolder (line 5) | type errPathObjHolder struct
  function newError (line 7) | func newError(values ...interface{}) *errors.Error {

FILE: app/proxyman/inbound/inbound.go
  type Manager (line 18) | type Manager struct
    method Type (line 34) | func (*Manager) Type() interface{} {
    method AddHandler (line 39) | func (m *Manager) AddHandler(ctx context.Context, handler inbound.Hand...
    method GetHandler (line 58) | func (m *Manager) GetHandler(ctx context.Context, tag string) (inbound...
    method RemoveHandler (line 70) | func (m *Manager) RemoveHandler(ctx context.Context, tag string) error {
    method Start (line 90) | func (m *Manager) Start() error {
    method Close (line 111) | func (m *Manager) Close() error {
  function New (line 26) | func New(ctx context.Context, config *proxyman.InboundConfig) (*Manager,...
  function NewHandler (line 137) | func NewHandler(ctx context.Context, config *core.InboundHandlerConfig) ...
  function init (line 171) | func init() {

FILE: app/proxyman/inbound/worker.go
  type worker (line 26) | type worker interface
  type tcpWorker (line 33) | type tcpWorker struct
    method callback (line 57) | func (w *tcpWorker) callback(conn internet.Connection) {
    method Proxy (line 108) | func (w *tcpWorker) Proxy() proxy.Inbound {
    method Start (line 112) | func (w *tcpWorker) Start() error {
    method Close (line 124) | func (w *tcpWorker) Close() error {
    method Port (line 141) | func (w *tcpWorker) Port() net.Port {
  function getTProxyType (line 50) | func getTProxyType(s *internet.MemoryStreamConfig) internet.SocketConfig...
  type udpConn (line 145) | type udpConn struct
    method updateActivity (line 157) | func (c *udpConn) updateActivity() {
    method ReadMultiBuffer (line 162) | func (c *udpConn) ReadMultiBuffer() (buf.MultiBuffer, error) {
    method Read (line 176) | func (c *udpConn) Read(buf []byte) (int, error) {
    method Write (line 181) | func (c *udpConn) Write(buf []byte) (int, error) {
    method Close (line 192) | func (c *udpConn) Close() error {
    method RemoteAddr (line 198) | func (c *udpConn) RemoteAddr() net.Addr {
    method LocalAddr (line 202) | func (c *udpConn) LocalAddr() net.Addr {
    method SetDeadline (line 206) | func (*udpConn) SetDeadline(time.Time) error {
    method SetReadDeadline (line 210) | func (*udpConn) SetReadDeadline(time.Time) error {
    method SetWriteDeadline (line 214) | func (*udpConn) SetWriteDeadline(time.Time) error {
  type connID (line 218) | type connID struct
  type udpWorker (line 223) | type udpWorker struct
    method getConnection (line 240) | func (w *udpWorker) getConnection(id connID) (*udpConn, bool) {
    method callback (line 273) | func (w *udpWorker) callback(b *buf.Buffer, source net.Destination, or...
    method removeConn (line 312) | func (w *udpWorker) removeConn(id connID) {
    method handlePackets (line 318) | func (w *udpWorker) handlePackets() {
    method clean (line 325) | func (w *udpWorker) clean() error {
    method Start (line 348) | func (w *udpWorker) Start() error {
    method Close (line 366) | func (w *udpWorker) Close() error {
    method Port (line 394) | func (w *udpWorker) Port() net.Port {
    method Proxy (line 398) | func (w *udpWorker) Proxy() proxy.Inbound {

FILE: app/proxyman/outbound/errors.generated.go
  type errPathObjHolder (line 5) | type errPathObjHolder struct
  function newError (line 7) | func newError(values ...interface{}) *errors.Error {

FILE: app/proxyman/outbound/handler.go
  function getStatCounter (line 22) | func getStatCounter(v *core.Instance, tag string) (stats.Counter, stats....
  type Handler (line 48) | type Handler struct
    method Tag (line 128) | func (h *Handler) Tag() string {
    method Dispatch (line 133) | func (h *Handler) Dispatch(ctx context.Context, link *transport.Link) {
    method Address (line 152) | func (h *Handler) Address() net.Address {
    method Dial (line 160) | func (h *Handler) Dial(ctx context.Context, dest net.Destination) (int...
    method getStatCouterConnection (line 203) | func (h *Handler) getStatCouterConnection(conn internet.Connection) in...
    method GetOutbound (line 215) | func (h *Handler) GetOutbound() proxy.Outbound {
    method Start (line 220) | func (h *Handler) Start() error {
    method Close (line 225) | func (h *Handler) Close() error {
  function NewHandler (line 60) | func NewHandler(ctx context.Context, config *core.OutboundHandlerConfig)...

FILE: app/proxyman/outbound/handler_test.go
  function TestInterfaces (line 18) | func TestInterfaces(t *testing.T) {
  constant v2rayKey (line 23) | v2rayKey core.V2rayKey = 1
  function TestOutboundWithoutStatCounter (line 25) | func TestOutboundWithoutStatCounter(t *testing.T) {
  function TestOutboundWithStatCounter (line 53) | func TestOutboundWithStatCounter(t *testing.T) {

FILE: app/proxyman/outbound/outbound.go
  type Manager (line 18) | type Manager struct
    method Type (line 35) | func (m *Manager) Type() interface{} {
    method Start (line 40) | func (m *Manager) Start() error {
    method Close (line 62) | func (m *Manager) Close() error {
    method GetDefaultHandler (line 81) | func (m *Manager) GetDefaultHandler() outbound.Handler {
    method GetHandler (line 92) | func (m *Manager) GetHandler(tag string) outbound.Handler {
    method AddHandler (line 102) | func (m *Manager) AddHandler(ctx context.Context, handler outbound.Han...
    method RemoveHandler (line 125) | func (m *Manager) RemoveHandler(ctx context.Context, tag string) error {
    method Select (line 141) | func (m *Manager) Select(selectors []string) []string {
  function New (line 27) | func New(ctx context.Context, config *proxyman.OutboundConfig) (*Manager...
  function init (line 163) | func init() {

FILE: app/proxyman/proxyman.go
  function ContextWithSniffingConfig (line 12) | func ContextWithSniffingConfig(ctx context.Context, c *SniffingConfig) c...

FILE: app/reverse/bridge.go
  type Bridge (line 20) | type Bridge struct
    method cleanup (line 49) | func (b *Bridge) cleanup() {
    method monitor (line 63) | func (b *Bridge) monitor() error {
    method Start (line 88) | func (b *Bridge) Start() error {
    method Close (line 92) | func (b *Bridge) Close() error {
  function NewBridge (line 29) | func NewBridge(config *BridgeConfig, dispatcher routing.Dispatcher) (*Br...
  type BridgeWorker (line 96) | type BridgeWorker struct
    method Type (line 131) | func (w *BridgeWorker) Type() interface{} {
    method Start (line 135) | func (w *BridgeWorker) Start() error {
    method Close (line 139) | func (w *BridgeWorker) Close() error {
    method IsActive (line 143) | func (w *BridgeWorker) IsActive() bool {
    method Connections (line 147) | func (w *BridgeWorker) Connections() uint32 {
    method handleInternalConn (line 151) | func (w *BridgeWorker) handleInternalConn(link transport.Link) {
    method Dispatch (line 173) | func (w *BridgeWorker) Dispatch(ctx context.Context, dest net.Destinat...
  function NewBridgeWorker (line 103) | func NewBridgeWorker(domain string, tag string, d routing.Dispatcher) (*...

FILE: app/reverse/config.go
  method FillInRandom (line 12) | func (c *Control) FillInRandom() {

FILE: app/reverse/config.pb.go
  constant _ (line 19) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 21) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  constant _ (line 26) | _ = proto.ProtoPackageIsVersion4
  type Control_State (line 28) | type Control_State
    method Enum (line 47) | func (x Control_State) Enum() *Control_State {
    method String (line 53) | func (x Control_State) String() string {
    method Descriptor (line 57) | func (Control_State) Descriptor() protoreflect.EnumDescriptor {
    method Type (line 61) | func (Control_State) Type() protoreflect.EnumType {
    method Number (line 65) | func (x Control_State) Number() protoreflect.EnumNumber {
    method EnumDescriptor (line 70) | func (Control_State) EnumDescriptor() ([]byte, []int) {
  constant Control_ACTIVE (line 31) | Control_ACTIVE Control_State = 0
  constant Control_DRAIN (line 32) | Control_DRAIN  Control_State = 1
  type Control (line 74) | type Control struct
    method Reset (line 83) | func (x *Control) Reset() {
    method String (line 92) | func (x *Control) String() string {
    method ProtoMessage (line 96) | func (*Control) ProtoMessage() {}
    method ProtoReflect (line 98) | func (x *Control) ProtoReflect() protoreflect.Message {
    method Descriptor (line 111) | func (*Control) Descriptor() ([]byte, []int) {
    method GetState (line 115) | func (x *Control) GetState() Control_State {
    method GetRandom (line 122) | func (x *Control) GetRandom() []byte {
  type BridgeConfig (line 129) | type BridgeConfig struct
    method Reset (line 138) | func (x *BridgeConfig) Reset() {
    method String (line 147) | func (x *BridgeConfig) String() string {
    method ProtoMessage (line 151) | func (*BridgeConfig) ProtoMessage() {}
    method ProtoReflect (line 153) | func (x *BridgeConfig) ProtoReflect() protoreflect.Message {
    method Descriptor (line 166) | func (*BridgeConfig) Descriptor() ([]byte, []int) {
    method GetTag (line 170) | func (x *BridgeConfig) GetTag() string {
    method GetDomain (line 177) | func (x *BridgeConfig) GetDomain() string {
  type PortalConfig (line 184) | type PortalConfig struct
    method Reset (line 193) | func (x *PortalConfig) Reset() {
    method String (line 202) | func (x *PortalConfig) String() string {
    method ProtoMessage (line 206) | func (*PortalConfig) ProtoMessage() {}
    method ProtoReflect (line 208) | func (x *PortalConfig) ProtoReflect() protoreflect.Message {
    method Descriptor (line 221) | func (*PortalConfig) Descriptor() ([]byte, []int) {
    method GetTag (line 225) | func (x *PortalConfig) GetTag() string {
    method GetDomain (line 232) | func (x *PortalConfig) GetDomain() string {
  type Config (line 239) | type Config struct
    method Reset (line 248) | func (x *Config) Reset() {
    method String (line 257) | func (x *Config) String() string {
    method ProtoMessage (line 261) | func (*Config) ProtoMessage() {}
    method ProtoReflect (line 263) | func (x *Config) ProtoReflect() protoreflect.Message {
    method Descriptor (line 276) | func (*Config) Descriptor() ([]byte, []int) {
    method GetBridgeConfig (line 280) | func (x *Config) GetBridgeConfig() []*BridgeConfig {
    method GetPortalConfig (line 287) | func (x *Config) GetPortalConfig() []*PortalConfig {
  function file_app_reverse_config_proto_rawDescGZIP (line 339) | func file_app_reverse_config_proto_rawDescGZIP() []byte {
  function init (line 366) | func init() { file_app_reverse_config_proto_init() }
  function file_app_reverse_config_proto_init (line 367) | func file_app_reverse_config_proto_init() {

FILE: app/reverse/errors.generated.go
  type errPathObjHolder (line 5) | type errPathObjHolder struct
  function newError (line 7) | func newError(values ...interface{}) *errors.Error {

FILE: app/reverse/portal.go
  type Portal (line 22) | type Portal struct
    method Start (line 55) | func (p *Portal) Start() error {
    method Close (line 62) | func (p *Portal) Close() error {
    method HandleConnection (line 66) | func (p *Portal) HandleConnection(ctx context.Context, link *transport...
  function NewPortal (line 30) | func NewPortal(config *PortalConfig, ohm outbound.Manager) (*Portal, err...
  type Outbound (line 90) | type Outbound struct
    method Tag (line 95) | func (o *Outbound) Tag() string {
    method Dispatch (line 99) | func (o *Outbound) Dispatch(ctx context.Context, link *transport.Link) {
    method Start (line 106) | func (o *Outbound) Start() error {
    method Close (line 110) | func (o *Outbound) Close() error {
  type StaticMuxPicker (line 114) | type StaticMuxPicker struct
    method cleanup (line 130) | func (p *StaticMuxPicker) cleanup() error {
    method PickAvailable (line 148) | func (p *StaticMuxPicker) PickAvailable() (*mux.ClientWorker, error) {
    method AddWorker (line 187) | func (p *StaticMuxPicker) AddWorker(worker *PortalWorker) {
  function NewStaticMuxPicker (line 120) | func NewStaticMuxPicker() (*StaticMuxPicker, error) {
  type PortalWorker (line 194) | type PortalWorker struct
    method heartbeat (line 231) | func (w *PortalWorker) heartbeat() error {
    method IsFull (line 260) | func (w *PortalWorker) IsFull() bool {
    method Closed (line 264) | func (w *PortalWorker) Closed() bool {
  function NewPortalWorker (line 202) | func NewPortalWorker(client *mux.ClientWorker) (*PortalWorker, error) {

FILE: app/reverse/portal_test.go
  function TestStaticPickerEmpty (line 10) | func TestStaticPickerEmpty(t *testing.T) {

FILE: app/reverse/reverse.go
  constant internalDomain (line 19) | internalDomain = "reverse.internal.v2ray.com"
  function isDomain (line 22) | func isDomain(dest net.Destination, domain string) bool {
  function isInternalDomain (line 26) | func isInternalDomain(dest net.Destination) bool {
  function init (line 30) | func init() {
  type Reverse (line 42) | type Reverse struct
    method Init (line 47) | func (r *Reverse) Init(config *Config, d routing.Dispatcher, ohm outbo...
    method Type (line 67) | func (r *Reverse) Type() interface{} {
    method Start (line 71) | func (r *Reverse) Start() error {
    method Close (line 87) | func (r *Reverse) Close() error {

FILE: app/router/balancing.go
  type BalancingStrategy (line 10) | type BalancingStrategy interface
  type RandomStrategy (line 14) | type RandomStrategy struct
    method PickOutbound (line 17) | func (s *RandomStrategy) PickOutbound(tags []string) string {
  type Balancer (line 26) | type Balancer struct
    method PickOutbound (line 32) | func (b *Balancer) PickOutbound() (string, error) {

FILE: app/router/command/command.go
  type routingServer (line 20) | type routingServer struct
    method TestRoute (line 33) | func (s *routingServer) TestRoute(ctx context.Context, request *TestRo...
    method SubscribeRoutingStats (line 48) | func (s *routingServer) SubscribeRoutingStats(request *SubscribeRoutin...
    method mustEmbedUnimplementedRoutingServiceServer (line 78) | func (s *routingServer) mustEmbedUnimplementedRoutingServiceServer() {}
  function NewRoutingServer (line 26) | func NewRoutingServer(router routing.Router, routingStats stats.Channel)...
  type service (line 80) | type service struct
    method Register (line 84) | func (s *service) Register(server *grpc.Server) {
  function init (line 90) | func init() {

FILE: app/router/command/command.pb.go
  constant _ (line 20) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 22) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  constant _ (line 27) | _ = proto.ProtoPackageIsVersion4
  type RoutingContext (line 32) | type RoutingContext struct
    method Reset (line 51) | func (x *RoutingContext) Reset() {
    method String (line 60) | func (x *RoutingContext) String() string {
    method ProtoMessage (line 64) | func (*RoutingContext) ProtoMessage() {}
    method ProtoReflect (line 66) | func (x *RoutingContext) ProtoReflect() protoreflect.Message {
    method Descriptor (line 79) | func (*RoutingContext) Descriptor() ([]byte, []int) {
    method GetInboundTag (line 83) | func (x *RoutingContext) GetInboundTag() string {
    method GetNetwork (line 90) | func (x *RoutingContext) GetNetwork() net.Network {
    method GetSourceIPs (line 97) | func (x *RoutingContext) GetSourceIPs() [][]byte {
    method GetTargetIPs (line 104) | func (x *RoutingContext) GetTargetIPs() [][]byte {
    method GetSourcePort (line 111) | func (x *RoutingContext) GetSourcePort() uint32 {
    method GetTargetPort (line 118) | func (x *RoutingContext) GetTargetPort() uint32 {
    method GetTargetDomain (line 125) | func (x *RoutingContext) GetTargetDomain() string {
    method GetProtocol (line 132) | func (x *RoutingContext) GetProtocol() string {
    method GetUser (line 139) | func (x *RoutingContext) GetUser() string {
    method GetAttributes (line 146) | func (x *RoutingContext) GetAttributes() map[string]string {
    method GetOutboundGroupTags (line 153) | func (x *RoutingContext) GetOutboundGroupTags() []string {
    method GetOutboundTag (line 160) | func (x *RoutingContext) GetOutboundTag() string {
  type SubscribeRoutingStatsRequest (line 184) | type SubscribeRoutingStatsRequest struct
    method Reset (line 192) | func (x *SubscribeRoutingStatsRequest) Reset() {
    method String (line 201) | func (x *SubscribeRoutingStatsRequest) String() string {
    method ProtoMessage (line 205) | func (*SubscribeRoutingStatsRequest) ProtoMessage() {}
    method ProtoReflect (line 207) | func (x *SubscribeRoutingStatsRequest) ProtoReflect() protoreflect.Mes...
    method Descriptor (line 220) | func (*SubscribeRoutingStatsRequest) Descriptor() ([]byte, []int) {
    method GetFieldSelectors (line 224) | func (x *SubscribeRoutingStatsRequest) GetFieldSelectors() []string {
  type TestRouteRequest (line 238) | type TestRouteRequest struct
    method Reset (line 248) | func (x *TestRouteRequest) Reset() {
    method String (line 257) | func (x *TestRouteRequest) String() string {
    method ProtoMessage (line 261) | func (*TestRouteRequest) ProtoMessage() {}
    method ProtoReflect (line 263) | func (x *TestRouteRequest) ProtoReflect() protoreflect.Message {
    method Descriptor (line 276) | func (*TestRouteRequest) Descriptor() ([]byte, []int) {
    method GetRoutingContext (line 280) | func (x *TestRouteRequest) GetRoutingContext() *RoutingContext {
    method GetFieldSelectors (line 287) | func (x *TestRouteRequest) GetFieldSelectors() []string {
    method GetPublishResult (line 294) | func (x *TestRouteRequest) GetPublishResult() bool {
  type Config (line 301) | type Config struct
    method Reset (line 307) | func (x *Config) Reset() {
    method String (line 316) | func (x *Config) String() string {
    method ProtoMessage (line 320) | func (*Config) ProtoMessage() {}
    method ProtoReflect (line 322) | func (x *Config) ProtoReflect() protoreflect.Message {
    method Descriptor (line 335) | func (*Config) Descriptor() ([]byte, []int) {
  function file_app_router_command_command_proto_rawDescGZIP (line 430) | func file_app_router_command_command_proto_rawDescGZIP() []byte {
  function init (line 461) | func init() { file_app_router_command_command_proto_init() }
  function file_app_router_command_command_proto_init (line 462) | func file_app_router_command_command_proto_init() {

FILE: app/router/command/command_grpc.pb.go
  constant _ (line 14) | _ = grpc.SupportPackageIsVersion7
  type RoutingServiceClient (line 19) | type RoutingServiceClient interface
  type routingServiceClient (line 24) | type routingServiceClient struct
    method SubscribeRoutingStats (line 32) | func (c *routingServiceClient) SubscribeRoutingStats(ctx context.Conte...
    method TestRoute (line 64) | func (c *routingServiceClient) TestRoute(ctx context.Context, in *Test...
  function NewRoutingServiceClient (line 28) | func NewRoutingServiceClient(cc grpc.ClientConnInterface) RoutingService...
  type RoutingService_SubscribeRoutingStatsClient (line 47) | type RoutingService_SubscribeRoutingStatsClient interface
  type routingServiceSubscribeRoutingStatsClient (line 52) | type routingServiceSubscribeRoutingStatsClient struct
    method Recv (line 56) | func (x *routingServiceSubscribeRoutingStatsClient) Recv() (*RoutingCo...
  type RoutingServiceServer (line 76) | type RoutingServiceServer interface
  type UnimplementedRoutingServiceServer (line 83) | type UnimplementedRoutingServiceServer struct
    method SubscribeRoutingStats (line 86) | func (UnimplementedRoutingServiceServer) SubscribeRoutingStats(*Subscr...
    method TestRoute (line 89) | func (UnimplementedRoutingServiceServer) TestRoute(context.Context, *T...
    method mustEmbedUnimplementedRoutingServiceServer (line 92) | func (UnimplementedRoutingServiceServer) mustEmbedUnimplementedRouting...
  type UnsafeRoutingServiceServer (line 97) | type UnsafeRoutingServiceServer interface
  function RegisterRoutingServiceServer (line 101) | func RegisterRoutingServiceServer(s *grpc.Server, srv RoutingServiceServ...
  function _RoutingService_SubscribeRoutingStats_Handler (line 105) | func _RoutingService_SubscribeRoutingStats_Handler(srv interface{}, stre...
  type RoutingService_SubscribeRoutingStatsServer (line 113) | type RoutingService_SubscribeRoutingStatsServer interface
  type routingServiceSubscribeRoutingStatsServer (line 118) | type routingServiceSubscribeRoutingStatsServer struct
    method Send (line 122) | func (x *routingServiceSubscribeRoutingStatsServer) Send(m *RoutingCon...
  function _RoutingService_TestRoute_Handler (line 126) | func _RoutingService_TestRoute_Handler(srv interface{}, ctx context.Cont...

FILE: app/router/command/command_test.go
  function TestServiceSubscribeRoutingStats (line 22) | func TestServiceSubscribeRoutingStats(t *testing.T) {
  function TestSerivceTestRoute (line 203) | func TestSerivceTestRoute(t *testing.T) {

FILE: app/router/command/config.go
  type routingContext (line 11) | type routingContext struct
    method GetSourceIPs (line 15) | func (c routingContext) GetSourceIPs() []net.IP {
    method GetSourcePort (line 19) | func (c routingContext) GetSourcePort() net.Port {
    method GetTargetIPs (line 23) | func (c routingContext) GetTargetIPs() []net.IP {
    method GetTargetPort (line 27) | func (c routingContext) GetTargetPort() net.Port {
  function AsRoutingContext (line 32) | func AsRoutingContext(r *RoutingContext) routing.Context {
  function AsRoutingRoute (line 37) | func AsRoutingRoute(r *RoutingContext) routing.Route {
  function AsProtobufMessage (line 57) | func AsProtobufMessage(fieldSelectors []string) func(routing.Route) *Rou...
  function mapBytesToIPs (line 80) | func mapBytesToIPs(bytes [][]byte) []net.IP {
  function mapIPsToBytes (line 88) | func mapIPsToBytes(ips []net.IP) [][]byte {

FILE: app/router/command/errors.generated.go
  type errPathObjHolder (line 5) | type errPathObjHolder struct
  function newError (line 7) | func newError(values ...interface{}) *errors.Error {

FILE: app/router/condition.go
  type Condition (line 16) | type Condition interface
  type ConditionChan (line 20) | type ConditionChan
    method Add (line 27) | func (v *ConditionChan) Add(cond Condition) *ConditionChan {
    method Apply (line 33) | func (v *ConditionChan) Apply(ctx routing.Context) bool {
    method Len (line 42) | func (v *ConditionChan) Len() int {
  function NewConditionChan (line 22) | func NewConditionChan() *ConditionChan {
  function domainToMatcher (line 53) | func domainToMatcher(domain *Domain) (strmatcher.Matcher, error) {
  type DomainMatcher (line 67) | type DomainMatcher struct
    method ApplyDomain (line 86) | func (m *DomainMatcher) ApplyDomain(domain string) bool {
    method Apply (line 91) | func (m *DomainMatcher) Apply(ctx routing.Context) bool {
  function NewDomainMatcher (line 71) | func NewDomainMatcher(domains []*Domain) (*DomainMatcher, error) {
  type MultiGeoIPMatcher (line 99) | type MultiGeoIPMatcher struct
    method Apply (line 123) | func (m *MultiGeoIPMatcher) Apply(ctx routing.Context) bool {
  function NewMultiGeoIPMatcher (line 104) | func NewMultiGeoIPMatcher(geoips []*GeoIP, onSource bool) (*MultiGeoIPMa...
  type PortMatcher (line 140) | type PortMatcher struct
    method Apply (line 154) | func (v *PortMatcher) Apply(ctx routing.Context) bool {
  function NewPortMatcher (line 146) | func NewPortMatcher(list *net.PortList, onSource bool) *PortMatcher {
  type NetworkMatcher (line 162) | type NetworkMatcher struct
    method Apply (line 175) | func (v NetworkMatcher) Apply(ctx routing.Context) bool {
  function NewNetworkMatcher (line 166) | func NewNetworkMatcher(network []net.Network) NetworkMatcher {
  type UserMatcher (line 179) | type UserMatcher struct
    method Apply (line 196) | func (v *UserMatcher) Apply(ctx routing.Context) bool {
  function NewUserMatcher (line 183) | func NewUserMatcher(users []string) *UserMatcher {
  type InboundTagMatcher (line 209) | type InboundTagMatcher struct
    method Apply (line 226) | func (v *InboundTagMatcher) Apply(ctx routing.Context) bool {
  function NewInboundTagMatcher (line 213) | func NewInboundTagMatcher(tags []string) *InboundTagMatcher {
  type ProtocolMatcher (line 239) | type ProtocolMatcher struct
    method Apply (line 258) | func (m *ProtocolMatcher) Apply(ctx routing.Context) bool {
  function NewProtocolMatcher (line 243) | func NewProtocolMatcher(protocols []string) *ProtocolMatcher {
  type AttributeMatcher (line 271) | type AttributeMatcher struct
    method Match (line 292) | func (m *AttributeMatcher) Match(attrs map[string]string) bool {
    method Apply (line 313) | func (m *AttributeMatcher) Apply(ctx routing.Context) bool {
  function NewAttributeMatcher (line 275) | func NewAttributeMatcher(code string) (*AttributeMatcher, error) {

FILE: app/router/condition_geoip.go
  type ipv6 (line 12) | type ipv6 struct
  type GeoIPMatcher (line 17) | type GeoIPMatcher struct
    method Init (line 39) | func (m *GeoIPMatcher) Init(cidrs []*CIDR) error {
    method match4 (line 85) | func (m *GeoIPMatcher) match4(ip uint32) bool {
    method match6 (line 119) | func (m *GeoIPMatcher) match6(ip ipv6) bool {
    method Match (line 149) | func (m *GeoIPMatcher) Match(ip net.IP) bool {
  function normalize4 (line 25) | func normalize4(ip uint32, prefix uint8) uint32 {
  function normalize6 (line 29) | func normalize6(ip ipv6, prefix uint8) ipv6 {
  function less6 (line 115) | func less6(a ipv6, b ipv6) bool {
  type GeoIPMatcherContainer (line 164) | type GeoIPMatcherContainer struct
    method Add (line 170) | func (c *GeoIPMatcherContainer) Add(geoip *GeoIP) (*GeoIPMatcher, erro...

FILE: app/router/condition_geoip_test.go
  function init (line 16) | func init() {
  function TestGeoIPMatcherContainer (line 28) | func TestGeoIPMatcherContainer(t *testing.T) {
  function TestGeoIPMatcher (line 55) | func TestGeoIPMatcher(t *testing.T) {
  function TestGeoIPMatcher4CN (line 126) | func TestGeoIPMatcher4CN(t *testing.T) {
  function TestGeoIPMatcher6US (line 138) | func TestGeoIPMatcher6US(t *testing.T) {
  function loadGeoIP (line 150) | func loadGeoIP(country string) ([]*router.CIDR, error) {
  function BenchmarkGeoIPMatcher4CN (line 169) | func BenchmarkGeoIPMatcher4CN(b *testing.B) {
  function BenchmarkGeoIPMatcher6US (line 183) | func BenchmarkGeoIPMatcher6US(b *testing.B) {

FILE: app/router/condition_test.go
  function init (line 24) | func init() {
  function withBackground (line 36) | func withBackground() routing.Context {
  function withOutbound (line 40) | func withOutbound(outbound *session.Outbound) routing.Context {
  function withInbound (line 44) | func withInbound(inbound *session.Inbound) routing.Context {
  function withContent (line 48) | func withContent(content *session.Content) routing.Context {
  function TestRoutingRule (line 52) | func TestRoutingRule(t *testing.T) {
  function loadGeoSite (line 336) | func loadGeoSite(country string) ([]*Domain, error) {
  function TestChinaSites (line 355) | func TestChinaSites(t *testing.T) {
  function BenchmarkMultiGeoIPMatcher (line 397) | func BenchmarkMultiGeoIPMatcher(b *testing.B) {

FILE: app/router/config.go
  type CIDRList (line 12) | type CIDRList
    method Len (line 15) | func (l *CIDRList) Len() int {
    method Less (line 20) | func (l *CIDRList) Less(i int, j int) bool {
    method Swap (line 46) | func (l *CIDRList) Swap(i int, j int) {
  type Rule (line 50) | type Rule struct
    method GetTag (line 56) | func (r *Rule) GetTag() (string, error) {
    method Apply (line 64) | func (r *Rule) Apply(ctx routing.Context) bool {
  method BuildCondition (line 68) | func (rr *RoutingRule) BuildCondition() (Condition, error) {
  method Build (line 150) | func (br *BalancingRule) Build(ohm outbound.Manager) (*Balancer, error) {

FILE: app/router/config.pb.go
  constant _ (line 20) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 22) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  constant _ (line 27) | _ = proto.ProtoPackageIsVersion4
  type Domain_Type (line 30) | type Domain_Type
    method Enum (line 59) | func (x Domain_Type) Enum() *Domain_Type {
    method String (line 65) | func (x Domain_Type) String() string {
    method Descriptor (line 69) | func (Domain_Type) Descriptor() protoreflect.EnumDescriptor {
    method Type (line 73) | func (Domain_Type) Type() protoreflect.EnumType {
    method Number (line 77) | func (x Domain_Type) Number() protoreflect.EnumNumber {
    method EnumDescriptor (line 82) | func (Domain_Type) EnumDescriptor() ([]byte, []int) {
  constant Domain_Plain (line 34) | Domain_Plain Domain_Type = 0
  constant Domain_Regex (line 36) | Domain_Regex Domain_Type = 1
  constant Domain_Domain (line 38) | Domain_Domain Domain_Type = 2
  constant Domain_Full (line 40) | Domain_Full Domain_Type = 3
  type Config_DomainStrategy (line 86) | type Config_DomainStrategy
    method Enum (line 115) | func (x Config_DomainStrategy) Enum() *Config_DomainStrategy {
    method String (line 121) | func (x Config_DomainStrategy) String() string {
    method Descriptor (line 125) | func (Config_DomainStrategy) Descriptor() protoreflect.EnumDescriptor {
    method Type (line 129) | func (Config_DomainStrategy) Type() protoreflect.EnumType {
    method Number (line 133) | func (x Config_DomainStrategy) Number() protoreflect.EnumNumber {
    method EnumDescriptor (line 138) | func (Config_DomainStrategy) EnumDescriptor() ([]byte, []int) {
  constant Config_AsIs (line 90) | Config_AsIs Config_DomainStrategy = 0
  constant Config_UseIp (line 92) | Config_UseIp Config_DomainStrategy = 1
  constant Config_IpIfNonMatch (line 94) | Config_IpIfNonMatch Config_DomainStrategy = 2
  constant Config_IpOnDemand (line 96) | Config_IpOnDemand Config_DomainStrategy = 3
  type Domain (line 143) | type Domain struct
    method Reset (line 156) | func (x *Domain) Reset() {
    method String (line 165) | func (x *Domain) String() string {
    method ProtoMessage (line 169) | func (*Domain) ProtoMessage() {}
    method ProtoReflect (line 171) | func (x *Domain) ProtoReflect() protoreflect.Message {
    method Descriptor (line 184) | func (*Domain) Descriptor() ([]byte, []int) {
    method GetType (line 188) | func (x *Domain) GetType() Domain_Type {
    method GetValue (line 195) | func (x *Domain) GetValue() string {
    method GetAttribute (line 202) | func (x *Domain) GetAttribute() []*Domain_Attribute {
  type CIDR (line 210) | type CIDR struct
    method Reset (line 221) | func (x *CIDR) Reset() {
    method String (line 230) | func (x *CIDR) String() string {
    method ProtoMessage (line 234) | func (*CIDR) ProtoMessage() {}
    method ProtoReflect (line 236) | func (x *CIDR) ProtoReflect() protoreflect.Message {
    method Descriptor (line 249) | func (*CIDR) Descriptor() ([]byte, []int) {
    method GetIp (line 253) | func (x *CIDR) GetIp() []byte {
    method GetPrefix (line 260) | func (x *CIDR) GetPrefix() uint32 {
  type GeoIP (line 267) | type GeoIP struct
    method Reset (line 276) | func (x *GeoIP) Reset() {
    method String (line 285) | func (x *GeoIP) String() string {
    method ProtoMessage (line 289) | func (*GeoIP) ProtoMessage() {}
    method ProtoReflect (line 291) | func (x *GeoIP) ProtoReflect() protoreflect.Message {
    method Descriptor (line 304) | func (*GeoIP) Descriptor() ([]byte, []int) {
    method GetCountryCode (line 308) | func (x *GeoIP) GetCountryCode() string {
    method GetCidr (line 315) | func (x *GeoIP) GetCidr() []*CIDR {
  type GeoIPList (line 322) | type GeoIPList struct
    method Reset (line 330) | func (x *GeoIPList) Reset() {
    method String (line 339) | func (x *GeoIPList) String() string {
    method ProtoMessage (line 343) | func (*GeoIPList) ProtoMessage() {}
    method ProtoReflect (line 345) | func (x *GeoIPList) ProtoReflect() protoreflect.Message {
    method Descriptor (line 358) | func (*GeoIPList) Descriptor() ([]byte, []int) {
    method GetEntry (line 362) | func (x *GeoIPList) GetEntry() []*GeoIP {
  type GeoSite (line 369) | type GeoSite struct
    method Reset (line 378) | func (x *GeoSite) Reset() {
    method String (line 387) | func (x *GeoSite) String() string {
    method ProtoMessage (line 391) | func (*GeoSite) ProtoMessage() {}
    method ProtoReflect (line 393) | func (x *GeoSite) ProtoReflect() protoreflect.Message {
    method Descriptor (line 406) | func (*GeoSite) Descriptor() ([]byte, []int) {
    method GetCountryCode (line 410) | func (x *GeoSite) GetCountryCode() string {
    method GetDomain (line 417) | func (x *GeoSite) GetDomain() []*Domain {
  type GeoSiteList (line 424) | type GeoSiteList struct
    method Reset (line 432) | func (x *GeoSiteList) Reset() {
    method String (line 441) | func (x *GeoSiteList) String() string {
    method ProtoMessage (line 445) | func (*GeoSiteList) ProtoMessage() {}
    method ProtoReflect (line 447) | func (x *GeoSiteList) ProtoReflect() protoreflect.Message {
    method Descriptor (line 460) | func (*GeoSiteList) Descriptor() ([]byte, []int) {
    method GetEntry (line 464) | func (x *GeoSiteList) GetEntry() []*GeoSite {
  type RoutingRule (line 471) | type RoutingRule struct
    method Reset (line 520) | func (x *RoutingRule) Reset() {
    method String (line 529) | func (x *RoutingRule) String() string {
    method ProtoMessage (line 533) | func (*RoutingRule) ProtoMessage() {}
    method ProtoReflect (line 535) | func (x *RoutingRule) ProtoReflect() protoreflect.Message {
    method Descriptor (line 548) | func (*RoutingRule) Descriptor() ([]byte, []int) {
    method GetTargetTag (line 552) | func (m *RoutingRule) GetTargetTag() isRoutingRule_TargetTag {
    method GetTag (line 559) | func (x *RoutingRule) GetTag() string {
    method GetBalancingTag (line 566) | func (x *RoutingRule) GetBalancingTag() string {
    method GetDomain (line 573) | func (x *RoutingRule) GetDomain() []*Domain {
    method GetCidr (line 581) | func (x *RoutingRule) GetCidr() []*CIDR {
    method GetGeoip (line 588) | func (x *RoutingRule) GetGeoip() []*GeoIP {
    method GetPortRange (line 596) | func (x *RoutingRule) GetPortRange() *net.PortRange {
    method GetPortList (line 603) | func (x *RoutingRule) GetPortList() *net.PortList {
    method GetNetworkList (line 611) | func (x *RoutingRule) GetNetworkList() *net.NetworkList {
    method GetNetworks (line 618) | func (x *RoutingRule) GetNetworks() []net.Network {
    method GetSourceCidr (line 626) | func (x *RoutingRule) GetSourceCidr() []*CIDR {
    method GetSourceGeoip (line 633) | func (x *RoutingRule) GetSourceGeoip() []*GeoIP {
    method GetSourcePortList (line 640) | func (x *RoutingRule) GetSourcePortList() *net.PortList {
    method GetUserEmail (line 647) | func (x *RoutingRule) GetUserEmail() []string {
    method GetInboundTag (line 654) | func (x *RoutingRule) GetInboundTag() []string {
    method GetProtocol (line 661) | func (x *RoutingRule) GetProtocol() []string {
    method GetAttributes (line 668) | func (x *RoutingRule) GetAttributes() string {
  type isRoutingRule_TargetTag (line 675) | type isRoutingRule_TargetTag interface
  type RoutingRule_Tag (line 679) | type RoutingRule_Tag struct
    method isRoutingRule_TargetTag (line 689) | func (*RoutingRule_Tag) isRoutingRule_TargetTag() {}
  type RoutingRule_BalancingTag (line 684) | type RoutingRule_BalancingTag struct
    method isRoutingRule_TargetTag (line 691) | func (*RoutingRule_BalancingTag) isRoutingRule_TargetTag() {}
  type BalancingRule (line 693) | type BalancingRule struct
    method Reset (line 702) | func (x *BalancingRule) Reset() {
    method String (line 711) | func (x *BalancingRule) String() string {
    method ProtoMessage (line 715) | func (*BalancingRule) ProtoMessage() {}
    method ProtoReflect (line 717) | func (x *BalancingRule) ProtoReflect() protoreflect.Message {
    method Descriptor (line 730) | func (*BalancingRule) Descriptor() ([]byte, []int) {
    method GetTag (line 734) | func (x *BalancingRule) GetTag() string {
    method GetOutboundSelector (line 741) | func (x *BalancingRule) GetOutboundSelector() []string {
  type Config (line 748) | type Config struct
    method Reset (line 758) | func (x *Config) Reset() {
    method String (line 767) | func (x *Config) String() string {
    method ProtoMessage (line 771) | func (*Config) ProtoMessage() {}
    method ProtoReflect (line 773) | func (x *Config) ProtoReflect() protoreflect.Message {
    method Descriptor (line 786) | func (*Config) Descriptor() ([]byte, []int) {
    method GetDomainStrategy (line 790) | func (x *Config) GetDomainStrategy() Config_DomainStrategy {
    method GetRule (line 797) | func (x *Config) GetRule() []*RoutingRule {
    method GetBalancingRule (line 804) | func (x *Config) GetBalancingRule() []*BalancingRule {
  type Domain_Attribute (line 811) | type Domain_Attribute struct
    method Reset (line 823) | func (x *Domain_Attribute) Reset() {
    method String (line 832) | func (x *Domain_Attribute) String() string {
    method ProtoMessage (line 836) | func (*Domain_Attribute) ProtoMessage() {}
    method ProtoReflect (line 838) | func (x *Domain_Attribute) ProtoReflect() protoreflect.Message {
    method Descriptor (line 851) | func (*Domain_Attribute) Descriptor() ([]byte, []int) {
    method GetKey (line 855) | func (x *Domain_Attribute) GetKey() string {
    method GetTypedValue (line 862) | func (m *Domain_Attribute) GetTypedValue() isDomain_Attribute_TypedVal...
    method GetBoolValue (line 869) | func (x *Domain_Attribute) GetBoolValue() bool {
    method GetIntValue (line 876) | func (x *Domain_Attribute) GetIntValue() int64 {
  type isDomain_Attribute_TypedValue (line 883) | type isDomain_Attribute_TypedValue interface
  type Domain_Attribute_BoolValue (line 887) | type Domain_Attribute_BoolValue struct
    method isDomain_Attribute_TypedValue (line 895) | func (*Domain_Attribute_BoolValue) isDomain_Attribute_TypedValue() {}
  type Domain_Attribute_IntValue (line 891) | type Domain_Attribute_IntValue struct
    method isDomain_Attribute_TypedValue (line 897) | func (*Domain_Attribute_IntValue) isDomain_Attribute_TypedValue() {}
  function file_app_router_config_proto_rawDescGZIP (line 1042) | func file_app_router_config_proto_rawDescGZIP() []byte {
  function init (line 1096) | func init() { file_app_router_config_proto_init() }
  function file_app_router_config_proto_init (line 1097) | func file_app_router_config_proto_init() {

FILE: app/router/errors.generated.go
  type errPathObjHolder (line 5) | type errPathObjHolder struct
  function newError (line 7) | func newError(values ...interface{}) *errors.Error {

FILE: app/router/router.go
  type Router (line 19) | type Router struct
    method Init (line 34) | func (r *Router) Init(config *Config, d dns.Client, ohm outbound.Manag...
    method PickRoute (line 72) | func (r *Router) PickRoute(ctx routing.Context) (routing.Route, error) {
    method pickRouteInternal (line 84) | func (r *Router) pickRouteInternal(ctx routing.Context) (*Rule, routin...
    method Start (line 112) | func (*Router) Start() error {
    method Close (line 117) | func (*Router) Close() error {
    method Type (line 122) | func (*Router) Type() interface{} {
  type Route (line 27) | type Route struct
    method GetOutboundGroupTags (line 127) | func (r *Route) GetOutboundGroupTags() []string {
    method GetOutboundTag (line 132) | func (r *Route) GetOutboundTag() string {
  function init (line 136) | func init() {

FILE: app/router/router_test.go
  type mockOutboundManager (line 17) | type mockOutboundManager struct
  function TestSimpleRouter (line 22) | func TestSimpleRouter(t *testing.T) {
  function TestSimpleBalancer (line 55) | func TestSimpleBalancer(t *testing.T) {
  function TestIPOnDemand (line 96) | func TestIPOnDemand(t *testing.T) {
  function TestIPIfNonMatchDomain (line 131) | func TestIPIfNonMatchDomain(t *testing.T) {
  function TestIPIfNonMatchIP (line 166) | func TestIPIfNonMatchIP(t *testing.T) {

FILE: app/stats/channel.go
  type Channel (line 13) | type Channel struct
    method Subscribers (line 38) | func (c *Channel) Subscribers() []chan interface{} {
    method Subscribe (line 45) | func (c *Channel) Subscribe() (chan interface{}, error) {
    method Unsubscribe (line 57) | func (c *Channel) Unsubscribe(subscriber chan interface{}) error {
    method Publish (line 73) | func (c *Channel) Publish(ctx context.Context, msg interface{}) {
    method Running (line 88) | func (c *Channel) Running() bool {
    method Start (line 100) | func (c *Channel) Start() error {
    method Close (line 130) | func (c *Channel) Close() error {
  function NewChannel (line 28) | func NewChannel(config *ChannelConfig) *Channel {
  type channelMessage (line 141) | type channelMessage struct
    method publish (line 146) | func (c channelMessage) publish(publisher chan channelMessage) {
    method publishNonBlocking (line 153) | func (c channelMessage) publishNonBlocking(publisher chan channelMessa...
    method broadcast (line 161) | func (c channelMessage) broadcast(subscriber chan interface{}) {
    method broadcastNonBlocking (line 168) | func (c channelMessage) broadcastNonBlocking(subscriber chan interface...

FILE: app/stats/channel_test.go
  function TestStatsChannel (line 14) | func TestStatsChannel(t *testing.T) {
  function TestStatsChannelUnsubcribe (line 98) | func TestStatsChannelUnsubcribe(t *testing.T) {
  function TestStatsChannelBlocking (line 188) | func TestStatsChannelBlocking(t *testing.T) {
  function TestStatsChannelNonBlocking (line 262) | func TestStatsChannelNonBlocking(t *testing.T) {
  function TestStatsChannelConcurrency (line 338) | func TestStatsChannelConcurrency(t *testing.T) {

FILE: app/stats/command/command.go
  type statsServer (line 22) | type statsServer struct
    method GetStats (line 34) | func (s *statsServer) GetStats(ctx context.Context, request *GetStatsR...
    method QueryStats (line 53) | func (s *statsServer) QueryStats(ctx context.Context, request *QuerySt...
    method GetSysStats (line 85) | func (s *statsServer) GetSysStats(ctx context.Context, request *SysSta...
    method mustEmbedUnimplementedStatsServiceServer (line 107) | func (s *statsServer) mustEmbedUnimplementedStatsServiceServer() {}
  function NewStatsServer (line 27) | func NewStatsServer(manager feature_stats.Manager) StatsServiceServer {
  type service (line 109) | type service struct
    method Register (line 113) | func (s *service) Register(server *grpc.Server) {
  function init (line 117) | func init() {

FILE: app/stats/command/command.pb.go
  constant _ (line 19) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 21) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  constant _ (line 26) | _ = proto.ProtoPackageIsVersion4
  type GetStatsRequest (line 28) | type GetStatsRequest struct
    method Reset (line 39) | func (x *GetStatsRequest) Reset() {
    method String (line 48) | func (x *GetStatsRequest) String() string {
    method ProtoMessage (line 52) | func (*GetStatsRequest) ProtoMessage() {}
    method ProtoReflect (line 54) | func (x *GetStatsRequest) ProtoReflect() protoreflect.Message {
    method Descriptor (line 67) | func (*GetStatsRequest) Descriptor() ([]byte, []int) {
    method GetName (line 71) | func (x *GetStatsRequest) GetName() string {
    method GetReset_ (line 78) | func (x *GetStatsRequest) GetReset_() bool {
  type Stat (line 85) | type Stat struct
    method Reset (line 94) | func (x *Stat) Reset() {
    method String (line 103) | func (x *Stat) String() string {
    method ProtoMessage (line 107) | func (*Stat) ProtoMessage() {}
    method ProtoReflect (line 109) | func (x *Stat) ProtoReflect() protoreflect.Message {
    method Descriptor (line 122) | func (*Stat) Descriptor() ([]byte, []int) {
    method GetName (line 126) | func (x *Stat) GetName() string {
    method GetValue (line 133) | func (x *Stat) GetValue() int64 {
  type GetStatsResponse (line 140) | type GetStatsResponse struct
    method Reset (line 148) | func (x *GetStatsResponse) Reset() {
    method String (line 157) | func (x *GetStatsResponse) String() string {
    method ProtoMessage (line 161) | func (*GetStatsResponse) ProtoMessage() {}
    method ProtoReflect (line 163) | func (x *GetStatsResponse) ProtoReflect() protoreflect.Message {
    method Descriptor (line 176) | func (*GetStatsResponse) Descriptor() ([]byte, []int) {
    method GetStat (line 180) | func (x *GetStatsResponse) GetStat() *Stat {
  type QueryStatsRequest (line 187) | type QueryStatsRequest struct
    method Reset (line 196) | func (x *QueryStatsRequest) Reset() {
    method String (line 205) | func (x *QueryStatsRequest) String() string {
    method ProtoMessage (line 209) | func (*QueryStatsRequest) ProtoMessage() {}
    method ProtoReflect (line 211) | func (x *QueryStatsRequest) ProtoReflect() protoreflect.Message {
    method Descriptor (line 224) | func (*QueryStatsRequest) Descriptor() ([]byte, []int) {
    method GetPattern (line 228) | func (x *QueryStatsRequest) GetPattern() string {
    method GetReset_ (line 235) | func (x *QueryStatsRequest) GetReset_() bool {
  type QueryStatsResponse (line 242) | type QueryStatsResponse struct
    method Reset (line 250) | func (x *QueryStatsResponse) Reset() {
    method String (line 259) | func (x *QueryStatsResponse) String() string {
    method ProtoMessage (line 263) | func (*QueryStatsResponse) ProtoMessage() {}
    method ProtoReflect (line 265) | func (x *QueryStatsResponse) ProtoReflect() protoreflect.Message {
    method Descriptor (line 278) | func (*QueryStatsResponse) Descriptor() ([]byte, []int) {
    method GetStat (line 282) | func (x *QueryStatsResponse) GetStat() []*Stat {
  type SysStatsRequest (line 289) | type SysStatsRequest struct
    method Reset (line 295) | func (x *SysStatsRequest) Reset() {
    method String (line 304) | func (x *SysStatsRequest) String() string {
    method ProtoMessage (line 308) | func (*SysStatsRequest) ProtoMessage() {}
    method ProtoReflect (line 310) | func (x *SysStatsRequest) ProtoReflect() protoreflect.Message {
    method Descriptor (line 323) | func (*SysStatsRequest) Descriptor() ([]byte, []int) {
  type SysStatsResponse (line 327) | type SysStatsResponse struct
    method Reset (line 344) | func (x *SysStatsResponse) Reset() {
    method String (line 353) | func (x *SysStatsResponse) String() string {
    method ProtoMessage (line 357) | func (*SysStatsResponse) ProtoMessage() {}
    method ProtoReflect (line 359) | func (x *SysStatsResponse) ProtoReflect() protoreflect.Message {
    method Descriptor (line 372) | func (*SysStatsResponse) Descriptor() ([]byte, []int) {
    method GetNumGoroutine (line 376) | func (x *SysStatsResponse) GetNumGoroutine() uint32 {
    method GetNumGC (line 383) | func (x *SysStatsResponse) GetNumGC() uint32 {
    method GetAlloc (line 390) | func (x *SysStatsResponse) GetAlloc() uint64 {
    method GetTotalAlloc (line 397) | func (x *SysStatsResponse) GetTotalAlloc() uint64 {
    method GetSys (line 404) | func (x *SysStatsResponse) GetSys() uint64 {
    method GetMallocs (line 411) | func (x *SysStatsResponse) GetMallocs() uint64 {
    method GetFrees (line 418) | func (x *SysStatsResponse) GetFrees() uint64 {
    method GetLiveObjects (line 425) | func (x *SysStatsResponse) GetLiveObjects() uint64 {
    method GetPauseTotalNs (line 432) | func (x *SysStatsResponse) GetPauseTotalNs() uint64 {
    method GetUptime (line 439) | func (x *SysStatsResponse) GetUptime() uint32 {
  type Config (line 446) | type Config struct
    method Reset (line 452) | func (x *Config) Reset() {
    method String (line 461) | func (x *Config) String() string {
    method ProtoMessage (line 465) | func (*Config) ProtoMessage() {}
    method ProtoReflect (line 467) | func (x *Config) ProtoReflect() protoreflect.Message {
    method Descriptor (line 480) | func (*Config) Descriptor() ([]byte, []int) {
  function file_app_stats_command_command_proto_rawDescGZIP (line 568) | func file_app_stats_command_command_proto_rawDescGZIP() []byte {
  function init (line 602) | func init() { file_app_stats_command_command_proto_init() }
  function file_app_stats_command_command_proto_init (line 603) | func file_app_stats_command_command_proto_init() {

FILE: app/stats/command/command_grpc.pb.go
  constant _ (line 14) | _ = grpc.SupportPackageIsVersion7
  type StatsServiceClient (line 19) | type StatsServiceClient interface
  type statsServiceClient (line 25) | type statsServiceClient struct
    method GetStats (line 33) | func (c *statsServiceClient) GetStats(ctx context.Context, in *GetStat...
    method QueryStats (line 42) | func (c *statsServiceClient) QueryStats(ctx context.Context, in *Query...
    method GetSysStats (line 51) | func (c *statsServiceClient) GetSysStats(ctx context.Context, in *SysS...
  function NewStatsServiceClient (line 29) | func NewStatsServiceClient(cc grpc.ClientConnInterface) StatsServiceClie...
  type StatsServiceServer (line 63) | type StatsServiceServer interface
  type UnimplementedStatsServiceServer (line 71) | type UnimplementedStatsServiceServer struct
    method GetStats (line 74) | func (UnimplementedStatsServiceServer) GetStats(context.Context, *GetS...
    method QueryStats (line 77) | func (UnimplementedStatsServiceServer) QueryStats(context.Context, *Qu...
    method GetSysStats (line 80) | func (UnimplementedStatsServiceServer) GetSysStats(context.Context, *S...
    method mustEmbedUnimplementedStatsServiceServer (line 83) | func (UnimplementedStatsServiceServer) mustEmbedUnimplementedStatsServ...
  type UnsafeStatsServiceServer (line 88) | type UnsafeStatsServiceServer interface
  function RegisterStatsServiceServer (line 92) | func RegisterStatsServiceServer(s *grpc.Server, srv StatsServiceServer) {
  function _StatsService_GetStats_Handler (line 96) | func _StatsService_GetStats_Handler(srv interface{}, ctx context.Context...
  function _StatsService_QueryStats_Handler (line 114) | func _StatsService_QueryStats_Handler(srv interface{}, ctx context.Conte...
  function _StatsService_GetSysStats_Handler (line 132) | func _StatsService_GetSysStats_Handler(srv interface{}, ctx context.Cont...

FILE: app/stats/command/command_test.go
  function TestGetStats (line 15) | func TestGetStats(t *testing.T) {
  function TestQueryStats (line 64) | func TestQueryStats(t *testing.T) {

FILE: app/stats/command/errors.generated.go
  type errPathObjHolder (line 5) | type errPathObjHolder struct
  function newError (line 7) | func newError(values ...interface{}) *errors.Error {

FILE: app/stats/config.pb.go
  constant _ (line 19) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 21) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  constant _ (line 26) | _ = proto.ProtoPackageIsVersion4
  type Config (line 28) | type Config struct
    method Reset (line 34) | func (x *Config) Reset() {
    method String (line 43) | func (x *Config) String() string {
    method ProtoMessage (line 47) | func (*Config) ProtoMessage() {}
    method ProtoReflect (line 49) | func (x *Config) ProtoReflect() protoreflect.Message {
    method Descriptor (line 62) | func (*Config) Descriptor() ([]byte, []int) {
  type ChannelConfig (line 66) | type ChannelConfig struct
    method Reset (line 76) | func (x *ChannelConfig) Reset() {
    method String (line 85) | func (x *ChannelConfig) String() string {
    method ProtoMessage (line 89) | func (*ChannelConfig) ProtoMessage() {}
    method ProtoReflect (line 91) | func (x *ChannelConfig) ProtoReflect() protoreflect.Message {
    method Descriptor (line 104) | func (*ChannelConfig) Descriptor() ([]byte, []int) {
    method GetBlocking (line 108) | func (x *ChannelConfig) GetBlocking() bool {
    method GetSubscriberLimit (line 115) | func (x *ChannelConfig) GetSubscriberLimit() int32 {
    method GetBufferSize (line 122) | func (x *ChannelConfig) GetBufferSize() int32 {
  function file_app_stats_config_proto_rawDescGZIP (line 156) | func file_app_stats_config_proto_rawDescGZIP() []byte {
  function init (line 176) | func init() { file_app_stats_config_proto_init() }
  function file_app_stats_config_proto_init (line 177) | func file_app_stats_config_proto_init() {

FILE: app/stats/counter.go
  type Counter (line 8) | type Counter struct
    method Value (line 13) | func (c *Counter) Value() int64 {
    method Set (line 18) | func (c *Counter) Set(newValue int64) int64 {
    method Add (line 23) | func (c *Counter) Add(delta int64) int64 {

FILE: app/stats/counter_test.go
  function TestStatsCounter (line 12) | func TestStatsCounter(t *testing.T) {

FILE: app/stats/errors.generated.go
  type errPathObjHolder (line 5) | type errPathObjHolder struct
  function newError (line 7) | func newError(values ...interface{}) *errors.Error {

FILE: app/stats/stats.go
  type Manager (line 17) | type Manager struct
    method Type (line 35) | func (*Manager) Type() interface{} {
    method RegisterCounter (line 40) | func (m *Manager) RegisterCounter(name string) (stats.Counter, error) {
    method UnregisterCounter (line 54) | func (m *Manager) UnregisterCounter(name string) error {
    method GetCounter (line 66) | func (m *Manager) GetCounter(name string) stats.Counter {
    method VisitCounters (line 77) | func (m *Manager) VisitCounters(visitor func(string, stats.Counter) bo...
    method RegisterChannel (line 89) | func (m *Manager) RegisterChannel(name string) (stats.Channel, error) {
    method UnregisterChannel (line 106) | func (m *Manager) UnregisterChannel(name string) error {
    method GetChannel (line 119) | func (m *Manager) GetChannel(name string) stats.Channel {
    method Start (line 130) | func (m *Manager) Start() error {
    method Close (line 147) | func (m *Manager) Close() error {
  function NewManager (line 25) | func NewManager(ctx context.Context, config *Config) (*Manager, error) {
  function init (line 165) | func init() {

FILE: app/stats/stats_test.go
  function TestInterface (line 13) | func TestInterface(t *testing.T) {
  function TestStatsChannelRunnable (line 17) | func TestStatsChannelRunnable(t *testing.T) {

FILE: common/antireplay/antireplay.go
  function NewAntiReplayWindow (line 9) | func NewAntiReplayWindow(AntiReplayTime int64) *AntiReplayWindow {
  type AntiReplayWindow (line 15) | type AntiReplayWindow struct
    method Check (line 24) | func (aw *AntiReplayWindow) Check(sum []byte) bool {

FILE: common/bitmask/byte.go
  type Byte (line 4) | type Byte
    method Has (line 7) | func (b Byte) Has(bb Byte) bool {
    method Set (line 11) | func (b *Byte) Set(bb Byte) {
    method Clear (line 15) | func (b *Byte) Clear(bb Byte) {
    method Toggle (line 19) | func (b *Byte) Toggle(bb Byte) {

FILE: common/bitmask/byte_test.go
  function TestBitmaskByte (line 9) | func TestBitmaskByte(t *testing.T) {

FILE: common/buf/buffer.go
  constant Size (line 11) | Size = 2048
  type Buffer (line 17) | type Buffer struct
    method Release (line 24) | func (b *Buffer) Release() {
    method Clear (line 37) | func (b *Buffer) Clear() {
    method Byte (line 43) | func (b *Buffer) Byte(index int32) byte {
    method SetByte (line 48) | func (b *Buffer) SetByte(index int32, value byte) {
    method Bytes (line 53) | func (b *Buffer) Bytes() []byte {
    method Extend (line 59) | func (b *Buffer) Extend(n int32) []byte {
    method BytesRange (line 70) | func (b *Buffer) BytesRange(from, to int32) []byte {
    method BytesFrom (line 81) | func (b *Buffer) BytesFrom(from int32) []byte {
    method BytesTo (line 89) | func (b *Buffer) BytesTo(to int32) []byte {
    method Resize (line 97) | func (b *Buffer) Resize(from, to int32) {
    method Advance (line 112) | func (b *Buffer) Advance(from int32) {
    method Len (line 120) | func (b *Buffer) Len() int32 {
    method IsEmpty (line 128) | func (b *Buffer) IsEmpty() bool {
    method IsFull (line 133) | func (b *Buffer) IsFull() bool {
    method Write (line 138) | func (b *Buffer) Write(data []byte) (int, error) {
    method WriteByte (line 145) | func (b *Buffer) WriteByte(v byte) error {
    method WriteString (line 155) | func (b *Buffer) WriteString(s string) (int, error) {
    method Read (line 160) | func (b *Buffer) Read(data []byte) (int, error) {
    method ReadFrom (line 174) | func (b *Buffer) ReadFrom(reader io.Reader) (int64, error) {
    method ReadFullFrom (line 181) | func (b *Buffer) ReadFullFrom(reader io.Reader, size int32) (int64, er...
    method String (line 193) | func (b *Buffer) String() string {
  function New (line 200) | func New() *Buffer {
  function StackNew (line 208) | func StackNew() Buffer {

FILE: common/buf/buffer_test.go
  function TestBufferClear (line 13) | func TestBufferClear(t *testing.T) {
  function TestBufferIsEmpty (line 29) | func TestBufferIsEmpty(t *testing.T) {
  function TestBufferString (line 38) | func TestBufferString(t *testing.T) {
  function TestBufferByte (line 49) | func TestBufferByte(t *testing.T) {
  function TestBufferResize (line 80) | func TestBufferResize(t *testing.T) {
  function TestBufferSlice (line 105) | func TestBufferSlice(t *testing.T) {
  function TestBufferReadFullFrom (line 134) | func TestBufferReadFullFrom(t *testing.T) {
  function BenchmarkNewBuffer (line 151) | func BenchmarkNewBuffer(b *testing.B) {
  function BenchmarkNewBufferStack (line 158) | func BenchmarkNewBufferStack(b *testing.B) {
  function BenchmarkWrite2 (line 165) | func BenchmarkWrite2(b *testing.B) {
  function BenchmarkWrite8 (line 175) | func BenchmarkWrite8(b *testing.B) {
  function BenchmarkWrite32 (line 185) | func BenchmarkWrite32(b *testing.B) {
  function BenchmarkWriteByte2 (line 197) | func BenchmarkWriteByte2(b *testing.B) {
  function BenchmarkWriteByte8 (line 208) | func BenchmarkWriteByte8(b *testing.B) {

FILE: common/buf/copy.go
  type dataHandler (line 11) | type dataHandler
  type copyHandler (line 13) | type copyHandler struct
  type SizeCounter (line 18) | type SizeCounter struct
  type CopyOption (line 23) | type CopyOption
  function UpdateActivity (line 26) | func UpdateActivity(timer signal.ActivityUpdater) CopyOption {
  function CountSize (line 35) | func CountSize(sc *SizeCounter) CopyOption {
  type readError (line 43) | type readError struct
    method Error (line 47) | func (e readError) Error() string {
    method Inner (line 51) | func (e readError) Inner() error {
  function IsReadError (line 56) | func IsReadError(err error) bool {
  type writeError (line 61) | type writeError struct
    method Error (line 65) | func (e writeError) Error() string {
    method Inner (line 69) | func (e writeError) Inner() error {
  function IsWriteError (line 74) | func IsWriteError(err error) bool {
  function copyInternal (line 79) | func copyInternal(reader Reader, writer Writer, handler *copyHandler) er...
  function Copy (line 99) | func Copy(reader Reader, writer Writer, options ...CopyOption) error {
  function CopyOnceTimeout (line 113) | func CopyOnceTimeout(reader Reader, writer Writer, timeout time.Duration...

FILE: common/buf/copy_test.go
  function TestReadError (line 15) | func TestReadError(t *testing.T) {
  function TestWriteError (line 36) | func TestWriteError(t *testing.T) {
  type TestReader (line 57) | type TestReader struct
    method Read (line 59) | func (TestReader) Read(b []byte) (int, error) {
  function BenchmarkCopy (line 63) | func BenchmarkCopy(b *testing.B) {

FILE: common/buf/errors.generated.go
  type errPathObjHolder (line 5) | type errPathObjHolder struct
  function newError (line 7) | func newError(values ...interface{}) *errors.Error {

FILE: common/buf/io.go
  type Reader (line 12) | type Reader interface
  type TimeoutReader (line 21) | type TimeoutReader interface
  type Writer (line 26) | type Writer interface
  function WriteAllBytes (line 32) | func WriteAllBytes(writer io.Writer, payload []byte) error {
  function isPacketReader (line 43) | func isPacketReader(reader io.Reader) bool {
  function NewReader (line 50) | func NewReader(reader io.Reader) Reader {
  function NewPacketReader (line 79) | func NewPacketReader(reader io.Reader) Reader {
  function isPacketWriter (line 89) | func isPacketWriter(writer io.Writer) bool {
  function NewWriter (line 102) | func NewWriter(writer io.Writer) Writer {

FILE: common/buf/io_test.go
  function TestWriterCreation (line 13) | func TestWriterCreation(t *testing.T) {

FILE: common/buf/multi_buffer.go
  function ReadAllToBytes (line 12) | func ReadAllToBytes(reader io.Reader) ([]byte, error) {
  type MultiBuffer (line 27) | type MultiBuffer
    method Copy (line 66) | func (mb MultiBuffer) Copy(b []byte) int {
    method Len (line 226) | func (mb MultiBuffer) Len() int32 {
    method IsEmpty (line 239) | func (mb MultiBuffer) IsEmpty() bool {
    method String (line 249) | func (mb MultiBuffer) String() string {
  function MergeMulti (line 30) | func MergeMulti(dest MultiBuffer, src MultiBuffer) (MultiBuffer, MultiBu...
  function MergeBytes (line 39) | func MergeBytes(dest MultiBuffer, src []byte) MultiBuffer {
  function ReleaseMulti (line 57) | func ReleaseMulti(mb MultiBuffer) MultiBuffer {
  function ReadFrom (line 79) | func ReadFrom(reader io.Reader) (MultiBuffer, error) {
  function SplitBytes (line 100) | func SplitBytes(mb MultiBuffer, b []byte) (MultiBuffer, int) {
  function SplitFirstBytes (line 126) | func SplitFirstBytes(mb MultiBuffer, p []byte) (MultiBuffer, int) {
  function Compact (line 137) | func Compact(mb MultiBuffer) MultiBuffer {
  function SplitFirst (line 161) | func SplitFirst(mb MultiBuffer) (MultiBuffer, *Buffer) {
  function SplitSize (line 173) | func SplitSize(mb MultiBuffer, size int32) (MultiBuffer, MultiBuffer) {
  function WriteMultiBuffer (line 207) | func WriteMultiBuffer(writer io.Writer, mb MultiBuffer) (MultiBuffer, er...
  type MultiBufferContainer (line 258) | type MultiBufferContainer struct
    method Read (line 263) | func (c *MultiBufferContainer) Read(b []byte) (int, error) {
    method ReadMultiBuffer (line 274) | func (c *MultiBufferContainer) ReadMultiBuffer() (MultiBuffer, error) {
    method Write (line 281) | func (c *MultiBufferContainer) Write(b []byte) (int, error) {
    method WriteMultiBuffer (line 287) | func (c *MultiBufferContainer) WriteMultiBuffer(b MultiBuffer) error {
    method Close (line 294) | func (c *MultiBufferContainer) Close() error {

FILE: common/buf/multi_buffer_test.go
  function TestMultiBufferRead (line 17) | func TestMultiBufferRead(t *testing.T) {
  function TestMultiBufferAppend (line 35) | func TestMultiBufferAppend(t *testing.T) {
  function TestMultiBufferSliceBySizeLarge (line 45) | func TestMultiBufferSliceBySizeLarge(t *testing.T) {
  function TestMultiBufferSplitFirst (line 69) | func TestMultiBufferSplitFirst(t *testing.T) {
  function TestMultiBufferReadAllToByte (line 102) | func TestMultiBufferReadAllToByte(t *testing.T) {
  function TestMultiBufferCopy (line 133) | func TestMultiBufferCopy(t *testing.T) {
  function TestSplitFirstBytes (line 149) | func TestSplitFirstBytes(t *testing.T) {
  function TestCompact (line 167) | func TestCompact(t *testing.T) {
  function BenchmarkSplitBytes (line 181) | func BenchmarkSplitBytes(b *testing.B) {

FILE: common/buf/reader.go
  function readOneUDP (line 10) | func readOneUDP(r io.Reader) (*Buffer, error) {
  function ReadBuffer (line 28) | func ReadBuffer(r io.Reader) (*Buffer, error) {
  type BufferedReader (line 39) | type BufferedReader struct
    method BufferedBytes (line 49) | func (r *BufferedReader) BufferedBytes() int32 {
    method ReadByte (line 54) | func (r *BufferedReader) ReadByte() (byte, error) {
    method Read (line 61) | func (r *BufferedReader) Read(b []byte) (int, error) {
    method ReadMultiBuffer (line 89) | func (r *BufferedReader) ReadMultiBuffer() (MultiBuffer, error) {
    method ReadAtMost (line 100) | func (r *BufferedReader) ReadAtMost(size int32) (MultiBuffer, error) {
    method writeToInternal (line 117) | func (r *BufferedReader) writeToInternal(writer io.Writer) (int64, err...
    method WriteTo (line 133) | func (r *BufferedReader) WriteTo(writer io.Writer) (int64, error) {
    method Interrupt (line 142) | func (r *BufferedReader) Interrupt() {
    method Close (line 147) | func (r *BufferedReader) Close() error {
  type SingleReader (line 152) | type SingleReader struct
    method ReadMultiBuffer (line 157) | func (r *SingleReader) ReadMultiBuffer() (MultiBuffer, error) {
  type PacketReader (line 163) | type PacketReader struct
    method ReadMultiBuffer (line 168) | func (r *PacketReader) ReadMultiBuffer() (MultiBuffer, error) {

FILE: common/buf/reader_test.go
  function TestBytesReaderWriteTo (line 14) | func TestBytesReaderWriteTo(t *testing.T) {
  function TestBytesReaderMultiBuffer (line 41) | func TestBytesReaderMultiBuffer(t *testing.T) {
  function TestReadByte (line 59) | func TestReadByte(t *testing.T) {
  function TestReadBuffer (line 80) | func TestReadBuffer(t *testing.T) {
  function TestReadAtMost (line 94) | func TestReadAtMost(t *testing.T) {
  function TestPacketReader_ReadMultiBuffer (line 113) | func TestPacketReader_ReadMultiBuffer(t *testing.T) {
  function TestReaderInterface (line 124) | func TestReaderInterface(t *testing.T) {

FILE: common/buf/readv_posix.go
  type posixReader (line 12) | type posixReader struct
    method Init (line 16) | func (r *posixReader) Init(bs []*Buffer) {
    method Read (line 30) | func (r *posixReader) Read(fd uintptr) int32 {
    method Clear (line 38) | func (r *posixReader) Clear() {
  function newMultiReader (line 45) | func newMultiReader() multiReader {

FILE: common/buf/readv_reader.go
  type allocStrategy (line 13) | type allocStrategy struct
    method Current (line 17) | func (s *allocStrategy) Current() uint32 {
    method Adjust (line 21) | func (s *allocStrategy) Adjust(n uint32) {
    method Alloc (line 37) | func (s *allocStrategy) Alloc() []*Buffer {
  type multiReader (line 45) | type multiReader interface
  type ReadVReader (line 52) | type ReadVReader struct
    method readMulti (line 71) | func (r *ReadVReader) readMulti() (MultiBuffer, error) {
    method ReadMultiBuffer (line 120) | func (r *ReadVReader) ReadMultiBuffer() (MultiBuffer, error) {
  function NewReadVReader (line 60) | func NewReadVReader(reader io.Reader, rawConn syscall.RawConn) *ReadVRea...
  function init (line 139) | func init() {

FILE: common/buf/readv_reader_wasm.go
  constant useReadv (line 10) | useReadv = false
  function NewReadVReader (line 12) | func NewReadVReader(reader io.Reader, rawConn syscall.RawConn) Reader {

FILE: common/buf/readv_test.go
  function TestReadvReader (line 18) | func TestReadvReader(t *testing.T) {

FILE: common/buf/readv_unix.go
  type unixReader (line 7) | type unixReader struct
    method Init (line 11) | func (r *unixReader) Init(bs []*Buffer) {
    method Read (line 22) | func (r *unixReader) Read(fd uintptr) int32 {
    method Clear (line 30) | func (r *unixReader) Clear() {
  function newMultiReader (line 34) | func newMultiReader() multiReader {

FILE: common/buf/readv_windows.go
  type windowsReader (line 7) | type windowsReader struct
    method Init (line 11) | func (r *windowsReader) Init(bs []*Buffer) {
    method Clear (line 20) | func (r *windowsReader) Clear() {
    method Read (line 27) | func (r *windowsReader) Read(fd uintptr) int32 {
  function newMultiReader (line 37) | func newMultiReader() multiReader {

FILE: common/buf/writer.go
  type BufferToBytesWriter (line 13) | type BufferToBytesWriter struct
    method WriteMultiBuffer (line 20) | func (w *BufferToBytesWriter) WriteMultiBuffer(mb MultiBuffer) error {
    method ReadFrom (line 61) | func (w *BufferToBytesWriter) ReadFrom(reader io.Reader) (int64, error) {
  type BufferedWriter (line 68) | type BufferedWriter struct
    method WriteByte (line 85) | func (w *BufferedWriter) WriteByte(c byte) error {
    method Write (line 90) | func (w *BufferedWriter) Write(b []byte) (int, error) {
    method WriteMultiBuffer (line 127) | func (w *BufferedWriter) WriteMultiBuffer(b MultiBuffer) error {
    method Flush (line 160) | func (w *BufferedWriter) Flush() error {
    method flushInternal (line 167) | func (w *BufferedWriter) flushInternal() error {
    method SetBuffered (line 185) | func (w *BufferedWriter) SetBuffered(f bool) error {
    method ReadFrom (line 197) | func (w *BufferedWriter) ReadFrom(reader io.Reader) (int64, error) {
    method Close (line 208) | func (w *BufferedWriter) Close() error {
  function NewBufferedWriter (line 76) | func NewBufferedWriter(writer Writer) *BufferedWriter {
  type SequentialWriter (line 216) | type SequentialWriter struct
    method WriteMultiBuffer (line 221) | func (w *SequentialWriter) WriteMultiBuffer(mb MultiBuffer) error {
  type noOpWriter (line 227) | type noOpWriter
    method WriteMultiBuffer (line 229) | func (noOpWriter) WriteMultiBuffer(b MultiBuffer) error {
    method Write (line 234) | func (noOpWriter) Write(b []byte) (int, error) {
    method ReadFrom (line 238) | func (noOpWriter) ReadFrom(reader io.Reader) (int64, error) {

FILE: common/buf/writer_test.go
  function TestWriter (line 17) | func TestWriter(t *testing.T) {
  function TestBytesWriterReadFrom (line 35) | func TestBytesWriterReadFrom(t *testing.T) {
  function TestDiscardBytes (line 56) | func TestDiscardBytes(t *testing.T) {
  function TestDiscardBytesMultiBuffer (line 67) | func TestDiscardBytesMultiBuffer(t *testing.T) {
  function TestWriterInterface (line 80) | func TestWriterInterface(t *testing.T) {

FILE: common/bytespool/pool.go
  function createAllocFunc (line 5) | func createAllocFunc(size int32) func() interface{} {
  constant numPools (line 16) | numPools  = 4
  constant sizeMulti (line 17) | sizeMulti = 4
  function init (line 25) | func init() {
  function GetPool (line 40) | func GetPool(size int32) *sync.Pool {
  function Alloc (line 52) | func Alloc(size int32) []byte {
  function Free (line 63) | func Free(b []byte) {

FILE: common/cmdarg/cmdarg.go
  type Arg (line 6) | type Arg
    method String (line 8) | func (c *Arg) String() string {
    method Set (line 13) | func (c *Arg) Set(value string) error {

FILE: common/common.go
  function Must (line 24) | func Must(err error) {
  function Must2 (line 31) | func Must2(v interface{}, err error) interface{} {
  function Error2 (line 37) | func Error2(v interface{}, err error) error {
  function envFile (line 43) | func envFile() (string, error) {
  function GetRuntimeEnv (line 62) | func GetRuntimeEnv(key string) (string, error) {
  function GetGOBIN (line 88) | func GetGOBIN() string {
  function GetGOPATH (line 108) | func GetGOPATH() string {
  function GetModuleName (line 128) | func GetModuleName(pathToProjectRoot string) (string, error) {

FILE: common/common_test.go
  function TestMust (line 10) | func TestMust(t *testing.T) {

FILE: common/crypto/aes.go
  function NewAesDecryptionStream (line 12) | func NewAesDecryptionStream(key []byte, iv []byte) cipher.Stream {
  function NewAesEncryptionStream (line 18) | func NewAesEncryptionStream(key []byte, iv []byte) cipher.Stream {
  function NewAesStreamMethod (line 22) | func NewAesStreamMethod(key []byte, iv []byte, f func(cipher.Block, []by...
  function NewAesCTRStream (line 29) | func NewAesCTRStream(key []byte, iv []byte) cipher.Stream {
  function NewAesGcm (line 34) | func NewAesGcm(key []byte) cipher.AEAD {

FILE: common/crypto/auth.go
  type BytesGenerator (line 14) | type BytesGenerator
  function GenerateEmptyBytes (line 16) | func GenerateEmptyBytes() BytesGenerator {
  function GenerateStaticBytes (line 23) | func GenerateStaticBytes(content []byte) BytesGenerator {
  function GenerateIncreasingNonce (line 29) | func GenerateIncreasingNonce(nonce []byte) BytesGenerator {
  function GenerateInitialAEADNonce (line 42) | func GenerateInitialAEADNonce() BytesGenerator {
  type Authenticator (line 46) | type Authenticator interface
  type AEADAuthenticator (line 53) | type AEADAuthenticator struct
    method Open (line 59) | func (v *AEADAuthenticator) Open(dst, cipherText []byte) ([]byte, erro...
    method Seal (line 72) | func (v *AEADAuthenticator) Seal(dst, plainText []byte) ([]byte, error) {
  type AuthenticationReader (line 85) | type AuthenticationReader struct
    method readSize (line 114) | func (r *AuthenticationReader) readSize() (uint16, uint16, error) {
    method readBuffer (line 132) | func (r *AuthenticationReader) readBuffer(size int32, padding int32) (...
    method readInternal (line 148) | func (r *AuthenticationReader) readInternal(soft bool, mb *buf.MultiBu...
    method ReadMultiBuffer (line 201) | func (r *AuthenticationReader) ReadMultiBuffer() (buf.MultiBuffer, err...
  function NewAuthenticationReader (line 98) | func NewAuthenticationReader(auth Authenticator, sizeParser ChunkSizeDec...
  type AuthenticationWriter (line 223) | type AuthenticationWriter struct
    method seal (line 244) | func (w *AuthenticationWriter) seal(b []byte) (*buf.Buffer, error) {
    method writeStream (line 272) | func (w *AuthenticationWriter) writeStream(mb buf.MultiBuffer) error {
    method writePacket (line 307) | func (w *AuthenticationWriter) writePacket(mb buf.MultiBuffer) error {
    method WriteMultiBuffer (line 333) | func (w *AuthenticationWriter) WriteMultiBuffer(mb buf.MultiBuffer) er...
  function NewAuthenticationWriter (line 231) | func NewAuthenticationWriter(auth Authenticator, sizeParser ChunkSizeEnc...

FILE: common/crypto/auth_test.go
  function TestAuthenticationReaderWriter (line 19) | func TestAuthenticationReaderWriter(t *testing.T) {
  function TestAuthenticationReaderWriterPacket (line 81) | func TestAuthenticationReaderWriterPacket(t *testing.T) {

FILE: common/crypto/benchmark_test.go
  constant benchSize (line 10) | benchSize = 1024 * 1024
  function benchmarkStream (line 12) | func benchmarkStream(b *testing.B, c cipher.Stream) {
  function BenchmarkChaCha20 (line 22) | func BenchmarkChaCha20(b *testing.B) {
  function BenchmarkChaCha20IETF (line 29) | func BenchmarkChaCha20IETF(b *testing.B) {
  function BenchmarkAESEncryption (line 36) | func BenchmarkAESEncryption(b *testing.B) {
  function BenchmarkAESDecryption (line 44) | func BenchmarkAESDecryption(b *testing.B) {

FILE: common/crypto/chacha20.go
  function NewChaCha20Stream (line 11) | func NewChaCha20Stream(key []byte, iv []byte) cipher.Stream {

FILE: common/crypto/chacha20_test.go
  function mustDecodeHex (line 14) | func mustDecodeHex(s string) []byte {
  function TestChaCha20Stream (line 20) | func TestChaCha20Stream(t *testing.T) {
  function TestChaCha20Decoding (line 59) | func TestChaCha20Decoding(t *testing.T) {

FILE: common/crypto/chunk.go
  type ChunkSizeDecoder (line 12) | type ChunkSizeDecoder interface
  type ChunkSizeEncoder (line 18) | type ChunkSizeEncoder interface
  type PaddingLengthGenerator (line 23) | type PaddingLengthGenerator interface
  type PlainChunkSizeParser (line 28) | type PlainChunkSizeParser struct
    method SizeBytes (line 30) | func (PlainChunkSizeParser) SizeBytes() int32 {
    method Encode (line 34) | func (PlainChunkSizeParser) Encode(size uint16, b []byte) []byte {
    method Decode (line 39) | func (PlainChunkSizeParser) Decode(b []byte) (uint16, error) {
  type AEADChunkSizeParser (line 43) | type AEADChunkSizeParser struct
    method SizeBytes (line 47) | func (p *AEADChunkSizeParser) SizeBytes() int32 {
    method Encode (line 51) | func (p *AEADChunkSizeParser) Encode(size uint16, b []byte) []byte {
    method Decode (line 58) | func (p *AEADChunkSizeParser) Decode(b []byte) (uint16, error) {
  type ChunkStreamReader (line 66) | type ChunkStreamReader struct
    method readSize (line 95) | func (r *ChunkStreamReader) readSize() (uint16, error) {
    method ReadMultiBuffer (line 102) | func (r *ChunkStreamReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
  function NewChunkStreamReader (line 76) | func NewChunkStreamReader(sizeDecoder ChunkSizeDecoder, reader io.Reader...
  function NewChunkStreamReaderWithChunkCount (line 80) | func NewChunkStreamReaderWithChunkCount(sizeDecoder ChunkSizeDecoder, re...
  type ChunkStreamWriter (line 128) | type ChunkStreamWriter struct
    method WriteMultiBuffer (line 140) | func (w *ChunkStreamWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
  function NewChunkStreamWriter (line 133) | func NewChunkStreamWriter(sizeEncoder ChunkSizeEncoder, writer io.Writer...

FILE: common/crypto/chunk_test.go
  function TestChunkStreamIO (line 13) | func TestChunkStreamIO(t *testing.T) {

FILE: common/crypto/errors.generated.go
  type errPathObjHolder (line 5) | type errPathObjHolder struct
  function newError (line 7) | func newError(values ...interface{}) *errors.Error {

FILE: common/crypto/internal/chacha.go
  constant wordSize (line 10) | wordSize  = 4
  constant stateSize (line 11) | stateSize = 16
  constant blockSize (line 12) | blockSize = stateSize * wordSize
  type ChaCha20Stream (line 15) | type ChaCha20Stream struct
    method XORKeyStream (line 51) | func (s *ChaCha20Stream) XORKeyStream(dst, src []byte) {
  function NewChaCha20Stream (line 22) | func NewChaCha20Stream(key []byte, nonce []byte, rounds int) *ChaCha20St...

FILE: common/crypto/internal/chacha_core.generated.go
  function ChaCha20Block (line 5) | func ChaCha20Block(s *[16]uint32, out []byte, rounds int) {

FILE: common/crypto/internal/chacha_core_gen.go
  function writeQuarterRound (line 11) | func writeQuarterRound(file *os.File, a, b, c, d int) {
  function writeChacha20Block (line 33) | func writeChacha20Block(file *os.File) {
  function main (line 57) | func main() {

FILE: common/crypto/io.go
  type CryptionReader (line 10) | type CryptionReader struct
    method Read (line 22) | func (r *CryptionReader) Read(data []byte) (int, error) {
  function NewCryptionReader (line 15) | func NewCryptionReader(stream cipher.Stream, reader io.Reader) *Cryption...
  type CryptionWriter (line 34) | type CryptionWriter struct
    method Write (line 50) | func (w *CryptionWriter) Write(data []byte) (int, error) {
    method WriteMultiBuffer (line 60) | func (w *CryptionWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
  function NewCryptionWriter (line 41) | func NewCryptionWriter(stream cipher.Stream, writer io.Writer) *Cryption...

FILE: common/dice/dice.go
  function Roll (line 11) | func Roll(n int) int {
  function RollDeterministic (line 19) | func RollDeterministic(n int, seed int64) int {
  function RollUint16 (line 27) | func RollUint16() uint16 {
  function RollUint64 (line 31) | func RollUint64() uint64 {
  function NewDeterministicDice (line 35) | func NewDeterministicDice(seed int64) *deterministicDice {
  type deterministicDice (line 39) | type deterministicDice struct
    method Roll (line 43) | func (dd *deterministicDice) Roll(n int) int {
  function init (line 50) | func init() {

FILE: common/dice/dice_test.go
  function BenchmarkRoll1 (line 10) | func BenchmarkRoll1(b *testing.B) {
  function BenchmarkRoll20 (line 16) | func BenchmarkRoll20(b *testing.B) {
  function BenchmarkIntn1 (line 22) | func BenchmarkIntn1(b *testing.B) {
  function BenchmarkIntn20 (line 28) | func BenchmarkIntn20(b *testing.B) {

FILE: common/errors.generated.go
  type errPathObjHolder (line 5) | type errPathObjHolder struct
  function newError (line 7) | func newError(values ...interface{}) *errors.Error {

FILE: common/errors/errorgen/main.go
  function main (line 12) | func main() {

FILE: common/errors/errors.go
  type hasInnerError (line 13) | type hasInnerError interface
  type hasSeverity (line 18) | type hasSeverity interface
  type Error (line 23) | type Error struct
    method WithPathObj (line 31) | func (err *Error) WithPathObj(obj interface{}) *Error {
    method pkgPath (line 36) | func (err *Error) pkgPath() string {
    method Error (line 44) | func (err *Error) Error() string {
    method Inner (line 70) | func (err *Error) Inner() error {
    method Base (line 77) | func (err *Error) Base(e error) *Error {
    method atSeverity (line 82) | func (err *Error) atSeverity(s log.Severity) *Error {
    method Severity (line 87) | func (err *Error) Severity() log.Severity {
    method AtDebug (line 103) | func (err *Error) AtDebug() *Error {
    method AtInfo (line 108) | func (err *Error) AtInfo() *Error {
    method AtWarning (line 113) | func (err *Error) AtWarning() *Error {
    method AtError (line 118) | func (err *Error) AtError() *Error {
    method String (line 123) | func (err *Error) String() string {
    method WriteToLog (line 128) | func (err *Error) WriteToLog(opts ...ExportOption) {
  type ExportOptionHolder (line 145) | type ExportOptionHolder struct
  type ExportOption (line 149) | type ExportOption
  function New (line 152) | func New(msg ...interface{}) *Error {
  function Cause (line 160) | func Cause(err error) error {
  function GetSeverity (line 190) | func GetSeverity(err error) log.Severity {

FILE: common/errors/errors_test.go
  function TestError (line 14) | func TestError(t *testing.T) {
  type e (line 40) | type e struct
  function TestErrorMessage (line 42) | func TestErrorMessage(t *testing.T) {

FILE: common/errors/multi_error.go
  type multiError (line 7) | type multiError
    method Error (line 9) | func (e multiError) Error() string {
  function Combine (line 19) | func Combine(maybeError ...error) error {

FILE: common/interfaces.go
  type Closable (line 8) | type Closable interface
  type Interruptible (line 16) | type Interruptible interface
  function Close (line 23) | func Close(obj interface{}) error {
  function Interrupt (line 33) | func Interrupt(obj interface{}) error {
  type Runnable (line 42) | type Runnable interface
  type HasType (line 50) | type HasType interface
  type ChainedClosable (line 57) | type ChainedClosable
    method Close (line 60) | func (cc ChainedClosable) Close() error {

FILE: common/log/access.go
  type logKey (line 10) | type logKey
  constant accessMessageKey (line 13) | accessMessageKey logKey = iota
  type AccessStatus (line 16) | type AccessStatus
  constant AccessAccepted (line 19) | AccessAccepted = AccessStatus("accepted")
  constant AccessRejected (line 20) | AccessRejected = AccessStatus("rejected")
  type AccessMessage (line 23) | type AccessMessage struct
    method String (line 32) | func (m *AccessMessage) String() string {
  function ContextWithAccessMessage (line 55) | func ContextWithAccessMessage(ctx context.Context, accessMessage *Access...
  function AccessMessageFromContext (line 59) | func AccessMessageFromContext(ctx context.Context) *AccessMessage {

FILE: common/log/log.go
  type Message (line 10) | type Message interface
  type Handler (line 15) | type Handler interface
  type GeneralMessage (line 20) | type GeneralMessage struct
    method String (line 26) | func (m *GeneralMessage) String() string {
  function Record (line 31) | func Record(msg Message) {
  function RegisterHandler (line 40) | func RegisterHandler(handler Handler) {
  type syncHandler (line 47) | type syncHandler struct
    method Handle (line 52) | func (h *syncHandler) Handle(msg Message) {
    method Set (line 61) | func (h *syncHandler) Set(handler Handler) {

FILE: common/log/log.pb.go
  constant _ (line 19) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 21) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  constant _ (line 26) | _ = proto.ProtoPackageIsVersion4
  type Severity (line 28) | type Severity
    method Enum (line 56) | func (x Severity) Enum() *Severity {
    method String (line 62) | func (x Severity) String() string {
    method Descriptor (line 66) | func (Severity) Descriptor() protoreflect.EnumDescriptor {
    method Type (line 70) | func (Severity) Type() protoreflect.EnumType {
    method Number (line 74) | func (x Severity) Number() protoreflect.EnumNumber {
    method EnumDescriptor (line 79) | func (Severity) EnumDescriptor() ([]byte, []int) {
  constant Severity_Unknown (line 31) | Severity_Unknown Severity = 0
  constant Severity_Error (line 32) | Severity_Error   Severity = 1
  constant Severity_Warning (line 33) | Severity_Warning Severity = 2
  constant Severity_Info (line 34) | Severity_Info    Severity = 3
  constant Severity_Debug (line 35) | Severity_Debug   Severity = 4
  function file_common_log_log_proto_rawDescGZIP (line 106) | func file_common_log_log_proto_rawDescGZIP() []byte {
  function init (line 125) | func init() { file_common_log_log_proto_init() }
  function file_common_log_log_proto_init (line 126) | func file_common_log_log_proto_init() {

FILE: common/log/log_test.go
  type testLogger (line 12) | type testLogger struct
    method Handle (line 16) | func (l *testLogger) Handle(msg log.Message) {
  function TestLogRecord (line 20) | func TestLogRecord(t *testing.T) {

FILE: common/log/logger.go
  type Writer (line 15) | type Writer interface
  type WriterCreator (line 21) | type WriterCreator
  type generalLogger (line 23) | type generalLogger struct
    method run (line 40) | func (l *generalLogger) run() {
    method Handle (line 69) | func (l *generalLogger) Handle(msg Message) {
    method Close (line 82) | func (l *generalLogger) Close() error {
  function NewLogger (line 31) | func NewLogger(logWriterCreator WriterCreator) Handler {
  type consoleLogWriter (line 86) | type consoleLogWriter struct
    method Write (line 90) | func (w *consoleLogWriter) Write(s string) error {
    method Close (line 95) | func (w *consoleLogWriter) Close() error {
  type fileLogWriter (line 99) | type fileLogWriter struct
    method Write (line 104) | func (w *fileLogWriter) Write(s string) error {
    method Close (line 109) | func (w *fileLogWriter) Close() error {
  function CreateStdoutLogWriter (line 114) | func CreateStdoutLogWriter() WriterCreator {
  function CreateStderrLogWriter (line 123) | func CreateStderrLogWriter() WriterCreator {
  function CreateFileLogWriter (line 132) | func CreateFileLogWriter(path string) (WriterCreator, error) {
  function init (line 150) | func init() {

FILE: common/log/logger_test.go
  function TestFileLogger (line 15) | func TestFileLogger(t *testing.T) {

FILE: common/mux/client.go
  type ClientManager (line 23) | type ClientManager struct
    method Dispatch (line 28) | func (m *ClientManager) Dispatch(ctx context.Context, link *transport....
  type WorkerPicker (line 42) | type WorkerPicker interface
  type IncrementalWorkerPicker (line 46) | type IncrementalWorkerPicker struct
    method cleanupFunc (line 54) | func (p *IncrementalWorkerPicker) cleanupFunc() error {
    method cleanup (line 66) | func (p *IncrementalWorkerPicker) cleanup() {
    method findAvailable (line 76) | func (p *IncrementalWorkerPicker) findAvailable() int {
    method pickInternal (line 86) | func (p *IncrementalWorkerPicker) pickInternal() (*ClientWorker, bool,...
    method PickAvailable (line 117) | func (p *IncrementalWorkerPicker) PickAvailable() (*ClientWorker, erro...
  type ClientWorkerFactory (line 126) | type ClientWorkerFactory interface
  type DialingWorkerFactory (line 130) | type DialingWorkerFactory struct
    method Create (line 136) | func (f *DialingWorkerFactory) Create() (*ClientWorker, error) {
  type ClientStrategy (line 166) | type ClientStrategy struct
  type ClientWorker (line 171) | type ClientWorker struct
    method TotalConnections (line 196) | func (m *ClientWorker) TotalConnections() uint32 {
    method ActiveConnections (line 200) | func (m *ClientWorker) ActiveConnections() uint32 {
    method Closed (line 205) | func (m *ClientWorker) Closed() bool {
    method monitor (line 209) | func (m *ClientWorker) monitor() {
    method IsClosing (line 269) | func (m *ClientWorker) IsClosing() bool {
    method IsFull (line 277) | func (m *ClientWorker) IsFull() bool {
    method Dispatch (line 289) | func (m *ClientWorker) Dispatch(ctx context.Context, link *transport.L...
    method handleStatueKeepAlive (line 305) | func (m *ClientWorker) handleStatueKeepAlive(meta *FrameMetadata, read...
    method handleStatusNew (line 312) | func (m *ClientWorker) handleStatusNew(meta *FrameMetadata, reader *bu...
    method handleStatusKeep (line 319) | func (m *ClientWorker) handleStatusKeep(meta *FrameMetadata, reader *b...
    method handleStatusEnd (line 351) | func (m *ClientWorker) handleStatusEnd(meta *FrameMetadata, reader *bu...
    method fetchOutput (line 365) | func (m *ClientWorker) fetchOutput() {
  function NewClientWorker (line 182) | func NewClientWorker(stream transport.Link, s ClientStrategy) (*ClientWo...
  function writeFirstPayload (line 229) | func writeFirstPayload(reader buf.Reader, writer *Writer) error {
  function fetchInput (line 242) | func fetchInput(ctx context.Context, s *Session, output buf.Writer) {

FILE: common/mux/client_test.go
  function TestIncrementalPickerFailure (line 19) | func TestIncrementalPickerFailure(t *testing.T) {
  function TestClientWorkerEOF (line 36) | func TestClientWorkerEOF(t *testing.T) {
  function TestClientWorkerClose (line 51) | func TestClientWorkerClose(t *testing.T) {

FILE: common/mux/errors.generated.go
  type errPathObjHolder (line 5) | type errPathObjHolder struct
  function newError (line 7) | func newError(values ...interface{}) *errors.Error {

FILE: common/mux/frame.go
  type SessionStatus (line 15) | type SessionStatus
  constant SessionStatusNew (line 18) | SessionStatusNew       SessionStatus = 0x01
  constant SessionStatusKeep (line 19) | SessionStatusKeep      SessionStatus = 0x02
  constant SessionStatusEnd (line 20) | SessionStatusEnd       SessionStatus = 0x03
  constant SessionStatusKeepAlive (line 21) | SessionStatusKeepAlive SessionStatus = 0x04
  constant OptionData (line 25) | OptionData  bitmask.Byte = 0x01
  constant OptionError (line 26) | OptionError bitmask.Byte = 0x02
  type TargetNetwork (line 29) | type TargetNetwork
  constant TargetNetworkTCP (line 32) | TargetNetworkTCP TargetNetwork = 0x01
  constant TargetNetworkUDP (line 33) | TargetNetworkUDP TargetNetwork = 0x02
  type FrameMetadata (line 56) | type FrameMetadata struct
    method WriteTo (line 63) | func (f FrameMetadata) WriteTo(b *buf.Buffer) error {
    method Unmarshal (line 92) | func (f *FrameMetadata) Unmarshal(reader io.Reader) error {
    method UnmarshalFromBuffer (line 112) | func (f *FrameMetadata) UnmarshalFromBuffer(b *buf.Buffer) error {

FILE: common/mux/frame_test.go
  function BenchmarkFrameWrite (line 12) | func BenchmarkFrameWrite(b *testing.B) {

FILE: common/mux/mux_test.go
  function readAll (line 17) | func readAll(reader buf.Reader) (buf.MultiBuffer, error) {
  function TestReaderWriter (line 32) | func TestReaderWriter(t *testing.T) {

FILE: common/mux/reader.go
  type PacketReader (line 12) | type PacketReader struct
    method ReadMultiBuffer (line 26) | func (r *PacketReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
  function NewPacketReader (line 18) | func NewPacketReader(reader io.Reader) *PacketReader {
  function NewStreamReader (line 50) | func NewStreamReader(reader *buf.BufferedReader) buf.Reader {

FILE: common/mux/server.go
  type Server (line 20) | type Server struct
    method Type (line 34) | func (s *Server) Type() interface{} {
    method Dispatch (line 39) | func (s *Server) Dispatch(ctx context.Context, dest net.Destination) (...
    method Start (line 60) | func (s *Server) Start() error {
    method Close (line 65) | func (s *Server) Close() error {
  function NewServer (line 25) | func NewServer(ctx context.Context) *Server {
  type ServerWorker (line 69) | type ServerWorker struct
    method ActiveConnections (line 96) | func (w *ServerWorker) ActiveConnections() uint32 {
    method Closed (line 100) | func (w *ServerWorker) Closed() bool {
    method handleStatusKeepAlive (line 104) | func (w *ServerWorker) handleStatusKeepAlive(meta *FrameMetadata, read...
    method handleStatusNew (line 111) | func (w *ServerWorker) handleStatusNew(ctx context.Context, meta *Fram...
    method handleStatusKeep (line 157) | func (w *ServerWorker) handleStatusKeep(meta *FrameMetadata, reader *b...
    method handleStatusEnd (line 190) | func (w *ServerWorker) handleStatusEnd(meta *FrameMetadata, reader *bu...
    method handleFrame (line 204) | func (w *ServerWorker) handleFrame(ctx context.Context, reader *buf.Bu...
    method run (line 231) | func (w *ServerWorker) run(ctx context.Context) {
  function NewServerWorker (line 75) | func NewServerWorker(ctx context.Context, d routing.Dispatcher, link *tr...
  function handle (line 85) | func handle(ctx context.Context, s *Session, output buf.Writer) {

FILE: common/mux/session.go
  type SessionManager (line 11) | type SessionManager struct
    method Closed (line 25) | func (m *SessionManager) Closed() bool {
    method Size (line 32) | func (m *SessionManager) Size() int {
    method Count (line 39) | func (m *SessionManager) Count() int {
    method Allocate (line 46) | func (m *SessionManager) Allocate() *Session {
    method Add (line 63) | func (m *SessionManager) Add(s *Session) {
    method Remove (line 75) | func (m *SessionManager) Remove(id uint16) {
    method Get (line 90) | func (m *SessionManager) Get(id uint16) (*Session, bool) {
    method CloseIfNoSession (line 102) | func (m *SessionManager) CloseIfNoSession() bool {
    method Close (line 118) | func (m *SessionManager) Close() error {
  function NewSessionManager (line 18) | func NewSessionManager() *SessionManager {
  type Session (line 138) | type Session struct
    method Close (line 147) | func (s *Session) Close() error {
    method NewReader (line 155) | func (s *Session) NewReader(reader *buf.BufferedReader) buf.Reader {

FILE: common/mux/session_test.go
  function TestSessionManagerAdd (line 9) | func TestSessionManagerAdd(t *testing.T) {
  function TestSessionManagerClose (line 40) | func TestSessionManagerClose(t *testing.T) {

FILE: common/mux/writer.go
  type Writer (line 11) | type Writer struct
    method getNextFrameMeta (line 39) | func (w *Writer) getNextFrameMeta() FrameMetadata {
    method writeMetaOnly (line 55) | func (w *Writer) writeMetaOnly() error {
    method writeData (line 79) | func (w *Writer) writeData(mb buf.MultiBuffer) error {
    method WriteMultiBuffer (line 87) | func (w *Writer) WriteMultiBuffer(mb buf.MultiBuffer) error {
    method Close (line 112) | func (w *Writer) Close() error {
  function NewWriter (line 20) | func NewWriter(id uint16, dest net.Destination, writer buf.Writer, trans...
  function NewResponseWriter (line 30) | func NewResponseWriter(id uint16, writer buf.Writer, transferType protoc...
  function writeMetaWithFrame (line 64) | func writeMetaWithFrame(writer buf.Writer, meta FrameMetadata, data buf....

FILE: common/net/address.go
  type AddressFamily (line 27) | type AddressFamily
    method IsIPv4 (line 41) | func (af AddressFamily) IsIPv4() bool {
    method IsIPv6 (line 46) | func (af AddressFamily) IsIPv6() bool {
    method IsIP (line 51) | func (af AddressFamily) IsIP() bool {
    method IsDomain (line 56) | func (af AddressFamily) IsDomain() bool {
  constant AddressFamilyIPv4 (line 31) | AddressFamilyIPv4 = AddressFamily(0)
  constant AddressFamilyIPv6 (line 34) | AddressFamilyIPv6 = AddressFamily(1)
  constant AddressFamilyDomain (line 37) | AddressFamilyDomain = AddressFamily(2)
  type Address (line 62) | type Address interface
  function isAlphaNum (line 70) | func isAlphaNum(c byte) bool {
  function ParseAddress (line 76) | func ParseAddress(addr string) Address {
  function IPAddress (line 98) | func IPAddress(ip []byte) Address {
  function DomainAddress (line 121) | func DomainAddress(domain string) Address {
  type ipv4Address (line 125) | type ipv4Address
    method IP (line 127) | func (a ipv4Address) IP() net.IP {
    method Domain (line 131) | func (ipv4Address) Domain() string {
    method Family (line 135) | func (ipv4Address) Family() AddressFamily {
    method String (line 139) | func (a ipv4Address) String() string {
  type ipv6Address (line 143) | type ipv6Address
    method IP (line 145) | func (a ipv6Address) IP() net.IP {
    method Domain (line 149) | func (ipv6Address) Domain() string {
    method Family (line 153) | func (ipv6Address) Family() AddressFamily {
    method String (line 157) | func (a ipv6Address) String() string {
  type domainAddress (line 161) | type domainAddress
    method IP (line 163) | func (domainAddress) IP() net.IP {
    method Domain (line 167) | func (a domainAddress) Domain() string {
    method Family (line 171) | func (domainAddress) Family() AddressFamily {
    method String (line 175) | func (a domainAddress) String() string {
  method AsAddress (line 180) | func (d *IPOrDomain) AsAddress() Address {
  function NewIPOrDomain (line 194) | func NewIPOrDomain(addr Address) *IPOrDomain {

FILE: common/net/address.pb.go
  constant _ (line 19) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 21) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  constant _ (line 26) | _ = proto.ProtoPackageIsVersion4
  type IPOrDomain (line 30) | type IPOrDomain struct
    method Reset (line 41) | func (x *IPOrDomain) Reset() {
    method String (line 50) | func (x *IPOrDomain) String() string {
    method ProtoMessage (line 54) | func (*IPOrDomain) ProtoMessage() {}
    method ProtoReflect (line 56) | func (x *IPOrDomain) ProtoReflect() protoreflect.Message {
    method Descriptor (line 69) | func (*IPOrDomain) Descriptor() ([]byte, []int) {
    method GetAddress (line 73) | func (m *IPOrDomain) GetAddress() isIPOrDomain_Address {
    method GetIp (line 80) | func (x *IPOrDomain) GetIp() []byte {
    method GetDomain (line 87) | func (x *IPOrDomain) GetDomain() string {
  type isIPOrDomain_Address (line 94) | type isIPOrDomain_Address interface
  type IPOrDomain_Ip (line 98) | type IPOrDomain_Ip struct
    method isIPOrDomain_Address (line 108) | func (*IPOrDomain_Ip) isIPOrDomain_Address() {}
  type IPOrDomain_Domain (line 103) | type IPOrDomain_Domain struct
    method isIPOrDomain_Address (line 110) | func (*IPOrDomain_Domain) isIPOrDomain_Address() {}
  function file_common_net_address_proto_rawDescGZIP (line 135) | func file_common_net_address_proto_rawDescGZIP() []byte {
  function init (line 154) | func init() { file_common_net_address_proto_init() }
  function file_common_net_address_proto_init (line 155) | func file_common_net_address_proto_init() {

FILE: common/net/address_test.go
  function TestAddressProperty (line 12) | func TestAddressProperty(t *testing.T) {
  function TestInvalidAddressConvertion (line 146) | func TestInvalidAddressConvertion(t *testing.T) {
  function BenchmarkParseAddressIPv4 (line 169) | func BenchmarkParseAddressIPv4(b *testing.B) {
  function BenchmarkParseAddressIPv6 (line 178) | func BenchmarkParseAddressIPv6(b *testing.B) {
  function BenchmarkParseAddressDomain (line 187) | func BenchmarkParseAddressDomain(b *testing.B) {

FILE: common/net/connection.go
  type ConnectionOption (line 15) | type ConnectionOption
  function ConnectionLocalAddr (line 17) | func ConnectionLocalAddr(a net.Addr) ConnectionOption {
  function ConnectionRemoteAddr (line 23) | func ConnectionRemoteAddr(a net.Addr) ConnectionOption {
  function ConnectionInput (line 29) | func ConnectionInput(writer io.Writer) ConnectionOption {
  function ConnectionInputMulti (line 35) | func ConnectionInputMulti(writer buf.Writer) ConnectionOption {
  function ConnectionOutput (line 41) | func ConnectionOutput(reader io.Reader) ConnectionOption {
  function ConnectionOutputMulti (line 47) | func ConnectionOutputMulti(reader buf.Reader) ConnectionOption {
  function ConnectionOutputMultiUDP (line 53) | func ConnectionOutputMultiUDP(reader buf.Reader) ConnectionOption {
  function ConnectionOnClose (line 62) | func ConnectionOnClose(n io.Closer) ConnectionOption {
  function NewConnection (line 68) | func NewConnection(opts ...ConnectionOption) net.Conn {
  type connection (line 88) | type connection struct
    method Read (line 97) | func (c *connection) Read(b []byte) (int, error) {
    method ReadMultiBuffer (line 102) | func (c *connection) ReadMultiBuffer() (buf.MultiBuffer, error) {
    method Write (line 107) | func (c *connection) Write(b []byte) (int, error) {
    method WriteMultiBuffer (line 118) | func (c *connection) WriteMultiBuffer(mb buf.MultiBuffer) error {
    method Close (line 128) | func (c *connection) Close() error {
    method LocalAddr (line 140) | func (c *connection) LocalAddr() net.Addr {
    method RemoteAddr (line 145) | func (c *connection) RemoteAddr() net.Addr {
    method SetDeadline (line 150) | func (c *connection) SetDeadline(t time.Time) error {
    method SetReadDeadline (line 155) | func (c *connection) SetReadDeadline(t time.Time) error {
    method SetWriteDeadline (line 160) | func (c *connection) SetWriteDeadline(t time.Time) error {

FILE: common/net/destination.go
  type Destination (line 9) | type Destination struct
    method NetAddr (line 80) | func (d Destination) NetAddr() string {
    method String (line 85) | func (d Destination) String() string {
    method IsValid (line 97) | func (d Destination) IsValid() bool {
  function DestinationFromAddr (line 16) | func DestinationFromAddr(addr net.Addr) Destination {
  function ParseDestination (line 31) | func ParseDestination(dest string) (Destination, error) {
  function TCPDestination (line 62) | func TCPDestination(address Address, port Port) Destination {
  function UDPDestination (line 71) | func UDPDestination(address Address, port Port) Destination {
  method AsDestination (line 102) | func (p *Endpoint) AsDestination() Destination {

FILE: common/net/destination.pb.go
  constant _ (line 19) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 21) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  constant _ (line 26) | _ = proto.ProtoPackageIsVersion4
  type Endpoint (line 29) | type Endpoint struct
    method Reset (line 39) | func (x *Endpoint) Reset() {
    method String (line 48) | func (x *Endpoint) String() string {
    method ProtoMessage (line 52) | func (*Endpoint) ProtoMessage() {}
    method ProtoReflect (line 54) | func (x *Endpoint) ProtoReflect() protoreflect.Message {
    method Descriptor (line 67) | func (*Endpoint) Descriptor() ([]byte, []int) {
    method GetNetwork (line 71) | func (x *Endpoint) GetNetwork() Network {
    method GetAddress (line 78) | func (x *Endpoint) GetAddress() *IPOrDomain {
    method GetPort (line 85) | func (x *Endpoint) GetPort() uint32 {
  function file_common_net_destination_proto_rawDescGZIP (line 124) | func file_common_net_destination_proto_rawDescGZIP() []byte {
  function init (line 147) | func init() { file_common_net_destination_proto_init() }
  function file_common_net_destination_proto_init (line 148) | func file_common_net_destination_proto_init() {

FILE: common/net/destination_test.go
  function TestDestinationProperty (line 11) | func TestDestinationProperty(t *testing.T) {
  function TestDestinationParse (line 46) | func TestDestinationParse(t *testing.T) {

FILE: common/net/errors.generated.go
  type errPathObjHolder (line 5) | type errPathObjHolder struct
  function newError (line 7) | func newError(values ...interface{}) *errors.Error {

FILE: common/net/network.go
  method SystemString (line 3) | func (n Network) SystemString() string {
  function HasNetwork (line 15) | func HasNetwork(list []Network, network Network) bool {

FILE: common/net/network.pb.go
  constant _ (line 19) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 21) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  constant _ (line 26) | _ = proto.ProtoPackageIsVersion4
  type Network (line 28) | type Network
    method Enum (line 54) | func (x Network) Enum() *Network {
    method String (line 60) | func (x Network) String() string {
    method Descriptor (line 64) | func (Network) Descriptor() protoreflect.EnumDescriptor {
    method Type (line 68) | func (Network) Type() protoreflect.EnumType {
    method Number (line 72) | func (x Network) Number() protoreflect.EnumNumber {
    method EnumDescriptor (line 77) | func (Network) EnumDescriptor() ([]byte, []int) {
  constant Network_Unknown (line 31) | Network_Unknown Network = 0
  constant Network_RawTCP (line 33) | Network_RawTCP Network = 1
  constant Network_TCP (line 34) | Network_TCP    Network = 2
  constant Network_UDP (line 35) | Network_UDP    Network = 3
  type NetworkList (line 82) | type NetworkList struct
    method Reset (line 90) | func (x *NetworkList) Reset() {
    method String (line 99) | func (x *NetworkList) String() string {
    method ProtoMessage (line 103) | func (*NetworkList) ProtoMessage() {}
    method ProtoReflect (line 105) | func (x *NetworkList) ProtoReflect() protoreflect.Message {
    method Descriptor (line 118) | func (*NetworkList) Descriptor() ([]byte, []int) {
    method GetNetwork (line 122) | func (x *NetworkList) GetNetwork() []Network {
  function file_common_net_network_proto_rawDescGZIP (line 156) | func file_common_net_network_proto_rawDescGZIP() []byte {
  function init (line 178) | func init() { file_common_net_network_proto_init() }
  function file_common_net_network_proto_init (line 179) | func file_common_net_network_proto_init() {

FILE: common/net/port.go
  type Port (line 9) | type Port
    method Value (line 37) | func (p Port) Value() uint16 {
    method String (line 42) | func (p Port) String() string {
  function PortFromBytes (line 13) | func PortFromBytes(port []byte) Port {
  function PortFromInt (line 19) | func PortFromInt(val uint32) (Port, error) {
  function PortFromString (line 28) | func PortFromString(s string) (Port, error) {
  method FromPort (line 47) | func (p *PortRange) FromPort() Port {
  method ToPort (line 52) | func (p *PortRange) ToPort() Port {
  method Contains (line 57) | func (p *PortRange) Contains(port Port) bool {
  function SinglePortRange (line 62) | func SinglePortRange(p Port) *PortRange {
  type MemoryPortRange (line 69) | type MemoryPortRange struct
    method Contains (line 74) | func (r MemoryPortRange) Contains(port Port) bool {
  type MemoryPortList (line 78) | type MemoryPortList
    method Contains (line 88) | func (mpl MemoryPortList) Contains(port Port) bool {
  function PortListFromProto (line 80) | func PortListFromProto(l *PortList) MemoryPortList {

FILE: common/net/port.pb.go
  constant _ (line 19) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 21) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  constant _ (line 26) | _ = proto.ProtoPackageIsVersion4
  type PortRange (line 29) | type PortRange struct
    method Reset (line 40) | func (x *PortRange) Reset() {
    method String (line 49) | func (x *PortRange) String() string {
    method ProtoMessage (line 53) | func (*PortRange) ProtoMessage() {}
    method ProtoReflect (line 55) | func (x *PortRange) ProtoReflect() protoreflect.Message {
    method Descriptor (line 68) | func (*PortRange) Descriptor() ([]byte, []int) {
    method GetFrom (line 72) | func (x *PortRange) GetFrom() uint32 {
    method GetTo (line 79) | func (x *PortRange) GetTo() uint32 {
  type PortList (line 87) | type PortList struct
    method Reset (line 95) | func (x *PortList) Reset() {
    method String (line 104) | func (x *PortList) String() string {
    method ProtoMessage (line 108) | func (*PortList) ProtoMessage() {}
    method ProtoReflect (line 110) | func (x *PortList) ProtoReflect() protoreflect.Message {
    method Descriptor (line 123) | func (*PortList) Descriptor() ([]byte, []int) {
    method GetRange (line 127) | func (x *PortList) GetRange() []*PortRange {
  function file_common_net_port_proto_rawDescGZIP (line 160) | func file_common_net_port_proto_rawDescGZIP() []byte {
  function init (line 181) | func init() { file_common_net_port_proto_init() }
  function file_common_net_port_proto_init (line 182) | func file_common_net_port_proto_init() {

FILE: common/net/port_test.go
  function TestPortRangeContains (line 9) | func TestPortRangeContains(t *testing.T) {

FILE: common/net/system.go
  constant IPv4len (line 47) | IPv4len = net.IPv4len
  constant IPv6len (line 48) | IPv6len = net.IPv6len

FILE: common/peer/latency.go
  type Latency (line 7) | type Latency interface
  type HasLatency (line 11) | type HasLatency interface
  type AverageLatency (line 16) | type AverageLatency struct
    method Update (line 21) | func (al *AverageLatency) Update(newValue uint64) {
    method Value (line 28) | func (al *AverageLatency) Value() uint64 {

FILE: common/platform/ctlcmd/attr_other.go
  function getSysProcAttr (line 7) | func getSysProcAttr() *syscall.SysProcAttr {

FILE: common/platform/ctlcmd/attr_windows.go
  function getSysProcAttr (line 7) | func getSysProcAttr() *syscall.SysProcAttr {

FILE: common/platform/ctlcmd/ctlcmd.go
  function Run (line 15) | func Run(args []string, input io.Reader) (buf.MultiBuffer, error) {

FILE: common/platform/ctlcmd/errors.generated.go
  type errPathObjHolder (line 5) | type errPathObjHolder struct
  function newError (line 7) | func newError(values ...interface{}) *errors.Error {

FILE: common/platform/filesystem/file.go
  type FileReaderFunc (line 11) | type FileReaderFunc
  function ReadFile (line 17) | func ReadFile(path string) ([]byte, error) {
  function ReadAsset (line 27) | func ReadAsset(file string) ([]byte, error) {
  function CopyFile (line 31) | func CopyFile(dst string, src string) error {

FILE: common/platform/others.go
  function ExpandEnv (line 10) | func ExpandEnv(s string) string {
  function LineSeparator (line 14) | func LineSeparator() string {
  function GetToolLocation (line 18) | func GetToolLocation(file string) string {
  function GetAssetLocation (line 25) | func GetAssetLocation(file string) string {

FILE: common/platform/platform.go
  type EnvFlag (line 10) | type EnvFlag struct
    method GetValue (line 22) | func (f EnvFlag) GetValue(defaultValue func() string) string {
    method GetValueAsInt (line 35) | func (f EnvFlag) GetValueAsInt(defaultValue int) int {
  function NewEnvFlag (line 15) | func NewEnvFlag(name string) EnvFlag {
  function NormalizeEnvName (line 51) | func NormalizeEnvName(name string) string {
  function getExecutableDir (line 55) | func getExecutableDir() string {
  function getExecutableSubDir (line 63) | func getExecutableSubDir(dir string) func() string {
  function GetPluginDirectory (line 69) | func GetPluginDirectory() string {
  function GetConfigurationPath (line 75) | func GetConfigurationPath() string {
  function GetConfDirPath (line 82) | func GetConfDirPath() string {

FILE: common/platform/platform_test.go
  function TestNormalizeEnvName (line 13) | func TestNormalizeEnvName(t *testing.T) {
  function TestEnvFlag (line 38) | func TestEnvFlag(t *testing.T) {
  function TestGetAssetLocation (line 46) | func TestGetAssetLocation(t *testing.T) {

FILE: common/platform/windows.go
  function ExpandEnv (line 7) | func ExpandEnv(s string) string {
  function LineSeparator (line 12) | func LineSeparator() string {
  function GetToolLocation (line 16) | func GetToolLocation(file string) string {
  function GetAssetLocation (line 23) | func GetAssetLocation(file string) string {

FILE: common/protocol/account.go
  type Account (line 4) | type Account interface
  type AsAccount (line 9) | type AsAccount interface

FILE: common/protocol/address.go
  type AddressOption (line 12) | type AddressOption
  function PortThenAddress (line 14) | func PortThenAddress() AddressOption {
  function AddressFamilyByte (line 20) | func AddressFamilyByte(b byte, f net.AddressFamily) AddressOption {
  type AddressTypeParser (line 30) | type AddressTypeParser
  function WithAddressTypeParser (line 32) | func WithAddressTypeParser(atp AddressTypeParser) AddressOption {
  type AddressSerializer (line 38) | type AddressSerializer interface
  constant afInvalid (line 44) | afInvalid = 255
  type option (line 46) | type option struct
  function NewAddressParser (line 54) | func NewAddressParser(options ...AddressOption) AddressSerializer {
  type portFirstAddressParser (line 82) | type portFirstAddressParser struct
    method ReadAddressPort (line 86) | func (p portFirstAddressParser) ReadAddressPort(buffer *buf.Buffer, in...
    method WriteAddressPort (line 104) | func (p portFirstAddressParser) WriteAddressPort(writer io.Writer, add...
  type portLastAddressParser (line 112) | type portLastAddressParser struct
    method ReadAddressPort (line 116) | func (p portLastAddressParser) ReadAddressPort(buffer *buf.Buffer, inp...
    method WriteAddressPort (line 135) | func (p portLastAddressParser) WriteAddressPort(writer io.Writer, addr...
  function readPort (line 143) | func readPort(b *buf.Buffer, reader io.Reader) (net.Port, error) {
  function writePort (line 150) | func writePort(writer io.Writer, port net.Port) error {
  function maybeIPPrefix (line 154) | func maybeIPPrefix(b byte) bool {
  function isValidDomain (line 158) | func isValidDomain(d string) bool {
  type addressParser (line 167) | type addressParser struct
    method readAddress (line 173) | func (p *addressParser) readAddress(b *buf.Buffer, reader io.Reader) (...
    method writeAddress (line 227) | func (p *addressParser) writeAddress(writer io.Writer, address net.Add...

FILE: common/protocol/address_test.go
  function TestAddressReading (line 15) | func TestAddressReading(t *testing.T) {
  function TestAddressWriting (line 111) | func TestAddressWriting(t *testing.T) {
  function BenchmarkAddressReadingIPv4 (line 145) | func BenchmarkAddressReadingIPv4(b *testing.B) {
  function BenchmarkAddressReadingIPv6 (line 166) | func BenchmarkAddressReadingIPv6(b *testing.B) {
  function BenchmarkAddressReadingDomain (line 187) | func BenchmarkAddressReadingDomain(b *testing.B) {
  function BenchmarkAddressWritingIPv4 (line 208) | func BenchmarkAddressWritingIPv4(b *testing.B) {
  function BenchmarkAddressWritingIPv6 (line 220) | func BenchmarkAddressWritingIPv6(b *testing.B) {
  function BenchmarkAddressWritingDomain (line 232) | func BenchmarkAddressWritingDomain(b *testing.B) {

FILE: common/protocol/bittorrent/bittorrent.go
  type SniffHeader (line 9) | type SniffHeader struct
    method Protocol (line 12) | func (h *SniffHeader) Protocol() string {
    method Domain (line 16) | func (h *SniffHeader) Domain() string {
  function SniffBittorrent (line 22) | func SniffBittorrent(b []byte) (*SniffHeader, error) {

FILE: common/protocol/context.go
  type key (line 7) | type key
  constant requestKey (line 10) | requestKey key = iota
  function ContextWithRequestHeader (line 13) | func ContextWithRequestHeader(ctx context.Context, request *RequestHeade...
  function RequestHeaderFromContext (line 17) | func RequestHeaderFromContext(ctx context.Context) *RequestHeader {

FILE: common/protocol/dns/errors.generated.go
  type errPathObjHolder (line 5) | type errPathObjHolder struct
  function newError (line 7) | func newError(values ...interface{}) *errors.Error {

FILE: common/protocol/dns/io.go
  function PackMessage (line 13) | func PackMessage(msg *dnsmessage.Message) (*buf.Buffer, error) {
  type MessageReader (line 25) | type MessageReader interface
  type UDPReader (line 29) | type UDPReader struct
    method readCache (line 36) | func (r *UDPReader) readCache() *buf.Buffer {
    method refill (line 45) | func (r *UDPReader) refill() error {
    method ReadMessage (line 57) | func (r *UDPReader) ReadMessage() (*buf.Buffer, error) {
    method Close (line 70) | func (r *UDPReader) Close() error {
  type TCPReader (line 81) | type TCPReader struct
    method ReadMessage (line 93) | func (r *TCPReader) ReadMessage() (*buf.Buffer, error) {
    method Interrupt (line 108) | func (r *TCPReader) Interrupt() {
    method Close (line 112) | func (r *TCPReader) Close() error {
  function NewTCPReader (line 85) | func NewTCPReader(reader buf.Reader) *TCPReader {
  type MessageWriter (line 116) | type MessageWriter interface
  type UDPWriter (line 120) | type UDPWriter struct
    method WriteMessage (line 124) | func (w *UDPWriter) WriteMessage(b *buf.Buffer) error {
  type TCPWriter (line 128) | type TCPWriter struct
    method WriteMessage (line 132) | func (w *TCPWriter) WriteMessage(b *buf.Buffer) error {

FILE: common/protocol/errors.generated.go
  type errPathObjHolder (line 5) | type errPathObjHolder struct
  function newError (line 7) | func newError(values ...interface{}) *errors.Error {

FILE: common/protocol/headers.go
  type RequestCommand (line 12) | type RequestCommand
    method TransferType (line 20) | func (c RequestCommand) TransferType() TransferType {
  constant RequestCommandTCP (line 15) | RequestCommandTCP = RequestCommand(0x01)
  constant RequestCommandUDP (line 16) | RequestCommandUDP = RequestCommand(0x02)
  constant RequestCommandMux (line 17) | RequestCommandMux = RequestCommand(0x03)
  constant RequestOptionChunkStream (line 33) | RequestOptionChunkStream bitmask.Byte = 0x01
  constant RequestOptionConnectionReuse (line 36) | RequestOptionConnectionReuse bitmask.Byte = 0x02
  constant RequestOptionChunkMasking (line 38) | RequestOptionChunkMasking bitmask.Byte = 0x04
  constant RequestOptionGlobalPadding (line 40) | RequestOptionGlobalPadding bitmask.Byte = 0x08
  type RequestHeader (line 43) | type RequestHeader struct
    method Destination (line 53) | func (h *RequestHeader) Destination() net.Destination {
  constant ResponseOptionConnectionReuse (line 61) | ResponseOptionConnectionReuse bitmask.Byte = 0x01
  type ResponseCommand (line 64) | type ResponseCommand interface
  type ResponseHeader (line 66) | type ResponseHeader struct
  type CommandSwitchAccount (line 71) | type CommandSwitchAccount struct
  method GetSecurityType (line 80) | func (sc *SecurityConfig) GetSecurityType() SecurityType {
  function isDomainTooLong (line 90) | func isDomainTooLong(domain string) bool {

FILE: common/protocol/headers.pb.go
  constant _ (line 19) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 21) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  constant _ (line 26) | _ = proto.ProtoPackageIsVersion4
  type SecurityType (line 28) | type SecurityType
    method Enum (line 59) | func (x SecurityType) Enum() *SecurityType {
    method String (line 65) | func (x SecurityType) String() string {
    method Descriptor (line 69) | func (SecurityType) Descriptor() protoreflect.EnumDescriptor {
    method Type (line 73) | func (SecurityType) Type() protoreflect.EnumType {
    method Number (line 77) | func (x SecurityType) Number() protoreflect.EnumNumber {
    method EnumDescriptor (line 82) | func (SecurityType) EnumDescriptor() ([]byte, []int) {
  constant SecurityType_UNKNOWN (line 31) | SecurityType_UNKNOWN           SecurityType = 0
  constant SecurityType_LEGACY (line 32) | SecurityType_LEGACY            SecurityType = 1
  constant SecurityType_AUTO (line 33) | SecurityType_AUTO              SecurityType = 2
  constant SecurityType_AES128_GCM (line 34) | SecurityType_AES128_GCM        SecurityType = 3
  constant SecurityType_CHACHA20_POLY1305 (line 35) | SecurityType_CHACHA20_POLY1305 SecurityType = 4
  constant SecurityType_NONE (line 36) | SecurityType_NONE              SecurityType = 5
  type SecurityConfig (line 86) | type SecurityConfig struct
    method Reset (line 94) | func (x *SecurityConfig) Reset() {
    method String (line 103) | func (x *SecurityConfig) String() string {
    method ProtoMessage (line 107) | func (*SecurityConfig) ProtoMessage() {}
    method ProtoReflect (line 109) | func (x *SecurityConfig) ProtoReflect() protoreflect.Message {
    method Descriptor (line 122) | func (*SecurityConfig) Descriptor() ([]byte, []int) {
    method GetType (line 126) | func (x *SecurityConfig) GetType() SecurityType {
  function file_common_protocol_headers_proto_rawDescGZIP (line 165) | func file_common_protocol_headers_proto_rawDescGZIP() []byte {
  function init (line 187) | func init() { file_common_protocol_headers_proto_init() }
  function file_common_protocol_headers_proto_init (line 188) | func file_common_protocol_headers_proto_init() {

FILE: common/protocol/http/headers.go
  function ParseXForwardedFor (line 12) | func ParseXForwardedFor(header http.Header) []net.Address {
  function RemoveHopByHopHeaders (line 26) | func RemoveHopByHopHeaders(header http.Header) {
  function ParseHost (line 50) | func ParseHost(rawHost string, defaultPort net.Port) (net.Destination, e...

FILE: common/protocol/http/headers_test.go
  function TestParseXForwardedFor (line 16) | func TestParseXForwardedFor(t *testing.T) {
  function TestHopByHopHeadersRemoving (line 25) | func TestHopByHopHeadersRemoving(t *testing.T) {
  function TestParseHost (line 82) | func TestParseHost(t *testing.T) {

FILE: common/protocol/http/sniff.go
  type version (line 12) | type version
  constant HTTP1 (line 15) | HTTP1 version = iota
  constant HTTP2 (line 16) | HTTP2
  type SniffHeader (line 19) | type SniffHeader struct
    method Protocol (line 24) | func (h *SniffHeader) Protocol() string {
    method Domain (line 35) | func (h *SniffHeader) Domain() string {
  function beginWithHTTPMethod (line 45) | func beginWithHTTPMethod(b []byte) error {
  function SniffHTTP (line 59) | func SniffHTTP(b []byte) (*SniffHeader, error) {

FILE: common/protocol/http/sniff_test.go
  function TestHTTPHeaders (line 9) | func TestHTTPHeaders(t *testing.T) {

FILE: common/protocol/id.go
  constant IDBytesLen (line 13) | IDBytesLen = 16
  type IDHash (line 16) | type IDHash
  function DefaultIDHash (line 18) | func DefaultIDHash(key []byte) hash.Hash {
  type ID (line 23) | type ID struct
    method Equals (line 29) | func (id *ID) Equals(another *ID) bool {
    method Bytes (line 33) | func (id *ID) Bytes() []byte {
    method String (line 37) | func (id *ID) String() string {
    method UUID (line 41) | func (id *ID) UUID() uuid.UUID {
    method CmdKey (line 45) | func (id ID) CmdKey() []byte {
  function NewID (line 50) | func NewID(uuid uuid.UUID) *ID {
  function nextID (line 59) | func nextID(u *uuid.UUID) uuid.UUID {
  function NewAlterIDs (line 73) | func NewAlterIDs(primary *ID, alterIDCount uint16) []*ID {

FILE: common/protocol/id_test.go
  function TestIdEquals (line 10) | func TestIdEquals(t *testing.T) {

FILE: common/protocol/payload.go
  type TransferType (line 3) | type TransferType
  constant TransferTypeStream (line 6) | TransferTypeStream TransferType = 0
  constant TransferTypePacket (line 7) | TransferTypePacket TransferType = 1
  type AddressType (line 10) | type AddressType
  constant AddressTypeIPv4 (line 13) | AddressTypeIPv4   AddressType = 1
  constant AddressTypeDomain (line 14) | AddressTypeDomain AddressType = 2
  constant AddressTypeIPv6 (line 15) | AddressTypeIPv6   AddressType = 3

FILE: common/protocol/server_picker.go
  type ServerList (line 7) | type ServerList struct
    method AddServer (line 16) | func (sl *ServerList) AddServer(server *ServerSpec) {
    method Size (line 23) | func (sl *ServerList) Size() uint32 {
    method GetServer (line 30) | func (sl *ServerList) GetServer(idx uint32) *ServerSpec {
    method removeServer (line 49) | func (sl *ServerList) removeServer(idx uint32) {
  function NewServerList (line 12) | func NewServerList() *ServerList {
  type ServerPicker (line 55) | type ServerPicker interface
  type RoundRobinServerPicker (line 59) | type RoundRobinServerPicker struct
    method PickServer (line 72) | func (p *RoundRobinServerPicker) PickServer() *ServerSpec {
  function NewRoundRobinServerPicker (line 65) | func NewRoundRobinServerPicker(serverlist *ServerList) *RoundRobinServer...

FILE: common/protocol/server_picker_test.go
  function TestServerList (line 11) | func TestServerList(t *testing.T) {
  function TestServerPicker (line 38) | func TestServerPicker(t *testing.T) {

FILE: common/protocol/server_spec.go
  type ValidationStrategy (line 11) | type ValidationStrategy interface
  type alwaysValidStrategy (line 16) | type alwaysValidStrategy struct
    method IsValid (line 22) | func (alwaysValidStrategy) IsValid() bool {
    method Invalidate (line 26) | func (alwaysValidStrategy) Invalidate() {}
  function AlwaysValid (line 18) | func AlwaysValid() ValidationStrategy {
  type timeoutValidStrategy (line 28) | type timeoutValidStrategy struct
    method IsValid (line 38) | func (s *timeoutValidStrategy) IsValid() bool {
    method Invalidate (line 42) | func (s *timeoutValidStrategy) Invalidate() {
  function BeforeTime (line 32) | func BeforeTime(t time.Time) ValidationStrategy {
  type ServerSpec (line 46) | type ServerSpec struct
    method Destination (line 74) | func (s *ServerSpec) Destination() net.Destination {
    method HasUser (line 78) | func (s *ServerSpec) HasUser(user *MemoryUser) bool {
    method AddUser (line 90) | func (s *ServerSpec) AddUser(user *MemoryUser) {
    method PickUser (line 101) | func (s *ServerSpec) PickUser() *MemoryUser {
    method IsValid (line 116) | func (s *ServerSpec) IsValid() bool {
    method Invalidate (line 120) | func (s *ServerSpec) Invalidate() {
  function NewServerSpec (line 53) | func NewServerSpec(dest net.Destination, valid ValidationStrategy, users...
  function NewServerSpecFromPB (line 61) | func NewServerSpecFromPB(spec *ServerEndpoint) (*ServerSpec, error) {

FILE: common/protocol/server_spec.pb.go
  constant _ (line 20) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 22) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  constant _ (line 27) | _ = proto.ProtoPackageIsVersion4
  type ServerEndpoint (line 29) | type ServerEndpoint struct
    method Reset (line 39) | func (x *ServerEndpoint) Reset() {
    method String (line 48) | func (x *ServerEndpoint) String() string {
    method ProtoMessage (line 52) | func (*ServerEndpoint) ProtoMessage() {}
    method ProtoReflect (line 54) | func (x *ServerEndpoint) ProtoReflect() protoreflect.Message {
    method Descriptor (line 67) | func (*ServerEndpoint) Descriptor() ([]byte, []int) {
    method GetAddress (line 71) | func (x *ServerEndpoint) GetAddress() *net.IPOrDomain {
    method GetPort (line 78) | func (x *ServerEndpoint) GetPort() uint32 {
    method GetUser (line 85) | func (x *ServerEndpoint) GetUser() []*User {
  function file_common_protocol_server_spec_proto_rawDescGZIP (line 126) | func file_common_protocol_server_spec_proto_rawDescGZIP() []byte {
  function init (line 149) | func init() { file_common_protocol_server_spec_proto_init() }
  function file_common_protocol_server_spec_proto_init (line 150) | func file_common_protocol_server_spec_proto_init() {

FILE: common/protocol/server_spec_test.go
  function TestAlwaysValidStrategy (line 15) | func TestAlwaysValidStrategy(t *testing.T) {
  function TestTimeoutValidStrategy (line 26) | func TestTimeoutValidStrategy(t *testing.T) {
  function TestUserInServerSpec (line 43) | func TestUserInServerSpec(t *testing.T) {
  function TestPickUser (line 73) | func TestPickUser(t *testing.T) {

FILE: common/protocol/time.go
  type Timestamp (line 9) | type Timestamp
  type TimestampGenerator (line 11) | type TimestampGenerator
  function NowTime (line 13) | func NowTime() Timestamp {
  function NewTimestampGenerator (line 17) | func NewTimestampGenerator(base Timestamp, delta int) TimestampGenerator {

FILE: common/protocol/time_test.go
  function TestGenerateRandomInt64InRange (line 10) | func TestGenerateRandomInt64InRange(t *testing.T) {

FILE: common/protocol/tls/cert/cert.go
  type Certificate (line 20) | type Certificate struct
    method ToPEM (line 42) | func (c *Certificate) ToPEM() ([]byte, []byte) {
  function ParseCertificate (line 27) | func ParseCertificate(certPEM []byte, keyPEM []byte) (*Certificate, erro...
  type Option (line 47) | type Option
  function Authority (line 49) | func Authority(isCA bool) Option {
  function NotBefore (line 55) | func NotBefore(t time.Time) Option {
  function NotAfter (line 61) | func NotAfter(t time.Time) Option {
  function DNSNames (line 67) | func DNSNames(names ...string) Option {
  function CommonName (line 73) | func CommonName(name string) Option {
  function KeyUsage (line 79) | func KeyUsage(usage x509.KeyUsage) Option {
  function Organization (line 85) | func Organization(org string) Option {
  function MustGenerate (line 91) | func MustGenerate(parent *Certificate, opts ...Option) *Certificate {
  function publicKey (line 97) | func publicKey(priv interface{}) interface{} {
  function Generate (line 110) | func Generate(parent *Certificate, opts ...Option) (*Certificate, error) {

FILE: common/protocol/tls/cert/cert_test.go
  function TestGenerate (line 15) | func TestGenerate(t *testing.T) {
  function generate (line 22) | func generate(domainNames []string, isCA bool, jsonOutput bool, fileOutp...
  type jsonCert (line 59) | type jsonCert struct
  function printJSON (line 64) | func printJSON(certificate *Certificate) {
  function printFile (line 75) | func printFile(certificate *Certificate, name string) error {
  function writeFile (line 83) | func writeFile(content []byte, name string) error {

FILE: common/protocol/tls/cert/errors.generated.go
  type errPathObjHolder (line 5) | type errPathObjHolder struct
  function newError (line 7) | func newError(values ...interface{}) *errors.Error {

FILE: common/protocol/tls/cert/privateKey.go
  type ecPrivateKey (line 9) | type ecPrivateKey struct
  type pkcs8 (line 16) | type pkcs8 struct
  type pkcs1AdditionalRSAPrime (line 23) | type pkcs1AdditionalRSAPrime struct
  type pkcs1PrivateKey (line 31) | type pkcs1PrivateKey struct

FILE: common/protocol/tls/sniff.go
  type SniffHeader (line 11) | type SniffHeader struct
    method Protocol (line 15) | func (h *SniffHeader) Protocol() string {
    method Domain (line 19) | func (h *SniffHeader) Domain() string {
  function IsValidTLSVersion (line 26) | func IsValidTLSVersion(major, minor byte) bool {
  function ReadClientHello (line 32) | func ReadClientHello(data []byte, h *SniffHeader) error {
  function SniffTLS (line 124) | func SniffTLS(b []byte) (*SniffHeader, error) {

FILE: common/protocol/tls/sniff_test.go
  function TestTLSHeaders (line 9) | func TestTLSHeaders(t *testing.T) {

FILE: common/protocol/udp/packet.go
  type Packet (line 9) | type Packet struct

FILE: common/protocol/user.go
  method GetTypedAccount (line 3) | func (u *User) GetTypedAccount() (Account, error) {
  method ToMemoryUser (line 21) | func (u *User) ToMemoryUser() (*MemoryUser, error) {
  type MemoryUser (line 34) | type MemoryUser struct

FILE: common/protocol/user.pb.go
  constant _ (line 20) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 22) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  constant _ (line 27) | _ = proto.ProtoPackageIsVersion4
  type User (line 30) | type User struct
    method Reset (line 42) | func (x *User) Reset() {
    method String (line 51) | func (x *User) String() string {
    method ProtoMessage (line 55) | func (*User) ProtoMessage() {}
    method ProtoReflect (line 57) | func (x *User) ProtoReflect() protoreflect.Message {
    method Descriptor (line 70) | func (*User) Descriptor() ([]byte, []int) {
    method GetLevel (line 74) | func (x *User) GetLevel() uint32 {
    method GetEmail (line 81) | func (x *User) GetEmail() string {
    method GetAccount (line 88) | func (x *User) GetAccount() *serial.TypedMessage {
  function file_common_protocol_user_proto_rawDescGZIP (line 125) | func file_common_protocol_user_proto_rawDescGZIP() []byte {
  function init (line 146) | func init() { file_common_protocol_user_proto_init() }
  function file_common_protocol_user_proto_init (line 147) | func file_common_protocol_user_proto_init() {

FILE: common/retry/errors.generated.go
  type errPathObjHolder (line 5) | type errPathObjHolder struct
  function newError (line 7) | func newError(values ...interface{}) *errors.Error {

FILE: common/retry/retry.go
  type Strategy (line 14) | type Strategy interface
  type retryer (line 19) | type retryer struct
    method On (line 25) | func (r *retryer) On(method func() error) error {
  function Timed (line 45) | func Timed(attempts int, delay uint32) Strategy {
  function ExponentialBackoff (line 54) | func ExponentialBackoff(attempts int, delay uint32) Strategy {

FILE: common/retry/retry_test.go
  function TestNoRetry (line 16) | func TestNoRetry(t *testing.T) {
  function TestRetryOnce (line 29) | func TestRetryOnce(t *testing.T) {
  function TestRetryMultiple (line 47) | func TestRetryMultiple(t *testing.T) {
  function TestRetryExhausted (line 65) | func TestRetryExhausted(t *testing.T) {
  function TestExponentialBackoff (line 83) | func TestExponentialBackoff(t *testing.T) {

FILE: common/serial/serial.go
  function ReadUint16 (line 9) | func ReadUint16(reader io.Reader) (uint16, error) {
  function WriteUint16 (line 18) | func WriteUint16(writer io.Writer, value uint16) (int, error) {
  function WriteUint64 (line 25) | func WriteUint64(writer io.Writer, value uint64) (int, error) {

FILE: common/serial/serial_test.go
  function TestUint16Serial (line 14) | func TestUint16Serial(t *testing.T) {
  function TestUint64Serial (line 28) | func TestUint64Serial(t *testing.T) {
  function TestReadUint16 (line 42) | func TestReadUint16(t *testing.T) {
  function BenchmarkReadUint16 (line 62) | func BenchmarkReadUint16(b *testing.B) {
  function BenchmarkWriteUint64 (line 77) | func BenchmarkWriteUint64(b *testing.B) {

FILE: common/serial/string.go
  function ToString (line 9) | func ToString(v interface{}) string {
  function Concat (line 29) | func Concat(v ...interface{}) string {

FILE: common/serial/string_test.go
  function TestToString (line 12) | func TestToString(t *testing.T) {
  function TestConcat (line 31) | func TestConcat(t *testing.T) {
  function BenchmarkConcat (line 52) | func BenchmarkConcat(b *testing.B) {

FILE: common/serial/typed_message.go
  function ToTypedMessage (line 11) | func ToTypedMessage(message proto.Message) *TypedMessage {
  function GetMessageType (line 23) | func GetMessageType(message proto.Message) string {
  function GetInstance (line 28) | func GetInstance(messageType string) (interface{}, error) {
  method GetInstance (line 37) | func (v *TypedMessage) GetInstance() (proto.Message, error) {

FILE: common/serial/typed_message.pb.go
  constant _ (line 19) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 21) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  constant _ (line 26) | _ = proto.ProtoPackageIsVersion4
  type TypedMessage (line 29) | type TypedMessage struct
    method Reset (line 40) | func (x *TypedMessage) Reset() {
    method String (line 49) | func (x *TypedMessage) String() string {
    method ProtoMessage (line 53) | func (*TypedMessage) ProtoMessage() {}
    method ProtoReflect (line 55) | func (x *TypedMessage) ProtoReflect() protoreflect.Message {
    method Descriptor (line 68) | func (*TypedMessage) Descriptor() ([]byte, []int) {
    method GetType (line 72) | func (x *TypedMessage) GetType() string {
    method GetValue (line 79) | func (x *TypedMessage) GetValue() []byte {
  function file_common_serial_typed_message_proto_rawDescGZIP (line 110) | func file_common_serial_typed_message_proto_rawDescGZIP() []byte {
  function init (line 129) | func init() { file_common_serial_typed_message_proto_init() }
  function file_common_serial_typed_message_proto_init (line 130) | func file_common_serial_typed_message_proto_init() {

FILE: common/serial/typed_message_test.go
  function TestGetInstance (line 9) | func TestGetInstance(t *testing.T) {
  function TestConvertingNilMessage (line 19) | func TestConvertingNilMessage(t *testing.T) {

FILE: common/session/context.go
  type sessionKey (line 5) | type sessionKey
  constant idSessionKey (line 8) | idSessionKey sessionKey = iota
  constant inboundSessionKey (line 9) | inboundSessionKey
  constant outboundSessionKey (line 10) | outboundSessionKey
  constant contentSessionKey (line 11) | contentSessionKey
  constant muxPreferedSessionKey (line 12) | muxPreferedSessionKey
  constant sockoptSessionKey (line 13) | sockoptSessionKey
  function ContextWithID (line 17) | func ContextWithID(ctx context.Context, id ID) context.Context {
  function IDFromContext (line 22) | func IDFromContext(ctx context.Context) ID {
  function ContextWithInbound (line 29) | func ContextWithInbound(ctx context.Context, inbound *Inbound) context.C...
  function InboundFromContext (line 33) | func InboundFromContext(ctx context.Context) *Inbound {
  function ContextWithOutbound (line 40) | func ContextWithOutbound(ctx context.Context, outbound *Outbound) contex...
  function OutboundFromContext (line 44) | func OutboundFromContext(ctx context.Context) *Outbound {
  function ContextWithContent (line 51) | func ContextWithContent(ctx context.Context, content *Content) context.C...
  function ContentFromContext (line 55) | func ContentFromContext(ctx context.Context) *Content {
  function ContextWithMuxPrefered (line 63) | func ContextWithMuxPrefered(ctx context.Context, forced bool) context.Co...
  function MuxPreferedFromContext (line 68) | func MuxPreferedFromContext(ctx context.Context) bool {
  function ContextWithSockopt (line 76) | func ContextWithSockopt(ctx context.Context, s *Sockopt) context.Context {
  function SockoptFromContext (line 81) | func SockoptFromContext(ctx context.Context) *Sockopt {

FILE: common/session/session.go
  type ID (line 14) | type ID
  function NewID (line 18) | func NewID() ID {
  function ExportIDToError (line 29) | func ExportIDToError(ctx context.Context) errors.ExportOption {
  type Inbound (line 37) | type Inbound struct
  type Outbound (line 49) | type Outbound struct
  type SniffingRequest (line 57) | type SniffingRequest struct
  type Content (line 63) | type Content struct
    method SetAttribute (line 81) | func (c *Content) SetAttribute(name string, value string) {
    method Attribute (line 89) | func (c *Content) Attribute(name string) string {
  type Sockopt (line 75) | type Sockopt struct

FILE: common/signal/done/done.go
  type Instance (line 8) | type Instance struct
    method Done (line 22) | func (d *Instance) Done() bool {
    method Wait (line 32) | func (d *Instance) Wait() <-chan struct{} {
    method Close (line 37) | func (d *Instance) Close() error {
  function New (line 15) | func New() *Instance {

FILE: common/signal/notifier.go
  type Notifier (line 4) | type Notifier struct
    method Signal (line 16) | func (n *Notifier) Signal() {
    method Wait (line 24) | func (n *Notifier) Wait() <-chan struct{} {
  function NewNotifier (line 9) | func NewNotifier() *Notifier {

FILE: common/signal/notifier_test.go
  function TestNotifierSignal (line 9) | func TestNotifierSignal(t *testing.T) {

FILE: common/signal/pubsub/pubsub.go
  type Subscriber (line 13) | type Subscriber struct
    method push (line 18) | func (s *Subscriber) push(msg interface{}) {
    method Wait (line 25) | func (s *Subscriber) Wait() <-chan interface{} {
    method Close (line 29) | func (s *Subs
Condensed preview — 752 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (2,652K chars).
[
  {
    "path": ".github/CODE_OF_CONDUCT.md",
    "chars": 3211,
    "preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, w"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_cn.md",
    "chars": 983,
    "preview": "---\nname: V2Ray 程序问题\nabout: \"提交一个 V2Ray 的程序问题报告。\"\n---\n\n除非特殊情况,请完整填写所有问题。不按模板发的 issue 将直接被关闭。\n如果你遇到的问题不是 V2Ray 的 bug,比如你不"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_en.md",
    "chars": 1840,
    "preview": "---\nname: Bug report\nabout: \"Create a bug report to help us improve\"\n---\n\nPlease answer all the questions with enough in"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/other_en.md",
    "chars": 459,
    "preview": "---\nname: Other\nabout: \"其它问题请使用 https://github.com/v2fly/discussion/issues 进行讨论 / Please discuss other issues at https:/"
  },
  {
    "path": ".github/ISSUE_TEMPLATE.md",
    "chars": 297,
    "preview": "如果你遇到的问题不是 V2Ray 的 bug,比如你不清楚要如何配置,请使用[Discussion](https://github.com/v2fly/discussion/issues)进行讨论。\n\n此 Issue 会被立即关闭。\n\nIf"
  },
  {
    "path": ".github/dependabot.yml",
    "chars": 562,
    "preview": "# To get started with Dependabot version updates, you'll need to specify which\n# package ecosystems to update and where "
  },
  {
    "path": ".github/linters/.golangci.yml",
    "chars": 526,
    "preview": "run:\n  timeout: 5m\n  skip-files:\n    - generated.*\n\nissues:\n  new: true\n\nlinters:\n  enable:\n    - bodyclose\n    - depgua"
  },
  {
    "path": ".github/pull_request_template.md",
    "chars": 57,
    "preview": "Please Move to https://github.com/v2fly/v2ray-core/pulls\n"
  },
  {
    "path": ".github/workflows/codeql-analysis.yml",
    "chars": 2393,
    "preview": "name: CodeQL\n\non:\n  push:\n    branches: [master]\n    paths:\n      - \"**/*.go\"\n  pull_request:\n    branches: [master]\n   "
  },
  {
    "path": ".github/workflows/coverage.yml",
    "chars": 984,
    "preview": "name: Coverage\n\non:\n  push:\n    branches: [master]\n    paths:\n      - \"**/*.go\"\n\njobs:\n  coverage:\n    if: github.reposi"
  },
  {
    "path": ".github/workflows/linter.yml",
    "chars": 663,
    "preview": "name: Linter\n\non:\n  push:\n    branches: [master]\n    paths:\n      - \"**/*.go\"\n  pull_request:\n    branches: [master]\n   "
  },
  {
    "path": ".github/workflows/sign.yml",
    "chars": 703,
    "preview": "name: Sign\n\non:\n  release:\n    types: [released]\n\njobs:\n  sign:\n    if: github.repository != 'v2ray/v2ray-core'\n    runs"
  },
  {
    "path": ".github/workflows/stale.yml",
    "chars": 607,
    "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": 893,
    "preview": "name: Test\n\non:\n  push:\n    branches: [master]\n    paths:\n      - \"**/*.go\"\n      - \"go.mod\"\n      - \"go.sum\"\n  pull_req"
  },
  {
    "path": ".github/workflows/updateGeofile.yml",
    "chars": 723,
    "preview": "name: Update Geofiles\n\non:\n  schedule:\n    - cron: \"0 0 * * FRI\"\n\njobs:\n  update:\n    if: github.repository == 'v2fly/v2"
  },
  {
    "path": ".gitignore",
    "chars": 24,
    "preview": "*.DS_Store\nbazel-*\n.idea"
  },
  {
    "path": "Dockerfile",
    "chars": 841,
    "preview": "############################\n# STEP 1 build executable binary\n############################\nFROM golang:alpine AS builder"
  },
  {
    "path": "LICENSE",
    "chars": 1088,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2015-2020 V2Fly Community\n\nPermission is hereby granted, free of charge, to any per"
  },
  {
    "path": "README.md",
    "chars": 1827,
    "preview": "# Move To https://github.com/v2fly/v2ray-core\n\n***\n\n# Project V\n\n[![GitHub Test Badge][1]][2] [![codecov.io][3]][4] [![G"
  },
  {
    "path": "SECURITY.md",
    "chars": 6255,
    "preview": "# 安全策略 Security Policy\n\n## 受支持的版本 Supported Versions\n\n目前 v2ray-core 项目由 [V2Fly 社区](https://github.com/v2fly) 继续提供代码维护,由于"
  },
  {
    "path": "WORKSPACE",
    "chars": 31,
    "preview": "workspace(name = \"v2ray_core\")\n"
  },
  {
    "path": "annotations.go",
    "chars": 680,
    "preview": "package core\n\n// Annotation is a concept in V2Ray. This struct is only for documentation. It is not used anywhere.\n// An"
  },
  {
    "path": "app/app.go",
    "chars": 114,
    "preview": "// Package app contains feature implementations of V2Ray. The features may be enabled during runtime.\npackage app\n"
  },
  {
    "path": "app/commander/commander.go",
    "chars": 2285,
    "preview": "// +build !confonly\n\npackage commander\n\n//go:generate go run v2ray.com/core/common/errors/errorgen\n\nimport (\n\t\"context\"\n"
  },
  {
    "path": "app/commander/config.pb.go",
    "chars": 6445,
    "preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.25.0\n// \tprotoc        v3.13.0\n// sou"
  },
  {
    "path": "app/commander/config.proto",
    "chars": 596,
    "preview": "syntax = \"proto3\";\n\npackage v2ray.core.app.commander;\noption csharp_namespace = \"V2Ray.Core.App.Commander\";\noption go_pa"
  },
  {
    "path": "app/commander/errors.generated.go",
    "chars": 207,
    "preview": "package commander\n\nimport \"v2ray.com/core/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interf"
  },
  {
    "path": "app/commander/outbound.go",
    "chars": 2168,
    "preview": "// +build !confonly\n\npackage commander\n\nimport (\n\t\"context\"\n\t\"sync\"\n\n\t\"v2ray.com/core/common\"\n\t\"v2ray.com/core/common/ne"
  },
  {
    "path": "app/commander/service.go",
    "chars": 224,
    "preview": "// +build !confonly\n\npackage commander\n\nimport (\n\t\"google.golang.org/grpc\"\n)\n\n// Service is a Commander service.\ntype Se"
  },
  {
    "path": "app/dispatcher/config.pb.go",
    "chars": 7223,
    "preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.25.0\n// \tprotoc        v3.13.0\n// sou"
  },
  {
    "path": "app/dispatcher/config.proto",
    "chars": 344,
    "preview": "syntax = \"proto3\";\n\npackage v2ray.core.app.dispatcher;\noption csharp_namespace = \"V2Ray.Core.App.Dispatcher\";\noption go_"
  },
  {
    "path": "app/dispatcher/default.go",
    "chars": 7481,
    "preview": "// +build !confonly\n\npackage dispatcher\n\n//go:generate go run v2ray.com/core/common/errors/errorgen\n\nimport (\n\t\"context\""
  },
  {
    "path": "app/dispatcher/dispatcher.go",
    "chars": 100,
    "preview": "// +build !confonly\n\npackage dispatcher\n\n//go:generate go run v2ray.com/core/common/errors/errorgen\n"
  },
  {
    "path": "app/dispatcher/errors.generated.go",
    "chars": 208,
    "preview": "package dispatcher\n\nimport \"v2ray.com/core/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...inter"
  },
  {
    "path": "app/dispatcher/sniffer.go",
    "chars": 1180,
    "preview": "// +build !confonly\n\npackage dispatcher\n\nimport (\n\t\"v2ray.com/core/common\"\n\t\"v2ray.com/core/common/protocol/bittorrent\"\n"
  },
  {
    "path": "app/dispatcher/stats.go",
    "chars": 502,
    "preview": "// +build !confonly\n\npackage dispatcher\n\nimport (\n\t\"v2ray.com/core/common\"\n\t\"v2ray.com/core/common/buf\"\n\t\"v2ray.com/core"
  },
  {
    "path": "app/dispatcher/stats_test.go",
    "chars": 785,
    "preview": "package dispatcher_test\n\nimport (\n\t\"testing\"\n\n\t. \"v2ray.com/core/app/dispatcher\"\n\t\"v2ray.com/core/common\"\n\t\"v2ray.com/co"
  },
  {
    "path": "app/dns/config.pb.go",
    "chars": 25140,
    "preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.25.0\n// \tprotoc        v3.13.0\n// sou"
  },
  {
    "path": "app/dns/config.proto",
    "chars": 1867,
    "preview": "syntax = \"proto3\";\n\npackage v2ray.core.app.dns;\noption csharp_namespace = \"V2Ray.Core.App.Dns\";\noption go_package = \"v2r"
  },
  {
    "path": "app/dns/dns.go",
    "chars": 129,
    "preview": "// Package dns is an implementation of core.DNS feature.\npackage dns\n\n//go:generate go run v2ray.com/core/common/errors/"
  },
  {
    "path": "app/dns/dnscommon.go",
    "chars": 5074,
    "preview": "// +build !confonly\n\npackage dns\n\nimport (\n\t\"encoding/binary\"\n\t\"time\"\n\n\t\"golang.org/x/net/dns/dnsmessage\"\n\t\"v2ray.com/co"
  },
  {
    "path": "app/dns/dnscommon_test.go",
    "chars": 4084,
    "preview": "// +build !confonly\n\npackage dns\n\nimport (\n\t\"math/rand\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"github.com"
  },
  {
    "path": "app/dns/dohdns.go",
    "chars": 9502,
    "preview": "// +build !confonly\n\npackage dns\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"sync\"\n"
  },
  {
    "path": "app/dns/errors.generated.go",
    "chars": 201,
    "preview": "package dns\n\nimport \"v2ray.com/core/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{})"
  },
  {
    "path": "app/dns/hosts.go",
    "chars": 3389,
    "preview": "// +build !confonly\n\npackage dns\n\nimport (\n\t\"v2ray.com/core/common\"\n\t\"v2ray.com/core/common/net\"\n\t\"v2ray.com/core/common"
  },
  {
    "path": "app/dns/hosts_test.go",
    "chars": 1454,
    "preview": "package dns_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t. \"v2ray.com/core/app/dns\"\n\t\"v2ray.com/core/com"
  },
  {
    "path": "app/dns/nameserver.go",
    "chars": 1151,
    "preview": "// +build !confonly\n\npackage dns\n\nimport (\n\t\"context\"\n\n\t\"v2ray.com/core/common/net\"\n\t\"v2ray.com/core/features/dns/locald"
  },
  {
    "path": "app/dns/nameserver_test.go",
    "chars": 444,
    "preview": "package dns_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\t\"time\"\n\n\t. \"v2ray.com/core/app/dns\"\n\t\"v2ray.com/core/common\"\n)\n\nfunc T"
  },
  {
    "path": "app/dns/server.go",
    "chars": 13435,
    "preview": "// +build !confonly\n\npackage dns\n\n//go:generate go run v2ray.com/core/common/errors/errorgen\n\nimport (\n\t\"context\"\n\t\"fmt\""
  },
  {
    "path": "app/dns/server_test.go",
    "chars": 22651,
    "preview": "package dns_test\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"github.com/miekg/dns\"\n\n\t\"v2ray.com/core"
  },
  {
    "path": "app/dns/udpns.go",
    "chars": 6343,
    "preview": "// +build !confonly\n\npackage dns\n\nimport (\n\t\"context\"\n\t\"strings\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"golang.org/x/net/dns/"
  },
  {
    "path": "app/log/command/command.go",
    "chars": 1242,
    "preview": "// +build !confonly\n\npackage command\n\n//go:generate go run v2ray.com/core/common/errors/errorgen\n\nimport (\n\t\"context\"\n\n\t"
  },
  {
    "path": "app/log/command/command_test.go",
    "chars": 815,
    "preview": "package command_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"v2ray.com/core\"\n\t\"v2ray.com/core/app/dispatcher\"\n\t\"v2ray.com/cor"
  },
  {
    "path": "app/log/command/config.pb.go",
    "chars": 9341,
    "preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.25.0\n// \tprotoc        v3.13.0\n// sou"
  },
  {
    "path": "app/log/command/config.proto",
    "chars": 447,
    "preview": "syntax = \"proto3\";\n\npackage v2ray.core.app.log.command;\noption csharp_namespace = \"V2Ray.Core.App.Log.Command\";\noption g"
  },
  {
    "path": "app/log/command/config_grpc.pb.go",
    "chars": 3579,
    "preview": "// Code generated by protoc-gen-go-grpc. DO NOT EDIT.\n\npackage command\n\nimport (\n\tcontext \"context\"\n\tgrpc \"google.golang"
  },
  {
    "path": "app/log/command/errors.generated.go",
    "chars": 205,
    "preview": "package command\n\nimport \"v2ray.com/core/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interfac"
  },
  {
    "path": "app/log/config.pb.go",
    "chars": 9686,
    "preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.25.0\n// \tprotoc        v3.13.0\n// sou"
  },
  {
    "path": "app/log/config.proto",
    "chars": 522,
    "preview": "syntax = \"proto3\";\n\npackage v2ray.core.app.log;\noption csharp_namespace = \"V2Ray.Core.App.Log\";\noption go_package = \"v2r"
  },
  {
    "path": "app/log/errors.generated.go",
    "chars": 201,
    "preview": "package log\n\nimport \"v2ray.com/core/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{})"
  },
  {
    "path": "app/log/log.go",
    "chars": 2808,
    "preview": "// +build !confonly\n\npackage log\n\n//go:generate go run v2ray.com/core/common/errors/errorgen\n\nimport (\n\t\"context\"\n\t\"sync"
  },
  {
    "path": "app/log/log_creator.go",
    "chars": 1337,
    "preview": "// +build !confonly\n\npackage log\n\nimport (\n\t\"v2ray.com/core/common\"\n\t\"v2ray.com/core/common/log\"\n)\n\ntype HandlerCreatorO"
  },
  {
    "path": "app/log/log_test.go",
    "chars": 1238,
    "preview": "package log_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/golang/mock/gomock\"\n\t\"v2ray.com/core/app/log\"\n\t\"v2ray.com"
  },
  {
    "path": "app/policy/config.go",
    "chars": 2509,
    "preview": "package policy\n\nimport (\n\t\"time\"\n\n\t\"v2ray.com/core/features/policy\"\n)\n\n// Duration converts Second to time.Duration.\nfun"
  },
  {
    "path": "app/policy/config.pb.go",
    "chars": 26022,
    "preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.25.0\n// \tprotoc        v3.13.0\n// sou"
  },
  {
    "path": "app/policy/config.proto",
    "chars": 1046,
    "preview": "syntax = \"proto3\";\n\npackage v2ray.core.app.policy;\noption csharp_namespace = \"V2Ray.Core.App.Policy\";\noption go_package "
  },
  {
    "path": "app/policy/errors.generated.go",
    "chars": 204,
    "preview": "package policy\n\nimport \"v2ray.com/core/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface"
  },
  {
    "path": "app/policy/manager.go",
    "chars": 1411,
    "preview": "package policy\n\nimport (\n\t\"context\"\n\n\t\"v2ray.com/core/common\"\n\t\"v2ray.com/core/features/policy\"\n)\n\n// Instance is an ins"
  },
  {
    "path": "app/policy/manager_test.go",
    "chars": 962,
    "preview": "package policy_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\t\"time\"\n\n\t. \"v2ray.com/core/app/policy\"\n\t\"v2ray.com/core/common\"\n\t\"v"
  },
  {
    "path": "app/policy/policy.go",
    "chars": 141,
    "preview": "// Package policy is an implementation of policy.Manager feature.\npackage policy\n\n//go:generate go run v2ray.com/core/co"
  },
  {
    "path": "app/proxyman/command/command.go",
    "chars": 4350,
    "preview": "// +build !confonly\n\npackage command\n\nimport (\n\t\"context\"\n\n\tgrpc \"google.golang.org/grpc\"\n\n\t\"v2ray.com/core\"\n\t\"v2ray.com"
  },
  {
    "path": "app/proxyman/command/command.pb.go",
    "chars": 40361,
    "preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.25.0\n// \tprotoc        v3.13.0\n// sou"
  },
  {
    "path": "app/proxyman/command/command.proto",
    "chars": 1672,
    "preview": "syntax = \"proto3\";\n\npackage v2ray.core.app.proxyman.command;\noption csharp_namespace = \"V2Ray.Core.App.Proxyman.Command\""
  },
  {
    "path": "app/proxyman/command/command_grpc.pb.go",
    "chars": 11344,
    "preview": "// Code generated by protoc-gen-go-grpc. DO NOT EDIT.\n\npackage command\n\nimport (\n\tcontext \"context\"\n\tgrpc \"google.golang"
  },
  {
    "path": "app/proxyman/command/doc.go",
    "chars": 76,
    "preview": "package command\n\n//go:generate go run v2ray.com/core/common/errors/errorgen\n"
  },
  {
    "path": "app/proxyman/command/errors.generated.go",
    "chars": 205,
    "preview": "package command\n\nimport \"v2ray.com/core/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interfac"
  },
  {
    "path": "app/proxyman/config.go",
    "chars": 758,
    "preview": "package proxyman\n\nfunc (s *AllocationStrategy) GetConcurrencyValue() uint32 {\n\tif s == nil || s.Concurrency == nil {\n\t\tr"
  },
  {
    "path": "app/proxyman/config.pb.go",
    "chars": 41839,
    "preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.25.0\n// \tprotoc        v3.13.0\n// sou"
  },
  {
    "path": "app/proxyman/config.proto",
    "chars": 2745,
    "preview": "syntax = \"proto3\";\n\npackage v2ray.core.app.proxyman;\noption csharp_namespace = \"V2Ray.Core.App.Proxyman\";\noption go_pack"
  },
  {
    "path": "app/proxyman/inbound/always.go",
    "chars": 4422,
    "preview": "package inbound\n\nimport (\n\t\"context\"\n\n\t\"v2ray.com/core\"\n\t\"v2ray.com/core/app/proxyman\"\n\t\"v2ray.com/core/common\"\n\t\"v2ray."
  },
  {
    "path": "app/proxyman/inbound/dynamic.go",
    "chars": 5282,
    "preview": "package inbound\n\nimport (\n\t\"context\"\n\t\"sync\"\n\t\"time\"\n\n\t\"v2ray.com/core\"\n\t\"v2ray.com/core/app/proxyman\"\n\t\"v2ray.com/core/"
  },
  {
    "path": "app/proxyman/inbound/errors.generated.go",
    "chars": 205,
    "preview": "package inbound\n\nimport \"v2ray.com/core/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interfac"
  },
  {
    "path": "app/proxyman/inbound/inbound.go",
    "chars": 4549,
    "preview": "package inbound\n\n//go:generate go run v2ray.com/core/common/errors/errorgen\n\nimport (\n\t\"context\"\n\t\"sync\"\n\n\t\"v2ray.com/co"
  },
  {
    "path": "app/proxyman/inbound/worker.go",
    "chars": 9085,
    "preview": "package inbound\n\nimport (\n\t\"context\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"v2ray.com/core/app/proxyman\"\n\t\"v2ray.com/core/com"
  },
  {
    "path": "app/proxyman/outbound/errors.generated.go",
    "chars": 206,
    "preview": "package outbound\n\nimport \"v2ray.com/core/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interfa"
  },
  {
    "path": "app/proxyman/outbound/handler.go",
    "chars": 6831,
    "preview": "package outbound\n\nimport (\n\t\"context\"\n\n\t\"v2ray.com/core\"\n\t\"v2ray.com/core/app/proxyman\"\n\t\"v2ray.com/core/common\"\n\t\"v2ray"
  },
  {
    "path": "app/proxyman/outbound/handler_test.go",
    "chars": 2148,
    "preview": "package outbound_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"v2ray.com/core\"\n\t\"v2ray.com/core/app/policy\"\n\t. \"v2ray.com/core"
  },
  {
    "path": "app/proxyman/outbound/outbound.go",
    "chars": 3577,
    "preview": "package outbound\n\n//go:generate go run v2ray.com/core/common/errors/errorgen\n\nimport (\n\t\"context\"\n\t\"strings\"\n\t\"sync\"\n\n\t\""
  },
  {
    "path": "app/proxyman/proxyman.go",
    "chars": 666,
    "preview": "// Package proxyman defines applications for managing inbound and outbound proxies.\npackage proxyman\n\nimport (\n\t\"context"
  },
  {
    "path": "app/reverse/bridge.go",
    "chars": 4065,
    "preview": "// +build !confonly\n\npackage reverse\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"github.com/golang/protobuf/proto\"\n\t\"v2ray.com/core/"
  },
  {
    "path": "app/reverse/config.go",
    "chars": 245,
    "preview": "// +build !confonly\n\npackage reverse\n\nimport (\n\t\"crypto/rand\"\n\t\"io\"\n\n\t\"v2ray.com/core/common/dice\"\n)\n\nfunc (c *Control) "
  },
  {
    "path": "app/reverse/config.pb.go",
    "chars": 14287,
    "preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.25.0\n// \tprotoc        v3.13.0\n// sou"
  },
  {
    "path": "app/reverse/config.proto",
    "chars": 593,
    "preview": "syntax = \"proto3\";\n\npackage v2ray.core.app.reverse;\noption csharp_namespace = \"V2Ray.Core.Proxy.Reverse\";\noption go_pack"
  },
  {
    "path": "app/reverse/errors.generated.go",
    "chars": 205,
    "preview": "package reverse\n\nimport \"v2ray.com/core/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interfac"
  },
  {
    "path": "app/reverse/portal.go",
    "chars": 5433,
    "preview": "// +build !confonly\n\npackage reverse\n\nimport (\n\t\"context\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/golang/protobuf/proto\"\n\t\"v2ray.c"
  },
  {
    "path": "app/reverse/portal_test.go",
    "chars": 374,
    "preview": "package reverse_test\n\nimport (\n\t\"testing\"\n\n\t\"v2ray.com/core/app/reverse\"\n\t\"v2ray.com/core/common\"\n)\n\nfunc TestStaticPick"
  },
  {
    "path": "app/reverse/reverse.go",
    "chars": 1939,
    "preview": "// +build !confonly\n\npackage reverse\n\n//go:generate go run v2ray.com/core/common/errors/errorgen\n\nimport (\n\t\"context\"\n\n\t"
  },
  {
    "path": "app/router/balancing.go",
    "chars": 889,
    "preview": "// +build !confonly\n\npackage router\n\nimport (\n\t\"v2ray.com/core/common/dice\"\n\t\"v2ray.com/core/features/outbound\"\n)\n\ntype "
  },
  {
    "path": "app/router/command/command.go",
    "chars": 2628,
    "preview": "// +build !confonly\n\npackage command\n\n//go:generate go run v2ray.com/core/common/errors/errorgen\n\nimport (\n\t\"context\"\n\t\""
  },
  {
    "path": "app/router/command/command.pb.go",
    "chars": 22641,
    "preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.25.0\n// \tprotoc        v3.13.0\n// sou"
  },
  {
    "path": "app/router/command/command.proto",
    "chars": 2551,
    "preview": "syntax = \"proto3\";\n\npackage v2ray.core.app.router.command;\noption csharp_namespace = \"V2Ray.Core.App.Router.Command\";\nop"
  },
  {
    "path": "app/router/command/command_grpc.pb.go",
    "chars": 5783,
    "preview": "// Code generated by protoc-gen-go-grpc. DO NOT EDIT.\n\npackage command\n\nimport (\n\tcontext \"context\"\n\tgrpc \"google.golang"
  },
  {
    "path": "app/router/command/command_test.go",
    "chars": 10174,
    "preview": "package command_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/golang/mock/gomock\"\n\t\"github.com/google/go-cm"
  },
  {
    "path": "app/router/command/config.go",
    "chars": 3402,
    "preview": "package command\n\nimport (\n\t\"strings\"\n\n\t\"v2ray.com/core/common/net\"\n\t\"v2ray.com/core/features/routing\"\n)\n\n// routingConte"
  },
  {
    "path": "app/router/command/errors.generated.go",
    "chars": 205,
    "preview": "package command\n\nimport \"v2ray.com/core/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interfac"
  },
  {
    "path": "app/router/condition.go",
    "chars": 6492,
    "preview": "// +build !confonly\n\npackage router\n\nimport (\n\t\"strings\"\n\n\t\"go.starlark.net/starlark\"\n\t\"go.starlark.net/syntax\"\n\n\t\"v2ray"
  },
  {
    "path": "app/router/condition_geoip.go",
    "chars": 3631,
    "preview": "// +build !confonly\n\npackage router\n\nimport (\n\t\"encoding/binary\"\n\t\"sort\"\n\n\t\"v2ray.com/core/common/net\"\n)\n\ntype ipv6 stru"
  },
  {
    "path": "app/router/condition_geoip_test.go",
    "chars": 4393,
    "preview": "package router_test\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n\t\"testing\"\n\n\tproto \"github.com/golang/protobuf/proto\"\n\t\"v2ray.com/c"
  },
  {
    "path": "app/router/condition_test.go",
    "chars": 10224,
    "preview": "package router_test\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n\t\"strconv\"\n\t\"testing\"\n\n\tproto \"github.com/golang/protobuf/proto\"\n\n\t"
  },
  {
    "path": "app/router/config.go",
    "chars": 3189,
    "preview": "// +build !confonly\n\npackage router\n\nimport (\n\t\"v2ray.com/core/common/net\"\n\t\"v2ray.com/core/features/outbound\"\n\t\"v2ray.c"
  },
  {
    "path": "app/router/config.pb.go",
    "chars": 43887,
    "preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.25.0\n// \tprotoc        v3.13.0\n// sou"
  },
  {
    "path": "app/router/config.proto",
    "chars": 3593,
    "preview": "syntax = \"proto3\";\n\npackage v2ray.core.app.router;\noption csharp_namespace = \"V2Ray.Core.App.Router\";\noption go_package "
  },
  {
    "path": "app/router/errors.generated.go",
    "chars": 204,
    "preview": "package router\n\nimport \"v2ray.com/core/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface"
  },
  {
    "path": "app/router/router.go",
    "chars": 3313,
    "preview": "// +build !confonly\n\npackage router\n\n//go:generate go run v2ray.com/core/common/errors/errorgen\n\nimport (\n\t\"context\"\n\n\t\""
  },
  {
    "path": "app/router/router_test.go",
    "chars": 4967,
    "preview": "package router_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/golang/mock/gomock\"\n\t. \"v2ray.com/core/app/router\"\n\t\"v"
  },
  {
    "path": "app/stats/channel.go",
    "chars": 4229,
    "preview": "// +build !confonly\n\npackage stats\n\nimport (\n\t\"context\"\n\t\"sync\"\n\n\t\"v2ray.com/core/common\"\n)\n\n// Channel is an implementa"
  },
  {
    "path": "app/stats/channel_test.go",
    "chars": 9693,
    "preview": "package stats_test\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"testing\"\n\t\"time\"\n\n\t. \"v2ray.com/core/app/stats\"\n\t\"v2ray.com/core/common"
  },
  {
    "path": "app/stats/command/command.go",
    "chars": 2834,
    "preview": "// +build !confonly\n\npackage command\n\n//go:generate go run v2ray.com/core/common/errors/errorgen\n\nimport (\n\t\"context\"\n\t\""
  },
  {
    "path": "app/stats/command/command.pb.go",
    "chars": 25406,
    "preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.25.0\n// \tprotoc        v3.13.0\n// sou"
  },
  {
    "path": "app/stats/command/command.proto",
    "chars": 1183,
    "preview": "syntax = \"proto3\";\n\npackage v2ray.core.app.stats.command;\noption csharp_namespace = \"V2Ray.Core.App.Stats.Command\";\nopti"
  },
  {
    "path": "app/stats/command/command_grpc.pb.go",
    "chars": 6377,
    "preview": "// Code generated by protoc-gen-go-grpc. DO NOT EDIT.\n\npackage command\n\nimport (\n\tcontext \"context\"\n\tgrpc \"google.golang"
  },
  {
    "path": "app/stats/command/command_test.go",
    "chars": 1843,
    "preview": "package command_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"github.com/google/go-cmp/cmp/cmp"
  },
  {
    "path": "app/stats/command/errors.generated.go",
    "chars": 205,
    "preview": "package command\n\nimport \"v2ray.com/core/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interfac"
  },
  {
    "path": "app/stats/config.pb.go",
    "chars": 7364,
    "preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.25.0\n// \tprotoc        v3.13.0\n// sou"
  },
  {
    "path": "app/stats/config.proto",
    "chars": 353,
    "preview": "syntax = \"proto3\";\n\npackage v2ray.core.app.stats;\noption csharp_namespace = \"V2Ray.Core.App.Stats\";\noption go_package = "
  },
  {
    "path": "app/stats/counter.go",
    "chars": 499,
    "preview": "// +build !confonly\n\npackage stats\n\nimport \"sync/atomic\"\n\n// Counter is an implementation of stats.Counter.\ntype Counter"
  },
  {
    "path": "app/stats/counter_test.go",
    "chars": 631,
    "preview": "package stats_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t. \"v2ray.com/core/app/stats\"\n\t\"v2ray.com/core/common\"\n\t\"v2ray.com/c"
  },
  {
    "path": "app/stats/errors.generated.go",
    "chars": 203,
    "preview": "package stats\n\nimport \"v2ray.com/core/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{"
  },
  {
    "path": "app/stats/stats.go",
    "chars": 3854,
    "preview": "// +build !confonly\n\npackage stats\n\n//go:generate go run v2ray.com/core/common/errors/errorgen\n\nimport (\n\t\"context\"\n\t\"sy"
  },
  {
    "path": "app/stats/stats_test.go",
    "chars": 1971,
    "preview": "package stats_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\t\"time\"\n\n\t. \"v2ray.com/core/app/stats\"\n\t\"v2ray.com/core/common\"\n\t\"v2r"
  },
  {
    "path": "azure-pipelines.yml",
    "chars": 1590,
    "preview": "trigger:\n  batch: true\n  branches:\n    include:\n      - master\n      - dev*\n      - refs/tags/*\n\npool:\n  vmImage: \"ubunt"
  },
  {
    "path": "common/antireplay/antireplay.go",
    "chars": 987,
    "preview": "package antireplay\n\nimport (\n\tcuckoo \"github.com/seiflotfy/cuckoofilter\"\n\t\"sync\"\n\t\"time\"\n)\n\nfunc NewAntiReplayWindow(Ant"
  },
  {
    "path": "common/bitmask/byte.go",
    "chars": 318,
    "preview": "package bitmask\n\n// Byte is a bitmask in byte.\ntype Byte byte\n\n// Has returns true if this bitmask contains another bitm"
  },
  {
    "path": "common/bitmask/byte_test.go",
    "chars": 692,
    "preview": "package bitmask_test\n\nimport (\n\t\"testing\"\n\n\t. \"v2ray.com/core/common/bitmask\"\n)\n\nfunc TestBitmaskByte(t *testing.T) {\n\tb"
  },
  {
    "path": "common/buf/buf.go",
    "chars": 178,
    "preview": "// Package buf provides a light-weight memory allocation mechanism.\npackage buf // import \"v2ray.com/core/common/buf\"\n\n/"
  },
  {
    "path": "common/buf/buffer.go",
    "chars": 4508,
    "preview": "package buf\n\nimport (\n\t\"io\"\n\n\t\"v2ray.com/core/common/bytespool\"\n)\n\nconst (\n\t// Size of a regular buffer.\n\tSize = 2048\n)\n"
  },
  {
    "path": "common/buf/buffer_test.go",
    "chars": 4465,
    "preview": "package buf_test\n\nimport (\n\t\"bytes\"\n\t\"crypto/rand\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"v2ray.com/core/common\"\n"
  },
  {
    "path": "common/buf/copy.go",
    "chars": 2637,
    "preview": "package buf\n\nimport (\n\t\"io\"\n\t\"time\"\n\n\t\"v2ray.com/core/common/errors\"\n\t\"v2ray.com/core/common/signal\"\n)\n\ntype dataHandler"
  },
  {
    "path": "common/buf/copy_test.go",
    "chars": 1487,
    "preview": "package buf_test\n\nimport (\n\t\"crypto/rand\"\n\t\"io\"\n\t\"testing\"\n\n\t\"github.com/golang/mock/gomock\"\n\n\t\"v2ray.com/core/common/bu"
  },
  {
    "path": "common/buf/errors.generated.go",
    "chars": 201,
    "preview": "package buf\n\nimport \"v2ray.com/core/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{})"
  },
  {
    "path": "common/buf/io.go",
    "chars": 2462,
    "preview": "package buf\n\nimport (\n\t\"io\"\n\t\"net\"\n\t\"os\"\n\t\"syscall\"\n\t\"time\"\n)\n\n// Reader extends io.Reader with MultiBuffer.\ntype Reader"
  },
  {
    "path": "common/buf/io_test.go",
    "chars": 975,
    "preview": "package buf_test\n\nimport (\n\t\"crypto/tls\"\n\t\"io\"\n\t\"testing\"\n\n\t. \"v2ray.com/core/common/buf\"\n\t\"v2ray.com/core/common/net\"\n\t"
  },
  {
    "path": "common/buf/multi_buffer.go",
    "chars": 6390,
    "preview": "package buf\n\nimport (\n\t\"io\"\n\n\t\"v2ray.com/core/common\"\n\t\"v2ray.com/core/common/errors\"\n\t\"v2ray.com/core/common/serial\"\n)\n"
  },
  {
    "path": "common/buf/multi_buffer_test.go",
    "chars": 3785,
    "preview": "package buf_test\n\nimport (\n\t\"bytes\"\n\t\"crypto/rand\"\n\t\"io\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"io/ioutil\"\n\t\"os\"\n"
  },
  {
    "path": "common/buf/reader.go",
    "chars": 3797,
    "preview": "package buf\n\nimport (\n\t\"io\"\n\n\t\"v2ray.com/core/common\"\n\t\"v2ray.com/core/common/errors\"\n)\n\nfunc readOneUDP(r io.Reader) (*"
  },
  {
    "path": "common/buf/reader_test.go",
    "chars": 2920,
    "preview": "package buf_test\n\nimport (\n\t\"bytes\"\n\t\"io\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"v2ray.com/core/common\"\n\t. \"v2ray.com/core/common/buf\""
  },
  {
    "path": "common/buf/readv_posix.go",
    "chars": 823,
    "preview": "// +build !windows\n// +build !wasm\n// +build !illumos\n\npackage buf\n\nimport (\n\t\"syscall\"\n\t\"unsafe\"\n)\n\ntype posixReader st"
  },
  {
    "path": "common/buf/readv_reader.go",
    "chars": 2572,
    "preview": "// +build !wasm\n\npackage buf\n\nimport (\n\t\"io\"\n\t\"runtime\"\n\t\"syscall\"\n\n\t\"v2ray.com/core/common/platform\"\n)\n\ntype allocStrat"
  },
  {
    "path": "common/buf/readv_reader_wasm.go",
    "chars": 182,
    "preview": "// +build wasm\n\npackage buf\n\nimport (\n\t\"io\"\n\t\"syscall\"\n)\n\nconst useReadv = false\n\nfunc NewReadVReader(reader io.Reader, "
  },
  {
    "path": "common/buf/readv_test.go",
    "chars": 1296,
    "preview": "// +build !wasm\n\npackage buf_test\n\nimport (\n\t\"crypto/rand\"\n\t\"net\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t\"golang."
  },
  {
    "path": "common/buf/readv_unix.go",
    "chars": 542,
    "preview": "// +build illumos\n\npackage buf\n\nimport \"golang.org/x/sys/unix\"\n\ntype unixReader struct {\n\tiovs [][]byte\n}\n\nfunc (r *unix"
  },
  {
    "path": "common/buf/readv_windows.go",
    "chars": 733,
    "preview": "package buf\n\nimport (\n\t\"syscall\"\n)\n\ntype windowsReader struct {\n\tbufs []syscall.WSABuf\n}\n\nfunc (r *windowsReader) Init(b"
  },
  {
    "path": "common/buf/writer.go",
    "chars": 4997,
    "preview": "package buf\n\nimport (\n\t\"io\"\n\t\"net\"\n\t\"sync\"\n\n\t\"v2ray.com/core/common\"\n\t\"v2ray.com/core/common/errors\"\n)\n\n// BufferToBytes"
  },
  {
    "path": "common/buf/writer_test.go",
    "chars": 2317,
    "preview": "package buf_test\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"crypto/rand\"\n\t\"io\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t\"v2ray.c"
  },
  {
    "path": "common/bytespool/pool.go",
    "chars": 1524,
    "preview": "package bytespool\n\nimport \"sync\"\n\nfunc createAllocFunc(size int32) func() interface{} {\n\treturn func() interface{} {\n\t\tr"
  },
  {
    "path": "common/cmdarg/cmdarg.go",
    "chars": 298,
    "preview": "package cmdarg\n\nimport \"strings\"\n\n// Arg is used by flag to accept multiple argument.\ntype Arg []string\n\nfunc (c *Arg) S"
  },
  {
    "path": "common/common.go",
    "chars": 4442,
    "preview": "// Package common contains common utilities that are shared among other packages.\n// See each sub-package for detail.\npa"
  },
  {
    "path": "common/common_test.go",
    "chars": 787,
    "preview": "package common_test\n\nimport (\n\t\"errors\"\n\t\"testing\"\n\n\t. \"v2ray.com/core/common\"\n)\n\nfunc TestMust(t *testing.T) {\n\thasPani"
  },
  {
    "path": "common/crypto/aes.go",
    "chars": 1256,
    "preview": "package crypto\n\nimport (\n\t\"crypto/aes\"\n\t\"crypto/cipher\"\n\n\t\"v2ray.com/core/common\"\n)\n\n// NewAesDecryptionStream creates a"
  },
  {
    "path": "common/crypto/auth.go",
    "chars": 7800,
    "preview": "package crypto\n\nimport (\n\t\"crypto/cipher\"\n\t\"io\"\n\t\"math/rand\"\n\n\t\"v2ray.com/core/common\"\n\t\"v2ray.com/core/common/buf\"\n\t\"v2"
  },
  {
    "path": "common/crypto/auth_test.go",
    "chars": 3339,
    "preview": "package crypto_test\n\nimport (\n\t\"bytes\"\n\t\"crypto/aes\"\n\t\"crypto/cipher\"\n\t\"crypto/rand\"\n\t\"io\"\n\t\"testing\"\n\n\t\"github.com/goog"
  },
  {
    "path": "common/crypto/benchmark_test.go",
    "chars": 979,
    "preview": "package crypto_test\n\nimport (\n\t\"crypto/cipher\"\n\t\"testing\"\n\n\t. \"v2ray.com/core/common/crypto\"\n)\n\nconst benchSize = 1024 *"
  },
  {
    "path": "common/crypto/chacha20.go",
    "chars": 394,
    "preview": "package crypto\n\nimport (\n\t\"crypto/cipher\"\n\n\t\"v2ray.com/core/common/crypto/internal\"\n)\n\n// NewChaCha20Stream creates a ne"
  },
  {
    "path": "common/crypto/chacha20_test.go",
    "chars": 2327,
    "preview": "package crypto_test\n\nimport (\n\t\"crypto/rand\"\n\t\"encoding/hex\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t\"v2ray.com/co"
  },
  {
    "path": "common/crypto/chunk.go",
    "chars": 3659,
    "preview": "package crypto\n\nimport (\n\t\"encoding/binary\"\n\t\"io\"\n\n\t\"v2ray.com/core/common\"\n\t\"v2ray.com/core/common/buf\"\n)\n\n// ChunkSize"
  },
  {
    "path": "common/crypto/chunk_test.go",
    "chars": 1027,
    "preview": "package crypto_test\n\nimport (\n\t\"bytes\"\n\t\"io\"\n\t\"testing\"\n\n\t\"v2ray.com/core/common\"\n\t\"v2ray.com/core/common/buf\"\n\t. \"v2ray"
  },
  {
    "path": "common/crypto/crypto.go",
    "chars": 178,
    "preview": "// Package crypto provides common crypto libraries for V2Ray.\npackage crypto // import \"v2ray.com/core/common/crypto\"\n\n/"
  },
  {
    "path": "common/crypto/errors.generated.go",
    "chars": 204,
    "preview": "package crypto\n\nimport \"v2ray.com/core/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface"
  },
  {
    "path": "common/crypto/internal/chacha.go",
    "chars": 1942,
    "preview": "package internal\n\n//go:generate go run chacha_core_gen.go\n\nimport (\n\t\"encoding/binary\"\n)\n\nconst (\n\twordSize  = 4        "
  },
  {
    "path": "common/crypto/internal/chacha_core.generated.go",
    "chars": 3159,
    "preview": "package internal\n\nimport \"encoding/binary\"\n\nfunc ChaCha20Block(s *[16]uint32, out []byte, rounds int) {\n\tvar x0, x1, x2,"
  },
  {
    "path": "common/crypto/internal/chacha_core_gen.go",
    "chars": 1811,
    "preview": "// +build generate\n\npackage main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n)\n\nfunc writeQuarterRound(file *os.File, a, b, c, d int) "
  },
  {
    "path": "common/crypto/io.go",
    "chars": 1349,
    "preview": "package crypto\n\nimport (\n\t\"crypto/cipher\"\n\t\"io\"\n\n\t\"v2ray.com/core/common/buf\"\n)\n\ntype CryptionReader struct {\n\tstream ci"
  },
  {
    "path": "common/dice/dice.go",
    "chars": 1055,
    "preview": "// Package dice contains common functions to generate random number.\n// It also initialize math/rand with the time in se"
  },
  {
    "path": "common/dice/dice_test.go",
    "chars": 421,
    "preview": "package dice_test\n\nimport (\n\t\"math/rand\"\n\t\"testing\"\n\n\t. \"v2ray.com/core/common/dice\"\n)\n\nfunc BenchmarkRoll1(b *testing.B"
  },
  {
    "path": "common/errors/errorgen/main.go",
    "chars": 1044,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"v2ray.com/core/common\"\n)\n\nfunc main() {\n\tpwd, err := os.G"
  },
  {
    "path": "common/errors/errors.go",
    "chars": 3748,
    "preview": "// Package errors is a drop-in replacement for Golang lib 'errors'.\npackage errors // import \"v2ray.com/core/common/erro"
  },
  {
    "path": "common/errors/errors_test.go",
    "chars": 1246,
    "preview": "package errors_test\n\nimport (\n\t\"io\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t. \"v2ray.com/core/common/er"
  },
  {
    "path": "common/errors/multi_error.go",
    "chars": 457,
    "preview": "package errors\n\nimport (\n\t\"strings\"\n)\n\ntype multiError []error\n\nfunc (e multiError) Error() string {\n\tvar r strings.Buil"
  },
  {
    "path": "common/errors.generated.go",
    "chars": 204,
    "preview": "package common\n\nimport \"v2ray.com/core/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface"
  },
  {
    "path": "common/interfaces.go",
    "chars": 1662,
    "preview": "package common\n\nimport \"v2ray.com/core/common/errors\"\n\n// Closable is the interface for objects that can release its res"
  },
  {
    "path": "common/log/access.go",
    "chars": 1331,
    "preview": "package log\n\nimport (\n\t\"context\"\n\t\"strings\"\n\n\t\"v2ray.com/core/common/serial\"\n)\n\ntype logKey int\n\nconst (\n\taccessMessageK"
  },
  {
    "path": "common/log/log.go",
    "chars": 1222,
    "preview": "package log // import \"v2ray.com/core/common/log\"\n\nimport (\n\t\"sync\"\n\n\t\"v2ray.com/core/common/serial\"\n)\n\n// Message is th"
  },
  {
    "path": "common/log/log.pb.go",
    "chars": 4899,
    "preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.25.0\n// \tprotoc        v3.13.0\n// sou"
  },
  {
    "path": "common/log/log.proto",
    "chars": 324,
    "preview": "syntax = \"proto3\";\n\npackage v2ray.core.common.log;\noption csharp_namespace = \"V2Ray.Core.Common.Log\";\noption go_package "
  },
  {
    "path": "common/log/log_test.go",
    "chars": 544,
    "preview": "package log_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t\"v2ray.com/core/common/log\"\n\t\"v2ray.com/core/co"
  },
  {
    "path": "common/log/logger.go",
    "chars": 3007,
    "preview": "package log\n\nimport (\n\t\"io\"\n\t\"log\"\n\t\"os\"\n\t\"time\"\n\n\t\"v2ray.com/core/common/platform\"\n\t\"v2ray.com/core/common/signal/done\""
  },
  {
    "path": "common/log/logger_test.go",
    "chars": 775,
    "preview": "package log_test\n\nimport (\n\t\"io/ioutil\"\n\t\"os\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"v2ray.com/core/common\"\n\t\"v2ray.com/core/c"
  },
  {
    "path": "common/mux/client.go",
    "chars": 9471,
    "preview": "package mux\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"sync\"\n\t\"time\"\n\n\t\"v2ray.com/core/common\"\n\t\"v2ray.com/core/common/buf\"\n\t\"v2ray.co"
  },
  {
    "path": "common/mux/client_test.go",
    "chars": 2749,
    "preview": "package mux_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/golang/mock/gomock\"\n\t\"v2ray.com/core/common\"\n\t\"v2"
  },
  {
    "path": "common/mux/errors.generated.go",
    "chars": 201,
    "preview": "package mux\n\nimport \"v2ray.com/core/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{})"
  },
  {
    "path": "common/mux/frame.go",
    "chars": 3361,
    "preview": "package mux\n\nimport (\n\t\"encoding/binary\"\n\t\"io\"\n\n\t\"v2ray.com/core/common\"\n\t\"v2ray.com/core/common/bitmask\"\n\t\"v2ray.com/co"
  },
  {
    "path": "common/mux/frame_test.go",
    "chars": 506,
    "preview": "package mux_test\n\nimport (\n\t\"testing\"\n\n\t\"v2ray.com/core/common\"\n\t\"v2ray.com/core/common/buf\"\n\t\"v2ray.com/core/common/mux"
  },
  {
    "path": "common/mux/mux.go",
    "chars": 72,
    "preview": "package mux\n\n//go:generate go run v2ray.com/core/common/errors/errorgen\n"
  },
  {
    "path": "common/mux/mux_test.go",
    "chars": 4151,
    "preview": "package mux_test\n\nimport (\n\t\"io\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t\"v2ray.com/core/common\"\n\t\"v2ray.com/core/"
  },
  {
    "path": "common/mux/reader.go",
    "chars": 1112,
    "preview": "package mux\n\nimport (\n\t\"io\"\n\n\t\"v2ray.com/core/common/buf\"\n\t\"v2ray.com/core/common/crypto\"\n\t\"v2ray.com/core/common/serial"
  },
  {
    "path": "common/mux/server.go",
    "chars": 6393,
    "preview": "package mux\n\nimport (\n\t\"context\"\n\t\"io\"\n\n\t\"v2ray.com/core\"\n\t\"v2ray.com/core/common\"\n\t\"v2ray.com/core/common/buf\"\n\t\"v2ray."
  },
  {
    "path": "common/mux/session.go",
    "chars": 2552,
    "preview": "package mux\n\nimport (\n\t\"sync\"\n\n\t\"v2ray.com/core/common\"\n\t\"v2ray.com/core/common/buf\"\n\t\"v2ray.com/core/common/protocol\"\n)"
  },
  {
    "path": "common/mux/session_test.go",
    "chars": 738,
    "preview": "package mux_test\n\nimport (\n\t\"testing\"\n\n\t. \"v2ray.com/core/common/mux\"\n)\n\nfunc TestSessionManagerAdd(t *testing.T) {\n\tm :"
  },
  {
    "path": "common/mux/writer.go",
    "chars": 2705,
    "preview": "package mux\n\nimport (\n\t\"v2ray.com/core/common\"\n\t\"v2ray.com/core/common/buf\"\n\t\"v2ray.com/core/common/net\"\n\t\"v2ray.com/cor"
  },
  {
    "path": "common/net/address.go",
    "chars": 5118,
    "preview": "package net\n\nimport (\n\t\"bytes\"\n\t\"net\"\n\t\"strings\"\n)\n\nvar (\n\t// LocalHostIP is a constant value for localhost IP in IPv4.\n"
  }
]

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

About this extraction

This page contains the full source code of the v2ray/v2ray-core GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 752 files (14.0 MB), approximately 634.2k tokens, and a symbol index with 5273 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!