MetaCubeX / mihomo

A simple Python Pydantic model for Honkai: Star Rail parsed data from the Mihomo API.
https://wiki.metacubex.one
MIT License
16.32k stars 2.62k forks source link

[Feature] Add priority determination to nameserver-policy. #1598

Closed MNDIA closed 1 week ago

MNDIA commented 1 week ago

Verify steps

Description

For this simple example.

  nameserver-policy: 
    "rule-set:category-ads-all_classical": rcode://success
    "+.cn": *cn_dns
    #......
    "+.us": *us_dns
    "+.uk": *uk_dns

    "rule-set:geolocation-!cn": 
      *international_dns

这个问题如何影响到你? The nameserver-policy is a set dictionary is unordered, and when encountering a domain name that together belongs to { 'rule-set:category-ads-all_classical' , '+.us' , 'rule-set:geolocation-!cn' } there is no top-to-bottom match order, which can cause to happen:
for a '+.us' URL, If +.us takes precedence over rule-set, then unblocked ads. If rule-set takes precedence over +.us, then US matches don't work anymore (There are more complex implications at the end)

你想实现什么功能? Add priority determination inside current nameserver-policy. For example, Arrays are sequential, just like rules

nameserver-policy: 
  - {policy: "rule-set:category-ads-all_classical", use: rcode://success}:
  - {policy: "+.cn", use: *cn_dns}:
  #......
  - {policy: "+.us", use: *us_dns}:
  - {policy: "+.uk", use: *uk_dns}:
  - {policy: "rule-set:geolocation-!cn", use: *international_dns}:

目前 Mihomo Core 的行为是什麽 The set dictionary of nameserver-policy is not in order, and match priority may depend on the level of detail of the domain wildcard, rather than the policy order. Currently the only order for DNS resolution is [direct-nameserver, nameserver-policy, nameserver, fallback]. The simple example above is used to illustrate the problem and can be solved by the following as a temporary alternative

  nameserver-policy: 
    "rule-set:category-ads-all_classical": rcode://success
    "+.cn": *cn_dns
    #......
    "+.us": *us_dns
    "+.uk": *uk_dns

    # "rule-set:geolocation-!cn": 
    #   *international_dns
  nameserver: 
    *cn_dns
  fallback: 
    *international_dns
  fallback-filter:
    geoip: true 
    geoip-code: CN 
    geosite:
      - gfw
    ipcidr:
      - 240.0.0.0/4

But rule-set:geolocation-!cn seems to work better, no omissions But fallback is limited and geosite is about to be deprecated, can't use ruleset. But four [direct-nameserver, nameserver-policy, nameserver, fallback] cannot express complex DNS logic.

In complex DNS logic policy has intersection, especially the logic appears to be application-oriented set, the following logic example in [direct-nameserver, nameserver-policy, nameserver, fallback] can not be expressed:

  nameserver-policy:
    "rule-set:category-ads-all_classical": rcode://success 
    "rule-set:bilibili_domain": *bilibili_dns 
    "rule-set:domestic_classical": *cn_dns
    "rule-set:download_domain,bing_domain,microsoft_domain,biliintl_domain,ehentai_domain,github_domain,twitter_domain,instagram_domain,facebook_domain,youtube_domain,google_domain,apple_domain,telegram_domain,discord_domain,reddit_domain,netflix_domain,bahamut_domain,spotify_domain,pixiv_domain,steam_domain,epic_domain,openai_domain":
      *international_dns

    "+.cn": *cn_dns
    "+.us": *us_dns
    "+.uk": *uk_dns
    "+.de,+.eu": *de_dns
    "+.jp,+.nico": *jp_dns
    "+.hk": *hk_dns
    #...

    "rule-set:international_classical": 
      *international_dns
    "+.org,+.io,+.dev":
      *international_dns
    "rule-set:geolocation-!cn":
      *international_dns

Assuming that bilibili.com appears in bilibili_domain, domestic_classical, (even category-ads-all_classical) at the same time, the resolution priority is all about luck

Possible Solution

nameserver-policy: 
  - {policy: "rule-set:category-ads-all_classical", use: rcode://success}
  - {policy: "rule-set:bilibili_domain", use: *bilibili_dns}
  - {policy: "rule-set:domestic_classical", use: *cn_dns}
  - policy: "rule-set:download_domain,bing_domain,microsoft_domain,biliintl_domain,ehentai_domain,github_domain,twitter_domain,instagram_domain,facebook_domain,youtube_domain,google_domain,apple_domain,telegram_domain,discord_domain,reddit_domain,netflix_domain,bahamut_domain,spotify_domain,pixiv_domain,steam_domain,epic_domain,openai_domain"
    use: *international_dns
  - {policy: "+.cn", use: *cn_dns}
  - {policy: "+.us", use: *us_dns}
  - {policy: "+.uk", use: *uk_dns}
  - {policy: "+.de,+.eu", use: *de_dns}
  - {policy: "+.jp,+.nico", use: *jp_dns}
  - {policy: "+.hk", use: *hk_dns}
  #......
  - {policy: "rule-set:international_classical", use: *international_dns}
  - {policy: "+.org,+.io,+.dev", use: *international_dns}
  - {policy: "rule-set:geolocation-!cn", use: *international_dns}
xishang0128 commented 1 week ago

The policy uses a go-ordered-map, so it is ordered