Skip to content

feat(rules): extend slash-separated OR payload support to GEOSITE, GEOIP, and IP-ASN#2774

Open
aJC7737 wants to merge 1 commit into
MetaCubeX:Alphafrom
aJC7737:more-slash-support
Open

feat(rules): extend slash-separated OR payload support to GEOSITE, GEOIP, and IP-ASN#2774
aJC7737 wants to merge 1 commit into
MetaCubeX:Alphafrom
aJC7737:more-slash-support

Conversation

@aJC7737

@aJC7737 aJC7737 commented May 8, 2026

Copy link
Copy Markdown

Summary

Extend slash-separated payload support to more rule types so one rule can OR-match multiple values without a long OR rule.

This supports:

  • GEOSITE,cn/gfw,PROXY
  • GEOIP,lan/cn,DIRECT
  • SRC-GEOIP,cn/us,DIRECT
  • IP-ASN,1/13335,PROXY
  • SRC-IP-ASN,13335/396982,DIRECT

The behavior matches existing slash-separated list patterns in rules such as IN-TYPE, IN-USER, IN-NAME, REMATCH-NAME, and numeric range rules.

Support Table

Rule type Syntax Slash support
GEOSITE GEOSITE,google/youtube,PROXY ★ yes
GEOIP GEOIP,cn/us,PROXY[,no-resolve|src] ★ yes
SRC-GEOIP SRC-GEOIP,cn/us,PROXY ★ yes
IP-ASN IP-ASN,13335/396982,PROXY[,no-resolve|src] ★ yes
SRC-IP-ASN SRC-IP-ASN,13335/396982,PROXY ★ yes
UID UID,1000/1001/2000-3000,PROXY ◐ yes, numeric ranges; Linux/Android only
IN-TYPE IN-TYPE,HTTP/SOCKS/MIXED,PROXY ◐ yes, manual split
IN-USER IN-USER,user1/user2,PROXY ◐ yes, manual split
IN-NAME IN-NAME,in1/in2,PROXY ◐ yes, manual split
DOMAIN DOMAIN,example.com,PROXY No
DOMAIN-SUFFIX DOMAIN-SUFFIX,example.com,PROXY No
DOMAIN-KEYWORD DOMAIN-KEYWORD,google,PROXY No
DOMAIN-REGEX DOMAIN-REGEX,^abc,PROXY No
DOMAIN-WILDCARD DOMAIN-WILDCARD,*.example.com,PROXY No
IP-CIDR IP-CIDR,1.1.1.0/24,PROXY[,no-resolve|src] No, slash is CIDR
IP-CIDR6 IP-CIDR6,2409::/64,PROXY[,no-resolve|src] No, slash is CIDR
SRC-IP-CIDR SRC-IP-CIDR,192.168.1.0/24,PROXY No, slash is CIDR
IP-SUFFIX IP-SUFFIX,1.2.3.4/32,PROXY[,no-resolve|src] No, slash is prefix length
SRC-IP-SUFFIX SRC-IP-SUFFIX,1.2.3.4/32,PROXY No, slash is prefix length
SRC-PORT SRC-PORT,80/443/1000-2000,PROXY ◐ yes, numeric ranges
DST-PORT DST-PORT,80/443/1000-2000,PROXY ◐ yes, numeric ranges
IN-PORT IN-PORT,7890/7891,PROXY ◐ yes, numeric ranges
DSCP DSCP,0/8/16-32,PROXY ◐ yes, numeric ranges
PROCESS-NAME PROCESS-NAME,curl,PROXY No
PROCESS-PATH PROCESS-PATH,/usr/bin/curl,PROXY No
PROCESS-NAME-REGEX PROCESS-NAME-REGEX,^curl$,PROXY No
PROCESS-PATH-REGEX PROCESS-PATH-REGEX,/bin/.*,PROXY No
PROCESS-NAME-WILDCARD PROCESS-NAME-WILDCARD,curl*,PROXY No
PROCESS-PATH-WILDCARD PROCESS-PATH-WILDCARD,*/curl,PROXY No
NETWORK NETWORK,TCP,PROXY or NETWORK,UDP,PROXY No
REMATCH-NAME REMATCH-NAME,name1/name2,PROXY ◐ yes, manual split
RULE-SET RULE-SET,provider-name,PROXY[,no-resolve|src] No
MATCH MATCH,PROXY N/A

What Changed

Rule behavior

  • GEOSITE accepts slash-separated categories and matches if any category matches.
  • GEOIP accepts slash-separated countries and pseudo-values and matches if any value matches.
    • Mixed payloads such as lan/cn are supported.
    • Pure lan behavior is preserved.
    • SRC-GEOIP inherits the same support.
  • IP-ASN accepts slash-separated ASNs and matches if any ASN matches.
    • SRC-IP-ASN inherits the same support.

Parsing

Added a shared slash-separated payload parser that:

  • trims whitespace around each segment
  • rejects empty segments such as cn//us, /cn, and cn/
  • deduplicates values while preserving order
  • supports optional normalization, such as lowercasing GeoSite and GeoIP payloads

Internal behavior

  • Canonicalized stored payload strings for logging and UI display.
  • Added combined matcher support for multi-value GEOSITE and GEOIP payloads.
  • Added exported copy accessors for multi-value payloads:
    • GEOIP.GetCountries()
    • ASN.GetASNs()
  • Preserved GetCountry() and GetASN() compatibility by returning the first parsed value.
  • Kept matcher loading aligned with current geodata cache behavior instead of caching matchers directly on rule instances.

Documentation

Added examples for:

  • routing rules using slash-separated GEOSITE, GEOIP, SRC-GEOIP, and IP-ASN
  • geosite: prefix usage in DNS-related config examples

Examples

rules:
  - IP-ASN,1/13335,PROXY
  - SRC-IP-ASN,13335/396982,DIRECT
  - GEOSITE,cn/gfw,PROXY
  - GEOIP,lan/cn,DIRECT
  - SRC-GEOIP,cn/us,DIRECT
dns:
  nameserver-policy:
    "geosite:google/youtube": https://dns.google/dns-query

Tests

Added/updated tests covering:

  • shared slash-separated payload parsing
  • trimming, deduplication, and canonicalization
  • empty segment rejection
  • GEOIP lan and mixed payload behavior
  • combined GeoIP and GeoSite matcher behavior
  • DNS fallback behavior when GeoIP matcher loading fails
  • copied accessor behavior for multi-value GEOIP and ASN payloads
  • parser-level coverage for slash GEOIP payloads

Tested with:

go test ./rules/...
go test ./...

@wwqgtxx
wwqgtxx force-pushed the Alpha branch 5 times, most recently from 61b8d7f to 17bed79 Compare May 15, 2026 10:13
@wwqgtxx
wwqgtxx force-pushed the Alpha branch 3 times, most recently from f513c49 to d67572b Compare June 12, 2026 02:06
@aJC7737
aJC7737 force-pushed the more-slash-support branch from f10959e to add46c0 Compare June 29, 2026 12:14
@aJC7737

aJC7737 commented Jun 29, 2026

Copy link
Copy Markdown
Author

Changes Since the Original Implementation

Compared with f10959e13ab98dd0427c784a1493c42f434f2ab0:

  • Rebased the feature onto current origin/Alpha.
  • Added explicit support/documentation for the source variants:
    • SRC-GEOIP
    • SRC-IP-ASN
  • Replaced the original use of the standard-library slices package with golang.org/x/exp/slices to stay compatible with the repo's current go 1.20 module target.
  • Removed per-rule sync.Once matcher caching from GEOSITE and GEOIP.
    • The current implementation relies on the geodata loader's shared cache instead.
    • This avoids stale rule-local matchers after geodata cache invalidation/update.
  • Added a lanIPMatcher path so pure GEOIP,lan,... can expose an IP matcher cleanly.
  • Changed DNS fallback GeoIP handling to distinguish "matched false" from "matcher load failed".
    • On matcher load failure, fallback filtering now returns false instead of treating the lookup as a normal non-match.
  • Added copied multi-value accessors:
    • GEOIP.GetCountries()
    • ASN.GetASNs()
  • Kept compatibility accessors:
    • GEOIP.GetCountry() returns the first parsed country.
    • ASN.GetASN() returns the first parsed ASN.
  • Normalized GEOSITE payloads through the shared parser, so displayed/logged payloads are canonicalized consistently.
  • Expanded tests substantially:
    • added combined matcher tests
    • added DNS fallback error-path tests
    • added accessor copy tests
    • added parser-level GEOIP slash test
  • Adjusted docs examples to use current, valid examples such as GEOIP,cn/us and explicit SRC-GEOIP coverage.

Extend slash-separated payload matching to GEOSITE, GEOIP, SRC-GEOIP,
IP-ASN, and SRC-IP-ASN rules.

The shared parser trims payload segments, rejects empty segments,
deduplicates values while preserving order, and supports per-rule
normalization. GEOIP keeps lan pseudo-rule behavior, supports mixed
payloads such as lan/cn, and exposes combined matchers for multi-value
payloads.

Add tests for parser behavior, canonical payload output, mixed GEOIP
matching, DNS fallback error handling, exported value copies, and
combined matcher behavior. Update config examples for routing rules and
geosite: prefix use.
@aJC7737
aJC7737 force-pushed the more-slash-support branch from add46c0 to 1ea3e5d Compare July 9, 2026 05:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant