[Feature]
1.Add Network rule, match network type(TCP/UDP) 2.Add logic rules(NOT,OR,AND) -AND,((DOMAIN,baidu.com),(NETWORK,UDP)),REJECT (cherry picked from commit d7092e2e37f2c48282c878edea1b2ebc2912b09a)
This commit is contained in:
53
rule/common/base.go
Normal file
53
rule/common/base.go
Normal file
@ -0,0 +1,53 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
|
||||
C "github.com/Dreamacro/clash/constant"
|
||||
)
|
||||
|
||||
var (
|
||||
errPayload = errors.New("payload error")
|
||||
|
||||
noResolve = "no-resolve"
|
||||
)
|
||||
|
||||
func HasNoResolve(params []string) bool {
|
||||
for _, p := range params {
|
||||
if p == noResolve {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func FindNetwork(params []string) C.NetWork {
|
||||
for _, p := range params {
|
||||
if p == "tcp" {
|
||||
return C.TCP
|
||||
} else if p == "udp" {
|
||||
return C.UDP
|
||||
}
|
||||
}
|
||||
return C.ALLNet
|
||||
}
|
||||
|
||||
func FindSourceIPs(params []string) []*net.IPNet {
|
||||
var ips []*net.IPNet
|
||||
for _, p := range params {
|
||||
if p == noResolve || len(p) < 7 {
|
||||
continue
|
||||
}
|
||||
_, ipnet, err := net.ParseCIDR(p)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
ips = append(ips, ipnet)
|
||||
}
|
||||
|
||||
if len(ips) > 0 {
|
||||
return ips
|
||||
}
|
||||
return nil
|
||||
}
|
48
rule/common/domain.go
Normal file
48
rule/common/domain.go
Normal file
@ -0,0 +1,48 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
C "github.com/Dreamacro/clash/constant"
|
||||
)
|
||||
|
||||
type Domain struct {
|
||||
domain string
|
||||
adapter string
|
||||
ruleExtra *C.RuleExtra
|
||||
}
|
||||
|
||||
func (d *Domain) RuleType() C.RuleType {
|
||||
return C.Domain
|
||||
}
|
||||
|
||||
func (d *Domain) Match(metadata *C.Metadata) bool {
|
||||
if metadata.AddrType != C.AtypDomainName {
|
||||
return false
|
||||
}
|
||||
return metadata.Host == d.domain
|
||||
}
|
||||
|
||||
func (d *Domain) Adapter() string {
|
||||
return d.adapter
|
||||
}
|
||||
|
||||
func (d *Domain) Payload() string {
|
||||
return d.domain
|
||||
}
|
||||
|
||||
func (d *Domain) ShouldResolveIP() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (d *Domain) RuleExtra() *C.RuleExtra {
|
||||
return d.ruleExtra
|
||||
}
|
||||
|
||||
func NewDomain(domain string, adapter string, ruleExtra *C.RuleExtra) *Domain {
|
||||
return &Domain{
|
||||
domain: strings.ToLower(domain),
|
||||
adapter: adapter,
|
||||
ruleExtra: ruleExtra,
|
||||
}
|
||||
}
|
49
rule/common/domain_keyword.go
Normal file
49
rule/common/domain_keyword.go
Normal file
@ -0,0 +1,49 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
C "github.com/Dreamacro/clash/constant"
|
||||
)
|
||||
|
||||
type DomainKeyword struct {
|
||||
keyword string
|
||||
adapter string
|
||||
ruleExtra *C.RuleExtra
|
||||
}
|
||||
|
||||
func (dk *DomainKeyword) RuleType() C.RuleType {
|
||||
return C.DomainKeyword
|
||||
}
|
||||
|
||||
func (dk *DomainKeyword) Match(metadata *C.Metadata) bool {
|
||||
if metadata.AddrType != C.AtypDomainName {
|
||||
return false
|
||||
}
|
||||
domain := metadata.Host
|
||||
return strings.Contains(domain, dk.keyword)
|
||||
}
|
||||
|
||||
func (dk *DomainKeyword) Adapter() string {
|
||||
return dk.adapter
|
||||
}
|
||||
|
||||
func (dk *DomainKeyword) Payload() string {
|
||||
return dk.keyword
|
||||
}
|
||||
|
||||
func (dk *DomainKeyword) ShouldResolveIP() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (dk *DomainKeyword) RuleExtra() *C.RuleExtra {
|
||||
return dk.ruleExtra
|
||||
}
|
||||
|
||||
func NewDomainKeyword(keyword string, adapter string, ruleExtra *C.RuleExtra) *DomainKeyword {
|
||||
return &DomainKeyword{
|
||||
keyword: strings.ToLower(keyword),
|
||||
adapter: adapter,
|
||||
ruleExtra: ruleExtra,
|
||||
}
|
||||
}
|
49
rule/common/domain_suffix.go
Normal file
49
rule/common/domain_suffix.go
Normal file
@ -0,0 +1,49 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
C "github.com/Dreamacro/clash/constant"
|
||||
)
|
||||
|
||||
type DomainSuffix struct {
|
||||
suffix string
|
||||
adapter string
|
||||
ruleExtra *C.RuleExtra
|
||||
}
|
||||
|
||||
func (ds *DomainSuffix) RuleType() C.RuleType {
|
||||
return C.DomainSuffix
|
||||
}
|
||||
|
||||
func (ds *DomainSuffix) Match(metadata *C.Metadata) bool {
|
||||
if metadata.AddrType != C.AtypDomainName {
|
||||
return false
|
||||
}
|
||||
domain := metadata.Host
|
||||
return strings.HasSuffix(domain, "."+ds.suffix) || domain == ds.suffix
|
||||
}
|
||||
|
||||
func (ds *DomainSuffix) Adapter() string {
|
||||
return ds.adapter
|
||||
}
|
||||
|
||||
func (ds *DomainSuffix) Payload() string {
|
||||
return ds.suffix
|
||||
}
|
||||
|
||||
func (ds *DomainSuffix) ShouldResolveIP() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (ds *DomainSuffix) RuleExtra() *C.RuleExtra {
|
||||
return ds.ruleExtra
|
||||
}
|
||||
|
||||
func NewDomainSuffix(suffix string, adapter string, ruleExtra *C.RuleExtra) *DomainSuffix {
|
||||
return &DomainSuffix{
|
||||
suffix: strings.ToLower(suffix),
|
||||
adapter: adapter,
|
||||
ruleExtra: ruleExtra,
|
||||
}
|
||||
}
|
44
rule/common/final.go
Normal file
44
rule/common/final.go
Normal file
@ -0,0 +1,44 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
C "github.com/Dreamacro/clash/constant"
|
||||
)
|
||||
|
||||
type Match struct {
|
||||
adapter string
|
||||
ruleExtra *C.RuleExtra
|
||||
}
|
||||
|
||||
func (f *Match) RuleType() C.RuleType {
|
||||
return C.MATCH
|
||||
}
|
||||
|
||||
func (f *Match) Match(metadata *C.Metadata) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (f *Match) Adapter() string {
|
||||
return f.adapter
|
||||
}
|
||||
|
||||
func (f *Match) Payload() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (f *Match) ShouldResolveIP() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (f *Match) RuleExtra() *C.RuleExtra {
|
||||
return f.ruleExtra
|
||||
}
|
||||
|
||||
func NewMatch(adapter string, ruleExtra *C.RuleExtra) *Match {
|
||||
if ruleExtra.SourceIPs == nil {
|
||||
ruleExtra = nil
|
||||
}
|
||||
return &Match{
|
||||
adapter: adapter,
|
||||
ruleExtra: ruleExtra,
|
||||
}
|
||||
}
|
63
rule/common/geoip.go
Normal file
63
rule/common/geoip.go
Normal file
@ -0,0 +1,63 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/Dreamacro/clash/component/mmdb"
|
||||
C "github.com/Dreamacro/clash/constant"
|
||||
)
|
||||
|
||||
type GEOIP struct {
|
||||
country string
|
||||
adapter string
|
||||
noResolveIP bool
|
||||
ruleExtra *C.RuleExtra
|
||||
}
|
||||
|
||||
func (g *GEOIP) RuleType() C.RuleType {
|
||||
return C.GEOIP
|
||||
}
|
||||
|
||||
func (g *GEOIP) Match(metadata *C.Metadata) bool {
|
||||
ip := metadata.DstIP
|
||||
if ip == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if strings.EqualFold(g.country, "LAN") || C.TunBroadcastAddr.Equal(ip) {
|
||||
return ip.IsPrivate()
|
||||
}
|
||||
record, _ := mmdb.Instance().Country(ip)
|
||||
return strings.EqualFold(record.Country.IsoCode, g.country)
|
||||
}
|
||||
|
||||
func (g *GEOIP) Adapter() string {
|
||||
return g.adapter
|
||||
}
|
||||
|
||||
func (g *GEOIP) Payload() string {
|
||||
return g.country
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
func NewGEOIP(country string, adapter string, noResolveIP bool, ruleExtra *C.RuleExtra) (*GEOIP, error) {
|
||||
geoip := &GEOIP{
|
||||
country: country,
|
||||
adapter: adapter,
|
||||
noResolveIP: noResolveIP,
|
||||
ruleExtra: ruleExtra,
|
||||
}
|
||||
|
||||
return geoip, nil
|
||||
}
|
70
rule/common/geosite.go
Normal file
70
rule/common/geosite.go
Normal file
@ -0,0 +1,70 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/Dreamacro/clash/component/geodata"
|
||||
"github.com/Dreamacro/clash/component/geodata/router"
|
||||
C "github.com/Dreamacro/clash/constant"
|
||||
"github.com/Dreamacro/clash/log"
|
||||
|
||||
_ "github.com/Dreamacro/clash/component/geodata/standard"
|
||||
)
|
||||
|
||||
type GEOSITE struct {
|
||||
country string
|
||||
adapter string
|
||||
ruleExtra *C.RuleExtra
|
||||
matcher *router.DomainMatcher
|
||||
}
|
||||
|
||||
func (gs *GEOSITE) RuleType() C.RuleType {
|
||||
return C.GEOSITE
|
||||
}
|
||||
|
||||
func (gs *GEOSITE) Match(metadata *C.Metadata) bool {
|
||||
if metadata.AddrType != C.AtypDomainName {
|
||||
return false
|
||||
}
|
||||
|
||||
domain := metadata.Host
|
||||
return gs.matcher.ApplyDomain(domain)
|
||||
}
|
||||
|
||||
func (gs *GEOSITE) Adapter() string {
|
||||
return gs.adapter
|
||||
}
|
||||
|
||||
func (gs *GEOSITE) Payload() string {
|
||||
return gs.country
|
||||
}
|
||||
|
||||
func (gs *GEOSITE) ShouldResolveIP() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (gs *GEOSITE) RuleExtra() *C.RuleExtra {
|
||||
return gs.ruleExtra
|
||||
}
|
||||
|
||||
func (gs *GEOSITE) GetDomainMatcher() *router.DomainMatcher {
|
||||
return gs.matcher
|
||||
}
|
||||
|
||||
func NewGEOSITE(country string, adapter string, ruleExtra *C.RuleExtra) (*GEOSITE, error) {
|
||||
matcher, recordsCount, err := geodata.LoadGeoSiteMatcher(country)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load GeoSite data error, %s", err.Error())
|
||||
}
|
||||
|
||||
log.Infoln("Start initial GeoSite rule %s => %s, records: %d", country, adapter, recordsCount)
|
||||
|
||||
geoSite := &GEOSITE{
|
||||
country: country,
|
||||
adapter: adapter,
|
||||
ruleExtra: ruleExtra,
|
||||
matcher: matcher,
|
||||
}
|
||||
|
||||
return geoSite, nil
|
||||
}
|
79
rule/common/ipcidr.go
Normal file
79
rule/common/ipcidr.go
Normal file
@ -0,0 +1,79 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
C "github.com/Dreamacro/clash/constant"
|
||||
)
|
||||
|
||||
type IPCIDROption func(*IPCIDR)
|
||||
|
||||
func WithIPCIDRSourceIP(b bool) IPCIDROption {
|
||||
return func(i *IPCIDR) {
|
||||
i.isSourceIP = b
|
||||
}
|
||||
}
|
||||
|
||||
func WithIPCIDRNoResolve(noResolve bool) IPCIDROption {
|
||||
return func(i *IPCIDR) {
|
||||
i.noResolveIP = noResolve
|
||||
}
|
||||
}
|
||||
|
||||
type IPCIDR struct {
|
||||
ipnet *net.IPNet
|
||||
adapter string
|
||||
ruleExtra *C.RuleExtra
|
||||
isSourceIP bool
|
||||
noResolveIP bool
|
||||
}
|
||||
|
||||
func (i *IPCIDR) RuleType() C.RuleType {
|
||||
if i.isSourceIP {
|
||||
return C.SrcIPCIDR
|
||||
}
|
||||
return C.IPCIDR
|
||||
}
|
||||
|
||||
func (i *IPCIDR) Match(metadata *C.Metadata) bool {
|
||||
ip := metadata.DstIP
|
||||
if i.isSourceIP {
|
||||
ip = metadata.SrcIP
|
||||
}
|
||||
return ip != nil && i.ipnet.Contains(ip)
|
||||
}
|
||||
|
||||
func (i *IPCIDR) Adapter() string {
|
||||
return i.adapter
|
||||
}
|
||||
|
||||
func (i *IPCIDR) Payload() string {
|
||||
return i.ipnet.String()
|
||||
}
|
||||
|
||||
func (i *IPCIDR) ShouldResolveIP() bool {
|
||||
return !i.noResolveIP
|
||||
}
|
||||
|
||||
func (i *IPCIDR) RuleExtra() *C.RuleExtra {
|
||||
return i.ruleExtra
|
||||
}
|
||||
|
||||
func NewIPCIDR(s string, adapter string, ruleExtra *C.RuleExtra, opts ...IPCIDROption) (*IPCIDR, error) {
|
||||
_, ipnet, err := net.ParseCIDR(s)
|
||||
if err != nil {
|
||||
return nil, errPayload
|
||||
}
|
||||
|
||||
ipcidr := &IPCIDR{
|
||||
ipnet: ipnet,
|
||||
adapter: adapter,
|
||||
ruleExtra: ruleExtra,
|
||||
}
|
||||
|
||||
for _, o := range opts {
|
||||
o(ipcidr)
|
||||
}
|
||||
|
||||
return ipcidr, nil
|
||||
}
|
53
rule/common/network_type.go
Normal file
53
rule/common/network_type.go
Normal file
@ -0,0 +1,53 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
C "github.com/Dreamacro/clash/constant"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type NetworkType struct {
|
||||
network C.NetWork
|
||||
adapter string
|
||||
}
|
||||
|
||||
func NewNetworkType(network, adapter string) (*NetworkType, error) {
|
||||
ntType := new(NetworkType)
|
||||
ntType.adapter = adapter
|
||||
switch strings.ToUpper(network) {
|
||||
case "TCP":
|
||||
ntType.network = C.TCP
|
||||
break
|
||||
case "UDP":
|
||||
ntType.network = C.UDP
|
||||
break
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported network type, only TCP/UDP")
|
||||
}
|
||||
|
||||
return ntType, nil
|
||||
}
|
||||
|
||||
func (n *NetworkType) RuleType() C.RuleType {
|
||||
return C.Network
|
||||
}
|
||||
|
||||
func (n *NetworkType) Match(metadata *C.Metadata) bool {
|
||||
return n.network == metadata.NetWork
|
||||
}
|
||||
|
||||
func (n *NetworkType) Adapter() string {
|
||||
return n.adapter
|
||||
}
|
||||
|
||||
func (n *NetworkType) Payload() string {
|
||||
return n.network.String()
|
||||
}
|
||||
|
||||
func (n *NetworkType) ShouldResolveIP() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (n *NetworkType) RuleExtra() *C.RuleExtra {
|
||||
return nil
|
||||
}
|
125
rule/common/port.go
Normal file
125
rule/common/port.go
Normal file
@ -0,0 +1,125 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
C "github.com/Dreamacro/clash/constant"
|
||||
)
|
||||
|
||||
type portReal struct {
|
||||
portStart int
|
||||
portEnd int
|
||||
}
|
||||
|
||||
type Port struct {
|
||||
adapter string
|
||||
port string
|
||||
isSource bool
|
||||
portList []portReal
|
||||
ruleExtra *C.RuleExtra
|
||||
}
|
||||
|
||||
func (p *Port) RuleType() C.RuleType {
|
||||
if p.isSource {
|
||||
return C.SrcPort
|
||||
}
|
||||
return C.DstPort
|
||||
}
|
||||
|
||||
func (p *Port) Match(metadata *C.Metadata) bool {
|
||||
if p.isSource {
|
||||
return p.matchPortReal(metadata.SrcPort)
|
||||
}
|
||||
return p.matchPortReal(metadata.DstPort)
|
||||
}
|
||||
|
||||
func (p *Port) Adapter() string {
|
||||
return p.adapter
|
||||
}
|
||||
|
||||
func (p *Port) Payload() string {
|
||||
return p.port
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
var rs bool
|
||||
for _, pr := range p.portList {
|
||||
if pr.portEnd == -1 {
|
||||
rs = port == pr.portStart
|
||||
} else {
|
||||
rs = port >= pr.portStart && port <= pr.portEnd
|
||||
}
|
||||
if rs {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func NewPort(port string, adapter string, isSource bool, ruleExtra *C.RuleExtra) (*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())
|
||||
}
|
||||
|
||||
var portList []portReal
|
||||
for _, p := range ports {
|
||||
if p == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
subPorts := strings.Split(p, "-")
|
||||
subPortsLen := len(subPorts)
|
||||
if subPortsLen > 2 {
|
||||
return nil, errPayload
|
||||
}
|
||||
|
||||
portStart, err := strconv.Atoi(strings.Trim(subPorts[0], "[ ]"))
|
||||
if err != nil || portStart < 0 || portStart > 65535 {
|
||||
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 {
|
||||
return nil, errPayload
|
||||
}
|
||||
|
||||
shouldReverse := portStart > portEnd
|
||||
if shouldReverse {
|
||||
portList = append(portList, portReal{portEnd, portStart})
|
||||
} else {
|
||||
portList = append(portList, portReal{portStart, portEnd})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(portList) == 0 {
|
||||
return nil, errPayload
|
||||
}
|
||||
|
||||
return &Port{
|
||||
adapter: adapter,
|
||||
port: port,
|
||||
isSource: isSource,
|
||||
portList: portList,
|
||||
ruleExtra: ruleExtra,
|
||||
}, nil
|
||||
}
|
83
rule/common/process.go
Normal file
83
rule/common/process.go
Normal file
@ -0,0 +1,83 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/Dreamacro/clash/common/cache"
|
||||
"github.com/Dreamacro/clash/component/process"
|
||||
C "github.com/Dreamacro/clash/constant"
|
||||
"github.com/Dreamacro/clash/log"
|
||||
)
|
||||
|
||||
var processCache = cache.NewLRUCache(cache.WithAge(2), cache.WithSize(64))
|
||||
|
||||
type Process struct {
|
||||
adapter string
|
||||
process string
|
||||
ruleExtra *C.RuleExtra
|
||||
}
|
||||
|
||||
func (ps *Process) RuleType() C.RuleType {
|
||||
return C.Process
|
||||
}
|
||||
|
||||
func (ps *Process) Match(metadata *C.Metadata) bool {
|
||||
if metadata.Process != "" {
|
||||
return strings.EqualFold(metadata.Process, ps.process)
|
||||
}
|
||||
// ignore match in proxy type "tproxy"
|
||||
//if metadata.Type == C.TPROXY || !C.AutoIptables {
|
||||
|
||||
if C.AutoIptables == "Enable" {
|
||||
return false
|
||||
}
|
||||
|
||||
key := fmt.Sprintf("%s:%s:%s", metadata.NetWork.String(), metadata.SrcIP.String(), metadata.SrcPort)
|
||||
cached, hit := processCache.Get(key)
|
||||
if !hit {
|
||||
srcPort, err := strconv.Atoi(metadata.SrcPort)
|
||||
if err != nil {
|
||||
processCache.Set(key, "")
|
||||
return false
|
||||
}
|
||||
|
||||
name, err := process.FindProcessName(metadata.NetWork.String(), metadata.SrcIP, srcPort)
|
||||
if err != nil {
|
||||
log.Debugln("[Rule] find process name %s error: %s", C.Process.String(), err.Error())
|
||||
}
|
||||
|
||||
processCache.Set(key, name)
|
||||
|
||||
cached = name
|
||||
}
|
||||
|
||||
metadata.Process = cached.(string)
|
||||
|
||||
return strings.EqualFold(metadata.Process, ps.process)
|
||||
}
|
||||
|
||||
func (ps *Process) Adapter() string {
|
||||
return ps.adapter
|
||||
}
|
||||
|
||||
func (ps *Process) Payload() string {
|
||||
return ps.process
|
||||
}
|
||||
|
||||
func (ps *Process) ShouldResolveIP() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (ps *Process) RuleExtra() *C.RuleExtra {
|
||||
return ps.ruleExtra
|
||||
}
|
||||
|
||||
func NewProcess(process string, adapter string, ruleExtra *C.RuleExtra) (*Process, error) {
|
||||
return &Process{
|
||||
adapter: adapter,
|
||||
process: process,
|
||||
ruleExtra: ruleExtra,
|
||||
}, nil
|
||||
}
|
Reference in New Issue
Block a user