2017-07-30 01:54:19 +08:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"log"
|
|
|
|
"os"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/nadoo/conflag"
|
|
|
|
)
|
|
|
|
|
|
|
|
// ruleForwarder, every ruleForwarder points to a rule file
|
|
|
|
type ruleForwarder struct {
|
2017-08-12 12:20:25 +08:00
|
|
|
Forward []string
|
2017-07-30 01:54:19 +08:00
|
|
|
Strategy string
|
|
|
|
CheckWebSite string
|
|
|
|
CheckDuration int
|
|
|
|
|
2017-08-16 13:20:12 +08:00
|
|
|
DNSServer []string
|
|
|
|
IPSet string
|
|
|
|
|
2017-08-12 12:20:25 +08:00
|
|
|
Domain []string
|
|
|
|
IP []string
|
|
|
|
CIDR []string
|
2017-07-30 01:54:19 +08:00
|
|
|
|
2017-07-30 10:35:11 +08:00
|
|
|
name string
|
|
|
|
Proxy
|
2017-07-30 01:54:19 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// newRuleProxyFromFile .
|
|
|
|
func newRuleProxyFromFile(ruleFile string) (*ruleForwarder, error) {
|
|
|
|
p := &ruleForwarder{name: ruleFile}
|
|
|
|
|
|
|
|
f := conflag.NewFromFile("rule", ruleFile)
|
2017-08-13 20:25:21 +08:00
|
|
|
f.StringSliceUniqVar(&p.Forward, "forward", nil, "forward url, format: SCHEMA://[USER|METHOD:PASSWORD@][HOST]:PORT[,SCHEMA://[USER|METHOD:PASSWORD@][HOST]:PORT]")
|
2017-07-30 01:54:19 +08:00
|
|
|
f.StringVar(&p.Strategy, "strategy", "rr", "forward strategy, default: rr")
|
2017-07-31 13:42:11 +08:00
|
|
|
f.StringVar(&p.CheckWebSite, "checkwebsite", "www.apple.com", "proxy check HTTP(NOT HTTPS) website address, format: HOST[:PORT], default port: 80")
|
2017-07-30 01:54:19 +08:00
|
|
|
f.IntVar(&p.CheckDuration, "checkduration", 30, "proxy check duration(seconds)")
|
|
|
|
|
2017-08-16 13:20:12 +08:00
|
|
|
f.StringSliceUniqVar(&p.DNSServer, "dnsserver", nil, "remote dns server")
|
|
|
|
f.StringVar(&p.IPSet, "ipset", "", "ipset name")
|
|
|
|
|
2017-08-13 20:25:21 +08:00
|
|
|
f.StringSliceUniqVar(&p.Domain, "domain", nil, "domain")
|
|
|
|
f.StringSliceUniqVar(&p.IP, "ip", nil, "ip")
|
|
|
|
f.StringSliceUniqVar(&p.CIDR, "cidr", nil, "cidr")
|
2017-07-30 01:54:19 +08:00
|
|
|
|
|
|
|
err := f.Parse()
|
|
|
|
if err != nil {
|
|
|
|
fmt.Fprintf(os.Stderr, "ERROR: %s\n", err)
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
var forwarders []Proxy
|
|
|
|
for _, chain := range p.Forward {
|
|
|
|
var forward Proxy
|
|
|
|
var err error
|
|
|
|
for _, url := range strings.Split(chain, ",") {
|
|
|
|
forward, err = ProxyFromURL(url, forward)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
forwarders = append(forwarders, forward)
|
|
|
|
}
|
|
|
|
|
|
|
|
forwarder := newStrategyForwarder(p.Strategy, forwarders)
|
|
|
|
|
|
|
|
for _, forward := range forwarders {
|
|
|
|
go check(forward, p.CheckWebSite, p.CheckDuration)
|
|
|
|
}
|
|
|
|
|
2017-07-30 10:35:11 +08:00
|
|
|
p.Proxy = forwarder
|
2017-07-30 01:54:19 +08:00
|
|
|
|
|
|
|
return p, err
|
|
|
|
}
|