parent
5f3c47e6c3
commit
5ef85697f3
2 changed files with 57 additions and 6 deletions
|
|
@ -19,6 +19,19 @@ const (
|
|||
ProtocolUDP
|
||||
)
|
||||
|
||||
func (p Protocol) String() string {
|
||||
switch p {
|
||||
case ProtocolBoth:
|
||||
return "tcp+udp"
|
||||
case ProtocolTCP:
|
||||
return "tcp"
|
||||
case ProtocolUDP:
|
||||
return "udp"
|
||||
default:
|
||||
return fmt.Sprintf("Protocol(%d)", int(p))
|
||||
}
|
||||
}
|
||||
|
||||
type Outbound interface {
|
||||
any
|
||||
}
|
||||
|
|
@ -63,12 +76,22 @@ type matchResult[O Outbound] struct {
|
|||
|
||||
type compiledRuleSetImpl[O Outbound] struct {
|
||||
Rules []compiledRule[O]
|
||||
Cache *lru.Cache[string, matchResult[O]] // key: HostInfo.String()
|
||||
Cache *lru.Cache[matchResultCacheKey, matchResult[O]] // key: HostInfo.String()
|
||||
}
|
||||
|
||||
type matchResultCacheKey struct {
|
||||
Host string
|
||||
Proto Protocol
|
||||
Port uint16
|
||||
}
|
||||
|
||||
func (s *compiledRuleSetImpl[O]) Match(host HostInfo, proto Protocol, port uint16) (O, net.IP) {
|
||||
host.Name = strings.ToLower(host.Name) // Normalize host name to lower case
|
||||
key := host.String()
|
||||
key := matchResultCacheKey{
|
||||
Host: host.String(),
|
||||
Proto: proto,
|
||||
Port: port,
|
||||
}
|
||||
if result, ok := s.Cache.Get(key); ok {
|
||||
return result.Outbound, result.HijackAddress
|
||||
}
|
||||
|
|
@ -130,7 +153,7 @@ func Compile[O Outbound](rules []TextRule, outbounds map[string]O,
|
|||
}
|
||||
compiledRules[i] = compiledRule[O]{outbound, hm, proto, startPort, endPort, hijackAddress}
|
||||
}
|
||||
cache, err := lru.New[string, matchResult[O]](cacheSize)
|
||||
cache, err := lru.New[matchResultCacheKey, matchResult[O]](cacheSize)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package acl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"testing"
|
||||
|
||||
|
|
@ -177,6 +178,30 @@ func TestCompile(t *testing.T) {
|
|||
wantOutbound: ob1,
|
||||
wantIP: net.ParseIP("2.2.2.2"),
|
||||
},
|
||||
{
|
||||
host: HostInfo{
|
||||
Name: "crap.v2ex.com",
|
||||
},
|
||||
proto: ProtocolTCP,
|
||||
port: 81,
|
||||
wantOutbound: 0,
|
||||
},
|
||||
{
|
||||
host: HostInfo{
|
||||
Name: "crap.v2ex.com",
|
||||
},
|
||||
proto: ProtocolUDP,
|
||||
port: 80,
|
||||
wantOutbound: ob3,
|
||||
},
|
||||
{
|
||||
host: HostInfo{
|
||||
Name: "crap.v2ex.com",
|
||||
},
|
||||
proto: ProtocolUDP,
|
||||
port: 81,
|
||||
wantOutbound: ob3,
|
||||
},
|
||||
{
|
||||
host: HostInfo{
|
||||
IPv4: net.ParseIP("210.140.92.187"),
|
||||
|
|
@ -261,9 +286,12 @@ func TestCompile(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, test := range tests {
|
||||
gotOutbound, gotIP := comp.Match(test.host, test.proto, test.port)
|
||||
assert.Equal(t, test.wantOutbound, gotOutbound)
|
||||
assert.Equal(t, test.wantIP, gotIP)
|
||||
testName := fmt.Sprintf("%s#%s#%d", test.host, test.proto, test.port)
|
||||
t.Run(testName, func(t *testing.T) {
|
||||
gotOutbound, gotIP := comp.Match(test.host, test.proto, test.port)
|
||||
assert.Equal(t, test.wantOutbound, gotOutbound)
|
||||
assert.Equal(t, test.wantIP, gotIP)
|
||||
})
|
||||
}
|
||||
|
||||
// Test Invalid Port Range Rule
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue