feat: автоопределение low-RAM роутеров и zram-swap, парсинг @ в URL query и устойчивость к отключенному IPv6

This commit is contained in:
Dushnilin
2026-09-06 14:31:45 +03:00
parent fd79c4e317
commit 85df236727
12 changed files with 210 additions and 31 deletions
+17 -1
View File
@@ -164,6 +164,21 @@ function int_or_range_option(section, key, fallback) {
return fallback;
}
function ipv6_supported() {
let override = getenv("TACHYON_ENABLE_IPV6");
if (override != null && override != "")
return override == "1" || override == "true";
if (!fs.stat("/proc/net/if_inet6")) {
if (!fs.stat("/proc"))
return true;
return false;
}
let data = fs.readfile("/proc/sys/net/ipv6/conf/all/disable_ipv6");
if (data != null && trim(data) == "1")
return false;
return true;
}
// Normalize a custom-signature-packet value (AmneziaWG i1-i5 / j1-j3) into
// the tag-chain format understood by the userspace WireGuard shipped with
// sing-box-extended and sing-box-lx ("<b 0x..>", "<r N>", "<rd N>", "<rc N>",
@@ -617,5 +632,6 @@ return {
get_mixed_port,
timeout_prefix,
bounded_command,
kill_matching_command
kill_matching_command,
ipv6_supported
};
+8 -2
View File
@@ -280,6 +280,9 @@ function url_get_scheme(value) {
function url_get_userinfo(value) {
value = strip_anchored_scheme(value);
let end = first_index_any(value, ["/", "?", "#"], 0);
if (end >= 0)
value = substr(value, 0, end);
let at = index(value, "@");
if (at >= 0)
print(substr(value, 0, at), "\n");
@@ -287,12 +290,15 @@ function url_get_userinfo(value) {
function url_authority(value) {
value = strip_first_scheme_marker(value);
let end = first_index_any(value, ["/", "?", "#"], 0);
if (end >= 0)
value = substr(value, 0, end);
let at = index(value, "@");
if (at >= 0)
value = substr(value, at + 1);
let end = first_index_any(value, ["/", "?", "#"], 0);
return end >= 0 ? substr(value, 0, end) : value;
return value;
}
function url_get_host(value) {
+6 -1
View File
@@ -139,6 +139,10 @@ function format_ipv6_tproxy_target(address, port) {
return "[" + address + "]:" + as_string(port);
}
function ipv6_supported() {
return common.ipv6_supported();
}
return {
valid_ipv4,
valid_ipv4_cidr,
@@ -149,5 +153,6 @@ return {
valid_ip_or_cidr,
nft_ip_or_cidr,
ip_family,
format_ipv6_tproxy_target
format_ipv6_tproxy_target,
ipv6_supported
};
+6 -5
View File
@@ -98,12 +98,12 @@ function strip_first_scheme_marker(value) {
function authority(value) {
value = strip_first_scheme_marker(value);
let at = rindex(value, "@");
if (at >= 0)
value = substr(value, at + 1);
let end = first_index_any(value, ["/", "?", "#"], 0);
return end >= 0 ? substr(value, 0, end) : value;
if (end >= 0)
value = substr(value, 0, end);
let at = rindex(value, "@");
return at >= 0 ? substr(value, at + 1) : value;
}
function host(value) {
@@ -318,6 +318,7 @@ return {
fragment,
strip_fragment,
strip_anchored_scheme,
authority,
host,
port,
userinfo,
+20 -17
View File
@@ -1918,17 +1918,6 @@ function ensure_tproxy_route_rule(table, mark, rt_tables_path) {
log_debug("IPv4 TPROXY route already exists");
}
if (!tproxy_route6_present(table)) {
log_debug("Added IPv6 TPROXY route");
if (!run_args([ "ip", "-6", "route", "add", "local", "::/0", "dev", "lo", "table", table ]) && !tproxy_route6_present(table)) {
log_fatal("Failed to add IPv6 route for tproxy. Aborted.");
return false;
}
}
else {
log_debug("IPv6 TPROXY route already exists");
}
if (!tproxy_marking_rule4_present(table, mark)) {
log_debug("Creating IPv4 TPROXY marking rule");
if (!run_args([ "ip", "-4", "rule", "add", "fwmark", as_string(mark) + "/" + as_string(mark), "table", table, "priority", "105" ]) && !tproxy_marking_rule4_present(table, mark)) {
@@ -1940,15 +1929,29 @@ function ensure_tproxy_route_rule(table, mark, rt_tables_path) {
log_debug("IPv4 TPROXY marking rule already exists");
}
if (!tproxy_marking_rule6_present(table, mark)) {
log_debug("Creating IPv6 TPROXY marking rule");
if (!run_args([ "ip", "-6", "rule", "add", "fwmark", as_string(mark) + "/" + as_string(mark), "table", table, "priority", "105" ]) && !tproxy_marking_rule6_present(table, mark)) {
log_fatal("Failed to create IPv6 marking rule. Aborted.");
return false;
if (core_ip.ipv6_supported()) {
if (!tproxy_route6_present(table)) {
log_debug("Added IPv6 TPROXY route");
if (!run_args([ "ip", "-6", "route", "add", "local", "::/0", "dev", "lo", "table", table ]) && !tproxy_route6_present(table)) {
log_warn("Failed to add IPv6 route for tproxy, skipping IPv6 routing");
}
}
else {
log_debug("IPv6 TPROXY route already exists");
}
if (!tproxy_marking_rule6_present(table, mark)) {
log_debug("Creating IPv6 TPROXY marking rule");
if (!run_args([ "ip", "-6", "rule", "add", "fwmark", as_string(mark) + "/" + as_string(mark), "table", table, "priority", "105" ]) && !tproxy_marking_rule6_present(table, mark)) {
log_warn("Failed to create IPv6 marking rule, skipping IPv6 marking");
}
}
else {
log_debug("IPv6 TPROXY marking rule already exists");
}
}
else {
log_debug("IPv6 TPROXY marking rule already exists");
log_debug("IPv6 is disabled or not supported, skipping IPv6 TPROXY route and marking rule");
}
let fw4_forward_out = command_output_from_args([ "nft", "list", "chain", "inet", "fw4", "forward" ]);
+7 -3
View File
@@ -399,6 +399,8 @@ function cli_bool(value) {
}
function tproxy_inbound_matcher() {
if (!core_ip.ipv6_supported())
return [ runtime_constants.TPROXY_INBOUND_TAG ];
return [ runtime_constants.TPROXY_INBOUND_TAG, runtime_constants.TPROXY_INBOUND6_TAG ];
}
@@ -486,10 +488,12 @@ function base_config(settings, service_address, runtime_context) {
push(dns_servers, fakeip_server);
let inbounds = [
{ type: "tproxy", tag: runtime_constants.TPROXY_INBOUND_TAG, listen: runtime_constants.TPROXY_INBOUND_ADDRESS, listen_port: runtime_constants.TPROXY_INBOUND_PORT, tcp_fast_open: true, udp_fragment: true },
{ type: "tproxy", tag: runtime_constants.TPROXY_INBOUND6_TAG, listen: runtime_constants.TPROXY_INBOUND6_ADDRESS, listen_port: runtime_constants.TPROXY_INBOUND_PORT, tcp_fast_open: true, udp_fragment: true },
{ type: "direct", tag: runtime_constants.DNS_INBOUND_TAG, listen: runtime_constants.DNS_INBOUND_ADDRESS, listen_port: runtime_constants.DNS_INBOUND_PORT }
{ type: "tproxy", tag: runtime_constants.TPROXY_INBOUND_TAG, listen: runtime_constants.TPROXY_INBOUND_ADDRESS, listen_port: runtime_constants.TPROXY_INBOUND_PORT, tcp_fast_open: true, udp_fragment: true }
];
if (core_ip.ipv6_supported()) {
push(inbounds, { type: "tproxy", tag: runtime_constants.TPROXY_INBOUND6_TAG, listen: runtime_constants.TPROXY_INBOUND6_ADDRESS, listen_port: runtime_constants.TPROXY_INBOUND_PORT, tcp_fast_open: true, udp_fragment: true });
}
push(inbounds, { type: "direct", tag: runtime_constants.DNS_INBOUND_TAG, listen: runtime_constants.DNS_INBOUND_ADDRESS, listen_port: runtime_constants.DNS_INBOUND_PORT });
for (let inbound in dns_config.inbounds)
push(inbounds, inbound);
@@ -548,7 +548,7 @@ function apply_link_transport(outbound, query) {
optional_query_number(result, "max_early_data", query.ed);
}
else if (transport == "grpc") {
optional_query_string(result, "service_name", query.serviceName);
optional_query_string(result, "service_name", query.serviceName || query.service_name);
}
else if (transport == "httpupgrade") {
optional_query_string(result, "path", query.path);
+1 -1
View File
@@ -653,7 +653,7 @@ function add_transport(url) {
let path = query.path || "";
let host = query.host || "";
let early_data = query.ed || "";
let grpc_service_name = query.serviceName || "";
let grpc_service_name = query.serviceName || query.service_name || "";
let xhttp_mode = query.mode || "auto";
let sni = query.sni || "";