2017-07-13 21:55:41 +08:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"net"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
2017-07-29 21:31:01 +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
|
|
|
|
}
|
|
|
|
|
2017-07-29 21:31:01 +08:00
|
|
|
// 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])
|
|
|
|
}
|
|
|
|
|
2017-07-29 21:31:01 +08:00
|
|
|
return &rrProxy{forwarders: forwarders}
|
2017-07-13 21:55:41 +08:00
|
|
|
}
|
|
|
|
|
2017-07-29 23:20:27 +08:00
|
|
|
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
|
|
|
|
2017-07-29 21:31:01 +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]
|
|
|
|
}
|
|
|
|
|
2017-07-16 12:16:50 +08:00
|
|
|
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-29 21:31:01 +08:00
|
|
|
func (p *rrProxy) Enabled() bool { return true }
|
|
|
|
func (p *rrProxy) SetEnable(enable bool) {}
|
|
|
|
func (p *rrProxy) Check(proxy Proxy, target string, duration time.Duration) {}
|
|
|
|
func (p *rrProxy) Addr() string { return "" }
|
|
|
|
func (p *rrProxy) Dial(network, addr string) (net.Conn, error) {
|
2017-07-13 21:55:41 +08:00
|
|
|
return p.NextProxy().Dial(network, addr)
|
|
|
|
}
|
|
|
|
|
|
|
|
// high availability proxy
|
2017-07-29 21:31:01 +08:00
|
|
|
type haProxy struct {
|
2017-07-13 21:55:41 +08:00
|
|
|
Proxy
|
|
|
|
}
|
|
|
|
|
|
|
|
// newHAProxy .
|
|
|
|
func newHAProxy(addr string, forwarders []Proxy) Proxy {
|
2017-07-29 21:31:01 +08:00
|
|
|
return &haProxy{Proxy: newRRProxy(addr, forwarders)}
|
2017-07-13 21:55:41 +08:00
|
|
|
}
|
|
|
|
|
2017-07-29 23:20:27 +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
|
|
|
|
}
|