Fix startup route and stability checks

This commit is contained in:
ushan0v
2026-07-13 18:02:33 +03:00
parent 8b476cd145
commit 7f84f65a4f
4 changed files with 85 additions and 4 deletions
+15 -2
View File
@@ -133,6 +133,19 @@ function command_output_from_args(args) {
return as_string(data);
}
function command_output_quiet_from_args(args) {
let pipe = fs.popen(command_from_args(args) + " 2>/dev/null", "r");
if (!pipe)
return "";
let data = pipe.read("all");
let status = pipe.close();
if (status != 0 || data == null)
return "";
return as_string(data);
}
function log_debug(message) {
run_args([ "logger", "-t", "forkop", "[debug] " + as_string(message) ]);
}
@@ -1341,11 +1354,11 @@ function ensure_rt_table_entry(path, table_id, table_name) {
}
function tproxy_route4_present(table) {
return has_local_default_route_text(command_output_from_args([ "ip", "route", "list", "table", table ]), 4);
return has_local_default_route_text(command_output_quiet_from_args([ "ip", "route", "list", "table", table ]), 4);
}
function tproxy_route6_present(table) {
return has_local_default_route_text(command_output_from_args([ "ip", "-6", "route", "list", "table", table ]), 6);
return has_local_default_route_text(command_output_quiet_from_args([ "ip", "-6", "route", "list", "table", table ]), 6);
}
function tproxy_route_present(table) {
+1 -1
View File
@@ -577,7 +577,7 @@ function wait_forkop_stable_start(rt_table, nft_table, mark, min_age, timeout) {
timeout--;
}
return false;
return forkop_stably_running(rt_table, nft_table, mark, min_age);
}
function whitespace_fields(value) {
+12 -1
View File
@@ -107,11 +107,19 @@ set -eo pipefail
} >> "${IP_LOG:?}"
if [ "$#" -eq 4 ] && [ "$1" = "route" ] && [ "$2" = "list" ] && [ "$3" = "table" ]; then
if [ "${IP_ROUTE_LIST_FAIL:-0}" = "1" ]; then
printf 'Error: ipv4: FIB table does not exist\nDump terminated\n' >&2
exit 2
fi
printf '%s\n' "${IP_ROUTE_OUTPUT:-}"
exit 0
fi
if [ "$#" -eq 5 ] && [ "$1" = "-6" ] && [ "$2" = "route" ] && [ "$3" = "list" ] && [ "$4" = "table" ]; then
if [ "${IP_ROUTE6_LIST_FAIL:-0}" = "1" ]; then
printf 'Error: ipv6: FIB table does not exist\nDump terminated\n' >&2
exit 2
fi
printf '%s\n' "${IP_ROUTE6_OUTPUT:-}"
exit 0
fi
@@ -329,7 +337,10 @@ assert_line_before "$NFT_LOG" \
: > "$IP_LOG"
: > "$LOGGER_LOG"
rt_tables="$WORK_DIR/rt_tables"
IP_ROUTE_OUTPUT='' IP_ROUTE6_OUTPUT='' IP_RULE_OUTPUT='' IP_RULE6_OUTPUT='' nft_ucode ensure-tproxy-route-rule forkop 0x00100000 "$rt_tables"
IP_ROUTE_LIST_FAIL=1 IP_ROUTE6_LIST_FAIL=1 IP_RULE_OUTPUT='' IP_RULE6_OUTPUT='' \
nft_ucode ensure-tproxy-route-rule forkop 0x00100000 "$rt_tables" 2>"$WORK_DIR/tproxy-route-check.err"
[ ! -s "$WORK_DIR/tproxy-route-check.err" ] ||
fail "missing tproxy route table predicates must suppress ip stderr"
assert_contains "$rt_tables" "105 forkop" "tproxy route table registry"
assert_contains "$IP_LOG" $'ip\troute\tadd\tlocal\t0.0.0.0/0\tdev\tlo\ttable\tforkop' "tproxy route add"
assert_contains "$IP_LOG" $'ip\t-6\troute\tadd\tlocal\t::/0\tdev\tlo\ttable\tforkop' "tproxy route6 add"
+57
View File
@@ -5,6 +5,7 @@ ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
FORKOP_LIB="$ROOT_DIR/forkop/files/usr/lib"
STATE_UC="$ROOT_DIR/forkop/files/usr/lib/service/state.uc"
NFT_UC="$ROOT_DIR/forkop/files/usr/lib/nft/apply.uc"
UCODE_BIN="$(command -v ucode)"
WORK_DIR="$(mktemp -d)"
export ZAPRET_DEFAULT_NFQWS_OPT="--default-zapret"
export ZAPRET2_DEFAULT_NFQWS2_OPT="--default-zapret2"
@@ -125,6 +126,62 @@ assert_eq "0" \
"$(state_ucode sing-box-reload-previous-pid-fixture missing old new)" \
"missing sing-box PID replacement constraint"
mkdir -p "$WORK_DIR/stable-start-bin"
cp "$(command -v sleep)" "$WORK_DIR/stable-start-bin/sing-box"
cat >"$WORK_DIR/stable-start-bin/ubus" <<'SH'
#!/usr/bin/env bash
set -eo pipefail
pid="$(cat "${SING_BOX_TEST_PID_FILE:?}")"
if [ -r "/proc/$pid/exe" ] && [ "$(basename "$(readlink "/proc/$pid/exe")")" = "sing-box" ]; then
printf '{"sing-box":{"instances":{"instance1":{"running":true,"pid":%s}}}}\n' "$pid"
else
printf '{"sing-box":{"instances":{}}}\n'
fi
SH
cat >"$WORK_DIR/stable-start-bin/nft" <<'SH'
#!/usr/bin/env bash
exit 0
SH
cat >"$WORK_DIR/stable-start-bin/ucode" <<'SH'
#!/usr/bin/env bash
if [ "$#" -ge 4 ] && [ "$1" = "-L" ] && [ "${3##*/}" = "apply.uc" ] && [ "$4" = "tproxy-route-rule-present" ]; then
exit 0
fi
exec "${REAL_UCODE:?}" "$@"
SH
chmod 0755 "$WORK_DIR/stable-start-bin/ubus" "$WORK_DIR/stable-start-bin/nft" "$WORK_DIR/stable-start-bin/ucode"
"$WORK_DIR/stable-start-bin/sing-box" 30 &
sing_box_pid=$!
printf '%s\n' "$sing_box_pid" >"$WORK_DIR/sing-box.pid"
if ! PATH="$WORK_DIR/stable-start-bin:$PATH" \
REAL_UCODE="$UCODE_BIN" \
SING_BOX_TEST_PID_FILE="$WORK_DIR/sing-box.pid" \
state_ucode sing-box-service-running; then
kill "$sing_box_pid" >/dev/null 2>&1 || true
wait "$sing_box_pid" 2>/dev/null || true
fail "stable-start fixture must expose a running sing-box process"
fi
if ! PATH="$WORK_DIR/stable-start-bin:$PATH" \
REAL_UCODE="$UCODE_BIN" \
SING_BOX_TEST_PID_FILE="$WORK_DIR/sing-box.pid" \
state_ucode forkop-running forkop ForkopTable 0x00100000; then
kill "$sing_box_pid" >/dev/null 2>&1 || true
wait "$sing_box_pid" 2>/dev/null || true
fail "stable-start fixture must expose configured Forkop networking"
fi
if ! PATH="$WORK_DIR/stable-start-bin:$PATH" \
REAL_UCODE="$UCODE_BIN" \
SING_BOX_TEST_PID_FILE="$WORK_DIR/sing-box.pid" \
state_ucode wait-forkop-stable-start forkop ForkopTable 0x00100000 2 2; then
kill "$sing_box_pid" >/dev/null 2>&1 || true
wait "$sing_box_pid" 2>/dev/null || true
fail "stable-start wait must check runtime state after its final sleep"
fi
kill "$sing_box_pid" >/dev/null 2>&1 || true
wait "$sing_box_pid" 2>/dev/null || true
PENDING_RELOAD_FILE="$WORK_DIR/reload.pending"
state_ucode mark-pending-reload "$PENDING_RELOAD_FILE" "reload_busy"
grep -Fxq "reason=reload_busy" "$PENDING_RELOAD_FILE" ||