The universal proxy platform https://sing-box.sagernet.org/
Find a file
世界 d454aa0fdf
route: formalize nested rule_set group-state semantics
Before 795d1c289, nested rule-set evaluation reused the parent rule
match cache. In practice, this meant these fields leaked across nested
evaluation:

- SourceAddressMatch
- SourcePortMatch
- DestinationAddressMatch
- DestinationPortMatch
- DidMatch

That leak had two opposite effects.

First, it made included rule-sets partially behave like the docs'
"merged" semantics. For example, if an outer route rule had:

  rule_set = ["geosite-additional-!cn"]
  ip_cidr  = 104.26.10.0/24

and the inline rule-set matched `domain_suffix = speedtest.net`, the
inner match could set `DestinationAddressMatch = true` and the outer
rule would then pass its destination-address group check. This is why
some `rule_set + ip_cidr` combinations used to work.

But the same leak also polluted sibling rules and sibling rule-sets.
A branch could partially match one group, then fail later, and still
leave that group cache set for the next branch. This broke cases such
as gh-3485: with `rule_set = [test1, test2]`, `test1` could touch
destination-address cache before an AdGuard `@@` exclusion made the
whole branch fail, and `test2` would then run against dirty state.

795d1c289 fixed that by cloning metadata for nested rule-set/rule
evaluation and resetting the rule match cache for each branch. That
stopped sibling pollution, but it also removed the only mechanism by
which a successful nested branch could affect the parent rule's grouped
matching state.

As a result, nested rule-sets became pure boolean sub-items against the
outer rule. The previous example stopped working: the inner
`domain_suffix = speedtest.net` still matched, but the outer rule no
longer observed any destination-address-group success, so it fell
through to `final`.

This change makes the semantics explicit instead of relying on cache
side effects:

- `rule_set: ["a", "b"]` is OR
- rules inside one rule-set are OR
- each nested branch is evaluated in isolation
- failed branches contribute no grouped match state
- a successful branch contributes its grouped match state back to the
  parent rule
- grouped state from different rule-sets must not be combined together
  to satisfy one outer rule

In other words, rule-sets now behave as "OR branches whose successful
group matches merge into the outer rule", which matches the documented
intent without reintroducing cross-branch cache leakage.
2026-03-24 15:03:43 +08:00
.github Add Alpine APK packaging to CI build 2026-03-11 20:41:29 +08:00
adapter Fix package_name shared uid matching 2026-03-23 18:57:35 +08:00
clients Bump version 2026-03-15 17:56:37 +08:00
cmd platform: Improve iOS OOM killer 2026-02-26 14:13:32 +08:00
common Fix package_name shared uid matching 2026-03-23 18:57:35 +08:00
constant Fix missing Tailscale in ProxyDisplayName 2026-02-27 19:39:52 +08:00
daemon Fix package_name shared uid matching 2026-03-23 18:57:35 +08:00
dns Fix DNS transport returning error for empty AAAA response 2026-03-23 19:21:55 +08:00
docs documentation: Fix Chinese link anchors 2026-03-16 12:24:10 +08:00
experimental Fix package_name shared uid matching 2026-03-23 18:57:35 +08:00
include Remove overdue deprecated features 2026-03-01 12:30:43 +08:00
log Fix panic when closing Box before Start with file log output 2026-01-17 05:48:39 +08:00
option Reject removed legacy inbound fields instead of silently ignoring 2026-03-21 17:16:10 +08:00
protocol Reject removed legacy inbound fields instead of silently ignoring 2026-03-21 17:16:10 +08:00
release Add Alpine APK packaging to CI build 2026-03-11 20:41:29 +08:00
route route: formalize nested rule_set group-state semantics 2026-03-24 15:03:43 +08:00
service ccm/ocm: Fix missing metering for 1M context and /fast mode 2026-03-11 20:41:29 +08:00
test Remove overdue deprecated features 2026-03-01 12:30:43 +08:00
transport Deprecate Socksaddr.IsFqdn: do not reject potentially valid domain names 2026-03-16 09:37:59 +08:00
.fpm_openwrt Add kmod-nft-queue dependency for openwrt package 2026-01-17 05:48:59 +08:00
.fpm_pacman release: Fix pacman package 2026-02-27 14:58:06 +08:00
.fpm_systemd Fix systemd package 2025-07-08 13:14:43 +08:00
.gitignore platform: Add windows build 2026-02-15 21:10:44 +08:00
.gitmodules platform: Unify client versions 2024-02-24 13:20:27 +08:00
.golangci.yml release: Unify default build tags and linker flags into shared files 2026-03-03 21:21:09 +08:00
box.go platform: Improve iOS OOM killer 2026-02-26 14:13:32 +08:00
debug.go platform: Improve iOS OOM killer 2026-02-26 14:13:32 +08:00
debug_http.go Fix hysteria bytes format 2025-04-29 20:45:19 +08:00
debug_stub.go Fix pprof URL path 2023-12-29 18:00:40 +08:00
debug_unix.go Fix pprof URL path 2023-12-29 18:00:40 +08:00
Dockerfile release: Unify default build tags and linker flags into shared files 2026-03-03 21:21:09 +08:00
Dockerfile.binary release: Fix Docker build for loong64 and mipsle 2026-02-23 16:31:19 +08:00
go.mod tun: Fix system stack rewriting TUN subnet destinations to loopback 2026-03-23 19:38:55 +08:00
go.sum tun: Fix system stack rewriting TUN subnet destinations to loopback 2026-03-23 19:38:55 +08:00
LICENSE
Makefile release: Unify default build tags and linker flags into shared files 2026-03-03 21:21:09 +08:00
mkdocs.yml documentation: Fix unicode heading anchors 2026-03-16 12:10:32 +08:00
README.md documentation: Add appreciate for Warp 2025-10-16 21:43:12 +08:00

Sponsored by Warp, built for coding with multiple AI agents

Warp sponsorship

sing-box

The universal proxy platform.

Packaging status

Documentation

https://sing-box.sagernet.org

License

Copyright (C) 2022 by nekohasekai <contact-sagernet@sekai.icu>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.

In addition, no derivative work may use the name or imply association
with this application without prior consent.