init: 1.0.0

This commit is contained in:
Chang lue Tsen
2025-04-25 12:08:29 +09:00
commit 8addcc584b
1031 changed files with 76472 additions and 0 deletions
+8
View File
@@ -0,0 +1,8 @@
package rules
import "errors"
var (
ErrRuleTypeNotFound = errors.New("rule type not found")
ErrRuleTargetNotFound = errors.New("rule target not found")
)
+44
View File
@@ -0,0 +1,44 @@
package rules
type RuleType int
const (
Domain RuleType = iota
DomainSuffix
DomainKeyword
GEOIP
IPCIDR
SrcIPCIDR
SrcPort
DstPort
InboundPort
Process
ProcessPath
IPSet
MATCH
Unknown
)
var ruleTypeMap = map[RuleType]string{
Domain: "DOMAIN",
DomainSuffix: "DOMAIN-SUFFIX",
DomainKeyword: "DOMAIN-KEYWORD",
GEOIP: "GEOIP",
IPCIDR: "IP-CIDR",
SrcIPCIDR: "SRC-IP-CIDR",
SrcPort: "SRC-PORT",
DstPort: "DST-PORT",
InboundPort: "INBOUND-PORT",
Process: "PROCESS-NAME",
ProcessPath: "PROCESS-PATH",
IPSet: "IPSET",
MATCH: "MATCH",
Unknown: "UNKNOWN",
}
func (rt RuleType) String() string {
if str, ok := ruleTypeMap[rt]; ok {
return str
}
return "UNKNOWN"
}
+10
View File
@@ -0,0 +1,10 @@
package rules
func ParseRuleType(ruleType string) RuleType {
for k, v := range ruleTypeMap {
if v == ruleType {
return k
}
}
return Unknown
}
+50
View File
@@ -0,0 +1,50 @@
package rules
import (
"strings"
)
const noResolve = "no-resolve"
type Rule struct {
Type string
Payload string
Target string
}
func NewRule(text, name string) *Rule {
rule := trimArr(strings.Split(text, ","))
var (
payload string
target string
)
switch l := len(rule); {
case l == 2:
payload = rule[1]
target = name
case l == 3:
payload = rule[1]
target = rule[2]
case l >= 4:
payload = rule[1]
target = rule[2]
default:
return nil
}
rule = trimArr(rule)
return &Rule{
Type: rule[0],
Payload: payload,
Target: target,
}
}
func (r *Rule) String() string {
text := r.Type + "," + r.Payload + "," + r.Target
switch ParseRuleType(r.Type) {
case IPCIDR, IPSet:
return text + "," + noResolve
default:
return text
}
}
+52
View File
@@ -0,0 +1,52 @@
package rules
import (
"strings"
"testing"
"github.com/stretchr/testify/assert"
)
var text = `
DOMAIN,example.com
DOMAIN-SUFFIX,google.com,DIRECT
DOMAIN-KEYWORD,amazon,REJECT
IP-CIDR,192.168.0.0/16
`
func TestNewRule(t *testing.T) {
var rs []string
// parse validate rules
ruleArr := strings.Split(text, "\n")
if len(ruleArr) == 0 {
t.Error("rules is empty")
}
ruleArr = trimArr(ruleArr)
for _, s := range ruleArr {
r := NewRule(s, "Test")
if r == nil {
t.Errorf("[CreateRuleGroup] rule %s is nil, len: %d", s, len(s))
continue
}
if err := r.Validate(); err != nil {
t.Errorf("[CreateRuleGroup] rule %s is invalid: %v", s, err)
continue
}
rs = append(rs, r.String())
}
expected := []string{
"DOMAIN,example.com,Test",
"DOMAIN-SUFFIX,google.com,DIRECT",
"DOMAIN-KEYWORD,amazon,REJECT",
"IP-CIDR,192.168.0.0/16,Test,no-resolve",
}
for i, r := range rs {
if r != expected[i] {
t.Errorf("expected %s, got %s", expected[i], r)
}
}
// Check if the rules are sorted
assert.Equal(t, len(rs), len(expected))
}
+14
View File
@@ -0,0 +1,14 @@
package rules
import "strings"
func trimArr(arr []string) []string {
var result []string
for _, s := range arr {
trimmed := strings.TrimSpace(s)
if trimmed != "" {
result = append(result, trimmed)
}
}
return result
}
+10
View File
@@ -0,0 +1,10 @@
package rules
import "fmt"
func (r *Rule) Validate() error {
if r.Type == "" || r.Payload == "" || r.Target == "" {
return fmt.Errorf("invalid rule: %+v", r)
}
return nil
}