fix(singbox): fix Leadaxe (lx) version parsing regex and AWG startup on OpenWrt
- In action.uc: replace broken PCRE non-capturing regex in extract_sing_box_version_from_output with token-based field splitting. ucode POSIX regex engine threw 'Repetition not preceded by valid expression', crashing component_action during binary validation. - In telegram.uc: replace non-capturing group (?:outbounds|server|servers) with standard capturing group for POSIX regex compatibility. - In generator_outbounds.uc and servers.uc: enhance is_lx detection to check sing-box-version file in addition to sing-box-variant, ensuring AWG 2.0 root schema is generated even if variant file is desynced. - In runtime.uc: add fallback recovery in sing_box_check retry loop for endpoints (auto-flattening amnezia sub-objects) and outbounds unknown fields.
This commit is contained in:
@@ -1356,12 +1356,11 @@ function extract_sing_box_version_from_output(output) {
|
||||
output = as_string(output);
|
||||
for (let line in split(output, "\n")) {
|
||||
line = trim(line);
|
||||
let m = match(line, /^(?:sing-box\s+)?version\s+([^\s]+)/i);
|
||||
if (m && m[1])
|
||||
return m[1];
|
||||
let fields = split(line, /[ \t\r\n]+/);
|
||||
if (length(fields) >= 3 && lc(fields[0]) == "sing-box" && lc(fields[1]) == "version")
|
||||
return fields[2];
|
||||
if (length(fields) >= 2 && lc(fields[0]) == "version")
|
||||
return fields[1];
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -2374,7 +2374,7 @@ function dispatch_command(token, chat_id, text, msg_id) {
|
||||
}
|
||||
|
||||
if (cmd == "/outbounds" || cmd == "/server" || cmd == "/servers") return view_outbounds(token, chat_id, msg_id);
|
||||
if (match(cmd, /^\/(?:outbounds|server|servers) /)) {
|
||||
if (match(cmd, /^\/(outbounds|server|servers) /)) {
|
||||
let parts = split(cmd, " ");
|
||||
let grp = trim(join(" ", slice(parts, 1)));
|
||||
return view_outbounds(token, chat_id, msg_id, grp);
|
||||
|
||||
@@ -1303,7 +1303,8 @@ function add_awg_endpoint(config, section) {
|
||||
let j2 = awg_cps_option(section, "awg_j2");
|
||||
let j3 = awg_cps_option(section, "awg_j3");
|
||||
let itime = int_option(section, "awg_itime", "0");
|
||||
let is_lx = trim(fs.readfile("/etc/tachyon/sing-box-variant") || "") == "lx";
|
||||
let is_lx = trim(fs.readfile("/etc/tachyon/sing-box-variant") || "") == "lx" ||
|
||||
index(trim(fs.readfile("/etc/tachyon/sing-box-version") || ""), "-lx") >= 0;
|
||||
|
||||
if (is_lx) {
|
||||
// sing-box-lx expects AWG fields at the endpoint root (AWG 2.0 schema).
|
||||
|
||||
@@ -978,6 +978,45 @@ function init_config(populate_nft, caches_prepared, no_refresh) {
|
||||
stripped = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
let ep_field_m = match(check_result.reason, /endpoints\[\d+\]\.(\w+): json: unknown field/);
|
||||
let out_field_m = match(check_result.reason, /outbounds\[\d+\]\.(\w+): json: unknown field/);
|
||||
if (ep_field_m) {
|
||||
let unknown_field = ep_field_m[1];
|
||||
log_message("Installed sing-box does not support endpoint field '" + unknown_field + "'; adjusting configuration", "warn");
|
||||
let cfg_text = as_string(fs.readfile(temp_config) || "");
|
||||
let cfg = length(cfg_text) > 0 ? json(cfg_text) : null;
|
||||
if (type(cfg) == "object" && type(cfg.endpoints) == "array") {
|
||||
for (let ep in cfg.endpoints) {
|
||||
if (type(ep) == "object") {
|
||||
if (unknown_field == "amnezia" && type(ep.amnezia) == "object") {
|
||||
for (let k, v in ep.amnezia) {
|
||||
if (ep[k] == null)
|
||||
ep[k] = v;
|
||||
}
|
||||
}
|
||||
delete ep[unknown_field];
|
||||
}
|
||||
}
|
||||
write_file(temp_config, sprintf("%J", cfg));
|
||||
stripped = true;
|
||||
}
|
||||
}
|
||||
else if (out_field_m) {
|
||||
let unknown_field = out_field_m[1];
|
||||
log_message("Installed sing-box does not support outbound field '" + unknown_field + "'; retrying without it", "warn");
|
||||
let cfg_text = as_string(fs.readfile(temp_config) || "");
|
||||
let cfg = length(cfg_text) > 0 ? json(cfg_text) : null;
|
||||
if (type(cfg) == "object" && type(cfg.outbounds) == "array") {
|
||||
for (let outb in cfg.outbounds) {
|
||||
if (type(outb) == "object")
|
||||
delete outb[unknown_field];
|
||||
}
|
||||
write_file(temp_config, sprintf("%J", cfg));
|
||||
stripped = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!stripped)
|
||||
break;
|
||||
check_result = sing_box_check(temp_config, runtime_log);
|
||||
|
||||
@@ -305,7 +305,8 @@ function add_standard_inbound(config, section, protocol, tag_name) {
|
||||
let jmin = int_option(section, "awg_jmin", "40");
|
||||
let jmax = int_option(section, "awg_jmax", "70");
|
||||
if (jmax > 1200) jmax = 1200;
|
||||
let is_lx = trim(fs.readfile("/etc/tachyon/sing-box-variant") || "") == "lx";
|
||||
let is_lx = trim(fs.readfile("/etc/tachyon/sing-box-variant") || "") == "lx" ||
|
||||
index(trim(fs.readfile("/etc/tachyon/sing-box-version") || ""), "-lx") >= 0;
|
||||
|
||||
let amnezia = {
|
||||
jc: jc,
|
||||
|
||||
Reference in New Issue
Block a user