5.0 KiB
Bundled Rule Snapshots
Bundled snapshots used by rule mode are explicitly maintained artifacts:
- geolocation-cn (issue #63): after manually reviewing the upstream source, run
Scripts/update-geolocation-cn.sh. It parses typed entries from the pinnedgeosite.datrelease of Loyalsoldier/domain-list-custom and generatesVendor/rules/geolocation-cn/snapshot.json. - china-ipv4 (issue #64): run
Scripts/update-china-ipv4.shto normalize and deduplicate IPv4 CIDRs from the pinnedchina.txtversion of gaoyifan/china-operator-ip, generatingVendor/rules/china-ipv4/snapshot.json. - gfwlist (issue #65): run
Scripts/update-gfwlist.shto decode the official Base64 AutoProxy list from a pinnedgfwlist.txtversion of gfwlist/gfwlist, generatingVendor/rules/gfwlist/snapshot.json.||hostand||host^are converted to domain-suffix matches. A|scheme://hostrule (optionally with a valid port) is converted to an exact-domain match when its path is empty or/, it has no query, fragment, or user information, and its host is a valid domain without wildcards; the scheme and port are ignored. Only a root path is eligible; rules with a specific path are skipped.@@retains the direct-routing action. Other URL prefixes, paths, wildcards, regular expressions, single-label prefixes, and IP-literal rules are counted by category in the loss report. A@@exception completely covered by proxy rules is not written as an ineffective ACL entry (sslocaldomain matching givesproxy_listpriority overbypass_list). The proxy rule is retained, and the number of shadowed exceptions is included only inabsorbedCount. The maintenance script prints per-rule evidence to stdout.
Snapshots use compact JSON with schema 2 / converter 2.0.0: each rule has only action and match; the source appears only in metadata.source; the conversion report retains counts only. Absorbed .cn entries and shadowed GFWList exceptions are not distributed in the snapshot and are not restored after a broad rule is disabled. See ADR-0024. Older snapshot versions are rejected.
Domain values and file DTOs for rules evolve independently. ProxyRule represents both a normalized rule value and rule identity across sources; custom entries also retain a UUID. Custom-rule files are written as schema 3 and no longer store source per rule. Schemas 1 and 2 remain readable; reading does not rewrite the file, and the next normal save updates its format. The bundled snapshot format is unchanged. See ADR-0039.
Python is the only upstream conversion implementation. Swift loads, validates, and consumes snapshots; it does not parse upstream input independently. Run the offline regression checks for conversion scripts with PYTHONDONTWRITEBYTECODE=1 python3 Scripts/test-rule-snapshot-converters.py. The default task test also runs both Python checks; run task test:rules for just these checks. Also run PYTHONDONTWRITEBYTECODE=1 python3 Scripts/test-rule-conversion-behavior.py to verify conversion behavior and the fixed snapshot fixtures used by the unit-test bundle. After reviewing a conversion change, add --write-fixtures to the same command to rebuild the fixtures. Fixture timestamps are fixed, and normal tests compare generated output byte for byte. Check snapshot integrity with Scripts/verify-rule-snapshots.sh.
If an update fails, the previous valid snapshot is kept. geolocation-cn conversion fails on unknown syntax or corrupted input. china-ipv4 conversion also fails on abnormal formats (when too many lines are rejected), when all entries are invalid, or when the snapshot size changes abnormally compared with the previous version. gfwlist conversion fails on unknown syntax, corrupted Base64, abnormal size, or an abnormal size change compared with the previous version. Normal builds run Scripts/verify-rule-snapshots.sh offline to check that snapshots exist, their digests match, and schema/converter versions agree; missing or corrupted snapshots fail the build. Distributed artifacts must include each source's NOTICE (license and attribution).
In rule mode, “proxy when unmatched” generates a proxy_all ACL containing both Chinese-domain and Chinese IPv4-CIDR direct-routing candidates, with fixed local bypass taking priority. “Direct when unmatched” generates a bypass_all ACL containing only effective GFWList proxy candidates. The two default actions do not unconditionally union all bundled sources. Unmatched destinations and IP literals that match no available rule go direct. CIDR checks may trigger local DNS queries: when matching an unmatched domain by IP, sslocal may perform a local DNS query. The product does not promise that all DNS queries travel through the remote Shadowsocks server.