🦄 Sync 2026-10-02 14:52:05

This commit is contained in:
github-actions[bot] committed 2026-10-02 14:52:05 +08:00
1 parent 4c85793342
commit 0bfe84f1e8
133 files changed
+7983 -3225

No files matched your search

@@ -131,6 +131,13 @@ export function build_context(dm, env) {
const ctx = {
routing_mode, proxy_mode, ipv6_support, log_level,
proxy_fallback,
/* Resolved by the caller, which is the only layer allowed to look at
* the filesystem (guard 27). The route rule and the DNS cn-fallback
* match must agree on it: they reference the same generated rule-set,
* and one of them naming a tag the other never declared fails the
* whole config. Default false - an absent env must not turn into an
* optimistic "assume the file is there". */
china_ip6_ready: (env?.china_ip6_ready === true),
self_mark, ntp_server, dns_port, mixed_port,
redirect_port, tproxy_port,
tun_name, tun_addr4, tun_addr6, tun_mtu,
@@ -291,9 +291,24 @@ function append_proxy_dns(config, dm, ctx) {
server: 'main-dns',
tag: 'cn-fallback'
});
/* The response is matched by the addresses the upstream returned,
* and geoip-cn has no IPv6 in it, so with IPv6 support on a
* mainland domain that resolved to an AAAA address was never
* recognised as mainland and its answer kept coming from the
* proxy resolver. Adding the v6 rule-set here is what makes the
* DNS half of the split agree with the route half, which
* classifies the same destinations through the same list
* (route.uc: china-ip6). Both tags have to be declared before
* this rule runs, which is why the list is built here rather than
* inlined: a rule_set naming an undeclared tag fails the config.
* china-ip6 is only declared when its file exists, so it is only
* named here under the same condition. */
const cn_fallback_sets = ['geoip-cn'];
if (ctx.ipv6_support === '1' && ctx.china_ip6_ready)
push(cn_fallback_sets, 'china-ip6');
push(config.dns.rules, {
match_response: 'cn-fallback',
rule_set: 'geoip-cn',
rule_set: cn_fallback_sets,
action: 'route',
server: 'china-dns'
});
@@ -28,7 +28,6 @@
import { isEmpty, strToInt, strToTime, strToBool, parse_port, HP_DIR } from '../homeproxy-pro.uc';
import { get_outbound, get_resolver, get_ruleset, get_direct_override } from './common.uc';
/* --- shared initial block (every routing mode) ------------------------- */
@@ -136,6 +135,25 @@ function build_route_proxy(config, dm, ctx, direct_overrides) {
action: 'route',
outbound: 'direct-out'
});
/* IPv6 half of the same split, and the reason a mainland site opened
* over IPv6 used to go through the proxy even with IPv6 support on.
* geoip-cn.srs carries no IPv6 and china_ip4.json is generated from an
* IPv4 list, so a destination that resolved to an AAAA address matched
* neither and fell through to `final` - which in this mode is main-out.
* The rule is emitted in both mainland modes (unlike china-ip, which
* proxy_mainland_china does not need twice because geoip-cn already
* picks the mainland side there): with no IPv6 in geoip-cn there is
* nothing left to pick it, so the side has to be named explicitly.
* `prefer_ipv4` on the resolve rule above is what lets both families
* through - it biases, it does not filter. */
if (ctx.ipv6_support === '1' && ctx.china_ip6_ready) {
push(config.route.rules, {
rule_set: 'china-ip6',
action: 'route',
outbound: ctx.proxy_fallback ? 'direct-out' : 'main-out'
});
}
}
/* Main UDP out */
@@ -250,15 +268,27 @@ function build_route_proxy(config, dm, ctx, direct_overrides) {
* from, so the two cannot drift apart. `type: local` is watched by
* sing-box with fswatch, so when the resource updater replaces the
* file the running instance reloads it in place - no restart and,
* more importantly, no second copy of the list to keep in sync.
* China IPv6 is deliberately absent: the firewall only fills the v6
* set when ipv6_support is on, and the client refuses to resolve
* AAAA when it is off. */
* more importantly, no second copy of the list to keep in sync. */
push(config.route.rule_set, {
type: 'local',
tag: 'china-ip',
path: HP_DIR + '/resources/china_ip4.json'
});
/* The IPv6 counterpart, from china_ip6.txt - the same list the
* firewall renders homeproxy_mainland_addr_v6 from, and the only
* IPv6 mainland data either side of the split has. Declared only
* when the file is actually there: a rule_set pointing at a missing
* file takes the whole config down with it, and a router whose v6
* list is unusable must still start (the firewall has already
* degraded to passing IPv6 through, with a warning). */
if (ctx.ipv6_support === '1' && ctx.china_ip6_ready) {
push(config.route.rule_set, {
type: 'local',
tag: 'china-ip6',
path: HP_DIR + '/resources/china_ip6.json'
});
}
}
if (isEmpty(config.route.rule_set))