Skip to content

Commit 9e67204

Browse files
committed
Add rule-set match command
1 parent 6d62d3e commit 9e67204

File tree

3 files changed

+97
-7
lines changed

3 files changed

+97
-7
lines changed

adapter/router.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ func RouterFromContext(ctx context.Context) Router {
7171

7272
type HeadlessRule interface {
7373
Match(metadata *InboundContext) bool
74+
String() string
7475
}
7576

7677
type Rule interface {
@@ -79,7 +80,6 @@ type Rule interface {
7980
Type() string
8081
UpdateGeosite() error
8182
Outbound() string
82-
String() string
8383
}
8484

8585
type DNSRule interface {

cmd/sing-box/cmd_rule_set_match.go

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"io"
6+
"os"
7+
8+
"github.com/sagernet/sing-box/adapter"
9+
"github.com/sagernet/sing-box/common/srs"
10+
C "github.com/sagernet/sing-box/constant"
11+
"github.com/sagernet/sing-box/log"
12+
"github.com/sagernet/sing-box/option"
13+
"github.com/sagernet/sing-box/route"
14+
E "github.com/sagernet/sing/common/exceptions"
15+
"github.com/sagernet/sing/common/json"
16+
17+
"github.com/spf13/cobra"
18+
)
19+
20+
var flagRuleSetMatchFormat string
21+
22+
var commandRuleSetMatch = &cobra.Command{
23+
Use: "match <rule-set path> <domain>",
24+
Short: "Check if a domain matches the rule set",
25+
Args: cobra.ExactArgs(2),
26+
Run: func(cmd *cobra.Command, args []string) {
27+
err := ruleSetMatch(args[0], args[1])
28+
if err != nil {
29+
log.Fatal(err)
30+
}
31+
},
32+
}
33+
34+
func init() {
35+
commandRuleSetMatch.Flags().StringVarP(&flagRuleSetMatchFormat, "format", "f", "source", "rule-set format")
36+
commandRuleSet.AddCommand(commandRuleSetMatch)
37+
}
38+
39+
func ruleSetMatch(sourcePath string, domain string) error {
40+
var (
41+
reader io.Reader
42+
err error
43+
)
44+
if sourcePath == "stdin" {
45+
reader = os.Stdin
46+
} else {
47+
reader, err = os.Open(sourcePath)
48+
if err != nil {
49+
return E.Cause(err, "read rule-set")
50+
}
51+
}
52+
content, err := io.ReadAll(reader)
53+
if err != nil {
54+
return E.Cause(err, "read rule-set")
55+
}
56+
var plainRuleSet option.PlainRuleSet
57+
switch flagRuleSetMatchFormat {
58+
case C.RuleSetFormatSource:
59+
var compat option.PlainRuleSetCompat
60+
compat, err = json.UnmarshalExtended[option.PlainRuleSetCompat](content)
61+
if err != nil {
62+
return err
63+
}
64+
plainRuleSet = compat.Upgrade()
65+
case C.RuleSetFormatBinary:
66+
plainRuleSet, err = srs.Read(bytes.NewReader(content), false)
67+
if err != nil {
68+
return err
69+
}
70+
default:
71+
return E.New("unknown rule set format: ", flagRuleSetMatchFormat)
72+
}
73+
for i, ruleOptions := range plainRuleSet.Rules {
74+
var currentRule adapter.HeadlessRule
75+
currentRule, err = route.NewHeadlessRule(nil, ruleOptions)
76+
if err != nil {
77+
return E.Cause(err, "parse rule_set.rules.[", i, "]")
78+
}
79+
if currentRule.Match(&adapter.InboundContext{
80+
Domain: domain,
81+
}) {
82+
println("match rules.[", i, "]: "+currentRule.String())
83+
}
84+
}
85+
return nil
86+
}

route/rule_headless.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -129,14 +129,18 @@ func NewDefaultHeadlessRule(router adapter.Router, options option.DefaultHeadles
129129
rule.allItems = append(rule.allItems, item)
130130
}
131131
if len(options.WIFISSID) > 0 {
132-
item := NewWIFISSIDItem(router, options.WIFISSID)
133-
rule.items = append(rule.items, item)
134-
rule.allItems = append(rule.allItems, item)
132+
if router != nil {
133+
item := NewWIFISSIDItem(router, options.WIFISSID)
134+
rule.items = append(rule.items, item)
135+
rule.allItems = append(rule.allItems, item)
136+
}
135137
}
136138
if len(options.WIFIBSSID) > 0 {
137-
item := NewWIFIBSSIDItem(router, options.WIFIBSSID)
138-
rule.items = append(rule.items, item)
139-
rule.allItems = append(rule.allItems, item)
139+
if router != nil {
140+
item := NewWIFIBSSIDItem(router, options.WIFIBSSID)
141+
rule.items = append(rule.items, item)
142+
rule.allItems = append(rule.allItems, item)
143+
}
140144
}
141145
return rule, nil
142146
}

0 commit comments

Comments
 (0)