mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-11-04 05:33:56 +08:00
🤞 Sync 2026-09-30 23:44:05
This commit is contained in:
1 parent
e3fde93105
commit
44bb740ab2
206 files changed
+5736
-2799
No files matched your search
@@ -282,7 +282,7 @@ Two further host differences are bridged so the remaining checks still run:
|
||||
| `tests/ucode/test_parser_flatten.uc` | Round-trip invariant for the canonical-Node pipeline: `flatten(normalize(parse_uri(uri)))` must equal the parser's flat UCI dict field-for-field for every supported scheme. This is what stops the parser, the Loader's `PROTOCOL_OPTIONS` (now derived from `parser/mapping.uc`) and the Repository's flatten from drifting apart. |
|
||||
| `tests/ucode/test_subscription_repository.uc` | Integration test for `subscription/repository.uc`: stages a sandboxed UCI file with a user node, a kept subscription node, and a dropped subscription node, then runs `Repository.apply_nodes` and asserts (a) the user node is untouched, (b) the kept node has the new fields and no stale fields, (c) the dropped node is gone, (d) a brand-new node is added under `md5(group+label)`. PR-03 added the `apply_main_node_refs` paths (urltest prune + missing-target switch + reset-to-nil) and the `scrub_stale_urltest_refs` pass to the same test. |
|
||||
| `tests/ucode/test_generators.sh` | Runs `generate_client.uc`/`generate_server.uc` against the UCI fixtures in `tests/fixtures/generators/` inside a scratch directory (the `uci` cursor and `HP_DIR`/`RUN_DIR` are redirected) and validates each result with `sing-box check`. The `redirect` case is the product's default `proxy_mode` and asserts, from the emitted JSON, that every dialling outbound carries the runtime `routing_mark`. |
|
||||
| `tests/ucode/test_dns_proxy_list.sh` | The `proxy_list.txt` → `dns.rules` plumbing and the bootstrap resolver, neither of which `run_case()` in the generator suite can see (it truncates both resource lists before every case and the fixture has no `bootstrap_dns` option). Patches the client fixture to each of the four proxy modes with both lists populated, and asserts the DNS rule order (`direct-domain` < `proxy-domain` via `main-dns` < the SVCB/HTTPS reject, `geosite-cn` last when the mode emits it) plus the routing half's `"tag": "proxy-domain"` and `route.final: main-out`. Then, separately: with `bootstrap_dns` set, `main-dns` must resolve its own hostname through `bootstrap-dns` and that server must carry no `domain_resolver`; with it unset, no `bootstrap-dns` server may be emitted at all. |
|
||||
| `tests/ucode/test_dns_proxy_list.sh` | The `proxy_list.txt` → `dns.rules` plumbing and the bootstrap resolver, neither of which `run_case()` in the generator suite can see (it truncates both resource lists before every case and the fixture has no `china_dns_server` option). Patches the client fixture to each of the four proxy modes with both lists populated, and asserts the DNS rule order (`direct-domain` < `proxy-domain` via `main-dns` < the SVCB/HTTPS reject, `geosite-cn` last when the mode emits it) plus the routing half's `"tag": "proxy-domain"` and `route.final: main-out`. Then, separately, the bootstrap resolver: it is derived from `china_dns_server`, so a bare IP there must make `main-dns` resolve its own hostname through `bootstrap-dns` with no `domain_resolver` of its own, and a DoH URL there (a hostname, which cannot resolve a hostname) must emit no `bootstrap-dns` server at all and leave `main-dns` on `default-dns`. |
|
||||
| `tests/toolchain/build-ucode-linux.sh` | Builds the local ucode toolchain described above; not part of `tests/run.sh`. |
|
||||
| `tests/toolchain/validate-data.sh` | Off-target stand-in for `/sbin/validate_data`, used through `HP_VALIDATE_DATA`; not part of `tests/run.sh`. |
|
||||
| `tests/ucode/test_ucode_grammar.sh` | Pins the ucode dialect: the toolchain must reject `export function ... }` without `;` and object/array destructuring, and must accept the constructs the package uses (`?.`/`??`, object spread, computed keys, template literals). |
|
||||
|
||||
@@ -2065,31 +2065,48 @@ rm -rf "$SNAP_TMP"
|
||||
trap - EXIT INT TERM
|
||||
|
||||
echo
|
||||
echo "== guard 45: a fresh install bootstraps main-dns, an untouched config still does not =="
|
||||
echo "== guard 45: the bootstrap resolver is derived, not configured =="
|
||||
|
||||
# E3. With no bootstrap_dns, `main-dns` (the DoH/DoT endpoint) falls back to
|
||||
# the WAN resolver, so the ISP answers the one lookup that decides where every
|
||||
# proxied name goes. The package default below closes that for fresh
|
||||
# installs; this guard exists so neither half drifts silently:
|
||||
# (a) an explicitly empty list must still emit NO bootstrap-dns server, so
|
||||
# a user who clears the field gets the old behaviour back rather than a
|
||||
# resolver the generator invents for them;
|
||||
# (b) the package-shipped default is what makes the fix reach a new install
|
||||
# at all - the field is read from the 'config' section, and the file is
|
||||
# a conffile, so this line only lands on fresh installs.
|
||||
if grep -q "if (isEmpty(ctx.bootstrap_dns))" "$SCRIPTS/generator/dns.uc"; then
|
||||
pass "an empty bootstrap_dns still emits no bootstrap-dns server"
|
||||
# main-dns is the user's DoH/DoT endpoint and the one server in the config
|
||||
# whose address is a hostname, so it needs a domain_resolver before it can
|
||||
# answer. It used to borrow default-dns - the WAN/ISP resolver - which makes
|
||||
# the ISP the answerer of the single query that decides where every proxied
|
||||
# name goes. It used to be a form field for that; it is derived now, from the
|
||||
# China DNS server. Both halves are pinned:
|
||||
# (a) the generator must read the China DNS server, never a separate option
|
||||
# - a second DNS address next to the China one made no sense to read;
|
||||
# (b) a bare IP is the only usable value, because the option also accepts
|
||||
# 'wan' and a DoH/DoT URL, and a hostname cannot resolve a hostname.
|
||||
if grep -q "const addr = ctx.china_dns_server;" "$SCRIPTS/generator/dns.uc"; then
|
||||
pass "the bootstrap address is taken from the China DNS server"
|
||||
else
|
||||
fail "append_bootstrap_dns no longer short-circuits on an empty bootstrap_dns - a"
|
||||
fail "user who cleared the field would get a resolver they did not ask for"
|
||||
fail "bootstrap_addr() no longer reads ctx.china_dns_server - if it reads a"
|
||||
fail "separate option again, main-dns may fall back to the WAN resolver"
|
||||
fi
|
||||
|
||||
if grep -q "^ list bootstrap_dns '223.5.5.5'" "$ROOT/root/etc/config/homeproxy-pro"; then
|
||||
pass "a fresh install ships a bootstrap_dns, so main-dns never asks the ISP"
|
||||
if grep -qE "match\(addr, /\^\[0-9\]\+" "$SCRIPTS/generator/dns.uc" &&
|
||||
grep -qE "match\(addr, /\^\[0-9a-fA-F:\]\+" "$SCRIPTS/generator/dns.uc"; then
|
||||
pass "only a bare IP is accepted as the bootstrap address"
|
||||
else
|
||||
fail "the package-shipped /etc/config/homeproxy-pro no longer ships a bootstrap_dns -"
|
||||
fail "a new install would resolve its DoH endpoint's hostname through the WAN"
|
||||
fail "resolver, which is the last query that still leaves via the ISP"
|
||||
fail "bootstrap_addr() no longer rejects a non-IP value - a DoH URL or the"
|
||||
fail "literal 'wan' is a hostname, and using one to resolve a hostname is a cycle"
|
||||
fi
|
||||
|
||||
# The option is gone from the form and from the shipped config; leaving either
|
||||
# would mean a value nothing reads, which is how the confusing second field
|
||||
# came to exist in the first place.
|
||||
if grep -q "bootstrap_dns" "$ROOT/root/etc/config/homeproxy-pro"; then
|
||||
fail "the package-shipped /etc/config/homeproxy-pro still carries a bootstrap_dns -"
|
||||
fail "the generator derives it now, so this option is read by nothing"
|
||||
else
|
||||
pass "the package-shipped /etc/config/homeproxy-pro carries no bootstrap_dns"
|
||||
fi
|
||||
|
||||
if grep -rq "bootstrap_dns" "$ROOT/htdocs/luci-static/resources/view/homeproxy-pro/"; then
|
||||
fail "a view still renders a bootstrap_dns field - the value is derived from"
|
||||
fail "the China DNS server, and a second DNS address only reads as a mistake"
|
||||
else
|
||||
pass "no view offers a bootstrap_dns field any more"
|
||||
fi
|
||||
|
||||
echo
|
||||
|
||||
@@ -3281,8 +3281,8 @@
|
||||
{
|
||||
"kind": "Value",
|
||||
"name": "dns_server",
|
||||
"title": "DNS server",
|
||||
"description": "Resolves every domain that is not on the China DNS path, through the selected proxy node. Pick an overseas service: a domestic resolver answers these queries with polluted or NXDOMAIN results, which is what makes a foreign site fail to resolve while the proxy itself works. Support UDP, TCP, DoH, DoQ, DoT. TCP protocol will be used if not specified.",
|
||||
"title": "Overseas DNS server",
|
||||
"description": "Resolves every domain that is not on the China DNS path, through the selected proxy node. A domestic resolver answers these queries with polluted or NXDOMAIN results, which is what makes a foreign site fail to resolve while the proxy itself works - so only overseas services are offered here. Support UDP, TCP, DoH, DoQ, DoT. TCP protocol will be used if not specified.",
|
||||
"depends": [
|
||||
{
|
||||
"routing_mode": "custom",
|
||||
@@ -3290,10 +3290,6 @@
|
||||
}
|
||||
],
|
||||
"values": [
|
||||
[
|
||||
"wan",
|
||||
"WAN DNS (read from interface)"
|
||||
],
|
||||
[
|
||||
"1.1.1.1",
|
||||
"CloudFlare Public DNS (1.1.1.1)"
|
||||
@@ -3305,29 +3301,13 @@
|
||||
[
|
||||
"8.8.8.8",
|
||||
"Google Public DNS (8.8.8.8)"
|
||||
],
|
||||
[
|
||||
"",
|
||||
"---"
|
||||
],
|
||||
[
|
||||
"223.5.5.5",
|
||||
"Aliyun Public DNS (223.5.5.5)"
|
||||
],
|
||||
[
|
||||
"119.29.29.29",
|
||||
"Tencent Public DNS (119.29.29.29)"
|
||||
],
|
||||
[
|
||||
"117.50.10.10",
|
||||
"ThreatBook Public DNS (117.50.10.10)"
|
||||
]
|
||||
],
|
||||
"subsection": null,
|
||||
"props": {
|
||||
"default": "8.8.8.8",
|
||||
"rmempty": false,
|
||||
"validate": "fn(758:77dbe8107e5c)"
|
||||
"validate": "fn(730:48f7f360fbd2)"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -3387,24 +3367,6 @@
|
||||
"rmempty": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "DynamicList",
|
||||
"name": "bootstrap_dns",
|
||||
"title": "Bootstrap DNS server",
|
||||
"description": "Resolver used to look up the DNS server's own hostname - only relevant when that address is a domain, as with a DoH/DoT endpoint. Leave empty to use the WAN resolver. Only the first entry is used.",
|
||||
"depends": [
|
||||
{
|
||||
"routing_mode": "custom",
|
||||
"!reverse": true
|
||||
}
|
||||
],
|
||||
"values": [],
|
||||
"subsection": null,
|
||||
"props": {
|
||||
"datatype": "ipaddr",
|
||||
"modalonly": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "SectionValue",
|
||||
"name": "_dns_cache",
|
||||
|
||||
@@ -20,10 +20,13 @@
|
||||
#
|
||||
# 2. The bootstrap resolver: the DoH/DoT endpoint (main-dns) is the only
|
||||
# server whose address is a hostname, and it used to borrow default-dns
|
||||
# (the WAN/ISP resolver) for that lookup. When the user configures a
|
||||
# bootstrap resolver, main-dns must point at it instead, and that server
|
||||
# must stay at the bottom of the chain (no domain_resolver of its own,
|
||||
# no DNS rule routing to it) or the lookup depends on itself.
|
||||
# (the WAN/ISP resolver) for that lookup, which makes the ISP the
|
||||
# answerer of the one query that decides where every proxied name goes.
|
||||
# The resolver is derived from the China DNS server now, so both halves
|
||||
# of that rule are asserted: a bare IP there yields a bootstrap-dns that
|
||||
# main-dns points at and which carries no domain_resolver of its own,
|
||||
# and a hostname there yields no bootstrap server at all (a hostname
|
||||
# cannot resolve the hostname it would be needed to resolve).
|
||||
#
|
||||
# Usage: sh tests/ucode/test_dns_proxy_list.sh <repo-root> [work-dir]
|
||||
|
||||
@@ -34,7 +37,8 @@ ROOT="$(cd "$ROOT" && pwd)"
|
||||
FIXTURE="$ROOT/tests/fixtures/generators/client.uci"
|
||||
DIRECT_DOMAIN="direct.example.cn"
|
||||
PROXY_DOMAIN="play.example.cn"
|
||||
BOOTSTRAP_DNS="223.5.5.5"
|
||||
CHINA_DNS_IP="223.5.5.5"
|
||||
CHINA_DNS_DOH="https://dns.alidns.com/dns-query"
|
||||
FAILED=0
|
||||
|
||||
rm -rf "$WORK"
|
||||
@@ -42,12 +46,14 @@ mkdir -p "$WORK"
|
||||
|
||||
# Stage the checkout the way test_generators.sh does: HP_DIR/RUN_DIR/UCICONFIG_DIR
|
||||
# are rewritten into the work dir and the fixture is copied in as the UCI
|
||||
# config. The extra bootstrap line is appended to the `config` section here
|
||||
# (the section's first named section), which is how the Loader reads it.
|
||||
# config. The fixture carries no china_dns_server (the generator then falls
|
||||
# back to the Aliyun public resolver), so the line is inserted into the
|
||||
# `config` section here - the section the Loader reads it from. It has to be
|
||||
# inserted rather than substituted for that reason.
|
||||
stage_case() {
|
||||
dir="$1"
|
||||
label="$2"
|
||||
bootstrap="$3"
|
||||
china_dns="$3"
|
||||
fixture="$4"
|
||||
|
||||
rm -rf "$dir"
|
||||
@@ -55,9 +61,9 @@ stage_case() {
|
||||
"$dir/scripts/parser" "$dir/resources"
|
||||
|
||||
cp "$fixture" "$dir/config/homeproxy-pro"
|
||||
if [ -n "$bootstrap" ]; then
|
||||
if [ -n "$china_dns" ]; then
|
||||
sed -i "/^\toption routing_mode /i\\
|
||||
\toption bootstrap_dns '$bootstrap'
|
||||
\toption china_dns_server '$china_dns'
|
||||
" "$dir/config/homeproxy-pro"
|
||||
fi
|
||||
|
||||
@@ -237,18 +243,18 @@ check_proxy_list() {
|
||||
return 0
|
||||
}
|
||||
|
||||
# --- 1. bootstrap resolver -------------------------------------------------
|
||||
# --- 1. bootstrap resolver, derived from a bare-IP China DNS server ---------
|
||||
|
||||
dir="$WORK/bootstrap"
|
||||
if stage_case "$dir" "bootstrap" "$BOOTSTRAP_DNS" "$FIXTURE"; then
|
||||
if stage_case "$dir" "bootstrap" "$CHINA_DNS_IP" "$FIXTURE"; then
|
||||
json="$dir/run/sing-box-c.json"
|
||||
|
||||
bootstrap_line="$(grep -nF '"tag": "bootstrap-dns"' "$json" | head -1 | cut -d: -f1)"
|
||||
if [ -z "$bootstrap_line" ]; then
|
||||
echo "FAIL: bootstrap: no bootstrap-dns server was emitted"
|
||||
echo "FAIL: bootstrap: a bare-IP China DNS server produced no bootstrap-dns server"
|
||||
FAILED=1
|
||||
elif ! sed -n "$bootstrap_line,$((bootstrap_line + 4))p" "$json" | grep -qF "\"$BOOTSTRAP_DNS\""; then
|
||||
echo "FAIL: bootstrap: bootstrap-dns does not carry $BOOTSTRAP_DNS"
|
||||
elif ! sed -n "$bootstrap_line,$((bootstrap_line + 4))p" "$json" | grep -qF "\"$CHINA_DNS_IP\""; then
|
||||
echo "FAIL: bootstrap: bootstrap-dns does not carry the China DNS server ($CHINA_DNS_IP)"
|
||||
FAILED=1
|
||||
elif sed -n "$bootstrap_line,$((bootstrap_line + 4))p" "$json" | grep -qF '"domain_resolver"'; then
|
||||
echo "FAIL: bootstrap: the bootstrap resolver has a domain_resolver of its own"
|
||||
@@ -264,26 +270,30 @@ if stage_case "$dir" "bootstrap" "$BOOTSTRAP_DNS" "$FIXTURE"; then
|
||||
echo "FAIL: bootstrap: main-dns still resolves through the WAN resolver"
|
||||
FAILED=1
|
||||
else
|
||||
echo "PASS: bootstrap: main-dns resolves its own hostname through bootstrap-dns ($BOOTSTRAP_DNS)"
|
||||
echo "PASS: bootstrap: main-dns resolves its own hostname through bootstrap-dns ($CHINA_DNS_IP)"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
FAILED=1
|
||||
fi
|
||||
|
||||
# --- 2. the default (no bootstrap configured) ------------------------------
|
||||
# --- 2. a hostname China DNS server is not a usable bootstrap --------------
|
||||
# The option also accepts a DoH/DoT URL, and a URL is a hostname: using one to
|
||||
# resolve the hostname it would be needed to resolve is the cycle this whole
|
||||
# mechanism exists to avoid. It must fall back to the WAN resolver, loudly
|
||||
# enough to be visible here, rather than to a broken bootstrap.
|
||||
|
||||
dir="$WORK/default"
|
||||
if stage_case "$dir" "default" "" "$FIXTURE"; then
|
||||
dir="$WORK/hostname"
|
||||
if stage_case "$dir" "hostname" "$CHINA_DNS_DOH" "$FIXTURE"; then
|
||||
json="$dir/run/sing-box-c.json"
|
||||
if grep -qF '"tag": "bootstrap-dns"' "$json"; then
|
||||
echo "FAIL: default: an unconfigured bootstrap resolver was emitted"
|
||||
echo "FAIL: hostname: a DoH China DNS server was used as the bootstrap resolver"
|
||||
FAILED=1
|
||||
elif ! grep -qF '"server": "default-dns"' "$json"; then
|
||||
echo "FAIL: default: main-dns no longer resolves through the WAN resolver"
|
||||
echo "FAIL: hostname: no bootstrap server and main-dns does not use default-dns either"
|
||||
FAILED=1
|
||||
else
|
||||
echo "PASS: default: no bootstrap server, main-dns still resolves through default-dns"
|
||||
echo "PASS: hostname: a DoH China DNS server yields no bootstrap server, main-dns uses default-dns"
|
||||
fi
|
||||
else
|
||||
FAILED=1
|
||||
|
||||
Reference in new issue
Block a user