Skip to content

Commit 549a9aa

Browse files
committed
feat: New service name rule
1 parent 76024ce commit 549a9aa

File tree

6 files changed

+77
-9
lines changed

6 files changed

+77
-9
lines changed

adapter/metadata.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ type Protocol = uint8
1919

2020
type Metadata struct {
2121
ConnectionID string
22+
ServiceName string
2223
SniffedProtocol Protocol
2324
SourceIP netip.Addr
2425
DestinationHostname string
@@ -30,7 +31,7 @@ type Metadata struct {
3031

3132
func (m *Metadata) GenerateID() {
3233
id := int64(fastrand.Int31())
33-
idColor := fastrand.Intn(len(color.List))
34+
idColor := fastrand.Int31n(int32(len(color.List)))
3435
m.ConnectionID = color.Apply(color.List[idColor], "["+strconv.FormatInt(id, 10)+"]")
3536
}
3637

route/rule.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ func NewRule(logger *log.Logger, config *config.Rule, listMap map[string]set.Str
3333
return NewLogicalAndRule(logger, config, listMap, ruleRegistry)
3434
case "or":
3535
return NewLogicalOrRule(logger, config, listMap, ruleRegistry)
36+
case "ServiceName":
37+
return NewServiceNameRule(config, listMap)
3638
case "SourceIPVersion":
3739
return NewSourceIPVersionRule(config)
3840
case "SourceIP":

route/rule_logic.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ func NewLogicalAndRule(logger *log.Logger, newConfig *config.Rule, listMap map[s
5555
return &RuleLogicalAnd{logicRule}, nil
5656
}
5757

58-
func (r RuleLogicalAnd) Match(metadata *adapter.Metadata) (match bool) {
58+
func (r *RuleLogicalAnd) Match(metadata *adapter.Metadata) (match bool) {
5959
match = true
6060
for _, rule := range r.rules {
6161
if !rule.Match(metadata) {
@@ -83,7 +83,7 @@ func NewLogicalOrRule(logger *log.Logger, newConfig *config.Rule, listMap map[st
8383
return &RuleLogicalOr{logicRule}, nil
8484
}
8585

86-
func (r RuleLogicalOr) Match(metadata *adapter.Metadata) (match bool) {
86+
func (r *RuleLogicalOr) Match(metadata *adapter.Metadata) (match bool) {
8787
for _, rule := range r.rules {
8888
if rule.Match(metadata) {
8989
match = true

route/rule_minecraft.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,11 @@ func NewMinecraftPlayerNameRule(newConfig *config.Rule, listMap map[string]set.S
4545
}, nil
4646
}
4747

48-
func (r RuleMinecraftPlayerName) Config() *config.Rule {
48+
func (r *RuleMinecraftPlayerName) Config() *config.Rule {
4949
return r.config
5050
}
5151

52-
func (r RuleMinecraftPlayerName) Match(metadata *adapter.Metadata) (match bool) {
52+
func (r *RuleMinecraftPlayerName) Match(metadata *adapter.Metadata) (match bool) {
5353
if metadata.Minecraft != nil {
5454
for _, nameSet := range r.sets {
5555
match = nameSet.Has(metadata.Minecraft.PlayerName)

route/rule_service.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package route
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"strings"
7+
8+
"github.com/layou233/zbproxy/v3/adapter"
9+
"github.com/layou233/zbproxy/v3/common/jsonx"
10+
"github.com/layou233/zbproxy/v3/common/set"
11+
"github.com/layou233/zbproxy/v3/config"
12+
)
13+
14+
type RuleServiceName struct {
15+
sets []set.StringSet
16+
config *config.Rule
17+
}
18+
19+
var _ Rule = (*RuleServiceName)(nil)
20+
21+
func NewServiceNameRule(newConfig *config.Rule, listMap map[string]set.StringSet) (Rule, error) {
22+
var serviceList jsonx.Listable[string]
23+
err := json.Unmarshal(newConfig.Parameter, &serviceList)
24+
if err != nil {
25+
return nil, fmt.Errorf("bad service name list %v: %w", newConfig.Parameter, err)
26+
}
27+
sets := []set.StringSet{
28+
{}, // new set for individual names
29+
}
30+
for _, i := range serviceList {
31+
if strings.HasPrefix(i, parameterListPrefix) {
32+
i = strings.TrimPrefix(i, parameterListPrefix)
33+
nameSet, found := listMap[i]
34+
if !found {
35+
return nil, fmt.Errorf("list [%v] is not found", i)
36+
}
37+
sets = append(sets, nameSet)
38+
} else {
39+
sets[0].Add(i)
40+
}
41+
}
42+
return &RuleServiceName{
43+
sets: sets,
44+
config: newConfig,
45+
}, nil
46+
}
47+
48+
func (r RuleServiceName) Config() *config.Rule {
49+
return r.config
50+
}
51+
52+
func (r RuleServiceName) Match(metadata *adapter.Metadata) (match bool) {
53+
for _, nameSet := range r.sets {
54+
match = nameSet.Has(metadata.ServiceName)
55+
if match {
56+
break
57+
}
58+
}
59+
if r.config.Invert {
60+
match = !match
61+
}
62+
return
63+
}

service/service.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,13 @@ func (s *Service) listenLoop() {
5959
s.logger.Warn().Str("service", s.config.Name).Str("ip", ipString).Msg("Rejected by access control")
6060
continue
6161
}
62-
metadata := &adapter.Metadata{}
62+
metadata := &adapter.Metadata{
63+
ServiceName: s.config.Name,
64+
DestinationHostname: s.config.TargetAddress,
65+
DestinationPort: s.config.TargetPort,
66+
SourceIP: common.MustOK(netip.AddrFromSlice(ip)).Unmap(),
67+
}
6368
metadata.GenerateID()
64-
metadata.DestinationHostname = s.config.TargetAddress
65-
metadata.DestinationPort = s.config.TargetPort
66-
metadata.SourceIP = common.MustOK(netip.AddrFromSlice(ip)).Unmap()
6769
s.logger.Info().Str("id", metadata.ConnectionID).Str("service", s.config.Name).
6870
Str("ip", ipString).Msg("New inbound connection")
6971
if s.legacyOutbound != nil {

0 commit comments

Comments
 (0)