├── .gitignore ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── SECURITY.md ├── annotations.go ├── app ├── app.go ├── browserforwarder │ ├── config.pb.go │ ├── config.proto │ ├── errors.generated.go │ └── forwarder.go ├── commander │ ├── commander.go │ ├── config.pb.go │ ├── config.proto │ ├── errors.generated.go │ ├── outbound.go │ └── service.go ├── controller │ ├── config.pb.go │ ├── config.proto │ ├── controller.go │ └── errors.generated.go ├── dispatcher │ ├── config.pb.go │ ├── config.proto │ ├── default.go │ ├── dispatcher.go │ ├── errors.generated.go │ ├── fakednssniffer.go │ ├── sniffer.go │ ├── stats.go │ ├── stats_test.go │ └── traffic.go ├── dns │ ├── config.go │ ├── config.pb.go │ ├── config.proto │ ├── dns.go │ ├── dns_test.go │ ├── dnscommon.go │ ├── dnscommon_test.go │ ├── errors.generated.go │ ├── fakedns │ │ ├── errors.generated.go │ │ ├── fake.go │ │ ├── fakedns.go │ │ ├── fakedns.pb.go │ │ ├── fakedns.proto │ │ └── fakedns_test.go │ ├── hosts.go │ ├── hosts_test.go │ ├── nameserver.go │ ├── nameserver_doh.go │ ├── nameserver_doh_test.go │ ├── nameserver_fakedns.go │ ├── nameserver_local.go │ ├── nameserver_local_test.go │ ├── nameserver_quic.go │ ├── nameserver_quic_test.go │ ├── nameserver_tcp.go │ ├── nameserver_tcp_test.go │ └── nameserver_udp.go ├── history │ ├── config.pb.go │ ├── config.proto │ ├── errors.generated.go │ └── history.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 ├── observatory │ ├── command │ │ ├── command.go │ │ ├── command.pb.go │ │ ├── command.proto │ │ └── command_grpc.pb.go │ ├── config.pb.go │ ├── config.proto │ ├── errors.generated.go │ ├── explainErrors.go │ ├── observatory.go │ └── observer.go ├── online │ ├── config.pb.go │ ├── config.proto │ ├── errors.generated.go │ └── online.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 │ └── strategy_leastping.go ├── rule │ ├── config.pb.go │ ├── config.proto │ ├── errors.generated.go │ └── rule.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 ├── status │ ├── config.pb.go │ ├── config.proto │ ├── errors.generated.go │ ├── status.go │ └── status_test.go └── traffic │ ├── config.pb.go │ ├── config.proto │ ├── errors.generated.go │ └── traffic.go ├── common ├── acme │ ├── acme.go │ ├── errors.generated.go │ ├── linux_cert_windows.go │ ├── local.go │ ├── local_cert.go │ └── test │ │ └── acme.go ├── antireplay │ ├── antireplay.go │ ├── bloomring.go │ └── replayfilter.go ├── api │ ├── client.go │ ├── client_test.go │ ├── errors.generated.go │ ├── model.go │ └── model_test.go ├── bitmask │ ├── byte.go │ └── byte_test.go ├── buf │ ├── buf.go │ ├── buffer.go │ ├── buffer_test.go │ ├── copy.go │ ├── copy_test.go │ ├── data │ │ └── test_MultiBufferReadAllToByte.dat │ ├── errors.generated.go │ ├── io.go │ ├── io_test.go │ ├── limit.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 ├── cache │ ├── lru.go │ └── lru_test.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.generated.go ├── errors │ ├── errorgen │ │ └── main.go │ ├── errors.go │ ├── errors_test.go │ └── multi_error.go ├── httpx │ └── httpsx.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 │ ├── securedload │ │ ├── embedded.go │ │ ├── embeddedhash.go │ │ ├── errors.generated.go │ │ ├── file.go │ │ ├── securedload.go │ │ └── verify.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 ├── strmatcher │ ├── ac_automaton_matcher.go │ ├── benchmark_test.go │ ├── domain_matcher.go │ ├── domain_matcher_test.go │ ├── full_matcher.go │ ├── full_matcher_test.go │ ├── matchers.go │ ├── matchers_test.go │ ├── mph_matcher.go │ ├── strmatcher.go │ └── strmatcher_test.go ├── task │ ├── common.go │ ├── periodic.go │ ├── periodic_test.go │ ├── task.go │ └── task_test.go ├── tlsx │ ├── tlsx.go │ └── tlsx_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 ├── doc └── compiler.md ├── errors.generated.go ├── features ├── controller │ └── controller.go ├── dns │ ├── client.go │ ├── fakedns.go │ └── localdns │ │ ├── client.go │ │ └── errors.generated.go ├── errors.generated.go ├── extension │ ├── browser.go │ ├── contextreceiver.go │ └── observatory.go ├── feature.go ├── history │ └── history.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 └── traffic │ ├── errors.generated.go │ └── traffic.go ├── format.go ├── functions.go ├── functions_test.go ├── go.mod ├── go.sum ├── infra ├── conf │ ├── api.go │ ├── blackhole.go │ ├── blackhole_test.go │ ├── browser_forwarder.go │ ├── buildable.go │ ├── cfgcommon │ │ ├── common.go │ │ ├── common_test.go │ │ ├── errors.generated.go │ │ └── session.go │ ├── command │ │ ├── command.go │ │ └── errors.generated.go │ ├── conf.go │ ├── dns.go │ ├── dns_proxy.go │ ├── dns_proxy_test.go │ ├── dns_test.go │ ├── dokodemo.go │ ├── dokodemo_test.go │ ├── errors.generated.go │ ├── fakedns.go │ ├── freedom.go │ ├── freedom_test.go │ ├── general_test.go │ ├── geodata │ │ ├── attr.go │ │ ├── errors.generated.go │ │ ├── geodata.go │ │ ├── geodata_test.go │ │ ├── geodataproto.go │ │ ├── memconservative │ │ │ ├── cache.go │ │ │ ├── decode.go │ │ │ ├── decode_test.go │ │ │ ├── errors.generated.go │ │ │ └── memc.go │ │ └── standard │ │ │ ├── errors.generated.go │ │ │ └── standard.go │ ├── gun.go │ ├── http.go │ ├── http_test.go │ ├── init.go │ ├── json │ │ ├── reader.go │ │ └── reader_test.go │ ├── lint.go │ ├── loader.go │ ├── log.go │ ├── loopback.go │ ├── mtproto.go │ ├── mtproto_test.go │ ├── observatory.go │ ├── policy.go │ ├── policy_test.go │ ├── reverse.go │ ├── reverse_test.go │ ├── router.go │ ├── router_strategy.go │ ├── router_test.go │ ├── rule │ │ ├── errors.generated.go │ │ ├── rule.go │ │ └── rule_test.go │ ├── serial │ │ ├── errors.generated.go │ │ ├── loader.go │ │ ├── loader_test.go │ │ └── serial.go │ ├── services.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 │ ├── certchainhash.go │ ├── command.go │ ├── config.go │ ├── control.go │ ├── errors.generated.go │ ├── fetch.go │ ├── love.go │ ├── main │ │ └── main.go │ ├── tlsping.go │ ├── uuid.go │ └── verify.go ├── vformat │ └── main.go └── vprotogen │ └── main.go ├── main ├── client.json ├── 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 └── server.json ├── 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 ├── loopback │ ├── config.go │ ├── config.pb.go │ ├── config.proto │ ├── errors.generated.go │ └── loopback.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 │ └── kdf_test.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 ├── config │ ├── config.json │ ├── systemd │ │ └── system │ │ │ ├── v2ray.service │ │ │ └── v2ray@.service │ ├── vpoint_socks_vmess.json │ └── vpoint_vmess_freedom.json ├── debian │ ├── changelog │ ├── control │ ├── copyright │ ├── rules │ ├── source │ │ └── format │ ├── v2ray-docs.docs │ ├── v2ray-domain-list-community.install │ ├── v2ray-geoip.install │ ├── v2ray.install │ ├── v2ray.service │ └── v2ray@.service ├── extra │ └── browserforwarder │ │ ├── index.html │ │ └── index.js ├── friendly-filenames.json ├── install-release.sh ├── requestsign.sh └── user-package.sh ├── release_vnet ├── BUILD ├── config │ ├── config.json │ ├── geoip.dat │ ├── geosite.dat │ ├── systemd │ │ └── vnet-v2ray.service │ └── systemv │ │ └── vnet-v2ray ├── deplody.sh ├── doc │ └── readme.md ├── install.sh ├── mapping.bzl ├── release-ci.sh ├── user-package.sh ├── verify │ └── official_release.asc └── version.json ├── release_vnet_v2ray ├── config │ ├── config.json │ └── systemd │ │ └── system │ │ ├── vnet-v2ray.service │ │ └── vnet-v2ray@.service ├── debian │ ├── changelog │ ├── control │ ├── copyright │ ├── rules │ ├── source │ │ └── format │ ├── v2ray-docs.docs │ ├── v2ray-domain-list-community.install │ ├── v2ray-geoip.install │ ├── v2ray.install │ ├── v2ray.service │ └── v2ray@.service ├── extra │ └── browserforwarder │ │ ├── index.html │ │ └── index.js ├── friendly-filenames.json ├── install-release.sh ├── requestsign.sh └── user-package.sh ├── testing ├── coverage │ └── coverall.sh ├── 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 │ ├── filelocker.go │ ├── filelocker_other.go │ ├── filelocker_windows.go │ ├── grpc │ │ ├── config.go │ │ ├── config.pb.go │ │ ├── config.proto │ │ ├── dial.go │ │ ├── encoding │ │ │ ├── conn.go │ │ │ ├── customSeviceName.go │ │ │ ├── encoding.go │ │ │ ├── errors.generated.go │ │ │ ├── stream.pb.go │ │ │ ├── stream.proto │ │ │ └── stream_grpc.pb.go │ │ ├── errors.generated.go │ │ ├── grpc.go │ │ └── hub.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_dns_android.go │ ├── system_dns_android_test.go │ ├── system_listener.go │ ├── system_listener_test.go │ ├── tagged │ │ ├── tagged.go │ │ └── taggedimpl │ │ │ ├── errors.generated.go │ │ │ ├── impl.go │ │ │ └── taggedimpl.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 │ │ ├── pin.go │ │ ├── pin_test.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 │ │ ├── connforwarder.go │ │ ├── dialer.go │ │ ├── errors.generated.go │ │ ├── hub.go │ │ ├── ws.go │ │ └── ws_test.go ├── link.go └── pipe │ ├── impl.go │ ├── pipe.go │ ├── pipe_test.go │ ├── reader.go │ └── writer.go ├── v2ray.go ├── v2ray_test.go └── vnet ├── BUILD ├── config.json ├── config.json.iovoi ├── config.json.vnetpanel ├── errors.generated.go ├── install.sh ├── main.go ├── main_test.go └── targets.bzl /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, built with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | # Dependency directories (remove the comment below to include it) 15 | # vendor/ 16 | 17 | *.DS_Store 18 | .idea 19 | *.zip 20 | *.tar.gz 21 | v2ray 22 | v2ctl 23 | mockgen 24 | vprotogen 25 | !infra/vprotogen/ 26 | errorgen 27 | !common/errors/errorgen/ 28 | *.dat 29 | -------------------------------------------------------------------------------- /annotations.go: -------------------------------------------------------------------------------- 1 | package core 2 | 3 | // Annotation is a concept in V2Ray. This struct is only for documentation. It is not used anywhere. 4 | // Annotations begin with "v2ray:" in comment, as metadata of functions or types. 5 | type Annotation struct { 6 | // API is for types or functions that can be used in other libs. Possible values are: 7 | // 8 | // * v2ray:api:beta for types or functions that are ready for use, but maybe changed in the future. 9 | // * v2ray:api:stable for types or functions with guarantee of backward compatibility. 10 | // * v2ray:api:deprecated for types or functions that should not be used anymore. 11 | // 12 | // Types or functions without api annotation should not be used externally. 13 | API string 14 | } 15 | -------------------------------------------------------------------------------- /app/app.go: -------------------------------------------------------------------------------- 1 | // Package app contains feature implementations of V2Ray. The features may be enabled during runtime. 2 | package app 3 | -------------------------------------------------------------------------------- /app/browserforwarder/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.app.browserforwarder; 4 | 5 | option csharp_namespace = "V2Ray.Core.App.Browserforwarder"; 6 | option go_package = "github.com/v2fly/v2ray-core/v4/app/browserforwarder"; 7 | option java_package = "com.v2ray.core.app.browserforwarder"; 8 | option java_multiple_files = true; 9 | 10 | // Config is the settings for BrowserForwarder. 11 | message Config { 12 | string listen_addr = 1; 13 | int32 listen_port = 2; 14 | } -------------------------------------------------------------------------------- /app/browserforwarder/errors.generated.go: -------------------------------------------------------------------------------- 1 | package browserforwarder 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /app/commander/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.app.commander; 4 | option csharp_namespace = "V2Ray.Core.App.Commander"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/app/commander"; 6 | option java_package = "com.v2ray.core.app.commander"; 7 | option java_multiple_files = true; 8 | 9 | import "common/serial/typed_message.proto"; 10 | 11 | // Config is the settings for Commander. 12 | message Config { 13 | // Tag of the outbound handler that handles grpc connections. 14 | string tag = 1; 15 | // Services that supported by this server. All services must implement Service 16 | // interface. 17 | repeated v2ray.core.common.serial.TypedMessage service = 2; 18 | } 19 | 20 | // ReflectionConfig is the placeholder config for ReflectionService. 21 | message ReflectionConfig {} 22 | -------------------------------------------------------------------------------- /app/commander/errors.generated.go: -------------------------------------------------------------------------------- 1 | package commander 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /app/commander/service.go: -------------------------------------------------------------------------------- 1 | // +build !confonly 2 | 3 | package commander 4 | 5 | import ( 6 | "context" 7 | 8 | "google.golang.org/grpc" 9 | "google.golang.org/grpc/reflection" 10 | 11 | "github.com/v2fly/v2ray-core/v4/common" 12 | ) 13 | 14 | // Service is a Commander service. 15 | type Service interface { 16 | // Register registers the service itself to a gRPC server. 17 | Register(*grpc.Server) 18 | } 19 | 20 | type reflectionService struct{} 21 | 22 | func (r reflectionService) Register(s *grpc.Server) { 23 | reflection.Register(s) 24 | } 25 | 26 | func init() { 27 | common.Must(common.RegisterConfig((*ReflectionConfig)(nil), func(ctx context.Context, cfg interface{}) (interface{}, error) { 28 | return reflectionService{}, nil 29 | })) 30 | } 31 | -------------------------------------------------------------------------------- /app/controller/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.app.controller; 4 | option csharp_namespace = "V2Ray.Core.App.Controller"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/controller"; 6 | option java_package = "com.v2ray.core.app.controller"; 7 | option java_multiple_files = true; 8 | 9 | message Config { 10 | string api_server = 1; 11 | string key = 2; 12 | int32 node_id = 3; 13 | } -------------------------------------------------------------------------------- /app/controller/errors.generated.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /app/dispatcher/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.app.dispatcher; 4 | option csharp_namespace = "V2Ray.Core.App.Dispatcher"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/app/dispatcher"; 6 | option java_package = "com.v2ray.core.app.dispatcher"; 7 | option java_multiple_files = true; 8 | 9 | message SessionConfig { 10 | reserved 1; 11 | } 12 | 13 | message Config { 14 | SessionConfig settings = 1; 15 | } 16 | -------------------------------------------------------------------------------- /app/dispatcher/dispatcher.go: -------------------------------------------------------------------------------- 1 | // +build !confonly 2 | 3 | package dispatcher 4 | 5 | //go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen 6 | -------------------------------------------------------------------------------- /app/dispatcher/errors.generated.go: -------------------------------------------------------------------------------- 1 | package dispatcher 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /app/dispatcher/stats.go: -------------------------------------------------------------------------------- 1 | // +build !confonly 2 | 3 | package dispatcher 4 | 5 | import ( 6 | "github.com/v2fly/v2ray-core/v4/common" 7 | "github.com/v2fly/v2ray-core/v4/common/buf" 8 | "github.com/v2fly/v2ray-core/v4/features/stats" 9 | ) 10 | 11 | type SizeStatWriter struct { 12 | Counter stats.Counter 13 | Writer buf.Writer 14 | } 15 | 16 | func (w *SizeStatWriter) WriteMultiBuffer(mb buf.MultiBuffer) error { 17 | w.Counter.Add(int64(mb.Len())) 18 | return w.Writer.WriteMultiBuffer(mb) 19 | } 20 | 21 | func (w *SizeStatWriter) Close() error { 22 | return common.Close(w.Writer) 23 | } 24 | 25 | func (w *SizeStatWriter) Interrupt() { 26 | common.Interrupt(w.Writer) 27 | } 28 | -------------------------------------------------------------------------------- /app/dispatcher/traffic.go: -------------------------------------------------------------------------------- 1 | package dispatcher 2 | 3 | import ( 4 | "github.com/v2fly/v2ray-core/v4/common" 5 | "github.com/v2fly/v2ray-core/v4/common/buf" 6 | "github.com/v2fly/v2ray-core/v4/features/traffic" 7 | ) 8 | 9 | type TrafficWriter struct { 10 | TM traffic.Manager 11 | Key string 12 | Writer buf.Writer 13 | Up bool 14 | } 15 | 16 | func (t TrafficWriter) WriteMultiBuffer(mb buf.MultiBuffer) error { 17 | if t.Up { 18 | t.TM.Up(t.Key, uint64(mb.Len())) 19 | } else { 20 | t.TM.Down(t.Key, uint64(mb.Len())) 21 | } 22 | return t.Writer.WriteMultiBuffer(mb) 23 | } 24 | 25 | func (w *TrafficWriter) Close() error { 26 | return common.Close(w.Writer) 27 | } 28 | 29 | func (w *TrafficWriter) Interrupt() { 30 | common.Interrupt(w.Writer) 31 | } 32 | -------------------------------------------------------------------------------- /app/dns/errors.generated.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /app/dns/fakedns/errors.generated.go: -------------------------------------------------------------------------------- 1 | package fakedns 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /app/dns/fakedns/fakedns.go: -------------------------------------------------------------------------------- 1 | // +build !confonly 2 | 3 | package fakedns 4 | 5 | //go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen 6 | -------------------------------------------------------------------------------- /app/dns/fakedns/fakedns.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.app.dns.fakedns; 4 | option csharp_namespace = "V2Ray.Core.App.Dns.Fakedns"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/app/dns/fakedns"; 6 | option java_package = "com.v2ray.core.app.dns.fakedns"; 7 | option java_multiple_files = true; 8 | 9 | message FakeDnsPool{ 10 | string ip_pool = 1; //CIDR of IP pool used as fake DNS IP 11 | int64 lruSize = 2; //Size of Pool for remembering relationship between domain name and IP address 12 | } 13 | 14 | message FakeDnsPoolMulti{ 15 | repeated FakeDnsPool pools = 1; 16 | } -------------------------------------------------------------------------------- /app/dns/nameserver_local_test.go: -------------------------------------------------------------------------------- 1 | package dns_test 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | "time" 7 | 8 | . "github.com/v2fly/v2ray-core/v4/app/dns" 9 | "github.com/v2fly/v2ray-core/v4/common" 10 | "github.com/v2fly/v2ray-core/v4/common/net" 11 | "github.com/v2fly/v2ray-core/v4/features/dns" 12 | ) 13 | 14 | func TestLocalNameServer(t *testing.T) { 15 | s := NewLocalNameServer() 16 | ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) 17 | ips, err := s.QueryIP(ctx, "google.com", net.IP{}, dns.IPOption{ 18 | IPv4Enable: true, 19 | IPv6Enable: true, 20 | }, false) 21 | cancel() 22 | common.Must(err) 23 | if len(ips) == 0 { 24 | t.Error("expect some ips, but got 0") 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/history/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.app.history; 4 | option csharp_namespace = "V2Ray.Core.App.History"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/app/history"; 6 | option java_package = "com.v2ray.core.app.history"; 7 | option java_multiple_files = true; 8 | 9 | message Config { 10 | string api_server = 1; 11 | string key = 2; 12 | int32 node_id = 3; 13 | } -------------------------------------------------------------------------------- /app/history/errors.generated.go: -------------------------------------------------------------------------------- 1 | package history 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /app/log/command/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.app.log.command; 4 | option csharp_namespace = "V2Ray.Core.App.Log.Command"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/app/log/command"; 6 | option java_package = "com.v2ray.core.app.log.command"; 7 | option java_multiple_files = true; 8 | 9 | message Config {} 10 | 11 | message RestartLoggerRequest {} 12 | 13 | message RestartLoggerResponse {} 14 | 15 | service LoggerService { 16 | rpc RestartLogger(RestartLoggerRequest) returns (RestartLoggerResponse) {} 17 | } 18 | -------------------------------------------------------------------------------- /app/log/command/errors.generated.go: -------------------------------------------------------------------------------- 1 | package command 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /app/log/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.app.log; 4 | option csharp_namespace = "V2Ray.Core.App.Log"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/app/log"; 6 | option java_package = "com.v2ray.core.app.log"; 7 | option java_multiple_files = true; 8 | 9 | import "common/log/log.proto"; 10 | 11 | enum LogType { 12 | None = 0; 13 | Console = 1; 14 | File = 2; 15 | Event = 3; 16 | } 17 | 18 | message Config { 19 | LogType error_log_type = 1; 20 | v2ray.core.common.log.Severity error_log_level = 2; 21 | string error_log_path = 3; 22 | 23 | LogType access_log_type = 4; 24 | string access_log_path = 5; 25 | } 26 | -------------------------------------------------------------------------------- /app/log/errors.generated.go: -------------------------------------------------------------------------------- 1 | package log 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /app/observatory/command/command.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.app.observatory.command; 4 | option csharp_namespace = "V2Ray.Core.App.Observatory.Command"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/app/observatory/command"; 6 | option java_package = "com.v2ray.core.app.observatory.command"; 7 | option java_multiple_files = true; 8 | 9 | import "app/observatory/config.proto"; 10 | 11 | message GetOutboundStatusRequest { 12 | } 13 | 14 | message GetOutboundStatusResponse { 15 | v2ray.core.app.observatory.ObservationResult status = 1; 16 | } 17 | 18 | service ObservatoryService { 19 | rpc GetOutboundStatus(GetOutboundStatusRequest) 20 | returns (GetOutboundStatusResponse) {} 21 | } 22 | 23 | 24 | message Config {} -------------------------------------------------------------------------------- /app/observatory/errors.generated.go: -------------------------------------------------------------------------------- 1 | package observatory 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /app/observatory/explainErrors.go: -------------------------------------------------------------------------------- 1 | package observatory 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errorCollector struct { 6 | errors *errors.Error 7 | } 8 | 9 | func (e *errorCollector) SubmitError(err error) { 10 | if e.errors == nil { 11 | e.errors = newError("underlying connection error").Base(err) 12 | return 13 | } 14 | e.errors = e.errors.Base(newError("underlying connection error").Base(err)) 15 | } 16 | 17 | func newErrorCollector() *errorCollector { 18 | return &errorCollector{} 19 | } 20 | 21 | func (e *errorCollector) UnderlyingError() error { 22 | if e.errors == nil { 23 | return newError("failed to produce report") 24 | } 25 | return e.errors 26 | } 27 | -------------------------------------------------------------------------------- /app/observatory/observatory.go: -------------------------------------------------------------------------------- 1 | package observatory 2 | 3 | //go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen 4 | -------------------------------------------------------------------------------- /app/online/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.app.online; 4 | option csharp_namespace = "V2Ray.Core.App.Online"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/app/online"; 6 | option java_package = "com.v2ray.core.app.online"; 7 | option java_multiple_files = true; 8 | 9 | message Config { 10 | string api_server = 1; 11 | string key = 2; 12 | int32 node_id = 3; 13 | } -------------------------------------------------------------------------------- /app/online/errors.generated.go: -------------------------------------------------------------------------------- 1 | package online 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /app/policy/errors.generated.go: -------------------------------------------------------------------------------- 1 | package policy 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /app/policy/policy.go: -------------------------------------------------------------------------------- 1 | // Package policy is an implementation of policy.Manager feature. 2 | package policy 3 | 4 | //go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen 5 | -------------------------------------------------------------------------------- /app/proxyman/command/doc.go: -------------------------------------------------------------------------------- 1 | package command 2 | 3 | //go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen 4 | -------------------------------------------------------------------------------- /app/proxyman/command/errors.generated.go: -------------------------------------------------------------------------------- 1 | package command 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /app/proxyman/config.go: -------------------------------------------------------------------------------- 1 | package proxyman 2 | 3 | func (s *AllocationStrategy) GetConcurrencyValue() uint32 { 4 | if s == nil || s.Concurrency == nil { 5 | return 3 6 | } 7 | return s.Concurrency.Value 8 | } 9 | 10 | func (s *AllocationStrategy) GetRefreshValue() uint32 { 11 | if s == nil || s.Refresh == nil { 12 | return 5 13 | } 14 | return s.Refresh.Value 15 | } 16 | 17 | func (c *ReceiverConfig) GetEffectiveSniffingSettings() *SniffingConfig { 18 | if c.SniffingSettings != nil { 19 | return c.SniffingSettings 20 | } 21 | 22 | if len(c.DomainOverride) > 0 { 23 | var p []string 24 | for _, kd := range c.DomainOverride { 25 | switch kd { 26 | case KnownProtocols_HTTP: 27 | p = append(p, "http") 28 | case KnownProtocols_TLS: 29 | p = append(p, "tls") 30 | } 31 | } 32 | return &SniffingConfig{ 33 | Enabled: true, 34 | DestinationOverride: p, 35 | } 36 | } 37 | 38 | return nil 39 | } 40 | -------------------------------------------------------------------------------- /app/proxyman/inbound/errors.generated.go: -------------------------------------------------------------------------------- 1 | package inbound 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /app/proxyman/outbound/errors.generated.go: -------------------------------------------------------------------------------- 1 | package outbound 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /app/proxyman/proxyman.go: -------------------------------------------------------------------------------- 1 | // Package proxyman defines applications for managing inbound and outbound proxies. 2 | package proxyman 3 | 4 | import ( 5 | "context" 6 | 7 | "v2ray.com/core/common/session" 8 | ) 9 | 10 | // ContextWithSniffingConfig is a wrapper of session.ContextWithContent. 11 | // Deprecated. Use session.ContextWithContent directly. 12 | func ContextWithSniffingConfig(ctx context.Context, c *SniffingConfig) context.Context { 13 | content := session.ContentFromContext(ctx) 14 | if content == nil { 15 | content = new(session.Content) 16 | ctx = session.ContextWithContent(ctx, content) 17 | } 18 | content.SniffingRequest.Enabled = c.Enabled 19 | content.SniffingRequest.OverrideDestinationForProtocol = c.DestinationOverride 20 | return ctx 21 | } 22 | -------------------------------------------------------------------------------- /app/reverse/config.go: -------------------------------------------------------------------------------- 1 | // +build !confonly 2 | 3 | package reverse 4 | 5 | import ( 6 | "crypto/rand" 7 | "io" 8 | 9 | "github.com/v2fly/v2ray-core/v4/common/dice" 10 | ) 11 | 12 | func (c *Control) FillInRandom() { 13 | randomLength := dice.Roll(64) 14 | c.Random = make([]byte, randomLength) 15 | io.ReadFull(rand.Reader, c.Random) 16 | } 17 | -------------------------------------------------------------------------------- /app/reverse/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.app.reverse; 4 | option csharp_namespace = "V2Ray.Core.Proxy.Reverse"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/app/reverse"; 6 | option java_package = "com.v2ray.core.proxy.reverse"; 7 | option java_multiple_files = true; 8 | 9 | message Control { 10 | enum State { 11 | ACTIVE = 0; 12 | DRAIN = 1; 13 | } 14 | 15 | State state = 1; 16 | bytes random = 99; 17 | } 18 | 19 | message BridgeConfig { 20 | string tag = 1; 21 | string domain = 2; 22 | } 23 | 24 | message PortalConfig { 25 | string tag = 1; 26 | string domain = 2; 27 | } 28 | 29 | message Config { 30 | repeated BridgeConfig bridge_config = 1; 31 | repeated PortalConfig portal_config = 2; 32 | } 33 | -------------------------------------------------------------------------------- /app/reverse/errors.generated.go: -------------------------------------------------------------------------------- 1 | package reverse 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /app/reverse/portal_test.go: -------------------------------------------------------------------------------- 1 | package reverse_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/v2fly/v2ray-core/v4/app/reverse" 7 | "github.com/v2fly/v2ray-core/v4/common" 8 | ) 9 | 10 | func TestStaticPickerEmpty(t *testing.T) { 11 | picker, err := reverse.NewStaticMuxPicker() 12 | common.Must(err) 13 | worker, err := picker.PickAvailable() 14 | if err == nil { 15 | t.Error("expected error, but nil") 16 | } 17 | if worker != nil { 18 | t.Error("expected nil worker, but not nil") 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/router/command/errors.generated.go: -------------------------------------------------------------------------------- 1 | package command 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /app/router/errors.generated.go: -------------------------------------------------------------------------------- 1 | package router 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /app/rule/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.app.rule; 4 | option csharp_namespace = "V2Ray.Core.App.Rule"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/app/rule"; 6 | option java_package = "com.v2ray.core.app.rule"; 7 | option java_multiple_files = true; 8 | 9 | message Config { 10 | string api_server = 1; 11 | string key = 2; 12 | int32 node_id = 3; 13 | string redirect_url = 4; 14 | } -------------------------------------------------------------------------------- /app/rule/errors.generated.go: -------------------------------------------------------------------------------- 1 | package rule 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /app/stats/command/errors.generated.go: -------------------------------------------------------------------------------- 1 | package command 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /app/stats/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.app.stats; 4 | option csharp_namespace = "V2Ray.Core.App.Stats"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/app/stats"; 6 | option java_package = "com.v2ray.core.app.stats"; 7 | option java_multiple_files = true; 8 | 9 | message Config {} 10 | 11 | message ChannelConfig { 12 | bool Blocking = 1; 13 | int32 SubscriberLimit = 2; 14 | int32 BufferSize = 3; 15 | } 16 | -------------------------------------------------------------------------------- /app/stats/counter.go: -------------------------------------------------------------------------------- 1 | // +build !confonly 2 | 3 | package stats 4 | 5 | import "sync/atomic" 6 | 7 | // Counter is an implementation of stats.Counter. 8 | type Counter struct { 9 | value int64 10 | } 11 | 12 | // Value implements stats.Counter. 13 | func (c *Counter) Value() int64 { 14 | return atomic.LoadInt64(&c.value) 15 | } 16 | 17 | // Set implements stats.Counter. 18 | func (c *Counter) Set(newValue int64) int64 { 19 | return atomic.SwapInt64(&c.value, newValue) 20 | } 21 | 22 | // Add implements stats.Counter. 23 | func (c *Counter) Add(delta int64) int64 { 24 | return atomic.AddInt64(&c.value, delta) 25 | } 26 | -------------------------------------------------------------------------------- /app/stats/counter_test.go: -------------------------------------------------------------------------------- 1 | package stats_test 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | . "github.com/v2fly/v2ray-core/v4/app/stats" 8 | "github.com/v2fly/v2ray-core/v4/common" 9 | "github.com/v2fly/v2ray-core/v4/features/stats" 10 | ) 11 | 12 | func TestStatsCounter(t *testing.T) { 13 | raw, err := common.CreateObject(context.Background(), &Config{}) 14 | common.Must(err) 15 | 16 | m := raw.(stats.Manager) 17 | c, err := m.RegisterCounter("test.counter") 18 | common.Must(err) 19 | 20 | if v := c.Add(1); v != 1 { 21 | t.Fatal("unpexcted Add(1) return: ", v, ", wanted ", 1) 22 | } 23 | 24 | if v := c.Set(0); v != 1 { 25 | t.Fatal("unexpected Set(0) return: ", v, ", wanted ", 1) 26 | } 27 | 28 | if v := c.Value(); v != 0 { 29 | t.Fatal("unexpected Value() return: ", v, ", wanted ", 0) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/stats/errors.generated.go: -------------------------------------------------------------------------------- 1 | package stats 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /app/status/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.app.status; 4 | option csharp_namespace = "V2Ray.Core.App.Status"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/app/status"; 6 | option java_package = "com.v2ray.core.app.status"; 7 | option java_multiple_files = true; 8 | 9 | 10 | message Config { 11 | string api_server = 1; 12 | string key = 2; 13 | int32 node_id = 3; 14 | } -------------------------------------------------------------------------------- /app/status/errors.generated.go: -------------------------------------------------------------------------------- 1 | package status 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /app/traffic/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.app.traffic; 4 | option csharp_namespace = "V2Ray.Core.App.Traffic"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/app/traffic"; 6 | option java_package = "com.v2ray.core.app.traffic"; 7 | option java_multiple_files = true; 8 | 9 | message Config { 10 | string api_server = 1; 11 | string key = 2; 12 | int32 node_id = 3; 13 | } -------------------------------------------------------------------------------- /app/traffic/errors.generated.go: -------------------------------------------------------------------------------- 1 | package traffic 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /common/acme/errors.generated.go: -------------------------------------------------------------------------------- 1 | package acme 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /common/acme/linux_cert_windows.go: -------------------------------------------------------------------------------- 1 | package acme 2 | 3 | const ( 4 | keyPath = "C:\\v2ray\\key.pem" 5 | certPath = "C:\\v2ray\\cert.pem" 6 | ) 7 | -------------------------------------------------------------------------------- /common/acme/local.go: -------------------------------------------------------------------------------- 1 | package acme 2 | 3 | import "io/ioutil" 4 | 5 | func SaveCert(key, cert []byte) error { 6 | 7 | if err := ioutil.WriteFile(keyPath, key, 0644); err != nil { 8 | return err 9 | } 10 | 11 | if err := ioutil.WriteFile(certPath, cert, 0644); err != nil { 12 | return err 13 | } 14 | return nil 15 | } 16 | 17 | func LoadCert() ([]byte, []byte, error) { 18 | key, err := ioutil.ReadFile(keyPath) 19 | if err != nil { 20 | return nil, nil, err 21 | } 22 | 23 | cert, err := ioutil.ReadFile(certPath) 24 | if err != nil { 25 | return nil, nil, err 26 | } 27 | 28 | return key, cert, nil 29 | } 30 | -------------------------------------------------------------------------------- /common/acme/local_cert.go: -------------------------------------------------------------------------------- 1 | // +build !windows 2 | 3 | package acme 4 | 5 | const ( 6 | keyPath = "/etc/v2ray/key.pem" 7 | certPath = "/etc/v2ray/cert.pem" 8 | ) 9 | -------------------------------------------------------------------------------- /common/antireplay/antireplay.go: -------------------------------------------------------------------------------- 1 | package antireplay 2 | 3 | type GeneralizedReplayFilter interface { 4 | Interval() int64 5 | Check(sum []byte) bool 6 | } 7 | -------------------------------------------------------------------------------- /common/antireplay/bloomring.go: -------------------------------------------------------------------------------- 1 | package antireplay 2 | 3 | import ( 4 | "sync" 5 | 6 | ss_bloomring "github.com/v2fly/ss-bloomring" 7 | ) 8 | 9 | type BloomRing struct { 10 | *ss_bloomring.BloomRing 11 | lock *sync.Mutex 12 | } 13 | 14 | func (b BloomRing) Interval() int64 { 15 | return 9999999 16 | } 17 | 18 | func (b BloomRing) Check(sum []byte) bool { 19 | b.lock.Lock() 20 | defer b.lock.Unlock() 21 | if b.Test(sum) { 22 | return false 23 | } 24 | b.Add(sum) 25 | return true 26 | } 27 | 28 | func NewBloomRing() BloomRing { 29 | const ( 30 | DefaultSFCapacity = 1e6 31 | // FalsePositiveRate 32 | DefaultSFFPR = 1e-6 33 | DefaultSFSlot = 10 34 | ) 35 | return BloomRing{ss_bloomring.NewBloomRing(DefaultSFSlot, DefaultSFCapacity, DefaultSFFPR), &sync.Mutex{}} 36 | } 37 | -------------------------------------------------------------------------------- /common/api/errors.generated.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /common/bitmask/byte.go: -------------------------------------------------------------------------------- 1 | package bitmask 2 | 3 | // Byte is a bitmask in byte. 4 | type Byte byte 5 | 6 | // Has returns true if this bitmask contains another bitmask. 7 | func (b Byte) Has(bb Byte) bool { 8 | return (b & bb) != 0 9 | } 10 | 11 | func (b *Byte) Set(bb Byte) { 12 | *b |= bb 13 | } 14 | 15 | func (b *Byte) Clear(bb Byte) { 16 | *b &= ^bb 17 | } 18 | 19 | func (b *Byte) Toggle(bb Byte) { 20 | *b ^= bb 21 | } 22 | -------------------------------------------------------------------------------- /common/bitmask/byte_test.go: -------------------------------------------------------------------------------- 1 | package bitmask_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/v2fly/v2ray-core/v4/common/bitmask" 7 | ) 8 | 9 | func TestBitmaskByte(t *testing.T) { 10 | b := Byte(0) 11 | b.Set(Byte(1)) 12 | if !b.Has(1) { 13 | t.Fatal("expected ", b, " to contain 1, but actually not") 14 | } 15 | 16 | b.Set(Byte(2)) 17 | if !b.Has(2) { 18 | t.Fatal("expected ", b, " to contain 2, but actually not") 19 | } 20 | if !b.Has(1) { 21 | t.Fatal("expected ", b, " to contain 1, but actually not") 22 | } 23 | 24 | b.Clear(Byte(1)) 25 | if !b.Has(2) { 26 | t.Fatal("expected ", b, " to contain 2, but actually not") 27 | } 28 | if b.Has(1) { 29 | t.Fatal("expected ", b, " to not contain 1, but actually did") 30 | } 31 | 32 | b.Toggle(Byte(2)) 33 | if b.Has(2) { 34 | t.Fatal("expected ", b, " to not contain 2, but actually did") 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /common/buf/buf.go: -------------------------------------------------------------------------------- 1 | // Package buf provides a light-weight memory allocation mechanism. 2 | package buf 3 | 4 | //go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen 5 | -------------------------------------------------------------------------------- /common/buf/errors.generated.go: -------------------------------------------------------------------------------- 1 | package buf 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /common/buf/readv_reader_wasm.go: -------------------------------------------------------------------------------- 1 | // +build wasm 2 | 3 | package buf 4 | 5 | import ( 6 | "io" 7 | "syscall" 8 | ) 9 | 10 | const useReadv = false 11 | 12 | func NewReadVReader(reader io.Reader, rawConn syscall.RawConn) Reader { 13 | panic("not implemented") 14 | } 15 | -------------------------------------------------------------------------------- /common/buf/readv_unix.go: -------------------------------------------------------------------------------- 1 | // +build illumos 2 | 3 | package buf 4 | 5 | import "golang.org/x/sys/unix" 6 | 7 | type unixReader struct { 8 | iovs [][]byte 9 | } 10 | 11 | func (r *unixReader) Init(bs []*Buffer) { 12 | iovs := r.iovs 13 | if iovs == nil { 14 | iovs = make([][]byte, 0, len(bs)) 15 | } 16 | for _, b := range bs { 17 | iovs = append(iovs, b.v) 18 | } 19 | r.iovs = iovs 20 | } 21 | 22 | func (r *unixReader) Read(fd uintptr) int32 { 23 | n, e := unix.Readv(int(fd), r.iovs) 24 | if e != nil { 25 | return -1 26 | } 27 | return int32(n) 28 | } 29 | 30 | func (r *unixReader) Clear() { 31 | r.iovs = r.iovs[:0] 32 | } 33 | 34 | func newMultiReader() multiReader { 35 | return &unixReader{} 36 | } 37 | -------------------------------------------------------------------------------- /common/buf/readv_windows.go: -------------------------------------------------------------------------------- 1 | package buf 2 | 3 | import ( 4 | "syscall" 5 | ) 6 | 7 | type windowsReader struct { 8 | bufs []syscall.WSABuf 9 | } 10 | 11 | func (r *windowsReader) Init(bs []*Buffer) { 12 | if r.bufs == nil { 13 | r.bufs = make([]syscall.WSABuf, 0, len(bs)) 14 | } 15 | for _, b := range bs { 16 | r.bufs = append(r.bufs, syscall.WSABuf{Len: uint32(Size), Buf: &b.v[0]}) 17 | } 18 | } 19 | 20 | func (r *windowsReader) Clear() { 21 | for idx := range r.bufs { 22 | r.bufs[idx].Buf = nil 23 | } 24 | r.bufs = r.bufs[:0] 25 | } 26 | 27 | func (r *windowsReader) Read(fd uintptr) int32 { 28 | var nBytes uint32 29 | var flags uint32 30 | err := syscall.WSARecv(syscall.Handle(fd), &r.bufs[0], uint32(len(r.bufs)), &nBytes, &flags, nil, nil) 31 | if err != nil { 32 | return -1 33 | } 34 | return int32(nBytes) 35 | } 36 | 37 | func newMultiReader() multiReader { 38 | return new(windowsReader) 39 | } 40 | -------------------------------------------------------------------------------- /common/cmdarg/cmdarg.go: -------------------------------------------------------------------------------- 1 | package cmdarg 2 | 3 | import "strings" 4 | 5 | // Arg is used by flag to accept multiple argument. 6 | type Arg []string 7 | 8 | func (c *Arg) String() string { 9 | return strings.Join([]string(*c), " ") 10 | } 11 | 12 | // Set is the method flag package calls 13 | func (c *Arg) Set(value string) error { 14 | *c = append(*c, value) 15 | return nil 16 | } 17 | -------------------------------------------------------------------------------- /common/common_test.go: -------------------------------------------------------------------------------- 1 | package common_test 2 | 3 | import ( 4 | "errors" 5 | "testing" 6 | 7 | . "github.com/v2fly/v2ray-core/v4/common" 8 | ) 9 | 10 | func TestMust(t *testing.T) { 11 | hasPanic := func(f func()) (ret bool) { 12 | defer func() { 13 | if r := recover(); r != nil { 14 | ret = true 15 | } 16 | }() 17 | f() 18 | return false 19 | } 20 | 21 | testCases := []struct { 22 | Input func() 23 | Panic bool 24 | }{ 25 | { 26 | Panic: true, 27 | Input: func() { Must(func() error { return errors.New("test error") }()) }, 28 | }, 29 | { 30 | Panic: true, 31 | Input: func() { Must2(func() (int, error) { return 0, errors.New("test error") }()) }, 32 | }, 33 | { 34 | Panic: false, 35 | Input: func() { Must(func() error { return nil }()) }, 36 | }, 37 | } 38 | 39 | for idx, test := range testCases { 40 | if hasPanic(test.Input) != test.Panic { 41 | t.Error("test case #", idx, " expect panic ", test.Panic, " but actually not") 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /common/crypto/chacha20.go: -------------------------------------------------------------------------------- 1 | package crypto 2 | 3 | import ( 4 | "crypto/cipher" 5 | 6 | "github.com/v2fly/v2ray-core/v4/common/crypto/internal" 7 | ) 8 | 9 | // NewChaCha20Stream creates a new Chacha20 encryption/descryption stream based on give key and IV. 10 | // Caller must ensure the length of key is 32 bytes, and length of IV is either 8 or 12 bytes. 11 | func NewChaCha20Stream(key []byte, iv []byte) cipher.Stream { 12 | return internal.NewChaCha20Stream(key, iv, 20) 13 | } 14 | -------------------------------------------------------------------------------- /common/crypto/crypto.go: -------------------------------------------------------------------------------- 1 | // Package crypto provides common crypto libraries for V2Ray. 2 | package crypto 3 | 4 | //go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen 5 | -------------------------------------------------------------------------------- /common/crypto/errors.generated.go: -------------------------------------------------------------------------------- 1 | package crypto 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /common/dice/dice_test.go: -------------------------------------------------------------------------------- 1 | package dice_test 2 | 3 | import ( 4 | "math/rand" 5 | "testing" 6 | 7 | . "github.com/v2fly/v2ray-core/v4/common/dice" 8 | ) 9 | 10 | func BenchmarkRoll1(b *testing.B) { 11 | for i := 0; i < b.N; i++ { 12 | Roll(1) 13 | } 14 | } 15 | 16 | func BenchmarkRoll20(b *testing.B) { 17 | for i := 0; i < b.N; i++ { 18 | Roll(20) 19 | } 20 | } 21 | 22 | func BenchmarkIntn1(b *testing.B) { 23 | for i := 0; i < b.N; i++ { 24 | rand.Intn(1) 25 | } 26 | } 27 | 28 | func BenchmarkIntn20(b *testing.B) { 29 | for i := 0; i < b.N; i++ { 30 | rand.Intn(20) 31 | } 32 | } 33 | 34 | func BenchmarkInt63(b *testing.B) { 35 | for i := 0; i < b.N; i++ { 36 | _ = uint16(rand.Int63() >> 47) 37 | } 38 | } 39 | 40 | func BenchmarkInt31(b *testing.B) { 41 | for i := 0; i < b.N; i++ { 42 | _ = uint16(rand.Int31() >> 15) 43 | } 44 | } 45 | 46 | func BenchmarkIntn(b *testing.B) { 47 | for i := 0; i < b.N; i++ { 48 | _ = uint16(rand.Intn(65536)) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /common/errors.generated.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /common/errors/errorgen/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "path/filepath" 7 | ) 8 | 9 | func main() { 10 | pwd, err := os.Getwd() 11 | if err != nil { 12 | fmt.Println("can not get current working directory") 13 | os.Exit(1) 14 | } 15 | pkg := filepath.Base(pwd) 16 | if pkg == "v2ray-core" { 17 | pkg = "core" 18 | } 19 | 20 | file, err := os.OpenFile("errors.generated.go", os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0o644) 21 | if err != nil { 22 | fmt.Printf("Failed to generate errors.generated.go: %v", err) 23 | os.Exit(1) 24 | } 25 | defer file.Close() 26 | 27 | fmt.Fprintf(file, `package %s 28 | 29 | import "github.com/v2fly/v2ray-core/v4/common/errors" 30 | 31 | type errPathObjHolder struct{} 32 | 33 | func newError(values ...interface{}) *errors.Error { 34 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 35 | } 36 | `, pkg) 37 | } 38 | -------------------------------------------------------------------------------- /common/errors/multi_error.go: -------------------------------------------------------------------------------- 1 | package errors 2 | 3 | import ( 4 | "strings" 5 | ) 6 | 7 | type multiError []error 8 | 9 | func (e multiError) Error() string { 10 | var r strings.Builder 11 | r.WriteString("multierr: ") 12 | for _, err := range e { 13 | r.WriteString(err.Error()) 14 | r.WriteString(" | ") 15 | } 16 | return r.String() 17 | } 18 | 19 | func Combine(maybeError ...error) error { 20 | var errs multiError 21 | for _, err := range maybeError { 22 | if err != nil { 23 | errs = append(errs, err) 24 | } 25 | } 26 | if len(errs) == 0 { 27 | return nil 28 | } 29 | return errs 30 | } 31 | -------------------------------------------------------------------------------- /common/httpx/httpsx.go: -------------------------------------------------------------------------------- 1 | package httpx 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "time" 7 | ) 8 | 9 | func Http302(redirectUrl string) string { 10 | template := "HTTP/1.1 302 Moved Temporarily\r\n" 11 | template += "Server: nginx\r\n" 12 | template += fmt.Sprintf("Location: %s\r\n\r\n", redirectUrl) 13 | return template 14 | } 15 | 16 | // Http403 return 403 Forbidden 17 | func Http403(content string) string { 18 | template := "HTTP/1.1 403 Forbidden\r\n" 19 | template += fmt.Sprintf("Date: %s\r\n", time.Now().Format(http.TimeFormat)) 20 | template += "Content-Type: text/html; charset=utf-8\r\n" 21 | template += fmt.Sprintf("Content-Length: %d\r\n", len(content)) 22 | template += "\r\n" 23 | template += content 24 | return template 25 | } 26 | -------------------------------------------------------------------------------- /common/log/log.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.common.log; 4 | option csharp_namespace = "V2Ray.Core.Common.Log"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/common/log"; 6 | option java_package = "com.v2ray.core.common.log"; 7 | option java_multiple_files = true; 8 | 9 | enum Severity { 10 | Unknown = 0; 11 | Error = 1; 12 | Warning = 2; 13 | Info = 3; 14 | Debug = 4; 15 | } 16 | -------------------------------------------------------------------------------- /common/log/log_test.go: -------------------------------------------------------------------------------- 1 | package log_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/google/go-cmp/cmp" 7 | 8 | "github.com/v2fly/v2ray-core/v4/common/log" 9 | "github.com/v2fly/v2ray-core/v4/common/net" 10 | ) 11 | 12 | type testLogger struct { 13 | value string 14 | } 15 | 16 | func (l *testLogger) Handle(msg log.Message) { 17 | l.value = msg.String() 18 | } 19 | 20 | func TestLogRecord(t *testing.T) { 21 | var logger testLogger 22 | log.RegisterHandler(&logger) 23 | 24 | ip := "8.8.8.8" 25 | log.Record(&log.GeneralMessage{ 26 | Severity: log.Severity_Error, 27 | Content: net.ParseAddress(ip), 28 | }) 29 | 30 | if diff := cmp.Diff("[Error] "+ip, logger.value); diff != "" { 31 | t.Error(diff) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /common/log/logger_test.go: -------------------------------------------------------------------------------- 1 | package log_test 2 | 3 | import ( 4 | "io/ioutil" 5 | "os" 6 | "strings" 7 | "testing" 8 | "time" 9 | 10 | "github.com/v2fly/v2ray-core/v4/common" 11 | "github.com/v2fly/v2ray-core/v4/common/buf" 12 | . "github.com/v2fly/v2ray-core/v4/common/log" 13 | ) 14 | 15 | func TestFileLogger(t *testing.T) { 16 | f, err := ioutil.TempFile("", "vtest") 17 | common.Must(err) 18 | path := f.Name() 19 | common.Must(f.Close()) 20 | 21 | creator, err := CreateFileLogWriter(path) 22 | common.Must(err) 23 | 24 | handler := NewLogger(creator) 25 | handler.Handle(&GeneralMessage{Content: "Test Log"}) 26 | time.Sleep(2 * time.Second) 27 | 28 | common.Must(common.Close(handler)) 29 | 30 | f, err = os.Open(path) 31 | common.Must(err) 32 | defer f.Close() 33 | 34 | b, err := buf.ReadAllToBytes(f) 35 | common.Must(err) 36 | if !strings.Contains(string(b), "Test Log") { 37 | t.Fatal("Expect log text contains 'Test Log', but actually: ", string(b)) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /common/mux/errors.generated.go: -------------------------------------------------------------------------------- 1 | package mux 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /common/mux/frame_test.go: -------------------------------------------------------------------------------- 1 | package mux_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/v2fly/v2ray-core/v4/common" 7 | "github.com/v2fly/v2ray-core/v4/common/buf" 8 | "github.com/v2fly/v2ray-core/v4/common/mux" 9 | "github.com/v2fly/v2ray-core/v4/common/net" 10 | ) 11 | 12 | func BenchmarkFrameWrite(b *testing.B) { 13 | frame := mux.FrameMetadata{ 14 | Target: net.TCPDestination(net.DomainAddress("www.v2fly.org"), net.Port(80)), 15 | SessionID: 1, 16 | SessionStatus: mux.SessionStatusNew, 17 | } 18 | writer := buf.New() 19 | defer writer.Release() 20 | 21 | for i := 0; i < b.N; i++ { 22 | common.Must(frame.WriteTo(writer)) 23 | writer.Clear() 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /common/mux/mux.go: -------------------------------------------------------------------------------- 1 | package mux 2 | 3 | //go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen 4 | -------------------------------------------------------------------------------- /common/mux/session_test.go: -------------------------------------------------------------------------------- 1 | package mux_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/v2fly/v2ray-core/v4/common/mux" 7 | ) 8 | 9 | func TestSessionManagerAdd(t *testing.T) { 10 | m := NewSessionManager() 11 | 12 | s := m.Allocate() 13 | if s.ID != 1 { 14 | t.Error("id: ", s.ID) 15 | } 16 | if m.Size() != 1 { 17 | t.Error("size: ", m.Size()) 18 | } 19 | 20 | s = m.Allocate() 21 | if s.ID != 2 { 22 | t.Error("id: ", s.ID) 23 | } 24 | if m.Size() != 2 { 25 | t.Error("size: ", m.Size()) 26 | } 27 | 28 | s = &Session{ 29 | ID: 4, 30 | } 31 | m.Add(s) 32 | if s.ID != 4 { 33 | t.Error("id: ", s.ID) 34 | } 35 | if m.Size() != 3 { 36 | t.Error("size: ", m.Size()) 37 | } 38 | } 39 | 40 | func TestSessionManagerClose(t *testing.T) { 41 | m := NewSessionManager() 42 | s := m.Allocate() 43 | 44 | if m.CloseIfNoSession() { 45 | t.Error("able to close") 46 | } 47 | m.Remove(s.ID) 48 | if !m.CloseIfNoSession() { 49 | t.Error("not able to close") 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /common/net/address.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.common.net; 4 | option csharp_namespace = "V2Ray.Core.Common.Net"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/common/net"; 6 | option java_package = "com.v2ray.core.common.net"; 7 | option java_multiple_files = true; 8 | 9 | // Address of a network host. It may be either an IP address or a domain 10 | // address. 11 | message IPOrDomain { 12 | oneof address { 13 | // IP address. Must by either 4 or 16 bytes. 14 | bytes ip = 1; 15 | 16 | // Domain address. 17 | string domain = 2; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /common/net/destination.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.common.net; 4 | option csharp_namespace = "V2Ray.Core.Common.Net"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/common/net"; 6 | option java_package = "com.v2ray.core.common.net"; 7 | option java_multiple_files = true; 8 | 9 | import "common/net/network.proto"; 10 | import "common/net/address.proto"; 11 | 12 | // Endpoint of a network connection. 13 | message Endpoint { 14 | Network network = 1; 15 | IPOrDomain address = 2; 16 | uint32 port = 3; 17 | } 18 | -------------------------------------------------------------------------------- /common/net/errors.generated.go: -------------------------------------------------------------------------------- 1 | package net 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /common/net/net.go: -------------------------------------------------------------------------------- 1 | // Package net is a drop-in replacement to Golang's net package, with some more functionalities. 2 | package net 3 | 4 | //go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen 5 | -------------------------------------------------------------------------------- /common/net/network.go: -------------------------------------------------------------------------------- 1 | package net 2 | 3 | func (n Network) SystemString() string { 4 | switch n { 5 | case Network_TCP: 6 | return "tcp" 7 | case Network_UDP: 8 | return "udp" 9 | case Network_UNIX: 10 | return "unix" 11 | default: 12 | return "unknown" 13 | } 14 | } 15 | 16 | // HasNetwork returns true if the network list has a certain network. 17 | func HasNetwork(list []Network, network Network) bool { 18 | for _, value := range list { 19 | if value == network { 20 | return true 21 | } 22 | } 23 | return false 24 | } 25 | -------------------------------------------------------------------------------- /common/net/network.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.common.net; 4 | option csharp_namespace = "V2Ray.Core.Common.Net"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/common/net"; 6 | option java_package = "com.v2ray.core.common.net"; 7 | option java_multiple_files = true; 8 | 9 | enum Network { 10 | Unknown = 0; 11 | 12 | RawTCP = 1 [deprecated = true]; 13 | TCP = 2; 14 | UDP = 3; 15 | UNIX = 4; 16 | } 17 | 18 | // NetworkList is a list of Networks. 19 | message NetworkList { repeated Network network = 1; } 20 | -------------------------------------------------------------------------------- /common/net/port.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.common.net; 4 | option csharp_namespace = "V2Ray.Core.Common.Net"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/common/net"; 6 | option java_package = "com.v2ray.core.common.net"; 7 | option java_multiple_files = true; 8 | 9 | // PortRange represents a range of ports. 10 | message PortRange { 11 | // The port that this range starts from. 12 | uint32 From = 1; 13 | // The port that this range ends with (inclusive). 14 | uint32 To = 2; 15 | } 16 | 17 | // PortList is a list of ports. 18 | message PortList { 19 | repeated PortRange range = 1; 20 | } 21 | -------------------------------------------------------------------------------- /common/net/port_test.go: -------------------------------------------------------------------------------- 1 | package net_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/v2fly/v2ray-core/v4/common/net" 7 | ) 8 | 9 | func TestPortRangeContains(t *testing.T) { 10 | portRange := &PortRange{ 11 | From: 53, 12 | To: 53, 13 | } 14 | 15 | if !portRange.Contains(Port(53)) { 16 | t.Error("expected port range containing 53, but actually not") 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /common/peer/latency.go: -------------------------------------------------------------------------------- 1 | package peer 2 | 3 | import ( 4 | "sync" 5 | ) 6 | 7 | type Latency interface { 8 | Value() uint64 9 | } 10 | 11 | type HasLatency interface { 12 | ConnectionLatency() Latency 13 | HandshakeLatency() Latency 14 | } 15 | 16 | type AverageLatency struct { 17 | access sync.Mutex 18 | value uint64 19 | } 20 | 21 | func (al *AverageLatency) Update(newValue uint64) { 22 | al.access.Lock() 23 | defer al.access.Unlock() 24 | 25 | al.value = (al.value + newValue*2) / 3 26 | } 27 | 28 | func (al *AverageLatency) Value() uint64 { 29 | return al.value 30 | } 31 | -------------------------------------------------------------------------------- /common/peer/peer.go: -------------------------------------------------------------------------------- 1 | package peer 2 | -------------------------------------------------------------------------------- /common/platform/ctlcmd/attr_other.go: -------------------------------------------------------------------------------- 1 | // +build !windows 2 | 3 | package ctlcmd 4 | 5 | import "syscall" 6 | 7 | func getSysProcAttr() *syscall.SysProcAttr { 8 | return nil 9 | } 10 | -------------------------------------------------------------------------------- /common/platform/ctlcmd/attr_windows.go: -------------------------------------------------------------------------------- 1 | // +build windows 2 | 3 | package ctlcmd 4 | 5 | import "syscall" 6 | 7 | func getSysProcAttr() *syscall.SysProcAttr { 8 | return &syscall.SysProcAttr{ 9 | HideWindow: true, 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /common/platform/ctlcmd/errors.generated.go: -------------------------------------------------------------------------------- 1 | package ctlcmd 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /common/platform/securedload/embedded.go: -------------------------------------------------------------------------------- 1 | package securedload 2 | 3 | const allowedHashes = `SHA256 (!#project==v2fly) = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 4 | SHA256 (!#version==embedded) = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 5 | SHA256 (subscriptions/subscriptionsDefinition.v2flyTemplate) = 3f165dba7de0d7c506fbdff3275ea64b76f307df435316a3ea0914ee957793ab 6 | SHA256 (browserforwarder/index.html) = 34f2c573724256421ade769bda18eeac85172bf0aaed00d7b90e41e843a2caef 7 | SHA256 (browserforwarder/index.js) = cb587a075bb0addcdc0d22c9222a48d2c7004b54935b5021379d3d35dc1f2927 8 | 9 | ` 10 | -------------------------------------------------------------------------------- /common/platform/securedload/errors.generated.go: -------------------------------------------------------------------------------- 1 | package securedload 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /common/platform/securedload/file.go: -------------------------------------------------------------------------------- 1 | package securedload 2 | 3 | func GetAssetSecured(name string) ([]byte, error) { 4 | var err error 5 | for k, v := range knownProtectedLoader { 6 | loadedData, errLoad := v.VerifyAndLoad(name) 7 | if errLoad == nil { 8 | return loadedData, nil 9 | } 10 | err = newError(k, " is not loading executable file").Base(errLoad) 11 | } 12 | return nil, err 13 | } 14 | -------------------------------------------------------------------------------- /common/platform/securedload/securedload.go: -------------------------------------------------------------------------------- 1 | package securedload 2 | 3 | //go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen 4 | -------------------------------------------------------------------------------- /common/platform/securedload/verify.go: -------------------------------------------------------------------------------- 1 | package securedload 2 | 3 | type ProtectedLoader interface { 4 | VerifyAndLoad(filename string) ([]byte, error) 5 | } 6 | 7 | var knownProtectedLoader map[string]ProtectedLoader 8 | 9 | func RegisterProtectedLoader(name string, sv ProtectedLoader) { 10 | if knownProtectedLoader == nil { 11 | knownProtectedLoader = map[string]ProtectedLoader{} 12 | } 13 | knownProtectedLoader[name] = sv 14 | } 15 | -------------------------------------------------------------------------------- /common/platform/windows.go: -------------------------------------------------------------------------------- 1 | // +build windows 2 | 3 | package platform 4 | 5 | import "path/filepath" 6 | 7 | func ExpandEnv(s string) string { 8 | // TODO 9 | return s 10 | } 11 | 12 | func LineSeparator() string { 13 | return "\r\n" 14 | } 15 | 16 | func GetToolLocation(file string) string { 17 | const name = "v2ray.location.tool" 18 | toolPath := EnvFlag{Name: name, AltName: NormalizeEnvName(name)}.GetValue(getExecutableDir) 19 | return filepath.Join(toolPath, file+".exe") 20 | } 21 | 22 | // GetAssetLocation search for `file` in the excutable dir 23 | func GetAssetLocation(file string) string { 24 | const name = "v2ray.location.asset" 25 | assetPath := NewEnvFlag(name).GetValue(getExecutableDir) 26 | return filepath.Join(assetPath, file) 27 | } 28 | -------------------------------------------------------------------------------- /common/protocol/account.go: -------------------------------------------------------------------------------- 1 | package protocol 2 | 3 | // Account is a user identity used for authentication. 4 | type Account interface { 5 | Equals(Account) bool 6 | } 7 | 8 | // AsAccount is an object can be converted into account. 9 | type AsAccount interface { 10 | AsAccount() (Account, error) 11 | } 12 | -------------------------------------------------------------------------------- /common/protocol/bittorrent/bittorrent.go: -------------------------------------------------------------------------------- 1 | package bittorrent 2 | 3 | import ( 4 | "errors" 5 | 6 | "github.com/v2fly/v2ray-core/v4/common" 7 | ) 8 | 9 | type SniffHeader struct{} 10 | 11 | func (h *SniffHeader) Protocol() string { 12 | return "bittorrent" 13 | } 14 | 15 | func (h *SniffHeader) Domain() string { 16 | return "" 17 | } 18 | 19 | var errNotBittorrent = errors.New("not bittorrent header") 20 | 21 | func SniffBittorrent(b []byte) (*SniffHeader, error) { 22 | if len(b) < 20 { 23 | return nil, common.ErrNoClue 24 | } 25 | 26 | if b[0] == 19 && string(b[1:20]) == "BitTorrent protocol" { 27 | return &SniffHeader{}, nil 28 | } 29 | 30 | return nil, errNotBittorrent 31 | } 32 | -------------------------------------------------------------------------------- /common/protocol/context.go: -------------------------------------------------------------------------------- 1 | package protocol 2 | 3 | import ( 4 | "context" 5 | ) 6 | 7 | type key int 8 | 9 | const ( 10 | requestKey key = iota 11 | ) 12 | 13 | func ContextWithRequestHeader(ctx context.Context, request *RequestHeader) context.Context { 14 | return context.WithValue(ctx, requestKey, request) 15 | } 16 | 17 | func RequestHeaderFromContext(ctx context.Context) *RequestHeader { 18 | request := ctx.Value(requestKey) 19 | if request == nil { 20 | return nil 21 | } 22 | return request.(*RequestHeader) 23 | } 24 | -------------------------------------------------------------------------------- /common/protocol/dns/errors.generated.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /common/protocol/errors.generated.go: -------------------------------------------------------------------------------- 1 | package protocol 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /common/protocol/headers.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.common.protocol; 4 | option csharp_namespace = "V2Ray.Core.Common.Protocol"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/common/protocol"; 6 | option java_package = "com.v2ray.core.common.protocol"; 7 | option java_multiple_files = true; 8 | 9 | enum SecurityType { 10 | UNKNOWN = 0; 11 | LEGACY = 1; 12 | AUTO = 2; 13 | AES128_GCM = 3; 14 | CHACHA20_POLY1305 = 4; 15 | NONE = 5; 16 | ZERO = 6; 17 | } 18 | 19 | message SecurityConfig { 20 | SecurityType type = 1; 21 | } 22 | -------------------------------------------------------------------------------- /common/protocol/id_test.go: -------------------------------------------------------------------------------- 1 | package protocol_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/v2fly/v2ray-core/v4/common/protocol" 7 | "github.com/v2fly/v2ray-core/v4/common/uuid" 8 | ) 9 | 10 | func TestIdEquals(t *testing.T) { 11 | id1 := NewID(uuid.New()) 12 | id2 := NewID(id1.UUID()) 13 | 14 | if !id1.Equals(id2) { 15 | t.Error("expected id1 to equal id2, but actually not") 16 | } 17 | 18 | if id1.String() != id2.String() { 19 | t.Error(id1.String(), " != ", id2.String()) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /common/protocol/payload.go: -------------------------------------------------------------------------------- 1 | package protocol 2 | 3 | type TransferType byte 4 | 5 | const ( 6 | TransferTypeStream TransferType = 0 7 | TransferTypePacket TransferType = 1 8 | ) 9 | 10 | type AddressType byte 11 | 12 | const ( 13 | AddressTypeIPv4 AddressType = 1 14 | AddressTypeDomain AddressType = 2 15 | AddressTypeIPv6 AddressType = 3 16 | ) 17 | -------------------------------------------------------------------------------- /common/protocol/protocol.go: -------------------------------------------------------------------------------- 1 | package protocol 2 | 3 | //go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen 4 | -------------------------------------------------------------------------------- /common/protocol/server_spec.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.common.protocol; 4 | option csharp_namespace = "V2Ray.Core.Common.Protocol"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/common/protocol"; 6 | option java_package = "com.v2ray.core.common.protocol"; 7 | option java_multiple_files = true; 8 | 9 | import "common/net/address.proto"; 10 | import "common/protocol/user.proto"; 11 | 12 | message ServerEndpoint { 13 | v2ray.core.common.net.IPOrDomain address = 1; 14 | uint32 port = 2; 15 | repeated v2ray.core.common.protocol.User user = 3; 16 | } 17 | -------------------------------------------------------------------------------- /common/protocol/time.go: -------------------------------------------------------------------------------- 1 | package protocol 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/v2fly/v2ray-core/v4/common/dice" 7 | ) 8 | 9 | type Timestamp int64 10 | 11 | type TimestampGenerator func() Timestamp 12 | 13 | func NowTime() Timestamp { 14 | return Timestamp(time.Now().Unix()) 15 | } 16 | 17 | func NewTimestampGenerator(base Timestamp, delta int) TimestampGenerator { 18 | return func() Timestamp { 19 | rangeInDelta := dice.Roll(delta*2) - delta 20 | return base + Timestamp(rangeInDelta) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /common/protocol/time_test.go: -------------------------------------------------------------------------------- 1 | package protocol_test 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | 7 | . "github.com/v2fly/v2ray-core/v4/common/protocol" 8 | ) 9 | 10 | func TestGenerateRandomInt64InRange(t *testing.T) { 11 | base := time.Now().Unix() 12 | delta := 100 13 | generator := NewTimestampGenerator(Timestamp(base), delta) 14 | 15 | for i := 0; i < 100; i++ { 16 | val := int64(generator()) 17 | if val > base+int64(delta) || val < base-int64(delta) { 18 | t.Error(val, " not between ", base-int64(delta), " and ", base+int64(delta)) 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /common/protocol/tls/cert/.gitignore: -------------------------------------------------------------------------------- 1 | *.pem -------------------------------------------------------------------------------- /common/protocol/tls/cert/errors.generated.go: -------------------------------------------------------------------------------- 1 | package cert 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /common/protocol/udp/packet.go: -------------------------------------------------------------------------------- 1 | package udp 2 | 3 | import ( 4 | "github.com/v2fly/v2ray-core/v4/common/buf" 5 | "github.com/v2fly/v2ray-core/v4/common/net" 6 | ) 7 | 8 | // Packet is a UDP packet together with its source and destination address. 9 | type Packet struct { 10 | Payload *buf.Buffer 11 | Source net.Destination 12 | Target net.Destination 13 | } 14 | -------------------------------------------------------------------------------- /common/protocol/udp/udp.go: -------------------------------------------------------------------------------- 1 | package udp 2 | -------------------------------------------------------------------------------- /common/protocol/user.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.common.protocol; 4 | option csharp_namespace = "V2Ray.Core.Common.Protocol"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/common/protocol"; 6 | option java_package = "com.v2ray.core.common.protocol"; 7 | option java_multiple_files = true; 8 | 9 | import "common/serial/typed_message.proto"; 10 | 11 | // User is a generic user for all procotols. 12 | message User { 13 | uint32 level = 1; 14 | string email = 2; 15 | 16 | // Protocol specific account information. Must be the account proto in one of 17 | // the proxies. 18 | v2ray.core.common.serial.TypedMessage account = 3; 19 | } 20 | -------------------------------------------------------------------------------- /common/retry/errors.generated.go: -------------------------------------------------------------------------------- 1 | package retry 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /common/serial/serial.go: -------------------------------------------------------------------------------- 1 | package serial 2 | 3 | import ( 4 | "encoding/binary" 5 | "io" 6 | ) 7 | 8 | // ReadUint16 reads first two bytes from the reader, and then coverts them to an uint16 value. 9 | func ReadUint16(reader io.Reader) (uint16, error) { 10 | var b [2]byte 11 | if _, err := io.ReadFull(reader, b[:]); err != nil { 12 | return 0, err 13 | } 14 | return binary.BigEndian.Uint16(b[:]), nil 15 | } 16 | 17 | // WriteUint16 writes an uint16 value into writer. 18 | func WriteUint16(writer io.Writer, value uint16) (int, error) { 19 | var b [2]byte 20 | binary.BigEndian.PutUint16(b[:], value) 21 | return writer.Write(b[:]) 22 | } 23 | 24 | // WriteUint64 writes an uint64 value into writer. 25 | func WriteUint64(writer io.Writer, value uint64) (int, error) { 26 | var b [8]byte 27 | binary.BigEndian.PutUint64(b[:], value) 28 | return writer.Write(b[:]) 29 | } 30 | -------------------------------------------------------------------------------- /common/serial/string.go: -------------------------------------------------------------------------------- 1 | package serial 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | // ToString serialize an arbitrary value into string. 9 | func ToString(v interface{}) string { 10 | if v == nil { 11 | return "" 12 | } 13 | 14 | switch value := v.(type) { 15 | case string: 16 | return value 17 | case *string: 18 | return *value 19 | case fmt.Stringer: 20 | return value.String() 21 | case error: 22 | return value.Error() 23 | default: 24 | return fmt.Sprintf("%+v", value) 25 | } 26 | } 27 | 28 | // Concat concatenates all input into a single string. 29 | func Concat(v ...interface{}) string { 30 | builder := strings.Builder{} 31 | for _, value := range v { 32 | builder.WriteString(ToString(value)) 33 | } 34 | return builder.String() 35 | } 36 | -------------------------------------------------------------------------------- /common/serial/typed_message.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.common.serial; 4 | option csharp_namespace = "V2Ray.Core.Common.Serial"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/common/serial"; 6 | option java_package = "com.v2ray.core.common.serial"; 7 | option java_multiple_files = true; 8 | 9 | // TypedMessage is a serialized proto message along with its type name. 10 | message TypedMessage { 11 | // The name of the message type, retrieved from protobuf API. 12 | string type = 1; 13 | // Serialized proto message. 14 | bytes value = 2; 15 | } 16 | -------------------------------------------------------------------------------- /common/serial/typed_message_test.go: -------------------------------------------------------------------------------- 1 | package serial_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/v2fly/v2ray-core/v4/common/serial" 7 | ) 8 | 9 | func TestGetInstance(t *testing.T) { 10 | p, err := GetInstance("") 11 | if p != nil { 12 | t.Error("expected nil instance, but got ", p) 13 | } 14 | if err == nil { 15 | t.Error("expect non-nil error, but got nil") 16 | } 17 | } 18 | 19 | func TestConvertingNilMessage(t *testing.T) { 20 | x := ToTypedMessage(nil) 21 | if x != nil { 22 | t.Error("expect nil, but actually not") 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /common/signal/notifier.go: -------------------------------------------------------------------------------- 1 | package signal 2 | 3 | // Notifier is a utility for notifying changes. The change producer may notify changes multiple time, and the consumer may get notified asynchronously. 4 | type Notifier struct { 5 | c chan struct{} 6 | } 7 | 8 | // NewNotifier creates a new Notifier. 9 | func NewNotifier() *Notifier { 10 | return &Notifier{ 11 | c: make(chan struct{}, 1), 12 | } 13 | } 14 | 15 | // Signal signals a change, usually by producer. This method never blocks. 16 | func (n *Notifier) Signal() { 17 | select { 18 | case n.c <- struct{}{}: 19 | default: 20 | } 21 | } 22 | 23 | // Wait returns a channel for waiting for changes. The returned channel never gets closed. 24 | func (n *Notifier) Wait() <-chan struct{} { 25 | return n.c 26 | } 27 | -------------------------------------------------------------------------------- /common/signal/notifier_test.go: -------------------------------------------------------------------------------- 1 | package signal_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/v2fly/v2ray-core/v4/common/signal" 7 | ) 8 | 9 | func TestNotifierSignal(t *testing.T) { 10 | n := NewNotifier() 11 | 12 | w := n.Wait() 13 | n.Signal() 14 | 15 | select { 16 | case <-w: 17 | default: 18 | t.Fail() 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /common/signal/pubsub/pubsub_test.go: -------------------------------------------------------------------------------- 1 | package pubsub_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/v2fly/v2ray-core/v4/common/signal/pubsub" 7 | ) 8 | 9 | func TestPubsub(t *testing.T) { 10 | service := NewService() 11 | 12 | sub := service.Subscribe("a") 13 | service.Publish("a", 1) 14 | 15 | select { 16 | case v := <-sub.Wait(): 17 | if v != 1 { 18 | t.Error("expected subscribed value 1, but got ", v) 19 | } 20 | default: 21 | t.Fail() 22 | } 23 | 24 | sub.Close() 25 | service.Publish("a", 2) 26 | 27 | select { 28 | case <-sub.Wait(): 29 | t.Fail() 30 | default: 31 | } 32 | 33 | service.Cleanup() 34 | } 35 | -------------------------------------------------------------------------------- /common/signal/semaphore/semaphore.go: -------------------------------------------------------------------------------- 1 | package semaphore 2 | 3 | // Instance is an implementation of semaphore. 4 | type Instance struct { 5 | token chan struct{} 6 | } 7 | 8 | // New create a new Semaphore with n permits. 9 | func New(n int) *Instance { 10 | s := &Instance{ 11 | token: make(chan struct{}, n), 12 | } 13 | for i := 0; i < n; i++ { 14 | s.token <- struct{}{} 15 | } 16 | return s 17 | } 18 | 19 | // Wait returns a channel for acquiring a permit. 20 | func (s *Instance) Wait() <-chan struct{} { 21 | return s.token 22 | } 23 | 24 | // Signal releases a permit into the semaphore. 25 | func (s *Instance) Signal() { 26 | s.token <- struct{}{} 27 | } 28 | -------------------------------------------------------------------------------- /common/strmatcher/full_matcher.go: -------------------------------------------------------------------------------- 1 | package strmatcher 2 | 3 | type FullMatcherGroup struct { 4 | matchers map[string][]uint32 5 | } 6 | 7 | func (g *FullMatcherGroup) Add(domain string, value uint32) { 8 | if g.matchers == nil { 9 | g.matchers = make(map[string][]uint32) 10 | } 11 | 12 | g.matchers[domain] = append(g.matchers[domain], value) 13 | } 14 | 15 | func (g *FullMatcherGroup) addMatcher(m fullMatcher, value uint32) { 16 | g.Add(string(m), value) 17 | } 18 | 19 | func (g *FullMatcherGroup) Match(str string) []uint32 { 20 | if g.matchers == nil { 21 | return nil 22 | } 23 | 24 | return g.matchers[str] 25 | } 26 | -------------------------------------------------------------------------------- /common/task/common.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common" 4 | 5 | // Close returns a func() that closes v. 6 | func Close(v interface{}) func() error { 7 | return func() error { 8 | return common.Close(v) 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /common/tlsx/tlsx_test.go: -------------------------------------------------------------------------------- 1 | package tlsx_test 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/v2fly/v2ray-core/v4/common/tlsx" 7 | ) 8 | 9 | func ExampleGenerateCAWithECC() { 10 | key, cert, err := tlsx.GenerateCAWithECC() 11 | if err != nil { 12 | fmt.Println(err.Error()) 13 | return 14 | } 15 | 16 | fmt.Println(string(cert)) 17 | fmt.Println() 18 | fmt.Println(string(key)) 19 | 20 | //Output: 21 | } 22 | -------------------------------------------------------------------------------- /common/type_test.go: -------------------------------------------------------------------------------- 1 | package common_test 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | . "github.com/v2fly/v2ray-core/v4/common" 8 | ) 9 | 10 | type TConfig struct { 11 | value int 12 | } 13 | 14 | type YConfig struct { 15 | value string 16 | } 17 | 18 | func TestObjectCreation(t *testing.T) { 19 | f := func(ctx context.Context, t interface{}) (interface{}, error) { 20 | return func() int { 21 | return t.(*TConfig).value 22 | }, nil 23 | } 24 | 25 | Must(RegisterConfig((*TConfig)(nil), f)) 26 | err := RegisterConfig((*TConfig)(nil), f) 27 | if err == nil { 28 | t.Error("expect non-nil error, but got nil") 29 | } 30 | 31 | g, err := CreateObject(context.Background(), &TConfig{value: 2}) 32 | Must(err) 33 | if v := g.(func() int)(); v != 2 { 34 | t.Error("expect return value 2, but got ", v) 35 | } 36 | 37 | _, err = CreateObject(context.Background(), &YConfig{value: "T"}) 38 | if err == nil { 39 | t.Error("expect non-nil error, but got nil") 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /context_test.go: -------------------------------------------------------------------------------- 1 | package core_test 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | _ "unsafe" 7 | 8 | . "github.com/v2fly/v2ray-core/v4" 9 | ) 10 | 11 | func TestFromContextPanic(t *testing.T) { 12 | defer func() { 13 | r := recover() 14 | if r == nil { 15 | t.Error("expect panic, but nil") 16 | } 17 | }() 18 | 19 | MustFromContext(context.Background()) 20 | } 21 | -------------------------------------------------------------------------------- /errors.generated.go: -------------------------------------------------------------------------------- 1 | package core 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /features/controller/controller.go: -------------------------------------------------------------------------------- 1 | package inbound 2 | 3 | import ( 4 | "github.com/v2fly/v2ray-core/v4/common/api" 5 | "github.com/v2fly/v2ray-core/v4/features" 6 | ) 7 | 8 | // Controller control inbound 9 | type Controller interface { 10 | features.Feature 11 | GetNodeInfo() *api.NodeInfo 12 | } 13 | 14 | // ControllerType returns the type of controller interface. Can be used for implementing common.HasType. 15 | func Type() interface{} { 16 | return (*Controller)(nil) 17 | } 18 | -------------------------------------------------------------------------------- /features/dns/fakedns.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import ( 4 | "github.com/v2fly/v2ray-core/v4/common/net" 5 | "github.com/v2fly/v2ray-core/v4/features" 6 | ) 7 | 8 | type FakeDNSEngine interface { 9 | features.Feature 10 | GetFakeIPForDomain(domain string) []net.Address 11 | GetDomainFromFakeDNS(ip net.Address) string 12 | } 13 | 14 | type FakeDNSEngineRev0 interface { 15 | FakeDNSEngine 16 | IsIPInIPPool(ip net.Address) bool 17 | GetFakeIPForDomain3(domain string, IPv4, IPv6 bool) []net.Address 18 | } 19 | -------------------------------------------------------------------------------- /features/dns/localdns/errors.generated.go: -------------------------------------------------------------------------------- 1 | package localdns 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /features/errors.generated.go: -------------------------------------------------------------------------------- 1 | package features 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /features/extension/browser.go: -------------------------------------------------------------------------------- 1 | package extension 2 | 3 | import ( 4 | "io" 5 | "net/http" 6 | ) 7 | 8 | type BrowserForwarder interface { 9 | DialWebsocket(url string, header http.Header) (io.ReadWriteCloser, error) 10 | } 11 | 12 | func BrowserForwarderType() interface{} { 13 | return (*BrowserForwarder)(nil) 14 | } 15 | -------------------------------------------------------------------------------- /features/extension/contextreceiver.go: -------------------------------------------------------------------------------- 1 | package extension 2 | 3 | import "context" 4 | 5 | type ContextReceiver interface { 6 | InjectContext(ctx context.Context) 7 | } 8 | -------------------------------------------------------------------------------- /features/extension/observatory.go: -------------------------------------------------------------------------------- 1 | package extension 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/golang/protobuf/proto" 7 | 8 | "github.com/v2fly/v2ray-core/v4/features" 9 | ) 10 | 11 | type Observatory interface { 12 | features.Feature 13 | 14 | GetObservation(ctx context.Context) (proto.Message, error) 15 | } 16 | 17 | func ObservatoryType() interface{} { 18 | return (*Observatory)(nil) 19 | } 20 | -------------------------------------------------------------------------------- /features/feature.go: -------------------------------------------------------------------------------- 1 | package features 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common" 4 | 5 | //go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen 6 | 7 | // Feature is the interface for V2Ray features. All features must implement this interface. 8 | // All existing features have an implementation in app directory. These features can be replaced by third-party ones. 9 | type Feature interface { 10 | common.HasType 11 | common.Runnable 12 | } 13 | 14 | // PrintDeprecatedFeatureWarning prints a warning for deprecated feature. 15 | func PrintDeprecatedFeatureWarning(feature string) { 16 | newError("You are using a deprecated feature: " + feature + ". Please update your config file with latest configuration format, or update your client software.").WriteToLog() 17 | } 18 | -------------------------------------------------------------------------------- /features/history/history.go: -------------------------------------------------------------------------------- 1 | package history 2 | 3 | import ( 4 | "context" 5 | "github.com/v2fly/v2ray-core/v4/common/api" 6 | "github.com/v2fly/v2ray-core/v4/features" 7 | ) 8 | 9 | // History report history 10 | type History interface { 11 | features.Feature 12 | Record(ctx context.Context, history *api.History) error 13 | } 14 | 15 | // ControllerType returns the type of controller interface. Can be used for implementing common.HasType. 16 | func Type() interface{} { 17 | return (*History)(nil) 18 | } 19 | -------------------------------------------------------------------------------- /features/policy/default.go: -------------------------------------------------------------------------------- 1 | package policy 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | // DefaultManager is the implementation of the Manager. 8 | type DefaultManager struct{} 9 | 10 | // Type implements common.HasType. 11 | func (DefaultManager) Type() interface{} { 12 | return ManagerType() 13 | } 14 | 15 | // ForLevel implements Manager. 16 | func (DefaultManager) ForLevel(level uint32) Session { 17 | p := SessionDefault() 18 | if level == 1 { 19 | p.Timeouts.ConnectionIdle = time.Second * 600 20 | } 21 | return p 22 | } 23 | 24 | // ForSystem implements Manager. 25 | func (DefaultManager) ForSystem() System { 26 | return System{} 27 | } 28 | 29 | // Start implements common.Runnable. 30 | func (DefaultManager) Start() error { 31 | return nil 32 | } 33 | 34 | // Close implements common.Closable. 35 | func (DefaultManager) Close() error { 36 | return nil 37 | } 38 | -------------------------------------------------------------------------------- /features/routing/dispatcher.go: -------------------------------------------------------------------------------- 1 | package routing 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/v2fly/v2ray-core/v4/common/net" 7 | "github.com/v2fly/v2ray-core/v4/features" 8 | "github.com/v2fly/v2ray-core/v4/transport" 9 | ) 10 | 11 | // Dispatcher is a feature that dispatches inbound requests to outbound handlers based on rules. 12 | // Dispatcher is required to be registered in a V2Ray instance to make V2Ray function properly. 13 | // 14 | // v2ray:api:stable 15 | type Dispatcher interface { 16 | features.Feature 17 | 18 | // Dispatch returns a Ray for transporting data for the given request. 19 | Dispatch(ctx context.Context, dest net.Destination) (*transport.Link, error) 20 | } 21 | 22 | // DispatcherType returns the type of Dispatcher interface. Can be used to implement common.HasType. 23 | // 24 | // v2ray:api:stable 25 | func DispatcherType() interface{} { 26 | return (*Dispatcher)(nil) 27 | } 28 | -------------------------------------------------------------------------------- /features/routing/dns/errors.generated.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /features/stats/errors.generated.go: -------------------------------------------------------------------------------- 1 | package stats 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /features/traffic/errors.generated.go: -------------------------------------------------------------------------------- 1 | package traffic 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /format.go: -------------------------------------------------------------------------------- 1 | package core 2 | 3 | //go:generate go install -v github.com/daixiang0/gci@latest 4 | //go:generate go run ./infra/vformat/ 5 | -------------------------------------------------------------------------------- /infra/conf/blackhole_test.go: -------------------------------------------------------------------------------- 1 | package conf_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/v2fly/v2ray-core/v4/common/serial" 7 | . "github.com/v2fly/v2ray-core/v4/infra/conf" 8 | "github.com/v2fly/v2ray-core/v4/proxy/blackhole" 9 | ) 10 | 11 | func TestHTTPResponseJSON(t *testing.T) { 12 | creator := func() Buildable { 13 | return new(BlackholeConfig) 14 | } 15 | 16 | runMultiTestCase(t, []TestCase{ 17 | { 18 | Input: `{ 19 | "response": { 20 | "type": "http" 21 | } 22 | }`, 23 | Parser: loadJSON(creator), 24 | Output: &blackhole.Config{ 25 | Response: serial.ToTypedMessage(&blackhole.HTTPResponse{}), 26 | }, 27 | }, 28 | { 29 | Input: `{}`, 30 | Parser: loadJSON(creator), 31 | Output: &blackhole.Config{}, 32 | }, 33 | }) 34 | } 35 | -------------------------------------------------------------------------------- /infra/conf/browser_forwarder.go: -------------------------------------------------------------------------------- 1 | package conf 2 | 3 | import ( 4 | "strings" 5 | 6 | "github.com/golang/protobuf/proto" 7 | 8 | "github.com/v2fly/v2ray-core/v4/app/browserforwarder" 9 | ) 10 | 11 | type BrowserForwarderConfig struct { 12 | ListenAddr string `json:"listenAddr"` 13 | ListenPort int32 `json:"listenPort"` 14 | } 15 | 16 | func (b *BrowserForwarderConfig) Build() (proto.Message, error) { 17 | b.ListenAddr = strings.TrimSpace(b.ListenAddr) 18 | if b.ListenAddr != "" && b.ListenPort == 0 { 19 | b.ListenPort = 54321 20 | } 21 | return &browserforwarder.Config{ 22 | ListenAddr: b.ListenAddr, 23 | ListenPort: b.ListenPort, 24 | }, nil 25 | } 26 | -------------------------------------------------------------------------------- /infra/conf/buildable.go: -------------------------------------------------------------------------------- 1 | package conf 2 | 3 | import "github.com/golang/protobuf/proto" 4 | 5 | type Buildable interface { 6 | Build() (proto.Message, error) 7 | } 8 | -------------------------------------------------------------------------------- /infra/conf/cfgcommon/errors.generated.go: -------------------------------------------------------------------------------- 1 | package cfgcommon 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /infra/conf/command/errors.generated.go: -------------------------------------------------------------------------------- 1 | package command 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /infra/conf/conf.go: -------------------------------------------------------------------------------- 1 | package conf 2 | 3 | //go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen 4 | -------------------------------------------------------------------------------- /infra/conf/dns_proxy.go: -------------------------------------------------------------------------------- 1 | package conf 2 | 3 | import ( 4 | "github.com/golang/protobuf/proto" 5 | 6 | "github.com/v2fly/v2ray-core/v4/common/net" 7 | "github.com/v2fly/v2ray-core/v4/infra/conf/cfgcommon" 8 | "github.com/v2fly/v2ray-core/v4/proxy/dns" 9 | ) 10 | 11 | type DNSOutboundConfig struct { 12 | Network cfgcommon.Network `json:"network"` 13 | Address *cfgcommon.Address `json:"address"` 14 | Port uint16 `json:"port"` 15 | } 16 | 17 | func (c *DNSOutboundConfig) Build() (proto.Message, error) { 18 | config := &dns.Config{ 19 | Server: &net.Endpoint{ 20 | Network: c.Network.Build(), 21 | Port: uint32(c.Port), 22 | }, 23 | } 24 | if c.Address != nil { 25 | config.Server.Address = c.Address.Build() 26 | } 27 | return config, nil 28 | } 29 | -------------------------------------------------------------------------------- /infra/conf/dns_proxy_test.go: -------------------------------------------------------------------------------- 1 | package conf_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/v2fly/v2ray-core/v4/common/net" 7 | . "github.com/v2fly/v2ray-core/v4/infra/conf" 8 | "github.com/v2fly/v2ray-core/v4/proxy/dns" 9 | ) 10 | 11 | func TestDnsProxyConfig(t *testing.T) { 12 | creator := func() Buildable { 13 | return new(DNSOutboundConfig) 14 | } 15 | 16 | runMultiTestCase(t, []TestCase{ 17 | { 18 | Input: `{ 19 | "address": "8.8.8.8", 20 | "port": 53, 21 | "network": "tcp" 22 | }`, 23 | Parser: loadJSON(creator), 24 | Output: &dns.Config{ 25 | Server: &net.Endpoint{ 26 | Network: net.Network_TCP, 27 | Address: net.NewIPOrDomain(net.IPAddress([]byte{8, 8, 8, 8})), 28 | Port: 53, 29 | }, 30 | }, 31 | }, 32 | }) 33 | } 34 | -------------------------------------------------------------------------------- /infra/conf/dokodemo.go: -------------------------------------------------------------------------------- 1 | package conf 2 | 3 | import ( 4 | "github.com/golang/protobuf/proto" 5 | 6 | "github.com/v2fly/v2ray-core/v4/infra/conf/cfgcommon" 7 | "github.com/v2fly/v2ray-core/v4/proxy/dokodemo" 8 | ) 9 | 10 | type DokodemoConfig struct { 11 | Host *cfgcommon.Address `json:"address"` 12 | PortValue uint16 `json:"port"` 13 | NetworkList *cfgcommon.NetworkList `json:"network"` 14 | TimeoutValue uint32 `json:"timeout"` 15 | Redirect bool `json:"followRedirect"` 16 | UserLevel uint32 `json:"userLevel"` 17 | } 18 | 19 | func (v *DokodemoConfig) Build() (proto.Message, error) { 20 | config := new(dokodemo.Config) 21 | if v.Host != nil { 22 | config.Address = v.Host.Build() 23 | } 24 | config.Port = uint32(v.PortValue) 25 | config.Networks = v.NetworkList.Build() 26 | config.Timeout = v.TimeoutValue 27 | config.FollowRedirect = v.Redirect 28 | config.UserLevel = v.UserLevel 29 | return config, nil 30 | } 31 | -------------------------------------------------------------------------------- /infra/conf/dokodemo_test.go: -------------------------------------------------------------------------------- 1 | package conf_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/v2fly/v2ray-core/v4/common/net" 7 | . "github.com/v2fly/v2ray-core/v4/infra/conf" 8 | "github.com/v2fly/v2ray-core/v4/proxy/dokodemo" 9 | ) 10 | 11 | func TestDokodemoConfig(t *testing.T) { 12 | creator := func() Buildable { 13 | return new(DokodemoConfig) 14 | } 15 | 16 | runMultiTestCase(t, []TestCase{ 17 | { 18 | Input: `{ 19 | "address": "8.8.8.8", 20 | "port": 53, 21 | "network": "tcp", 22 | "timeout": 10, 23 | "followRedirect": true, 24 | "userLevel": 1 25 | }`, 26 | Parser: loadJSON(creator), 27 | Output: &dokodemo.Config{ 28 | Address: &net.IPOrDomain{ 29 | Address: &net.IPOrDomain_Ip{ 30 | Ip: []byte{8, 8, 8, 8}, 31 | }, 32 | }, 33 | Port: 53, 34 | Networks: []net.Network{net.Network_TCP}, 35 | Timeout: 10, 36 | FollowRedirect: true, 37 | UserLevel: 1, 38 | }, 39 | }, 40 | }) 41 | } 42 | -------------------------------------------------------------------------------- /infra/conf/errors.generated.go: -------------------------------------------------------------------------------- 1 | package conf 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /infra/conf/geodata/errors.generated.go: -------------------------------------------------------------------------------- 1 | package geodata 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /infra/conf/geodata/geodataproto.go: -------------------------------------------------------------------------------- 1 | package geodata 2 | 3 | import "github.com/v2fly/v2ray-core/v4/app/router" 4 | 5 | //go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen 6 | 7 | type LoaderImplementation interface { 8 | LoadSite(filename, list string) ([]*router.Domain, error) 9 | LoadIP(filename, country string) ([]*router.CIDR, error) 10 | } 11 | 12 | type Loader interface { 13 | LoaderImplementation 14 | LoadGeoSite(list string) ([]*router.Domain, error) 15 | LoadGeoSiteWithAttr(file string, siteWithAttr string) ([]*router.Domain, error) 16 | LoadGeoIP(country string) ([]*router.CIDR, error) 17 | } 18 | -------------------------------------------------------------------------------- /infra/conf/geodata/memconservative/errors.generated.go: -------------------------------------------------------------------------------- 1 | package memconservative 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /infra/conf/geodata/standard/errors.generated.go: -------------------------------------------------------------------------------- 1 | package standard 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /infra/conf/gun.go: -------------------------------------------------------------------------------- 1 | package conf 2 | 3 | import ( 4 | "github.com/golang/protobuf/proto" 5 | 6 | "github.com/v2fly/v2ray-core/v4/transport/internet/grpc" 7 | ) 8 | 9 | type GunConfig struct { 10 | ServiceName string `json:"serviceName"` 11 | } 12 | 13 | func (g GunConfig) Build() (proto.Message, error) { 14 | return &grpc.Config{ServiceName: g.ServiceName}, nil 15 | } 16 | -------------------------------------------------------------------------------- /infra/conf/http_test.go: -------------------------------------------------------------------------------- 1 | package conf_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/v2fly/v2ray-core/v4/infra/conf" 7 | "github.com/v2fly/v2ray-core/v4/proxy/http" 8 | ) 9 | 10 | func TestHTTPServerConfig(t *testing.T) { 11 | creator := func() Buildable { 12 | return new(HTTPServerConfig) 13 | } 14 | 15 | runMultiTestCase(t, []TestCase{ 16 | { 17 | Input: `{ 18 | "timeout": 10, 19 | "accounts": [ 20 | { 21 | "user": "my-username", 22 | "pass": "my-password" 23 | } 24 | ], 25 | "allowTransparent": true, 26 | "userLevel": 1 27 | }`, 28 | Parser: loadJSON(creator), 29 | Output: &http.ServerConfig{ 30 | Accounts: map[string]string{ 31 | "my-username": "my-password", 32 | }, 33 | AllowTransparent: true, 34 | UserLevel: 1, 35 | Timeout: 10, 36 | }, 37 | }, 38 | }) 39 | } 40 | -------------------------------------------------------------------------------- /infra/conf/init.go: -------------------------------------------------------------------------------- 1 | package conf 2 | 3 | func init() { 4 | RegisterConfigureFilePostProcessingStage("FakeDNS", &FakeDNSPostProcessingStage{}) 5 | } 6 | -------------------------------------------------------------------------------- /infra/conf/lint.go: -------------------------------------------------------------------------------- 1 | package conf 2 | 3 | type ConfigureFilePostProcessingStage interface { 4 | Process(conf *Config) error 5 | } 6 | 7 | var configureFilePostProcessingStages map[string]ConfigureFilePostProcessingStage 8 | 9 | func RegisterConfigureFilePostProcessingStage(name string, stage ConfigureFilePostProcessingStage) { 10 | if configureFilePostProcessingStages == nil { 11 | configureFilePostProcessingStages = make(map[string]ConfigureFilePostProcessingStage) 12 | } 13 | configureFilePostProcessingStages[name] = stage 14 | } 15 | 16 | func PostProcessConfigureFile(conf *Config) error { 17 | for k, v := range configureFilePostProcessingStages { 18 | if err := v.Process(conf); err != nil { 19 | return newError("Rejected by Postprocessing Stage ", k).AtError().Base(err) 20 | } 21 | } 22 | return nil 23 | } 24 | -------------------------------------------------------------------------------- /infra/conf/loopback.go: -------------------------------------------------------------------------------- 1 | package conf 2 | 3 | import ( 4 | "github.com/golang/protobuf/proto" 5 | 6 | "github.com/v2fly/v2ray-core/v4/proxy/loopback" 7 | ) 8 | 9 | type LoopbackConfig struct { 10 | InboundTag string `json:"inboundTag"` 11 | } 12 | 13 | func (l LoopbackConfig) Build() (proto.Message, error) { 14 | return &loopback.Config{InboundTag: l.InboundTag}, nil 15 | } 16 | -------------------------------------------------------------------------------- /infra/conf/observatory.go: -------------------------------------------------------------------------------- 1 | package conf 2 | 3 | import ( 4 | "github.com/golang/protobuf/proto" 5 | 6 | "github.com/v2fly/v2ray-core/v4/app/observatory" 7 | ) 8 | 9 | type ObservatoryConfig struct { 10 | SubjectSelector []string `json:"subjectSelector"` 11 | } 12 | 13 | func (o *ObservatoryConfig) Build() (proto.Message, error) { 14 | return &observatory.Config{SubjectSelector: o.SubjectSelector}, nil 15 | } 16 | -------------------------------------------------------------------------------- /infra/conf/policy_test.go: -------------------------------------------------------------------------------- 1 | package conf_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/v2fly/v2ray-core/v4/common" 7 | . "github.com/v2fly/v2ray-core/v4/infra/conf" 8 | ) 9 | 10 | func TestBufferSize(t *testing.T) { 11 | cases := []struct { 12 | Input int32 13 | Output int32 14 | }{ 15 | { 16 | Input: 0, 17 | Output: 0, 18 | }, 19 | { 20 | Input: -1, 21 | Output: -1, 22 | }, 23 | { 24 | Input: 1, 25 | Output: 1024, 26 | }, 27 | } 28 | 29 | for _, c := range cases { 30 | bs := c.Input 31 | pConf := Policy{ 32 | BufferSize: &bs, 33 | } 34 | p, err := pConf.Build() 35 | common.Must(err) 36 | if p.Buffer.Connection != c.Output { 37 | t.Error("expected buffer size ", c.Output, " but got ", p.Buffer.Connection) 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /infra/conf/reverse_test.go: -------------------------------------------------------------------------------- 1 | package conf_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/v2fly/v2ray-core/v4/app/reverse" 7 | "github.com/v2fly/v2ray-core/v4/infra/conf" 8 | ) 9 | 10 | func TestReverseConfig(t *testing.T) { 11 | creator := func() conf.Buildable { 12 | return new(conf.ReverseConfig) 13 | } 14 | 15 | runMultiTestCase(t, []TestCase{ 16 | { 17 | Input: `{ 18 | "bridges": [{ 19 | "tag": "test", 20 | "domain": "test.v2fly.org" 21 | }] 22 | }`, 23 | Parser: loadJSON(creator), 24 | Output: &reverse.Config{ 25 | BridgeConfig: []*reverse.BridgeConfig{ 26 | {Tag: "test", Domain: "test.v2fly.org"}, 27 | }, 28 | }, 29 | }, 30 | { 31 | Input: `{ 32 | "portals": [{ 33 | "tag": "test", 34 | "domain": "test.v2fly.org" 35 | }] 36 | }`, 37 | Parser: loadJSON(creator), 38 | Output: &reverse.Config{ 39 | PortalConfig: []*reverse.PortalConfig{ 40 | {Tag: "test", Domain: "test.v2fly.org"}, 41 | }, 42 | }, 43 | }, 44 | }) 45 | } 46 | -------------------------------------------------------------------------------- /infra/conf/router_strategy.go: -------------------------------------------------------------------------------- 1 | package conf 2 | 3 | const ( 4 | strategyRandom string = "random" 5 | strategyLeastPing string = "leastping" 6 | ) 7 | -------------------------------------------------------------------------------- /infra/conf/rule/errors.generated.go: -------------------------------------------------------------------------------- 1 | package rule 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /infra/conf/serial/errors.generated.go: -------------------------------------------------------------------------------- 1 | package serial 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /infra/conf/serial/serial.go: -------------------------------------------------------------------------------- 1 | package serial 2 | 3 | //go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen 4 | -------------------------------------------------------------------------------- /infra/conf/services.go: -------------------------------------------------------------------------------- 1 | package conf 2 | 3 | import ( 4 | "encoding/json" 5 | 6 | "github.com/golang/protobuf/jsonpb" 7 | "github.com/jhump/protoreflect/desc" 8 | "github.com/jhump/protoreflect/dynamic" 9 | 10 | "github.com/v2fly/v2ray-core/v4/common/serial" 11 | ) 12 | 13 | func (c *Config) BuildServices(service map[string]*json.RawMessage) ([]*serial.TypedMessage, error) { 14 | var ret []*serial.TypedMessage 15 | for k, v := range service { 16 | message, err := desc.LoadMessageDescriptor(k) 17 | if err != nil || message == nil { 18 | return nil, newError("Cannot find service", k, "").Base(err) 19 | } 20 | 21 | serviceConfig := dynamic.NewMessage(message) 22 | 23 | if err := serviceConfig.UnmarshalJSONPB(&jsonpb.Unmarshaler{AllowUnknownFields: false}, *v); err != nil { 24 | return nil, newError("Cannot interpret service configure file", k, "").Base(err) 25 | } 26 | 27 | ret = append(ret, serial.ToTypedMessage(serviceConfig)) 28 | } 29 | return ret, nil 30 | } 31 | -------------------------------------------------------------------------------- /infra/conf/shadowsocks_test.go: -------------------------------------------------------------------------------- 1 | package conf_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/v2fly/v2ray-core/v4/common/net" 7 | "github.com/v2fly/v2ray-core/v4/common/protocol" 8 | "github.com/v2fly/v2ray-core/v4/common/serial" 9 | . "github.com/v2fly/v2ray-core/v4/infra/conf" 10 | "github.com/v2fly/v2ray-core/v4/proxy/shadowsocks" 11 | ) 12 | 13 | func TestShadowsocksServerConfigParsing(t *testing.T) { 14 | creator := func() Buildable { 15 | return new(ShadowsocksServerConfig) 16 | } 17 | 18 | runMultiTestCase(t, []TestCase{ 19 | { 20 | Input: `{ 21 | "method": "aes-256-GCM", 22 | "password": "v2ray-password" 23 | }`, 24 | Parser: loadJSON(creator), 25 | Output: &shadowsocks.ServerConfig{ 26 | User: &protocol.User{ 27 | Account: serial.ToTypedMessage(&shadowsocks.Account{ 28 | CipherType: shadowsocks.CipherType_AES_256_GCM, 29 | Password: "v2ray-password", 30 | }), 31 | }, 32 | Network: []net.Network{net.Network_TCP}, 33 | }, 34 | }, 35 | }) 36 | } 37 | -------------------------------------------------------------------------------- /infra/control/control.go: -------------------------------------------------------------------------------- 1 | package control 2 | 3 | //go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen 4 | -------------------------------------------------------------------------------- /infra/control/errors.generated.go: -------------------------------------------------------------------------------- 1 | package control 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /infra/control/uuid.go: -------------------------------------------------------------------------------- 1 | package control 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/v2fly/v2ray-core/v4/common" 7 | "github.com/v2fly/v2ray-core/v4/common/uuid" 8 | ) 9 | 10 | type UUIDCommand struct{} 11 | 12 | func (c *UUIDCommand) Name() string { 13 | return "uuid" 14 | } 15 | 16 | func (c *UUIDCommand) Description() Description { 17 | return Description{ 18 | Short: "Generate new UUID", 19 | Usage: []string{"v2ctl uuid"}, 20 | } 21 | } 22 | 23 | func (c *UUIDCommand) Execute([]string) error { 24 | u := uuid.New() 25 | fmt.Println(u.String()) 26 | return nil 27 | } 28 | 29 | func init() { 30 | common.Must(RegisterCommand(&UUIDCommand{})) 31 | } 32 | -------------------------------------------------------------------------------- /main/confloader/errors.generated.go: -------------------------------------------------------------------------------- 1 | package confloader 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /main/confloader/external/errors.generated.go: -------------------------------------------------------------------------------- 1 | package external 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /main/distro/debug/debug.go: -------------------------------------------------------------------------------- 1 | package debug 2 | 3 | import ( 4 | "net/http" 5 | ) 6 | 7 | func init() { 8 | go func() { 9 | http.ListenAndServe(":6060", nil) 10 | }() 11 | } 12 | -------------------------------------------------------------------------------- /main/errors.generated.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /main/json/errors.generated.go: -------------------------------------------------------------------------------- 1 | package json 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /main/jsonem/errors.generated.go: -------------------------------------------------------------------------------- 1 | package jsonem 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /main/main_test.go: -------------------------------------------------------------------------------- 1 | // +build coveragemain 2 | 3 | package main 4 | 5 | import ( 6 | "testing" 7 | ) 8 | 9 | func TestRunMainForCoverage(t *testing.T) { 10 | main() 11 | } 12 | -------------------------------------------------------------------------------- /main/server.json: -------------------------------------------------------------------------------- 1 | { 2 | "log": { 3 | "loglevel": "debug" 4 | }, 5 | "inbounds": [ 6 | { 7 | "port": 10086, 8 | "protocol": "vmess", 9 | "settings": { 10 | "clients": [ 11 | { 12 | "id": "b831381d-6324-4d53-ad4f-8cda48b30811", 13 | "limit": 102400 14 | } 15 | ] 16 | } 17 | } 18 | ], 19 | "outbounds": [ 20 | { 21 | "protocol": "freedom", 22 | "settings": {} 23 | } 24 | ], 25 | "stats": {}, 26 | "policy": { 27 | "levels": { 28 | "0": { 29 | "handshake": 4, 30 | "connIdle": 300, 31 | "uplinkOnly": 2, 32 | "downlinkOnly": 5, 33 | "statsUserUplink": true, 34 | "statsUserDownlink": true, 35 | "bufferSize": 0 36 | } 37 | }, 38 | "system": { 39 | "statsInboundUplink": false, 40 | "statsInboundDownlink": false 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /proto.go: -------------------------------------------------------------------------------- 1 | package core 2 | 3 | //go:generate go install -v google.golang.org/protobuf/cmd/protoc-gen-go@latest 4 | //go:generate go install -v google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest 5 | //go:generate go run ./infra/vprotogen/ 6 | -------------------------------------------------------------------------------- /proxy/blackhole/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.proxy.blackhole; 4 | option csharp_namespace = "V2Ray.Core.Proxy.Blackhole"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/proxy/blackhole"; 6 | option java_package = "com.v2ray.core.proxy.blackhole"; 7 | option java_multiple_files = true; 8 | 9 | import "common/serial/typed_message.proto"; 10 | 11 | message NoneResponse {} 12 | 13 | message HTTPResponse {} 14 | 15 | message Config { 16 | v2ray.core.common.serial.TypedMessage response = 1; 17 | } 18 | -------------------------------------------------------------------------------- /proxy/blackhole/config_test.go: -------------------------------------------------------------------------------- 1 | package blackhole_test 2 | 3 | import ( 4 | "bufio" 5 | "net/http" 6 | "testing" 7 | 8 | "github.com/v2fly/v2ray-core/v4/common" 9 | "github.com/v2fly/v2ray-core/v4/common/buf" 10 | . "github.com/v2fly/v2ray-core/v4/proxy/blackhole" 11 | ) 12 | 13 | func TestHTTPResponse(t *testing.T) { 14 | buffer := buf.New() 15 | 16 | httpResponse := new(HTTPResponse) 17 | httpResponse.WriteTo(buf.NewWriter(buffer)) 18 | 19 | reader := bufio.NewReader(buffer) 20 | response, err := http.ReadResponse(reader, nil) 21 | common.Must(err) 22 | defer response.Body.Close() 23 | 24 | if response.StatusCode != 403 { 25 | t.Error("expected status code 403, but got ", response.StatusCode) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /proxy/blackhole/errors.generated.go: -------------------------------------------------------------------------------- 1 | package blackhole 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /proxy/dns/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.proxy.dns; 4 | option csharp_namespace = "V2Ray.Core.Proxy.Dns"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/proxy/dns"; 6 | option java_package = "com.v2ray.core.proxy.dns"; 7 | option java_multiple_files = true; 8 | 9 | import "common/net/destination.proto"; 10 | 11 | message Config { 12 | // Server is the DNS server address. If specified, this address overrides the 13 | // original one. 14 | v2ray.core.common.net.Endpoint server = 1; 15 | } 16 | -------------------------------------------------------------------------------- /proxy/dns/errors.generated.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /proxy/dokodemo/config.go: -------------------------------------------------------------------------------- 1 | package dokodemo 2 | 3 | import ( 4 | "github.com/v2fly/v2ray-core/v4/common/net" 5 | ) 6 | 7 | // GetPredefinedAddress returns the defined address from proto config. Null if address is not valid. 8 | func (v *Config) GetPredefinedAddress() net.Address { 9 | addr := v.Address.AsAddress() 10 | if addr == nil { 11 | return nil 12 | } 13 | return addr 14 | } 15 | -------------------------------------------------------------------------------- /proxy/dokodemo/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.proxy.dokodemo; 4 | option csharp_namespace = "V2Ray.Core.Proxy.Dokodemo"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/proxy/dokodemo"; 6 | option java_package = "com.v2ray.core.proxy.dokodemo"; 7 | option java_multiple_files = true; 8 | 9 | import "common/net/address.proto"; 10 | import "common/net/network.proto"; 11 | 12 | message Config { 13 | v2ray.core.common.net.IPOrDomain address = 1; 14 | uint32 port = 2; 15 | 16 | // List of networks that the Dokodemo accepts. 17 | // Deprecated. Use networks. 18 | v2ray.core.common.net.NetworkList network_list = 3 [deprecated = true]; 19 | // List of networks that the Dokodemo accepts. 20 | repeated v2ray.core.common.net.Network networks = 7; 21 | 22 | uint32 timeout = 4 [deprecated = true]; 23 | bool follow_redirect = 5; 24 | uint32 user_level = 6; 25 | } 26 | -------------------------------------------------------------------------------- /proxy/dokodemo/errors.generated.go: -------------------------------------------------------------------------------- 1 | package dokodemo 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /proxy/freedom/config.go: -------------------------------------------------------------------------------- 1 | package freedom 2 | 3 | func (c *Config) useIP() bool { 4 | return c.DomainStrategy == Config_USE_IP || c.DomainStrategy == Config_USE_IP4 || c.DomainStrategy == Config_USE_IP6 5 | } 6 | -------------------------------------------------------------------------------- /proxy/freedom/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.proxy.freedom; 4 | option csharp_namespace = "V2Ray.Core.Proxy.Freedom"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/proxy/freedom"; 6 | option java_package = "com.v2ray.core.proxy.freedom"; 7 | option java_multiple_files = true; 8 | 9 | import "common/protocol/server_spec.proto"; 10 | 11 | message DestinationOverride { 12 | v2ray.core.common.protocol.ServerEndpoint server = 1; 13 | } 14 | 15 | message Config { 16 | enum DomainStrategy { 17 | AS_IS = 0; 18 | USE_IP = 1; 19 | USE_IP4 = 2; 20 | USE_IP6 = 3; 21 | } 22 | DomainStrategy domain_strategy = 1; 23 | uint32 timeout = 2 [deprecated = true]; 24 | DestinationOverride destination_override = 3; 25 | uint32 user_level = 4; 26 | } 27 | -------------------------------------------------------------------------------- /proxy/freedom/errors.generated.go: -------------------------------------------------------------------------------- 1 | package freedom 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /proxy/http/config.go: -------------------------------------------------------------------------------- 1 | package http 2 | 3 | import ( 4 | "github.com/v2fly/v2ray-core/v4/common/protocol" 5 | ) 6 | 7 | func (a *Account) Equals(another protocol.Account) bool { 8 | if account, ok := another.(*Account); ok { 9 | return a.Username == account.Username 10 | } 11 | return false 12 | } 13 | 14 | func (a *Account) AsAccount() (protocol.Account, error) { 15 | return a, nil 16 | } 17 | 18 | func (sc *ServerConfig) HasAccount(username, password string) bool { 19 | if sc.Accounts == nil { 20 | return false 21 | } 22 | 23 | p, found := sc.Accounts[username] 24 | if !found { 25 | return false 26 | } 27 | return p == password 28 | } 29 | -------------------------------------------------------------------------------- /proxy/http/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.proxy.http; 4 | option csharp_namespace = "V2Ray.Core.Proxy.Http"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/proxy/http"; 6 | option java_package = "com.v2ray.core.proxy.http"; 7 | option java_multiple_files = true; 8 | 9 | import "common/protocol/server_spec.proto"; 10 | 11 | message Account { 12 | string username = 1; 13 | string password = 2; 14 | } 15 | 16 | // Config for HTTP proxy server. 17 | message ServerConfig { 18 | uint32 timeout = 1 [deprecated = true]; 19 | map accounts = 2; 20 | bool allow_transparent = 3; 21 | uint32 user_level = 4; 22 | } 23 | 24 | // ClientConfig is the protobuf config for HTTP proxy client. 25 | message ClientConfig { 26 | // Sever is a list of HTTP server addresses. 27 | repeated v2ray.core.common.protocol.ServerEndpoint server = 1; 28 | } 29 | -------------------------------------------------------------------------------- /proxy/http/errors.generated.go: -------------------------------------------------------------------------------- 1 | package http 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /proxy/http/http.go: -------------------------------------------------------------------------------- 1 | package http 2 | 3 | //go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen 4 | -------------------------------------------------------------------------------- /proxy/loopback/config.go: -------------------------------------------------------------------------------- 1 | package loopback 2 | 3 | //go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen 4 | -------------------------------------------------------------------------------- /proxy/loopback/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.proxy.loopback; 4 | option csharp_namespace = "V2Ray.Core.Proxy.Loopback"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/proxy/loopback"; 6 | option java_package = "com.v2ray.core.proxy.loopback"; 7 | option java_multiple_files = true; 8 | 9 | message Config { 10 | string inbound_tag = 1; 11 | } 12 | -------------------------------------------------------------------------------- /proxy/loopback/errors.generated.go: -------------------------------------------------------------------------------- 1 | package loopback 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /proxy/mtproto/config.go: -------------------------------------------------------------------------------- 1 | package mtproto 2 | 3 | import ( 4 | "github.com/v2fly/v2ray-core/v4/common/protocol" 5 | ) 6 | 7 | func (a *Account) Equals(another protocol.Account) bool { 8 | aa, ok := another.(*Account) 9 | if !ok { 10 | return false 11 | } 12 | 13 | if len(a.Secret) != len(aa.Secret) { 14 | return false 15 | } 16 | 17 | for i, v := range a.Secret { 18 | if v != aa.Secret[i] { 19 | return false 20 | } 21 | } 22 | 23 | return true 24 | } 25 | -------------------------------------------------------------------------------- /proxy/mtproto/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.proxy.mtproto; 4 | option csharp_namespace = "V2Ray.Core.Proxy.Mtproto"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/proxy/mtproto"; 6 | option java_package = "com.v2ray.core.proxy.mtproto"; 7 | option java_multiple_files = true; 8 | 9 | import "common/protocol/user.proto"; 10 | 11 | message Account { 12 | bytes secret = 1; 13 | } 14 | 15 | message ServerConfig { 16 | // User is a list of users that allowed to connect to this inbound. 17 | // Although this is a repeated field, only the first user is effective for 18 | // now. 19 | repeated v2ray.core.common.protocol.User user = 1; 20 | } 21 | 22 | message ClientConfig {} 23 | -------------------------------------------------------------------------------- /proxy/mtproto/errors.generated.go: -------------------------------------------------------------------------------- 1 | package mtproto 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /proxy/mtproto/mtproto.go: -------------------------------------------------------------------------------- 1 | package mtproto 2 | 3 | //go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen 4 | -------------------------------------------------------------------------------- /proxy/shadowsocks/errors.generated.go: -------------------------------------------------------------------------------- 1 | package shadowsocks 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /proxy/shadowsocks/shadowsocks.go: -------------------------------------------------------------------------------- 1 | // Package shadowsocks provides compatible functionality to Shadowsocks. 2 | // 3 | // Shadowsocks client and server are implemented as outbound and inbound respectively in V2Ray's term. 4 | // 5 | // R.I.P Shadowsocks 6 | package shadowsocks 7 | 8 | //go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen 9 | -------------------------------------------------------------------------------- /proxy/socks/config.go: -------------------------------------------------------------------------------- 1 | // +build !confonly 2 | 3 | package socks 4 | 5 | import "github.com/v2fly/v2ray-core/v4/common/protocol" 6 | 7 | func (a *Account) Equals(another protocol.Account) bool { 8 | if account, ok := another.(*Account); ok { 9 | return a.Username == account.Username 10 | } 11 | return false 12 | } 13 | 14 | func (a *Account) AsAccount() (protocol.Account, error) { 15 | return a, nil 16 | } 17 | 18 | func (c *ServerConfig) HasAccount(username, password string) bool { 19 | if c.Accounts == nil { 20 | return false 21 | } 22 | storedPassed, found := c.Accounts[username] 23 | if !found { 24 | return false 25 | } 26 | return storedPassed == password 27 | } 28 | -------------------------------------------------------------------------------- /proxy/socks/errors.generated.go: -------------------------------------------------------------------------------- 1 | package socks 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /proxy/socks/socks.go: -------------------------------------------------------------------------------- 1 | // Package socks provides implements of Socks protocol 4, 4a and 5. 2 | package socks 3 | 4 | //go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen 5 | -------------------------------------------------------------------------------- /proxy/trojan/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.proxy.trojan; 4 | option csharp_namespace = "V2Ray.Core.Proxy.Trojan"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/proxy/trojan"; 6 | option java_package = "com.v2ray.core.proxy.trojan"; 7 | option java_multiple_files = true; 8 | 9 | import "common/protocol/user.proto"; 10 | import "common/protocol/server_spec.proto"; 11 | 12 | message Account { 13 | string password = 1; 14 | } 15 | 16 | message Fallback { 17 | string alpn = 1; 18 | string path = 2; 19 | string type = 3; 20 | string dest = 4; 21 | uint64 xver = 5; 22 | } 23 | 24 | message ClientConfig { 25 | repeated v2ray.core.common.protocol.ServerEndpoint server = 1; 26 | } 27 | 28 | message ServerConfig { 29 | repeated v2ray.core.common.protocol.User users = 1; 30 | repeated Fallback fallbacks = 3; 31 | } 32 | -------------------------------------------------------------------------------- /proxy/trojan/errors.generated.go: -------------------------------------------------------------------------------- 1 | package trojan 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /proxy/trojan/trojan.go: -------------------------------------------------------------------------------- 1 | package trojan 2 | -------------------------------------------------------------------------------- /proxy/vless/account.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.proxy.vless; 4 | option csharp_namespace = "V2Ray.Core.Proxy.Vless"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/proxy/vless"; 6 | option java_package = "com.v2ray.core.proxy.vless"; 7 | option java_multiple_files = true; 8 | 9 | message Account { 10 | // ID of the account, in the form of a UUID, e.g., "66ad4540-b58c-4ad2-9926-ea63445a9b57". 11 | string id = 1; 12 | // Flow settings. 13 | string flow = 2; 14 | // Encryption settings. Only applies to client side, and only accepts "none" for now. 15 | string encryption = 3; 16 | } 17 | -------------------------------------------------------------------------------- /proxy/vless/encoding/addons.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.proxy.vless.encoding; 4 | option csharp_namespace = "V2Ray.Core.Proxy.Vless.Encoding"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/proxy/vless/encoding"; 6 | option java_package = "com.v2ray.core.proxy.vless.encoding"; 7 | option java_multiple_files = true; 8 | 9 | message Addons { 10 | string Flow = 1; 11 | bytes Seed = 2; 12 | } 13 | -------------------------------------------------------------------------------- /proxy/vless/encoding/errors.generated.go: -------------------------------------------------------------------------------- 1 | package encoding 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /proxy/vless/errors.generated.go: -------------------------------------------------------------------------------- 1 | package vless 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /proxy/vless/inbound/config.go: -------------------------------------------------------------------------------- 1 | // +build !confonly 2 | 3 | package inbound 4 | -------------------------------------------------------------------------------- /proxy/vless/inbound/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.proxy.vless.inbound; 4 | option csharp_namespace = "V2Ray.Core.Proxy.Vless.Inbound"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/proxy/vless/inbound"; 6 | option java_package = "com.v2ray.core.proxy.vless.inbound"; 7 | option java_multiple_files = true; 8 | 9 | import "common/protocol/user.proto"; 10 | 11 | message Fallback { 12 | string alpn = 1; 13 | string path = 2; 14 | string type = 3; 15 | string dest = 4; 16 | uint64 xver = 5; 17 | } 18 | 19 | message Config { 20 | repeated v2ray.core.common.protocol.User clients = 1; 21 | // Decryption settings. Only applies to server side, and only accepts "none" 22 | // for now. 23 | string decryption = 2; 24 | repeated Fallback fallbacks = 3; 25 | } 26 | -------------------------------------------------------------------------------- /proxy/vless/inbound/errors.generated.go: -------------------------------------------------------------------------------- 1 | package inbound 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /proxy/vless/outbound/config.go: -------------------------------------------------------------------------------- 1 | // +build !confonly 2 | 3 | package outbound 4 | -------------------------------------------------------------------------------- /proxy/vless/outbound/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.proxy.vless.outbound; 4 | option csharp_namespace = "V2Ray.Core.Proxy.Vless.Outbound"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/proxy/vless/outbound"; 6 | option java_package = "com.v2ray.core.proxy.vless.outbound"; 7 | option java_multiple_files = true; 8 | 9 | import "common/protocol/server_spec.proto"; 10 | 11 | message Config { 12 | repeated v2ray.core.common.protocol.ServerEndpoint vnext = 1; 13 | } 14 | -------------------------------------------------------------------------------- /proxy/vless/outbound/errors.generated.go: -------------------------------------------------------------------------------- 1 | package outbound 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /proxy/vless/vless.go: -------------------------------------------------------------------------------- 1 | // Package vless contains the implementation of VLess protocol and transportation. 2 | // 3 | // VLess contains both inbound and outbound connections. VLess inbound is usually used on servers 4 | // together with 'freedom' to talk to final destination, while VLess outbound is usually used on 5 | // clients with 'socks' for proxying. 6 | package vless 7 | 8 | //go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen 9 | -------------------------------------------------------------------------------- /proxy/vmess/account.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.proxy.vmess; 4 | option csharp_namespace = "V2Ray.Core.Proxy.Vmess"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/proxy/vmess"; 6 | option java_package = "com.v2ray.core.proxy.vmess"; 7 | option java_multiple_files = true; 8 | 9 | import "common/protocol/headers.proto"; 10 | 11 | message Account { 12 | // ID of the account, in the form of a UUID, e.g., 13 | // "66ad4540-b58c-4ad2-9926-ea63445a9b57". 14 | string id = 1; 15 | // Number of alternative IDs. Client and server must share the same number. 16 | uint32 alter_id = 2; 17 | // Security settings. Only applies to client side. 18 | v2ray.core.common.protocol.SecurityConfig security_settings = 3; 19 | // Define tests enabled for this account 20 | string tests_enabled = 4; 21 | uint64 limit = 5; 22 | } 23 | -------------------------------------------------------------------------------- /proxy/vmess/aead/consts.go: -------------------------------------------------------------------------------- 1 | package aead 2 | 3 | const ( 4 | KDFSaltConstAuthIDEncryptionKey = "AES Auth ID Encryption" 5 | KDFSaltConstAEADRespHeaderLenKey = "AEAD Resp Header Len Key" 6 | KDFSaltConstAEADRespHeaderLenIV = "AEAD Resp Header Len IV" 7 | KDFSaltConstAEADRespHeaderPayloadKey = "AEAD Resp Header Key" 8 | KDFSaltConstAEADRespHeaderPayloadIV = "AEAD Resp Header IV" 9 | KDFSaltConstVMessAEADKDF = "VMess AEAD KDF" 10 | KDFSaltConstVMessHeaderPayloadAEADKey = "VMess Header AEAD Key" 11 | KDFSaltConstVMessHeaderPayloadAEADIV = "VMess Header AEAD Nonce" 12 | KDFSaltConstVMessHeaderPayloadLengthAEADKey = "VMess Header AEAD Key_Length" 13 | KDFSaltConstVMessHeaderPayloadLengthAEADIV = "VMess Header AEAD Nonce_Length" 14 | ) 15 | -------------------------------------------------------------------------------- /proxy/vmess/aead/kdf.go: -------------------------------------------------------------------------------- 1 | package aead 2 | 3 | import ( 4 | "crypto/hmac" 5 | "crypto/sha256" 6 | "hash" 7 | ) 8 | 9 | func KDF(key []byte, path ...string) []byte { 10 | hmacCreator := &hMacCreator{value: []byte(KDFSaltConstVMessAEADKDF)} 11 | for _, v := range path { 12 | hmacCreator = &hMacCreator{value: []byte(v), parent: hmacCreator} 13 | } 14 | hmacf := hmacCreator.Create() 15 | hmacf.Write(key) 16 | return hmacf.Sum(nil) 17 | } 18 | 19 | type hMacCreator struct { 20 | parent *hMacCreator 21 | value []byte 22 | } 23 | 24 | func (h *hMacCreator) Create() hash.Hash { 25 | if h.parent == nil { 26 | return hmac.New(sha256.New, h.value) 27 | } 28 | return hmac.New(h.parent.Create, h.value) 29 | } 30 | 31 | func KDF16(key []byte, path ...string) []byte { 32 | r := KDF(key, path...) 33 | return r[:16] 34 | } 35 | -------------------------------------------------------------------------------- /proxy/vmess/aead/kdf_test.go: -------------------------------------------------------------------------------- 1 | package aead 2 | 3 | import ( 4 | "encoding/hex" 5 | "fmt" 6 | "testing" 7 | 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | func TestKDFValue(t *testing.T) { 12 | GeneratedKey := KDF([]byte("Demo Key for KDF Value Test"), "Demo Path for KDF Value Test", "Demo Path for KDF Value Test2", "Demo Path for KDF Value Test3") 13 | fmt.Println(hex.EncodeToString(GeneratedKey)) 14 | assert.Equal(t, "53e9d7e1bd7bd25022b71ead07d8a596efc8a845c7888652fd684b4903dc8892", hex.EncodeToString(GeneratedKey), "Should generate expected KDF Value") 15 | } 16 | -------------------------------------------------------------------------------- /proxy/vmess/encoding/auth_test.go: -------------------------------------------------------------------------------- 1 | package encoding_test 2 | 3 | import ( 4 | "crypto/rand" 5 | "testing" 6 | 7 | "github.com/google/go-cmp/cmp" 8 | 9 | "github.com/v2fly/v2ray-core/v4/common" 10 | . "github.com/v2fly/v2ray-core/v4/proxy/vmess/encoding" 11 | ) 12 | 13 | func TestFnvAuth(t *testing.T) { 14 | fnvAuth := new(FnvAuthenticator) 15 | 16 | expectedText := make([]byte, 256) 17 | _, err := rand.Read(expectedText) 18 | common.Must(err) 19 | 20 | buffer := make([]byte, 512) 21 | b := fnvAuth.Seal(buffer[:0], nil, expectedText, nil) 22 | b, err = fnvAuth.Open(buffer[:0], nil, b, nil) 23 | common.Must(err) 24 | if r := cmp.Diff(b, expectedText); r != "" { 25 | t.Error(r) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /proxy/vmess/encoding/commands_test.go: -------------------------------------------------------------------------------- 1 | package encoding_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/google/go-cmp/cmp" 7 | 8 | "github.com/v2fly/v2ray-core/v4/common" 9 | "github.com/v2fly/v2ray-core/v4/common/buf" 10 | "github.com/v2fly/v2ray-core/v4/common/protocol" 11 | "github.com/v2fly/v2ray-core/v4/common/uuid" 12 | . "github.com/v2fly/v2ray-core/v4/proxy/vmess/encoding" 13 | ) 14 | 15 | func TestSwitchAccount(t *testing.T) { 16 | sa := &protocol.CommandSwitchAccount{ 17 | Port: 1234, 18 | ID: uuid.New(), 19 | AlterIds: 1024, 20 | Level: 128, 21 | ValidMin: 16, 22 | } 23 | 24 | buffer := buf.New() 25 | common.Must(MarshalCommand(sa, buffer)) 26 | 27 | cmd, err := UnmarshalCommand(1, buffer.BytesFrom(2)) 28 | common.Must(err) 29 | 30 | sa2, ok := cmd.(*protocol.CommandSwitchAccount) 31 | if !ok { 32 | t.Fatal("failed to convert command to CommandSwitchAccount") 33 | } 34 | if r := cmp.Diff(sa2, sa); r != "" { 35 | t.Error(r) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /proxy/vmess/encoding/encoding.go: -------------------------------------------------------------------------------- 1 | package encoding 2 | 3 | import ( 4 | "github.com/v2fly/v2ray-core/v4/common/net" 5 | "github.com/v2fly/v2ray-core/v4/common/protocol" 6 | ) 7 | 8 | //go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen 9 | 10 | const ( 11 | Version = byte(1) 12 | ) 13 | 14 | var addrParser = protocol.NewAddressParser( 15 | protocol.AddressFamilyByte(byte(protocol.AddressTypeIPv4), net.AddressFamilyIPv4), 16 | protocol.AddressFamilyByte(byte(protocol.AddressTypeDomain), net.AddressFamilyDomain), 17 | protocol.AddressFamilyByte(byte(protocol.AddressTypeIPv6), net.AddressFamilyIPv6), 18 | protocol.PortThenAddress(), 19 | ) 20 | -------------------------------------------------------------------------------- /proxy/vmess/encoding/errors.generated.go: -------------------------------------------------------------------------------- 1 | package encoding 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /proxy/vmess/errors.generated.go: -------------------------------------------------------------------------------- 1 | package vmess 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /proxy/vmess/inbound/config.go: -------------------------------------------------------------------------------- 1 | // +build !confonly 2 | 3 | package inbound 4 | 5 | // GetDefaultValue returns default settings of DefaultConfig. 6 | func (c *Config) GetDefaultValue() *DefaultConfig { 7 | if c.GetDefault() == nil { 8 | return &DefaultConfig{} 9 | } 10 | return c.Default 11 | } 12 | -------------------------------------------------------------------------------- /proxy/vmess/inbound/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.proxy.vmess.inbound; 4 | option csharp_namespace = "V2Ray.Core.Proxy.Vmess.Inbound"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/proxy/vmess/inbound"; 6 | option java_package = "com.v2ray.core.proxy.vmess.inbound"; 7 | option java_multiple_files = true; 8 | 9 | import "common/protocol/user.proto"; 10 | 11 | message DetourConfig { 12 | string to = 1; 13 | } 14 | 15 | message DefaultConfig { 16 | uint32 alter_id = 1; 17 | uint32 level = 2; 18 | } 19 | 20 | message Config { 21 | repeated v2ray.core.common.protocol.User user = 1; 22 | DefaultConfig default = 2; 23 | DetourConfig detour = 3; 24 | bool secure_encryption_only = 4; 25 | } 26 | -------------------------------------------------------------------------------- /proxy/vmess/inbound/errors.generated.go: -------------------------------------------------------------------------------- 1 | package inbound 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /proxy/vmess/outbound/config.go: -------------------------------------------------------------------------------- 1 | package outbound 2 | -------------------------------------------------------------------------------- /proxy/vmess/outbound/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.proxy.vmess.outbound; 4 | option csharp_namespace = "V2Ray.Core.Proxy.Vmess.Outbound"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/proxy/vmess/outbound"; 6 | option java_package = "com.v2ray.core.proxy.vmess.outbound"; 7 | option java_multiple_files = true; 8 | 9 | import "common/protocol/server_spec.proto"; 10 | 11 | message Config { 12 | repeated v2ray.core.common.protocol.ServerEndpoint Receiver = 1; 13 | } 14 | -------------------------------------------------------------------------------- /proxy/vmess/outbound/errors.generated.go: -------------------------------------------------------------------------------- 1 | package outbound 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /proxy/vmess/vmess.go: -------------------------------------------------------------------------------- 1 | // Package vmess contains the implementation of VMess protocol and transportation. 2 | // 3 | // VMess contains both inbound and outbound connections. VMess inbound is usually used on servers 4 | // together with 'freedom' to talk to final destination, while VMess outbound is usually used on 5 | // clients with 'socks' for proxying. 6 | package vmess 7 | 8 | //go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen 9 | -------------------------------------------------------------------------------- /proxy/vmess/vmessCtxInterface.go: -------------------------------------------------------------------------------- 1 | package vmess 2 | 3 | // example 4 | const AlterID = "VMessCtxInterface_AlterID" 5 | -------------------------------------------------------------------------------- /release/config/systemd/system/v2ray.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=V2Ray Service 3 | Documentation=https://www.v2fly.org/ 4 | After=network.target nss-lookup.target 5 | 6 | [Service] 7 | User=nobody 8 | CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE 9 | AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE 10 | NoNewPrivileges=true 11 | ExecStart=/usr/local/bin/v2ray -config /usr/local/etc/v2ray/config.json 12 | Restart=on-failure 13 | RestartPreventExitStatus=23 14 | 15 | [Install] 16 | WantedBy=multi-user.target 17 | -------------------------------------------------------------------------------- /release/config/systemd/system/v2ray@.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=V2Ray Service 3 | Documentation=https://www.v2fly.org/ 4 | After=network.target nss-lookup.target 5 | 6 | [Service] 7 | User=nobody 8 | CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE 9 | AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE 10 | NoNewPrivileges=true 11 | ExecStart=/usr/local/bin/v2ray -config /usr/local/etc/v2ray/%i.json 12 | Restart=on-failure 13 | RestartPreventExitStatus=23 14 | 15 | [Install] 16 | WantedBy=multi-user.target 17 | -------------------------------------------------------------------------------- /release/config/vpoint_socks_vmess.json: -------------------------------------------------------------------------------- 1 | { 2 | "log": { 3 | "loglevel": "warning" 4 | }, 5 | "inbounds": [{ 6 | "port": 1080, 7 | "listen": "127.0.0.1", 8 | "protocol": "socks", 9 | "settings": { 10 | "auth": "noauth", 11 | "udp": false, 12 | "ip": "127.0.0.1" 13 | } 14 | }], 15 | "outbounds": [{ 16 | "protocol": "freedom", 17 | "settings": {}, 18 | "tag": "direct" 19 | }], 20 | "policy": { 21 | "levels": { 22 | "0": {"uplinkOnly": 0} 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /release/config/vpoint_vmess_freedom.json: -------------------------------------------------------------------------------- 1 | { 2 | "inbounds": [{ 3 | "port": 10086, 4 | "protocol": "vmess", 5 | "settings": { 6 | "clients": [ 7 | { 8 | "id": "23ad6b10-8d1a-40f7-8ad0-e3e35cd38297", 9 | "level": 1, 10 | "alterId": 64 11 | } 12 | ] 13 | } 14 | }], 15 | "outbounds": [{ 16 | "protocol": "freedom", 17 | "settings": {} 18 | },{ 19 | "protocol": "blackhole", 20 | "settings": {}, 21 | "tag": "blocked" 22 | }], 23 | "routing": { 24 | "rules": [ 25 | { 26 | "type": "field", 27 | "ip": ["geoip:private"], 28 | "outboundTag": "blocked" 29 | } 30 | ] 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /release/debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | 3 | include /usr/share/dpkg/default.mk 4 | 5 | BUILDDIR=_build 6 | 7 | %: 8 | dh $@ --builddirectory=$(BUILDDIR) --buildsystem=golang --with=golang 9 | 10 | execute_after_dh_auto_configure: 11 | go mod vendor 12 | cp -r vendor/* _build/src 13 | 14 | override_dh_auto_clean: 15 | dh_auto_clean 16 | rm -rf vendor 17 | 18 | override_dh_auto_build: 19 | DH_GOPKG="github.com/v2fly/v2ray-core/v4/main" dh_auto_build -- -ldflags "-s -w" 20 | cd $(BUILDDIR); mv bin/main bin/v2ray 21 | DH_GOPKG="github.com/v2fly/v2ray-core/v4/infra/control/main" dh_auto_build -- -ldflags "-s -w" -tags confonly 22 | cd $(BUILDDIR); mv bin/main bin/v2ctl 23 | 24 | override_dh_auto_install: 25 | dh_auto_install -- --no-source 26 | 27 | override_dh_auto_test: 28 | -------------------------------------------------------------------------------- /release/debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (quilt) 2 | -------------------------------------------------------------------------------- /release/debian/v2ray-docs.docs: -------------------------------------------------------------------------------- 1 | README.md 2 | -------------------------------------------------------------------------------- /release/debian/v2ray-domain-list-community.install: -------------------------------------------------------------------------------- 1 | release/config/geosite.dat usr/share/v2ray 2 | -------------------------------------------------------------------------------- /release/debian/v2ray-geoip.install: -------------------------------------------------------------------------------- 1 | release/config/geoip.dat usr/share/v2ray 2 | -------------------------------------------------------------------------------- /release/debian/v2ray.install: -------------------------------------------------------------------------------- 1 | usr/bin 2 | release/config/config.json etc/v2ray 3 | -------------------------------------------------------------------------------- /release/debian/v2ray.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=V2Ray Service 3 | Documentation=https://www.v2fly.org/ 4 | After=network.target nss-lookup.target 5 | 6 | [Service] 7 | User=nobody 8 | CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE 9 | AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE 10 | NoNewPrivileges=true 11 | ExecStart=/usr/bin/v2ray -config /etc/v2ray/config.json 12 | Restart=on-failure 13 | RestartPreventExitStatus=23 14 | 15 | [Install] 16 | WantedBy=multi-user.target 17 | -------------------------------------------------------------------------------- /release/debian/v2ray@.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=V2Ray Service 3 | Documentation=https://www.v2fly.org/ 4 | After=network.target nss-lookup.target 5 | 6 | [Service] 7 | User=nobody 8 | CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE 9 | AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE 10 | NoNewPrivileges=true 11 | ExecStart=/usr/bin/v2ray -config /etc/v2ray/%i.json 12 | Restart=on-failure 13 | RestartPreventExitStatus=23 14 | 15 | [Install] 16 | WantedBy=multi-user.target 17 | -------------------------------------------------------------------------------- /release/extra/browserforwarder/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Bridge 6 | 7 | 8 | See debug console for detail 9 | 10 | 11 | -------------------------------------------------------------------------------- /release_vnet/config/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "api_server": "", 3 | "key": "", 4 | "node_id": 0, 5 | "log_path": "/var/log/v2ray/vnet-v2ray.log" 6 | } 7 | -------------------------------------------------------------------------------- /release_vnet/config/geoip.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ProxyPanel/VNet-V2ray/61bc404e3cef2b98df24dfe1bfb3ade4d455d774/release_vnet/config/geoip.dat -------------------------------------------------------------------------------- /release_vnet/config/geosite.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ProxyPanel/VNet-V2ray/61bc404e3cef2b98df24dfe1bfb3ade4d455d774/release_vnet/config/geosite.dat -------------------------------------------------------------------------------- /release_vnet/config/systemd/vnet-v2ray.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=VNet V2Ray Service 3 | After=network.target 4 | Wants=network.target 5 | 6 | [Service] 7 | # This service runs as root. You may consider to run it as another user for security concerns. 8 | # By uncommenting the following two lines, this service will run as user v2ray/v2ray. 9 | # More discussion at https://github.com/v2ray/v2ray-core/issues/1011 10 | # User=v2ray 11 | # Group=v2ray 12 | Type=simple 13 | ExecStart=/usr/bin/v2ray/vnet-v2ray -config /etc/v2ray/config.json 14 | Restart=on-failure 15 | # Don't restart in the case of configuration error 16 | RestartPreventExitStatus=23 17 | LimitNOFILE=20480000 18 | 19 | [Install] 20 | WantedBy=multi-user.target 21 | -------------------------------------------------------------------------------- /release_vnet/doc/readme.md: -------------------------------------------------------------------------------- 1 | # V2Ray 内核 2 | 3 | V2Ray 内核可以单独使用,也可以配置其它程序一起使用。 4 | 5 | 官网:https://www.v2ray.com/ 6 | 7 | ## 使用方式 8 | 9 | ### Windows 或 macOS 10 | 11 | 压缩包内的 config.json 是默认的配置文件,无需修改即可使用。配置文件的详细信息可以在官网找到。 12 | 13 | * Windows 中的可执行文件为 v2ray.exe 和 wv2ray.exe。双击即可运行。 14 | * v2ray.exe 是一个命令行程序,启动后可以看到命令行界面。 15 | * wv2ray.exe 是一个后台程序,没有界面,会在后台自动运行。 16 | * macOS 中的可执行文件为 v2ray。右键单击,然后选择使用 Terminal 打开即可。 17 | 18 | ### Linux 19 | 20 | 压缩包中包含多个配置文件,按需使用。 21 | 22 | 可执行程序为 v2ray,启动命令: 23 | 24 | ```bash 25 | v2ray --config= 26 | ``` 27 | 28 | ## 验证文件 29 | 30 | 压缩包中的 .sig 文件为 GPG 签名文件,用来验证对应程序文件的真实性。签名公钥可以在下面的链接找到: 31 | 32 | https://github.com/v2ray/v2ray-core/blob/master/release/verify/official_release.asc 33 | 34 | ## 问题反馈 35 | 36 | * Github: https://github.com/v2ray/v2ray-core 37 | * Telegram: https://t.me/v2fly_chat 38 | -------------------------------------------------------------------------------- /release_vnet/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | GO_AMD64=https://storage.googleapis.com/golang/go1.11.1.linux-amd64.tar.gz 4 | GO_X86=https://storage.googleapis.com/golang/go1.11.1.linux-386.tar.gz 5 | ARCH=$(uname -m) 6 | GO_CUR=${GO_AMD64} 7 | 8 | if [ "$ARCH" == "i686" ] || [ "$ARCH" == "i386" ]; then 9 | GO_CUR=${GO_X86} 10 | fi 11 | 12 | which git > /dev/null || apt-get install git -y 13 | 14 | if [ -z "$GOPATH" ]; then 15 | curl -o go_latest.tar.gz ${GO_CUR} 16 | tar -C /usr/local -xzf go_latest.tar.gz 17 | rm go_latest.tar.gz 18 | export PATH=$PATH:/usr/local/go/bin 19 | 20 | mkdir /v2ray &> /dev/null 21 | export GOPATH=/v2ray 22 | fi 23 | 24 | go get -insecure -u v2ray.com/core/... 25 | go build -o $GOPATH/bin/v2ray v2ray.com/core/main 26 | go build -o $GOPATH/bin/v2ctl v2ray.com/core/infra/control/main 27 | -------------------------------------------------------------------------------- /release_vnet/mapping.bzl: -------------------------------------------------------------------------------- 1 | def gen_mappings(os, arch): 2 | return { 3 | "v2ray_core/release_vnet/doc": "doc", 4 | "v2ray_core/release_vnet/config": "", 5 | "v2ray_core/vnet/" + os + "/" + arch: "", 6 | } 7 | -------------------------------------------------------------------------------- /release_vnet/version.json: -------------------------------------------------------------------------------- 1 | { 2 | "latest": "v1.7.0", 3 | "history": [ 4 | "v1.7.0" 5 | ] 6 | } -------------------------------------------------------------------------------- /release_vnet_v2ray/config/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "url": "", 3 | "key": "", 4 | "id": 0, 5 | "error_log_path": "/var/log/vnet-v2ray/error.log", 6 | "access_log_path": "/var/log/vnet-v2ray/access.log" 7 | } 8 | -------------------------------------------------------------------------------- /release_vnet_v2ray/config/systemd/system/vnet-v2ray.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=VNet V2Ray Service 3 | After=network.target nss-lookup.target 4 | 5 | [Service] 6 | Type=simple 7 | User=nobody 8 | CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE 9 | AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE 10 | NoNewPrivileges=true 11 | ExecStart=/usr/local/bin/vnet-v2ray -config /usr/local/etc/vnet-v2ray/config.json 12 | Restart=on-failure 13 | RestartPreventExitStatus=23 14 | LimitNOFILE=20480000 15 | 16 | [Install] 17 | WantedBy=multi-user.target 18 | 19 | 20 | -------------------------------------------------------------------------------- /release_vnet_v2ray/config/systemd/system/vnet-v2ray@.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=VNet V2Ray Service 3 | After=network.target nss-lookup.target 4 | 5 | [Service] 6 | Type=simple 7 | User=nobody 8 | CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE 9 | AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE 10 | NoNewPrivileges=true 11 | ExecStart=/usr/local/bin/vnet-v2ray -config /usr/local/etc/vnet-v2ray/%i.json 12 | Restart=on-failure 13 | RestartPreventExitStatus=23 14 | LimitNOFILE=20480000 15 | 16 | [Install] 17 | WantedBy=multi-user.target 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /release_vnet_v2ray/debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | 3 | include /usr/share/dpkg/default.mk 4 | 5 | BUILDDIR=_build 6 | 7 | %: 8 | dh $@ --builddirectory=$(BUILDDIR) --buildsystem=golang --with=golang 9 | 10 | execute_after_dh_auto_configure: 11 | go mod vendor 12 | cp -r vendor/* _build/src 13 | 14 | override_dh_auto_clean: 15 | dh_auto_clean 16 | rm -rf vendor 17 | 18 | override_dh_auto_build: 19 | DH_GOPKG="github.com/v2fly/v2ray-core/v4/main" dh_auto_build -- -ldflags "-s -w" 20 | cd $(BUILDDIR); mv bin/main bin/v2ray 21 | DH_GOPKG="github.com/v2fly/v2ray-core/v4/infra/control/main" dh_auto_build -- -ldflags "-s -w" -tags confonly 22 | cd $(BUILDDIR); mv bin/main bin/v2ctl 23 | 24 | override_dh_auto_install: 25 | dh_auto_install -- --no-source 26 | 27 | override_dh_auto_test: 28 | -------------------------------------------------------------------------------- /release_vnet_v2ray/debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (quilt) 2 | -------------------------------------------------------------------------------- /release_vnet_v2ray/debian/v2ray-docs.docs: -------------------------------------------------------------------------------- 1 | README.md 2 | -------------------------------------------------------------------------------- /release_vnet_v2ray/debian/v2ray-domain-list-community.install: -------------------------------------------------------------------------------- 1 | release/config/geosite.dat usr/share/v2ray 2 | -------------------------------------------------------------------------------- /release_vnet_v2ray/debian/v2ray-geoip.install: -------------------------------------------------------------------------------- 1 | release/config/geoip.dat usr/share/v2ray 2 | -------------------------------------------------------------------------------- /release_vnet_v2ray/debian/v2ray.install: -------------------------------------------------------------------------------- 1 | usr/bin 2 | release/config/config.json etc/v2ray 3 | -------------------------------------------------------------------------------- /release_vnet_v2ray/debian/v2ray.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=V2Ray Service 3 | Documentation=https://www.v2fly.org/ 4 | After=network.target nss-lookup.target 5 | 6 | [Service] 7 | User=nobody 8 | CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE 9 | AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE 10 | NoNewPrivileges=true 11 | ExecStart=/usr/bin/v2ray -config /etc/v2ray/config.json 12 | Restart=on-failure 13 | RestartPreventExitStatus=23 14 | 15 | [Install] 16 | WantedBy=multi-user.target 17 | -------------------------------------------------------------------------------- /release_vnet_v2ray/debian/v2ray@.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=V2Ray Service 3 | Documentation=https://www.v2fly.org/ 4 | After=network.target nss-lookup.target 5 | 6 | [Service] 7 | User=nobody 8 | CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE 9 | AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE 10 | NoNewPrivileges=true 11 | ExecStart=/usr/bin/v2ray -config /etc/v2ray/%i.json 12 | Restart=on-failure 13 | RestartPreventExitStatus=23 14 | 15 | [Install] 16 | WantedBy=multi-user.target 17 | -------------------------------------------------------------------------------- /release_vnet_v2ray/extra/browserforwarder/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Bridge 6 | 7 | 8 | See debug console for detail 9 | 10 | 11 | -------------------------------------------------------------------------------- /testing/scenarios/common_regular.go: -------------------------------------------------------------------------------- 1 | // +build !coverage 2 | 3 | package scenarios 4 | 5 | import ( 6 | "bytes" 7 | "fmt" 8 | "os" 9 | "os/exec" 10 | ) 11 | 12 | func BuildV2Ray() error { 13 | genTestBinaryPath() 14 | if _, err := os.Stat(testBinaryPath); err == nil { 15 | return nil 16 | } 17 | 18 | fmt.Printf("Building V2Ray into path (%s)\n", testBinaryPath) 19 | cmd := exec.Command("go", "build", "-o="+testBinaryPath, GetSourcePath()) 20 | return cmd.Run() 21 | } 22 | 23 | func RunV2RayProtobuf(config []byte) *exec.Cmd { 24 | genTestBinaryPath() 25 | proc := exec.Command(testBinaryPath, "-config=stdin:", "-format=pb") 26 | proc.Stdin = bytes.NewBuffer(config) 27 | proc.Stderr = os.Stderr 28 | proc.Stdout = os.Stdout 29 | 30 | return proc 31 | } 32 | -------------------------------------------------------------------------------- /testing/servers/http/http.go: -------------------------------------------------------------------------------- 1 | package tcp 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/v2fly/v2ray-core/v4/common/net" 7 | ) 8 | 9 | type Server struct { 10 | Port net.Port 11 | PathHandler map[string]http.HandlerFunc 12 | server *http.Server 13 | } 14 | 15 | func (s *Server) ServeHTTP(resp http.ResponseWriter, req *http.Request) { 16 | if req.URL.Path == "/" { 17 | resp.Header().Set("Content-Type", "text/plain; charset=utf-8") 18 | resp.WriteHeader(http.StatusOK) 19 | resp.Write([]byte("Home")) 20 | return 21 | } 22 | 23 | handler, found := s.PathHandler[req.URL.Path] 24 | if found { 25 | handler(resp, req) 26 | } 27 | } 28 | 29 | func (s *Server) Start() (net.Destination, error) { 30 | s.server = &http.Server{ 31 | Addr: "127.0.0.1:" + s.Port.String(), 32 | Handler: s, 33 | } 34 | go s.server.ListenAndServe() 35 | return net.TCPDestination(net.LocalHostIP, s.Port), nil 36 | } 37 | 38 | func (s *Server) Close() error { 39 | return s.server.Close() 40 | } 41 | -------------------------------------------------------------------------------- /testing/servers/tcp/port.go: -------------------------------------------------------------------------------- 1 | package tcp 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/net" 4 | 5 | // PickPort returns an unused TCP port of the system. 6 | func PickPort() net.Port { 7 | listener := pickPort() 8 | defer listener.Close() 9 | 10 | addr := listener.Addr().(*net.TCPAddr) 11 | return net.Port(addr.Port) 12 | } 13 | 14 | func pickPort() net.Listener { 15 | listener, err := net.Listen("tcp4", "127.0.0.1:0") 16 | if err != nil { 17 | listener = pickPort() 18 | } 19 | return listener 20 | } 21 | -------------------------------------------------------------------------------- /testing/servers/udp/port.go: -------------------------------------------------------------------------------- 1 | package udp 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/net" 4 | 5 | // PickPort returns an unused UDP port of the system. 6 | func PickPort() net.Port { 7 | conn := pickPort() 8 | defer conn.Close() 9 | 10 | addr := conn.LocalAddr().(*net.UDPAddr) 11 | return net.Port(addr.Port) 12 | } 13 | 14 | func pickPort() *net.UDPConn { 15 | conn, err := net.ListenUDP("udp4", &net.UDPAddr{ 16 | IP: net.LocalHostIP.IP(), 17 | Port: 0, 18 | }) 19 | if err != nil { 20 | conn = pickPort() 21 | } 22 | return conn 23 | } 24 | -------------------------------------------------------------------------------- /transport/config.go: -------------------------------------------------------------------------------- 1 | package transport 2 | 3 | import ( 4 | "github.com/v2fly/v2ray-core/v4/transport/internet" 5 | ) 6 | 7 | // Apply applies this Config. 8 | func (c *Config) Apply() error { 9 | if c == nil { 10 | return nil 11 | } 12 | return internet.ApplyGlobalTransportSettings(c.TransportSettings) 13 | } 14 | -------------------------------------------------------------------------------- /transport/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.transport; 4 | option csharp_namespace = "V2Ray.Core.Transport"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/transport"; 6 | option java_package = "com.v2ray.core.transport"; 7 | option java_multiple_files = true; 8 | 9 | import "transport/internet/config.proto"; 10 | 11 | // Global transport settings. This affects all type of connections that go 12 | // through V2Ray. Deprecated. Use each settings in StreamConfig. 13 | message Config { 14 | option deprecated = true; 15 | repeated v2ray.core.transport.internet.TransportConfig transport_settings = 1; 16 | } 17 | -------------------------------------------------------------------------------- /transport/internet/connection.go: -------------------------------------------------------------------------------- 1 | package internet 2 | 3 | import ( 4 | "net" 5 | 6 | "github.com/v2fly/v2ray-core/v4/features/stats" 7 | ) 8 | 9 | type Connection interface { 10 | net.Conn 11 | } 12 | 13 | type StatCouterConnection struct { 14 | Connection 15 | ReadCounter stats.Counter 16 | WriteCounter stats.Counter 17 | } 18 | 19 | func (c *StatCouterConnection) Read(b []byte) (int, error) { 20 | nBytes, err := c.Connection.Read(b) 21 | if c.ReadCounter != nil { 22 | c.ReadCounter.Add(int64(nBytes)) 23 | } 24 | 25 | return nBytes, err 26 | } 27 | 28 | func (c *StatCouterConnection) Write(b []byte) (int, error) { 29 | nBytes, err := c.Connection.Write(b) 30 | if c.WriteCounter != nil { 31 | c.WriteCounter.Add(int64(nBytes)) 32 | } 33 | return nBytes, err 34 | } 35 | -------------------------------------------------------------------------------- /transport/internet/dialer_test.go: -------------------------------------------------------------------------------- 1 | package internet_test 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | "github.com/google/go-cmp/cmp" 8 | 9 | "github.com/v2fly/v2ray-core/v4/common" 10 | "github.com/v2fly/v2ray-core/v4/common/net" 11 | "github.com/v2fly/v2ray-core/v4/testing/servers/tcp" 12 | . "github.com/v2fly/v2ray-core/v4/transport/internet" 13 | ) 14 | 15 | func TestDialWithLocalAddr(t *testing.T) { 16 | server := &tcp.Server{} 17 | dest, err := server.Start() 18 | common.Must(err) 19 | defer server.Close() 20 | 21 | conn, err := DialSystem(context.Background(), net.TCPDestination(net.LocalHostIP, dest.Port), nil) 22 | common.Must(err) 23 | if r := cmp.Diff(conn.RemoteAddr().String(), "127.0.0.1:"+dest.Port.String()); r != "" { 24 | t.Error(r) 25 | } 26 | conn.Close() 27 | } 28 | -------------------------------------------------------------------------------- /transport/internet/domainsocket/config.go: -------------------------------------------------------------------------------- 1 | // +build !confonly 2 | 3 | package domainsocket 4 | 5 | import ( 6 | "github.com/v2fly/v2ray-core/v4/common" 7 | "github.com/v2fly/v2ray-core/v4/common/net" 8 | "github.com/v2fly/v2ray-core/v4/transport/internet" 9 | ) 10 | 11 | const ( 12 | protocolName = "domainsocket" 13 | sizeofSunPath = 108 14 | ) 15 | 16 | func (c *Config) GetUnixAddr() (*net.UnixAddr, error) { 17 | path := c.Path 18 | if path == "" { 19 | return nil, newError("empty domain socket path") 20 | } 21 | if c.Abstract && path[0] != '@' { 22 | path = "@" + path 23 | } 24 | if c.Abstract && c.Padding { 25 | raw := []byte(path) 26 | addr := make([]byte, sizeofSunPath) 27 | copy(addr, raw) 28 | path = string(addr) 29 | } 30 | return &net.UnixAddr{ 31 | Name: path, 32 | Net: "unix", 33 | }, nil 34 | } 35 | 36 | func init() { 37 | common.Must(internet.RegisterProtocolConfigCreator(protocolName, func() interface{} { 38 | return new(Config) 39 | })) 40 | } 41 | -------------------------------------------------------------------------------- /transport/internet/domainsocket/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.transport.internet.domainsocket; 4 | option csharp_namespace = "V2Ray.Core.Transport.Internet.DomainSocket"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/transport/internet/domainsocket"; 6 | option java_package = "com.v2ray.core.transport.internet.domainsocket"; 7 | option java_multiple_files = true; 8 | 9 | message Config { 10 | // Path of the domain socket. This overrides the IP/Port parameter from 11 | // upstream caller. 12 | string path = 1; 13 | // Abstract speicifies whether to use abstract namespace or not. 14 | // Traditionally Unix domain socket is file system based. Abstract domain 15 | // socket can be used without acquiring file lock. 16 | bool abstract = 2; 17 | // Some apps, eg. haproxy, use the full length of sockaddr_un.sun_path to 18 | // connect(2) or bind(2) when using abstract UDS. 19 | bool padding = 3; 20 | } 21 | -------------------------------------------------------------------------------- /transport/internet/domainsocket/errgen.go: -------------------------------------------------------------------------------- 1 | package domainsocket 2 | 3 | //go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen 4 | -------------------------------------------------------------------------------- /transport/internet/domainsocket/errors.generated.go: -------------------------------------------------------------------------------- 1 | package domainsocket 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /transport/internet/errors.generated.go: -------------------------------------------------------------------------------- 1 | package internet 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /transport/internet/filelocker.go: -------------------------------------------------------------------------------- 1 | package internet 2 | 3 | import ( 4 | "os" 5 | ) 6 | 7 | // FileLocker is UDS access lock 8 | type FileLocker struct { 9 | path string 10 | file *os.File 11 | } 12 | -------------------------------------------------------------------------------- /transport/internet/filelocker_other.go: -------------------------------------------------------------------------------- 1 | // +build !windows 2 | 3 | package internet 4 | 5 | import ( 6 | "os" 7 | 8 | "golang.org/x/sys/unix" 9 | ) 10 | 11 | // Acquire lock 12 | func (fl *FileLocker) Acquire() error { 13 | f, err := os.Create(fl.path) 14 | if err != nil { 15 | return err 16 | } 17 | if err := unix.Flock(int(f.Fd()), unix.LOCK_EX); err != nil { 18 | f.Close() 19 | return newError("failed to lock file: ", fl.path).Base(err) 20 | } 21 | fl.file = f 22 | return nil 23 | } 24 | 25 | // Release lock 26 | func (fl *FileLocker) Release() { 27 | if err := unix.Flock(int(fl.file.Fd()), unix.LOCK_UN); err != nil { 28 | newError("failed to unlock file: ", fl.path).Base(err).WriteToLog() 29 | } 30 | if err := fl.file.Close(); err != nil { 31 | newError("failed to close file: ", fl.path).Base(err).WriteToLog() 32 | } 33 | if err := os.Remove(fl.path); err != nil { 34 | newError("failed to remove file: ", fl.path).Base(err).WriteToLog() 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /transport/internet/filelocker_windows.go: -------------------------------------------------------------------------------- 1 | package internet 2 | 3 | // Acquire lock 4 | func (fl *FileLocker) Acquire() error { 5 | return nil 6 | } 7 | 8 | // Release lock 9 | func (fl *FileLocker) Release() { 10 | return 11 | } 12 | -------------------------------------------------------------------------------- /transport/internet/grpc/config.go: -------------------------------------------------------------------------------- 1 | package grpc 2 | 3 | import ( 4 | "github.com/v2fly/v2ray-core/v4/common" 5 | "github.com/v2fly/v2ray-core/v4/transport/internet" 6 | ) 7 | 8 | const protocolName = "gun" 9 | 10 | func init() { 11 | common.Must(internet.RegisterProtocolConfigCreator(protocolName, func() interface{} { 12 | return new(Config) 13 | })) 14 | } 15 | -------------------------------------------------------------------------------- /transport/internet/grpc/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package v2ray.core.transport.internet.grpc.encoding; 3 | option go_package = "github.com/v2fly/v2ray-core/v4/transport/internet/grpc"; 4 | 5 | message Config { 6 | string host = 1; 7 | string service_name = 2; 8 | } -------------------------------------------------------------------------------- /transport/internet/grpc/encoding/encoding.go: -------------------------------------------------------------------------------- 1 | package encoding 2 | 3 | //go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen 4 | -------------------------------------------------------------------------------- /transport/internet/grpc/encoding/errors.generated.go: -------------------------------------------------------------------------------- 1 | package encoding 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /transport/internet/grpc/encoding/stream.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package v2ray.core.transport.internet.grpc.encoding; 3 | option go_package = "github.com/v2fly/v2ray-core/v4/transport/internet/grpc/encoding"; 4 | 5 | message Hunk { 6 | bytes data = 1; 7 | } 8 | 9 | service GunService { 10 | rpc Tun (stream Hunk) returns (stream Hunk); 11 | } 12 | -------------------------------------------------------------------------------- /transport/internet/grpc/errors.generated.go: -------------------------------------------------------------------------------- 1 | package grpc 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /transport/internet/grpc/grpc.go: -------------------------------------------------------------------------------- 1 | // +build !confonly 2 | 3 | package grpc 4 | 5 | //go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen 6 | -------------------------------------------------------------------------------- /transport/internet/headers/http/errors.generated.go: -------------------------------------------------------------------------------- 1 | package http 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /transport/internet/headers/http/linkedreadRequest.go: -------------------------------------------------------------------------------- 1 | package http 2 | 3 | import ( 4 | "bufio" 5 | "net/http" 6 | 7 | // required to use go:linkname 8 | _ "unsafe" 9 | ) 10 | 11 | //go:linkname readRequest net/http.readRequest 12 | func readRequest(b *bufio.Reader, deleteHostHeader bool) (req *http.Request, err error) 13 | -------------------------------------------------------------------------------- /transport/internet/headers/http/resp.go: -------------------------------------------------------------------------------- 1 | package http 2 | 3 | var resp400 = &ResponseConfig{ 4 | Version: &Version{ 5 | Value: "1.1", 6 | }, 7 | Status: &Status{ 8 | Code: "400", 9 | Reason: "Bad Request", 10 | }, 11 | Header: []*Header{ 12 | { 13 | Name: "Connection", 14 | Value: []string{"close"}, 15 | }, 16 | { 17 | Name: "Cache-Control", 18 | Value: []string{"private"}, 19 | }, 20 | { 21 | Name: "Content-Length", 22 | Value: []string{"0"}, 23 | }, 24 | }, 25 | } 26 | 27 | var resp404 = &ResponseConfig{ 28 | Version: &Version{ 29 | Value: "1.1", 30 | }, 31 | Status: &Status{ 32 | Code: "404", 33 | Reason: "Not Found", 34 | }, 35 | Header: []*Header{ 36 | { 37 | Name: "Connection", 38 | Value: []string{"close"}, 39 | }, 40 | { 41 | Name: "Cache-Control", 42 | Value: []string{"private"}, 43 | }, 44 | { 45 | Name: "Content-Length", 46 | Value: []string{"0"}, 47 | }, 48 | }, 49 | } 50 | -------------------------------------------------------------------------------- /transport/internet/headers/noop/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.transport.internet.headers.noop; 4 | option csharp_namespace = "V2Ray.Core.Transport.Internet.Headers.Noop"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/transport/internet/headers/noop"; 6 | option java_package = "com.v2ray.core.transport.internet.headers.noop"; 7 | option java_multiple_files = true; 8 | 9 | message Config {} 10 | 11 | message ConnectionConfig {} 12 | -------------------------------------------------------------------------------- /transport/internet/headers/noop/noop.go: -------------------------------------------------------------------------------- 1 | package noop 2 | 3 | import ( 4 | "context" 5 | "net" 6 | 7 | "github.com/v2fly/v2ray-core/v4/common" 8 | ) 9 | 10 | type Header struct{} 11 | 12 | func (Header) Size() int32 { 13 | return 0 14 | } 15 | 16 | // Serialize implements PacketHeader. 17 | func (Header) Serialize([]byte) {} 18 | 19 | func NewHeader(context.Context, interface{}) (interface{}, error) { 20 | return Header{}, nil 21 | } 22 | 23 | type ConnectionHeader struct{} 24 | 25 | func (ConnectionHeader) Client(conn net.Conn) net.Conn { 26 | return conn 27 | } 28 | 29 | func (ConnectionHeader) Server(conn net.Conn) net.Conn { 30 | return conn 31 | } 32 | 33 | func NewConnectionHeader(context.Context, interface{}) (interface{}, error) { 34 | return ConnectionHeader{}, nil 35 | } 36 | 37 | func init() { 38 | common.Must(common.RegisterConfig((*Config)(nil), NewHeader)) 39 | common.Must(common.RegisterConfig((*ConnectionConfig)(nil), NewConnectionHeader)) 40 | } 41 | -------------------------------------------------------------------------------- /transport/internet/headers/srtp/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.transport.internet.headers.srtp; 4 | option csharp_namespace = "V2Ray.Core.Transport.Internet.Headers.Srtp"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/transport/internet/headers/srtp"; 6 | option java_package = "com.v2ray.core.transport.internet.headers.srtp"; 7 | option java_multiple_files = true; 8 | 9 | message Config { 10 | uint32 version = 1; 11 | bool padding = 2; 12 | bool extension = 3; 13 | uint32 csrc_count = 4; 14 | bool marker = 5; 15 | uint32 payload_type = 6; 16 | } 17 | -------------------------------------------------------------------------------- /transport/internet/headers/srtp/srtp.go: -------------------------------------------------------------------------------- 1 | package srtp 2 | 3 | import ( 4 | "context" 5 | "encoding/binary" 6 | 7 | "github.com/v2fly/v2ray-core/v4/common" 8 | "github.com/v2fly/v2ray-core/v4/common/dice" 9 | ) 10 | 11 | type SRTP struct { 12 | header uint16 13 | number uint16 14 | } 15 | 16 | func (*SRTP) Size() int32 { 17 | return 4 18 | } 19 | 20 | // Serialize implements PacketHeader. 21 | func (s *SRTP) Serialize(b []byte) { 22 | s.number++ 23 | binary.BigEndian.PutUint16(b, s.header) 24 | binary.BigEndian.PutUint16(b[2:], s.number) 25 | } 26 | 27 | // New returns a new SRTP instance based on the given config. 28 | func New(ctx context.Context, config interface{}) (interface{}, error) { 29 | return &SRTP{ 30 | header: 0xB5E8, 31 | number: dice.RollUint16(), 32 | }, nil 33 | } 34 | 35 | func init() { 36 | common.Must(common.RegisterConfig((*Config)(nil), New)) 37 | } 38 | -------------------------------------------------------------------------------- /transport/internet/headers/srtp/srtp_test.go: -------------------------------------------------------------------------------- 1 | package srtp_test 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | "github.com/v2fly/v2ray-core/v4/common" 8 | "github.com/v2fly/v2ray-core/v4/common/buf" 9 | . "github.com/v2fly/v2ray-core/v4/transport/internet/headers/srtp" 10 | ) 11 | 12 | func TestSRTPWrite(t *testing.T) { 13 | content := []byte{'a', 'b', 'c', 'd', 'e', 'f', 'g'} 14 | srtpRaw, err := New(context.Background(), &Config{}) 15 | common.Must(err) 16 | 17 | srtp := srtpRaw.(*SRTP) 18 | 19 | payload := buf.New() 20 | srtp.Serialize(payload.Extend(srtp.Size())) 21 | payload.Write(content) 22 | 23 | expectedLen := int32(len(content)) + srtp.Size() 24 | if payload.Len() != expectedLen { 25 | t.Error("expected ", expectedLen, " of bytes, but got ", payload.Len()) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /transport/internet/headers/tls/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.transport.internet.headers.tls; 4 | option csharp_namespace = "V2Ray.Core.Transport.Internet.Headers.Tls"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/transport/internet/headers/tls"; 6 | option java_package = "com.v2ray.core.transport.internet.headers.tls"; 7 | option java_multiple_files = true; 8 | 9 | message PacketConfig {} 10 | -------------------------------------------------------------------------------- /transport/internet/headers/tls/dtls_test.go: -------------------------------------------------------------------------------- 1 | package tls_test 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | "github.com/v2fly/v2ray-core/v4/common" 8 | "github.com/v2fly/v2ray-core/v4/common/buf" 9 | . "github.com/v2fly/v2ray-core/v4/transport/internet/headers/tls" 10 | ) 11 | 12 | func TestDTLSWrite(t *testing.T) { 13 | content := []byte{'a', 'b', 'c', 'd', 'e', 'f', 'g'} 14 | dtlsRaw, err := New(context.Background(), &PacketConfig{}) 15 | common.Must(err) 16 | 17 | dtls := dtlsRaw.(*DTLS) 18 | 19 | payload := buf.New() 20 | dtls.Serialize(payload.Extend(dtls.Size())) 21 | payload.Write(content) 22 | 23 | if payload.Len() != int32(len(content))+dtls.Size() { 24 | t.Error("payload len: ", payload.Len(), " want ", int32(len(content))+dtls.Size()) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /transport/internet/headers/utp/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.transport.internet.headers.utp; 4 | option csharp_namespace = "V2Ray.Core.Transport.Internet.Headers.Utp"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/transport/internet/headers/utp"; 6 | option java_package = "com.v2ray.core.transport.internet.headers.utp"; 7 | option java_multiple_files = true; 8 | 9 | message Config { 10 | uint32 version = 1; 11 | } 12 | -------------------------------------------------------------------------------- /transport/internet/headers/utp/utp.go: -------------------------------------------------------------------------------- 1 | package utp 2 | 3 | import ( 4 | "context" 5 | "encoding/binary" 6 | 7 | "github.com/v2fly/v2ray-core/v4/common" 8 | "github.com/v2fly/v2ray-core/v4/common/dice" 9 | ) 10 | 11 | type UTP struct { 12 | header byte 13 | extension byte 14 | connectionID uint16 15 | } 16 | 17 | func (*UTP) Size() int32 { 18 | return 4 19 | } 20 | 21 | // Serialize implements PacketHeader. 22 | func (u *UTP) Serialize(b []byte) { 23 | binary.BigEndian.PutUint16(b, u.connectionID) 24 | b[2] = u.header 25 | b[3] = u.extension 26 | } 27 | 28 | // New creates a new UTP header for the given config. 29 | func New(ctx context.Context, config interface{}) (interface{}, error) { 30 | return &UTP{ 31 | header: 1, 32 | extension: 0, 33 | connectionID: dice.RollUint16(), 34 | }, nil 35 | } 36 | 37 | func init() { 38 | common.Must(common.RegisterConfig((*Config)(nil), New)) 39 | } 40 | -------------------------------------------------------------------------------- /transport/internet/headers/utp/utp_test.go: -------------------------------------------------------------------------------- 1 | package utp_test 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | "github.com/v2fly/v2ray-core/v4/common" 8 | "github.com/v2fly/v2ray-core/v4/common/buf" 9 | . "github.com/v2fly/v2ray-core/v4/transport/internet/headers/utp" 10 | ) 11 | 12 | func TestUTPWrite(t *testing.T) { 13 | content := []byte{'a', 'b', 'c', 'd', 'e', 'f', 'g'} 14 | utpRaw, err := New(context.Background(), &Config{}) 15 | common.Must(err) 16 | 17 | utp := utpRaw.(*UTP) 18 | 19 | payload := buf.New() 20 | utp.Serialize(payload.Extend(utp.Size())) 21 | payload.Write(content) 22 | 23 | if payload.Len() != int32(len(content))+utp.Size() { 24 | t.Error("unexpected payload length: ", payload.Len()) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /transport/internet/headers/wechat/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.transport.internet.headers.wechat; 4 | option csharp_namespace = "V2Ray.Core.Transport.Internet.Headers.Wechat"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/transport/internet/headers/wechat"; 6 | option java_package = "com.v2ray.core.transport.internet.headers.wechat"; 7 | option java_multiple_files = true; 8 | 9 | message VideoConfig {} 10 | -------------------------------------------------------------------------------- /transport/internet/headers/wechat/wechat.go: -------------------------------------------------------------------------------- 1 | package wechat 2 | 3 | import ( 4 | "context" 5 | "encoding/binary" 6 | 7 | "github.com/v2fly/v2ray-core/v4/common" 8 | "github.com/v2fly/v2ray-core/v4/common/dice" 9 | ) 10 | 11 | type VideoChat struct { 12 | sn uint32 13 | } 14 | 15 | func (vc *VideoChat) Size() int32 { 16 | return 13 17 | } 18 | 19 | // Serialize implements PacketHeader. 20 | func (vc *VideoChat) Serialize(b []byte) { 21 | vc.sn++ 22 | b[0] = 0xa1 23 | b[1] = 0x08 24 | binary.BigEndian.PutUint32(b[2:], vc.sn) // b[2:6] 25 | b[6] = 0x00 26 | b[7] = 0x10 27 | b[8] = 0x11 28 | b[9] = 0x18 29 | b[10] = 0x30 30 | b[11] = 0x22 31 | b[12] = 0x30 32 | } 33 | 34 | // NewVideoChat returns a new VideoChat instance based on given config. 35 | func NewVideoChat(ctx context.Context, config interface{}) (interface{}, error) { 36 | return &VideoChat{ 37 | sn: uint32(dice.RollUint16()), 38 | }, nil 39 | } 40 | 41 | func init() { 42 | common.Must(common.RegisterConfig((*VideoConfig)(nil), NewVideoChat)) 43 | } 44 | -------------------------------------------------------------------------------- /transport/internet/headers/wechat/wechat_test.go: -------------------------------------------------------------------------------- 1 | package wechat_test 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | "github.com/v2fly/v2ray-core/v4/common" 8 | "github.com/v2fly/v2ray-core/v4/common/buf" 9 | . "github.com/v2fly/v2ray-core/v4/transport/internet/headers/wechat" 10 | ) 11 | 12 | func TestUTPWrite(t *testing.T) { 13 | videoRaw, err := NewVideoChat(context.Background(), &VideoConfig{}) 14 | common.Must(err) 15 | 16 | video := videoRaw.(*VideoChat) 17 | 18 | payload := buf.New() 19 | video.Serialize(payload.Extend(video.Size())) 20 | 21 | if payload.Len() != video.Size() { 22 | t.Error("expected payload size ", video.Size(), " but got ", payload.Len()) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /transport/internet/headers/wireguard/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.transport.internet.headers.wireguard; 4 | option csharp_namespace = "V2Ray.Core.Transport.Internet.Headers.Wireguard"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/transport/internet/headers/wireguard"; 6 | option java_package = "com.v2ray.core.transport.internet.headers.wireguard"; 7 | option java_multiple_files = true; 8 | 9 | message WireguardConfig {} 10 | -------------------------------------------------------------------------------- /transport/internet/headers/wireguard/wireguard.go: -------------------------------------------------------------------------------- 1 | package wireguard 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/v2fly/v2ray-core/v4/common" 7 | ) 8 | 9 | type Wireguard struct{} 10 | 11 | func (Wireguard) Size() int32 { 12 | return 4 13 | } 14 | 15 | // Serialize implements PacketHeader. 16 | func (Wireguard) Serialize(b []byte) { 17 | b[0] = 0x04 18 | b[1] = 0x00 19 | b[2] = 0x00 20 | b[3] = 0x00 21 | } 22 | 23 | // NewWireguard returns a new VideoChat instance based on given config. 24 | func NewWireguard(ctx context.Context, config interface{}) (interface{}, error) { 25 | return Wireguard{}, nil 26 | } 27 | 28 | func init() { 29 | common.Must(common.RegisterConfig((*WireguardConfig)(nil), NewWireguard)) 30 | } 31 | -------------------------------------------------------------------------------- /transport/internet/http/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.transport.internet.http; 4 | option csharp_namespace = "V2Ray.Core.Transport.Internet.Http"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/transport/internet/http"; 6 | option java_package = "com.v2ray.core.transport.internet.http"; 7 | option java_multiple_files = true; 8 | 9 | import "transport/internet/headers/http/config.proto"; 10 | 11 | message Config { 12 | repeated string host = 1; 13 | string path = 2; 14 | string method = 3; 15 | repeated v2ray.core.transport.internet.headers.http.Header header = 4; 16 | } 17 | -------------------------------------------------------------------------------- /transport/internet/http/errors.generated.go: -------------------------------------------------------------------------------- 1 | package http 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /transport/internet/http/http.go: -------------------------------------------------------------------------------- 1 | package http 2 | 3 | //go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen 4 | -------------------------------------------------------------------------------- /transport/internet/internet.go: -------------------------------------------------------------------------------- 1 | package internet 2 | 3 | //go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen 4 | -------------------------------------------------------------------------------- /transport/internet/kcp/connection_test.go: -------------------------------------------------------------------------------- 1 | package kcp_test 2 | 3 | import ( 4 | "io" 5 | "testing" 6 | "time" 7 | 8 | "github.com/v2fly/v2ray-core/v4/common/buf" 9 | . "github.com/v2fly/v2ray-core/v4/transport/internet/kcp" 10 | ) 11 | 12 | type NoOpCloser int 13 | 14 | func (NoOpCloser) Close() error { 15 | return nil 16 | } 17 | 18 | func TestConnectionReadTimeout(t *testing.T) { 19 | conn := NewConnection(ConnMetadata{Conversation: 1}, &KCPPacketWriter{ 20 | Writer: buf.DiscardBytes, 21 | }, NoOpCloser(0), &Config{}) 22 | conn.SetReadDeadline(time.Now().Add(time.Second)) 23 | 24 | b := make([]byte, 1024) 25 | nBytes, err := conn.Read(b) 26 | if nBytes != 0 || err == nil { 27 | t.Error("unexpected read: ", nBytes, err) 28 | } 29 | 30 | conn.Terminate() 31 | } 32 | 33 | func TestConnectionInterface(t *testing.T) { 34 | _ = (io.Writer)(new(Connection)) 35 | _ = (io.Reader)(new(Connection)) 36 | _ = (buf.Reader)(new(Connection)) 37 | _ = (buf.Writer)(new(Connection)) 38 | } 39 | -------------------------------------------------------------------------------- /transport/internet/kcp/crypt_test.go: -------------------------------------------------------------------------------- 1 | package kcp_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/google/go-cmp/cmp" 7 | 8 | "github.com/v2fly/v2ray-core/v4/common" 9 | . "github.com/v2fly/v2ray-core/v4/transport/internet/kcp" 10 | ) 11 | 12 | func TestSimpleAuthenticator(t *testing.T) { 13 | cache := make([]byte, 512) 14 | 15 | payload := []byte{'a', 'b', 'c', 'd', 'e', 'f', 'g'} 16 | 17 | auth := NewSimpleAuthenticator() 18 | b := auth.Seal(cache[:0], nil, payload, nil) 19 | c, err := auth.Open(cache[:0], nil, b, nil) 20 | common.Must(err) 21 | if r := cmp.Diff(c, payload); r != "" { 22 | t.Error(r) 23 | } 24 | } 25 | 26 | func TestSimpleAuthenticator2(t *testing.T) { 27 | cache := make([]byte, 512) 28 | 29 | payload := []byte{'a', 'b'} 30 | 31 | auth := NewSimpleAuthenticator() 32 | b := auth.Seal(cache[:0], nil, payload, nil) 33 | c, err := auth.Open(cache[:0], nil, b, nil) 34 | common.Must(err) 35 | if r := cmp.Diff(c, payload); r != "" { 36 | t.Error(r) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /transport/internet/kcp/cryptreal.go: -------------------------------------------------------------------------------- 1 | package kcp 2 | 3 | import ( 4 | "crypto/aes" 5 | "crypto/cipher" 6 | "crypto/sha256" 7 | 8 | "github.com/v2fly/v2ray-core/v4/common" 9 | ) 10 | 11 | func NewAEADAESGCMBasedOnSeed(seed string) cipher.AEAD { 12 | hashedSeed := sha256.Sum256([]byte(seed)) 13 | aesBlock := common.Must2(aes.NewCipher(hashedSeed[:16])).(cipher.Block) 14 | return common.Must2(cipher.NewGCM(aesBlock)).(cipher.AEAD) 15 | } 16 | -------------------------------------------------------------------------------- /transport/internet/kcp/errors.generated.go: -------------------------------------------------------------------------------- 1 | package kcp 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /transport/internet/kcp/io_test.go: -------------------------------------------------------------------------------- 1 | package kcp_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/v2fly/v2ray-core/v4/transport/internet/kcp" 7 | ) 8 | 9 | func TestKCPPacketReader(t *testing.T) { 10 | reader := KCPPacketReader{ 11 | Security: &SimpleAuthenticator{}, 12 | } 13 | 14 | testCases := []struct { 15 | Input []byte 16 | Output []Segment 17 | }{ 18 | { 19 | Input: []byte{}, 20 | Output: nil, 21 | }, 22 | { 23 | Input: []byte{1}, 24 | Output: nil, 25 | }, 26 | } 27 | 28 | for _, testCase := range testCases { 29 | seg := reader.Read(testCase.Input) 30 | if testCase.Output == nil && seg != nil { 31 | t.Errorf("Expect nothing returned, but actually %v", seg) 32 | } else if testCase.Output != nil && seg == nil { 33 | t.Errorf("Expect some output, but got nil") 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /transport/internet/kcp/kcp.go: -------------------------------------------------------------------------------- 1 | // Package kcp - A Fast and Reliable ARQ Protocol 2 | // 3 | // Acknowledgement: 4 | // skywind3000@github for inventing the KCP protocol 5 | // xtaci@github for translating to Golang 6 | package kcp 7 | 8 | //go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen 9 | -------------------------------------------------------------------------------- /transport/internet/kcp/xor.go: -------------------------------------------------------------------------------- 1 | // +build !amd64 2 | 3 | package kcp 4 | 5 | // xorfwd performs XOR forwards in words, x[i] ^= x[i-4], i from 0 to len 6 | func xorfwd(x []byte) { 7 | for i := 4; i < len(x); i++ { 8 | x[i] ^= x[i-4] 9 | } 10 | } 11 | 12 | // xorbkd performs XOR backwords in words, x[i] ^= x[i-4], i from len to 0 13 | func xorbkd(x []byte) { 14 | for i := len(x) - 1; i >= 4; i-- { 15 | x[i] ^= x[i-4] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /transport/internet/kcp/xor_amd64.go: -------------------------------------------------------------------------------- 1 | package kcp 2 | 3 | //go:noescape 4 | func xorfwd(x []byte) 5 | 6 | //go:noescape 7 | func xorbkd(x []byte) 8 | -------------------------------------------------------------------------------- /transport/internet/kcp/xor_amd64.s: -------------------------------------------------------------------------------- 1 | #include "textflag.h" 2 | 3 | // func xorfwd(x []byte) 4 | TEXT ·xorfwd(SB),NOSPLIT,$0 5 | MOVQ x+0(FP), SI // x[i] 6 | MOVQ x_len+8(FP), CX // x.len 7 | MOVQ x+0(FP), DI 8 | ADDQ $4, DI // x[i+4] 9 | SUBQ $4, CX 10 | xorfwdloop: 11 | MOVL (SI), AX 12 | XORL AX, (DI) 13 | ADDQ $4, SI 14 | ADDQ $4, DI 15 | SUBQ $4, CX 16 | 17 | CMPL CX, $0 18 | JE xorfwddone 19 | 20 | JMP xorfwdloop 21 | xorfwddone: 22 | RET 23 | 24 | // func xorbkd(x []byte) 25 | TEXT ·xorbkd(SB),NOSPLIT,$0 26 | MOVQ x+0(FP), SI 27 | MOVQ x_len+8(FP), CX // x.len 28 | MOVQ x+0(FP), DI 29 | ADDQ CX, SI // x[-8] 30 | SUBQ $8, SI 31 | ADDQ CX, DI // x[-4] 32 | SUBQ $4, DI 33 | SUBQ $4, CX 34 | xorbkdloop: 35 | MOVL (SI), AX 36 | XORL AX, (DI) 37 | SUBQ $4, SI 38 | SUBQ $4, DI 39 | SUBQ $4, CX 40 | 41 | CMPL CX, $0 42 | JE xorbkddone 43 | 44 | JMP xorbkdloop 45 | 46 | xorbkddone: 47 | RET 48 | -------------------------------------------------------------------------------- /transport/internet/quic/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.transport.internet.quic; 4 | option csharp_namespace = "V2Ray.Core.Transport.Internet.Quic"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/transport/internet/quic"; 6 | option java_package = "com.v2ray.core.transport.internet.quic"; 7 | option java_multiple_files = true; 8 | 9 | import "common/serial/typed_message.proto"; 10 | import "common/protocol/headers.proto"; 11 | 12 | message Config { 13 | string key = 1; 14 | v2ray.core.common.protocol.SecurityConfig security = 2; 15 | v2ray.core.common.serial.TypedMessage header = 3; 16 | } 17 | -------------------------------------------------------------------------------- /transport/internet/quic/errors.generated.go: -------------------------------------------------------------------------------- 1 | package quic 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /transport/internet/quic/pool.go: -------------------------------------------------------------------------------- 1 | // +build !confonly 2 | 3 | package quic 4 | 5 | import ( 6 | "sync" 7 | 8 | "github.com/v2fly/v2ray-core/v4/common/bytespool" 9 | ) 10 | 11 | var pool *sync.Pool 12 | 13 | func init() { 14 | pool = bytespool.GetPool(2048) 15 | } 16 | 17 | func getBuffer() []byte { 18 | return pool.Get().([]byte) 19 | } 20 | 21 | func putBuffer(p []byte) { 22 | pool.Put(p) // nolint: staticcheck 23 | } 24 | -------------------------------------------------------------------------------- /transport/internet/quic/quic.go: -------------------------------------------------------------------------------- 1 | // +build !confonly 2 | 3 | package quic 4 | 5 | import ( 6 | "github.com/v2fly/v2ray-core/v4/common" 7 | "github.com/v2fly/v2ray-core/v4/transport/internet" 8 | ) 9 | 10 | //go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen 11 | 12 | // Here is some modification needs to be done before update quic vendor. 13 | // * use bytespool in buffer_pool.go 14 | // * set MaxReceivePacketSize to 1452 - 32 (16 bytes auth, 16 bytes head) 15 | // 16 | // 17 | 18 | const ( 19 | protocolName = "quic" 20 | internalDomain = "quic.internal.v2fly.org" 21 | ) 22 | 23 | func init() { 24 | common.Must(internet.RegisterProtocolConfigCreator(protocolName, func() interface{} { 25 | return new(Config) 26 | })) 27 | } 28 | -------------------------------------------------------------------------------- /transport/internet/sockopt.go: -------------------------------------------------------------------------------- 1 | package internet 2 | 3 | func isTCPSocket(network string) bool { 4 | switch network { 5 | case "tcp", "tcp4", "tcp6": 6 | return true 7 | default: 8 | return false 9 | } 10 | } 11 | 12 | func isUDPSocket(network string) bool { 13 | switch network { 14 | case "udp", "udp4", "udp6": 15 | return true 16 | default: 17 | return false 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /transport/internet/sockopt_other.go: -------------------------------------------------------------------------------- 1 | // +build js dragonfly netbsd openbsd solaris 2 | 3 | package internet 4 | 5 | func applyOutboundSocketOptions(network string, address string, fd uintptr, config *SocketConfig) error { 6 | return nil 7 | } 8 | 9 | func applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig) error { 10 | return nil 11 | } 12 | 13 | func bindAddr(fd uintptr, ip []byte, port uint32) error { 14 | return nil 15 | } 16 | 17 | func setReuseAddr(fd uintptr) error { 18 | return nil 19 | } 20 | 21 | func setReusePort(fd uintptr) error { 22 | return nil 23 | } 24 | -------------------------------------------------------------------------------- /transport/internet/system_dns_android.go: -------------------------------------------------------------------------------- 1 | // +build android 2 | 3 | package internet 4 | 5 | import ( 6 | "context" 7 | "net" 8 | ) 9 | 10 | const SystemDNS = "8.8.8.8:53" 11 | 12 | /* DNSResolverFunc 13 | This is a temporary API and is subject to removal at any time. 14 | */ 15 | type DNSResolverFunc func() *net.Resolver 16 | 17 | /* NewDNSResolver 18 | This is a temporary API and is subject to removal at any time. 19 | */ 20 | var NewDNSResolver DNSResolverFunc = func() *net.Resolver { 21 | return &net.Resolver{ 22 | PreferGo: true, 23 | Dial: func(ctx context.Context, network, _ string) (net.Conn, error) { 24 | var dialer net.Dialer 25 | return dialer.DialContext(ctx, network, SystemDNS) 26 | }, 27 | } 28 | } 29 | 30 | func init() { 31 | net.DefaultResolver = NewDNSResolver() 32 | } 33 | -------------------------------------------------------------------------------- /transport/internet/system_dns_android_test.go: -------------------------------------------------------------------------------- 1 | // +build android 2 | 3 | package internet 4 | 5 | import ( 6 | "context" 7 | "testing" 8 | ) 9 | 10 | func TestDNSResolver(t *testing.T) { 11 | resolver := NewDNSResolver() 12 | if ips, err := resolver.LookupIP(context.Background(), "ip", "www.google.com"); err != nil { 13 | t.Errorf("failed to lookupIP, %v, %v", ips, err) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /transport/internet/system_listener_test.go: -------------------------------------------------------------------------------- 1 | package internet_test 2 | 3 | import ( 4 | "context" 5 | "net" 6 | "testing" 7 | 8 | "github.com/v2fly/v2ray-core/v4/common" 9 | "github.com/v2fly/v2ray-core/v4/transport/internet" 10 | ) 11 | 12 | func TestRegisterListenerController(t *testing.T) { 13 | var gotFd uintptr 14 | 15 | common.Must(internet.RegisterListenerController(func(network string, addr string, fd uintptr) error { 16 | gotFd = fd 17 | return nil 18 | })) 19 | 20 | conn, err := internet.ListenSystemPacket(context.Background(), &net.UDPAddr{ 21 | IP: net.IPv4zero, 22 | }, nil) 23 | common.Must(err) 24 | common.Must(conn.Close()) 25 | 26 | if gotFd == 0 { 27 | t.Error("expected none-zero fd, but actually 0") 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /transport/internet/tagged/tagged.go: -------------------------------------------------------------------------------- 1 | package tagged 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/v2fly/v2ray-core/v4/common/net" 7 | ) 8 | 9 | type DialFunc func(ctx context.Context, dest net.Destination, tag string) (net.Conn, error) 10 | 11 | var Dialer DialFunc 12 | -------------------------------------------------------------------------------- /transport/internet/tagged/taggedimpl/errors.generated.go: -------------------------------------------------------------------------------- 1 | package taggedimpl 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /transport/internet/tagged/taggedimpl/taggedimpl.go: -------------------------------------------------------------------------------- 1 | package taggedimpl 2 | 3 | //go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen 4 | -------------------------------------------------------------------------------- /transport/internet/tcp/config.go: -------------------------------------------------------------------------------- 1 | // +build !confonly 2 | 3 | package tcp 4 | 5 | import ( 6 | "github.com/v2fly/v2ray-core/v4/common" 7 | "github.com/v2fly/v2ray-core/v4/transport/internet" 8 | ) 9 | 10 | const protocolName = "tcp" 11 | 12 | func init() { 13 | common.Must(internet.RegisterProtocolConfigCreator(protocolName, func() interface{} { 14 | return new(Config) 15 | })) 16 | } 17 | -------------------------------------------------------------------------------- /transport/internet/tcp/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.transport.internet.tcp; 4 | option csharp_namespace = "V2Ray.Core.Transport.Internet.Tcp"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/transport/internet/tcp"; 6 | option java_package = "com.v2ray.core.transport.internet.tcp"; 7 | option java_multiple_files = true; 8 | 9 | import "common/serial/typed_message.proto"; 10 | 11 | message Config { 12 | reserved 1; 13 | v2ray.core.common.serial.TypedMessage header_settings = 2; 14 | bool accept_proxy_protocol = 3; 15 | } 16 | -------------------------------------------------------------------------------- /transport/internet/tcp/errors.generated.go: -------------------------------------------------------------------------------- 1 | package tcp 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /transport/internet/tcp/sockopt_freebsd.go: -------------------------------------------------------------------------------- 1 | // +build freebsd 2 | // +build !confonly 3 | 4 | package tcp 5 | 6 | import ( 7 | "github.com/v2fly/v2ray-core/v4/common/net" 8 | "github.com/v2fly/v2ray-core/v4/transport/internet" 9 | ) 10 | 11 | // GetOriginalDestination from tcp conn 12 | func GetOriginalDestination(conn internet.Connection) (net.Destination, error) { 13 | la := conn.LocalAddr() 14 | ra := conn.RemoteAddr() 15 | ip, port, err := internet.OriginalDst(la, ra) 16 | if err != nil { 17 | return net.Destination{}, newError("failed to get destination").Base(err) 18 | } 19 | dest := net.TCPDestination(net.IPAddress(ip), net.Port(port)) 20 | if !dest.IsValid() { 21 | return net.Destination{}, newError("failed to parse destination.") 22 | } 23 | return dest, nil 24 | } 25 | -------------------------------------------------------------------------------- /transport/internet/tcp/sockopt_linux_test.go: -------------------------------------------------------------------------------- 1 | // +build linux 2 | 3 | package tcp_test 4 | 5 | import ( 6 | "context" 7 | "strings" 8 | "testing" 9 | 10 | "github.com/v2fly/v2ray-core/v4/common" 11 | "github.com/v2fly/v2ray-core/v4/testing/servers/tcp" 12 | "github.com/v2fly/v2ray-core/v4/transport/internet" 13 | . "github.com/v2fly/v2ray-core/v4/transport/internet/tcp" 14 | ) 15 | 16 | func TestGetOriginalDestination(t *testing.T) { 17 | tcpServer := tcp.Server{} 18 | dest, err := tcpServer.Start() 19 | common.Must(err) 20 | defer tcpServer.Close() 21 | 22 | config, err := internet.ToMemoryStreamConfig(nil) 23 | common.Must(err) 24 | conn, err := Dial(context.Background(), dest, config) 25 | common.Must(err) 26 | defer conn.Close() 27 | 28 | originalDest, err := GetOriginalDestination(conn) 29 | if !(dest == originalDest || strings.Contains(err.Error(), "failed to call getsockopt")) { 30 | t.Error("unexpected state") 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /transport/internet/tcp/sockopt_other.go: -------------------------------------------------------------------------------- 1 | // +build !linux,!freebsd 2 | // +build !confonly 3 | 4 | package tcp 5 | 6 | import ( 7 | "github.com/v2fly/v2ray-core/v4/common/net" 8 | "github.com/v2fly/v2ray-core/v4/transport/internet" 9 | ) 10 | 11 | func GetOriginalDestination(conn internet.Connection) (net.Destination, error) { 12 | return net.Destination{}, nil 13 | } 14 | -------------------------------------------------------------------------------- /transport/internet/tcp/tcp.go: -------------------------------------------------------------------------------- 1 | package tcp 2 | 3 | //go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen 4 | -------------------------------------------------------------------------------- /transport/internet/tls/config_windows.go: -------------------------------------------------------------------------------- 1 | // +build windows 2 | // +build !confonly 3 | 4 | package tls 5 | 6 | import "crypto/x509" 7 | 8 | func (c *Config) getCertPool() (*x509.CertPool, error) { 9 | if c.DisableSystemRoot { 10 | return c.loadSelfCertPool() 11 | } 12 | 13 | return nil, nil 14 | } 15 | -------------------------------------------------------------------------------- /transport/internet/tls/errors.generated.go: -------------------------------------------------------------------------------- 1 | package tls 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /transport/internet/tls/pin.go: -------------------------------------------------------------------------------- 1 | package tls 2 | 3 | import ( 4 | "crypto/sha256" 5 | "encoding/base64" 6 | "encoding/pem" 7 | ) 8 | 9 | func CalculatePEMCertChainSHA256Hash(certContent []byte) string { 10 | var certChain [][]byte 11 | for { 12 | block, remain := pem.Decode(certContent) 13 | if block == nil { 14 | break 15 | } 16 | certChain = append(certChain, block.Bytes) 17 | certContent = remain 18 | } 19 | certChainHash := GenerateCertChainHash(certChain) 20 | certChainHashB64 := base64.StdEncoding.EncodeToString(certChainHash) 21 | return certChainHashB64 22 | } 23 | 24 | func GenerateCertChainHash(rawCerts [][]byte) []byte { 25 | var hashValue []byte 26 | for _, certValue := range rawCerts { 27 | out := sha256.Sum256(certValue) 28 | if hashValue == nil { 29 | hashValue = out[:] 30 | } else { 31 | newHashValue := sha256.Sum256(append(hashValue, out[:]...)) 32 | hashValue = newHashValue[:] 33 | } 34 | } 35 | return hashValue 36 | } 37 | -------------------------------------------------------------------------------- /transport/internet/udp/config.go: -------------------------------------------------------------------------------- 1 | package udp 2 | 3 | import ( 4 | "github.com/v2fly/v2ray-core/v4/common" 5 | "github.com/v2fly/v2ray-core/v4/transport/internet" 6 | ) 7 | 8 | func init() { 9 | common.Must(internet.RegisterProtocolConfigCreator(protocolName, func() interface{} { 10 | return new(Config) 11 | })) 12 | } 13 | -------------------------------------------------------------------------------- /transport/internet/udp/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.transport.internet.udp; 4 | option csharp_namespace = "V2Ray.Core.Transport.Internet.Udp"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/transport/internet/udp"; 6 | option java_package = "com.v2ray.core.transport.internet.udp"; 7 | option java_multiple_files = true; 8 | 9 | message Config {} 10 | -------------------------------------------------------------------------------- /transport/internet/udp/dialer.go: -------------------------------------------------------------------------------- 1 | package udp 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/v2fly/v2ray-core/v4/common" 7 | "github.com/v2fly/v2ray-core/v4/common/net" 8 | "github.com/v2fly/v2ray-core/v4/transport/internet" 9 | ) 10 | 11 | func init() { 12 | common.Must(internet.RegisterTransportDialer(protocolName, 13 | func(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (internet.Connection, error) { 14 | var sockopt *internet.SocketConfig 15 | if streamSettings != nil { 16 | sockopt = streamSettings.SocketSettings 17 | } 18 | conn, err := internet.DialSystem(ctx, dest, sockopt) 19 | if err != nil { 20 | return nil, err 21 | } 22 | // TODO: handle dialer options 23 | return internet.Connection(conn), nil 24 | })) 25 | } 26 | -------------------------------------------------------------------------------- /transport/internet/udp/errors.generated.go: -------------------------------------------------------------------------------- 1 | package udp 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /transport/internet/udp/hub_other.go: -------------------------------------------------------------------------------- 1 | // +build !linux,!freebsd 2 | 3 | package udp 4 | 5 | import ( 6 | "github.com/v2fly/v2ray-core/v4/common/net" 7 | ) 8 | 9 | func RetrieveOriginalDest(oob []byte) net.Destination { 10 | return net.Destination{} 11 | } 12 | 13 | func ReadUDPMsg(conn *net.UDPConn, payload []byte, oob []byte) (int, int, int, *net.UDPAddr, error) { 14 | nBytes, addr, err := conn.ReadFromUDP(payload) 15 | return nBytes, 0, 0, addr, err 16 | } 17 | -------------------------------------------------------------------------------- /transport/internet/udp/udp.go: -------------------------------------------------------------------------------- 1 | package udp 2 | 3 | //go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen 4 | 5 | const protocolName = "udp" 6 | -------------------------------------------------------------------------------- /transport/internet/websocket/config.go: -------------------------------------------------------------------------------- 1 | // +build !confonly 2 | 3 | package websocket 4 | 5 | import ( 6 | "net/http" 7 | 8 | "github.com/v2fly/v2ray-core/v4/common" 9 | "github.com/v2fly/v2ray-core/v4/transport/internet" 10 | ) 11 | 12 | const protocolName = "websocket" 13 | 14 | func (c *Config) GetNormalizedPath() string { 15 | path := c.Path 16 | if path == "" { 17 | return "/" 18 | } 19 | if path[0] != '/' { 20 | return "/" + path 21 | } 22 | return path 23 | } 24 | 25 | func (c *Config) GetRequestHeader() http.Header { 26 | header := http.Header{} 27 | for _, h := range c.Header { 28 | header.Add(h.Key, h.Value) 29 | } 30 | return header 31 | } 32 | 33 | func init() { 34 | common.Must(internet.RegisterProtocolConfigCreator(protocolName, func() interface{} { 35 | return new(Config) 36 | })) 37 | } 38 | -------------------------------------------------------------------------------- /transport/internet/websocket/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.transport.internet.websocket; 4 | option csharp_namespace = "V2Ray.Core.Transport.Internet.Websocket"; 5 | option go_package = "github.com/v2fly/v2ray-core/v4/transport/internet/websocket"; 6 | option java_package = "com.v2ray.core.transport.internet.websocket"; 7 | option java_multiple_files = true; 8 | 9 | message Header { 10 | string key = 1; 11 | string value = 2; 12 | } 13 | 14 | message Config { 15 | reserved 1; 16 | 17 | // URL path to the WebSocket service. Empty value means root(/). 18 | string path = 2; 19 | 20 | repeated Header header = 3; 21 | 22 | bool accept_proxy_protocol = 4; 23 | 24 | int32 max_early_data = 5; 25 | 26 | bool use_browser_forwarding = 6; 27 | 28 | string early_data_header_name = 7; 29 | } 30 | -------------------------------------------------------------------------------- /transport/internet/websocket/errors.generated.go: -------------------------------------------------------------------------------- 1 | package websocket 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /transport/internet/websocket/ws.go: -------------------------------------------------------------------------------- 1 | /*Package websocket implements Websocket transport 2 | 3 | Websocket transport implements an HTTP(S) compliable, surveillance proof transport method with plausible deniability. 4 | */ 5 | package websocket 6 | 7 | //go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen 8 | -------------------------------------------------------------------------------- /transport/link.go: -------------------------------------------------------------------------------- 1 | package transport 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/buf" 4 | 5 | // Link is a utility for connecting between an inbound and an outbound proxy handler. 6 | type Link struct { 7 | Reader buf.Reader 8 | Writer buf.Writer 9 | } 10 | -------------------------------------------------------------------------------- /transport/pipe/reader.go: -------------------------------------------------------------------------------- 1 | package pipe 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/v2fly/v2ray-core/v4/common/buf" 7 | ) 8 | 9 | // Reader is a buf.Reader that reads content from a pipe. 10 | type Reader struct { 11 | pipe *pipe 12 | } 13 | 14 | // ReadMultiBuffer implements buf.Reader. 15 | func (r *Reader) ReadMultiBuffer() (buf.MultiBuffer, error) { 16 | return r.pipe.ReadMultiBuffer() 17 | } 18 | 19 | // ReadMultiBufferTimeout reads content from a pipe within the given duration, or returns buf.ErrTimeout otherwise. 20 | func (r *Reader) ReadMultiBufferTimeout(d time.Duration) (buf.MultiBuffer, error) { 21 | return r.pipe.ReadMultiBufferTimeout(d) 22 | } 23 | 24 | // Interrupt implements common.Interruptible. 25 | func (r *Reader) Interrupt() { 26 | r.pipe.Interrupt() 27 | } 28 | -------------------------------------------------------------------------------- /transport/pipe/writer.go: -------------------------------------------------------------------------------- 1 | package pipe 2 | 3 | import ( 4 | "github.com/v2fly/v2ray-core/v4/common/buf" 5 | ) 6 | 7 | // Writer is a buf.Writer that writes data into a pipe. 8 | type Writer struct { 9 | pipe *pipe 10 | } 11 | 12 | // WriteMultiBuffer implements buf.Writer. 13 | func (w *Writer) WriteMultiBuffer(mb buf.MultiBuffer) error { 14 | return w.pipe.WriteMultiBuffer(mb) 15 | } 16 | 17 | // Close implements io.Closer. After the pipe is closed, writing to the pipe will return io.ErrClosedPipe, while reading will return io.EOF. 18 | func (w *Writer) Close() error { 19 | return w.pipe.Close() 20 | } 21 | 22 | // Interrupt implements common.Interruptible. 23 | func (w *Writer) Interrupt() { 24 | w.pipe.Interrupt() 25 | } 26 | -------------------------------------------------------------------------------- /vnet/BUILD: -------------------------------------------------------------------------------- 1 | load("//infra/bazel:build.bzl", "foreign_go_binary") 2 | load("//infra/bazel:gpg.bzl", "gpg_sign") 3 | load("//infra/bazel:matrix.bzl", "SUPPORTED_MATRIX") 4 | load("//vnet:targets.bzl", "gen_targets") 5 | 6 | package(default_visibility=["//visibility:public"]) 7 | 8 | gen_targets(SUPPORTED_MATRIX) -------------------------------------------------------------------------------- /vnet/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "url": "https://v.rcauth.com", 3 | "key": "d9wjqzcq", 4 | "id": 2, 5 | "error_log_path": "/var/log/vnet-v2ray/error.log", 6 | "access_log_path": "/var/log/vnet-v2ray/access.log" 7 | } -------------------------------------------------------------------------------- /vnet/config.json.iovoi: -------------------------------------------------------------------------------- 1 | { 2 | "api_server":"http://panel.iovoi.xyz/", 3 | "key": "geptpxzp8zwdatc5", 4 | "node_id":16 5 | } -------------------------------------------------------------------------------- /vnet/config.json.vnetpanel: -------------------------------------------------------------------------------- 1 | { 2 | "api_server":"http://www.vnetpanel.com/", 3 | "key": "rgt4vrzxsepqbpfc", 4 | "node_id":7 5 | } -------------------------------------------------------------------------------- /vnet/errors.generated.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "github.com/v2fly/v2ray-core/v4/common/errors" 4 | 5 | type errPathObjHolder struct{} 6 | 7 | func newError(values ...interface{}) *errors.Error { 8 | return errors.New(values...).WithPathObj(errPathObjHolder{}) 9 | } 10 | -------------------------------------------------------------------------------- /vnet/install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # vnet-v2ray install script 4 | 5 | NODE_ID="" 6 | NODE_KEY="" 7 | HOST="" 8 | ACTION="install" 9 | 10 | while [[ $# -gt 0 ]]; do 11 | key=$1 12 | case $key in 13 | --node_id) 14 | NODE_ID="$2" 15 | shift 16 | ;; 17 | --node_key) 18 | NODE_KEY="$2" 19 | shift 20 | ;; 21 | --host) 22 | HOST="$2" 23 | shift 24 | ;; 25 | --action) 26 | ACTION="$2" 27 | shift 28 | ;; 29 | *) ;; 30 | esac 31 | done 32 | 33 | -------------------------------------------------------------------------------- /vnet/main_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func ExampleAuth() { 6 | fmt.Println("aaaa","bbb") 7 | // Output: 8 | 9 | } 10 | --------------------------------------------------------------------------------