diff --git a/CMakeLists.txt b/CMakeLists.txt index d9397a9..7f889a0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -221,6 +221,23 @@ set(PROJECT_SOURCES include/sys/windows/eventHandler.h src/dataStore/Group.cpp src/dataStore/ProxyEntity.cpp + include/configs/baseConfig.h + include/configs/common/DialFields.h + include/configs/common/TLS.h + include/configs/common/multiplex.h + include/configs/common/transport.h + include/configs/common/Outbound.h + include/configs/outbounds/socks.h + include/configs/outbounds/http.h + include/configs/outbounds/shadowsocks.h + include/configs/outbounds/vmess.h + include/configs/outbounds/trojan.h + include/configs/outbounds/hysteria.h + include/configs/outbounds/vless.h + include/configs/outbounds/tuic.h + include/configs/outbounds/hysteria2.h + include/configs/outbounds/anyTLS.h + include/configs/outbounds/ssh.h ) if (NOT APPLE AND Qt6_VERSION VERSION_GREATER_EQUAL 6.9.0) diff --git a/include/configs/baseConfig.h b/include/configs/baseConfig.h new file mode 100644 index 0000000..f153341 --- /dev/null +++ b/include/configs/baseConfig.h @@ -0,0 +1,38 @@ +#pragma once + +#include +#include +#include "include/global/ConfigItem.hpp" + +namespace Configs +{ + class baseConfig : public JsonStore + { + public: + virtual bool ParseFromLink(QString link); + + virtual bool ParseFromJson(QJsonObject object); + + virtual QString ExportToLink(); + + virtual QJsonObject ExportToJson(); + + virtual QJsonObject Build(); + }; + + class outboundMeta + { + public: + void ResolveDomainToIP(const std::function &onFinished); + + virtual QString DisplayAddress(); + + virtual QString DisplayName(); + + virtual QString DisplayType() { return {}; }; + + virtual QString DisplayTypeAndName(); + + virtual bool IsEndpoint() { return false; }; + }; +} diff --git a/include/configs/common/DialFields.h b/include/configs/common/DialFields.h new file mode 100644 index 0000000..b58d987 --- /dev/null +++ b/include/configs/common/DialFields.h @@ -0,0 +1,24 @@ +#pragma once +#include "include/configs/baseConfig.h" + +namespace Configs +{ + class DialFields : public baseConfig + { + public: + bool reuse_addr = false; + QString connect_timeout; + bool tcp_fast_open = false; + bool tcp_multi_path = false; + bool udp_fragment = false; + + DialFields() + { + _add(new configItem("reuse_addr", &reuse_addr, itemType::boolean)); + _add(new configItem("connect_timeout", &connect_timeout, itemType::string)); + _add(new configItem("tcp_fast_open", &tcp_fast_open, itemType::boolean)); + _add(new configItem("tcp_multi_path", &tcp_multi_path, itemType::boolean)); + _add(new configItem("udp_fragment", &udp_fragment, itemType::boolean)); + } + }; +} diff --git a/include/configs/common/Outbound.h b/include/configs/common/Outbound.h new file mode 100644 index 0000000..2f2e588 --- /dev/null +++ b/include/configs/common/Outbound.h @@ -0,0 +1,26 @@ +#pragma once +#include "include/configs/baseConfig.h" + +namespace Configs +{ + class OutboundCommons : public baseConfig + { + public: + QString type; + QString name; + int id = -1; + QString server; + int server_port = 0; + std::shared_ptr dialFields = std::make_shared(); + + OutboundCommons() + { + _add(new configItem("type", &type, string)); + _add(new configItem("name", &name, string)); + _add(new configItem("id", &id, integer)); + _add(new configItem("server", &server, string)); + _add(new configItem("server_port", &server_port, integer)); + _add(new configItem("dial_fields", dynamic_cast(dialFields.get()), jsonStore)); + } + }; +} diff --git a/include/configs/common/TLS.h b/include/configs/common/TLS.h new file mode 100644 index 0000000..bcdd5e0 --- /dev/null +++ b/include/configs/common/TLS.h @@ -0,0 +1,104 @@ +#pragma once +#include "include/configs/baseConfig.h" + +namespace Configs +{ + + inline QStringList tlsFingerprints = {"", "chrome", "firefox", "edge", "safari", "360", "qq", "ios", "android", "random", "randomized"}; + + class uTLS : public baseConfig + { + public: + bool enabled = false; + QString fingerPrint; + + uTLS() + { + _add(new configItem("enabled", &enabled, boolean)); + _add(new configItem("fingerprint", &fingerPrint, string)); + } + }; + + class ECH : public baseConfig + { + public: + bool enabled = false; + QStringList config; + QString config_path; + + ECH() + { + _add(new configItem("enabled", &enabled, boolean)); + _add(new configItem("config", &config, stringList)); + _add(new configItem("config_path", &config_path, string)); + } + }; + + class Reality : public baseConfig + { + public: + bool enabled = false; + QString public_key; + QString short_id; + + Reality() + { + _add(new configItem("enabled", &enabled, boolean)); + _add(new configItem("public_key", &public_key, string)); + _add(new configItem("short_id", &short_id, string)); + } + }; + + class TLS : public baseConfig + { + public: + bool enabled = false; + bool disable_sni = false; + QString server_name; + bool insecure = false; + QStringList alpn; + QString min_version; + QString max_version; + QStringList cipher_suites; + QStringList curve_preferences; + QString certificate; + QString certificate_path; + QStringList certificate_public_key_sha256; + QString client_certificate; + QString client_certificate_path; + QStringList client_key; + QString client_key_path; + bool fragment = false; + QString fragment_fallback_delay; + bool record_fragment = false; + std::shared_ptr ech = std::make_shared(); + std::shared_ptr utls = std::make_shared(); + std::shared_ptr reality = std::make_shared(); + + TLS() + { + _add(new configItem("enabled", &enabled, boolean)); + _add(new configItem("disable_sni", &disable_sni, boolean)); + _add(new configItem("server_name", &server_name, string)); + _add(new configItem("insecure", &insecure, boolean)); + _add(new configItem("alpn", &alpn, stringList)); + _add(new configItem("min_version", &min_version, string)); + _add(new configItem("max_version", &max_version, string)); + _add(new configItem("cipher_suites", &cipher_suites, stringList)); + _add(new configItem("curve_preferences", &curve_preferences, stringList)); + _add(new configItem("certificate", &certificate, string)); + _add(new configItem("certificate_path", &certificate_path, string)); + _add(new configItem("certificate_public_key_sha256", &certificate_public_key_sha256, stringList)); + _add(new configItem("client_certificate", &client_certificate, string)); + _add(new configItem("client_certificate_path", &client_certificate_path, string)); + _add(new configItem("client_key", &client_key, stringList)); + _add(new configItem("client_key_path", &client_key_path, string)); + _add(new configItem("fragment", &fragment, boolean)); + _add(new configItem("fragment_fallback_delay", &fragment_fallback_delay, string)); + _add(new configItem("record_fragment", &record_fragment, boolean)); + _add(new configItem("ech", dynamic_cast(ech.get()), jsonStore)); + _add(new configItem("utls", dynamic_cast(utls.get()), jsonStore)); + _add(new configItem("reality", dynamic_cast(reality.get()), jsonStore)); + } + }; +} diff --git a/include/configs/common/multiplex.h b/include/configs/common/multiplex.h new file mode 100644 index 0000000..9179081 --- /dev/null +++ b/include/configs/common/multiplex.h @@ -0,0 +1,45 @@ +#pragma once +#include "include/configs/baseConfig.h" + +namespace Configs +{ + inline QStringLists muxProtocols = {"smux", "yamux", "h2mux"}; + + class TcpBrutal : public baseConfig + { + public: + bool enabled = false; + int up_mbps = 0; + int down_mbps = 0; + + TcpBrutal() + { + _add(new configItem("enabled", &enabled, boolean)); + _add(new configItem("up_mbps", &up_mbps, integer)); + _add(new configItem("down_mbps", &down_mbps, integer)); + } + }; + + class Multiplex : public baseConfig + { + public: + bool enabled = false; + QString protocol; + int max_connections = 0; + int min_streams = 0; + int max_streams = 0; + bool padding = false; + std::shared_ptr brutal = std::make_shared(); + + Multiplex() + { + _add(new configItem("enabled", &enabled, boolean)); + _add(new configItem("protocol", &protocol, string)); + _add(new configItem("max_connections", &max_connections, integer)); + _add(new configItem("min_streams", &min_streams, integer)); + _add(new configItem("max_streams", &max_streams, integer)); + _add(new configItem("padding", &padding, boolean)); + _add(new configItem("brutal", dynamic_cast(brutal.get()), jsonStore)); + } + }; +} diff --git a/include/configs/common/transport.h b/include/configs/common/transport.h new file mode 100644 index 0000000..b26b676 --- /dev/null +++ b/include/configs/common/transport.h @@ -0,0 +1,40 @@ +#pragma once +#include "include/configs/baseConfig.h" + +namespace Configs +{ + class Transport : public baseConfig + { + public: + QString type; + + // HTTP + QString host; + QString path; + QString method; + QStringList headers; + QString idle_timeout; + QString ping_timeout; + + // Websocket + int max_early_data = 0; + QString early_data_header_name; + + // gRPC + QString service_name; + + Transport() + { + _add(new configItem("type", &type, string)); + _add(new configItem("host", &host, string)); + _add(new configItem("path", &path, string)); + _add(new configItem("method", &method, string)); + _add(new configItem("headers", &headers, stringList)); + _add(new configItem("idle_timeout", &idle_timeout, string)); + _add(new configItem("ping_timeout", &ping_timeout, string)); + _add(new configItem("max_early_data", &max_early_data, integer)); + _add(new configItem("early_data_header_name", &early_data_header_name, string)); + _add(new configItem("service_name", &service_name, string)); + } + }; +} diff --git a/include/configs/outbounds/anyTLS.h b/include/configs/outbounds/anyTLS.h new file mode 100644 index 0000000..14d8a55 --- /dev/null +++ b/include/configs/outbounds/anyTLS.h @@ -0,0 +1,28 @@ +#pragma once +#include "include/configs/baseConfig.h" +#include "include/configs/common/Outbound.h" +#include "include/configs/common/TLS.h" + +namespace Configs +{ + class anyTLS : public baseConfig, public outboundMeta + { + public: + std::shared_ptr commons = std::make_shared(); + QString password; + QString idle_session_check_interval = "30s"; + QString idle_session_timeout = "30s"; + int min_idle_session = 5; + std::shared_ptr tls = std::make_shared(); + + anyTLS() + { + _add(new configItem("commons", dynamic_cast(commons.get()), jsonStore)); + _add(new configItem("password", &password, string)); + _add(new configItem("idle_session_check_interval", &idle_session_check_interval, string)); + _add(new configItem("idle_session_timeout", &idle_session_timeout, string)); + _add(new configItem("min_idle_session", &min_idle_session, integer)); + _add(new configItem("tls", dynamic_cast(tls.get()), jsonStore)); + } + }; +} diff --git a/include/configs/outbounds/http.h b/include/configs/outbounds/http.h new file mode 100644 index 0000000..0ab7601 --- /dev/null +++ b/include/configs/outbounds/http.h @@ -0,0 +1,29 @@ +#pragma once +#include "include/configs/baseConfig.h" +#include "include/configs/common/DialFields.h" +#include "include/configs/common/Outbound.h" +#include "include/configs/common/TLS.h" + +namespace Configs +{ + class http : public baseConfig, public outboundMeta + { + public: + std::shared_ptr commons = std::make_shared(); + QString username; + QString password; + QString path; + QStringList headers; + std::shared_ptr tls = std::make_shared(); + + http() + { + _add(new configItem("commons", dynamic_cast(commons.get()), jsonStore)); + _add(new configItem("username", &username, string)); + _add(new configItem("password", &password, string)); + _add(new configItem("path", &path, string)); + _add(new configItem("headers", &headers, stringList)); + _add(new configItem("tls", dynamic_cast(tls.get()), jsonStore)); + } + }; +} diff --git a/include/configs/outbounds/hysteria.h b/include/configs/outbounds/hysteria.h new file mode 100644 index 0000000..f51d5e5 --- /dev/null +++ b/include/configs/outbounds/hysteria.h @@ -0,0 +1,40 @@ +#pragma once +#include "include/configs/baseConfig.h" +#include "include/configs/common/Outbound.h" +#include "include/configs/common/TLS.h" + +namespace Configs +{ + class hysteria : public baseConfig, public outboundMeta + { + public: + std::shared_ptr commons = std::make_shared(); + QStringList server_ports; + QString hop_interval; + int up_mbps = 0; + int down_mbps = 0; + QString obfs; + QString auth; + QString auth_str; + int recv_window_conn = 0; + int recv_window = 0; + bool disable_mtu_discovery = false; + std::shared_ptr tls = std::make_shared(); + + hysteria() + { + _add(new configItem("commons", dynamic_cast(commons.get()), jsonStore)); + _add(new configItem("server_ports", &server_ports, stringList)); + _add(new configItem("hop_interval", &hop_interval, string)); + _add(new configItem("up_mbps", &up_mbps, integer)); + _add(new configItem("down_mbps", &down_mbps, integer)); + _add(new configItem("obfs", &obfs, string)); + _add(new configItem("auth", &auth, string)); + _add(new configItem("auth_str", &auth_str, string)); + _add(new configItem("recv_window_conn", &recv_window_conn, integer)); + _add(new configItem("recv_window", &recv_window, integer)); + _add(new configItem("disable_mtu_discovery", &disable_mtu_discovery, boolean)); + _add(new configItem("tls", dynamic_cast(tls.get()), jsonStore)); + } + }; +} diff --git a/include/configs/outbounds/hysteria2.h b/include/configs/outbounds/hysteria2.h new file mode 100644 index 0000000..ef42313 --- /dev/null +++ b/include/configs/outbounds/hysteria2.h @@ -0,0 +1,34 @@ +#pragma once +#include "include/configs/baseConfig.h" +#include "include/configs/common/Outbound.h" +#include "include/configs/common/TLS.h" + +namespace Configs +{ + class hysteria2 : public baseConfig, public outboundMeta + { + public: + std::shared_ptr commons = std::make_shared(); + QStringList server_ports; + QString hop_interval; + int up_mbps = 0; + int down_mbps = 0; + QString obfsType = "salamander"; + QString obfsPassword; + QString password; + std::shared_ptr tls = std::make_shared(); + + hysteria2() + { + _add(new configItem("commons", dynamic_cast(commons.get()), jsonStore)); + _add(new configItem("server_ports", &server_ports, stringList)); + _add(new configItem("hop_interval", &hop_interval, string)); + _add(new configItem("up_mbps", &up_mbps, integer)); + _add(new configItem("down_mbps", &down_mbps, integer)); + _add(new configItem("obfsType", &obfsType, string)); + _add(new configItem("obfsPassword", &obfsPassword, string)); + _add(new configItem("password", &password, string)); + _add(new configItem("tls", dynamic_cast(tls.get()), jsonStore)); + } + }; +} diff --git a/include/configs/outbounds/shadowsocks.h b/include/configs/outbounds/shadowsocks.h new file mode 100644 index 0000000..a0a0073 --- /dev/null +++ b/include/configs/outbounds/shadowsocks.h @@ -0,0 +1,36 @@ +#pragma once +#include + +#include "include/configs/baseConfig.h" +#include "include/configs/common/DialFields.h" +#include "include/configs/common/multiplex.h" +#include "include/configs/common/Outbound.h" + +namespace Configs +{ + + inline QStringList shadowsocksMethods = {"2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305", "none", "aes-128-gcm", "aes-192-gcm", "aes-256-gcm", "chacha20-ietf-poly1305", "xchacha20-ietf-poly1305", "aes-128-ctr", "aes-192-ctr", "aes-256-ctr", "aes-128-cfb", "aes-192-cfb", "aes-256-cfb", "rc4-md5", "chacha20-ietf", "xchacha20"}; + + class shadowsocks : public baseConfig, public outboundMeta + { + public: + std::shared_ptr commons = std::make_shared(); + QString method; + QString password; + QString plugin; + QString plugin_opts; + bool uot = false; + std::shared_ptr mux = std::make_shared(); + + shadowsocks() + { + _add(new configItem("commons", dynamic_cast(commons.get()), jsonStore)); + _add(new configItem("method", &method, string)); + _add(new configItem("password", &password, string)); + _add(new configItem("plugin", &plugin, string)); + _add(new configItem("plugin_opts", &plugin_opts, string)); + _add(new configItem("uot", &uot, itemType::boolean)); + _add(new configItem("mux", dynamic_cast(mux.get()), jsonStore)); + } + }; +} diff --git a/include/configs/outbounds/socks.h b/include/configs/outbounds/socks.h new file mode 100644 index 0000000..1991400 --- /dev/null +++ b/include/configs/outbounds/socks.h @@ -0,0 +1,24 @@ +#pragma once +#include "include/configs/baseConfig.h" +#include "include/configs/common/DialFields.h" +#include "include/configs/common/Outbound.h" + +namespace Configs +{ + class socks : public baseConfig, public outboundMeta + { + public: + std::shared_ptr commons = std::make_shared(); + QString username; + QString password; + bool uot = false; + + socks() + { + _add(new configItem("commons", dynamic_cast(commons.get()), jsonStore)); + _add(new configItem("username", &username, string)); + _add(new configItem("password", &password, string)); + _add(new configItem("uot", &uot, boolean)); + } + }; +} diff --git a/include/configs/outbounds/ssh.h b/include/configs/outbounds/ssh.h new file mode 100644 index 0000000..b20f8d9 --- /dev/null +++ b/include/configs/outbounds/ssh.h @@ -0,0 +1,33 @@ +#pragma once +#include "include/configs/baseConfig.h" +#include "include/configs/common/Outbound.h" + +namespace Configs +{ + class ssh : public baseConfig, public outboundMeta + { + public: + std::shared_ptr commons = std::make_shared(); + QString user; + QString password; + QString private_key; + QString private_key_path; + QString private_key_passphrase; + QStringList host_key; + QStringList host_key_algorithms; + QString client_version; + + ssh() + { + _add(new configItem("commons", dynamic_cast(commons.get()), jsonStore)); + _add(new configItem("user", &user, string)); + _add(new configItem("password", &password, string)); + _add(new configItem("private_key", &private_key, string)); + _add(new configItem("private_key_path", &private_key_path, string)); + _add(new configItem("private_key_passphrase", &private_key_passphrase, string)); + _add(new configItem("host_key", &host_key, stringList)); + _add(new configItem("host_key_algorithms", &host_key_algorithms, stringList)); + _add(new configItem("client_version", &client_version, string)); + } + }; +} diff --git a/include/configs/outbounds/trojan.h b/include/configs/outbounds/trojan.h new file mode 100644 index 0000000..2e7c2f9 --- /dev/null +++ b/include/configs/outbounds/trojan.h @@ -0,0 +1,29 @@ +#pragma once +#include "include/configs/baseConfig.h" +#include "include/configs/common/DialFields.h" +#include "include/configs/common/multiplex.h" +#include "include/configs/common/Outbound.h" +#include "include/configs/common/TLS.h" +#include "include/configs/common/transport.h" + +namespace Configs +{ + class Trojan : public baseConfig, public outboundMeta + { + public: + std::shared_ptr commons = std::make_shared(); + QString password; + std::shared_ptr tls = std::make_shared(); + std::shared_ptr mux = std::make_shared(); + std::shared_ptr transport = std::make_shared(); + + Trojan() + { + _add(new configItem("commons", dynamic_cast(commons.get()), jsonStore)); + _add(new configItem("password", &password, string)); + _add(new configItem("tls", dynamic_cast(tls.get()), jsonStore)); + _add(new configItem("mux", dynamic_cast(mux.get()), jsonStore)); + _add(new configItem("transport", dynamic_cast(transport.get()), jsonStore)); + } + }; +} diff --git a/include/configs/outbounds/tuic.h b/include/configs/outbounds/tuic.h new file mode 100644 index 0000000..4658285 --- /dev/null +++ b/include/configs/outbounds/tuic.h @@ -0,0 +1,38 @@ +#pragma once +#include "include/configs/baseConfig.h" +#include "include/configs/common/Outbound.h" +#include "include/configs/common/TLS.h" + +namespace Configs +{ + + inline QStringList ccAlgorithms = {"cubic", "new_reno", "bbr"}; + inline QStringList udpRelayModes = {"", "native", "quic"}; + + class tuic : public baseConfig, public outboundMeta + { + public: + std::shared_ptr commons = std::make_shared(); + QString uuid; + QString password; + QString congestion_control; + QString udp_relay_mode; + bool udp_over_stream = false; + bool zero_rtt_handshake = false; + QString heartbeat; + std::shared_ptr tls = std::make_shared(); + + tuic() + { + _add(new configItem("commons", dynamic_cast(commons.get()), jsonStore)); + _add(new configItem("uuid", &uuid, string)); + _add(new configItem("password", &password, string)); + _add(new configItem("congestion_control", &congestion_control, string)); + _add(new configItem("udp_relay_mode", &udp_relay_mode, string)); + _add(new configItem("udp_over_stream", &udp_over_stream, boolean)); + _add(new configItem("zero_rtt_handshake", &zero_rtt_handshake, boolean)); + _add(new configItem("heartbeat", &heartbeat, string)); + _add(new configItem("tls", dynamic_cast(tls.get()), jsonStore)); + } + }; +} diff --git a/include/configs/outbounds/vless.h b/include/configs/outbounds/vless.h new file mode 100644 index 0000000..3c87ff6 --- /dev/null +++ b/include/configs/outbounds/vless.h @@ -0,0 +1,34 @@ +#pragma once +#include "include/configs/baseConfig.h" +#include "include/configs/common/multiplex.h" +#include "include/configs/common/Outbound.h" +#include "include/configs/common/TLS.h" +#include "include/configs/common/transport.h" + +namespace Configs +{ + inline QStringList vlessFlows = {"xtls-rprx-vision"}; + + class vless : public baseConfig, public outboundMeta + { + public: + std::shared_ptr commons = std::make_shared(); + QString uuid; + QString flow; + std::shared_ptr tls = std::make_shared(); + QString packet_encoding; + std::shared_ptr mux = std::make_shared(); + std::shared_ptr transport = std::make_shared(); + + vless() + { + _add(new configItem("commons", dynamic_cast(commons.get()), jsonStore)); + _add(new configItem("uuid", &uuid, string)); + _add(new configItem("flow", &flow, string)); + _add(new configItem("tls", dynamic_cast(tls.get()), jsonStore)); + _add(new configItem("packet_encoding", &packet_encoding, string)); + _add(new configItem("mux", dynamic_cast(mux.get()), jsonStore)); + _add(new configItem("transport", dynamic_cast(transport.get()), jsonStore)); + } + }; +} diff --git a/include/configs/outbounds/vmess.h b/include/configs/outbounds/vmess.h new file mode 100644 index 0000000..b42dc0a --- /dev/null +++ b/include/configs/outbounds/vmess.h @@ -0,0 +1,43 @@ +#pragma once +#include "include/configs/baseConfig.h" +#include "include/configs/common/DialFields.h" +#include "include/configs/common/multiplex.h" +#include "include/configs/common/Outbound.h" +#include "include/configs/common/TLS.h" +#include "include/configs/common/transport.h" + +namespace Configs +{ + + inline QStringList vmessSecurity = {"auto", "none", "zero", "aes-128-gcm", "chacha20-poly1305"}; + inline QStringList vPacketEncoding = {"", "packetaddr", "xudp"}; + + class vmess : public baseConfig, public outboundMeta + { + public: + std::shared_ptr commons = std::make_shared(); + QString uuid; + QString security = "auto"; + int alter_id = 0; + bool global_padding = false; + bool authenticated_length = false; + std::shared_ptr tls = std::make_shared(); + QString packet_encoding; + std::shared_ptr transport = std::make_shared(); + std::shared_ptr mux = std::make_shared(); + + vmess() + { + _add(new configItem("commons", dynamic_cast(commons.get()), jsonStore)); + _add(new configItem("uuid", &uuid, string)); + _add(new configItem("security", &security, string)); + _add(new configItem("alter-id", &alter_id, integer)); + _add(new configItem("global-padding", &global_padding, boolean)); + _add(new configItem("authenticated_length", &authenticated_length, boolean)); + _add(new configItem("tls", dynamic_cast(tls.get()), jsonStore)); + _add(new configItem("packet_encoding", &packet_encoding, string)); + _add(new configItem("transport", dynamic_cast(transport.get()), jsonStore)); + _add(new configItem("mux", dynamic_cast(mux.get()), jsonStore)); + } + }; +}