feat: автоопределение low-RAM роутеров и zram-swap, парсинг @ в URL query и устойчивость к отключенному IPv6
This commit is contained in:
@@ -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
|
||||
};
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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" ]);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 || "";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user