Skip to content

Commit 3b472f7

Browse files
committed
chore: Add source matching for ip type rules
1 parent f3743fc commit 3b472f7

File tree

4 files changed

+50
-12
lines changed

4 files changed

+50
-12
lines changed

constant/rule.go

+9-3
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ const (
88
DomainRegex
99
GEOSITE
1010
GEOIP
11-
IPCIDR
11+
SrcGEOIP
1212
IPASN
13+
SrcIPASN
14+
IPCIDR
1315
SrcIPCIDR
1416
IPSuffix
1517
SrcIPSuffix
@@ -48,10 +50,14 @@ func (rt RuleType) String() string {
4850
return "GeoSite"
4951
case GEOIP:
5052
return "GeoIP"
51-
case IPCIDR:
52-
return "IPCIDR"
53+
case SrcGEOIP:
54+
return "SrcGeoIP"
5355
case IPASN:
5456
return "IPASN"
57+
case SrcIPASN:
58+
return "SrcIPASN"
59+
case IPCIDR:
60+
return "IPCIDR"
5561
case SrcIPCIDR:
5662
return "SrcIPCIDR"
5763
case IPSuffix:

rules/common/geoip.go

+21-2
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,25 @@ type GEOIP struct {
1717
country string
1818
adapter string
1919
noResolveIP bool
20+
isSourceIP bool
2021
geoIPMatcher *router.GeoIPMatcher
2122
recodeSize int
2223
}
2324

2425
var _ C.Rule = (*GEOIP)(nil)
2526

2627
func (g *GEOIP) RuleType() C.RuleType {
28+
if g.isSourceIP {
29+
return C.SrcGEOIP
30+
}
2731
return C.GEOIP
2832
}
2933

3034
func (g *GEOIP) Match(metadata *C.Metadata) (bool, string) {
3135
ip := metadata.DstIP
36+
if g.isSourceIP {
37+
ip = metadata.SrcIP
38+
}
3239
if !ip.IsValid() {
3340
return false, ""
3441
}
@@ -49,6 +56,16 @@ func (g *GEOIP) Match(metadata *C.Metadata) (bool, string) {
4956
}
5057

5158
if !C.GeodataMode {
59+
if g.isSourceIP {
60+
codes := mmdb.IPInstance().LookupCode(ip.AsSlice())
61+
for _, code := range codes {
62+
if g.country == code {
63+
return true, g.adapter
64+
}
65+
}
66+
return false, g.adapter
67+
}
68+
5269
if metadata.DstGeoIP != nil {
5370
return false, g.adapter
5471
}
@@ -62,7 +79,7 @@ func (g *GEOIP) Match(metadata *C.Metadata) (bool, string) {
6279
}
6380

6481
match := g.geoIPMatcher.Match(ip)
65-
if match {
82+
if match && !g.isSourceIP {
6683
metadata.DstGeoIP = append(metadata.DstGeoIP, g.country)
6784
}
6885
return match, g.adapter
@@ -92,7 +109,7 @@ func (g *GEOIP) GetRecodeSize() int {
92109
return g.recodeSize
93110
}
94111

95-
func NewGEOIP(country string, adapter string, noResolveIP bool) (*GEOIP, error) {
112+
func NewGEOIP(country string, adapter string, isSrc, noResolveIP bool) (*GEOIP, error) {
96113
if err := geodata.InitGeoIP(); err != nil {
97114
log.Errorln("can't initial GeoIP: %s", err)
98115
return nil, err
@@ -105,6 +122,7 @@ func NewGEOIP(country string, adapter string, noResolveIP bool) (*GEOIP, error)
105122
country: country,
106123
adapter: adapter,
107124
noResolveIP: noResolveIP,
125+
isSourceIP: isSrc,
108126
}
109127
return geoip, nil
110128
}
@@ -120,6 +138,7 @@ func NewGEOIP(country string, adapter string, noResolveIP bool) (*GEOIP, error)
120138
country: country,
121139
adapter: adapter,
122140
noResolveIP: noResolveIP,
141+
isSourceIP: isSrc,
123142
geoIPMatcher: geoIPMatcher,
124143
recodeSize: size,
125144
}

rules/common/ipasn.go

+12-3
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,32 @@ type ASN struct {
1414
asn string
1515
adapter string
1616
noResolveIP bool
17+
isSourceIP bool
1718
}
1819

1920
func (a *ASN) Match(metadata *C.Metadata) (bool, string) {
2021
ip := metadata.DstIP
22+
if a.isSourceIP {
23+
ip = metadata.SrcIP
24+
}
2125
if !ip.IsValid() {
2226
return false, ""
2327
}
2428

2529
result := mmdb.ASNInstance().LookupASN(ip.AsSlice())
26-
2730
asnNumber := strconv.FormatUint(uint64(result.AutonomousSystemNumber), 10)
28-
metadata.DstIPASN = asnNumber + " " + result.AutonomousSystemOrganization
31+
if !a.isSourceIP {
32+
metadata.DstIPASN = asnNumber + " " + result.AutonomousSystemOrganization
33+
}
2934

3035
match := a.asn == asnNumber
3136
return match, a.adapter
3237
}
3338

3439
func (a *ASN) RuleType() C.RuleType {
40+
if a.isSourceIP {
41+
return C.SrcIPASN
42+
}
3543
return C.IPASN
3644
}
3745

@@ -51,7 +59,7 @@ func (a *ASN) GetASN() string {
5159
return a.asn
5260
}
5361

54-
func NewIPASN(asn string, adapter string, noResolveIP bool) (*ASN, error) {
62+
func NewIPASN(asn string, adapter string, isSrc, noResolveIP bool) (*ASN, error) {
5563
C.ASNEnable = true
5664
if err := geodata.InitASN(); err != nil {
5765
log.Errorln("can't initial ASN: %s", err)
@@ -63,5 +71,6 @@ func NewIPASN(asn string, adapter string, noResolveIP bool) (*ASN, error) {
6371
asn: asn,
6472
adapter: adapter,
6573
noResolveIP: noResolveIP,
74+
isSourceIP: isSrc,
6675
}, nil
6776
}

rules/parser.go

+8-4
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,17 @@ func ParseRule(tp, payload, target string, params []string, subRules map[string]
2323
parsed, parseErr = RC.NewGEOSITE(payload, target)
2424
case "GEOIP":
2525
noResolve := RC.HasNoResolve(params)
26-
parsed, parseErr = RC.NewGEOIP(payload, target, noResolve)
26+
parsed, parseErr = RC.NewGEOIP(payload, target, false, noResolve)
27+
case "SRC-GEOIP":
28+
parsed, parseErr = RC.NewGEOIP(payload, target, true, true)
29+
case "IP-ASN":
30+
noResolve := RC.HasNoResolve(params)
31+
parsed, parseErr = RC.NewIPASN(payload, target, false, noResolve)
32+
case "SRC-IP-ASN":
33+
parsed, parseErr = RC.NewIPASN(payload, target, true, true)
2734
case "IP-CIDR", "IP-CIDR6":
2835
noResolve := RC.HasNoResolve(params)
2936
parsed, parseErr = RC.NewIPCIDR(payload, target, RC.WithIPCIDRNoResolve(noResolve))
30-
case "IP-ASN":
31-
noResolve := RC.HasNoResolve(params)
32-
parsed, parseErr = RC.NewIPASN(payload, target, noResolve)
3337
case "SRC-IP-CIDR":
3438
parsed, parseErr = RC.NewIPCIDR(payload, target, RC.WithIPCIDRSourceIP(true), RC.WithIPCIDRNoResolve(true))
3539
case "IP-SUFFIX":

0 commit comments

Comments
 (0)