rule: move to separate package

This commit is contained in:
nadoo 2018-08-12 22:24:49 +08:00
parent 3a8af82f87
commit 978029bd2b
6 changed files with 101 additions and 82 deletions

72
conf.go
View File

@ -2,15 +2,14 @@ package main
import ( import (
"fmt" "fmt"
"io/ioutil"
"log" "log"
"os" "os"
"path" "path"
"strings"
"github.com/nadoo/conflag" "github.com/nadoo/conflag"
"github.com/nadoo/glider/dns" "github.com/nadoo/glider/dns"
"github.com/nadoo/glider/rule"
"github.com/nadoo/glider/strategy" "github.com/nadoo/glider/strategy"
) )
@ -32,7 +31,7 @@ var conf struct {
IPSet string IPSet string
rules []*RuleConf rules []*rule.Config
} }
func confInit() { func confInit() {
@ -74,7 +73,7 @@ func confInit() {
// rulefiles // rulefiles
for _, ruleFile := range conf.RuleFile { for _, ruleFile := range conf.RuleFile {
rule, err := NewRuleConfFromFile(ruleFile) rule, err := rule.NewConfFromFile(ruleFile)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
@ -86,10 +85,10 @@ func confInit() {
if !path.IsAbs(conf.RulesDir) { if !path.IsAbs(conf.RulesDir) {
conf.RulesDir = path.Join(flag.ConfDir(), conf.RulesDir) conf.RulesDir = path.Join(flag.ConfDir(), conf.RulesDir)
} }
ruleFolderFiles, _ := listDir(conf.RulesDir, ".rule") ruleFolderFiles, _ := rule.ListDir(conf.RulesDir, ".rule")
for _, ruleFile := range ruleFolderFiles { for _, ruleFile := range ruleFolderFiles {
rule, err := NewRuleConfFromFile(ruleFile) rule, err := rule.NewConfFromFile(ruleFile)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
@ -100,67 +99,6 @@ func confInit() {
} }
func listDir(dirPth string, suffix string) (files []string, err error) {
files = make([]string, 0, 10)
dir, err := ioutil.ReadDir(dirPth)
if err != nil {
return nil, err
}
PthSep := string(os.PathSeparator)
suffix = strings.ToUpper(suffix)
for _, fi := range dir {
if fi.IsDir() {
continue
}
if strings.HasSuffix(strings.ToUpper(fi.Name()), suffix) {
files = append(files, dirPth+PthSep+fi.Name())
}
}
return files, nil
}
// RuleConf , every ruleForwarder points to a rule file
type RuleConf struct {
name string
Forward []string
StrategyConfig strategy.Config
DNSServers []string
IPSet string
Domain []string
IP []string
CIDR []string
}
// NewRuleConfFromFile .
func NewRuleConfFromFile(ruleFile string) (*RuleConf, error) {
p := &RuleConf{name: ruleFile}
f := conflag.NewFromFile("rule", ruleFile)
f.StringSliceUniqVar(&p.Forward, "forward", nil, "forward url, format: SCHEME://[USER|METHOD:PASSWORD@][HOST]:PORT?PARAMS[,SCHEME://[USER|METHOD:PASSWORD@][HOST]:PORT?PARAMS]")
f.StringVar(&p.StrategyConfig.Strategy, "strategy", "rr", "forward strategy, default: rr")
f.StringVar(&p.StrategyConfig.CheckWebSite, "checkwebsite", "www.apple.com", "proxy check HTTP(NOT HTTPS) website address, format: HOST[:PORT], default port: 80")
// TODO: change to checkinterval
f.IntVar(&p.StrategyConfig.CheckInterval, "checkduration", 30, "proxy check interval(seconds)")
f.StringSliceUniqVar(&p.DNSServers, "dnsserver", nil, "remote dns server")
f.StringVar(&p.IPSet, "ipset", "", "ipset name")
f.StringSliceUniqVar(&p.Domain, "domain", nil, "domain")
f.StringSliceUniqVar(&p.IP, "ip", nil, "ip")
f.StringSliceUniqVar(&p.CIDR, "cidr", nil, "cidr")
err := f.Parse()
if err != nil {
fmt.Fprintf(os.Stderr, "ERROR: %s\n", err)
return nil, err
}
return p, err
}
func usage() { func usage() {
app := os.Args[0] app := os.Args[0]
fmt.Fprintf(os.Stderr, "\n") fmt.Fprintf(os.Stderr, "\n")

View File

@ -14,6 +14,8 @@ import (
"syscall" "syscall"
"unsafe" "unsafe"
"github.com/nadoo/glider/rule"
"github.com/nadoo/glider/common/log" "github.com/nadoo/glider/common/log"
) )
@ -77,7 +79,7 @@ type IPSetManager struct {
} }
// NewIPSetManager returns a IPSetManager // NewIPSetManager returns a IPSetManager
func NewIPSetManager(mainSet string, rules []*RuleConf) (*IPSetManager, error) { func NewIPSetManager(mainSet string, rules []*rule.Config) (*IPSetManager, error) {
fd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, syscall.NETLINK_NETFILTER) fd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, syscall.NETLINK_NETFILTER)
if err != nil { if err != nil {
log.F("%s", err) log.F("%s", err)

View File

@ -2,13 +2,17 @@
package main package main
import "errors" import (
"errors"
"github.com/nadoo/glider/rule"
)
// IPSetManager struct // IPSetManager struct
type IPSetManager struct{} type IPSetManager struct{}
// NewIPSetManager returns a IPSetManager // NewIPSetManager returns a IPSetManager
func NewIPSetManager(mainSet string, rules []*RuleConf) (*IPSetManager, error) { func NewIPSetManager(mainSet string, rules []*rule.Config) (*IPSetManager, error) {
return nil, errors.New("ipset not supported on this os") return nil, errors.New("ipset not supported on this os")
} }

View File

@ -9,6 +9,7 @@ import (
"github.com/nadoo/glider/common/log" "github.com/nadoo/glider/common/log"
"github.com/nadoo/glider/dns" "github.com/nadoo/glider/dns"
"github.com/nadoo/glider/proxy" "github.com/nadoo/glider/proxy"
"github.com/nadoo/glider/rule"
"github.com/nadoo/glider/strategy" "github.com/nadoo/glider/strategy"
_ "github.com/nadoo/glider/proxy/http" _ "github.com/nadoo/glider/proxy/http"
@ -35,7 +36,7 @@ func main() {
} }
} }
dialer := NewRuleDialer(conf.rules, strategy.NewDialer(conf.Forward, &conf.StrategyConfig)) dialer := rule.NewDialer(conf.rules, strategy.NewDialer(conf.Forward, &conf.StrategyConfig))
ipsetM, _ := NewIPSetManager(conf.IPSet, conf.rules) ipsetM, _ := NewIPSetManager(conf.IPSet, conf.rules)
// DNS Server // DNS Server

74
rule/config.go Normal file
View File

@ -0,0 +1,74 @@
package rule
import (
"fmt"
"io/ioutil"
"os"
"strings"
"github.com/nadoo/conflag"
"github.com/nadoo/glider/strategy"
)
// Config , every rule dialer points to a rule file
type Config struct {
name string
Forward []string
StrategyConfig strategy.Config
DNSServers []string
IPSet string
Domain []string
IP []string
CIDR []string
}
// NewConfFromFile .
func NewConfFromFile(ruleFile string) (*Config, error) {
p := &Config{name: ruleFile}
f := conflag.NewFromFile("rule", ruleFile)
f.StringSliceUniqVar(&p.Forward, "forward", nil, "forward url, format: SCHEME://[USER|METHOD:PASSWORD@][HOST]:PORT?PARAMS[,SCHEME://[USER|METHOD:PASSWORD@][HOST]:PORT?PARAMS]")
f.StringVar(&p.StrategyConfig.Strategy, "strategy", "rr", "forward strategy, default: rr")
f.StringVar(&p.StrategyConfig.CheckWebSite, "checkwebsite", "www.apple.com", "proxy check HTTP(NOT HTTPS) website address, format: HOST[:PORT], default port: 80")
// TODO: change to checkinterval
f.IntVar(&p.StrategyConfig.CheckInterval, "checkduration", 30, "proxy check interval(seconds)")
f.StringSliceUniqVar(&p.DNSServers, "dnsserver", nil, "remote dns server")
f.StringVar(&p.IPSet, "ipset", "", "ipset name")
f.StringSliceUniqVar(&p.Domain, "domain", nil, "domain")
f.StringSliceUniqVar(&p.IP, "ip", nil, "ip")
f.StringSliceUniqVar(&p.CIDR, "cidr", nil, "cidr")
err := f.Parse()
if err != nil {
fmt.Fprintf(os.Stderr, "ERROR: %s\n", err)
return nil, err
}
return p, err
}
// ListDir returns file list named with suffix in dirPth
func ListDir(dirPth string, suffix string) (files []string, err error) {
files = make([]string, 0, 10)
dir, err := ioutil.ReadDir(dirPth)
if err != nil {
return nil, err
}
PthSep := string(os.PathSeparator)
suffix = strings.ToUpper(suffix)
for _, fi := range dir {
if fi.IsDir() {
continue
}
if strings.HasSuffix(strings.ToUpper(fi.Name()), suffix) {
files = append(files, dirPth+PthSep+fi.Name())
}
}
return files, nil
}

View File

@ -1,4 +1,4 @@
package main package rule
import ( import (
"net" "net"
@ -10,8 +10,8 @@ import (
"github.com/nadoo/glider/strategy" "github.com/nadoo/glider/strategy"
) )
// RuleDialer struct // Dialer struct
type RuleDialer struct { type Dialer struct {
gDialer proxy.Dialer gDialer proxy.Dialer
domainMap sync.Map domainMap sync.Map
@ -19,9 +19,9 @@ type RuleDialer struct {
cidrMap sync.Map cidrMap sync.Map
} }
// NewRuleDialer returns a new rule dialer // NewDialer returns a new rule dialer
func NewRuleDialer(rules []*RuleConf, gDialer proxy.Dialer) *RuleDialer { func NewDialer(rules []*Config, gDialer proxy.Dialer) *Dialer {
rd := &RuleDialer{gDialer: gDialer} rd := &Dialer{gDialer: gDialer}
for _, r := range rules { for _, r := range rules {
sDialer := strategy.NewDialer(r.Forward, &r.StrategyConfig) sDialer := strategy.NewDialer(r.Forward, &r.StrategyConfig)
@ -45,10 +45,10 @@ func NewRuleDialer(rules []*RuleConf, gDialer proxy.Dialer) *RuleDialer {
} }
// Addr returns RuleDialer's address, always be "RULES" // Addr returns RuleDialer's address, always be "RULES"
func (rd *RuleDialer) Addr() string { return "RULE DIALER, DEFAULT: " + rd.gDialer.Addr() } func (rd *Dialer) Addr() string { return "RULE DIALER, DEFAULT: " + rd.gDialer.Addr() }
// NextDialer return next dialer according to rule // NextDialer return next dialer according to rule
func (rd *RuleDialer) NextDialer(dstAddr string) proxy.Dialer { func (rd *Dialer) NextDialer(dstAddr string) proxy.Dialer {
host, _, err := net.SplitHostPort(dstAddr) host, _, err := net.SplitHostPort(dstAddr)
if err != nil { if err != nil {
// TODO: check here // TODO: check here
@ -96,17 +96,17 @@ func (rd *RuleDialer) NextDialer(dstAddr string) proxy.Dialer {
} }
// Dial dials to targer addr and return a conn // Dial dials to targer addr and return a conn
func (rd *RuleDialer) Dial(network, addr string) (net.Conn, error) { func (rd *Dialer) Dial(network, addr string) (net.Conn, error) {
return rd.NextDialer(addr).Dial(network, addr) return rd.NextDialer(addr).Dial(network, addr)
} }
// DialUDP connects to the given address via the proxy // DialUDP connects to the given address via the proxy
func (rd *RuleDialer) DialUDP(network, addr string) (pc net.PacketConn, writeTo net.Addr, err error) { func (rd *Dialer) DialUDP(network, addr string) (pc net.PacketConn, writeTo net.Addr, err error) {
return rd.NextDialer(addr).DialUDP(network, addr) return rd.NextDialer(addr).DialUDP(network, addr)
} }
// AddDomainIP used to update ipMap rules according to domainMap rule // AddDomainIP used to update ipMap rules according to domainMap rule
func (rd *RuleDialer) AddDomainIP(domain, ip string) error { func (rd *Dialer) AddDomainIP(domain, ip string) error {
if ip != "" { if ip != "" {
domainParts := strings.Split(domain, ".") domainParts := strings.Split(domain, ".")
length := len(domainParts) length := len(domainParts)