Merge remote-tracking branch 'yaling888/with-tun' into Alpha
# Conflicts: # .github/workflows/codeql-analysis.yml # .github/workflows/linter.yml # .github/workflows/release.yml # Makefile # README.md # adapter/outbound/vless.go # component/geodata/memconservative/cache.go # component/geodata/router/condition.go # component/geodata/router/condition_geoip.go # component/geodata/standard/standard.go # component/geodata/utils.go # config/config.go # config/initial.go # constant/metadata.go # constant/path.go # constant/rule.go # constant/rule_extra.go # dns/client.go # dns/filters.go # dns/resolver.go # go.mod # go.sum # hub/executor/executor.go # hub/route/configs.go # listener/listener.go # listener/tproxy/tproxy_linux_iptables.go # listener/tun/dev/dev.go # listener/tun/dev/dev_darwin.go # listener/tun/dev/dev_linux.go # listener/tun/dev/dev_windows.go # listener/tun/dev/wintun/config.go # listener/tun/dev/wintun/dll_windows.go # listener/tun/dev/wintun/session_windows.go # listener/tun/dev/wintun/wintun_windows.go # listener/tun/ipstack/commons/dns.go # listener/tun/ipstack/gvisor/tun.go # listener/tun/ipstack/gvisor/tundns.go # listener/tun/ipstack/gvisor/utils.go # listener/tun/ipstack/stack_adapter.go # listener/tun/ipstack/system/dns.go # listener/tun/ipstack/system/tcp.go # listener/tun/ipstack/system/tun.go # listener/tun/tun_adapter.go # main.go # rule/common/base.go # rule/common/domain.go # rule/common/domain_keyword.go # rule/common/domain_suffix.go # rule/common/final.go # rule/common/geoip.go # rule/common/geosite.go # rule/common/ipcidr.go # rule/common/port.go # rule/parser.go # rule/process.go # test/go.mod # test/go.sum # transport/vless/xtls.go # tunnel/tunnel.go
This commit is contained in:
@ -14,6 +14,22 @@ var (
|
||||
noResolve = "no-resolve"
|
||||
)
|
||||
|
||||
type Base struct {
|
||||
ruleExtra *C.RuleExtra
|
||||
}
|
||||
|
||||
func (b *Base) RuleExtra() *C.RuleExtra {
|
||||
return b.ruleExtra
|
||||
}
|
||||
|
||||
func (b *Base) SetRuleExtra(re *C.RuleExtra) {
|
||||
b.ruleExtra = re
|
||||
}
|
||||
|
||||
func (b *Base) ShouldFindProcess() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func HasNoResolve(params []string) bool {
|
||||
for _, p := range params {
|
||||
if p == noResolve {
|
||||
@ -25,9 +41,9 @@ func HasNoResolve(params []string) bool {
|
||||
|
||||
func FindNetwork(params []string) C.NetWork {
|
||||
for _, p := range params {
|
||||
if p == "tcp" {
|
||||
if strings.EqualFold(p, "tcp") {
|
||||
return C.TCP
|
||||
} else if p == "udp" {
|
||||
} else if strings.EqualFold(p, "udp") {
|
||||
return C.UDP
|
||||
}
|
||||
}
|
||||
|
@ -7,9 +7,9 @@ import (
|
||||
)
|
||||
|
||||
type Domain struct {
|
||||
domain string
|
||||
adapter string
|
||||
ruleExtra *C.RuleExtra
|
||||
*Base
|
||||
domain string
|
||||
adapter string
|
||||
}
|
||||
|
||||
func (d *Domain) RuleType() C.RuleType {
|
||||
@ -35,18 +35,16 @@ func (d *Domain) ShouldResolveIP() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (d *Domain) RuleExtra() *C.RuleExtra {
|
||||
return d.ruleExtra
|
||||
}
|
||||
|
||||
func (d *Domain) ShouldFindProcess() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func NewDomain(domain string, adapter string, ruleExtra *C.RuleExtra) *Domain {
|
||||
func NewDomain(domain string, adapter string) *Domain {
|
||||
return &Domain{
|
||||
domain: strings.ToLower(domain),
|
||||
adapter: adapter,
|
||||
ruleExtra: ruleExtra,
|
||||
Base: &Base{},
|
||||
domain: strings.ToLower(domain),
|
||||
adapter: adapter,
|
||||
}
|
||||
}
|
||||
|
||||
var _ C.Rule = (*Domain)(nil)
|
||||
|
@ -7,9 +7,9 @@ import (
|
||||
)
|
||||
|
||||
type DomainKeyword struct {
|
||||
keyword string
|
||||
adapter string
|
||||
ruleExtra *C.RuleExtra
|
||||
*Base
|
||||
keyword string
|
||||
adapter string
|
||||
}
|
||||
|
||||
func (dk *DomainKeyword) RuleType() C.RuleType {
|
||||
@ -40,14 +40,12 @@ func (dk *DomainKeyword) ShouldFindProcess() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (dk *DomainKeyword) RuleExtra() *C.RuleExtra {
|
||||
return dk.ruleExtra
|
||||
}
|
||||
|
||||
func NewDomainKeyword(keyword string, adapter string, ruleExtra *C.RuleExtra) *DomainKeyword {
|
||||
func NewDomainKeyword(keyword string, adapter string) *DomainKeyword {
|
||||
return &DomainKeyword{
|
||||
keyword: strings.ToLower(keyword),
|
||||
adapter: adapter,
|
||||
ruleExtra: ruleExtra,
|
||||
Base: &Base{},
|
||||
keyword: strings.ToLower(keyword),
|
||||
adapter: adapter,
|
||||
}
|
||||
}
|
||||
|
||||
var _ C.Rule = (*DomainKeyword)(nil)
|
||||
|
@ -7,9 +7,9 @@ import (
|
||||
)
|
||||
|
||||
type DomainSuffix struct {
|
||||
suffix string
|
||||
adapter string
|
||||
ruleExtra *C.RuleExtra
|
||||
*Base
|
||||
suffix string
|
||||
adapter string
|
||||
}
|
||||
|
||||
func (ds *DomainSuffix) RuleType() C.RuleType {
|
||||
@ -36,19 +36,16 @@ func (ds *DomainSuffix) ShouldResolveIP() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (ds *DomainSuffix) RuleExtra() *C.RuleExtra {
|
||||
return ds.ruleExtra
|
||||
}
|
||||
|
||||
|
||||
func (ds *DomainSuffix) ShouldFindProcess() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func NewDomainSuffix(suffix string, adapter string, ruleExtra *C.RuleExtra) *DomainSuffix {
|
||||
func NewDomainSuffix(suffix string, adapter string) *DomainSuffix {
|
||||
return &DomainSuffix{
|
||||
suffix: strings.ToLower(suffix),
|
||||
adapter: adapter,
|
||||
ruleExtra: ruleExtra,
|
||||
Base: &Base{},
|
||||
suffix: strings.ToLower(suffix),
|
||||
adapter: adapter,
|
||||
}
|
||||
}
|
||||
|
||||
var _ C.Rule = (*DomainSuffix)(nil)
|
||||
|
@ -5,8 +5,8 @@ import (
|
||||
)
|
||||
|
||||
type Match struct {
|
||||
adapter string
|
||||
ruleExtra *C.RuleExtra
|
||||
*Base
|
||||
adapter string
|
||||
}
|
||||
|
||||
func (f *Match) RuleType() C.RuleType {
|
||||
@ -33,16 +33,11 @@ func (f *Match) ShouldFindProcess() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (f *Match) RuleExtra() *C.RuleExtra {
|
||||
return f.ruleExtra
|
||||
func NewMatch(adapter string) *Match {
|
||||
return &Match{
|
||||
Base: &Base{},
|
||||
adapter: adapter,
|
||||
}
|
||||
}
|
||||
|
||||
func NewMatch(adapter string, ruleExtra *C.RuleExtra) *Match {
|
||||
if ruleExtra.SourceIPs == nil {
|
||||
ruleExtra = nil
|
||||
}
|
||||
return &Match{
|
||||
adapter: adapter,
|
||||
ruleExtra: ruleExtra,
|
||||
}
|
||||
}
|
||||
var _ C.Rule = (*Match)(nil)
|
||||
|
@ -4,18 +4,19 @@ import (
|
||||
"fmt"
|
||||
"github.com/Dreamacro/clash/component/geodata"
|
||||
"github.com/Dreamacro/clash/component/geodata/router"
|
||||
"github.com/Dreamacro/clash/component/mmdb"
|
||||
"strings"
|
||||
|
||||
"github.com/Dreamacro/clash/component/mmdb"
|
||||
"github.com/Dreamacro/clash/component/resolver"
|
||||
C "github.com/Dreamacro/clash/constant"
|
||||
"github.com/Dreamacro/clash/log"
|
||||
)
|
||||
|
||||
type GEOIP struct {
|
||||
country string
|
||||
adapter string
|
||||
noResolveIP bool
|
||||
ruleExtra *C.RuleExtra
|
||||
*Base
|
||||
country string
|
||||
adapter string
|
||||
noResolveIP bool
|
||||
geoIPMatcher *router.GeoIPMatcher
|
||||
}
|
||||
|
||||
@ -33,8 +34,13 @@ func (g *GEOIP) Match(metadata *C.Metadata) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
if strings.EqualFold(g.country, "LAN") || C.TunBroadcastAddr.Equal(ip) {
|
||||
return ip.IsPrivate()
|
||||
if strings.EqualFold(g.country, "LAN") {
|
||||
return ip.IsPrivate() ||
|
||||
ip.IsUnspecified() ||
|
||||
ip.IsLoopback() ||
|
||||
ip.IsMulticast() ||
|
||||
ip.IsLinkLocalUnicast() ||
|
||||
resolver.IsFakeBroadcastIP(ip)
|
||||
}
|
||||
if !C.GeodataMode {
|
||||
record, _ := mmdb.Instance().Country(ip)
|
||||
@ -55,10 +61,6 @@ func (g *GEOIP) ShouldResolveIP() bool {
|
||||
return !g.noResolveIP
|
||||
}
|
||||
|
||||
func (g *GEOIP) RuleExtra() *C.RuleExtra {
|
||||
return g.ruleExtra
|
||||
}
|
||||
|
||||
func (g *GEOIP) GetCountry() string {
|
||||
return g.country
|
||||
}
|
||||
@ -67,13 +69,13 @@ func (g *GEOIP) GetIPMatcher() *router.GeoIPMatcher {
|
||||
return g.geoIPMatcher
|
||||
}
|
||||
|
||||
func NewGEOIP(country string, adapter string, noResolveIP bool, ruleExtra *C.RuleExtra) (*GEOIP, error) {
|
||||
func NewGEOIP(country string, adapter string, noResolveIP bool) (*GEOIP, error) {
|
||||
if !C.GeodataMode {
|
||||
geoip := &GEOIP{
|
||||
Base: &Base{},
|
||||
country: country,
|
||||
adapter: adapter,
|
||||
noResolveIP: noResolveIP,
|
||||
ruleExtra: ruleExtra,
|
||||
}
|
||||
return geoip, nil
|
||||
}
|
||||
@ -85,11 +87,13 @@ func NewGEOIP(country string, adapter string, noResolveIP bool, ruleExtra *C.Rul
|
||||
|
||||
log.Infoln("Start initial GeoIP rule %s => %s, records: %d", country, adapter, recordsCount)
|
||||
geoip := &GEOIP{
|
||||
Base: &Base{},
|
||||
country: country,
|
||||
adapter: adapter,
|
||||
noResolveIP: noResolveIP,
|
||||
ruleExtra: ruleExtra,
|
||||
geoIPMatcher: geoIPMatcher,
|
||||
}
|
||||
return geoip, nil
|
||||
}
|
||||
|
||||
var _ C.Rule = (*GEOIP)(nil)
|
||||
|
@ -13,10 +13,10 @@ import (
|
||||
)
|
||||
|
||||
type GEOSITE struct {
|
||||
country string
|
||||
adapter string
|
||||
ruleExtra *C.RuleExtra
|
||||
matcher *router.DomainMatcher
|
||||
*Base
|
||||
country string
|
||||
adapter string
|
||||
matcher *router.DomainMatcher
|
||||
}
|
||||
|
||||
func (gs *GEOSITE) RuleType() C.RuleType {
|
||||
@ -48,10 +48,6 @@ func (gs *GEOSITE) ShouldFindProcess() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (gs *GEOSITE) RuleExtra() *C.RuleExtra {
|
||||
return gs.ruleExtra
|
||||
}
|
||||
|
||||
func (gs *GEOSITE) GetDomainMatcher() *router.DomainMatcher {
|
||||
return gs.matcher
|
||||
}
|
||||
@ -65,11 +61,13 @@ func NewGEOSITE(country string, adapter string, ruleExtra *C.RuleExtra) (*GEOSIT
|
||||
log.Infoln("Start initial GeoSite rule %s => %s, records: %d", country, adapter, recordsCount)
|
||||
|
||||
geoSite := &GEOSITE{
|
||||
country: country,
|
||||
adapter: adapter,
|
||||
ruleExtra: ruleExtra,
|
||||
matcher: matcher,
|
||||
Base: &Base{},
|
||||
country: country,
|
||||
adapter: adapter,
|
||||
matcher: matcher,
|
||||
}
|
||||
|
||||
return geoSite, nil
|
||||
}
|
||||
|
||||
var _ C.Rule = (*GEOSITE)(nil)
|
||||
|
@ -21,9 +21,9 @@ func WithIPCIDRNoResolve(noResolve bool) IPCIDROption {
|
||||
}
|
||||
|
||||
type IPCIDR struct {
|
||||
*Base
|
||||
ipnet *net.IPNet
|
||||
adapter string
|
||||
ruleExtra *C.RuleExtra
|
||||
isSourceIP bool
|
||||
noResolveIP bool
|
||||
}
|
||||
@ -59,20 +59,16 @@ func (i *IPCIDR) ShouldFindProcess() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (i *IPCIDR) RuleExtra() *C.RuleExtra {
|
||||
return i.ruleExtra
|
||||
}
|
||||
|
||||
func NewIPCIDR(s string, adapter string, ruleExtra *C.RuleExtra, opts ...IPCIDROption) (*IPCIDR, error) {
|
||||
func NewIPCIDR(s string, adapter string, opts ...IPCIDROption) (*IPCIDR, error) {
|
||||
_, ipnet, err := net.ParseCIDR(s)
|
||||
if err != nil {
|
||||
return nil, errPayload
|
||||
}
|
||||
|
||||
ipcidr := &IPCIDR{
|
||||
ipnet: ipnet,
|
||||
adapter: adapter,
|
||||
ruleExtra: ruleExtra,
|
||||
Base: &Base{},
|
||||
ipnet: ipnet,
|
||||
adapter: adapter,
|
||||
}
|
||||
|
||||
for _, o := range opts {
|
||||
@ -81,3 +77,5 @@ func NewIPCIDR(s string, adapter string, ruleExtra *C.RuleExtra, opts ...IPCIDRO
|
||||
|
||||
return ipcidr, nil
|
||||
}
|
||||
|
||||
var _ C.Rule = (*IPCIDR)(nil)
|
||||
|
@ -14,11 +14,11 @@ type portReal struct {
|
||||
}
|
||||
|
||||
type Port struct {
|
||||
adapter string
|
||||
port string
|
||||
isSource bool
|
||||
portList []portReal
|
||||
ruleExtra *C.RuleExtra
|
||||
*Base
|
||||
adapter string
|
||||
port string
|
||||
isSource bool
|
||||
portList []portReal
|
||||
}
|
||||
|
||||
func (p *Port) ShouldFindProcess() bool {
|
||||
@ -51,16 +51,8 @@ func (p *Port) ShouldResolveIP() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (p *Port) RuleExtra() *C.RuleExtra {
|
||||
return p.ruleExtra
|
||||
}
|
||||
|
||||
func (p *Port) matchPortReal(portRef string) bool {
|
||||
port, err := strconv.Atoi(portRef)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
port, _ := strconv.Atoi(portRef)
|
||||
var rs bool
|
||||
for _, pr := range p.portList {
|
||||
if pr.portEnd == -1 {
|
||||
@ -75,7 +67,7 @@ func (p *Port) matchPortReal(portRef string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func NewPort(port string, adapter string, isSource bool, ruleExtra *C.RuleExtra) (*Port, error) {
|
||||
func NewPort(port string, adapter string, isSource bool) (*Port, error) {
|
||||
ports := strings.Split(port, "/")
|
||||
if len(ports) > 28 {
|
||||
return nil, fmt.Errorf("%s, too many ports to use, maximum support 28 ports", errPayload.Error())
|
||||
@ -93,24 +85,25 @@ func NewPort(port string, adapter string, isSource bool, ruleExtra *C.RuleExtra)
|
||||
return nil, errPayload
|
||||
}
|
||||
|
||||
portStart, err := strconv.Atoi(strings.Trim(subPorts[0], "[ ]"))
|
||||
if err != nil || portStart < 0 || portStart > 65535 {
|
||||
portStart, err := strconv.ParseUint(strings.Trim(subPorts[0], "[ ]"), 10, 16)
|
||||
if err != nil {
|
||||
return nil, errPayload
|
||||
}
|
||||
|
||||
if subPortsLen == 1 {
|
||||
portList = append(portList, portReal{portStart, -1})
|
||||
} else if subPortsLen == 2 {
|
||||
portEnd, err1 := strconv.Atoi(strings.Trim(subPorts[1], "[ ]"))
|
||||
if err1 != nil || portEnd < 0 || portEnd > 65535 {
|
||||
switch subPortsLen {
|
||||
case 1:
|
||||
portList = append(portList, portReal{int(portStart), -1})
|
||||
case 2:
|
||||
portEnd, err := strconv.ParseUint(strings.Trim(subPorts[1], "[ ]"), 10, 16)
|
||||
if err != nil {
|
||||
return nil, errPayload
|
||||
}
|
||||
|
||||
shouldReverse := portStart > portEnd
|
||||
if shouldReverse {
|
||||
portList = append(portList, portReal{portEnd, portStart})
|
||||
portList = append(portList, portReal{int(portEnd), int(portStart)})
|
||||
} else {
|
||||
portList = append(portList, portReal{portStart, portEnd})
|
||||
portList = append(portList, portReal{int(portStart), int(portEnd)})
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -120,10 +113,12 @@ func NewPort(port string, adapter string, isSource bool, ruleExtra *C.RuleExtra)
|
||||
}
|
||||
|
||||
return &Port{
|
||||
adapter: adapter,
|
||||
port: port,
|
||||
isSource: isSource,
|
||||
portList: portList,
|
||||
ruleExtra: ruleExtra,
|
||||
Base: &Base{},
|
||||
adapter: adapter,
|
||||
port: port,
|
||||
isSource: isSource,
|
||||
portList: portList,
|
||||
}, nil
|
||||
}
|
||||
|
||||
var _ C.Rule = (*Port)(nil)
|
||||
|
@ -14,41 +14,35 @@ func ParseRule(tp, payload, target string, params []string) (C.Rule, error) {
|
||||
parsed C.Rule
|
||||
)
|
||||
|
||||
ruleExtra := &C.RuleExtra{
|
||||
Network: RC.FindNetwork(params),
|
||||
SourceIPs: RC.FindSourceIPs(params),
|
||||
ProcessNames: RC.FindProcessName(params),
|
||||
}
|
||||
|
||||
switch tp {
|
||||
case "DOMAIN":
|
||||
parsed = RC.NewDomain(payload, target, ruleExtra)
|
||||
parsed = RC.NewDomain(payload, target)
|
||||
case "DOMAIN-SUFFIX":
|
||||
parsed = RC.NewDomainSuffix(payload, target, ruleExtra)
|
||||
parsed = RC.NewDomainSuffix(payload, target)
|
||||
case "DOMAIN-KEYWORD":
|
||||
parsed = RC.NewDomainKeyword(payload, target, ruleExtra)
|
||||
parsed = RC.NewDomainKeyword(payload, target)
|
||||
case "GEOSITE":
|
||||
parsed, parseErr = RC.NewGEOSITE(payload, target, ruleExtra)
|
||||
parsed, parseErr = RC.NewGEOSITE(payload, target)
|
||||
case "GEOIP":
|
||||
noResolve := RC.HasNoResolve(params)
|
||||
parsed, parseErr = RC.NewGEOIP(payload, target, noResolve, ruleExtra)
|
||||
parsed, parseErr = RC.NewGEOIP(payload, target, noResolve)
|
||||
case "IP-CIDR", "IP-CIDR6":
|
||||
noResolve := RC.HasNoResolve(params)
|
||||
parsed, parseErr = RC.NewIPCIDR(payload, target, ruleExtra, RC.WithIPCIDRNoResolve(noResolve))
|
||||
parsed, parseErr = RC.NewIPCIDR(payload, target, RC.WithIPCIDRNoResolve(noResolve))
|
||||
case "SRC-IP-CIDR":
|
||||
parsed, parseErr = RC.NewIPCIDR(payload, target, ruleExtra, RC.WithIPCIDRSourceIP(true), RC.WithIPCIDRNoResolve(true))
|
||||
parsed, parseErr = RC.NewIPCIDR(payload, target, RC.WithIPCIDRSourceIP(true), RC.WithIPCIDRNoResolve(true))
|
||||
case "SRC-PORT":
|
||||
parsed, parseErr = RC.NewPort(payload, target, true, ruleExtra)
|
||||
parsed, parseErr = RC.NewPort(payload, target, true)
|
||||
case "DST-PORT":
|
||||
parsed, parseErr = RC.NewPort(payload, target, false, ruleExtra)
|
||||
parsed, parseErr = RC.NewPort(payload, target, false)
|
||||
case "PROCESS-NAME":
|
||||
parsed, parseErr = RC.NewProcess(payload, target, true,ruleExtra)
|
||||
parsed, parseErr = RC.NewProcess(payload, target, true)
|
||||
case "PROCESS-PATH":
|
||||
parsed, parseErr = RC.NewProcess(payload, target, false,ruleExtra)
|
||||
parsed, parseErr = RC.NewProcess(payload, target, false)
|
||||
case "MATCH":
|
||||
parsed = RC.NewMatch(target, ruleExtra)
|
||||
parsed = RC.NewMatch(target)
|
||||
case "RULE-SET":
|
||||
parsed, parseErr = RP.NewRuleSet(payload, target, ruleExtra)
|
||||
parsed, parseErr = RP.NewRuleSet(payload, target)
|
||||
case "NETWORK":
|
||||
parsed, parseErr = RC.NewNetworkType(payload, target)
|
||||
case "AND":
|
||||
@ -61,5 +55,17 @@ func ParseRule(tp, payload, target string, params []string) (C.Rule, error) {
|
||||
parseErr = fmt.Errorf("unsupported rule type %s", tp)
|
||||
}
|
||||
|
||||
return parsed, parseErr
|
||||
if parseErr != nil {
|
||||
return nil, parseErr
|
||||
}
|
||||
|
||||
ruleExtra := &C.RuleExtra{
|
||||
Network: RC.FindNetwork(params),
|
||||
SourceIPs: RC.FindSourceIPs(params),
|
||||
ProcessNames: RC.FindProcessName(params),
|
||||
}
|
||||
|
||||
parsed.SetRuleExtra(ruleExtra)
|
||||
|
||||
return parsed, nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user