glider/strategy.go

102 lines
2.3 KiB
Go
Raw Normal View History

2017-07-13 21:55:41 +08:00
package main
2017-07-30 01:54:19 +08:00
import "net"
2017-07-13 21:55:41 +08:00
// newStrategyForwarder .
func newStrategyForwarder(strategy string, forwarders []Proxy) Proxy {
var proxy Proxy
if len(forwarders) == 0 {
proxy = Direct
} else if len(forwarders) == 1 {
proxy = forwarders[0]
} else if len(forwarders) > 1 {
switch strategy {
case "rr":
proxy = newRRProxy("", forwarders)
logf("forward to remote servers in round robin mode.")
case "ha":
proxy = newHAProxy("", forwarders)
logf("forward to remote servers in high availability mode.")
default:
logf("not supported forward mode '%s', just use the first forward server.", conf.Strategy)
proxy = forwarders[0]
}
}
return proxy
}
// rrProxy
type rrProxy struct {
2017-07-13 21:55:41 +08:00
forwarders []Proxy
idx int
}
// newRRProxy .
func newRRProxy(addr string, forwarders []Proxy) Proxy {
2017-07-13 21:55:41 +08:00
if len(forwarders) == 0 {
return Direct
} else if len(forwarders) == 1 {
return newProxy(addr, forwarders[0])
}
return &rrProxy{forwarders: forwarders}
2017-07-13 21:55:41 +08:00
}
2017-07-30 01:54:19 +08:00
func (p *rrProxy) Addr() string { return "strategy forwarder" }
func (p *rrProxy) ListenAndServe() {}
func (p *rrProxy) Serve(c net.Conn) {}
func (p *rrProxy) CurrentProxy() Proxy { return p.forwarders[p.idx] }
func (p *rrProxy) GetProxy(dstAddr string) Proxy { return p.NextProxy() }
2017-07-13 21:55:41 +08:00
func (p *rrProxy) NextProxy() Proxy {
2017-07-13 21:55:41 +08:00
n := len(p.forwarders)
if n == 1 {
return p.forwarders[0]
}
found := false
for i := 0; i < n; i++ {
p.idx = (p.idx + 1) % n
if p.forwarders[p.idx].Enabled() {
found = true
break
}
}
if !found {
2017-07-16 20:13:01 +08:00
logf("NO AVAILABLE PROXY FOUND! please check your network or proxy server settings.")
2017-07-13 21:55:41 +08:00
}
return p.forwarders[p.idx]
}
2017-07-30 01:54:19 +08:00
func (p *rrProxy) Enabled() bool { return true }
func (p *rrProxy) SetEnable(enable bool) {}
func (p *rrProxy) Dial(network, addr string) (net.Conn, error) {
return p.GetProxy(addr).Dial(network, addr)
2017-07-13 21:55:41 +08:00
}
// high availability proxy
type haProxy struct {
2017-07-13 21:55:41 +08:00
Proxy
}
// newHAProxy .
func newHAProxy(addr string, forwarders []Proxy) Proxy {
return &haProxy{Proxy: newRRProxy(addr, forwarders)}
2017-07-13 21:55:41 +08:00
}
func (p *haProxy) GetProxy(dstAddr string) Proxy {
2017-07-13 21:55:41 +08:00
proxy := p.CurrentProxy()
if proxy.Enabled() == false {
return p.NextProxy()
}
return proxy
}
func (p *haProxy) Dial(network, addr string) (net.Conn, error) {
return p.GetProxy(addr).Dial(network, addr)
}