From 8daa7784b03dd2b5dec83e98a511dbd38f92eaa1 Mon Sep 17 00:00:00 2001 From: nadoo <287492+nadoo@users.noreply.github.com> Date: Mon, 20 Aug 2018 22:23:00 +0800 Subject: [PATCH] general: add global setting `interface` --- conf.go | 1 + proxy/dialer.go | 9 +++++---- proxy/direct.go | 11 +++++++---- proxy/forwarder.go | 20 +++++++++++++------- proxy/server.go | 9 +++++---- rule/config.go | 1 + rule/rule.go | 10 +++++----- strategy/strategy.go | 10 ++++++++-- 8 files changed, 45 insertions(+), 26 deletions(-) diff --git a/conf.go b/conf.go index 3963298..a92c87a 100644 --- a/conf.go +++ b/conf.go @@ -44,6 +44,7 @@ func confInit() { // TODO: change to checkinterval flag.IntVar(&conf.StrategyConfig.CheckInterval, "checkduration", 30, "proxy check interval(seconds)") flag.IntVar(&conf.StrategyConfig.MaxFailures, "maxfailures", 3, "max failures to change forwarder status to disabled") + flag.StringVar(&conf.StrategyConfig.IntFace, "interface", "", "source ip or source interface") flag.StringSliceUniqVar(&conf.RuleFile, "rulefile", nil, "rule file path") flag.StringVar(&conf.RulesDir, "rules-dir", "", "rule file folder") diff --git a/proxy/dialer.go b/proxy/dialer.go index 5e665e1..9c10c9e 100644 --- a/proxy/dialer.go +++ b/proxy/dialer.go @@ -37,17 +37,18 @@ func RegisterDialer(name string, c DialerCreator) { } // DialerFromURL calls the registered creator to create dialers. +// dialer is the default upstream dialer so cannot be nil, we can use Default when calling this function. func DialerFromURL(s string, dialer Dialer) (Dialer, error) { + if dialer == nil { + return nil, errors.New("DialerFromURL: dialer cannot be nil") + } + u, err := url.Parse(s) if err != nil { log.F("parse err: %s", err) return nil, err } - if dialer == nil { - dialer = Default - } - c, ok := dialerMap[strings.ToLower(u.Scheme)] if ok { return c(s, dialer) diff --git a/proxy/direct.go b/proxy/direct.go index 637a33c..512dbad 100644 --- a/proxy/direct.go +++ b/proxy/direct.go @@ -1,6 +1,7 @@ package proxy import ( + "errors" "net" "github.com/nadoo/glider/common/log" @@ -28,7 +29,7 @@ func NewDirect(intface string) (*Direct, error) { iface, err := net.InterfaceByName(intface) if err != nil { - return nil, err + return nil, errors.New(err.Error() + ": " + intface) } return &Direct{iface: iface}, nil @@ -39,9 +40,11 @@ func (d *Direct) Addr() string { return "DIRECT" } // Dial connects to the address addr on the network net func (d *Direct) Dial(network, addr string) (c net.Conn, err error) { - c, err = dial(network, addr, d.ip) - if err == nil { - return + if d.iface == nil || d.ip != nil { + c, err = dial(network, addr, d.ip) + if err == nil { + return + } } for _, ip := range d.IFaceIPs() { diff --git a/proxy/forwarder.go b/proxy/forwarder.go index f5ad8f9..4998378 100644 --- a/proxy/forwarder.go +++ b/proxy/forwarder.go @@ -14,16 +14,17 @@ import ( type Forwarder struct { Dialer Priority int - addr string - disabled uint32 - failures uint32 MaxFailures uint32 //maxfailures to set to Disabled - latency int64 - intface string // local interface or ip address + + addr string + disabled uint32 + failures uint32 + latency int64 + intface string // local interface or ip address } // ForwarderFromURL parses `forward=` command value and returns a new forwarder -func ForwarderFromURL(s string) (f *Forwarder, err error) { +func ForwarderFromURL(s, intface string) (f *Forwarder, err error) { f = &Forwarder{} ss := strings.Split(s, "#") @@ -31,8 +32,13 @@ func ForwarderFromURL(s string) (f *Forwarder, err error) { err = f.parseOption(ss[1]) } + iface := intface + if f.intface != "" && f.intface != intface { + iface = f.intface + } + var d Dialer - d, err = NewDirect(f.intface) + d, err = NewDirect(iface) if err != nil { return nil, err } diff --git a/proxy/server.go b/proxy/server.go index ad77eef..aef83c9 100644 --- a/proxy/server.go +++ b/proxy/server.go @@ -27,7 +27,12 @@ func RegisterServer(name string, c ServerCreator) { } // ServerFromURL calls the registered creator to create proxy servers. +// dialer is the default upstream dialer so cannot be nil, we can use Default when calling this function. func ServerFromURL(s string, dialer Dialer) (Server, error) { + if dialer == nil { + return nil, errors.New("ServerFromURL: dialer cannot be nil") + } + if !strings.Contains(s, "://") { s = "mixed://" + s } @@ -38,10 +43,6 @@ func ServerFromURL(s string, dialer Dialer) (Server, error) { return nil, err } - if dialer == nil { - dialer = Default - } - c, ok := serverMap[strings.ToLower(u.Scheme)] if ok { return c(s, dialer) diff --git a/rule/config.go b/rule/config.go index 884f1fe..9763e09 100644 --- a/rule/config.go +++ b/rule/config.go @@ -36,6 +36,7 @@ func NewConfFromFile(ruleFile string) (*Config, error) { 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.StringVar(&p.StrategyConfig.IntFace, "interface", "", "source ip or source interface") f.StringSliceUniqVar(&p.DNSServers, "dnsserver", nil, "remote dns server") f.StringVar(&p.IPSet, "ipset", "", "ipset name") diff --git a/rule/rule.go b/rule/rule.go index 52aea36..55a29a3 100644 --- a/rule/rule.go +++ b/rule/rule.go @@ -25,20 +25,20 @@ func NewDialer(rules []*Config, gDialer proxy.Dialer) *Dialer { rd := &Dialer{gDialer: gDialer} for _, r := range rules { - sDialer := strategy.NewDialer(r.Forward, &r.StrategyConfig) - rd.dialers = append(rd.dialers, sDialer) + sd := strategy.NewDialer(r.Forward, &r.StrategyConfig) + rd.dialers = append(rd.dialers, sd) for _, domain := range r.Domain { - rd.domainMap.Store(strings.ToLower(domain), sDialer) + rd.domainMap.Store(strings.ToLower(domain), sd) } for _, ip := range r.IP { - rd.ipMap.Store(ip, sDialer) + rd.ipMap.Store(ip, sd) } for _, s := range r.CIDR { if _, cidr, err := net.ParseCIDR(s); err == nil { - rd.cidrMap.Store(cidr, sDialer) + rd.cidrMap.Store(cidr, sd) } } } diff --git a/strategy/strategy.go b/strategy/strategy.go index 06bfd8d..8954435 100644 --- a/strategy/strategy.go +++ b/strategy/strategy.go @@ -18,6 +18,7 @@ type Config struct { CheckWebSite string CheckInterval int MaxFailures int + IntFace string } // Checker is an interface of forwarder checker @@ -29,7 +30,7 @@ type Checker interface { func NewDialer(s []string, c *Config) proxy.Dialer { var fwdrs []*proxy.Forwarder for _, chain := range s { - fwdr, err := proxy.ForwarderFromURL(chain) + fwdr, err := proxy.ForwarderFromURL(chain, c.IntFace) if err != nil { log.Fatal(err) } @@ -38,7 +39,11 @@ func NewDialer(s []string, c *Config) proxy.Dialer { } if len(fwdrs) == 0 { - return proxy.Default + d, err := proxy.NewDirect(c.IntFace) + if err != nil { + log.Fatal(err) + } + return d } if len(fwdrs) == 1 { @@ -139,6 +144,7 @@ func (rr *rrDialer) nextDialer(dstAddr string) *proxy.Forwarder { } if !found { + rr.priority = 0 log.F("NO AVAILABLE PROXY FOUND! please check your network or proxy server settings.") }