fix: zram_is_active ложный позитив, порог 256MB, log_fatal→log_warn в nft, кэш ipv6_supported, лимит prefetcher
This commit is contained in:
@@ -164,19 +164,31 @@ function int_or_range_option(section, key, fallback) {
|
||||
return fallback;
|
||||
}
|
||||
|
||||
let _ipv6_supported_cached = null;
|
||||
|
||||
function ipv6_supported() {
|
||||
// Environment override bypasses cache so tests can control the value per-call.
|
||||
let override = getenv("TACHYON_ENABLE_IPV6");
|
||||
if (override != null && override != "")
|
||||
return override == "1" || override == "true";
|
||||
// Cache the /proc result for the lifetime of this process: the kernel IPv6
|
||||
// support state does not change at runtime, and reading two /proc paths on
|
||||
// every probe tick adds unnecessary I/O on storage-constrained routers.
|
||||
if (_ipv6_supported_cached != null)
|
||||
return _ipv6_supported_cached;
|
||||
if (!fs.stat("/proc/net/if_inet6")) {
|
||||
if (!fs.stat("/proc"))
|
||||
return true;
|
||||
return false;
|
||||
_ipv6_supported_cached = true;
|
||||
else
|
||||
_ipv6_supported_cached = false;
|
||||
return _ipv6_supported_cached;
|
||||
}
|
||||
let data = fs.readfile("/proc/sys/net/ipv6/conf/all/disable_ipv6");
|
||||
if (data != null && trim(data) == "1")
|
||||
return false;
|
||||
return true;
|
||||
_ipv6_supported_cached = false;
|
||||
else
|
||||
_ipv6_supported_cached = true;
|
||||
return _ipv6_supported_cached;
|
||||
}
|
||||
|
||||
// Normalize a custom-signature-packet value (AmneziaWG i1-i5 / j1-j3) into
|
||||
|
||||
@@ -458,7 +458,7 @@ function nft_add_set_elements(table, set_name, elements) {
|
||||
|
||||
if (res != 0) {
|
||||
let err_msg = trim(as_string(fs.readfile("/tmp/nft_err.log") || ""));
|
||||
log_fatal("nft add element failed: cmd='" + cmd_str + "', code=" + res + ", err='" + err_msg + "'");
|
||||
log_warn("nft add element failed: cmd='" + cmd_str + "', code=" + res + ", err='" + err_msg + "'");
|
||||
}
|
||||
return res == 0;
|
||||
}
|
||||
@@ -1903,14 +1903,14 @@ function ensure_tproxy_route_rule(table, mark, rt_tables_path) {
|
||||
rt_tables_path = as_string(rt_tables_path || "/etc/iproute2/rt_tables");
|
||||
|
||||
if (!ensure_rt_table_entry(rt_tables_path, "105", table)) {
|
||||
log_fatal("Failed to update route table registry. Aborted.");
|
||||
log_warn("Failed to update route table registry. TPROXY routing may not work correctly.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!tproxy_route4_present(table)) {
|
||||
log_debug("Added IPv4 TPROXY route");
|
||||
if (!run_args([ "ip", "route", "add", "local", "0.0.0.0/0", "dev", "lo", "table", table ]) && !tproxy_route4_present(table)) {
|
||||
log_fatal("Failed to add IPv4 route for tproxy. Aborted.");
|
||||
log_warn("Failed to add IPv4 route for tproxy. IPv4 TPROXY interception will not work.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1921,7 +1921,7 @@ function ensure_tproxy_route_rule(table, mark, rt_tables_path) {
|
||||
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)) {
|
||||
log_fatal("Failed to create IPv4 marking rule. Aborted.");
|
||||
log_warn("Failed to create IPv4 marking rule. IPv4 TPROXY interception will not work.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,6 +311,12 @@ function run_zero_rtt_prefetching() {
|
||||
let sections = uci_core.get_all(CONFIG_NAME);
|
||||
if (!sections) return;
|
||||
|
||||
// Safety cap: prefetching thousands of domains on a 128 MB router spawns
|
||||
// enough dig/nslookup processes to trigger the OOM killer. The cap is a
|
||||
// reasonable upper bound for user-managed lists; ruleset-driven traffic is
|
||||
// handled by sing-box's own DNS cache, not by this prefetcher.
|
||||
const PREFETCH_DOMAIN_LIMIT = 500;
|
||||
|
||||
let unique_domains = {};
|
||||
for (let k in keys(sections)) {
|
||||
let sec = sections[k];
|
||||
@@ -328,23 +334,32 @@ function run_zero_rtt_prefetching() {
|
||||
dom = trim(dom);
|
||||
if (dom != "" && index(dom, "*") < 0 && index(dom, "?") < 0) {
|
||||
unique_domains[dom] = true;
|
||||
if (length(keys(unique_domains)) >= PREFETCH_DOMAIN_LIMIT) break;
|
||||
}
|
||||
}
|
||||
|
||||
if (length(keys(unique_domains)) >= PREFETCH_DOMAIN_LIMIT) break;
|
||||
|
||||
let text_val = sec.user_domains_text;
|
||||
if (text_val) {
|
||||
for (let line in split(text_val, "\n")) {
|
||||
line = trim(line);
|
||||
if (line != "" && index(line, "#") != 0 && index(line, "*") < 0 && index(line, "?") < 0) {
|
||||
unique_domains[line] = true;
|
||||
if (length(keys(unique_domains)) >= PREFETCH_DOMAIN_LIMIT) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (length(keys(unique_domains)) >= PREFETCH_DOMAIN_LIMIT) break;
|
||||
}
|
||||
|
||||
let domain_list = keys(unique_domains);
|
||||
if (length(domain_list) == 0) return;
|
||||
|
||||
if (length(domain_list) >= PREFETCH_DOMAIN_LIMIT)
|
||||
log_message("Zero-RTT Prefetcher: domain list capped at " + PREFETCH_DOMAIN_LIMIT + " to prevent OOM on low-RAM devices", "warn");
|
||||
|
||||
log_message("Zero-RTT Prefetcher: pre-resolving " + length(domain_list) + " domains in batches...", "info");
|
||||
let batch = [];
|
||||
for (let i, dom in domain_list) {
|
||||
|
||||
Reference in New Issue
Block a user