Skip to content

Commit

Permalink
Merge pull request #1 from lonelam/hysteria-support
Browse files Browse the repository at this point in the history
Hysteria support
  • Loading branch information
lonelam committed Mar 22, 2024
2 parents eef5328 + 4452f60 commit 94f94e1
Show file tree
Hide file tree
Showing 4 changed files with 425 additions and 10 deletions.
190 changes: 181 additions & 9 deletions src/generator/config/subexport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,15 +116,19 @@ bool applyMatcher(const std::string &rule, std::string &real_rule, const Proxy &
std::string target, ret_real_rule;
static const std::string groupid_regex = R"(^!!(?:GROUPID|INSERT)=([\d\-+!,]+)(?:!!(.*))?$)", group_regex = R"(^!!(?:GROUP)=(.+?)(?:!!(.*))?$)";
static const std::string type_regex = R"(^!!(?:TYPE)=(.+?)(?:!!(.*))?$)", port_regex = R"(^!!(?:PORT)=(.+?)(?:!!(.*))?$)", server_regex = R"(^!!(?:SERVER)=(.+?)(?:!!(.*))?$)";
static const std::map<ProxyType, const char *> types = {{ProxyType::Shadowsocks, "SS"},
{ProxyType::ShadowsocksR, "SSR"},
{ProxyType::VMess, "VMESS"},
{ProxyType::Trojan, "TROJAN"},
{ProxyType::Snell, "SNELL"},
{ProxyType::HTTP, "HTTP"},
{ProxyType::HTTPS, "HTTPS"},
{ProxyType::SOCKS5, "SOCKS5"},
{ProxyType::WireGuard, "WIREGUARD"}};
static const std::map<ProxyType, const char *> types = {
{ProxyType::Shadowsocks, "SS"},
{ProxyType::ShadowsocksR, "SSR"},
{ProxyType::VMess, "VMESS"},
{ProxyType::Trojan, "TROJAN"},
{ProxyType::Snell, "SNELL"},
{ProxyType::HTTP, "HTTP"},
{ProxyType::HTTPS, "HTTPS"},
{ProxyType::SOCKS5, "SOCKS5"},
{ProxyType::WireGuard, "WIREGUARD"},
{ProxyType::Hysteria, "HYSTERIA"},
{ProxyType::Hysteria2, "HYSTERIA2"}
};
if(startsWith(rule, "!!GROUP="))
{
regGetMatch(rule, group_regex, 3, 0, &target, &ret_real_rule);
Expand Down Expand Up @@ -466,6 +470,77 @@ void proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGr
if(x.Mtu > 0)
singleproxy["mtu"] = x.Mtu;
break;
case ProxyType::Hysteria:
singleproxy["type"] = "hysteria";
if (!x.Ports.empty())
singleproxy["ports"] = x.Ports;
if (!x.Protocol.empty())
singleproxy["protocol"] = x.Protocol;
if (!x.OBFSParam.empty())
singleproxy["obfs-protocol"] = x.OBFSParam;
if (!x.Up.empty())
singleproxy["up"] = x.Up;
if (x.UpSpeed)
singleproxy["up-speed"] = x.UpSpeed;
if (!x.Down.empty())
singleproxy["down"] = x.Down;
if (x.DownSpeed)
singleproxy["down-speed"] = x.DownSpeed;
if (!x.AuthStr.empty())
{
singleproxy["auth-str"] = x.AuthStr;
singleproxy["auth"] = base64Encode(x.AuthStr);
}
if (!x.OBFS.empty())
singleproxy["obfs"] = x.OBFS;
if (!x.SNI.empty())
singleproxy["sni"] = x.SNI;
if (!scv.is_undef())
singleproxy["skip-cert-verify"] = scv.get();
if (!x.Fingerprint.empty())
singleproxy["fingerprint"] = x.Fingerprint;
if (!x.Alpn.empty())
singleproxy["alpn"] = x.Alpn;
if (!x.Ca.empty())
singleproxy["ca-str"] = fileGet(x.Ca);
if (!x.CaStr.empty())
singleproxy["ca-str"] = x.CaStr;
if (x.RecvWindowConn)
singleproxy["recv-window-conn"] = x.RecvWindowConn;
if (x.RecvWindow)
singleproxy["recv-window"] = x.RecvWindow;
if (!x.DisableMtuDiscovery.is_undef())
singleproxy["disable-mtu-discovery"] = x.DisableMtuDiscovery.get();
if (!x.TCPFastOpen.is_undef())
singleproxy["fast-open"] = x.TCPFastOpen.get();
if (x.HopInterval)
singleproxy["hop-interval"] = x.HopInterval;
break;
case ProxyType::Hysteria2:
singleproxy["type"] = "hysteria2";
if (!x.Up.empty())
singleproxy["up"] = x.UpSpeed;
if (!x.Down.empty())
singleproxy["down"] = x.DownSpeed;
if (!x.Password.empty())
singleproxy["password"] = x.Password;
if (!x.OBFS.empty())
singleproxy["obfs"] = x.OBFS;
if (!x.OBFSParam.empty())
singleproxy["obfs-password"] = x.OBFSParam;
if (!x.SNI.empty())
singleproxy["sni"] = x.SNI;
if (!scv.is_undef())
singleproxy["skip-cert-verify"] = scv.get();
if (!x.Alpn.empty())
singleproxy["alpn"] = x.Alpn;
if (!x.Ca.empty())
singleproxy["ca-str"] = fileGet(x.Ca);
if (!x.CaStr.empty())
singleproxy["ca-str"] = x.CaStr;
if (x.CWND)
singleproxy["cwnd"] = x.CWND;
break;
default:
continue;
}
Expand Down Expand Up @@ -834,6 +909,20 @@ std::string proxyToSurge(std::vector<Proxy> &nodes, const std::string &base_conf
ini.set(real_section, "keepalive", std::to_string(x.KeepAlive));
ini.set(real_section, "peer", "(" + generatePeer(x) + ")");
break;
case ProxyType::Hysteria2:
if(surge_ver < 5)
continue;
proxy = "hysteria, " + hostname + ", " + port + ", password=" + password;
if(x.DownSpeed)
proxy += ", download-bandwidth=" + x.DownSpeed;

if(!scv.is_undef())
proxy += ",skip-cert-verify=" + std::string(scv.get() ? "true" : "false");
if(!x.Fingerprint.empty())
proxy += ",server-cert-fingerprint-sha256=" + x.Fingerprint;
if(!x.SNI.empty())
proxy += ",sni=" + x.SNI;
break;
default:
continue;
}
Expand Down Expand Up @@ -2225,6 +2314,89 @@ void proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json, std::v
proxy.AddMember("mtu", x.Mtu, allocator);
break;
}
case ProxyType::Hysteria:
{
addSingBoxCommonMembers(proxy, x, "hysteria", allocator);
if (!x.Up.empty())
proxy.AddMember("up", rapidjson::StringRef(x.Up.c_str()), allocator);
if (!x.Down.empty())
proxy.AddMember("down", rapidjson::StringRef(x.Down.c_str()), allocator);
if (!x.OBFS.empty())
{
proxy.AddMember("obfs", rapidjson::StringRef(x.OBFS.c_str()), allocator);
}

if (!x.AuthStr.empty())
{
proxy.AddMember("auth_str", rapidjson::StringRef(x.AuthStr.c_str()), allocator);
std::string auth_str = base64Encode(x.AuthStr);
proxy.AddMember("auth",rapidjson::StringRef(auth_str.c_str()), allocator);
}
if (x.RecvWindowConn)
proxy.AddMember("recv_window_conn", x.RecvWindowConn, allocator);
if (x.RecvWindow)
proxy.AddMember("recv_window", x.RecvWindow, allocator);
if (!x.DisableMtuDiscovery.is_undef())
proxy.AddMember("disable_mtu_discovery", x.DisableMtuDiscovery.get(), allocator);

rapidjson::Value tls(rapidjson::kObjectType);
tls.AddMember("enabled", true, allocator);
if (!scv.is_undef())
tls.AddMember("insecure", scv.get(), allocator);
if (!x.Alpn.empty())
{
rapidjson::Value alpn(rapidjson::kArrayType);
alpn.PushBack(rapidjson::StringRef(x.Alpn.c_str()), allocator);
tls.AddMember("alpn", alpn, allocator);
}
if (!x.Ca.empty())
{
std::string ca_str = fileGet(x.Ca);
tls.AddMember("certificate", rapidjson::StringRef(ca_str.c_str()), allocator);
}
if (!x.CaStr.empty())
tls.AddMember("certificate", rapidjson::StringRef(x.CaStr.c_str()), allocator);
proxy.AddMember("tls", tls, allocator);
break;
}
case ProxyType::Hysteria2:
{
addSingBoxCommonMembers(proxy, x, "hysteria2", allocator);
if (!x.Up.empty())
proxy.AddMember("up_mbps", x.UpSpeed, allocator);
if (!x.Down.empty())
proxy.AddMember("down_mbps", x.DownSpeed, allocator);
if (!x.OBFS.empty())
{
rapidjson::Value obfs(rapidjson::kObjectType);
obfs.AddMember("type", rapidjson::StringRef(x.OBFS.c_str()), allocator);
if (!x.OBFSParam.empty())
obfs.AddMember("password", rapidjson::StringRef(x.OBFSParam.c_str()), allocator);
proxy.AddMember("obfs", obfs, allocator);
}
if (!x.Password.empty())
proxy.AddMember("password", rapidjson::StringRef(x.Password.c_str()), allocator);

rapidjson::Value tls(rapidjson::kObjectType);
tls.AddMember("enabled", true, allocator);
if (!scv.is_undef())
tls.AddMember("insecure", scv.get(), allocator);
if (!x.Alpn.empty())
{
rapidjson::Value alpn(rapidjson::kArrayType);
alpn.PushBack(rapidjson::StringRef(x.Alpn.c_str()), allocator);
tls.AddMember("alpn", alpn, allocator);
}
if (!x.Ca.empty())
{
std::string ca_str = fileGet(x.Ca);
tls.AddMember("certificate", rapidjson::StringRef(ca_str.c_str()), allocator);
}
if (!x.CaStr.empty())
tls.AddMember("certificate", rapidjson::StringRef(x.CaStr.c_str()), allocator);
proxy.AddMember("tls", tls, allocator);
break;
}
case ProxyType::HTTP:
case ProxyType::HTTPS:
{
Expand Down
30 changes: 29 additions & 1 deletion src/parser/config/proxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ enum class ProxyType
HTTP,
HTTPS,
SOCKS5,
WireGuard
WireGuard,
Hysteria,
Hysteria2
};

inline String getProxyTypeName(ProxyType type)
Expand All @@ -43,6 +45,12 @@ inline String getProxyTypeName(ProxyType type)
return "HTTPS";
case ProxyType::SOCKS5:
return "SOCKS5";
case ProxyType::WireGuard:
return "WireGuard";
case ProxyType::Hysteria:
return "Hysteria";
case ProxyType::Hysteria2:
return "Hysteria2";
default:
return "Unknown";
}
Expand Down Expand Up @@ -99,6 +107,24 @@ struct Proxy
uint16_t KeepAlive = 0;
String TestUrl;
String ClientId;

String Ports;
String Up;
uint32_t UpSpeed;
String Down;
uint32_t DownSpeed;
String AuthStr;
String SNI;
String Fingerprint;
String Ca;
String CaStr;
uint32_t RecvWindowConn;
uint32_t RecvWindow;
tribool DisableMtuDiscovery;
uint32_t HopInterval;
String Alpn;

uint32_t CWND = 0;
};

#define SS_DEFAULT_GROUP "SSProvider"
Expand All @@ -109,5 +135,7 @@ struct Proxy
#define TROJAN_DEFAULT_GROUP "TrojanProvider"
#define SNELL_DEFAULT_GROUP "SnellProvider"
#define WG_DEFAULT_GROUP "WireGuardProvider"
#define HYSTERIA_DEFAULT_GROUP "HysteriaProvider"
#define HYSTERIA2_DEFAULT_GROUP "Hysteria2Provider"

#endif // PROXY_H_INCLUDED
Loading

0 comments on commit 94f94e1

Please sign in to comment.