add support for reading from file; re-enable args a and aaaa

This commit is contained in:
eddc005 2024-06-03 22:17:04 +01:00
parent f5741f61ac
commit 65b15515af
3 changed files with 95 additions and 27 deletions

View File

@ -4,7 +4,7 @@ type Modifier interface {
// Name returns the name of the modifier. // Name returns the name of the modifier.
Name() string Name() string
// New returns a new modifier instance. // New returns a new modifier instance.
New(args map[string][]interface{}) (Instance, error) New(args map[string]interface{}) (Instance, error)
} }
type Instance interface{} type Instance interface{}

View File

@ -1,11 +1,14 @@
package udp package udp
import ( import (
"bufio"
"encoding/binary" "encoding/binary"
"errors" "errors"
"fmt"
"hash/fnv" "hash/fnv"
"math/rand/v2" "math/rand/v2"
"net" "net"
"os"
"github.com/apernet/OpenGFW/modifier" "github.com/apernet/OpenGFW/modifier"
@ -17,37 +20,102 @@ var _ modifier.Modifier = (*DNSModifier)(nil)
var ( var (
errInvalidIP = errors.New("invalid ip") errInvalidIP = errors.New("invalid ip")
errInvalidIPList = errors.New("invalid ip list")
errInvalidIpListFile = errors.New("unable to open or parse ip list file")
errNotValidDNSResponse = errors.New("not a valid dns response") errNotValidDNSResponse = errors.New("not a valid dns response")
errEmptyDNSQuestion = errors.New("empty dns question") errEmptyDNSQuestion = errors.New("empty dns question")
) )
func fmtErrInvalidIP(ip string) error {
return fmt.Errorf("invalid ip: %s", ip)
}
func fmtErrInvalidIpListFile(filePath string) error {
return fmt.Errorf("unable to open or parse ip list file: %s", filePath)
}
type DNSModifier struct{} type DNSModifier struct{}
func (m *DNSModifier) Name() string { func (m *DNSModifier) Name() string {
return "dns" return "dns"
} }
func (m *DNSModifier) New(args map[string][]interface{}) (modifier.Instance, error) { func (m *DNSModifier) parseIpEntry(entry interface{}, i *dnsModifierInstance) error {
entryStr, ok := entry.(string)
if !ok {
return &modifier.ErrInvalidArgs{Err: errInvalidIP}
}
ip := net.ParseIP(entryStr)
if ip == nil {
return &modifier.ErrInvalidArgs{Err: fmtErrInvalidIP(entryStr)}
}
if ip4 := ip.To4(); ip4 != nil {
i.A = append(i.A, ip4)
} else {
i.AAAA = append(i.AAAA, ip)
}
return nil
}
func (m *DNSModifier) parseIpList(list []interface{}, i *dnsModifierInstance) error {
for _, entry := range list {
if err := m.parseIpEntry(entry, i); err != nil {
return err
}
}
return nil
}
func (m *DNSModifier) parseIpListFile(filePath string, i *dnsModifierInstance) error {
file, err := os.Open(filePath)
if err != nil {
return &modifier.ErrInvalidArgs{Err: fmtErrInvalidIpListFile(filePath)}
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
if err := m.parseIpEntry(line, i); err != nil {
return err
}
}
if err := scanner.Err(); err != nil {
return &modifier.ErrInvalidArgs{Err: fmtErrInvalidIpListFile(filePath)}
}
return nil
}
func (m *DNSModifier) New(args map[string]interface{}) (modifier.Instance, error) {
i := &dnsModifierInstance{} i := &dnsModifierInstance{}
i.seed = rand.Uint32() i.seed = rand.Uint32()
for _, arg := range args["a"] {
aStr, ok := arg.(string) for key, value := range args {
if ok { switch key {
a := net.ParseIP(aStr).To4() case "a", "aaaa":
if a == nil { if err := m.parseIpEntry(value, i); err != nil {
return nil, &modifier.ErrInvalidArgs{Err: errInvalidIP} return nil, err
} }
i.A = append(i.A, a) case "list":
if list, ok := value.([]interface{}); ok {
if err := m.parseIpList(list, i); err != nil {
return nil, err
} }
} else {
return nil, &modifier.ErrInvalidArgs{Err: errInvalidIPList}
} }
for _, arg := range args["aaaa"] { case "file":
aaaaStr, ok := arg.(string) if filePath, ok := value.(string); ok {
if ok { if err := m.parseIpListFile(filePath, i); err != nil {
aaaa := net.ParseIP(aaaaStr).To16() return nil, err
if aaaa == nil { }
return nil, &modifier.ErrInvalidArgs{Err: errInvalidIP} } else {
return nil, &modifier.ErrInvalidArgs{Err: errInvalidIpListFile}
} }
i.AAAA = append(i.AAAA, aaaa)
} }
} }
return i, nil return i, nil

View File

@ -33,7 +33,7 @@ type ExprRule struct {
type ModifierEntry struct { type ModifierEntry struct {
Name string `yaml:"name"` Name string `yaml:"name"`
Args map[string][]interface{} `yaml:"args"` Args map[string]interface{} `yaml:"args"`
} }
func ExprRulesFromYAML(file string) ([]ExprRule, error) { func ExprRulesFromYAML(file string) ([]ExprRule, error) {